1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-04 10:19:33 +02:00

'padding' and 'padding-*' CSS property support

This commit is contained in:
Nikolay Pultsin 2014-11-08 04:58:56 +00:00
parent d73f7816cf
commit 643f5a345c
24 changed files with 258 additions and 101 deletions

View file

@ -8,6 +8,9 @@
* (planned) Fixed authors list/tags list editing * (planned) Fixed authors list/tags list editing
* (planned) CSS selectors priority * (planned) CSS selectors priority
===== 2.2 beta 3 (Nov ??, 2014) =====
* Added 'padding' and 'padding-*' CSS property support
===== 2.2 beta 2 (Nov 02, 2014) ===== ===== 2.2 beta 2 (Nov 02, 2014) =====
* Added '*' selector support in CSS * Added '*' selector support in CSS
* Optimised combined selectors processing * Optimised combined selectors processing

View file

@ -123,17 +123,17 @@ void BookReader::addControl(FBTextKind kind, bool start) {
} }
} }
void BookReader::addStyleEntry(const ZLTextStyleEntry &entry, const std::vector<std::string> &fontFamilies) { void BookReader::addStyleEntry(const ZLTextStyleEntry &entry, const std::vector<std::string> &fontFamilies, unsigned char depth) {
if (paragraphIsOpen()) { if (paragraphIsOpen()) {
flushTextBufferToParagraph(); flushTextBufferToParagraph();
myCurrentTextModel->addStyleEntry(entry, fontFamilies); myCurrentTextModel->addStyleEntry(entry, fontFamilies, depth);
} }
} }
void BookReader::addStyleEntry(const ZLTextStyleEntry &entry) { void BookReader::addStyleEntry(const ZLTextStyleEntry &entry, unsigned char depth) {
if (paragraphIsOpen()) { if (paragraphIsOpen()) {
flushTextBufferToParagraph(); flushTextBufferToParagraph();
myCurrentTextModel->addStyleEntry(entry); myCurrentTextModel->addStyleEntry(entry, depth);
} }
} }

View file

@ -61,8 +61,8 @@ public:
void endParagraph(); void endParagraph();
bool paragraphIsOpen() const; bool paragraphIsOpen() const;
void addControl(FBTextKind kind, bool start); void addControl(FBTextKind kind, bool start);
void addStyleEntry(const ZLTextStyleEntry &entry); void addStyleEntry(const ZLTextStyleEntry &entry, unsigned char depth);
void addStyleEntry(const ZLTextStyleEntry &entry, const std::vector<std::string> &fontFamilies); void addStyleEntry(const ZLTextStyleEntry &entry, const std::vector<std::string> &fontFamilies, unsigned char depth);
void addStyleCloseEntry(); void addStyleCloseEntry();
void addHyperlinkControl(FBTextKind kind, const std::string &label); void addHyperlinkControl(FBTextKind kind, const std::string &label);
void addHyperlinkLabel(const std::string &label); void addHyperlinkLabel(const std::string &label);

View file

@ -279,12 +279,35 @@ shared_ptr<ZLTextStyleEntry> StyleSheetTable::createOrUpdateControl(const Attrib
} }
} }
::trySetLength(*entry, ZLTextStyleEntry::LENGTH_SPACE_BEFORE, split[0]); ::trySetLength(*entry, ZLTextStyleEntry::LENGTH_SPACE_BEFORE, split[0]);
::trySetLength(*entry, ZLTextStyleEntry::LENGTH_RIGHT_INDENT, split[1]); ::trySetLength(*entry, ZLTextStyleEntry::LENGTH_MARGIN_RIGHT, split[1]);
::trySetLength(*entry, ZLTextStyleEntry::LENGTH_SPACE_AFTER, split[2]); ::trySetLength(*entry, ZLTextStyleEntry::LENGTH_SPACE_AFTER, split[2]);
::trySetLength(*entry, ZLTextStyleEntry::LENGTH_LEFT_INDENT, split[3]); ::trySetLength(*entry, ZLTextStyleEntry::LENGTH_MARGIN_LEFT, split[3]);
} }
setLength(*entry, ZLTextStyleEntry::LENGTH_LEFT_INDENT, styles, "margin-left"); const std::string padding = value(styles, "padding");
setLength(*entry, ZLTextStyleEntry::LENGTH_RIGHT_INDENT, styles, "margin-right"); if (!padding.empty()) {
std::vector<std::string> split = ZLStringUtil::split(padding, " ", true);
if (split.size() > 0) {
switch (split.size()) {
case 1:
split.push_back(split[0]);
// go through
case 2:
split.push_back(split[0]);
// go through
case 3:
split.push_back(split[1]);
break;
}
}
::trySetLength(*entry, ZLTextStyleEntry::LENGTH_SPACE_BEFORE, split[0]);
::trySetLength(*entry, ZLTextStyleEntry::LENGTH_PADDING_RIGHT, split[1]);
::trySetLength(*entry, ZLTextStyleEntry::LENGTH_SPACE_AFTER, split[2]);
::trySetLength(*entry, ZLTextStyleEntry::LENGTH_PADDING_LEFT, split[3]);
}
setLength(*entry, ZLTextStyleEntry::LENGTH_MARGIN_LEFT, styles, "margin-left");
setLength(*entry, ZLTextStyleEntry::LENGTH_MARGIN_RIGHT, styles, "margin-right");
setLength(*entry, ZLTextStyleEntry::LENGTH_PADDING_LEFT, styles, "padding-left");
setLength(*entry, ZLTextStyleEntry::LENGTH_PADDING_RIGHT, styles, "padding-right");
setLength(*entry, ZLTextStyleEntry::LENGTH_FIRST_LINE_INDENT, styles, "text-indent"); setLength(*entry, ZLTextStyleEntry::LENGTH_FIRST_LINE_INDENT, styles, "text-indent");
setLength(*entry, ZLTextStyleEntry::LENGTH_SPACE_BEFORE, styles, "margin-top"); setLength(*entry, ZLTextStyleEntry::LENGTH_SPACE_BEFORE, styles, "margin-top");
setLength(*entry, ZLTextStyleEntry::LENGTH_SPACE_BEFORE, styles, "padding-top"); setLength(*entry, ZLTextStyleEntry::LENGTH_SPACE_BEFORE, styles, "padding-top");

View file

@ -87,7 +87,7 @@ void DocBookReader::handleHardLinebreak() {
} }
myModelReader.beginParagraph(); myModelReader.beginParagraph();
if (!myCurrentStyleEntry.isNull()) { if (!myCurrentStyleEntry.isNull()) {
myModelReader.addStyleEntry(*myCurrentStyleEntry); myModelReader.addStyleEntry(*myCurrentStyleEntry, 0);
} }
for (std::size_t i = 0; i < myKindStack.size(); ++i) { for (std::size_t i = 0; i < myKindStack.size(); ++i) {
myModelReader.addControl(myKindStack.at(i), true); myModelReader.addControl(myKindStack.at(i), true);
@ -276,7 +276,7 @@ void DocBookReader::handleParagraphStyle(const OleMainStream::Style &styleInfo)
break; break;
} }
myCurrentStyleEntry = entry; myCurrentStyleEntry = entry;
myModelReader.addStyleEntry(*myCurrentStyleEntry); myModelReader.addStyleEntry(*myCurrentStyleEntry, 0);
// we should have the same font style, as for the previous paragraph, // we should have the same font style, as for the previous paragraph,
// if it has the same StyleIdCurrent // if it has the same StyleIdCurrent

View file

@ -465,11 +465,12 @@ bool HtmlBookReader::tagHandler(const HtmlTag &tag) {
if (tag.Start) { if (tag.Start) {
for (std::vector<shared_ptr<TagData> >::const_iterator it = myTagDataStack.begin(); it != myTagDataStack.end(); ++it) { for (std::vector<shared_ptr<TagData> >::const_iterator it = myTagDataStack.begin(); it != myTagDataStack.end(); ++it) {
const unsigned char depth = it - myTagDataStack.begin() + 1;
const std::vector<shared_ptr<ZLTextStyleEntry> > &entries = (*it)->StyleEntries; const std::vector<shared_ptr<ZLTextStyleEntry> > &entries = (*it)->StyleEntries;
const bool inheritedOnly = it + 1 != myTagDataStack.end(); const bool inheritedOnly = it + 1 != myTagDataStack.end();
for (std::vector<shared_ptr<ZLTextStyleEntry> >::const_iterator jt = entries.begin(); jt != entries.end(); ++jt) { for (std::vector<shared_ptr<ZLTextStyleEntry> >::const_iterator jt = entries.begin(); jt != entries.end(); ++jt) {
shared_ptr<ZLTextStyleEntry> entry = inheritedOnly ? (*jt)->inherited() : *jt; shared_ptr<ZLTextStyleEntry> entry = inheritedOnly ? (*jt)->inherited() : *jt;
myBookReader.addStyleEntry(*entry); myBookReader.addStyleEntry(*entry, depth);
} }
} }
} }

View file

@ -227,6 +227,7 @@ void RtfBookReader::setEncoding(int) {
void RtfBookReader::setAlignment() { void RtfBookReader::setAlignment() {
ZLTextStyleEntry entry(ZLTextStyleEntry::STYLE_OTHER_ENTRY); ZLTextStyleEntry entry(ZLTextStyleEntry::STYLE_OTHER_ENTRY);
entry.setAlignmentType(myState.Alignment); entry.setAlignmentType(myState.Alignment);
myBookReader.addStyleEntry(entry); // TODO: replace 0 with depth?
myBookReader.addStyleEntry(entry, 0);
// TODO: call addStyleCloseEntry somewhere (?) // TODO: call addStyleCloseEntry somewhere (?)
} }

View file

@ -735,23 +735,23 @@ bool XHTMLReader::matches(const shared_ptr<CSSSelector::Component> next, int dep
} }
} }
void XHTMLReader::addTextStyleEntry(const std::string &tag, const std::string &aClass) { void XHTMLReader::addTextStyleEntry(const std::string &tag, const std::string &aClass, unsigned char depth) {
std::vector<std::pair<CSSSelector,shared_ptr<ZLTextStyleEntry> > > controls = std::vector<std::pair<CSSSelector,shared_ptr<ZLTextStyleEntry> > > controls =
myStyleSheetTable.allControls(tag, aClass); myStyleSheetTable.allControls(tag, aClass);
for (std::vector<std::pair<CSSSelector,shared_ptr<ZLTextStyleEntry> > >::const_iterator it = controls.begin(); it != controls.end(); ++it) { for (std::vector<std::pair<CSSSelector,shared_ptr<ZLTextStyleEntry> > >::const_iterator it = controls.begin(); it != controls.end(); ++it) {
if (matches(it->first.Next)) { if (matches(it->first.Next)) {
shared_ptr<ZLTextStyleEntry> entry = it->second; shared_ptr<ZLTextStyleEntry> entry = it->second;
if (!entry.isNull()) { if (!entry.isNull()) {
addTextStyleEntry(*(entry->start())); addTextStyleEntry(*(entry->start()), depth);
myTagDataStack.back()->StyleEntries.push_back(entry); myTagDataStack.back()->StyleEntries.push_back(entry);
} }
} }
} }
} }
void XHTMLReader::addTextStyleEntry(const ZLTextStyleEntry &entry) { void XHTMLReader::addTextStyleEntry(const ZLTextStyleEntry &entry, unsigned char depth) {
if (!entry.isFeatureSupported(ZLTextStyleEntry::FONT_FAMILY)) { if (!entry.isFeatureSupported(ZLTextStyleEntry::FONT_FAMILY)) {
myModelReader.addStyleEntry(entry); myModelReader.addStyleEntry(entry, depth);
return; return;
} }
@ -772,7 +772,7 @@ void XHTMLReader::addTextStyleEntry(const ZLTextStyleEntry &entry) {
} }
if (!doFixFamiliesList) { if (!doFixFamiliesList) {
myModelReader.addStyleEntry(entry); myModelReader.addStyleEntry(entry, depth);
} else { } else {
std::vector<std::string> realFamilies; std::vector<std::string> realFamilies;
for (std::vector<std::string>::const_iterator it = families.begin(); it != families.end(); ++it) { for (std::vector<std::string>::const_iterator it = families.begin(); it != families.end(); ++it) {
@ -783,7 +783,7 @@ void XHTMLReader::addTextStyleEntry(const ZLTextStyleEntry &entry) {
realFamilies.push_back(*it); realFamilies.push_back(*it);
} }
} }
myModelReader.addStyleEntry(entry, realFamilies); myModelReader.addStyleEntry(entry, realFamilies, depth);
} }
} }
@ -835,17 +835,18 @@ void XHTMLReader::startElementHandler(const char *tag, const char **attributes)
action->doAtStart(*this, attributes); action->doAtStart(*this, attributes);
} }
addTextStyleEntry(ANY, EMPTY); const unsigned char depth = myTagDataStack.size();
addTextStyleEntry(sTag, EMPTY); addTextStyleEntry(ANY, EMPTY, depth);
addTextStyleEntry(sTag, EMPTY, depth);
for (std::vector<std::string>::const_iterator it = classesList.begin(); it != classesList.end(); ++it) { for (std::vector<std::string>::const_iterator it = classesList.begin(); it != classesList.end(); ++it) {
addTextStyleEntry(EMPTY, *it); addTextStyleEntry(EMPTY, *it, depth);
addTextStyleEntry(sTag, *it); addTextStyleEntry(sTag, *it, depth);
} }
const char *style = attributeValue(attributes, "style"); const char *style = attributeValue(attributes, "style");
if (style != 0) { if (style != 0) {
//ZLLogger::Instance().println("CSS", std::string("parsing style attribute: ") + style); //ZLLogger::Instance().println("CSS", std::string("parsing style attribute: ") + style);
shared_ptr<ZLTextStyleEntry> entry = myStyleParser->parseSingleEntry(style); shared_ptr<ZLTextStyleEntry> entry = myStyleParser->parseSingleEntry(style);
addTextStyleEntry(*entry); addTextStyleEntry(*entry, depth);
myTagDataStack.back()->StyleEntries.push_back(entry); myTagDataStack.back()->StyleEntries.push_back(entry);
} }
} }
@ -859,10 +860,11 @@ void XHTMLReader::endElementHandler(const char *tag) {
const TagData &tagData = *myTagDataStack.back(); const TagData &tagData = *myTagDataStack.back();
const std::vector<shared_ptr<ZLTextStyleEntry> > &entries = tagData.StyleEntries; const std::vector<shared_ptr<ZLTextStyleEntry> > &entries = tagData.StyleEntries;
size_t entryCount = entries.size(); size_t entryCount = entries.size();
const unsigned char depth = myTagDataStack.size();
for (std::vector<shared_ptr<ZLTextStyleEntry> >::const_iterator jt = entries.begin(); jt != entries.end(); ++jt) { for (std::vector<shared_ptr<ZLTextStyleEntry> >::const_iterator jt = entries.begin(); jt != entries.end(); ++jt) {
shared_ptr<ZLTextStyleEntry> endEntry = (*jt)->end(); shared_ptr<ZLTextStyleEntry> endEntry = (*jt)->end();
if (!endEntry.isNull()) { if (!endEntry.isNull()) {
addTextStyleEntry(*endEntry); addTextStyleEntry(*endEntry, depth);
++entryCount; ++entryCount;
} }
} }
@ -894,9 +896,10 @@ void XHTMLReader::beginParagraph(bool restarted) {
} }
const std::vector<shared_ptr<ZLTextStyleEntry> > &entries = (*it)->StyleEntries; const std::vector<shared_ptr<ZLTextStyleEntry> > &entries = (*it)->StyleEntries;
bool inheritedOnly = !restarted || it + 1 != myTagDataStack.end(); bool inheritedOnly = !restarted || it + 1 != myTagDataStack.end();
const unsigned char depth = it - myTagDataStack.begin() + 1;
for (std::vector<shared_ptr<ZLTextStyleEntry> >::const_iterator jt = entries.begin(); jt != entries.end(); ++jt) { for (std::vector<shared_ptr<ZLTextStyleEntry> >::const_iterator jt = entries.begin(); jt != entries.end(); ++jt) {
shared_ptr<ZLTextStyleEntry> entry = inheritedOnly ? (*jt)->inherited() : (*jt)->start(); shared_ptr<ZLTextStyleEntry> entry = inheritedOnly ? (*jt)->inherited() : (*jt)->start();
addTextStyleEntry(*entry); addTextStyleEntry(*entry, depth);
} }
} }
} }
@ -909,13 +912,14 @@ void XHTMLReader::restartParagraph() {
if (myCurrentParagraphIsEmpty) { if (myCurrentParagraphIsEmpty) {
myModelReader.addFixedHSpace(1); myModelReader.addFixedHSpace(1);
} }
const unsigned char depth = myTagDataStack.size();
ZLTextStyleEntry spaceAfterBlocker(ZLTextStyleEntry::STYLE_OTHER_ENTRY); ZLTextStyleEntry spaceAfterBlocker(ZLTextStyleEntry::STYLE_OTHER_ENTRY);
spaceAfterBlocker.setLength( spaceAfterBlocker.setLength(
ZLTextStyleEntry::LENGTH_SPACE_AFTER, ZLTextStyleEntry::LENGTH_SPACE_AFTER,
0, 0,
ZLTextStyleEntry::SIZE_UNIT_PIXEL ZLTextStyleEntry::SIZE_UNIT_PIXEL
); );
addTextStyleEntry(spaceAfterBlocker); addTextStyleEntry(spaceAfterBlocker, depth);
endParagraph(); endParagraph();
beginParagraph(true); beginParagraph(true);
ZLTextStyleEntry spaceBeforeBlocker(ZLTextStyleEntry::STYLE_OTHER_ENTRY); ZLTextStyleEntry spaceBeforeBlocker(ZLTextStyleEntry::STYLE_OTHER_ENTRY);
@ -924,7 +928,7 @@ void XHTMLReader::restartParagraph() {
0, 0,
ZLTextStyleEntry::SIZE_UNIT_PIXEL ZLTextStyleEntry::SIZE_UNIT_PIXEL
); );
addTextStyleEntry(spaceBeforeBlocker); addTextStyleEntry(spaceBeforeBlocker, depth);
} }
void XHTMLReader::pushTextKind(FBTextKind kind) { void XHTMLReader::pushTextKind(FBTextKind kind) {

View file

@ -109,8 +109,8 @@ private:
void restartParagraph(); void restartParagraph();
const XHTMLTagInfoList &tagInfos(size_t depth) const; const XHTMLTagInfoList &tagInfos(size_t depth) const;
bool matches(const shared_ptr<CSSSelector::Component> next, int depth = 0, int pos = -1) const; bool matches(const shared_ptr<CSSSelector::Component> next, int depth = 0, int pos = -1) const;
void addTextStyleEntry(const std::string &tag, const std::string &aClass); void addTextStyleEntry(const std::string &tag, const std::string &aClass, unsigned char depth);
void addTextStyleEntry(const ZLTextStyleEntry &entry); void addTextStyleEntry(const ZLTextStyleEntry &entry, unsigned char depth);
void pushTextKind(FBTextKind kind); void pushTextKind(FBTextKind kind);

View file

@ -239,11 +239,11 @@ void ZLTextModel::addControl(ZLTextKind textKind, bool isStart) {
//static int EntryCount = 0; //static int EntryCount = 0;
//static int EntryLen = 0; //static int EntryLen = 0;
void ZLTextModel::addStyleEntry(const ZLTextStyleEntry &entry) { void ZLTextModel::addStyleEntry(const ZLTextStyleEntry &entry, unsigned char depth) {
addStyleEntry(entry, entry.fontFamilies()); addStyleEntry(entry, entry.fontFamilies(), depth);
} }
void ZLTextModel::addStyleEntry(const ZLTextStyleEntry &entry, const std::vector<std::string> &fontFamilies) { void ZLTextModel::addStyleEntry(const ZLTextStyleEntry &entry, const std::vector<std::string> &fontFamilies, unsigned char depth) {
// +++ calculating entry size // +++ calculating entry size
std::size_t len = 4; // entry type + feature mask std::size_t len = 4; // entry type + feature mask
for (int i = 0; i < ZLTextStyleEntry::NUMBER_OF_LENGTHS; ++i) { for (int i = 0; i < ZLTextStyleEntry::NUMBER_OF_LENGTHS; ++i) {
@ -278,7 +278,7 @@ void ZLTextModel::addStyleEntry(const ZLTextStyleEntry &entry, const std::vector
char *address = myLastEntryStart; char *address = myLastEntryStart;
*address++ = entry.entryKind(); *address++ = entry.entryKind();
*address++ = 0; *address++ = depth;
address = ZLCachedMemoryAllocator::writeUInt16(address, entry.myFeatureMask); address = ZLCachedMemoryAllocator::writeUInt16(address, entry.myFeatureMask);
for (int i = 0; i < ZLTextStyleEntry::NUMBER_OF_LENGTHS; ++i) { for (int i = 0; i < ZLTextStyleEntry::NUMBER_OF_LENGTHS; ++i) {

View file

@ -67,8 +67,8 @@ public:
ZLTextMark previousMark(ZLTextMark position) const; ZLTextMark previousMark(ZLTextMark position) const;
*/ */
void addControl(ZLTextKind textKind, bool isStart); void addControl(ZLTextKind textKind, bool isStart);
void addStyleEntry(const ZLTextStyleEntry &entry); void addStyleEntry(const ZLTextStyleEntry &entry, unsigned char depth);
void addStyleEntry(const ZLTextStyleEntry &entry, const std::vector<std::string> &fontFamilies); void addStyleEntry(const ZLTextStyleEntry &entry, const std::vector<std::string> &fontFamilies, unsigned char depth);
void addStyleCloseEntry(); void addStyleCloseEntry();
void addHyperlinkControl(ZLTextKind textKind, ZLHyperlinkType hyperlinkType, const std::string &label); void addHyperlinkControl(ZLTextKind textKind, ZLHyperlinkType hyperlinkType, const std::string &label);
void addText(const std::string &text); void addText(const std::string &text);

View file

@ -46,8 +46,10 @@ short ZLTextStyleEntry::length(Feature featureId, const Metrics &metrics) const
case SIZE_UNIT_PERCENT: case SIZE_UNIT_PERCENT:
switch (featureId) { switch (featureId) {
default: default:
case LENGTH_LEFT_INDENT: case LENGTH_MARGIN_LEFT:
case LENGTH_RIGHT_INDENT: case LENGTH_MARGIN_RIGHT:
case LENGTH_PADDING_LEFT:
case LENGTH_PADDING_RIGHT:
case LENGTH_FIRST_LINE_INDENT: case LENGTH_FIRST_LINE_INDENT:
return (myLengths[featureId].Size * metrics.FullWidth + 50) / 100; return (myLengths[featureId].Size * metrics.FullWidth + 50) / 100;
case LENGTH_SPACE_BEFORE: case LENGTH_SPACE_BEFORE:

View file

@ -45,7 +45,14 @@ shared_ptr<ZLTextStyleEntry> ZLTextStyleEntry::end() const {
shared_ptr<ZLTextStyleEntry> ZLTextStyleEntry::inherited() const { shared_ptr<ZLTextStyleEntry> ZLTextStyleEntry::inherited() const {
ZLTextStyleEntry *clone = new ZLTextStyleEntry(myEntryKind); ZLTextStyleEntry *clone = new ZLTextStyleEntry(myEntryKind);
clone->myFeatureMask = myFeatureMask & ~(1 << LENGTH_SPACE_BEFORE) & ~(1 << LENGTH_SPACE_AFTER); static const unsigned short skip =
//(1 << LENGTH_MARGIN_LEFT) |
//(1 << LENGTH_MARGIN_RIGHT) |
//(1 << LENGTH_PADDING_LEFT) |
//(1 << LENGTH_PADDING_RIGHT) |
(1 << LENGTH_SPACE_BEFORE) |
(1 << LENGTH_SPACE_AFTER);
clone->myFeatureMask = myFeatureMask & ~skip;
for (int i = 0; i < NUMBER_OF_LENGTHS; ++i) { for (int i = 0; i < NUMBER_OF_LENGTHS; ++i) {
clone->myLengths[i] = myLengths[i]; clone->myLengths[i] = myLengths[i];
} }

View file

@ -62,14 +62,16 @@ public:
}; };
enum Feature { enum Feature {
LENGTH_LEFT_INDENT = 0, LENGTH_PADDING_LEFT = 0,
LENGTH_RIGHT_INDENT = 1, LENGTH_PADDING_RIGHT = 1,
LENGTH_FIRST_LINE_INDENT = 2, LENGTH_MARGIN_LEFT = 2,
LENGTH_SPACE_BEFORE = 3, LENGTH_MARGIN_RIGHT = 3,
LENGTH_SPACE_AFTER = 4, LENGTH_FIRST_LINE_INDENT = 4,
LENGTH_FONT_SIZE = 5, LENGTH_SPACE_BEFORE = 5,
LENGTH_VERTICAL_ALIGN = 6, LENGTH_SPACE_AFTER = 6,
NUMBER_OF_LENGTHS = 7, LENGTH_FONT_SIZE = 7,
LENGTH_VERTICAL_ALIGN = 8,
NUMBER_OF_LENGTHS = 9,
ALIGNMENT_TYPE = NUMBER_OF_LENGTHS, ALIGNMENT_TYPE = NUMBER_OF_LENGTHS,
FONT_FAMILY = NUMBER_OF_LENGTHS + 1, FONT_FAMILY = NUMBER_OF_LENGTHS + 1,
FONT_STYLE_MODIFIER = NUMBER_OF_LENGTHS + 2, FONT_STYLE_MODIFIER = NUMBER_OF_LENGTHS + 2,

View file

@ -20,6 +20,7 @@
package org.geometerplus.zlibrary.text.model; package org.geometerplus.zlibrary.text.model;
public final class ZLTextCSSStyleEntry extends ZLTextStyleEntry { public final class ZLTextCSSStyleEntry extends ZLTextStyleEntry {
public ZLTextCSSStyleEntry() { public ZLTextCSSStyleEntry(short depth) {
super(depth);
} }
} }

View file

@ -21,5 +21,6 @@ package org.geometerplus.zlibrary.text.model;
public final class ZLTextOtherStyleEntry extends ZLTextStyleEntry { public final class ZLTextOtherStyleEntry extends ZLTextStyleEntry {
public ZLTextOtherStyleEntry() { public ZLTextOtherStyleEntry() {
super((short)0);
} }
} }

View file

@ -147,14 +147,16 @@ public class ZLTextPlainModel implements ZLTextModel, ZLTextStyleEntry.Feature {
} }
dataOffset = 0; dataOffset = 0;
} }
byte type = (byte)data[dataOffset]; short first = (short)data[dataOffset];
byte type = (byte)first;
if (type == 0) { if (type == 0) {
data = myStorage.block(++myDataIndex); data = myStorage.block(++myDataIndex);
if (data == null) { if (data == null) {
return false; return false;
} }
dataOffset = 0; dataOffset = 0;
type = (byte)data[0]; first = (short)data[0];
type = (byte)first;
} }
myType = type; myType = type;
++dataOffset; ++dataOffset;
@ -205,9 +207,10 @@ public class ZLTextPlainModel implements ZLTextModel, ZLTextStyleEntry.Feature {
case ZLTextParagraph.Entry.STYLE_CSS: case ZLTextParagraph.Entry.STYLE_CSS:
case ZLTextParagraph.Entry.STYLE_OTHER: case ZLTextParagraph.Entry.STYLE_OTHER:
{ {
final short depth = (short)((first >> 8) & 0xFF);
final ZLTextStyleEntry entry = final ZLTextStyleEntry entry =
type == ZLTextParagraph.Entry.STYLE_CSS type == ZLTextParagraph.Entry.STYLE_CSS
? new ZLTextCSSStyleEntry() ? new ZLTextCSSStyleEntry(depth)
: new ZLTextOtherStyleEntry(); : new ZLTextOtherStyleEntry();
final short mask = (short)data[dataOffset++]; final short mask = (short)data[dataOffset++];

View file

@ -28,14 +28,16 @@ import org.geometerplus.zlibrary.core.util.ZLBoolean3;
public abstract class ZLTextStyleEntry { public abstract class ZLTextStyleEntry {
public interface Feature { public interface Feature {
int LENGTH_LEFT_INDENT = 0; int LENGTH_PADDING_LEFT = 0;
int LENGTH_RIGHT_INDENT = 1; int LENGTH_PADDING_RIGHT = 1;
int LENGTH_FIRST_LINE_INDENT = 2; int LENGTH_MARGIN_LEFT = 2;
int LENGTH_SPACE_BEFORE = 3; int LENGTH_MARGIN_RIGHT = 3;
int LENGTH_SPACE_AFTER = 4; int LENGTH_FIRST_LINE_INDENT = 4;
int LENGTH_FONT_SIZE = 5; int LENGTH_SPACE_BEFORE = 5;
int LENGTH_VERTICAL_ALIGN = 6; int LENGTH_SPACE_AFTER = 6;
int NUMBER_OF_LENGTHS = 7; int LENGTH_FONT_SIZE = 7;
int LENGTH_VERTICAL_ALIGN = 8;
int NUMBER_OF_LENGTHS = 9;
int ALIGNMENT_TYPE = NUMBER_OF_LENGTHS; int ALIGNMENT_TYPE = NUMBER_OF_LENGTHS;
int FONT_FAMILY = NUMBER_OF_LENGTHS + 1; int FONT_FAMILY = NUMBER_OF_LENGTHS + 1;
int FONT_STYLE_MODIFIER = NUMBER_OF_LENGTHS + 2; int FONT_STYLE_MODIFIER = NUMBER_OF_LENGTHS + 2;
@ -78,6 +80,7 @@ public abstract class ZLTextStyleEntry {
} }
} }
public final short Depth;
private short myFeatureMask; private short myFeatureMask;
private Length[] myLengths = new Length[Feature.NUMBER_OF_LENGTHS]; private Length[] myLengths = new Length[Feature.NUMBER_OF_LENGTHS];
@ -91,7 +94,8 @@ public abstract class ZLTextStyleEntry {
return (mask & (1 << featureId)) != 0; return (mask & (1 << featureId)) != 0;
} }
protected ZLTextStyleEntry() { protected ZLTextStyleEntry(short depth) {
Depth = depth;
} }
public final boolean isFeatureSupported(int featureId) { public final boolean isFeatureSupported(int featureId) {
@ -106,8 +110,10 @@ public abstract class ZLTextStyleEntry {
private static int fullSize(ZLTextMetrics metrics, int fontSize, int featureId) { private static int fullSize(ZLTextMetrics metrics, int fontSize, int featureId) {
switch (featureId) { switch (featureId) {
default: default:
case Feature.LENGTH_LEFT_INDENT: case Feature.LENGTH_MARGIN_LEFT:
case Feature.LENGTH_RIGHT_INDENT: case Feature.LENGTH_MARGIN_RIGHT:
case Feature.LENGTH_PADDING_LEFT:
case Feature.LENGTH_PADDING_RIGHT:
case Feature.LENGTH_FIRST_LINE_INDENT: case Feature.LENGTH_FIRST_LINE_INDENT:
return metrics.FullWidth; return metrics.FullWidth;
case Feature.LENGTH_SPACE_BEFORE: case Feature.LENGTH_SPACE_BEFORE:

View file

@ -41,8 +41,17 @@ public abstract class ZLTextStyle {
public abstract boolean isUnderline(); public abstract boolean isUnderline();
public abstract boolean isStrikeThrough(); public abstract boolean isStrikeThrough();
public abstract int getLeftIndent(ZLTextMetrics metrics); public final int getLeftIndent(ZLTextMetrics metrics) {
public abstract int getRightIndent(ZLTextMetrics metrics); return getLeftMargin(metrics) + getLeftPadding(metrics);
}
public final int getRightIndent(ZLTextMetrics metrics) {
return getRightMargin(metrics) + getRightPadding(metrics);
}
public abstract int getLeftMargin(ZLTextMetrics metrics);
public abstract int getRightMargin(ZLTextMetrics metrics);
public abstract int getLeftPadding(ZLTextMetrics metrics);
public abstract int getRightPadding(ZLTextMetrics metrics);
public abstract int getFirstLineIndent(ZLTextMetrics metrics); public abstract int getFirstLineIndent(ZLTextMetrics metrics);
public abstract int getLineSpacePercent(); public abstract int getLineSpacePercent();
public abstract int getVerticalAlign(ZLTextMetrics metrics); public abstract int getVerticalAlign(ZLTextMetrics metrics);

View file

@ -111,12 +111,22 @@ public class ZLTextBaseStyle extends ZLTextStyle {
} }
@Override @Override
public int getLeftIndent(ZLTextMetrics metrics) { public int getLeftMargin(ZLTextMetrics metrics) {
return 0; return 0;
} }
@Override @Override
public int getRightIndent(ZLTextMetrics metrics) { public int getRightMargin(ZLTextMetrics metrics) {
return 0;
}
@Override
public int getLeftPadding(ZLTextMetrics metrics) {
return 0;
}
@Override
public int getRightPadding(ZLTextMetrics metrics) {
return 0; return 0;
} }

View file

@ -43,8 +43,10 @@ public abstract class ZLTextDecoratedStyle extends ZLTextStyle {
private int mySpaceBefore; private int mySpaceBefore;
private int mySpaceAfter; private int mySpaceAfter;
private int myVerticalAlign; private int myVerticalAlign;
private int myLeftIndent; private int myLeftMargin;
private int myRightIndent; private int myRightMargin;
private int myLeftPadding;
private int myRightPadding;
private int myFirstLineIndent; private int myFirstLineIndent;
private ZLTextMetrics myMetrics; private ZLTextMetrics myMetrics;
@ -72,8 +74,10 @@ public abstract class ZLTextDecoratedStyle extends ZLTextStyle {
mySpaceBefore = getSpaceBeforeInternal(metrics, myFontSize); mySpaceBefore = getSpaceBeforeInternal(metrics, myFontSize);
mySpaceAfter = getSpaceAfterInternal(metrics, myFontSize); mySpaceAfter = getSpaceAfterInternal(metrics, myFontSize);
myVerticalAlign = getVerticalAlignInternal(metrics, myFontSize); myVerticalAlign = getVerticalAlignInternal(metrics, myFontSize);
myLeftIndent = getLeftIndentInternal(metrics, myFontSize); myLeftMargin = getLeftMarginInternal(metrics, myFontSize);
myRightIndent = getRightIndentInternal(metrics, myFontSize); myRightMargin = getRightMarginInternal(metrics, myFontSize);
myLeftPadding = getLeftPaddingInternal(metrics, myFontSize);
myRightPadding = getRightPaddingInternal(metrics, myFontSize);
myFirstLineIndent = getFirstLineIndentInternal(metrics, myFontSize); myFirstLineIndent = getFirstLineIndentInternal(metrics, myFontSize);
} }
@ -159,22 +163,40 @@ public abstract class ZLTextDecoratedStyle extends ZLTextStyle {
protected abstract int getVerticalAlignInternal(ZLTextMetrics metrics, int fontSize); protected abstract int getVerticalAlignInternal(ZLTextMetrics metrics, int fontSize);
@Override @Override
public final int getLeftIndent(ZLTextMetrics metrics) { public final int getLeftMargin(ZLTextMetrics metrics) {
if (!metrics.equals(myMetrics)) { if (!metrics.equals(myMetrics)) {
initMetricsCache(metrics); initMetricsCache(metrics);
} }
return myLeftIndent; return myLeftMargin;
} }
protected abstract int getLeftIndentInternal(ZLTextMetrics metrics, int fontSize); protected abstract int getLeftMarginInternal(ZLTextMetrics metrics, int fontSize);
@Override @Override
public final int getRightIndent(ZLTextMetrics metrics) { public final int getRightMargin(ZLTextMetrics metrics) {
if (!metrics.equals(myMetrics)) { if (!metrics.equals(myMetrics)) {
initMetricsCache(metrics); initMetricsCache(metrics);
} }
return myRightIndent; return myRightMargin;
} }
protected abstract int getRightIndentInternal(ZLTextMetrics metrics, int fontSize); protected abstract int getRightMarginInternal(ZLTextMetrics metrics, int fontSize);
@Override
public final int getLeftPadding(ZLTextMetrics metrics) {
if (!metrics.equals(myMetrics)) {
initMetricsCache(metrics);
}
return myLeftPadding;
}
protected abstract int getLeftPaddingInternal(ZLTextMetrics metrics, int fontSize);
@Override
public final int getRightPadding(ZLTextMetrics metrics) {
if (!metrics.equals(myMetrics)) {
initMetricsCache(metrics);
}
return myRightPadding;
}
protected abstract int getRightPaddingInternal(ZLTextMetrics metrics, int fontSize);
@Override @Override
public final int getFirstLineIndent(ZLTextMetrics metrics) { public final int getFirstLineIndent(ZLTextMetrics metrics) {

View file

@ -63,16 +63,40 @@ public class ZLTextExplicitlyDecoratedStyle extends ZLTextDecoratedStyle impleme
return allEntries; return allEntries;
} }
private ZLTextStyle myTreeParent;
private ZLTextStyle computeTreeParent() {
if (myEntry.Depth == 0) {
return Parent.Parent;
}
int count = 0;
ZLTextStyle p = Parent;
for (; p != p.Parent; p = p.Parent) {
if (p instanceof ZLTextExplicitlyDecoratedStyle) {
if (((ZLTextExplicitlyDecoratedStyle)p).myEntry.Depth != myEntry.Depth) {
return p;
}
} else {
if (++count > 1) {
return p;
}
}
}
return p;
}
private ZLTextStyle getTreeParent() {
if (myTreeParent == null) {
myTreeParent = computeTreeParent();
}
return myTreeParent;
}
@Override @Override
protected int getFontSizeInternal(ZLTextMetrics metrics) { protected int getFontSizeInternal(ZLTextMetrics metrics) {
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSFontSizeOption.getValue()) { if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSFontSizeOption.getValue()) {
return Parent.getFontSize(metrics); return Parent.getFontSize(metrics);
} }
// Yes, Parent.Parent, not Parent (parent = current tag pre-defined size, final int baseFontSize = getTreeParent().getFontSize(metrics);
// we want to override it)
// TODO: use _previous_tag_value_
final int baseFontSize = Parent.Parent.getFontSize(metrics);
if (myEntry.isFeatureSupported(FONT_STYLE_MODIFIER)) { if (myEntry.isFeatureSupported(FONT_STYLE_MODIFIER)) {
if (myEntry.getFontModifier(FONT_MODIFIER_INHERIT) == ZLBoolean3.B3_TRUE) { if (myEntry.getFontModifier(FONT_MODIFIER_INHERIT) == ZLBoolean3.B3_TRUE) {
return baseFontSize; return baseFontSize;
@ -136,26 +160,48 @@ public class ZLTextExplicitlyDecoratedStyle extends ZLTextDecoratedStyle impleme
} }
@Override @Override
public int getLeftIndentInternal(ZLTextMetrics metrics, int fontSize) { public int getLeftMarginInternal(ZLTextMetrics metrics, int fontSize) {
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSMarginsOption.getValue()) { if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSMarginsOption.getValue()) {
return Parent.getLeftIndent(metrics); return Parent.getLeftMargin(metrics);
} }
if (!myEntry.isFeatureSupported(LENGTH_LEFT_INDENT)) { if (!myEntry.isFeatureSupported(LENGTH_MARGIN_LEFT)) {
return Parent.getLeftIndent(metrics); return Parent.getLeftMargin(metrics);
} }
return myEntry.getLength(LENGTH_LEFT_INDENT, metrics, fontSize); return getTreeParent().getLeftMargin(metrics) + myEntry.getLength(LENGTH_MARGIN_LEFT, metrics, fontSize);
} }
@Override @Override
public int getRightIndentInternal(ZLTextMetrics metrics, int fontSize) { public int getRightMarginInternal(ZLTextMetrics metrics, int fontSize) {
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSMarginsOption.getValue()) { if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSMarginsOption.getValue()) {
return Parent.getRightIndent(metrics); return Parent.getRightMargin(metrics);
} }
if (!myEntry.isFeatureSupported(LENGTH_RIGHT_INDENT)) { if (!myEntry.isFeatureSupported(LENGTH_MARGIN_RIGHT)) {
return Parent.getRightIndent(metrics); return Parent.getRightMargin(metrics);
} }
return myEntry.getLength(LENGTH_RIGHT_INDENT, metrics, fontSize); return getTreeParent().getRightMargin(metrics) + myEntry.getLength(LENGTH_MARGIN_RIGHT, metrics, fontSize);
}
@Override
public int getLeftPaddingInternal(ZLTextMetrics metrics, int fontSize) {
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSMarginsOption.getValue()) {
return Parent.getLeftPadding(metrics);
}
if (!myEntry.isFeatureSupported(LENGTH_PADDING_LEFT)) {
return Parent.getLeftPadding(metrics);
}
return getTreeParent().getLeftPadding(metrics) + myEntry.getLength(LENGTH_PADDING_LEFT, metrics, fontSize);
}
@Override
public int getRightPaddingInternal(ZLTextMetrics metrics, int fontSize) {
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSMarginsOption.getValue()) {
return Parent.getRightPadding(metrics);
}
if (!myEntry.isFeatureSupported(LENGTH_PADDING_RIGHT)) {
return Parent.getRightPadding(metrics);
}
return getTreeParent().getRightPadding(metrics) + myEntry.getLength(LENGTH_PADDING_RIGHT, metrics, fontSize);
} }
@Override @Override
protected int getFirstLineIndentInternal(ZLTextMetrics metrics, int fontSize) { protected int getFirstLineIndentInternal(ZLTextMetrics metrics, int fontSize) {

View file

@ -105,12 +105,20 @@ public class ZLTextNGStyle extends ZLTextDecoratedStyle {
} }
@Override @Override
protected int getLeftIndentInternal(ZLTextMetrics metrics, int fontSize) { protected int getLeftMarginInternal(ZLTextMetrics metrics, int fontSize) {
return myDescription.getLeftIndent(metrics, Parent.getLeftIndent(metrics), fontSize); return myDescription.getLeftMargin(metrics, Parent.getLeftMargin(metrics), fontSize);
} }
@Override @Override
protected int getRightIndentInternal(ZLTextMetrics metrics, int fontSize) { protected int getRightMarginInternal(ZLTextMetrics metrics, int fontSize) {
return myDescription.getRightIndent(metrics, Parent.getRightIndent(metrics), fontSize); return myDescription.getRightMargin(metrics, Parent.getRightMargin(metrics), fontSize);
}
@Override
protected int getLeftPaddingInternal(ZLTextMetrics metrics, int fontSize) {
return myDescription.getLeftPadding(metrics, Parent.getLeftPadding(metrics), fontSize);
}
@Override
protected int getRightPaddingInternal(ZLTextMetrics metrics, int fontSize) {
return myDescription.getRightPadding(metrics, Parent.getRightPadding(metrics), fontSize);
} }
@Override @Override
protected int getFirstLineIndentInternal(ZLTextMetrics metrics, int fontSize) { protected int getFirstLineIndentInternal(ZLTextMetrics metrics, int fontSize) {

View file

@ -88,26 +88,34 @@ public class ZLTextNGStyleDescription {
); );
} }
int getLeftIndent(ZLTextMetrics metrics, int base, int fontSize) { int getLeftMargin(ZLTextMetrics metrics, int base, int fontSize) {
final ZLTextStyleEntry.Length length = parseLength(MarginLeftOption.getValue()); final ZLTextStyleEntry.Length length = parseLength(MarginLeftOption.getValue());
if (length == null) { if (length == null) {
return base; return base;
} }
return ZLTextStyleEntry.compute( return base + ZLTextStyleEntry.compute(
length, metrics, fontSize, ZLTextStyleEntry.Feature.LENGTH_LEFT_INDENT length, metrics, fontSize, ZLTextStyleEntry.Feature.LENGTH_MARGIN_LEFT
); );
} }
int getRightIndent(ZLTextMetrics metrics, int base, int fontSize) { int getRightMargin(ZLTextMetrics metrics, int base, int fontSize) {
final ZLTextStyleEntry.Length length = parseLength(MarginRightOption.getValue()); final ZLTextStyleEntry.Length length = parseLength(MarginRightOption.getValue());
if (length == null) { if (length == null) {
return base; return base;
} }
return ZLTextStyleEntry.compute( return base + ZLTextStyleEntry.compute(
length, metrics, fontSize, ZLTextStyleEntry.Feature.LENGTH_RIGHT_INDENT length, metrics, fontSize, ZLTextStyleEntry.Feature.LENGTH_MARGIN_RIGHT
); );
} }
int getLeftPadding(ZLTextMetrics metrics, int base, int fontSize) {
return base;
}
int getRightPadding(ZLTextMetrics metrics, int base, int fontSize) {
return base;
}
int getFirstLineIndent(ZLTextMetrics metrics, int base, int fontSize) { int getFirstLineIndent(ZLTextMetrics metrics, int base, int fontSize) {
final ZLTextStyleEntry.Length length = parseLength(TextIndentOption.getValue()); final ZLTextStyleEntry.Length length = parseLength(TextIndentOption.getValue());
if (length == null) { if (length == null) {