From e8914786d1b75f8c48d8f5990e1eefd77f411d7b Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Fri, 3 Jul 2015 01:42:03 +0300 Subject: [PATCH] Create one combined CSS entry per XHTML element --- .../src/formats/xhtml/XHTMLReader.cpp | 26 +++++++++++-------- .../fbreader/src/formats/xhtml/XHTMLReader.h | 2 +- .../text/src/model/ZLTextParagraph.cpp | 22 ++++++++++++++++ .../zlibrary/text/src/model/ZLTextParagraph.h | 4 ++- 4 files changed, 41 insertions(+), 13 deletions(-) diff --git a/fbreader/fbreader/fbreader/src/formats/xhtml/XHTMLReader.cpp b/fbreader/fbreader/fbreader/src/formats/xhtml/XHTMLReader.cpp index ff3af24..ba86d22 100644 --- a/fbreader/fbreader/fbreader/src/formats/xhtml/XHTMLReader.cpp +++ b/fbreader/fbreader/fbreader/src/formats/xhtml/XHTMLReader.cpp @@ -506,12 +506,12 @@ bool XHTMLReader::readFile(const ZLFile &file, const std::string &referenceName) return readDocument(file); } -void XHTMLReader::addStyleEntry(const std::string &tag, const std::string &aClass) { - shared_ptr entry = myStyleSheetTable.control(tag, aClass); - if (!entry.isNull()) { - myModelReader.addControl(*entry); - myStyleEntryStack.push_back(entry); +shared_ptr XHTMLReader::addStyleEntry(shared_ptr entry, shared_ptr styleEntry) { + if (!styleEntry.isNull() && !styleEntry->isEmpty()) { + if (entry.isNull()) entry = new ZLTextStyleEntry; + entry->apply(*styleEntry); } + return entry; } void XHTMLReader::startElementHandler(const char *tag, const char **attributes) { @@ -536,17 +536,21 @@ void XHTMLReader::startElementHandler(const char *tag, const char **attributes) action->doAtStart(*this, attributes); } - const int sizeBefore = myStyleEntryStack.size(); - addStyleEntry(sTag, ""); - addStyleEntry("", sClass); - addStyleEntry(sTag, sClass); + shared_ptr entry; + entry = addStyleEntry(entry, myStyleSheetTable.control(sTag, "")); + entry = addStyleEntry(entry, myStyleSheetTable.control("", sClass)); + entry = addStyleEntry(entry, myStyleSheetTable.control(sTag, sClass)); const char *style = attributeValue(attributes, "style"); if (style != 0) { - shared_ptr entry = myStyleParser.parseString(style); + entry = addStyleEntry(entry, myStyleParser.parseString(style)); + } + if (!entry.isNull()) { myModelReader.addControl(*entry); myStyleEntryStack.push_back(entry); + myCSSStack.push_back(1); + } else { + myCSSStack.push_back(0); } - myCSSStack.push_back(myStyleEntryStack.size() - sizeBefore); } void XHTMLReader::endElementHandler(const char *tag) { diff --git a/fbreader/fbreader/fbreader/src/formats/xhtml/XHTMLReader.h b/fbreader/fbreader/fbreader/src/formats/xhtml/XHTMLReader.h index b5c7a2d..af96cea 100644 --- a/fbreader/fbreader/fbreader/src/formats/xhtml/XHTMLReader.h +++ b/fbreader/fbreader/fbreader/src/formats/xhtml/XHTMLReader.h @@ -73,7 +73,7 @@ private: void beginParagraph(); void endParagraph(); - void addStyleEntry(const std::string &tag, const std::string &aClass); + static shared_ptr addStyleEntry(shared_ptr entry, shared_ptr styleEntry); private: BookReader &myModelReader; diff --git a/fbreader/fbreader/zlibrary/text/src/model/ZLTextParagraph.cpp b/fbreader/fbreader/zlibrary/text/src/model/ZLTextParagraph.cpp index 3df54de..d7ecf4c 100644 --- a/fbreader/fbreader/zlibrary/text/src/model/ZLTextParagraph.cpp +++ b/fbreader/fbreader/zlibrary/text/src/model/ZLTextParagraph.cpp @@ -74,6 +74,28 @@ ZLTextStyleEntry::ZLTextStyleEntry(char *address) { } } +void ZLTextStyleEntry::apply(const ZLTextStyleEntry &entry) { + for (int i = 0; i < NUMBER_OF_LENGTHS; ++i) { + if (entry.lengthSupported((Length)i)) { + myLengths[i] = entry.myLengths[i]; + myMask |= 1 << i; + } + } + if (entry.alignmentTypeSupported()) { + setAlignmentType(entry.alignmentType()); + } + if (entry.mySupportedFontModifier) { + myFontModifier &= ~entry.mySupportedFontModifier; + myFontModifier |= (entry.myFontModifier & entry.mySupportedFontModifier); + } + if (entry.fontSizeSupported()) { + setFontSizeMag(entry.fontSizeMag()); + } + if (entry.fontFamilySupported()) { + setFontFamily(entry.fontFamily()); + } +} + const shared_ptr ZLTextParagraph::Iterator::entry() const { if (myEntry.isNull()) { switch (*myPointer) { diff --git a/fbreader/fbreader/zlibrary/text/src/model/ZLTextParagraph.h b/fbreader/fbreader/zlibrary/text/src/model/ZLTextParagraph.h index 7a8caaa..0b4059d 100644 --- a/fbreader/fbreader/zlibrary/text/src/model/ZLTextParagraph.h +++ b/fbreader/fbreader/zlibrary/text/src/model/ZLTextParagraph.h @@ -96,6 +96,8 @@ public: ZLTextStyleEntry(char *address); ~ZLTextStyleEntry(); + void apply(const ZLTextStyleEntry &entry); + bool isEmpty() const; bool lengthSupported(Length name) const; @@ -336,7 +338,7 @@ inline ZLTextStyleEntry::~ZLTextStyleEntry() {} inline ZLTextStyleEntry::Metrics::Metrics(int fontSize, int fontXHeight, int fullWidth, int fullHeight) : FontSize(fontSize), FontXHeight(fontXHeight), FullWidth(fullWidth), FullHeight(fullHeight) {} -inline bool ZLTextStyleEntry::isEmpty() const { return myMask == 0; } +inline bool ZLTextStyleEntry::isEmpty() const { return myMask == 0 && mySupportedFontModifier == 0; } inline bool ZLTextStyleEntry::lengthSupported(Length name) const { return (myMask & (1 << name)) != 0; } inline void ZLTextStyleEntry::setLength(Length name, short length, SizeUnit unit) {