diff --git a/jni/NativeFormats/fbreader/src/formats/css/StyleSheetParser.cpp b/jni/NativeFormats/fbreader/src/formats/css/StyleSheetParser.cpp index 964917956..c83c3f519 100644 --- a/jni/NativeFormats/fbreader/src/formats/css/StyleSheetParser.cpp +++ b/jni/NativeFormats/fbreader/src/formats/css/StyleSheetParser.cpp @@ -20,13 +20,15 @@ #include #include -#include +#include #include +#include #include #include "StyleSheetParser.h" +#include "../util/MiscUtil.h" -StyleSheetParser::StyleSheetParser() { +StyleSheetParser::StyleSheetParser(const std::string &pathPrefix) : myPathPrefix(pathPrefix) { reset(); } @@ -179,6 +181,9 @@ void StyleSheetParser::processWordWithoutComments(const std::string &word) { } } +StyleSheetSingleStyleParser::StyleSheetSingleStyleParser(const std::string &pathPrefix) : StyleSheetParser(pathPrefix) { +} + shared_ptr StyleSheetSingleStyleParser::parseString(const char *text) { myReadState = WAITING_FOR_ATTRIBUTE; parse(text, std::strlen(text), true); @@ -187,6 +192,9 @@ shared_ptr StyleSheetSingleStyleParser::parseString(const char return control; } +StyleSheetMultiStyleParser::StyleSheetMultiStyleParser(const std::string &pathPrefix) : StyleSheetParser(pathPrefix) { +} + void StyleSheetMultiStyleParser::storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map) { std::string s = selector; ZLStringUtil::stripWhiteSpaces(s); @@ -215,8 +223,46 @@ void StyleSheetMultiStyleParser::storeData(const std::string &selector, const St } } -void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const StyleSheetTable::AttributeMap&) { +static std::string firstValue(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]; +} + +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"); + if (family.empty()) { + ZLLogger::Instance().println("FONT", "Font family not specified in @font-face entry"); + return; + } + const StyleSheetTable::AttributeMap::const_iterator it = attributes.find("src"); + std::string url; + if (it != attributes.end()) { + for (std::vector::const_iterator jt = it->second.begin(); jt != it->second.end(); ++jt) { + if (ZLStringUtil::stringStartsWith(*jt, "url(") && + ZLStringUtil::stringEndsWith(*jt, ")")) { + url = jt->substr(4, jt->size() - 5); + if (url.size() > 2 && url[0] == url[url.size() - 1]) { + if (url[0] == '\'' || url[0] == '"') { + url = url.substr(1, url.size() - 2); + } + } + break; + } + } + } + if (url.empty()) { + ZLLogger::Instance().println("FONT", "Source not specified for " + family); + return; + } + const ZLFile fontFile(myPathPrefix + MiscUtil::decodeHtmlURL(url)); + const bool bold = firstValue(attributes, "font-weight") == "bold"; + const bool italic = firstValue(attributes, "font-style") == "italic"; + ZLLogger::Instance().println("FONT", family + " => " + fontFile.path()); } } @@ -235,13 +281,16 @@ void StyleSheetMultiStyleParser::parseStream(ZLInputStream &stream) { } } -StyleSheetTableParser::StyleSheetTableParser(StyleSheetTable &table) : myTable(table) { +StyleSheetTableParser::StyleSheetTableParser(const std::string &pathPrefix, StyleSheetTable &table) : StyleSheetMultiStyleParser(pathPrefix), myTable(table) { } void StyleSheetTableParser::store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) { myTable.addMap(tag, aClass, map); } +StyleSheetParserWithCache::StyleSheetParserWithCache(const std::string &pathPrefix) : StyleSheetMultiStyleParser(pathPrefix) { +} + void StyleSheetParserWithCache::store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) { myEntries.push_back(new Entry(tag, aClass, map)); } diff --git a/jni/NativeFormats/fbreader/src/formats/css/StyleSheetParser.h b/jni/NativeFormats/fbreader/src/formats/css/StyleSheetParser.h index 3f23a61eb..ab7fbd7ce 100644 --- a/jni/NativeFormats/fbreader/src/formats/css/StyleSheetParser.h +++ b/jni/NativeFormats/fbreader/src/formats/css/StyleSheetParser.h @@ -29,7 +29,7 @@ class ZLInputStream; class StyleSheetParser { protected: - StyleSheetParser(); + StyleSheetParser(const std::string &pathPrefix); public: virtual ~StyleSheetParser(); @@ -45,6 +45,9 @@ private: void processWordWithoutComments(const std::string &word); void processControl(const char control); +protected: + const std::string myPathPrefix; + private: std::string myWord; std::string myAttributeName; @@ -65,11 +68,15 @@ friend class StyleSheetSingleStyleParser; class StyleSheetSingleStyleParser : public StyleSheetParser { public: + StyleSheetSingleStyleParser(const std::string &pathPrefix); shared_ptr parseString(const char *text); }; class StyleSheetMultiStyleParser : public StyleSheetParser { +protected: + StyleSheetMultiStyleParser(const std::string &pathPrefix); + public: void parseStream(ZLInputStream &stream); @@ -84,7 +91,7 @@ private: class StyleSheetTableParser : public StyleSheetMultiStyleParser { public: - StyleSheetTableParser(StyleSheetTable &table); + StyleSheetTableParser(const std::string &pathPrexix, StyleSheetTable &table); private: void store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map); @@ -105,6 +112,7 @@ private: }; public: + StyleSheetParserWithCache(const std::string &pathPrefix); void applyToTable(StyleSheetTable &table) const; private: diff --git a/jni/NativeFormats/fbreader/src/formats/html/HtmlBookReader.cpp b/jni/NativeFormats/fbreader/src/formats/html/HtmlBookReader.cpp index 009591af7..862b73d5b 100644 --- a/jni/NativeFormats/fbreader/src/formats/html/HtmlBookReader.cpp +++ b/jni/NativeFormats/fbreader/src/formats/html/HtmlBookReader.cpp @@ -274,7 +274,7 @@ HtmlStyleTagAction::HtmlStyleTagAction(HtmlBookReader &reader) : HtmlTagAction(r } void HtmlStyleTagAction::run(const HtmlReader::HtmlTag &tag) { - myReader.myStyleSheetParser = tag.Start ? new StyleSheetTableParser(myReader.myStyleSheetTable) : 0; + myReader.myStyleSheetParser = tag.Start ? new StyleSheetTableParser(myReader.myBaseDirPath, myReader.myStyleSheetTable) : 0; /* if (!tag.Start) { myReader.myStyleSheetTable.dump(); diff --git a/jni/NativeFormats/fbreader/src/formats/xhtml/XHTMLReader.cpp b/jni/NativeFormats/fbreader/src/formats/xhtml/XHTMLReader.cpp index 65cc8dab0..b3043597c 100644 --- a/jni/NativeFormats/fbreader/src/formats/xhtml/XHTMLReader.cpp +++ b/jni/NativeFormats/fbreader/src/formats/xhtml/XHTMLReader.cpp @@ -229,7 +229,7 @@ void XHTMLTagStyleAction::doAtStart(XHTMLReader &reader, const char **xmlattribu if (reader.myReadState == XHTML_READ_NOTHING) { reader.myReadState = XHTML_READ_STYLE; - reader.myTableParser = new StyleSheetTableParser(reader.myStyleSheetTable); + reader.myTableParser = new StyleSheetTableParser(reader.myPathPrefix, reader.myStyleSheetTable); ZLLogger::Instance().println("CSS", "parsing style tag content"); } } @@ -259,14 +259,15 @@ void XHTMLTagLinkAction::doAtStart(XHTMLReader &reader, const char **xmlattribut return; } - const std::string cssFilePath = reader.myPathPrefix + MiscUtil::decodeHtmlURL(href); + std::string cssFilePath = reader.myPathPrefix + MiscUtil::decodeHtmlURL(href); //ZLLogger::Instance().registerClass("CSS"); ZLLogger::Instance().println("CSS", "style file: " + cssFilePath); const ZLFile cssFile(cssFilePath); - shared_ptr parser = reader.myFileParsers[cssFile.path()]; + cssFilePath = cssFile.path(); + shared_ptr parser = reader.myFileParsers[cssFilePath]; if (parser.isNull()) { - parser = new StyleSheetParserWithCache(); - reader.myFileParsers[cssFile.path()] = parser; + parser = new StyleSheetParserWithCache(MiscUtil::htmlDirectoryPrefix(cssFilePath)); + reader.myFileParsers[cssFilePath] = parser; ZLLogger::Instance().println("CSS", "creating stream"); shared_ptr cssStream = ZLFile(cssFilePath).inputStream(reader.myEncryptionMap); if (!cssStream.isNull()) { @@ -639,7 +640,7 @@ bool XHTMLReader::readFile(const ZLFile &file, const std::string &referenceName) myStylesToRemove = 0; myDoPageBreakAfterStack.clear(); - myStyleParser = new StyleSheetSingleStyleParser(); + myStyleParser = new StyleSheetSingleStyleParser(myPathPrefix); myTableParser.reset(); return readDocument(file.inputStream(myEncryptionMap)); diff --git a/jni/NativeFormats/zlibrary/core/src/util/ZLStringUtil.cpp b/jni/NativeFormats/zlibrary/core/src/util/ZLStringUtil.cpp index 4ec3b1fff..a90f55f51 100644 --- a/jni/NativeFormats/zlibrary/core/src/util/ZLStringUtil.cpp +++ b/jni/NativeFormats/zlibrary/core/src/util/ZLStringUtil.cpp @@ -103,6 +103,19 @@ std::vector ZLStringUtil::split(const std::string &str, const std:: return result; } +std::string ZLStringUtil::join(const std::vector &data, const std::string &delimiter) { + std::string joined; + bool addDelimiter = false; + for (std::vector::const_iterator it = data.begin(); it != data.end(); ++it) { + if (addDelimiter) { + joined += delimiter; + } + joined += *it; + addDelimiter = true; + } + return joined; +} + std::string ZLStringUtil::printf(const std::string &format, const std::string &arg0) { int index = format.find("%s"); if (index == -1) { diff --git a/jni/NativeFormats/zlibrary/core/src/util/ZLStringUtil.h b/jni/NativeFormats/zlibrary/core/src/util/ZLStringUtil.h index 0b54092b1..59c254ca9 100644 --- a/jni/NativeFormats/zlibrary/core/src/util/ZLStringUtil.h +++ b/jni/NativeFormats/zlibrary/core/src/util/ZLStringUtil.h @@ -37,6 +37,7 @@ public: static void stripWhiteSpaces(std::string &str); static std::vector split(const std::string &str, const std::string &delimiter); + static std::string join(const std::vector &data, const std::string &delimiter); static std::string printf(const std::string &format, const std::string &arg0);