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:
parent
d73f7816cf
commit
643f5a345c
24 changed files with 258 additions and 101 deletions
|
@ -8,6 +8,9 @@
|
|||
* (planned) Fixed authors list/tags list editing
|
||||
* (planned) CSS selectors priority
|
||||
|
||||
===== 2.2 beta 3 (Nov ??, 2014) =====
|
||||
* Added 'padding' and 'padding-*' CSS property support
|
||||
|
||||
===== 2.2 beta 2 (Nov 02, 2014) =====
|
||||
* Added '*' selector support in CSS
|
||||
* Optimised combined selectors processing
|
||||
|
|
|
@ -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()) {
|
||||
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()) {
|
||||
flushTextBufferToParagraph();
|
||||
myCurrentTextModel->addStyleEntry(entry);
|
||||
myCurrentTextModel->addStyleEntry(entry, depth);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,8 +61,8 @@ public:
|
|||
void endParagraph();
|
||||
bool paragraphIsOpen() const;
|
||||
void addControl(FBTextKind kind, bool start);
|
||||
void addStyleEntry(const ZLTextStyleEntry &entry);
|
||||
void addStyleEntry(const ZLTextStyleEntry &entry, const std::vector<std::string> &fontFamilies);
|
||||
void addStyleEntry(const ZLTextStyleEntry &entry, unsigned char depth);
|
||||
void addStyleEntry(const ZLTextStyleEntry &entry, const std::vector<std::string> &fontFamilies, unsigned char depth);
|
||||
void addStyleCloseEntry();
|
||||
void addHyperlinkControl(FBTextKind kind, const std::string &label);
|
||||
void addHyperlinkLabel(const std::string &label);
|
||||
|
|
|
@ -279,12 +279,35 @@ shared_ptr<ZLTextStyleEntry> StyleSheetTable::createOrUpdateControl(const Attrib
|
|||
}
|
||||
}
|
||||
::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_LEFT_INDENT, split[3]);
|
||||
::trySetLength(*entry, ZLTextStyleEntry::LENGTH_MARGIN_LEFT, split[3]);
|
||||
}
|
||||
setLength(*entry, ZLTextStyleEntry::LENGTH_LEFT_INDENT, styles, "margin-left");
|
||||
setLength(*entry, ZLTextStyleEntry::LENGTH_RIGHT_INDENT, styles, "margin-right");
|
||||
const std::string padding = value(styles, "padding");
|
||||
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_SPACE_BEFORE, styles, "margin-top");
|
||||
setLength(*entry, ZLTextStyleEntry::LENGTH_SPACE_BEFORE, styles, "padding-top");
|
||||
|
|
|
@ -87,7 +87,7 @@ void DocBookReader::handleHardLinebreak() {
|
|||
}
|
||||
myModelReader.beginParagraph();
|
||||
if (!myCurrentStyleEntry.isNull()) {
|
||||
myModelReader.addStyleEntry(*myCurrentStyleEntry);
|
||||
myModelReader.addStyleEntry(*myCurrentStyleEntry, 0);
|
||||
}
|
||||
for (std::size_t i = 0; i < myKindStack.size(); ++i) {
|
||||
myModelReader.addControl(myKindStack.at(i), true);
|
||||
|
@ -276,7 +276,7 @@ void DocBookReader::handleParagraphStyle(const OleMainStream::Style &styleInfo)
|
|||
break;
|
||||
}
|
||||
myCurrentStyleEntry = entry;
|
||||
myModelReader.addStyleEntry(*myCurrentStyleEntry);
|
||||
myModelReader.addStyleEntry(*myCurrentStyleEntry, 0);
|
||||
|
||||
// we should have the same font style, as for the previous paragraph,
|
||||
// if it has the same StyleIdCurrent
|
||||
|
|
|
@ -465,11 +465,12 @@ bool HtmlBookReader::tagHandler(const HtmlTag &tag) {
|
|||
|
||||
if (tag.Start) {
|
||||
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 bool inheritedOnly = it + 1 != myTagDataStack.end();
|
||||
for (std::vector<shared_ptr<ZLTextStyleEntry> >::const_iterator jt = entries.begin(); jt != entries.end(); ++jt) {
|
||||
shared_ptr<ZLTextStyleEntry> entry = inheritedOnly ? (*jt)->inherited() : *jt;
|
||||
myBookReader.addStyleEntry(*entry);
|
||||
myBookReader.addStyleEntry(*entry, depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -227,6 +227,7 @@ void RtfBookReader::setEncoding(int) {
|
|||
void RtfBookReader::setAlignment() {
|
||||
ZLTextStyleEntry entry(ZLTextStyleEntry::STYLE_OTHER_ENTRY);
|
||||
entry.setAlignmentType(myState.Alignment);
|
||||
myBookReader.addStyleEntry(entry);
|
||||
// TODO: replace 0 with depth?
|
||||
myBookReader.addStyleEntry(entry, 0);
|
||||
// TODO: call addStyleCloseEntry somewhere (?)
|
||||
}
|
||||
|
|
|
@ -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 =
|
||||
myStyleSheetTable.allControls(tag, aClass);
|
||||
for (std::vector<std::pair<CSSSelector,shared_ptr<ZLTextStyleEntry> > >::const_iterator it = controls.begin(); it != controls.end(); ++it) {
|
||||
if (matches(it->first.Next)) {
|
||||
shared_ptr<ZLTextStyleEntry> entry = it->second;
|
||||
if (!entry.isNull()) {
|
||||
addTextStyleEntry(*(entry->start()));
|
||||
addTextStyleEntry(*(entry->start()), depth);
|
||||
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)) {
|
||||
myModelReader.addStyleEntry(entry);
|
||||
myModelReader.addStyleEntry(entry, depth);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -772,7 +772,7 @@ void XHTMLReader::addTextStyleEntry(const ZLTextStyleEntry &entry) {
|
|||
}
|
||||
|
||||
if (!doFixFamiliesList) {
|
||||
myModelReader.addStyleEntry(entry);
|
||||
myModelReader.addStyleEntry(entry, depth);
|
||||
} else {
|
||||
std::vector<std::string> realFamilies;
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
addTextStyleEntry(ANY, EMPTY);
|
||||
addTextStyleEntry(sTag, EMPTY);
|
||||
const unsigned char depth = myTagDataStack.size();
|
||||
addTextStyleEntry(ANY, EMPTY, depth);
|
||||
addTextStyleEntry(sTag, EMPTY, depth);
|
||||
for (std::vector<std::string>::const_iterator it = classesList.begin(); it != classesList.end(); ++it) {
|
||||
addTextStyleEntry(EMPTY, *it);
|
||||
addTextStyleEntry(sTag, *it);
|
||||
addTextStyleEntry(EMPTY, *it, depth);
|
||||
addTextStyleEntry(sTag, *it, depth);
|
||||
}
|
||||
const char *style = attributeValue(attributes, "style");
|
||||
if (style != 0) {
|
||||
//ZLLogger::Instance().println("CSS", std::string("parsing style attribute: ") + style);
|
||||
shared_ptr<ZLTextStyleEntry> entry = myStyleParser->parseSingleEntry(style);
|
||||
addTextStyleEntry(*entry);
|
||||
addTextStyleEntry(*entry, depth);
|
||||
myTagDataStack.back()->StyleEntries.push_back(entry);
|
||||
}
|
||||
}
|
||||
|
@ -859,10 +860,11 @@ void XHTMLReader::endElementHandler(const char *tag) {
|
|||
const TagData &tagData = *myTagDataStack.back();
|
||||
const std::vector<shared_ptr<ZLTextStyleEntry> > &entries = tagData.StyleEntries;
|
||||
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) {
|
||||
shared_ptr<ZLTextStyleEntry> endEntry = (*jt)->end();
|
||||
if (!endEntry.isNull()) {
|
||||
addTextStyleEntry(*endEntry);
|
||||
addTextStyleEntry(*endEntry, depth);
|
||||
++entryCount;
|
||||
}
|
||||
}
|
||||
|
@ -894,9 +896,10 @@ void XHTMLReader::beginParagraph(bool restarted) {
|
|||
}
|
||||
const std::vector<shared_ptr<ZLTextStyleEntry> > &entries = (*it)->StyleEntries;
|
||||
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) {
|
||||
shared_ptr<ZLTextStyleEntry> entry = inheritedOnly ? (*jt)->inherited() : (*jt)->start();
|
||||
addTextStyleEntry(*entry);
|
||||
addTextStyleEntry(*entry, depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -909,13 +912,14 @@ void XHTMLReader::restartParagraph() {
|
|||
if (myCurrentParagraphIsEmpty) {
|
||||
myModelReader.addFixedHSpace(1);
|
||||
}
|
||||
const unsigned char depth = myTagDataStack.size();
|
||||
ZLTextStyleEntry spaceAfterBlocker(ZLTextStyleEntry::STYLE_OTHER_ENTRY);
|
||||
spaceAfterBlocker.setLength(
|
||||
ZLTextStyleEntry::LENGTH_SPACE_AFTER,
|
||||
0,
|
||||
ZLTextStyleEntry::SIZE_UNIT_PIXEL
|
||||
);
|
||||
addTextStyleEntry(spaceAfterBlocker);
|
||||
addTextStyleEntry(spaceAfterBlocker, depth);
|
||||
endParagraph();
|
||||
beginParagraph(true);
|
||||
ZLTextStyleEntry spaceBeforeBlocker(ZLTextStyleEntry::STYLE_OTHER_ENTRY);
|
||||
|
@ -924,7 +928,7 @@ void XHTMLReader::restartParagraph() {
|
|||
0,
|
||||
ZLTextStyleEntry::SIZE_UNIT_PIXEL
|
||||
);
|
||||
addTextStyleEntry(spaceBeforeBlocker);
|
||||
addTextStyleEntry(spaceBeforeBlocker, depth);
|
||||
}
|
||||
|
||||
void XHTMLReader::pushTextKind(FBTextKind kind) {
|
||||
|
|
|
@ -109,8 +109,8 @@ private:
|
|||
void restartParagraph();
|
||||
const XHTMLTagInfoList &tagInfos(size_t depth) 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 ZLTextStyleEntry &entry);
|
||||
void addTextStyleEntry(const std::string &tag, const std::string &aClass, unsigned char depth);
|
||||
void addTextStyleEntry(const ZLTextStyleEntry &entry, unsigned char depth);
|
||||
|
||||
void pushTextKind(FBTextKind kind);
|
||||
|
||||
|
|
|
@ -239,11 +239,11 @@ void ZLTextModel::addControl(ZLTextKind textKind, bool isStart) {
|
|||
//static int EntryCount = 0;
|
||||
//static int EntryLen = 0;
|
||||
|
||||
void ZLTextModel::addStyleEntry(const ZLTextStyleEntry &entry) {
|
||||
addStyleEntry(entry, entry.fontFamilies());
|
||||
void ZLTextModel::addStyleEntry(const ZLTextStyleEntry &entry, unsigned char depth) {
|
||||
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
|
||||
std::size_t len = 4; // entry type + feature mask
|
||||
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;
|
||||
|
||||
*address++ = entry.entryKind();
|
||||
*address++ = 0;
|
||||
*address++ = depth;
|
||||
address = ZLCachedMemoryAllocator::writeUInt16(address, entry.myFeatureMask);
|
||||
|
||||
for (int i = 0; i < ZLTextStyleEntry::NUMBER_OF_LENGTHS; ++i) {
|
||||
|
|
|
@ -67,8 +67,8 @@ public:
|
|||
ZLTextMark previousMark(ZLTextMark position) const;
|
||||
*/
|
||||
void addControl(ZLTextKind textKind, bool isStart);
|
||||
void addStyleEntry(const ZLTextStyleEntry &entry);
|
||||
void addStyleEntry(const ZLTextStyleEntry &entry, const std::vector<std::string> &fontFamilies);
|
||||
void addStyleEntry(const ZLTextStyleEntry &entry, unsigned char depth);
|
||||
void addStyleEntry(const ZLTextStyleEntry &entry, const std::vector<std::string> &fontFamilies, unsigned char depth);
|
||||
void addStyleCloseEntry();
|
||||
void addHyperlinkControl(ZLTextKind textKind, ZLHyperlinkType hyperlinkType, const std::string &label);
|
||||
void addText(const std::string &text);
|
||||
|
|
|
@ -46,8 +46,10 @@ short ZLTextStyleEntry::length(Feature featureId, const Metrics &metrics) const
|
|||
case SIZE_UNIT_PERCENT:
|
||||
switch (featureId) {
|
||||
default:
|
||||
case LENGTH_LEFT_INDENT:
|
||||
case LENGTH_RIGHT_INDENT:
|
||||
case LENGTH_MARGIN_LEFT:
|
||||
case LENGTH_MARGIN_RIGHT:
|
||||
case LENGTH_PADDING_LEFT:
|
||||
case LENGTH_PADDING_RIGHT:
|
||||
case LENGTH_FIRST_LINE_INDENT:
|
||||
return (myLengths[featureId].Size * metrics.FullWidth + 50) / 100;
|
||||
case LENGTH_SPACE_BEFORE:
|
||||
|
|
|
@ -45,7 +45,14 @@ shared_ptr<ZLTextStyleEntry> ZLTextStyleEntry::end() const {
|
|||
|
||||
shared_ptr<ZLTextStyleEntry> ZLTextStyleEntry::inherited() const {
|
||||
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) {
|
||||
clone->myLengths[i] = myLengths[i];
|
||||
}
|
||||
|
|
|
@ -62,14 +62,16 @@ public:
|
|||
};
|
||||
|
||||
enum Feature {
|
||||
LENGTH_LEFT_INDENT = 0,
|
||||
LENGTH_RIGHT_INDENT = 1,
|
||||
LENGTH_FIRST_LINE_INDENT = 2,
|
||||
LENGTH_SPACE_BEFORE = 3,
|
||||
LENGTH_SPACE_AFTER = 4,
|
||||
LENGTH_FONT_SIZE = 5,
|
||||
LENGTH_VERTICAL_ALIGN = 6,
|
||||
NUMBER_OF_LENGTHS = 7,
|
||||
LENGTH_PADDING_LEFT = 0,
|
||||
LENGTH_PADDING_RIGHT = 1,
|
||||
LENGTH_MARGIN_LEFT = 2,
|
||||
LENGTH_MARGIN_RIGHT = 3,
|
||||
LENGTH_FIRST_LINE_INDENT = 4,
|
||||
LENGTH_SPACE_BEFORE = 5,
|
||||
LENGTH_SPACE_AFTER = 6,
|
||||
LENGTH_FONT_SIZE = 7,
|
||||
LENGTH_VERTICAL_ALIGN = 8,
|
||||
NUMBER_OF_LENGTHS = 9,
|
||||
ALIGNMENT_TYPE = NUMBER_OF_LENGTHS,
|
||||
FONT_FAMILY = NUMBER_OF_LENGTHS + 1,
|
||||
FONT_STYLE_MODIFIER = NUMBER_OF_LENGTHS + 2,
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.geometerplus.zlibrary.text.model;
|
||||
|
||||
public final class ZLTextCSSStyleEntry extends ZLTextStyleEntry {
|
||||
public ZLTextCSSStyleEntry() {
|
||||
public ZLTextCSSStyleEntry(short depth) {
|
||||
super(depth);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,5 +21,6 @@ package org.geometerplus.zlibrary.text.model;
|
|||
|
||||
public final class ZLTextOtherStyleEntry extends ZLTextStyleEntry {
|
||||
public ZLTextOtherStyleEntry() {
|
||||
super((short)0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,14 +147,16 @@ public class ZLTextPlainModel implements ZLTextModel, ZLTextStyleEntry.Feature {
|
|||
}
|
||||
dataOffset = 0;
|
||||
}
|
||||
byte type = (byte)data[dataOffset];
|
||||
short first = (short)data[dataOffset];
|
||||
byte type = (byte)first;
|
||||
if (type == 0) {
|
||||
data = myStorage.block(++myDataIndex);
|
||||
if (data == null) {
|
||||
return false;
|
||||
}
|
||||
dataOffset = 0;
|
||||
type = (byte)data[0];
|
||||
first = (short)data[0];
|
||||
type = (byte)first;
|
||||
}
|
||||
myType = type;
|
||||
++dataOffset;
|
||||
|
@ -205,9 +207,10 @@ public class ZLTextPlainModel implements ZLTextModel, ZLTextStyleEntry.Feature {
|
|||
case ZLTextParagraph.Entry.STYLE_CSS:
|
||||
case ZLTextParagraph.Entry.STYLE_OTHER:
|
||||
{
|
||||
final short depth = (short)((first >> 8) & 0xFF);
|
||||
final ZLTextStyleEntry entry =
|
||||
type == ZLTextParagraph.Entry.STYLE_CSS
|
||||
? new ZLTextCSSStyleEntry()
|
||||
? new ZLTextCSSStyleEntry(depth)
|
||||
: new ZLTextOtherStyleEntry();
|
||||
|
||||
final short mask = (short)data[dataOffset++];
|
||||
|
|
|
@ -28,14 +28,16 @@ import org.geometerplus.zlibrary.core.util.ZLBoolean3;
|
|||
|
||||
public abstract class ZLTextStyleEntry {
|
||||
public interface Feature {
|
||||
int LENGTH_LEFT_INDENT = 0;
|
||||
int LENGTH_RIGHT_INDENT = 1;
|
||||
int LENGTH_FIRST_LINE_INDENT = 2;
|
||||
int LENGTH_SPACE_BEFORE = 3;
|
||||
int LENGTH_SPACE_AFTER = 4;
|
||||
int LENGTH_FONT_SIZE = 5;
|
||||
int LENGTH_VERTICAL_ALIGN = 6;
|
||||
int NUMBER_OF_LENGTHS = 7;
|
||||
int LENGTH_PADDING_LEFT = 0;
|
||||
int LENGTH_PADDING_RIGHT = 1;
|
||||
int LENGTH_MARGIN_LEFT = 2;
|
||||
int LENGTH_MARGIN_RIGHT = 3;
|
||||
int LENGTH_FIRST_LINE_INDENT = 4;
|
||||
int LENGTH_SPACE_BEFORE = 5;
|
||||
int LENGTH_SPACE_AFTER = 6;
|
||||
int LENGTH_FONT_SIZE = 7;
|
||||
int LENGTH_VERTICAL_ALIGN = 8;
|
||||
int NUMBER_OF_LENGTHS = 9;
|
||||
int ALIGNMENT_TYPE = NUMBER_OF_LENGTHS;
|
||||
int FONT_FAMILY = NUMBER_OF_LENGTHS + 1;
|
||||
int FONT_STYLE_MODIFIER = NUMBER_OF_LENGTHS + 2;
|
||||
|
@ -78,6 +80,7 @@ public abstract class ZLTextStyleEntry {
|
|||
}
|
||||
}
|
||||
|
||||
public final short Depth;
|
||||
private short myFeatureMask;
|
||||
|
||||
private Length[] myLengths = new Length[Feature.NUMBER_OF_LENGTHS];
|
||||
|
@ -91,7 +94,8 @@ public abstract class ZLTextStyleEntry {
|
|||
return (mask & (1 << featureId)) != 0;
|
||||
}
|
||||
|
||||
protected ZLTextStyleEntry() {
|
||||
protected ZLTextStyleEntry(short depth) {
|
||||
Depth = depth;
|
||||
}
|
||||
|
||||
public final boolean isFeatureSupported(int featureId) {
|
||||
|
@ -106,8 +110,10 @@ public abstract class ZLTextStyleEntry {
|
|||
private static int fullSize(ZLTextMetrics metrics, int fontSize, int featureId) {
|
||||
switch (featureId) {
|
||||
default:
|
||||
case Feature.LENGTH_LEFT_INDENT:
|
||||
case Feature.LENGTH_RIGHT_INDENT:
|
||||
case Feature.LENGTH_MARGIN_LEFT:
|
||||
case Feature.LENGTH_MARGIN_RIGHT:
|
||||
case Feature.LENGTH_PADDING_LEFT:
|
||||
case Feature.LENGTH_PADDING_RIGHT:
|
||||
case Feature.LENGTH_FIRST_LINE_INDENT:
|
||||
return metrics.FullWidth;
|
||||
case Feature.LENGTH_SPACE_BEFORE:
|
||||
|
|
|
@ -41,8 +41,17 @@ public abstract class ZLTextStyle {
|
|||
public abstract boolean isUnderline();
|
||||
public abstract boolean isStrikeThrough();
|
||||
|
||||
public abstract int getLeftIndent(ZLTextMetrics metrics);
|
||||
public abstract int getRightIndent(ZLTextMetrics metrics);
|
||||
public final int getLeftIndent(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 getLineSpacePercent();
|
||||
public abstract int getVerticalAlign(ZLTextMetrics metrics);
|
||||
|
|
|
@ -111,12 +111,22 @@ public class ZLTextBaseStyle extends ZLTextStyle {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int getLeftIndent(ZLTextMetrics metrics) {
|
||||
public int getLeftMargin(ZLTextMetrics metrics) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,8 +43,10 @@ public abstract class ZLTextDecoratedStyle extends ZLTextStyle {
|
|||
private int mySpaceBefore;
|
||||
private int mySpaceAfter;
|
||||
private int myVerticalAlign;
|
||||
private int myLeftIndent;
|
||||
private int myRightIndent;
|
||||
private int myLeftMargin;
|
||||
private int myRightMargin;
|
||||
private int myLeftPadding;
|
||||
private int myRightPadding;
|
||||
private int myFirstLineIndent;
|
||||
private ZLTextMetrics myMetrics;
|
||||
|
||||
|
@ -72,8 +74,10 @@ public abstract class ZLTextDecoratedStyle extends ZLTextStyle {
|
|||
mySpaceBefore = getSpaceBeforeInternal(metrics, myFontSize);
|
||||
mySpaceAfter = getSpaceAfterInternal(metrics, myFontSize);
|
||||
myVerticalAlign = getVerticalAlignInternal(metrics, myFontSize);
|
||||
myLeftIndent = getLeftIndentInternal(metrics, myFontSize);
|
||||
myRightIndent = getRightIndentInternal(metrics, myFontSize);
|
||||
myLeftMargin = getLeftMarginInternal(metrics, myFontSize);
|
||||
myRightMargin = getRightMarginInternal(metrics, myFontSize);
|
||||
myLeftPadding = getLeftPaddingInternal(metrics, myFontSize);
|
||||
myRightPadding = getRightPaddingInternal(metrics, myFontSize);
|
||||
myFirstLineIndent = getFirstLineIndentInternal(metrics, myFontSize);
|
||||
}
|
||||
|
||||
|
@ -159,22 +163,40 @@ public abstract class ZLTextDecoratedStyle extends ZLTextStyle {
|
|||
protected abstract int getVerticalAlignInternal(ZLTextMetrics metrics, int fontSize);
|
||||
|
||||
@Override
|
||||
public final int getLeftIndent(ZLTextMetrics metrics) {
|
||||
public final int getLeftMargin(ZLTextMetrics metrics) {
|
||||
if (!metrics.equals(myMetrics)) {
|
||||
initMetricsCache(metrics);
|
||||
}
|
||||
return myLeftIndent;
|
||||
return myLeftMargin;
|
||||
}
|
||||
protected abstract int getLeftIndentInternal(ZLTextMetrics metrics, int fontSize);
|
||||
protected abstract int getLeftMarginInternal(ZLTextMetrics metrics, int fontSize);
|
||||
|
||||
@Override
|
||||
public final int getRightIndent(ZLTextMetrics metrics) {
|
||||
public final int getRightMargin(ZLTextMetrics metrics) {
|
||||
if (!metrics.equals(myMetrics)) {
|
||||
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
|
||||
public final int getFirstLineIndent(ZLTextMetrics metrics) {
|
||||
|
|
|
@ -63,16 +63,40 @@ public class ZLTextExplicitlyDecoratedStyle extends ZLTextDecoratedStyle impleme
|
|||
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
|
||||
protected int getFontSizeInternal(ZLTextMetrics metrics) {
|
||||
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSFontSizeOption.getValue()) {
|
||||
return Parent.getFontSize(metrics);
|
||||
}
|
||||
|
||||
// Yes, Parent.Parent, not Parent (parent = current tag pre-defined size,
|
||||
// we want to override it)
|
||||
// TODO: use _previous_tag_value_
|
||||
final int baseFontSize = Parent.Parent.getFontSize(metrics);
|
||||
final int baseFontSize = getTreeParent().getFontSize(metrics);
|
||||
if (myEntry.isFeatureSupported(FONT_STYLE_MODIFIER)) {
|
||||
if (myEntry.getFontModifier(FONT_MODIFIER_INHERIT) == ZLBoolean3.B3_TRUE) {
|
||||
return baseFontSize;
|
||||
|
@ -136,26 +160,48 @@ public class ZLTextExplicitlyDecoratedStyle extends ZLTextDecoratedStyle impleme
|
|||
}
|
||||
|
||||
@Override
|
||||
public int getLeftIndentInternal(ZLTextMetrics metrics, int fontSize) {
|
||||
public int getLeftMarginInternal(ZLTextMetrics metrics, int fontSize) {
|
||||
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSMarginsOption.getValue()) {
|
||||
return Parent.getLeftIndent(metrics);
|
||||
return Parent.getLeftMargin(metrics);
|
||||
}
|
||||
|
||||
if (!myEntry.isFeatureSupported(LENGTH_LEFT_INDENT)) {
|
||||
return Parent.getLeftIndent(metrics);
|
||||
if (!myEntry.isFeatureSupported(LENGTH_MARGIN_LEFT)) {
|
||||
return Parent.getLeftMargin(metrics);
|
||||
}
|
||||
return myEntry.getLength(LENGTH_LEFT_INDENT, metrics, fontSize);
|
||||
return getTreeParent().getLeftMargin(metrics) + myEntry.getLength(LENGTH_MARGIN_LEFT, metrics, fontSize);
|
||||
}
|
||||
@Override
|
||||
public int getRightIndentInternal(ZLTextMetrics metrics, int fontSize) {
|
||||
public int getRightMarginInternal(ZLTextMetrics metrics, int fontSize) {
|
||||
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSMarginsOption.getValue()) {
|
||||
return Parent.getRightIndent(metrics);
|
||||
return Parent.getRightMargin(metrics);
|
||||
}
|
||||
|
||||
if (!myEntry.isFeatureSupported(LENGTH_RIGHT_INDENT)) {
|
||||
return Parent.getRightIndent(metrics);
|
||||
if (!myEntry.isFeatureSupported(LENGTH_MARGIN_RIGHT)) {
|
||||
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
|
||||
protected int getFirstLineIndentInternal(ZLTextMetrics metrics, int fontSize) {
|
||||
|
|
|
@ -105,12 +105,20 @@ public class ZLTextNGStyle extends ZLTextDecoratedStyle {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected int getLeftIndentInternal(ZLTextMetrics metrics, int fontSize) {
|
||||
return myDescription.getLeftIndent(metrics, Parent.getLeftIndent(metrics), fontSize);
|
||||
protected int getLeftMarginInternal(ZLTextMetrics metrics, int fontSize) {
|
||||
return myDescription.getLeftMargin(metrics, Parent.getLeftMargin(metrics), fontSize);
|
||||
}
|
||||
@Override
|
||||
protected int getRightIndentInternal(ZLTextMetrics metrics, int fontSize) {
|
||||
return myDescription.getRightIndent(metrics, Parent.getRightIndent(metrics), fontSize);
|
||||
protected int getRightMarginInternal(ZLTextMetrics metrics, int 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
|
||||
protected int getFirstLineIndentInternal(ZLTextMetrics metrics, int fontSize) {
|
||||
|
|
|
@ -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());
|
||||
if (length == null) {
|
||||
return base;
|
||||
}
|
||||
return ZLTextStyleEntry.compute(
|
||||
length, metrics, fontSize, ZLTextStyleEntry.Feature.LENGTH_LEFT_INDENT
|
||||
return base + ZLTextStyleEntry.compute(
|
||||
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());
|
||||
if (length == null) {
|
||||
return base;
|
||||
}
|
||||
return ZLTextStyleEntry.compute(
|
||||
length, metrics, fontSize, ZLTextStyleEntry.Feature.LENGTH_RIGHT_INDENT
|
||||
return base + ZLTextStyleEntry.compute(
|
||||
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) {
|
||||
final ZLTextStyleEntry.Length length = parseLength(TextIndentOption.getValue());
|
||||
if (length == null) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue