[fbreader] Added support for text color

Specified with CSS color attribute
This commit is contained in:
Slava Monich 2015-08-11 13:53:21 +03:00
parent 75886f0a2e
commit 97ce479c50
23 changed files with 483 additions and 51 deletions

View file

@ -47,13 +47,13 @@ static const std::string HELVETICA = "Helvetica";
BooksPaintContext::BooksPaintContext() :
iPainter(NULL), iWidth(0), iHeight(0),
iSpaceWidth(0), iDescent(0)
iSpaceWidth(0), iDescent(0), iInvertColors(false)
{
}
BooksPaintContext::BooksPaintContext(int aWidth, int aHeight) :
iPainter(NULL), iWidth(aWidth), iHeight(aHeight),
iSpaceWidth(0), iDescent(0)
iSpaceWidth(0), iDescent(0), iInvertColors(false)
{
}
@ -199,8 +199,7 @@ void BooksPaintContext::drawImage(int x, int y, const ZLImageData& image,
QSize(imageWidth(image, width, height, type),
imageHeight(image, width, height, type)),
Qt::KeepAspectRatio,
Qt::SmoothTransformation
);
Qt::SmoothTransformation);
iPainter->drawImage(x, y - scaled.height(), scaled);
}
}
@ -255,3 +254,10 @@ int BooksPaintContext::height() const
{
return iHeight;
}
ZLColor BooksPaintContext::realColor(quint8 aRed, quint8 aGreen, quint8 aBlue) const
{
return iInvertColors ?
ZLColor(255-aRed, 255-aGreen, 255-aBlue) :
ZLColor(aRed, aGreen, aBlue);
}

View file

@ -36,6 +36,7 @@
#include "BooksTypes.h"
#include "ZLColor.h"
#include "ZLPaintContext.h"
#include <QFont>
@ -86,12 +87,17 @@ public:
void fillRectangle(int x0, int y0, int x1, int y1);
void drawFilledCircle(int x, int y, int r);
void setInvertColors(bool aInvertColors);
ZLColor realColor(quint8 aRed, quint8 aGreen, quint8 aBlue) const;
ZLColor realColor(const ZLColor aColor) const;
private:
QPainter* iPainter;
int iWidth;
int iHeight;
mutable int iSpaceWidth;
int iDescent;
bool iInvertColors;
QFont iFont;
};
@ -108,5 +114,9 @@ inline QSize BooksPaintContext::size() const
inline QColor qtColor(const ZLColor& aColor)
{ return QColor(aColor.Red, aColor.Green, aColor.Blue); }
inline ZLColor BooksPaintContext::realColor(const ZLColor aColor) const
{ return realColor(aColor.Red, aColor.Green, aColor.Blue); }
inline void BooksPaintContext::setInvertColors(bool aInvertColors)
{ iInvertColors = aInvertColors; }
#endif /* BOOKS_PAINT_CONTEXT_H */

View file

@ -34,18 +34,20 @@
#include "BooksTextView.h"
#include "BooksTextStyle.h"
#include "ZLStringUtil.h"
#define SUPER ZLTextView
const ZLColor BooksTextView::DEFAULT_BACKGROUND(255, 255, 255);
const ZLColor BooksTextView::INVERTED_BACKGROUND(0, 0, 0);
BooksTextView::BooksTextView(
ZLPaintContext& aContext,
BooksPaintContext& aContext,
shared_ptr<ZLTextStyle> aTextStyle,
BooksMargins aMargins) :
SUPER(aContext),
iMargins(aMargins),
iInvertColors(false),
iPaintContext(aContext),
iTextStyle(aTextStyle)
{
}
@ -82,7 +84,7 @@ int BooksTextView::bottomMargin() const
ZLColor BooksTextView::backgroundColor() const
{
return iInvertColors ? INVERTED_BACKGROUND : DEFAULT_BACKGROUND;
return iPaintContext.realColor(DEFAULT_BACKGROUND);
}
ZLColor BooksTextView::color(const std::string &aStyle) const
@ -91,21 +93,34 @@ ZLColor BooksTextView::color(const std::string &aStyle) const
static const std::string EXTERNAL_HYPERLINK("external");
static const std::string BOOK_HYPERLINK("book");
if (aStyle == INTERNAL_HYPERLINK) {
return ZLColor(33, 96, 180);
} else if (aStyle == EXTERNAL_HYPERLINK) {
return ZLColor(33, 96, 180);
} else if (aStyle == BOOK_HYPERLINK) {
return ZLColor(23, 68, 128);
} else if (aStyle == ZLTextStyle::SELECTION_BACKGROUND) {
return ZLColor(82, 131, 194);
} else if (aStyle == ZLTextStyle::HIGHLIGHTED_TEXT) {
return ZLColor(60, 139, 255);
} else if (iInvertColors) {
return ZLColor(255, 255, 255);
if (ZLStringUtil::startsWith(aStyle, '#')) {
if (aStyle.length() == 7) {
int i, value = 0;
for (i=1; i<7; i++) {
int nibble = ZLStringUtil::fromHex(aStyle[i]);
if (nibble >= 0) {
value <<= 4;
value |= nibble;
} else {
return ZLColor(0, 0, 0);
break;
}
}
if (i == 7) {
return iPaintContext.realColor(ZLColor(value));
}
}
} else if (aStyle == INTERNAL_HYPERLINK) {
return iPaintContext.realColor(33, 96, 180);
} else if (aStyle == EXTERNAL_HYPERLINK) {
return iPaintContext.realColor(33, 96, 180);
} else if (aStyle == BOOK_HYPERLINK) {
return iPaintContext.realColor(23, 68, 128);
} else if (aStyle == ZLTextStyle::SELECTION_BACKGROUND) {
return iPaintContext.realColor(82, 131, 194);
} else if (aStyle == ZLTextStyle::HIGHLIGHTED_TEXT) {
return iPaintContext.realColor(60, 139, 255);
}
return iPaintContext.realColor(0, 0, 0);
}
shared_ptr<ZLTextStyle> BooksTextView::baseStyle() const

View file

@ -36,6 +36,7 @@
#include "BooksTypes.h"
#include "BooksPos.h"
#include "BooksPaintContext.h"
#include "ZLColor.h"
#include "ZLTextView.h"
@ -46,7 +47,7 @@
class BooksTextView: public ZLTextView
{
public:
BooksTextView(ZLPaintContext& aContext,
BooksTextView(BooksPaintContext& aContext,
shared_ptr<ZLTextStyle> aTextStyle,
BooksMargins aMargin);
@ -80,7 +81,7 @@ public:
private:
BooksMargins iMargins;
bool iInvertColors;
BooksPaintContext& iPaintContext;
std::string iCaption;
shared_ptr<ZLTextStyle> iTextStyle;
};
@ -88,6 +89,6 @@ private:
inline BooksPos BooksTextView::position() const
{ return BooksPos(textArea().startCursor()); }
inline void BooksTextView::setInvertColors(bool aInvertColors)
{ iInvertColors = aInvertColors; }
{ iPaintContext.setInvertColors(aInvertColors); }
#endif // BOOKS_TEXT_VIEW_H

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
* Copyright (C) 2015 Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -39,6 +40,7 @@ StyleSheetTable::Style StyleSheetSingleStyleParser::parseString(const char *text
parse(text, strlen(text), true);
if (!myStateStack.empty()) {
switch (myStateStack.top()) {
case ATTRIBUTE_VALUE:
case ATTRIBUTE_VALUE_SPACE:
case ATTRIBUTE_VALUE_COMMA:
finishAttributeValue();
@ -201,7 +203,10 @@ void StyleSheetParser::processChar4(char c) {
myMap[myAttributeName].resize(0);
myWord.resize(0);
static const std::string FONT_FAMILY("font-family");
if (myAttributeName == FONT_FAMILY) {
static const std::string COLOR("color");
if (myAttributeName == COLOR) {
myStateStack.top() = ATTRIBUTE_VALUE;
} else if (myAttributeName == FONT_FAMILY) {
myStateStack.top() = ATTRIBUTE_VALUE_COMMA;
} else {
myStateStack.top() = ATTRIBUTE_VALUE_SPACE;
@ -227,6 +232,7 @@ void StyleSheetParser::processChar4(char c) {
}
break;
case ATTRIBUTE_VALUE:
case ATTRIBUTE_VALUE_SPACE:
case ATTRIBUTE_VALUE_COMMA:
switch (c) {
@ -296,6 +302,7 @@ void StyleSheetParser::processChar4(char c) {
// in which the string was found.
myStateStack.pop();
switch (myStateStack.top()) {
case ATTRIBUTE_VALUE:
case ATTRIBUTE_VALUE_SPACE:
case ATTRIBUTE_VALUE_COMMA:
myStateStack.top() = ATTRIBUTE_IGNORE;

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
* Copyright (C) 2015 Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -45,6 +46,7 @@ private:
COMMENT,
SELECTOR,
ATTRIBUTE_NAME,
ATTRIBUTE_VALUE,
ATTRIBUTE_VALUE_SPACE,
ATTRIBUTE_VALUE_COMMA,
ATTRIBUTE_IGNORE,

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
* Copyright (C) 2015 Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,8 +20,10 @@
#include <cstdlib>
#include <algorithm>
#include <string.h>
#include <ZLStringUtil.h>
#include "ZLStringUtil.h"
#include "ZLUnicodeUtil.h"
#include "StyleSheetTable.h"
@ -219,7 +222,7 @@ void StyleSheetTable::updateTextStyle(ZLTextStyleEntry &entry, const AttributeMa
static const std::string TEXT_ALIGN("text-align");
const std::vector<std::string> &alignment = values(styles, TEXT_ALIGN);
if (!alignment.empty()) {
const std::string &value = alignment.at(0);
const std::string &value = alignment[0];
if (value == "justify") {
entry.setAlignmentType(ALIGN_JUSTIFY);
} else if (value == "left") {
@ -233,7 +236,7 @@ void StyleSheetTable::updateTextStyle(ZLTextStyleEntry &entry, const AttributeMa
static const std::string FLOAT("float");
const std::vector<std::string> &floatVal = values(styles, FLOAT);
if (!floatVal.empty()) {
const std::string &value = floatVal.at(0);
const std::string &value = floatVal[0];
if (value == "left") {
entry.setAlignmentType(ALIGN_LEFT);
} else if (value == "right") {
@ -246,7 +249,7 @@ void StyleSheetTable::updateTextStyle(ZLTextStyleEntry &entry, const AttributeMa
const std::vector<std::string> &weight = values(styles, FONT_WEIGHT);
if (!weight.empty()) {
int num = -1;
const std::string &value = weight.at(0);
const std::string &value = weight[0];
if (value == "bold") {
num = 700;
} else if (value == "normal") {
@ -286,7 +289,7 @@ void StyleSheetTable::updateTextStyle(ZLTextStyleEntry &entry, const AttributeMa
static const std::string FONT_SIZE("font-size");
const std::vector<std::string> &fontSize = values(styles, FONT_SIZE);
if (!fontSize.empty()) {
const std::string &value = fontSize.at(0);
const std::string &value = fontSize[0];
if (value == "xx-small") {
entry.setFontSizeMag(-3);
} else if (value == "x-small") {
@ -418,11 +421,20 @@ void StyleSheetTable::updateTextStyle(ZLTextStyleEntry &entry, const AttributeMa
setLength(entry, ZLTextStyleEntry::LENGTH_FIRST_LINE_INDENT_DELTA, styles, TEXT_INDENT);
setMargin(entry, ZLTextStyleEntry::LENGTH_SPACE_BEFORE, styles, MARGIN_TOP);
setMargin(entry, ZLTextStyleEntry::LENGTH_SPACE_AFTER, styles, MARGIN_BOTTOM);
static const std::string COLOR("color");
std::vector<std::string> colors = values(styles, COLOR);
if (colors.size() == 1) {
ZLColor color;
if (stringToColor(colors[0], color)) {
entry.setColor(color);
}
}
}
void StyleSheetTable::getPageBreakValue(const std::vector<std::string> &values, ZLBoolean3 &value) {
if (!values.empty()) {
const std::string &first = values.at(0);
const std::string &first = values[0];
if ((first == "always") ||
(first == "left") ||
(first == "right")) {
@ -445,7 +457,7 @@ void StyleSheetTable::updateStyle(Style &style, const AttributeMap &map) {
static const std::string WHITE_SPACE("white-space");
const std::vector<std::string> &whiteSpace = values(map, WHITE_SPACE);
if (!whiteSpace.empty()) {
const std::string &value = whiteSpace.at(0);
const std::string &value = whiteSpace[0];
if (value == "normal") {
style.WhiteSpace = WS_NORMAL;
} else if (value == "nowrap") {
@ -465,3 +477,237 @@ void StyleSheetTable::updateStyle(Style &style, const AttributeMap &map) {
style.DisplayNone = true;
}
}
bool StyleSheetTable::stringToColor(const std::string &text, ZLColor &color) {
std::string str(text);
ZLStringUtil::stripWhiteSpaces(str);
if (!str.empty()) {
// Color spec must be an ASCII string
if (ZLUnicodeUtil::utf8Length(str) == (int)str.length()) {
static const std::string RGB("rgb");
if (str[0] == '#') {
if (str.length() == 4) {
// Hexadecimal notation #RGB
int rgb[3];
for (int i=0; i<3; i++) {
if ((rgb[i] = ZLStringUtil::fromHex(str[i+1])) < 0) {
return false;
}
}
color.Red = ((rgb[0] << 4) | rgb[0]);
color.Green = ((rgb[1] << 4) | rgb[1]);
color.Blue = ((rgb[2] << 4) | rgb[2]);
return true;
} else if (str.length() == 7) {
// Hexadecimal notation #RRGGBB
int rrggbb[6];
for (int i=0; i<6; i++) {
if ((rrggbb[i] = ZLStringUtil::fromHex(str[i+1])) < 0) {
return false;
}
}
color.Red = ((rrggbb[0] << 4) | rrggbb[1]);
color.Green = ((rrggbb[2] << 4) | rrggbb[3]);
color.Blue = ((rrggbb[4] << 4) | rrggbb[5]);
return true;
}
} else if (ZLStringUtil::stringStartsWith(str, RGB)) {
// Functional Notation rgb(R,G,B)
str.erase(0,3);
ZLStringUtil::stripWhiteSpaces(str);
if (ZLStringUtil::startsWith(str, '(') && ZLStringUtil::endsWith(str, ')')) {
str = str.substr(1,str.length()-2);
std::vector<std::string> rgb = ZLStringUtil::splitString(str, ",");
if (rgb.size() == 3) {
int i;
long c[3];
for (i=0; i<3; i++) {
std::string tmp(rgb[i]);
ZLStringUtil::stripWhiteSpaces(tmp);
if (ZLStringUtil::endsWith(tmp, '%')) {
tmp.resize(tmp.length()-1);
if (ZLStringUtil::stringToLong(tmp, c[i]) && c[i] >= 0 && c[i] <= 100) {
c[i] = (c[i] * 255 + 50) / 100;
continue;
}
} else if (ZLStringUtil::stringToLong(tmp, c[i]) && c[i] >= 0 && c[i] <= 255) {
continue;
}
}
if (i == 3) {
color.Red = c[0];
color.Green = c[1];
color.Blue = c[2];
return true;
}
}
}
} else {
// Color keywords
static const struct _CSSColorEntry {
const char* stringValue;
long intValue;
} knownColors [] = {
{ "aliceblue", 0xf0f8ff },
{ "antiquewhite", 0xfaebd7 },
{ "aqua", 0x00ffff },
{ "aquamarine", 0x7fffd4 },
{ "azure", 0xf0ffff },
{ "beige", 0xf5f5dc },
{ "bisque", 0xffe4c4 },
{ "black", 0x000000 },
{ "blanchedalmond", 0xffe4c4 },
{ "blue", 0x0000ff },
{ "blueviolet", 0x8a2be2 },
{ "brown", 0xa52a2a },
{ "burlywood", 0xdeb887 },
{ "cadetblue", 0x5f9ea0 },
{ "chartreuse", 0x7fff00 },
{ "chocolate", 0xd2691e },
{ "coral", 0xff7f50 },
{ "cornflowerblue", 0x6495ed },
{ "cornsilk", 0xfff8dc },
{ "crimson", 0xdc143c },
{ "darkblue", 0x00008b },
{ "darkcyan", 0x008b8b },
{ "darkgoldenrod", 0xb8860b },
{ "darkgray", 0xa9a9a9 },
{ "darkgreen", 0x006400 },
{ "darkkhaki", 0xbdb76b },
{ "darkmagenta", 0x8b008b },
{ "darkolivegreen", 0x556b2f },
{ "darkorange", 0xff8c00 },
{ "darkorchid", 0x9932cc },
{ "darkred", 0x8b0000 },
{ "darksalmon", 0xe9967a },
{ "darkseagreen", 0x8fbc8f },
{ "darkslateblue", 0x483d8b },
{ "darkslategray", 0x2f4f4f },
{ "darkturquoise", 0x00ced1 },
{ "darkviolet", 0x9400d3 },
{ "deeppink", 0xff1493 },
{ "deepskyblue", 0x00bfff },
{ "dimgray", 0x696969 },
{ "dodgerblue", 0x1e90ff },
{ "firebrick", 0xb22222 },
{ "floralwhite", 0xfffaf0 },
{ "forestgreen", 0x228b22 },
{ "fuchsia", 0xff00ff },
{ "gainsboro", 0xdcdcdc },
{ "ghostwhite", 0xf8f8ff },
{ "goldenrod", 0xdaa520 },
{ "gold", 0xffd700 },
{ "gray", 0x808080 },
{ "green", 0x008000 },
{ "greenyellow", 0xadff2f },
{ "grey", 0x808080 },
{ "honeydew", 0xf0fff0 },
{ "hotpink", 0xff69b4 },
{ "indianred", 0xcd5c5c },
{ "indigo", 0x4b0082 },
{ "ivory", 0xfffff0 },
{ "khaki", 0xf0e68c },
{ "lavenderblush", 0xfff0f5 },
{ "lavender", 0xe6e6fa },
{ "lawngreen", 0x7cfc00 },
{ "lemonchiffon", 0xfffacd },
{ "lightblue", 0xadd8e6 },
{ "lightcoral", 0xf08080 },
{ "lightcyan", 0xe0ffff },
{ "lightgoldenrodyellow", 0xfafad2 },
{ "lightgreen", 0x90ee90 },
{ "lightgrey", 0xd3d3d3 },
{ "lightpink", 0xffb6c1 },
{ "lightsalmon", 0xffa07a },
{ "lightseagreen", 0x20b2aa },
{ "lightskyblue", 0x87cefa },
{ "lightslategray", 0x778899 },
{ "lightsteelblue", 0xb0c4de },
{ "lightyellow", 0xffffe0 },
{ "lime", 0x00ff00 },
{ "limegreen", 0x32cd32 },
{ "linen", 0xfaf0e6 },
{ "maroon", 0x800000 },
{ "mediumaquamarine", 0x66cdaa },
{ "mediumblue", 0x0000cd },
{ "mediumorchid", 0xba55d3 },
{ "mediumpurple", 0x9370db },
{ "mediumseagreen", 0x3cb371 },
{ "mediumslateblue", 0x7b68ee },
{ "mediumspringgreen", 0x00fa9a },
{ "mediumturquoise", 0x48d1cc },
{ "mediumvioletred", 0xc71585 },
{ "midnightblue", 0x191970 },
{ "mintcream", 0xf5fffa },
{ "mistyrose", 0xffe4e1 },
{ "moccasin", 0xffe4b5 },
{ "navajowhite", 0xffdead },
{ "navy", 0x000080 },
{ "oldlace", 0xfdf5e6 },
{ "olive", 0x808000 },
{ "olivedrab", 0x6b8e23 },
{ "orange", 0xffa500 },
{ "orangered", 0xff4500 },
{ "orchid", 0xda70d6 },
{ "palegoldenrod", 0xeee8aa },
{ "palegreen", 0x98fb98 },
{ "paleturquoise", 0xafeeee },
{ "palevioletred", 0xdb7093 },
{ "papayawhip", 0xffefd5 },
{ "peachpuff", 0xffdab9 },
{ "peru", 0xcd853f },
{ "pink", 0xffc0cb },
{ "plum", 0xdda0dd },
{ "powderblue", 0xb0e0e6 },
{ "purple", 0x800080 },
{ "rebeccapurple", 0x663399 },
{ "red", 0xff0000 },
{ "rosybrown", 0xbc8f8f },
{ "royalblue", 0x4169e1 },
{ "saddlebrown", 0x8b4513 },
{ "salmon", 0xfa8072 },
{ "sandybrown", 0xf4a460 },
{ "seagreen", 0x2e8b57 },
{ "seashell", 0xfff5ee },
{ "sienna", 0xa0522d },
{ "silver", 0xc0c0c0 },
{ "skyblue", 0x87ceeb },
{ "slateblue", 0x6a5acd },
{ "slategrey", 0x708090 },
{ "snow", 0xfffafa },
{ "springgreen", 0x00ff7f },
{ "steelblue", 0x4682b4 },
{ "tan", 0xd2b48c },
{ "teal", 0x008080 },
{ "thistle", 0xd8bfd8 },
{ "tomato", 0xff6347 },
{ "turquoise", 0x40e0d0 },
{ "violet", 0xee82ee },
{ "wheat", 0xf5deb3 },
{ "white", 0xffffff },
{ "whitesmoke", 0xf5f5f5 },
{ "yellow", 0xffff00 },
{ "yellowgreen", 0x9acd32 }
};
int low = 0;
int high = (sizeof(knownColors)/sizeof(knownColors[0]))-1;
const char* key = str.c_str();
while (low <= high) {
const int mid = (low + high)/2;
int cmp = strcasecmp(knownColors[mid].stringValue, key);
if (cmp < 0) {
low = mid + 1;
} else if (cmp > 0) {
high = mid - 1;
} else {
color.setIntValue(knownColors[mid].intValue);
return true;
}
}
}
}
}
return false;
}

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
* Copyright (C) 2015 Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -26,6 +27,7 @@
#include <shared_ptr.h>
#include <ZLColor.h>
#include <ZLTextParagraph.h>
#include <ZLBoolean3.h>
@ -127,6 +129,7 @@ private:
static void setMargin(ZLTextStyleEntry &entry, ZLTextStyleEntry::Length name, const std::string &value);
static const std::vector<std::string> &values(const AttributeMap &map, const std::string &name);
static bool sortBySpecificity(const Entry *e1, const Entry *e2);
static bool stringToColor(const std::string &text, ZLColor &color);
public:
bool isEmpty() const;

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
* Copyright (C) 2015 Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -27,6 +28,8 @@ struct ZLColor {
ZLColor(unsigned char r, unsigned char g, unsigned char b);
ZLColor(long longValue = 0);
void setIntValue(long longValue);
long intValue();
bool operator == (const ZLColor &color) const;
@ -35,6 +38,7 @@ struct ZLColor {
inline ZLColor::ZLColor(unsigned char r, unsigned char g, unsigned char b) : Red(r), Green(g), Blue(b) {}
inline ZLColor::ZLColor(long longValue) : Red((unsigned char)(longValue >> 16)), Green((unsigned char)(longValue >> 8)), Blue((unsigned char)longValue) {}
inline void ZLColor::setIntValue(long longValue) { Red = (unsigned char)(longValue >> 16); Green = (unsigned char)(longValue >> 8); Blue = (unsigned char)longValue; }
inline long ZLColor::intValue() { return (((long)Red) << 16) + (((long)Green) << 8) + Blue; }
inline bool ZLColor::operator == (const ZLColor &color) const { return (Red == color.Red) && (Green == color.Green) && (Blue == color.Blue); }
inline bool ZLColor::operator != (const ZLColor &color) const { return !operator==(color); }

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
* Copyright (C) 2015 Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,8 +21,11 @@
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <locale.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include "ZLStringUtil.h"
@ -154,3 +158,25 @@ double ZLStringUtil::stringToDouble(const std::string &value, double defaultValu
return defaultValue;
}
}
bool ZLStringUtil::stringToLong(const char *s, long &result) {
while (*s && isspace(*s)) s++;
char* endptr = NULL;
long number = strtol(s, &endptr, 10);
if (endptr && endptr != s) {
if ((number != LONG_MAX && number != LONG_MIN) || (errno != ERANGE)) {
while (*endptr && isspace(*endptr)) endptr++;
if (!*endptr) {
result = number;
return true;
}
}
}
return false;
}
int ZLStringUtil::fromHex(char hex) {
return (hex >= '0' && hex <= '9') ? (hex - '0') :
(hex >= 'a' && hex <= 'z') ? (hex - 'a' + 10) :
(hex >= 'A' && hex <= 'Z') ? (hex - 'A' + 10) : -1;
}

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
* Copyright (C) 2015 Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -31,6 +32,7 @@ private:
public:
static bool stringStartsWith(const std::string &str, const std::string &start);
static bool stringEndsWith(const std::string &str, const std::string &end);
static bool startsWith(const std::string &str, char c);
static bool endsWith(const std::string &str, char c);
static bool caseInsensitiveEqual(const std::string &str1, const std::string &str2);
static bool caseInsensitiveSort(const std::string &str1, const std::string &str2);
@ -45,12 +47,22 @@ public:
static std::string doubleToString(double value);
static double stringToDouble(const std::string &value, double defaultValue);
static bool stringToLong(const std::string &str, long &result);
static bool stringToLong(const char *str, long &result);
static int fromHex(char hex);
};
inline std::vector<std::string> ZLStringUtil::splitString(const std::string &str, const char* delim) {
return ZLStringUtil::splitString(str.c_str(), delim);
}
inline bool ZLStringUtil::startsWith(const std::string &str, char c) {
return !str.empty() && str[0] == c;
}
inline bool ZLStringUtil::endsWith(const std::string &str, char c) {
return !str.empty() && str[str.length()-1] == c;
}
inline bool ZLStringUtil::stringToLong(const std::string &str, long &result) {
return stringToLong(str.c_str(), result);
}
#endif /* __ZLSTRINGUTIL_H__ */

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
* Copyright (C) 2015 Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -234,6 +235,7 @@ void ZLTextModel::addControl(const ZLTextStyleEntry &entry) {
len += entry.myFontFamilies.at(i).length() + 1;
}
}
if (mask & ZLTextStyleEntry::SUPPORT_COLOR) len += 3;
myLastEntryStart = myAllocator.allocate(len);
char *address = myLastEntryStart;
*address++ = ZLTextParagraphEntry::STYLE_ENTRY;
@ -263,6 +265,11 @@ void ZLTextModel::addControl(const ZLTextStyleEntry &entry) {
address += nbytes;
}
}
if (mask & ZLTextStyleEntry::SUPPORT_COLOR) {
*address++ = entry.myColor.Red;
*address++ = entry.myColor.Green;
*address++ = entry.myColor.Blue;
}
myParagraphs.back()->addEntry(myLastEntryStart);
}

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
* Copyright (C) 2015 Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -109,12 +110,19 @@ ZLTextStyleEntry::ZLTextStyleEntry(char *address) {
myFontFamilies.push_back(font);
}
}
if (colorSupported()) {
ZLColor color;
color.Red = (unsigned char)*address++;
color.Green = (unsigned char)*address++;
color.Blue = (unsigned char)*address++;
setColor(color);
}
}
void ZLTextStyleEntry::reset() {
mySupportedFontModifier = 0;
myMask = 0;
myFontFamilies.clear();
myFontFamilies.resize(0);
}
void ZLTextStyleEntry::apply(const ZLTextStyleEntry &other) {
@ -143,6 +151,9 @@ void ZLTextStyleEntry::apply(const ZLTextStyleEntry &other) {
if (other.myMask & SUPPORT_FONT_FAMILIES) {
setFontFamilies(other.myFontFamilies);
}
if (other.myMask & SUPPORT_COLOR) {
setColor(other.myColor);
}
}
void ZLTextStyleEntry::inherit(const ZLTextStyleEntry &other) {
@ -169,6 +180,10 @@ void ZLTextStyleEntry::inherit(const ZLTextStyleEntry &other) {
if (other.myMask & SUPPORT_FONT_FAMILIES) {
setFontFamilies(other.myFontFamilies);
}
// color
if (other.myMask & SUPPORT_COLOR) {
setColor(other.myColor);
}
}
bool ZLTextStyleEntry::equals(const ZLTextStyleEntry &other) const {
@ -198,6 +213,9 @@ bool ZLTextStyleEntry::equals(const ZLTextStyleEntry &other) const {
if ((myMask & SUPPORT_FONT_FAMILIES) && myFontFamilies != other.myFontFamilies) {
return false;
}
if ((myMask & SUPPORT_OPACITY) && myColor != other.myColor) {
return false;
}
return true;
} else {
return false;
@ -334,6 +352,7 @@ void ZLTextParagraph::Iterator::next() {
while (*myPointer++);
}
}
if (mask & ZLTextStyleEntry::SUPPORT_COLOR) myPointer += 3;
break;
}
case ZLTextParagraphEntry::FIXED_HSPACE_ENTRY:

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
* Copyright (C) 2015 Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -26,6 +27,7 @@
#include <shared_ptr.h>
#include <ZLColor.h>
#include <ZLTextKind.h>
#include <ZLTextAlignmentType.h>
#include <ZLTextFontModifier.h>
@ -137,11 +139,16 @@ public:
const std::vector<std::string> &fontFamilies() const;
void setFontFamilies(const std::vector<std::string> &fontFamilies);
bool colorSupported() const;
const ZLColor &color() const;
void setColor(const ZLColor &color);
enum {
SUPPORT_ALIGNMENT_TYPE = 1 << NUMBER_OF_LENGTHS,
SUPPORT_FONT_SIZE = 1 << (NUMBER_OF_LENGTHS + 1),
SUPPORT_FONT_FAMILIES = 1 << (NUMBER_OF_LENGTHS + 2),
SUPPORT_OPACITY = 1 << (NUMBER_OF_LENGTHS + 3)
SUPPORT_OPACITY = 1 << (NUMBER_OF_LENGTHS + 3),
SUPPORT_COLOR = 1 << (NUMBER_OF_LENGTHS + 4)
};
private:
@ -155,6 +162,7 @@ private:
unsigned char myFontModifier;
signed char myFontSizeMag;
std::vector<std::string> myFontFamilies;
ZLColor myColor;
friend class ZLTextModel;
};
@ -400,6 +408,10 @@ inline bool ZLTextStyleEntry::fontFamiliesSupported() const { return (myMask & S
inline const std::vector<std::string> &ZLTextStyleEntry::fontFamilies() const { return myFontFamilies; }
inline void ZLTextStyleEntry::setFontFamilies(const std::vector<std::string> &fontFamilies) { myFontFamilies = fontFamilies; myMask |= SUPPORT_FONT_FAMILIES; }
inline bool ZLTextStyleEntry::colorSupported() const { return (myMask & SUPPORT_COLOR) != 0; }
inline const ZLColor &ZLTextStyleEntry::color() const { return myColor; }
inline void ZLTextStyleEntry::setColor(const ZLColor &color) { myColor = color; myMask |= SUPPORT_COLOR; }
inline ZLTextControlEntry::ZLTextControlEntry(ZLTextKind kind, bool isStart) : myKind(kind), myStart(isStart) {}
inline ZLTextControlEntry::~ZLTextControlEntry() {}
inline ZLTextKind ZLTextControlEntry::kind() const { return myKind; }

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
* Copyright (C) 2015 Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -181,6 +182,13 @@ const std::string &ZLTextFullDecoratedStyle::colorStyle() const {
return style.empty() ? base()->colorStyle() : style;
}
ZLTextForcedStyle::ZLTextForcedStyle(shared_ptr<ZLTextStyle> base, const ZLTextStyleEntry &entry) :
ZLTextDecoratedStyle(base), myEntry(entry) {
if (myEntry.colorSupported()) {
myColorStyle = ZLTextStyle::colorStyle(myEntry.color());
}
}
short ZLTextForcedStyle::lineStartIndent(const ZLTextStyleEntry::Metrics &metrics, bool rtl) const {
ZLTextStyleEntry::Length lengthType = rtl ?
ZLTextStyleEntry::LENGTH_RIGHT_INDENT :
@ -279,6 +287,10 @@ const std::vector<std::string> &ZLTextForcedStyle::fontFamilies() const {
myEntry.fontFamilies() : base()->fontFamilies();
}
const std::string &ZLTextForcedStyle::colorStyle() const {
return myEntry.colorSupported() ? myColorStyle : base()->colorStyle();
}
const std::string &ZLTextStyleDecoration::colorStyle() const {
return myColorStyle;
}

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
* Copyright (C) 2015 Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -67,6 +68,7 @@ public:
private:
const ZLTextStyleEntry &myEntry;
std::string myColorStyle;
};
class ZLTextPartialDecoratedStyle : public ZLTextDecoratedStyle {
@ -138,9 +140,7 @@ inline ZLTextDecoratedStyle::~ZLTextDecoratedStyle() {}
inline bool ZLTextDecoratedStyle::isDecorated() const { return true; }
inline const shared_ptr<ZLTextStyle> ZLTextDecoratedStyle::base() const { return myBase; }
inline ZLTextForcedStyle::ZLTextForcedStyle(shared_ptr<ZLTextStyle> base, const ZLTextStyleEntry &entry) : ZLTextDecoratedStyle(base), myEntry(entry) {}
inline ZLTextForcedStyle::~ZLTextForcedStyle() {}
inline const std::string &ZLTextForcedStyle::colorStyle() const { return base()->colorStyle(); }
inline int ZLTextForcedStyle::verticalShift() const { return base()->verticalShift(); }
inline double ZLTextForcedStyle::lineSpace() const { return base()->lineSpace(); }
inline bool ZLTextForcedStyle::allowHyphenations() const { return base()->allowHyphenations(); }

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
* Copyright (C) 2015 Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -17,9 +18,17 @@
* 02110-1301, USA.
*/
#include <stdio.h>
#include "ZLTextStyle.h"
const std::string ZLTextStyle::REGULAR_TEXT = "";
const std::string ZLTextStyle::SELECTION_BACKGROUND = "selectionBackground";
const std::string ZLTextStyle::HIGHLIGHTED_TEXT = "highlightedText";
const std::string ZLTextStyle::TREE_LINES = "treeLines";
std::string ZLTextStyle::colorStyle(ZLColor color) {
char buf[8];
snprintf(buf, sizeof(buf), "#%02x%02x%02x", color.Red, color.Green, color.Blue);
return std::string(buf);
}

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
* Copyright (C) 2015 Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -25,6 +26,7 @@
#include <shared_ptr.h>
#include <ZLColor.h>
#include <ZLTextAlignmentType.h>
#include <ZLTextParagraph.h>
@ -64,6 +66,7 @@ public:
virtual bool allowHyphenations() const = 0;
int lineSpacePercent() const;
static std::string colorStyle(ZLColor color);
};
inline ZLTextStyle::ZLTextStyle() {}

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2004-2010 Geometer Plus <contact@geometerplus.com>
* Copyright (C) 2015 Slava Monich <slava.monich@jolla.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,8 +20,6 @@
#include <cstdlib>
#include <cstring>
#include <errno.h>
#include <limits.h>
#include <ZLibrary.h>
#include <ZLFile.h>
@ -29,6 +28,7 @@
#include "ZLTextStyle.h"
#include "ZLTextStyleCollection.h"
#include "ZLTextDecoratedStyle.h"
#include "ZLStringUtil.h"
ZLTextStyleCollection *ZLTextStyleCollection::ourInstance = 0;
@ -72,21 +72,13 @@ int ZLTextStyleReader::lengthValue(const char **attributes, const char *name, ZL
if (ZLTextStyleEntry::parseLength(stringValue, size, unit)) {
return size;
} else {
const char *s = stringValue;
while (*s && isspace(*s)) s++;
char* endptr = NULL;
long number = strtol(s, &endptr, 10);
if (endptr && endptr != s) {
if ((number != LONG_MAX && number != LONG_MIN) || (errno != ERANGE)) {
while (*endptr && isspace(*endptr)) endptr++;
if (!*endptr) {
long number;
if (ZLStringUtil::stringToLong(stringValue, number)) {
unit = ZLTextStyleEntry::SIZE_UNIT_PIXEL;
return number;
}
}
}
}
}
return defaultValue;
}

View file

@ -30,3 +30,11 @@ body,h1,h2, /*///****/ div, p {
/* 12: Known style with missing semicolon */
font-style: italic
}
/* 13. Sypported ways to represent colors */
.red { color: #f00; }
.green { color: "#00ff00"; }
.blue { color: rgb(0,0, 255); }
.olive { color: rgb(50%, 50%, 0%); }
.orangered { color: orangered }
.palegreen { color: "palegreen"; }

View file

@ -18,3 +18,21 @@ p {
font-style: italic;
font-family: "Foo Bar";
}
.red {
color: #ff0000;
}
.green {
color: #00ff00;
}
.blue {
color: #0000ff;
}
.olive {
color: #808000;
}
.orangered {
color: #ff4500;
}
.palegreen {
color: #98fb98;
}

View file

@ -42,6 +42,9 @@
.calibre5 {
font-style: italic;
}
.calibre6 {
color: #4183c4;
}
.calibre8 {
font-weight: bold;
}
@ -70,6 +73,18 @@
font-weight: bold;
font-size: 144%; /* 2 */
}
.hljs-comment {
color: #8e908c;
}
.hljs-keyword {
color: #8959a8;
}
.hljs-preprocessor {
color: #f5871f;
}
.hljs-string {
color: #718c00;
}
.lang-c {
margin-left: 0;
margin-bottom: 0;
@ -86,6 +101,7 @@
}
.page {
font-family: "sans-serif";
color: #333333;
}
.table {
margin-bottom: 16px;

View file

@ -39,6 +39,7 @@
#include "ZLInputStream.h"
#include "ZLStringUtil.h"
#include "ZLTextStyle.h"
#include "ZLFile.h"
#include "filesystem/ZLQtFSManager.h"
@ -161,6 +162,9 @@ dump_style(
}
out << size << "%; /* " << ((int)mag) << " */\n";
}
if (style.TextStyle.colorSupported()) {
out << " color: " << ZLTextStyle::colorStyle(style.TextStyle.color()) << ";\n";
}
}
static void