dannym
unread,Aug 12, 2010, 5:00:17 PM8/12/10Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Sign in to report message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to FBReader
Hi,
I tried your book and it indeed does have the problem.
So I checked the source code of FBReader and found why.
The CSS parser will emit ZLTextStyleEntry instances which will be
added to the model via addControl. However, ZLTextStyleEntry has a
flag which says whether or not a specific attribute has indeed be set
(I'm not sure why). So if your CSS entry has no "text-align" (which it
usually doesn't), it _will not touch the text alignment at all_. This
becomes a problem if there was an element before us (which ended
already) which did affect text alignment but our element doesn't,
hence it isn't restoring the style to its original setting.
An easy fix would be to change the CSS parser to always set text-align
to left whether it has been specified or not (1 liner workaround).
I've just checked zlibrary/text/src/model/ZLTextParagraph.cpp and
zlibrary/text/src/area/ZLTextAreaStyle.cpp.
zlibrary/text/src/style/ZLTextDecoratedStyle.cpp seems to have some
base() reference for some kind of ZLTextStyleEntry-with-holes
stacking, but for some reason it does not always work (?).
(Dirty) workaround attached.
diff -upr orig/fbreader-0.12.10/fbreader/src/formats/xhtml/
XHTMLReader.cpp fbreader-0.12.10/fbreader/src/formats/xhtml/
XHTMLReader.cpp
--- orig/fbreader-0.12.10/fbreader/src/formats/xhtml/XHTMLReader.cpp
2010-04-01 15:14:24.000000000 +0200
+++ fbreader-0.12.10/fbreader/src/formats/xhtml/XHTMLReader.cpp
2010-08-12 22:11:19.000000000 +0200
@@ -486,6 +486,20 @@ void XHTMLReader::fillTagTable() {
XHTMLReader::XHTMLReader(BookReader &modelReader) :
myModelReader(modelReader) {
}
+static shared_ptr<ZLTextStyleEntry> createBodyStyleEntry() {
+ shared_ptr<ZLTextStyleEntry> entry = new ZLTextStyleEntry();
+ //setLength
+ // TODO don't hard-code these, just move that to some central place
where it does the right thing (settings etc).
+ //entry->setFontModifier(FONT_MODIFIER_DEFAULT);
+ entry->setFontModifier(FONT_MODIFIER_BOLD, false);
+ entry->setFontModifier(FONT_MODIFIER_ITALIC, false);
+ entry->setFontModifier(FONT_MODIFIER_SMALLCAPS, false);
+ entry->setFontSizeMag(1);
+ //void setFontFamily(const std::string &fontFamily);
+ entry->setAlignmentType(ALIGN_LEFT);
+ return entry;
+}
+
bool XHTMLReader::readFile(const std::string &filePath, const
std::string &referenceName) {
myModelReader.addHyperlinkLabel(referenceName);
@@ -502,6 +516,7 @@ bool XHTMLReader::readFile(const std::st
myCSSStack.clear();
myStyleEntryStack.clear();
+ myStyleEntryStack.push_back(createBodyStyleEntry());
myStylesToRemove = 0;
return readDocument(filePath);
@@ -538,14 +553,21 @@ void XHTMLReader::startElementHandler(co
}
const int sizeBefore = myStyleEntryStack.size();
- addStyleEntry(sTag, "");
- addStyleEntry("", sClass);
- addStyleEntry(sTag, sClass);
- const char *style = attributeValue(attributes, "style");
- if (style != 0) {
- shared_ptr<ZLTextStyleEntry> entry =
myStyleParser.parseString(style);
+
+ if(strcmp(tag, "body") == 0) {
+ shared_ptr<ZLTextStyleEntry> entry = createBodyStyleEntry();
myModelReader.addControl(*entry);
myStyleEntryStack.push_back(entry);
+ } else {
+ addStyleEntry(sTag, "");
+ addStyleEntry("", sClass);
+ addStyleEntry(sTag, sClass);
+ const char *style = attributeValue(attributes, "style");
+ if (style != 0) {
+ shared_ptr<ZLTextStyleEntry> entry =
myStyleParser.parseString(style);
+ myModelReader.addControl(*entry);
+ myStyleEntryStack.push_back(entry);
+ }
}
myCSSStack.push_back(myStyleEntryStack.size() - sizeBefore);
}
@@ -559,13 +581,15 @@ void XHTMLReader::endElementHandler(cons
XHTMLTagAction *action = ourTagActions[ZLUnicodeUtil::toLower(tag)];
if (action != 0) {
- action->doAtEnd(*this);
+ //action->doAtEnd(*this);
myNewParagraphInProgress = false;
}
for (; myStylesToRemove > 0; --myStylesToRemove) {
myStyleEntryStack.pop_back();
}
+
+ replayStyleEntryStack();
if (myDoPageBreakAfterStack.back()) {
myModelReader.insertEndOfSectionParagraph();
@@ -573,6 +597,13 @@ void XHTMLReader::endElementHandler(cons
myDoPageBreakAfterStack.pop_back();
}
+void XHTMLReader::replayStyleEntryStack() {
+ std::vector<shared_ptr<ZLTextStyleEntry> >::const_iterator iter_end
= myStyleEntryStack.end();
+ for(std::vector<shared_ptr<ZLTextStyleEntry> >::const_iterator iter
= myStyleEntryStack.begin(); iter != iter_end; ++iter) {
+ myModelReader.addControl(**iter);
+ }
+}
+
void XHTMLReader::beginParagraph() {
myCurrentParagraphIsEmpty = true;
myModelReader.beginParagraph();
@@ -612,10 +643,9 @@ void XHTMLReader::endParagraph() {
myModelReader.addControl(blockingEntry);
}
for (; myStylesToRemove > 0; --myStylesToRemove) {
- myModelReader.addControl(*myStyleEntryStack.back());
myStyleEntryStack.pop_back();
}
- myModelReader.endParagraph();
+ replayStyleEntryStack();
}
void XHTMLReader::characterDataHandler(const char *text, size_t len)
{
Nur in fbreader-0.12.10/fbreader/src/formats/xhtml/: XHTMLReader.d.
diff -upr orig/fbreader-0.12.10/fbreader/src/formats/xhtml/
XHTMLReader.h fbreader-0.12.10/fbreader/src/formats/xhtml/
XHTMLReader.h
--- orig/fbreader-0.12.10/fbreader/src/formats/xhtml/XHTMLReader.h
2010-04-01 15:14:24.000000000 +0200
+++ fbreader-0.12.10/fbreader/src/formats/xhtml/XHTMLReader.h
2010-08-12 22:10:41.000000000 +0200
@@ -72,6 +72,7 @@ private:
void beginParagraph();
void endParagraph();
void addStyleEntry(const std::string tag, const std::string aClass);
+ void replayStyleEntryStack();
private:
BookReader &myModelReader;
Nur in fbreader-0.12.10/fbreader/src/formats/xhtml/: XHTMLReader.o.