mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-05 10:49:24 +02:00
do not split css values in parser
This commit is contained in:
parent
5cea231a6a
commit
ccdb527030
3 changed files with 75 additions and 92 deletions
|
@ -72,7 +72,7 @@ void StyleSheetParser::parse(const char *text, int len, bool final) {
|
||||||
const char *start = text;
|
const char *start = text;
|
||||||
const char *end = text + len;
|
const char *end = text + len;
|
||||||
for (const char *ptr = start; ptr != end; ++ptr) {
|
for (const char *ptr = start; ptr != end; ++ptr) {
|
||||||
if (std::isspace(*ptr)) {
|
if (myReadState != ATTRIBUTE_VALUE && std::isspace(*ptr)) {
|
||||||
if (start != ptr) {
|
if (start != ptr) {
|
||||||
myWord.append(start, ptr - start);
|
myWord.append(start, ptr - start);
|
||||||
}
|
}
|
||||||
|
@ -221,16 +221,9 @@ void StyleSheetParser::processWord(const std::string &word) {
|
||||||
myMap[myAttributeName].clear();
|
myMap[myAttributeName].clear();
|
||||||
break;
|
break;
|
||||||
case ATTRIBUTE_VALUE:
|
case ATTRIBUTE_VALUE:
|
||||||
{
|
myMap[myAttributeName] = word;
|
||||||
const std::size_t l = word.length();
|
|
||||||
if (l >= 2 && (word[0] == '"' || word[0] == '\'') && word[0] == word[l - 1]) {
|
|
||||||
myMap[myAttributeName].push_back(word.substr(1, l - 2));
|
|
||||||
} else {
|
|
||||||
myMap[myAttributeName].push_back(word);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyleSheetSingleStyleParser::StyleSheetSingleStyleParser(const std::string &pathPrefix) : StyleSheetParser(pathPrefix) {
|
StyleSheetSingleStyleParser::StyleSheetSingleStyleParser(const std::string &pathPrefix) : StyleSheetParser(pathPrefix) {
|
||||||
|
@ -275,18 +268,18 @@ void StyleSheetMultiStyleParser::storeData(const std::string &selector, const St
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string firstValue(const StyleSheetTable::AttributeMap &map, const std::string &key) {
|
static std::string value(const StyleSheetTable::AttributeMap &map, const std::string &key) {
|
||||||
const StyleSheetTable::AttributeMap::const_iterator it = map.find(key);
|
const StyleSheetTable::AttributeMap::const_iterator it = map.find(key);
|
||||||
if (it == map.end() || it->second.empty()) {
|
if (it == map.end() || it->second.empty()) {
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
return it->second[0];
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &attributes) {
|
void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &attributes) {
|
||||||
ZLLogger::Instance().registerClass("FONT");
|
ZLLogger::Instance().registerClass("FONT");
|
||||||
if (name == "@font-face") {
|
if (name == "@font-face") {
|
||||||
const std::string family = firstValue(attributes, "font-family");
|
const std::string family = value(attributes, "font-family");
|
||||||
if (family.empty()) {
|
if (family.empty()) {
|
||||||
ZLLogger::Instance().println("FONT", "Font family not specified in @font-face entry");
|
ZLLogger::Instance().println("FONT", "Font family not specified in @font-face entry");
|
||||||
return;
|
return;
|
||||||
|
@ -294,7 +287,9 @@ void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const St
|
||||||
const StyleSheetTable::AttributeMap::const_iterator it = attributes.find("src");
|
const StyleSheetTable::AttributeMap::const_iterator it = attributes.find("src");
|
||||||
std::string path;
|
std::string path;
|
||||||
if (it != attributes.end()) {
|
if (it != attributes.end()) {
|
||||||
for (std::vector<std::string>::const_iterator jt = it->second.begin(); jt != it->second.end(); ++jt) {
|
// TODO: better split
|
||||||
|
const std::vector<std::string> ids = ZLStringUtil::split(it->second, " ");
|
||||||
|
for (std::vector<std::string>::const_iterator jt = ids.begin(); jt != ids.end(); ++jt) {
|
||||||
if (ZLStringUtil::stringStartsWith(*jt, "url(") &&
|
if (ZLStringUtil::stringStartsWith(*jt, "url(") &&
|
||||||
ZLStringUtil::stringEndsWith(*jt, ")")) {
|
ZLStringUtil::stringEndsWith(*jt, ")")) {
|
||||||
path = url2FullPath(*jt);
|
path = url2FullPath(*jt);
|
||||||
|
@ -308,8 +303,8 @@ void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const St
|
||||||
}
|
}
|
||||||
myFontMap.appendFontFace(
|
myFontMap.appendFontFace(
|
||||||
family,
|
family,
|
||||||
firstValue(attributes, "font-weight"),
|
value(attributes, "font-weight"),
|
||||||
firstValue(attributes, "font-style"),
|
value(attributes, "font-style"),
|
||||||
path
|
path
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,29 +29,23 @@ bool StyleSheetTable::isEmpty() const {
|
||||||
|
|
||||||
void StyleSheetTable::addMap(const std::string &tag, const std::string &aClass, const AttributeMap &map) {
|
void StyleSheetTable::addMap(const std::string &tag, const std::string &aClass, const AttributeMap &map) {
|
||||||
if ((!tag.empty() || !aClass.empty()) && !map.empty()) {
|
if ((!tag.empty() || !aClass.empty()) && !map.empty()) {
|
||||||
Key key(tag, aClass);
|
const Key key(tag, aClass);
|
||||||
myControlMap[key] = createControl(map);
|
myControlMap[key] = createControl(map);
|
||||||
const std::vector<std::string> &pbb = values(map, "page-break-before");
|
|
||||||
if (!pbb.empty()) {
|
const std::string &pbb = value(map, "page-break-before");
|
||||||
if ((pbb[0] == "always") ||
|
if (pbb == "always" || pbb == "left" || pbb == "right") {
|
||||||
(pbb[0] == "left") ||
|
|
||||||
(pbb[0] == "right")) {
|
|
||||||
myPageBreakBeforeMap[key] = true;
|
myPageBreakBeforeMap[key] = true;
|
||||||
} else if (pbb[0] == "avoid") {
|
} else if (pbb == "avoid") {
|
||||||
myPageBreakBeforeMap[key] = false;
|
myPageBreakBeforeMap[key] = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
const std::vector<std::string> &pba = values(map, "page-break-after");
|
const std::string &pba = value(map, "page-break-after");
|
||||||
if (!pba.empty()) {
|
if (pba == "always" || pba == "left" || pba == "right") {
|
||||||
if ((pba[0] == "always") ||
|
|
||||||
(pba[0] == "left") ||
|
|
||||||
(pba[0] == "right")) {
|
|
||||||
myPageBreakAfterMap[key] = true;
|
myPageBreakAfterMap[key] = true;
|
||||||
} else if (pba[0] == "avoid") {
|
} else if (pba == "avoid") {
|
||||||
myPageBreakAfterMap[key] = false;
|
myPageBreakAfterMap[key] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parseLength(const std::string &toParse, short &size, ZLTextStyleEntry::SizeUnit &unit) {
|
static bool parseLength(const std::string &toParse, short &size, ZLTextStyleEntry::SizeUnit &unit) {
|
||||||
|
@ -84,14 +78,11 @@ void StyleSheetTable::setLength(ZLTextStyleEntry &entry, ZLTextStyleEntry::Featu
|
||||||
if (it == map.end()) {
|
if (it == map.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const std::vector<std::string> &values = it->second;
|
|
||||||
if (!values.empty() && !values[0].empty()) {
|
|
||||||
short size;
|
short size;
|
||||||
ZLTextStyleEntry::SizeUnit unit;
|
ZLTextStyleEntry::SizeUnit unit;
|
||||||
if (parseLength(values[0], size, unit)) {
|
if (parseLength(it->second, size, unit)) {
|
||||||
entry.setLength(featureId, size, unit);
|
entry.setLength(featureId, size, unit);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StyleSheetTable::doBreakBefore(const std::string &tag, const std::string &aClass) const {
|
bool StyleSheetTable::doBreakBefore(const std::string &tag, const std::string &aClass) const {
|
||||||
|
@ -138,106 +129,103 @@ shared_ptr<ZLTextStyleEntry> StyleSheetTable::control(const std::string &tag, co
|
||||||
return (it != myControlMap.end()) ? it->second : 0;
|
return (it != myControlMap.end()) ? it->second : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string> &StyleSheetTable::values(const AttributeMap &map, const std::string &name) {
|
const std::string &StyleSheetTable::value(const AttributeMap &map, const std::string &name) {
|
||||||
const AttributeMap::const_iterator it = map.find(name);
|
const AttributeMap::const_iterator it = map.find(name);
|
||||||
if (it != map.end()) {
|
if (it != map.end()) {
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
static const std::vector<std::string> emptyVector;
|
static const std::string emptyString;
|
||||||
return emptyVector;
|
return emptyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<ZLTextStyleEntry> StyleSheetTable::createControl(const AttributeMap &styles) {
|
shared_ptr<ZLTextStyleEntry> StyleSheetTable::createControl(const AttributeMap &styles) {
|
||||||
shared_ptr<ZLTextStyleEntry> entry = new ZLTextStyleEntry(ZLTextStyleEntry::STYLE_CSS_ENTRY);
|
shared_ptr<ZLTextStyleEntry> entry = new ZLTextStyleEntry(ZLTextStyleEntry::STYLE_CSS_ENTRY);
|
||||||
|
|
||||||
const std::vector<std::string> &alignment = values(styles, "text-align");
|
const std::string &alignment = value(styles, "text-align");
|
||||||
if (!alignment.empty()) {
|
if (alignment == "justify") {
|
||||||
if (alignment[0] == "justify") {
|
|
||||||
entry->setAlignmentType(ALIGN_JUSTIFY);
|
entry->setAlignmentType(ALIGN_JUSTIFY);
|
||||||
} else if (alignment[0] == "left") {
|
} else if (alignment == "left") {
|
||||||
entry->setAlignmentType(ALIGN_LEFT);
|
entry->setAlignmentType(ALIGN_LEFT);
|
||||||
} else if (alignment[0] == "right") {
|
} else if (alignment == "right") {
|
||||||
entry->setAlignmentType(ALIGN_RIGHT);
|
entry->setAlignmentType(ALIGN_RIGHT);
|
||||||
} else if (alignment[0] == "center") {
|
} else if (alignment == "center") {
|
||||||
entry->setAlignmentType(ALIGN_CENTER);
|
entry->setAlignmentType(ALIGN_CENTER);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<std::string> &deco = values(styles, "text-decoration");
|
const std::string &deco = value(styles, "text-decoration");
|
||||||
for (std::vector<std::string>::const_iterator it = deco.begin(); it != deco.end(); ++it) {
|
if (deco == "underline") {
|
||||||
if (*it == "underline") {
|
|
||||||
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_UNDERLINED, true);
|
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_UNDERLINED, true);
|
||||||
} else if (*it == "line-through") {
|
} else if (deco == "line-through") {
|
||||||
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_STRIKEDTHROUGH, true);
|
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_STRIKEDTHROUGH, true);
|
||||||
} else if (*it == "none") {
|
} else if (deco == "none") {
|
||||||
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_UNDERLINED, false);
|
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_UNDERLINED, false);
|
||||||
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_STRIKEDTHROUGH, false);
|
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_STRIKEDTHROUGH, false);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<std::string> &bold = values(styles, "font-weight");
|
const std::string bold = value(styles, "font-weight");
|
||||||
if (!bold.empty()) {
|
if (!bold.empty()) {
|
||||||
int num = -1;
|
int num = -1;
|
||||||
if (bold[0] == "bold") {
|
if (bold == "bold") {
|
||||||
num = 700;
|
num = 700;
|
||||||
} else if (bold[0] == "normal") {
|
} else if (bold == "normal") {
|
||||||
num = 400;
|
num = 400;
|
||||||
} else if (bold[0] == "bolder") {
|
} else if (bold == "bolder") {
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
} else if (bold[0] == "lighter") {
|
} else if (bold == "lighter") {
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
} else {
|
} else {
|
||||||
num = ZLStringUtil::stringToInteger(bold[0], -1);
|
num = ZLStringUtil::stringToInteger(bold, -1);
|
||||||
}
|
}
|
||||||
if (num != -1) {
|
if (num != -1) {
|
||||||
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_BOLD, num >= 600);
|
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_BOLD, num >= 600);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string> &italic = values(styles, "font-style");
|
const std::string &italic = value(styles, "font-style");
|
||||||
if (!italic.empty()) {
|
if (!italic.empty()) {
|
||||||
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_ITALIC, italic[0] == "italic");
|
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_ITALIC, italic == "italic" || italic == "oblique");
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string> &variant = values(styles, "font-variant");
|
const std::string &variant = value(styles, "font-variant");
|
||||||
if (!variant.empty()) {
|
if (!variant.empty()) {
|
||||||
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_SMALLCAPS, variant[0] == "small-caps");
|
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_SMALLCAPS, variant == "small-caps");
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string> &fontFamily = values(styles, "font-family");
|
const std::string &fontFamily = value(styles, "font-family");
|
||||||
if (!fontFamily.empty() && !fontFamily[0].empty()) {
|
// TODO: split(',')
|
||||||
entry->setFontFamily(fontFamily[0]);
|
if (!fontFamily.empty()) {
|
||||||
|
entry->setFontFamily(fontFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string> &fontSize = values(styles, "font-size");
|
const std::string &fontSize = value(styles, "font-size");
|
||||||
if (!fontSize.empty()) {
|
if (!fontSize.empty()) {
|
||||||
bool doSetFontSize = true;
|
bool doSetFontSize = true;
|
||||||
short size = 100;
|
short size = 100;
|
||||||
ZLTextStyleEntry::SizeUnit unit = ZLTextStyleEntry::SIZE_UNIT_PERCENT;
|
ZLTextStyleEntry::SizeUnit unit = ZLTextStyleEntry::SIZE_UNIT_PERCENT;
|
||||||
if (fontSize[0] == "xx-small") {
|
if (fontSize == "xx-small") {
|
||||||
size = 58;
|
size = 58;
|
||||||
} else if (fontSize[0] == "x-small") {
|
} else if (fontSize == "x-small") {
|
||||||
size = 69;
|
size = 69;
|
||||||
} else if (fontSize[0] == "small") {
|
} else if (fontSize == "small") {
|
||||||
size = 83;
|
size = 83;
|
||||||
} else if (fontSize[0] == "medium") {
|
} else if (fontSize == "medium") {
|
||||||
size = 100;
|
size = 100;
|
||||||
} else if (fontSize[0] == "large") {
|
} else if (fontSize == "large") {
|
||||||
size = 120;
|
size = 120;
|
||||||
} else if (fontSize[0] == "x-large") {
|
} else if (fontSize == "x-large") {
|
||||||
size = 144;
|
size = 144;
|
||||||
} else if (fontSize[0] == "xx-large") {
|
} else if (fontSize == "xx-large") {
|
||||||
size = 173;
|
size = 173;
|
||||||
} else if (fontSize[0] == "inherit") {
|
} else if (fontSize == "inherit") {
|
||||||
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_INHERIT, true);
|
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_INHERIT, true);
|
||||||
doSetFontSize = false;
|
doSetFontSize = false;
|
||||||
} else if (fontSize[0] == "smaller") {
|
} else if (fontSize == "smaller") {
|
||||||
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_SMALLER, true);
|
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_SMALLER, true);
|
||||||
doSetFontSize = false;
|
doSetFontSize = false;
|
||||||
} else if (fontSize[0] == "larger") {
|
} else if (fontSize == "larger") {
|
||||||
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_LARGER, true);
|
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_LARGER, true);
|
||||||
doSetFontSize = false;
|
doSetFontSize = false;
|
||||||
} else if (!parseLength(fontSize[0], size, unit)) {
|
} else if (!parseLength(fontSize, size, unit)) {
|
||||||
doSetFontSize = false;
|
doSetFontSize = false;
|
||||||
}
|
}
|
||||||
if (doSetFontSize) {
|
if (doSetFontSize) {
|
||||||
|
|
|
@ -32,14 +32,14 @@
|
||||||
class StyleSheetTable {
|
class StyleSheetTable {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef std::map<std::string,std::vector<std::string> > AttributeMap;
|
typedef std::map<std::string,std::string> AttributeMap;
|
||||||
static shared_ptr<ZLTextStyleEntry> createControl(const AttributeMap &map);
|
static shared_ptr<ZLTextStyleEntry> createControl(const AttributeMap &map);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addMap(const std::string &tag, const std::string &aClass, const AttributeMap &map);
|
void addMap(const std::string &tag, const std::string &aClass, const AttributeMap &map);
|
||||||
|
|
||||||
static void setLength(ZLTextStyleEntry &entry, ZLTextStyleEntry::Feature featureId, const AttributeMap &map, const std::string &attributeName);
|
static void setLength(ZLTextStyleEntry &entry, ZLTextStyleEntry::Feature featureId, const AttributeMap &map, const std::string &attributeName);
|
||||||
static const std::vector<std::string> &values(const AttributeMap &map, const std::string &name);
|
static const std::string &value(const AttributeMap &map, const std::string &name);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool isEmpty() const;
|
bool isEmpty() const;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue