From ccdb527030d173f79d9ae6bf8e7261fda9d68e9e Mon Sep 17 00:00:00 2001 From: Nikolay Pultsin Date: Sun, 30 Mar 2014 03:08:32 +0300 Subject: [PATCH] do not split css values in parser --- .../src/formats/css/StyleSheetParser.cpp | 25 ++-- .../src/formats/css/StyleSheetTable.cpp | 138 ++++++++---------- .../src/formats/css/StyleSheetTable.h | 4 +- 3 files changed, 75 insertions(+), 92 deletions(-) diff --git a/jni/NativeFormats/fbreader/src/formats/css/StyleSheetParser.cpp b/jni/NativeFormats/fbreader/src/formats/css/StyleSheetParser.cpp index ba6b41d8c..39c52f04b 100644 --- a/jni/NativeFormats/fbreader/src/formats/css/StyleSheetParser.cpp +++ b/jni/NativeFormats/fbreader/src/formats/css/StyleSheetParser.cpp @@ -72,7 +72,7 @@ void StyleSheetParser::parse(const char *text, int len, bool final) { const char *start = text; const char *end = text + len; for (const char *ptr = start; ptr != end; ++ptr) { - if (std::isspace(*ptr)) { + if (myReadState != ATTRIBUTE_VALUE && std::isspace(*ptr)) { if (start != ptr) { myWord.append(start, ptr - start); } @@ -221,15 +221,8 @@ void StyleSheetParser::processWord(const std::string &word) { myMap[myAttributeName].clear(); break; case ATTRIBUTE_VALUE: - { - 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); - } + myMap[myAttributeName] = word; break; - } } } @@ -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); if (it == map.end() || it->second.empty()) { return std::string(); } - return it->second[0]; + return it->second; } void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &attributes) { ZLLogger::Instance().registerClass("FONT"); if (name == "@font-face") { - const std::string family = firstValue(attributes, "font-family"); + const std::string family = value(attributes, "font-family"); if (family.empty()) { ZLLogger::Instance().println("FONT", "Font family not specified in @font-face entry"); return; @@ -294,7 +287,9 @@ void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const St const StyleSheetTable::AttributeMap::const_iterator it = attributes.find("src"); std::string path; if (it != attributes.end()) { - for (std::vector::const_iterator jt = it->second.begin(); jt != it->second.end(); ++jt) { + // TODO: better split + const std::vector ids = ZLStringUtil::split(it->second, " "); + for (std::vector::const_iterator jt = ids.begin(); jt != ids.end(); ++jt) { if (ZLStringUtil::stringStartsWith(*jt, "url(") && ZLStringUtil::stringEndsWith(*jt, ")")) { path = url2FullPath(*jt); @@ -308,8 +303,8 @@ void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const St } myFontMap.appendFontFace( family, - firstValue(attributes, "font-weight"), - firstValue(attributes, "font-style"), + value(attributes, "font-weight"), + value(attributes, "font-style"), path ); } diff --git a/jni/NativeFormats/fbreader/src/formats/css/StyleSheetTable.cpp b/jni/NativeFormats/fbreader/src/formats/css/StyleSheetTable.cpp index 1d6e11cea..1f5f6618d 100644 --- a/jni/NativeFormats/fbreader/src/formats/css/StyleSheetTable.cpp +++ b/jni/NativeFormats/fbreader/src/formats/css/StyleSheetTable.cpp @@ -29,27 +29,21 @@ bool StyleSheetTable::isEmpty() const { void StyleSheetTable::addMap(const std::string &tag, const std::string &aClass, const AttributeMap &map) { if ((!tag.empty() || !aClass.empty()) && !map.empty()) { - Key key(tag, aClass); + const Key key(tag, aClass); myControlMap[key] = createControl(map); - const std::vector &pbb = values(map, "page-break-before"); - if (!pbb.empty()) { - if ((pbb[0] == "always") || - (pbb[0] == "left") || - (pbb[0] == "right")) { - myPageBreakBeforeMap[key] = true; - } else if (pbb[0] == "avoid") { - myPageBreakBeforeMap[key] = false; - } + + const std::string &pbb = value(map, "page-break-before"); + if (pbb == "always" || pbb == "left" || pbb == "right") { + myPageBreakBeforeMap[key] = true; + } else if (pbb == "avoid") { + myPageBreakBeforeMap[key] = false; } - const std::vector &pba = values(map, "page-break-after"); - if (!pba.empty()) { - if ((pba[0] == "always") || - (pba[0] == "left") || - (pba[0] == "right")) { - myPageBreakAfterMap[key] = true; - } else if (pba[0] == "avoid") { - myPageBreakAfterMap[key] = false; - } + + const std::string &pba = value(map, "page-break-after"); + if (pba == "always" || pba == "left" || pba == "right") { + myPageBreakAfterMap[key] = true; + } else if (pba == "avoid") { + myPageBreakAfterMap[key] = false; } } } @@ -84,13 +78,10 @@ void StyleSheetTable::setLength(ZLTextStyleEntry &entry, ZLTextStyleEntry::Featu if (it == map.end()) { return; } - const std::vector &values = it->second; - if (!values.empty() && !values[0].empty()) { - short size; - ZLTextStyleEntry::SizeUnit unit; - if (parseLength(values[0], size, unit)) { - entry.setLength(featureId, size, unit); - } + short size; + ZLTextStyleEntry::SizeUnit unit; + if (parseLength(it->second, size, unit)) { + entry.setLength(featureId, size, unit); } } @@ -138,106 +129,103 @@ shared_ptr StyleSheetTable::control(const std::string &tag, co return (it != myControlMap.end()) ? it->second : 0; } -const std::vector &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); if (it != map.end()) { return it->second; } - static const std::vector emptyVector; - return emptyVector; + static const std::string emptyString; + return emptyString; } shared_ptr StyleSheetTable::createControl(const AttributeMap &styles) { shared_ptr entry = new ZLTextStyleEntry(ZLTextStyleEntry::STYLE_CSS_ENTRY); - const std::vector &alignment = values(styles, "text-align"); - if (!alignment.empty()) { - if (alignment[0] == "justify") { - entry->setAlignmentType(ALIGN_JUSTIFY); - } else if (alignment[0] == "left") { - entry->setAlignmentType(ALIGN_LEFT); - } else if (alignment[0] == "right") { - entry->setAlignmentType(ALIGN_RIGHT); - } else if (alignment[0] == "center") { - entry->setAlignmentType(ALIGN_CENTER); - } + const std::string &alignment = value(styles, "text-align"); + if (alignment == "justify") { + entry->setAlignmentType(ALIGN_JUSTIFY); + } else if (alignment == "left") { + entry->setAlignmentType(ALIGN_LEFT); + } else if (alignment == "right") { + entry->setAlignmentType(ALIGN_RIGHT); + } else if (alignment == "center") { + entry->setAlignmentType(ALIGN_CENTER); } - const std::vector &deco = values(styles, "text-decoration"); - for (std::vector::const_iterator it = deco.begin(); it != deco.end(); ++it) { - if (*it == "underline") { - entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_UNDERLINED, true); - } else if (*it == "line-through") { - entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_STRIKEDTHROUGH, true); - } else if (*it == "none") { - entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_UNDERLINED, false); - entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_STRIKEDTHROUGH, false); - } + const std::string &deco = value(styles, "text-decoration"); + if (deco == "underline") { + entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_UNDERLINED, true); + } else if (deco == "line-through") { + entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_STRIKEDTHROUGH, true); + } else if (deco == "none") { + entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_UNDERLINED, false); + entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_STRIKEDTHROUGH, false); } - const std::vector &bold = values(styles, "font-weight"); + const std::string bold = value(styles, "font-weight"); if (!bold.empty()) { int num = -1; - if (bold[0] == "bold") { + if (bold == "bold") { num = 700; - } else if (bold[0] == "normal") { + } else if (bold == "normal") { num = 400; - } else if (bold[0] == "bolder") { + } else if (bold == "bolder") { // TODO: implement - } else if (bold[0] == "lighter") { + } else if (bold == "lighter") { // TODO: implement } else { - num = ZLStringUtil::stringToInteger(bold[0], -1); + num = ZLStringUtil::stringToInteger(bold, -1); } if (num != -1) { entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_BOLD, num >= 600); } } - const std::vector &italic = values(styles, "font-style"); + const std::string &italic = value(styles, "font-style"); 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 &variant = values(styles, "font-variant"); + const std::string &variant = value(styles, "font-variant"); 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 &fontFamily = values(styles, "font-family"); - if (!fontFamily.empty() && !fontFamily[0].empty()) { - entry->setFontFamily(fontFamily[0]); + const std::string &fontFamily = value(styles, "font-family"); + // TODO: split(',') + if (!fontFamily.empty()) { + entry->setFontFamily(fontFamily); } - const std::vector &fontSize = values(styles, "font-size"); + const std::string &fontSize = value(styles, "font-size"); if (!fontSize.empty()) { bool doSetFontSize = true; short size = 100; ZLTextStyleEntry::SizeUnit unit = ZLTextStyleEntry::SIZE_UNIT_PERCENT; - if (fontSize[0] == "xx-small") { + if (fontSize == "xx-small") { size = 58; - } else if (fontSize[0] == "x-small") { + } else if (fontSize == "x-small") { size = 69; - } else if (fontSize[0] == "small") { + } else if (fontSize == "small") { size = 83; - } else if (fontSize[0] == "medium") { + } else if (fontSize == "medium") { size = 100; - } else if (fontSize[0] == "large") { + } else if (fontSize == "large") { size = 120; - } else if (fontSize[0] == "x-large") { + } else if (fontSize == "x-large") { size = 144; - } else if (fontSize[0] == "xx-large") { + } else if (fontSize == "xx-large") { size = 173; - } else if (fontSize[0] == "inherit") { + } else if (fontSize == "inherit") { entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_INHERIT, true); doSetFontSize = false; - } else if (fontSize[0] == "smaller") { + } else if (fontSize == "smaller") { entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_SMALLER, true); doSetFontSize = false; - } else if (fontSize[0] == "larger") { + } else if (fontSize == "larger") { entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_LARGER, true); doSetFontSize = false; - } else if (!parseLength(fontSize[0], size, unit)) { + } else if (!parseLength(fontSize, size, unit)) { doSetFontSize = false; } if (doSetFontSize) { diff --git a/jni/NativeFormats/fbreader/src/formats/css/StyleSheetTable.h b/jni/NativeFormats/fbreader/src/formats/css/StyleSheetTable.h index 5ebbb47de..a7c1d623c 100644 --- a/jni/NativeFormats/fbreader/src/formats/css/StyleSheetTable.h +++ b/jni/NativeFormats/fbreader/src/formats/css/StyleSheetTable.h @@ -32,14 +32,14 @@ class StyleSheetTable { public: - typedef std::map > AttributeMap; + typedef std::map AttributeMap; static shared_ptr createControl(const AttributeMap &map); private: 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 const std::vector &values(const AttributeMap &map, const std::string &name); + static const std::string &value(const AttributeMap &map, const std::string &name); public: bool isEmpty() const;