mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-04 10:19:33 +02:00
CSS-like file for default styles definitions
This commit is contained in:
parent
22840e800e
commit
09f30f873f
19 changed files with 691 additions and 102 deletions
100
assets/default/styles.css
Normal file
100
assets/default/styles.css
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
p {
|
||||||
|
fbreader-id: 51;
|
||||||
|
fbreader-name: xhtml-tag-p;
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
fbreader-id: 9;
|
||||||
|
fbreader-name: "Preformatted text";
|
||||||
|
font-family: Monospace;
|
||||||
|
text-align: left;
|
||||||
|
hyphens: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
fbreader-id: 21;
|
||||||
|
fbreader-name: "Code";
|
||||||
|
font-family: Monospace;
|
||||||
|
hyphens: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
fbreader-id: 31;
|
||||||
|
fbreader-name: "Header 1";
|
||||||
|
font-size: 2em;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 0.67em;
|
||||||
|
margin-bottom: 0.67em;
|
||||||
|
hyphens: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
fbreader-id: 32;
|
||||||
|
fbreader-name: "Header 2";
|
||||||
|
font-size: 1.5em;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 0.83em;
|
||||||
|
margin-bottom: 0.83em;
|
||||||
|
hyphens: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
fbreader-id: 33;
|
||||||
|
fbreader-name: "Header 3";
|
||||||
|
font-size: 1.17em;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
fbreader-id: 34;
|
||||||
|
fbreader-name: "Header 4";
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 1.33em;
|
||||||
|
margin-bottom: 1.33em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
fbreader-id: 35;
|
||||||
|
fbreader-name: "Header 5";
|
||||||
|
font-size: 0.83em;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 1.67em;
|
||||||
|
margin-bottom: 1.67em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
fbreader-id: 36;
|
||||||
|
fbreader-name: "Header 6";
|
||||||
|
font-size: 0.67em;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 2.33em;
|
||||||
|
margin-bottom: 2.33em;
|
||||||
|
}
|
||||||
|
|
||||||
|
em {
|
||||||
|
fbreader-id: 17;
|
||||||
|
fbreader-name: "Emphasis";
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
fbreader-id: 18;
|
||||||
|
fbreader-name: "Strong";
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
fbreader-id: 27;
|
||||||
|
fbreader-name: "Italic";
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
b {
|
||||||
|
fbreader-id: 28;
|
||||||
|
fbreader-name: "Bold";
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
|
@ -6,34 +6,22 @@
|
||||||
<style id="1" name="Title" fontSizeDelta="10" bold="true" spaceBefore="2" spaceAfter="7" alignment="center" allowHyphenations="false"/>
|
<style id="1" name="Title" fontSizeDelta="10" bold="true" spaceBefore="2" spaceAfter="7" alignment="center" allowHyphenations="false"/>
|
||||||
<style id="3" name="Poem Title" fontSizeDelta="2" bold="true" spaceBefore="6" spaceAfter="6" leftIndent="40" allowHyphenations="false"/>
|
<style id="3" name="Poem Title" fontSizeDelta="2" bold="true" spaceBefore="6" spaceAfter="6" leftIndent="40" allowHyphenations="false"/>
|
||||||
<style id="2" name="Section Title" fontSizeDelta="6" bold="true" spaceAfter="5" alignment="center" allowHyphenations="false"/>
|
<style id="2" name="Section Title" fontSizeDelta="6" bold="true" spaceAfter="5" alignment="center" allowHyphenations="false"/>
|
||||||
<style id="31" name="Header 1" fontSizeDelta="6" bold="true" spaceAfter="5" alignment="center" allowHyphenations="false"/>
|
|
||||||
<style id="32" name="Header 2" fontSizeDelta="6" bold="true" spaceAfter="5" alignment="center" allowHyphenations="false"/>
|
|
||||||
<style id="5" name="Annotation" fontSizeDelta="-2" firstLineIndentDelta="dpi*0.12" allowHyphenations="true"/>
|
<style id="5" name="Annotation" fontSizeDelta="-2" firstLineIndentDelta="dpi*0.12" allowHyphenations="true"/>
|
||||||
<style id="6" name="Epigraph" fontSizeDelta="-2" italic="true" leftIndent="80" allowHyphenations="true"/>
|
<style id="6" name="Epigraph" fontSizeDelta="-2" italic="true" leftIndent="80" allowHyphenations="true"/>
|
||||||
<style id="4" name="Subtitle" bold="true" allowHyphenations="true"/>
|
<style id="4" name="Subtitle" bold="true" allowHyphenations="true"/>
|
||||||
<style id="33" name="Header 3" bold="true" allowHyphenations="true"/>
|
|
||||||
<style id="34" name="Header 4" bold="true" allowHyphenations="true"/>
|
|
||||||
<style id="13" name="Author" leftIndent="20" allowHyphenations="false"/>
|
<style id="13" name="Author" leftIndent="20" allowHyphenations="false"/>
|
||||||
<style id="14" name="Date" leftIndent="40" allowHyphenations="false"/>
|
<style id="14" name="Date" leftIndent="40" allowHyphenations="false"/>
|
||||||
<style id="7" name="Stanza" spaceBefore="6" spaceAfter="6" alignment="left" allowHyphenations="false"/>
|
<style id="7" name="Stanza" spaceBefore="6" spaceAfter="6" alignment="left" allowHyphenations="false"/>
|
||||||
<style id="8" name="Verse" leftIndent="20" alignment="left" allowHyphenations="false"/>
|
<style id="8" name="Verse" leftIndent="20" alignment="left" allowHyphenations="false"/>
|
||||||
<style id="10" name="Image" spaceBefore="8" alignment="center"/>
|
<style id="10" name="Image" spaceBefore="8" alignment="center"/>
|
||||||
<style id="9" name="Preformatted text" family="Monospace" alignment="left" allowHyphenations="false"/>
|
|
||||||
|
|
||||||
<style id="12" partial="true" name="Cite" italic="true"/>
|
<style id="12" partial="true" name="Cite" italic="true"/>
|
||||||
<style id="15" partial="true" name="Internal Hyperlink" allowHyphenations="false" underline="true"/>
|
<style id="15" partial="true" name="Internal Hyperlink" allowHyphenations="false" underline="true"/>
|
||||||
<style id="37" partial="true" name="External Hyperlink" allowHyphenations="false" underline="true"/>
|
<style id="37" partial="true" name="External Hyperlink" allowHyphenations="false" underline="true"/>
|
||||||
<style id="16" partial="true" name="Footnote" fontSizeDelta="-5" vShift="7" allowHyphenations="false"/>
|
<style id="16" partial="true" name="Footnote" fontSizeDelta="-5" vShift="7" allowHyphenations="false"/>
|
||||||
<style id="17" partial="true" name="Emphasis" italic="true"/>
|
|
||||||
<style id="18" partial="true" name="Strong" bold="true"/>
|
|
||||||
<style id="35" name="Header 5" bold="true"/>
|
|
||||||
<style id="36" name="Header 6" bold="true"/>
|
|
||||||
<style id="19" partial="true" name="Subscript" fontSizeDelta="-4" vShift="-4" allowHyphenations="false"/>
|
|
||||||
<style id="20" partial="true" name="Superscript" fontSizeDelta="-4" vShift="10" allowHyphenations="false"/>
|
|
||||||
<style id="21" partial="true" name="Code" italic="true" allowHyphenations="false"/>
|
|
||||||
<style id="22" partial="true" name="StrikeThrough" strikeThrough="true"/>
|
|
||||||
<style id="27" partial="true" name="Italic" italic="true"/>
|
|
||||||
<style id="28" partial="true" name="Bold" bold="true"/>
|
|
||||||
<style id="29" partial="true" name="Definition" italic="true"/>
|
<style id="29" partial="true" name="Definition" italic="true"/>
|
||||||
<style id="30" partial="true" name="Definition Description" italic="true"/>
|
<style id="30" partial="true" name="Definition Description" italic="true"/>
|
||||||
|
<style id="19" partial="true" name="Subscript" fontSizeDelta="-4" vShift="-4" allowHyphenations="false"/>
|
||||||
|
<style id="20" partial="true" name="Superscript" fontSizeDelta="-4" vShift="10" allowHyphenations="false"/>
|
||||||
|
<style id="22" partial="true" name="StrikeThrough" strikeThrough="true"/>
|
||||||
</DefaultStyles>
|
</DefaultStyles>
|
||||||
|
|
|
@ -65,6 +65,8 @@ enum FBTextKind {
|
||||||
H6 = 36,
|
H6 = 36,
|
||||||
EXTERNAL_HYPERLINK = 37,
|
EXTERNAL_HYPERLINK = 37,
|
||||||
//BOOK_HYPERLINK = 38,
|
//BOOK_HYPERLINK = 38,
|
||||||
|
|
||||||
|
XHTML_TAG_P = 51,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __FBTEXTKIND_H__ */
|
#endif /* __FBTEXTKIND_H__ */
|
||||||
|
|
|
@ -60,6 +60,10 @@ void XHTMLTagAction::endParagraph(XHTMLReader &reader) {
|
||||||
reader.endParagraph();
|
reader.endParagraph();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XHTMLTagAction::restartParagraph(XHTMLReader &reader) {
|
||||||
|
reader.restartParagraph();
|
||||||
|
}
|
||||||
|
|
||||||
class XHTMLGlobalTagAction : public XHTMLTagAction {
|
class XHTMLGlobalTagAction : public XHTMLTagAction {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -96,7 +100,11 @@ public:
|
||||||
|
|
||||||
class XHTMLTagParagraphAction : public XHTMLTextModeTagAction {
|
class XHTMLTagParagraphAction : public XHTMLTextModeTagAction {
|
||||||
|
|
||||||
|
private:
|
||||||
|
const FBTextKind myTextKind;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
XHTMLTagParagraphAction(FBTextKind textKind = (FBTextKind)-1);
|
||||||
void doAtStart(XHTMLReader &reader, const char **xmlattributes);
|
void doAtStart(XHTMLReader &reader, const char **xmlattributes);
|
||||||
void doAtEnd(XHTMLReader &reader);
|
void doAtEnd(XHTMLReader &reader);
|
||||||
};
|
};
|
||||||
|
@ -286,8 +294,14 @@ void XHTMLTagLinkAction::doAtStart(XHTMLReader &reader, const char **xmlattribut
|
||||||
void XHTMLTagLinkAction::doAtEnd(XHTMLReader&) {
|
void XHTMLTagLinkAction::doAtEnd(XHTMLReader&) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XHTMLTagParagraphAction::XHTMLTagParagraphAction(FBTextKind textKind) : myTextKind(textKind) {
|
||||||
|
}
|
||||||
|
|
||||||
void XHTMLTagParagraphAction::doAtStart(XHTMLReader &reader, const char**) {
|
void XHTMLTagParagraphAction::doAtStart(XHTMLReader &reader, const char**) {
|
||||||
if (!reader.myNewParagraphInProgress) {
|
if (!reader.myNewParagraphInProgress) {
|
||||||
|
if (myTextKind != -1) {
|
||||||
|
bookReader(reader).pushKind(myTextKind);
|
||||||
|
}
|
||||||
beginParagraph(reader);
|
beginParagraph(reader);
|
||||||
reader.myNewParagraphInProgress = true;
|
reader.myNewParagraphInProgress = true;
|
||||||
}
|
}
|
||||||
|
@ -295,6 +309,9 @@ void XHTMLTagParagraphAction::doAtStart(XHTMLReader &reader, const char**) {
|
||||||
|
|
||||||
void XHTMLTagParagraphAction::doAtEnd(XHTMLReader &reader) {
|
void XHTMLTagParagraphAction::doAtEnd(XHTMLReader &reader) {
|
||||||
endParagraph(reader);
|
endParagraph(reader);
|
||||||
|
if (myTextKind != -1) {
|
||||||
|
bookReader(reader).popKind();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XHTMLTagBodyAction::doAtStart(XHTMLReader &reader, const char**) {
|
void XHTMLTagBodyAction::doAtStart(XHTMLReader &reader, const char**) {
|
||||||
|
@ -316,8 +333,7 @@ void XHTMLTagRestartParagraphAction::doAtStart(XHTMLReader &reader, const char**
|
||||||
if (reader.myCurrentParagraphIsEmpty) {
|
if (reader.myCurrentParagraphIsEmpty) {
|
||||||
bookReader(reader).addFixedHSpace(1);
|
bookReader(reader).addFixedHSpace(1);
|
||||||
}
|
}
|
||||||
endParagraph(reader);
|
restartParagraph(reader);
|
||||||
beginParagraph(reader);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XHTMLTagRestartParagraphAction::doAtEnd(XHTMLReader&) {
|
void XHTMLTagRestartParagraphAction::doAtEnd(XHTMLReader&) {
|
||||||
|
@ -496,12 +512,15 @@ void XHTMLTagParagraphWithControlAction::doAtEnd(XHTMLReader &reader) {
|
||||||
|
|
||||||
void XHTMLTagPreAction::doAtStart(XHTMLReader &reader, const char**) {
|
void XHTMLTagPreAction::doAtStart(XHTMLReader &reader, const char**) {
|
||||||
reader.myPreformatted = true;
|
reader.myPreformatted = true;
|
||||||
|
bookReader(reader).pushKind(XHTML_TAG_P);
|
||||||
|
bookReader(reader).pushKind(PREFORMATTED);
|
||||||
beginParagraph(reader);
|
beginParagraph(reader);
|
||||||
bookReader(reader).addControl(PREFORMATTED, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XHTMLTagPreAction::doAtEnd(XHTMLReader &reader) {
|
void XHTMLTagPreAction::doAtEnd(XHTMLReader &reader) {
|
||||||
endParagraph(reader);
|
endParagraph(reader);
|
||||||
|
bookReader(reader).popKind();
|
||||||
|
bookReader(reader).popKind();
|
||||||
reader.myPreformatted = false;
|
reader.myPreformatted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,7 +562,7 @@ void XHTMLReader::fillTagTable() {
|
||||||
//addAction("font", new XHTMLTagAction());
|
//addAction("font", new XHTMLTagAction());
|
||||||
addAction("style", new XHTMLTagStyleAction());
|
addAction("style", new XHTMLTagStyleAction());
|
||||||
|
|
||||||
addAction("p", new XHTMLTagParagraphAction());
|
addAction("p", new XHTMLTagParagraphAction(XHTML_TAG_P));
|
||||||
addAction("h1", new XHTMLTagParagraphWithControlAction(H1));
|
addAction("h1", new XHTMLTagParagraphWithControlAction(H1));
|
||||||
addAction("h2", new XHTMLTagParagraphWithControlAction(H2));
|
addAction("h2", new XHTMLTagParagraphWithControlAction(H2));
|
||||||
addAction("h3", new XHTMLTagParagraphWithControlAction(H3));
|
addAction("h3", new XHTMLTagParagraphWithControlAction(H3));
|
||||||
|
@ -787,41 +806,12 @@ void XHTMLReader::endElementHandler(const char *tag) {
|
||||||
void XHTMLReader::beginParagraph() {
|
void XHTMLReader::beginParagraph() {
|
||||||
myCurrentParagraphIsEmpty = true;
|
myCurrentParagraphIsEmpty = true;
|
||||||
myModelReader.beginParagraph();
|
myModelReader.beginParagraph();
|
||||||
bool doBlockSpaceBefore = false;
|
|
||||||
for (std::vector<shared_ptr<ZLTextStyleEntry> >::const_iterator it = myStyleEntryStack.begin(); it != myStyleEntryStack.end(); ++it) {
|
for (std::vector<shared_ptr<ZLTextStyleEntry> >::const_iterator it = myStyleEntryStack.begin(); it != myStyleEntryStack.end(); ++it) {
|
||||||
addTextStyleEntry(**it);
|
addTextStyleEntry(**it);
|
||||||
doBlockSpaceBefore =
|
|
||||||
doBlockSpaceBefore ||
|
|
||||||
(*it)->isFeatureSupported(ZLTextStyleEntry::LENGTH_SPACE_BEFORE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (doBlockSpaceBefore) {
|
|
||||||
ZLTextStyleEntry blockingEntry(ZLTextStyleEntry::STYLE_OTHER_ENTRY);
|
|
||||||
blockingEntry.setLength(
|
|
||||||
ZLTextStyleEntry::LENGTH_SPACE_BEFORE,
|
|
||||||
0,
|
|
||||||
ZLTextStyleEntry::SIZE_UNIT_PIXEL
|
|
||||||
);
|
|
||||||
addTextStyleEntry(blockingEntry);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XHTMLReader::endParagraph() {
|
void XHTMLReader::endParagraph() {
|
||||||
bool doBlockSpaceAfter = false;
|
|
||||||
for (std::vector<shared_ptr<ZLTextStyleEntry> >::const_iterator it = myStyleEntryStack.begin(); it != myStyleEntryStack.end() - myStylesToRemove; ++it) {
|
|
||||||
doBlockSpaceAfter =
|
|
||||||
doBlockSpaceAfter ||
|
|
||||||
(*it)->isFeatureSupported(ZLTextStyleEntry::LENGTH_SPACE_AFTER);
|
|
||||||
}
|
|
||||||
if (doBlockSpaceAfter) {
|
|
||||||
ZLTextStyleEntry blockingEntry(ZLTextStyleEntry::STYLE_OTHER_ENTRY);
|
|
||||||
blockingEntry.setLength(
|
|
||||||
ZLTextStyleEntry::LENGTH_SPACE_AFTER,
|
|
||||||
0,
|
|
||||||
ZLTextStyleEntry::SIZE_UNIT_PIXEL
|
|
||||||
);
|
|
||||||
addTextStyleEntry(blockingEntry);
|
|
||||||
}
|
|
||||||
for (; myStylesToRemove > 0; --myStylesToRemove) {
|
for (; myStylesToRemove > 0; --myStylesToRemove) {
|
||||||
addTextStyleEntry(*myStyleEntryStack.back());
|
addTextStyleEntry(*myStyleEntryStack.back());
|
||||||
myStyleEntryStack.pop_back();
|
myStyleEntryStack.pop_back();
|
||||||
|
@ -829,6 +819,25 @@ void XHTMLReader::endParagraph() {
|
||||||
myModelReader.endParagraph();
|
myModelReader.endParagraph();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XHTMLReader::restartParagraph() {
|
||||||
|
ZLTextStyleEntry spaceAfterBlocker(ZLTextStyleEntry::STYLE_OTHER_ENTRY);
|
||||||
|
spaceAfterBlocker.setLength(
|
||||||
|
ZLTextStyleEntry::LENGTH_SPACE_AFTER,
|
||||||
|
0,
|
||||||
|
ZLTextStyleEntry::SIZE_UNIT_PIXEL
|
||||||
|
);
|
||||||
|
addTextStyleEntry(spaceAfterBlocker);
|
||||||
|
endParagraph();
|
||||||
|
beginParagraph();
|
||||||
|
ZLTextStyleEntry spaceBeforeBlocker(ZLTextStyleEntry::STYLE_OTHER_ENTRY);
|
||||||
|
spaceBeforeBlocker.setLength(
|
||||||
|
ZLTextStyleEntry::LENGTH_SPACE_BEFORE,
|
||||||
|
0,
|
||||||
|
ZLTextStyleEntry::SIZE_UNIT_PIXEL
|
||||||
|
);
|
||||||
|
addTextStyleEntry(spaceBeforeBlocker);
|
||||||
|
}
|
||||||
|
|
||||||
void XHTMLReader::characterDataHandler(const char *text, std::size_t len) {
|
void XHTMLReader::characterDataHandler(const char *text, std::size_t len) {
|
||||||
switch (myReadState) {
|
switch (myReadState) {
|
||||||
case XHTML_READ_NOTHING:
|
case XHTML_READ_NOTHING:
|
||||||
|
@ -845,11 +854,9 @@ void XHTMLReader::characterDataHandler(const char *text, std::size_t len) {
|
||||||
if (myCurrentParagraphIsEmpty) {
|
if (myCurrentParagraphIsEmpty) {
|
||||||
myModelReader.addFixedHSpace(1);
|
myModelReader.addFixedHSpace(1);
|
||||||
}
|
}
|
||||||
endParagraph();
|
restartParagraph();
|
||||||
text += 1;
|
text += 1;
|
||||||
len -= 1;
|
len -= 1;
|
||||||
beginParagraph();
|
|
||||||
myModelReader.addControl(PREFORMATTED, true);
|
|
||||||
}
|
}
|
||||||
std::size_t spaceCounter = 0;
|
std::size_t spaceCounter = 0;
|
||||||
while (spaceCounter < len && std::isspace((unsigned char)*(text + spaceCounter))) {
|
while (spaceCounter < len && std::isspace((unsigned char)*(text + spaceCounter))) {
|
||||||
|
|
|
@ -59,6 +59,7 @@ protected:
|
||||||
static const std::string &pathPrefix(XHTMLReader &reader);
|
static const std::string &pathPrefix(XHTMLReader &reader);
|
||||||
static void beginParagraph(XHTMLReader &reader);
|
static void beginParagraph(XHTMLReader &reader);
|
||||||
static void endParagraph(XHTMLReader &reader);
|
static void endParagraph(XHTMLReader &reader);
|
||||||
|
static void restartParagraph(XHTMLReader &reader);
|
||||||
};
|
};
|
||||||
|
|
||||||
class XHTMLReader : public ZLXMLReader {
|
class XHTMLReader : public ZLXMLReader {
|
||||||
|
@ -93,6 +94,7 @@ private:
|
||||||
|
|
||||||
void beginParagraph();
|
void beginParagraph();
|
||||||
void endParagraph();
|
void endParagraph();
|
||||||
|
void restartParagraph();
|
||||||
bool addTextStyleEntry(const std::string tag, const std::string aClass);
|
bool addTextStyleEntry(const std::string tag, const std::string aClass);
|
||||||
void addTextStyleEntry(const ZLTextStyleEntry &entry);
|
void addTextStyleEntry(const ZLTextStyleEntry &entry);
|
||||||
|
|
||||||
|
|
|
@ -60,4 +60,6 @@ public interface FBTextKind {
|
||||||
byte H6 = 36;
|
byte H6 = 36;
|
||||||
byte EXTERNAL_HYPERLINK = 37;
|
byte EXTERNAL_HYPERLINK = 37;
|
||||||
//byte BOOK_HYPERLINK = 38;
|
//byte BOOK_HYPERLINK = 38;
|
||||||
|
|
||||||
|
byte XHTML_TAG_P = 51;
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,16 +22,12 @@ package org.geometerplus.zlibrary.text.model;
|
||||||
public final class ZLTextMetrics {
|
public final class ZLTextMetrics {
|
||||||
public final int DPI;
|
public final int DPI;
|
||||||
public final int DefaultFontSize;
|
public final int DefaultFontSize;
|
||||||
public final int FontSize;
|
|
||||||
public final int FontXHeight;
|
|
||||||
public final int FullWidth;
|
public final int FullWidth;
|
||||||
public final int FullHeight;
|
public final int FullHeight;
|
||||||
|
|
||||||
public ZLTextMetrics(int dpi, int defaultFontSize, int fontSize, int fontXHeight, int fullWidth, int fullHeight) {
|
public ZLTextMetrics(int dpi, int defaultFontSize, int fullWidth, int fullHeight) {
|
||||||
DPI = dpi;
|
DPI = dpi;
|
||||||
DefaultFontSize = defaultFontSize;
|
DefaultFontSize = defaultFontSize;
|
||||||
FontSize = fontSize;
|
|
||||||
FontXHeight = fontXHeight;
|
|
||||||
FullWidth = fullWidth;
|
FullWidth = fullWidth;
|
||||||
FullHeight = fullHeight;
|
FullHeight = fullHeight;
|
||||||
}
|
}
|
||||||
|
@ -46,14 +42,14 @@ public final class ZLTextMetrics {
|
||||||
}
|
}
|
||||||
final ZLTextMetrics oo = (ZLTextMetrics)o;
|
final ZLTextMetrics oo = (ZLTextMetrics)o;
|
||||||
return
|
return
|
||||||
FontSize == oo.FontSize &&
|
DPI == oo.DPI &&
|
||||||
FontXHeight == oo.FontXHeight &&
|
DefaultFontSize == oo.DefaultFontSize &&
|
||||||
FullWidth == oo.FullWidth &&
|
FullWidth == oo.FullWidth &&
|
||||||
FullHeight == oo.FullHeight;
|
FullHeight == oo.FullHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return FontSize + 13 * (FontXHeight + 13 * (FullHeight + 13 * FullWidth));
|
return DPI + 13 * (DefaultFontSize + 13 * (FullHeight + 13 * FullWidth));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,11 +59,11 @@ public abstract class ZLTextStyleEntry {
|
||||||
byte PERCENT = 4;
|
byte PERCENT = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Length {
|
public static class Length {
|
||||||
public final short Size;
|
public final short Size;
|
||||||
public final byte Unit;
|
public final byte Unit;
|
||||||
|
|
||||||
Length(short size, byte unit) {
|
public Length(short size, byte unit) {
|
||||||
Size = size;
|
Size = size;
|
||||||
Unit = unit;
|
Unit = unit;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ public abstract class ZLTextStyleEntry {
|
||||||
myLengths[featureId] = new Length(size, unit);
|
myLengths[featureId] = new Length(size, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int fullSize(ZLTextMetrics metrics, 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_LEFT_INDENT:
|
||||||
|
@ -104,26 +104,31 @@ public abstract class ZLTextStyleEntry {
|
||||||
case Feature.LENGTH_SPACE_AFTER:
|
case Feature.LENGTH_SPACE_AFTER:
|
||||||
return metrics.FullHeight;
|
return metrics.FullHeight;
|
||||||
case Feature.LENGTH_FONT_SIZE:
|
case Feature.LENGTH_FONT_SIZE:
|
||||||
return metrics.FontSize;
|
return fontSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final int getLength(int featureId, ZLTextMetrics metrics) {
|
public final int getLength(int featureId, ZLTextMetrics metrics, int baseFontSize) {
|
||||||
switch (myLengths[featureId].Unit) {
|
return compute(myLengths[featureId], metrics, baseFontSize, featureId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int compute(Length length, ZLTextMetrics metrics, int baseFontSize, int featureId) {
|
||||||
|
switch (length.Unit) {
|
||||||
default:
|
default:
|
||||||
case SizeUnit.PIXEL:
|
case SizeUnit.PIXEL:
|
||||||
return myLengths[featureId].Size * metrics.FontSize / metrics.DefaultFontSize;
|
return length.Size * baseFontSize / metrics.DefaultFontSize;
|
||||||
// we understand "point" as "1/2 point"
|
// we understand "point" as "1/2 point"
|
||||||
case SizeUnit.POINT:
|
case SizeUnit.POINT:
|
||||||
return myLengths[featureId].Size
|
return length.Size
|
||||||
* metrics.DPI * metrics.FontSize
|
* metrics.DPI * baseFontSize
|
||||||
/ 72 / metrics.DefaultFontSize / 2;
|
/ 72 / metrics.DefaultFontSize / 2;
|
||||||
case SizeUnit.EM_100:
|
case SizeUnit.EM_100:
|
||||||
return (myLengths[featureId].Size * metrics.FontSize + 50) / 100;
|
return (length.Size * baseFontSize + 50) / 100;
|
||||||
case SizeUnit.EX_100:
|
case SizeUnit.EX_100:
|
||||||
return (myLengths[featureId].Size * metrics.FontXHeight + 50) / 100;
|
// TODO 1.5 font size => height of X
|
||||||
|
return (length.Size * baseFontSize * 3 / 2 + 50) / 100;
|
||||||
case SizeUnit.PERCENT:
|
case SizeUnit.PERCENT:
|
||||||
return (myLengths[featureId].Size * fullSize(metrics, featureId) + 50) / 100;
|
return (length.Size * fullSize(metrics, baseFontSize, featureId) + 50) / 100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -645,8 +645,10 @@ public abstract class ZLTextView extends ZLTextViewBase {
|
||||||
charsPerParagraph * 1.2f);
|
charsPerParagraph * 1.2f);
|
||||||
|
|
||||||
final int strHeight = getWordHeight() + getContext().getDescent();
|
final int strHeight = getWordHeight() + getContext().getDescent();
|
||||||
final int effectiveHeight = (int) (textHeight - (getTextStyle().getSpaceBefore(metrics())
|
final int effectiveHeight = (int)
|
||||||
+ getTextStyle().getSpaceAfter(metrics())) / charsPerParagraph);
|
(textHeight -
|
||||||
|
(getTextStyle().getSpaceBefore(metrics())
|
||||||
|
+ getTextStyle().getSpaceAfter(metrics()) / 2) / charsPerParagraph);
|
||||||
final int linesPerPage = effectiveHeight / strHeight;
|
final int linesPerPage = effectiveHeight / strHeight;
|
||||||
|
|
||||||
return charsPerLine * linesPerPage;
|
return charsPerLine * linesPerPage;
|
||||||
|
|
|
@ -52,14 +52,9 @@ abstract class ZLTextViewBase extends ZLView {
|
||||||
// be returned from this method enen in multi-thread environment
|
// be returned from this method enen in multi-thread environment
|
||||||
ZLTextMetrics m = myMetrics;
|
ZLTextMetrics m = myMetrics;
|
||||||
if (m == null) {
|
if (m == null) {
|
||||||
final ZLTextStyleCollection collection = getTextStyleCollection();
|
|
||||||
final ZLTextBaseStyle base = collection.getBaseStyle();
|
|
||||||
m = new ZLTextMetrics(
|
m = new ZLTextMetrics(
|
||||||
ZLibrary.Instance().getDisplayDPI(),
|
ZLibrary.Instance().getDisplayDPI(),
|
||||||
collection.getDefaultFontSize(),
|
getTextStyleCollection().getDefaultFontSize(),
|
||||||
base.getFontSize(),
|
|
||||||
// TODO: font X height
|
|
||||||
base.getFontSize() * 15 / 10,
|
|
||||||
// TODO: screen area width
|
// TODO: screen area width
|
||||||
100,
|
100,
|
||||||
// TODO: screen area height
|
// TODO: screen area height
|
||||||
|
@ -156,12 +151,18 @@ abstract class ZLTextViewBase extends ZLView {
|
||||||
|
|
||||||
private void applyControl(ZLTextControlElement control) {
|
private void applyControl(ZLTextControlElement control) {
|
||||||
if (control.IsStart) {
|
if (control.IsStart) {
|
||||||
final ZLTextStyleDecoration decoration =
|
final ZLTextNGStyleDescription description =
|
||||||
getTextStyleCollection().getDecoration(control.Kind);
|
getTextStyleCollection().getDescription(control.Kind);
|
||||||
if (control instanceof ZLTextHyperlinkControlElement) {
|
if (description != null) {
|
||||||
setTextStyle(decoration.createDecoratedStyle(myTextStyle, ((ZLTextHyperlinkControlElement)control).Hyperlink));
|
setTextStyle(new ZLTextNGStyle(myTextStyle, description));
|
||||||
} else {
|
} else {
|
||||||
setTextStyle(decoration.createDecoratedStyle(myTextStyle));
|
final ZLTextStyleDecoration decoration =
|
||||||
|
getTextStyleCollection().getDecoration(control.Kind);
|
||||||
|
if (control instanceof ZLTextHyperlinkControlElement) {
|
||||||
|
setTextStyle(decoration.createDecoratedStyle(myTextStyle, ((ZLTextHyperlinkControlElement)control).Hyperlink));
|
||||||
|
} else {
|
||||||
|
setTextStyle(decoration.createDecoratedStyle(myTextStyle));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setTextStyle(myTextStyle.Parent);
|
setTextStyle(myTextStyle.Parent);
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2007-2014 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geometerplus.zlibrary.text.view.style;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||||
|
|
||||||
|
class SimpleCSSReader {
|
||||||
|
private enum State {
|
||||||
|
EXPECT_SELECTOR,
|
||||||
|
EXPECT_OPEN_BRACKET,
|
||||||
|
EXPECT_NAME,
|
||||||
|
EXPECT_VALUE
|
||||||
|
}
|
||||||
|
|
||||||
|
private State myState;
|
||||||
|
private Map<Integer,ZLTextNGStyleDescription> myDescriptionMap;
|
||||||
|
private Map<String,String> myCurrentMap;
|
||||||
|
private String mySelector;
|
||||||
|
private String myName;
|
||||||
|
|
||||||
|
Map<Integer,ZLTextNGStyleDescription> read(ZLFile file) {
|
||||||
|
myDescriptionMap = new LinkedHashMap<Integer,ZLTextNGStyleDescription>();
|
||||||
|
myState = State.EXPECT_SELECTOR;
|
||||||
|
|
||||||
|
InputStream stream = null;
|
||||||
|
try {
|
||||||
|
stream = file.getInputStream();
|
||||||
|
final BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
for (String token : smartSplit(line)) {
|
||||||
|
processToken(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
} finally {
|
||||||
|
if (stream != null) {
|
||||||
|
try {
|
||||||
|
stream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return myDescriptionMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processToken(String token) {
|
||||||
|
switch (myState) {
|
||||||
|
case EXPECT_SELECTOR:
|
||||||
|
mySelector = token;
|
||||||
|
myState = State.EXPECT_OPEN_BRACKET;
|
||||||
|
break;
|
||||||
|
case EXPECT_OPEN_BRACKET:
|
||||||
|
if ("{".equals(token)) {
|
||||||
|
myCurrentMap = new HashMap<String,String>();
|
||||||
|
myState = State.EXPECT_NAME;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EXPECT_NAME:
|
||||||
|
if ("}".equals(token)) {
|
||||||
|
if (mySelector != null) {
|
||||||
|
try {
|
||||||
|
myDescriptionMap.put(
|
||||||
|
Integer.valueOf(myCurrentMap.get("fbreader-id")),
|
||||||
|
new ZLTextNGStyleDescription(mySelector, myCurrentMap)
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myState = State.EXPECT_SELECTOR;
|
||||||
|
} else {
|
||||||
|
myName = token;
|
||||||
|
myState = State.EXPECT_VALUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EXPECT_VALUE:
|
||||||
|
if (myCurrentMap != null && myName != null) {
|
||||||
|
myCurrentMap.put(myName, token);
|
||||||
|
}
|
||||||
|
myState = State.EXPECT_NAME;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> smartSplit(String line) {
|
||||||
|
final List<String> tokens = new LinkedList<String>();
|
||||||
|
final Matcher m = Pattern.compile("([^\"\\s:;]+|\".+?\")").matcher(line);
|
||||||
|
while (m.find()) {
|
||||||
|
tokens.add(m.group(1).replace("\"", ""));
|
||||||
|
}
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,6 +37,8 @@ public class ZLTextBaseStyle extends ZLTextStyle {
|
||||||
|
|
||||||
public final ZLBooleanOption UseCSSTextAlignmentOption =
|
public final ZLBooleanOption UseCSSTextAlignmentOption =
|
||||||
new ZLBooleanOption("Style", "css:textAlignment", true);
|
new ZLBooleanOption("Style", "css:textAlignment", true);
|
||||||
|
public final ZLBooleanOption UseCSSMarginsOption =
|
||||||
|
new ZLBooleanOption("Style", "css:margins", true);
|
||||||
public final ZLBooleanOption UseCSSFontSizeOption =
|
public final ZLBooleanOption UseCSSFontSizeOption =
|
||||||
new ZLBooleanOption("Style", "css:fontSize", true);
|
new ZLBooleanOption("Style", "css:fontSize", true);
|
||||||
public final ZLBooleanOption UseCSSFontFamilyOption =
|
public final ZLBooleanOption UseCSSFontFamilyOption =
|
||||||
|
|
|
@ -65,8 +65,8 @@ public abstract class ZLTextDecoratedStyle extends ZLTextStyle {
|
||||||
private void initMetricsCache(ZLTextMetrics metrics) {
|
private void initMetricsCache(ZLTextMetrics metrics) {
|
||||||
myMetrics = metrics;
|
myMetrics = metrics;
|
||||||
myFontSize = getFontSizeInternal(metrics);
|
myFontSize = getFontSizeInternal(metrics);
|
||||||
mySpaceBefore = getSpaceBeforeInternal(metrics);
|
mySpaceBefore = getSpaceBeforeInternal(metrics, myFontSize);
|
||||||
mySpaceAfter = getSpaceAfterInternal(metrics);
|
mySpaceAfter = getSpaceAfterInternal(metrics, myFontSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -94,7 +94,7 @@ public abstract class ZLTextDecoratedStyle extends ZLTextStyle {
|
||||||
}
|
}
|
||||||
return mySpaceBefore;
|
return mySpaceBefore;
|
||||||
}
|
}
|
||||||
protected abstract int getSpaceBeforeInternal(ZLTextMetrics metrics);
|
protected abstract int getSpaceBeforeInternal(ZLTextMetrics metrics, int fontSize);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final int getSpaceAfter(ZLTextMetrics metrics) {
|
public final int getSpaceAfter(ZLTextMetrics metrics) {
|
||||||
|
@ -103,7 +103,7 @@ public abstract class ZLTextDecoratedStyle extends ZLTextStyle {
|
||||||
}
|
}
|
||||||
return mySpaceAfter;
|
return mySpaceAfter;
|
||||||
}
|
}
|
||||||
protected abstract int getSpaceAfterInternal(ZLTextMetrics metrics);
|
protected abstract int getSpaceAfterInternal(ZLTextMetrics metrics, int fontSize);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final boolean isItalic() {
|
public final boolean isItalic() {
|
||||||
|
|
|
@ -69,19 +69,22 @@ public class ZLTextExplicitlyDecoratedStyle extends ZLTextDecoratedStyle impleme
|
||||||
return Parent.getFontSize(metrics);
|
return Parent.getFontSize(metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Yes, Parent.Parent, not Parent (parent = current tag pre-defined size,
|
||||||
|
// we want to override it)
|
||||||
|
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 Parent.Parent.getFontSize(metrics);
|
return baseFontSize;
|
||||||
}
|
}
|
||||||
if (myEntry.getFontModifier(FONT_MODIFIER_LARGER) == ZLBoolean3.B3_TRUE) {
|
if (myEntry.getFontModifier(FONT_MODIFIER_LARGER) == ZLBoolean3.B3_TRUE) {
|
||||||
return Parent.Parent.getFontSize(metrics) * 120 / 100;
|
return baseFontSize * 120 / 100;
|
||||||
}
|
}
|
||||||
if (myEntry.getFontModifier(FONT_MODIFIER_SMALLER) == ZLBoolean3.B3_TRUE) {
|
if (myEntry.getFontModifier(FONT_MODIFIER_SMALLER) == ZLBoolean3.B3_TRUE) {
|
||||||
return Parent.Parent.getFontSize(metrics) * 100 / 120;
|
return baseFontSize * 100 / 120;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (myEntry.isFeatureSupported(LENGTH_FONT_SIZE)) {
|
if (myEntry.isFeatureSupported(LENGTH_FONT_SIZE)) {
|
||||||
return myEntry.getLength(LENGTH_FONT_SIZE, metrics);
|
return myEntry.getLength(LENGTH_FONT_SIZE, metrics, baseFontSize);
|
||||||
}
|
}
|
||||||
return Parent.getFontSize(metrics);
|
return Parent.getFontSize(metrics);
|
||||||
}
|
}
|
||||||
|
@ -153,26 +156,26 @@ public class ZLTextExplicitlyDecoratedStyle extends ZLTextDecoratedStyle impleme
|
||||||
return Parent.getVerticalShift();
|
return Parent.getVerticalShift();
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected int getSpaceBeforeInternal(ZLTextMetrics metrics) {
|
protected int getSpaceBeforeInternal(ZLTextMetrics metrics, int fontSize) {
|
||||||
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSFontFamilyOption.getValue()) {
|
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSMarginsOption.getValue()) {
|
||||||
return Parent.getSpaceBefore(metrics);
|
return Parent.getSpaceBefore(metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!myEntry.isFeatureSupported(LENGTH_SPACE_BEFORE)) {
|
if (!myEntry.isFeatureSupported(LENGTH_SPACE_BEFORE)) {
|
||||||
return Parent.getSpaceBefore(metrics);
|
return Parent.getSpaceBefore(metrics);
|
||||||
}
|
}
|
||||||
return myEntry.getLength(LENGTH_SPACE_BEFORE, metrics);
|
return myEntry.getLength(LENGTH_SPACE_BEFORE, metrics, fontSize);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected int getSpaceAfterInternal(ZLTextMetrics metrics) {
|
protected int getSpaceAfterInternal(ZLTextMetrics metrics, int fontSize) {
|
||||||
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSFontFamilyOption.getValue()) {
|
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSMarginsOption.getValue()) {
|
||||||
return Parent.getSpaceAfter(metrics);
|
return Parent.getSpaceAfter(metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!myEntry.isFeatureSupported(LENGTH_SPACE_AFTER)) {
|
if (!myEntry.isFeatureSupported(LENGTH_SPACE_AFTER)) {
|
||||||
return Parent.getSpaceAfter(metrics);
|
return Parent.getSpaceAfter(metrics);
|
||||||
}
|
}
|
||||||
return myEntry.getLength(LENGTH_SPACE_AFTER, metrics);
|
return myEntry.getLength(LENGTH_SPACE_AFTER, metrics, fontSize);
|
||||||
}
|
}
|
||||||
public byte getAlignment() {
|
public byte getAlignment() {
|
||||||
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSTextAlignmentOption.getValue()) {
|
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSTextAlignmentOption.getValue()) {
|
||||||
|
|
|
@ -54,12 +54,12 @@ public class ZLTextFullyDecoratedStyle extends ZLTextPartiallyDecoratedStyle {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getSpaceBeforeInternal(ZLTextMetrics metrics) {
|
protected int getSpaceBeforeInternal(ZLTextMetrics metrics, int fontSize) {
|
||||||
return myFullDecoration.SpaceBeforeOption.getValue();
|
return myFullDecoration.SpaceBeforeOption.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getSpaceAfterInternal(ZLTextMetrics metrics) {
|
protected int getSpaceAfterInternal(ZLTextMetrics metrics, int fontSize) {
|
||||||
return myFullDecoration.SpaceAfterOption.getValue();
|
return myFullDecoration.SpaceAfterOption.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
161
src/org/geometerplus/zlibrary/text/view/style/ZLTextNGStyle.java
Normal file
161
src/org/geometerplus/zlibrary/text/view/style/ZLTextNGStyle.java
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2007-2014 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geometerplus.zlibrary.text.view.style;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.geometerplus.zlibrary.core.fonts.FontEntry;
|
||||||
|
import org.geometerplus.zlibrary.core.util.ZLBoolean3;
|
||||||
|
import org.geometerplus.zlibrary.text.model.ZLTextAlignmentType;
|
||||||
|
import org.geometerplus.zlibrary.text.model.ZLTextMetrics;
|
||||||
|
import org.geometerplus.zlibrary.text.view.ZLTextStyle;
|
||||||
|
|
||||||
|
public class ZLTextNGStyle extends ZLTextDecoratedStyle {
|
||||||
|
private final ZLTextNGStyleDescription myDescription;
|
||||||
|
|
||||||
|
public ZLTextNGStyle(ZLTextStyle parent, ZLTextNGStyleDescription description) {
|
||||||
|
super(parent, parent.Hyperlink);
|
||||||
|
myDescription = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<FontEntry> getFontEntriesInternal() {
|
||||||
|
final List<FontEntry> parentEntries = Parent.getFontEntries();
|
||||||
|
final String decoratedValue = myDescription.FontFamilyOption.getValue();
|
||||||
|
if ("".equals(decoratedValue)) {
|
||||||
|
return parentEntries;
|
||||||
|
}
|
||||||
|
final FontEntry e = FontEntry.systemEntry(decoratedValue);
|
||||||
|
if (parentEntries.size() > 0 && e.equals(parentEntries.get(0))) {
|
||||||
|
return parentEntries;
|
||||||
|
}
|
||||||
|
final List<FontEntry> entries = new ArrayList<FontEntry>(parentEntries.size() + 1);
|
||||||
|
entries.add(e);
|
||||||
|
entries.addAll(parentEntries);
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getFontSizeInternal(ZLTextMetrics metrics) {
|
||||||
|
return myDescription.getFontSize(metrics, Parent.getFontSize(metrics));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isBoldInternal() {
|
||||||
|
switch (myDescription.isBold()) {
|
||||||
|
case B3_TRUE:
|
||||||
|
return true;
|
||||||
|
case B3_FALSE:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return Parent.isBold();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected boolean isItalicInternal() {
|
||||||
|
switch (myDescription.isItalic()) {
|
||||||
|
case B3_TRUE:
|
||||||
|
return true;
|
||||||
|
case B3_FALSE:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return Parent.isItalic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected boolean isUnderlineInternal() {
|
||||||
|
switch (myDescription.isUnderlined()) {
|
||||||
|
case B3_TRUE:
|
||||||
|
return true;
|
||||||
|
case B3_FALSE:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return Parent.isUnderline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected boolean isStrikeThroughInternal() {
|
||||||
|
switch (myDescription.isStrikedThrough()) {
|
||||||
|
case B3_TRUE:
|
||||||
|
return true;
|
||||||
|
case B3_FALSE:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return Parent.isStrikeThrough();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLeftIndent() {
|
||||||
|
// TODO: implement
|
||||||
|
return Parent.getLeftIndent();
|
||||||
|
}
|
||||||
|
public int getRightIndent() {
|
||||||
|
// TODO: implement
|
||||||
|
return Parent.getRightIndent();
|
||||||
|
}
|
||||||
|
public int getFirstLineIndentDelta() {
|
||||||
|
// TODO: implement
|
||||||
|
return Parent.getFirstLineIndentDelta();
|
||||||
|
}
|
||||||
|
public int getLineSpacePercent() {
|
||||||
|
// TODO: implement
|
||||||
|
return Parent.getLineSpacePercent();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected int getVerticalShiftInternal() {
|
||||||
|
// TODO: implement
|
||||||
|
return Parent.getVerticalShift();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected int getSpaceBeforeInternal(ZLTextMetrics metrics, int fontSize) {
|
||||||
|
return myDescription.getSpaceBefore(metrics, Parent.getSpaceBefore(metrics), fontSize);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected int getSpaceAfterInternal(ZLTextMetrics metrics, int fontSize) {
|
||||||
|
return myDescription.getSpaceAfter(metrics, Parent.getSpaceAfter(metrics), fontSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getAlignment() {
|
||||||
|
final byte defined = myDescription.getAlignment();
|
||||||
|
if (defined != ZLTextAlignmentType.ALIGN_UNDEFINED) {
|
||||||
|
return defined;
|
||||||
|
}
|
||||||
|
return Parent.getAlignment();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean allowHyphenations() {
|
||||||
|
switch (myDescription.allowHyphenations()) {
|
||||||
|
case B3_TRUE:
|
||||||
|
return true;
|
||||||
|
case B3_FALSE:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return Parent.allowHyphenations();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ZLTextNGStyle[" + myDescription.Name + "]";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,189 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2007-2014 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geometerplus.zlibrary.text.view.style;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.geometerplus.zlibrary.core.options.ZLStringOption;
|
||||||
|
import org.geometerplus.zlibrary.core.util.ZLBoolean3;
|
||||||
|
import org.geometerplus.zlibrary.text.model.*;
|
||||||
|
|
||||||
|
public class ZLTextNGStyleDescription {
|
||||||
|
public final String Name;
|
||||||
|
|
||||||
|
public final ZLStringOption FontFamilyOption;
|
||||||
|
public final ZLStringOption FontSizeOption;
|
||||||
|
public final ZLStringOption FontWeightOption;
|
||||||
|
public final ZLStringOption FontStyleOption;
|
||||||
|
public final ZLStringOption HyphenationOption;
|
||||||
|
public final ZLStringOption MarginTopOption;
|
||||||
|
public final ZLStringOption MarginBottomOption;
|
||||||
|
public final ZLStringOption AlignmentOption;
|
||||||
|
|
||||||
|
private static ZLStringOption createOption(String selector, String name, Map<String,String> valueMap) {
|
||||||
|
return new ZLStringOption("Style", selector + "::" + name, valueMap.get(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
ZLTextNGStyleDescription(String selector, Map<String,String> valueMap) {
|
||||||
|
Name = valueMap.get("fbreader-name");
|
||||||
|
|
||||||
|
FontFamilyOption = createOption(selector, "font-family", valueMap);
|
||||||
|
FontSizeOption = createOption(selector, "font-size", valueMap);
|
||||||
|
FontWeightOption = createOption(selector, "font-weight", valueMap);
|
||||||
|
FontStyleOption = createOption(selector, "font-style", valueMap);
|
||||||
|
HyphenationOption = createOption(selector, "hyphens", valueMap);
|
||||||
|
MarginTopOption = createOption(selector, "margin-top", valueMap);
|
||||||
|
MarginBottomOption = createOption(selector, "margin-bottom", valueMap);
|
||||||
|
AlignmentOption = createOption(selector, "text-align", valueMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getFontSize(ZLTextMetrics metrics, int baseFontSize) {
|
||||||
|
final ZLTextStyleEntry.Length length = parseLength(FontSizeOption.getValue());
|
||||||
|
if (length == null) {
|
||||||
|
return baseFontSize;
|
||||||
|
}
|
||||||
|
return ZLTextStyleEntry.compute(
|
||||||
|
length, metrics, baseFontSize, ZLTextStyleEntry.Feature.LENGTH_FONT_SIZE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSpaceBefore(ZLTextMetrics metrics, int base, int fontSize) {
|
||||||
|
final ZLTextStyleEntry.Length length = parseLength(MarginTopOption.getValue());
|
||||||
|
if (length == null) {
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
return ZLTextStyleEntry.compute(
|
||||||
|
length, metrics, fontSize, ZLTextStyleEntry.Feature.LENGTH_SPACE_BEFORE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSpaceAfter(ZLTextMetrics metrics, int base, int fontSize) {
|
||||||
|
final ZLTextStyleEntry.Length length = parseLength(MarginBottomOption.getValue());
|
||||||
|
if (length == null) {
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
return ZLTextStyleEntry.compute(
|
||||||
|
length, metrics, fontSize, ZLTextStyleEntry.Feature.LENGTH_SPACE_AFTER
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZLBoolean3 isBold() {
|
||||||
|
final String fontWeight = FontWeightOption.getValue();
|
||||||
|
if ("bold".equals(fontWeight)) {
|
||||||
|
return ZLBoolean3.B3_TRUE;
|
||||||
|
} else if ("normal".equals(fontWeight)) {
|
||||||
|
return ZLBoolean3.B3_FALSE;
|
||||||
|
} else {
|
||||||
|
return ZLBoolean3.B3_UNDEFINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ZLBoolean3 isItalic() {
|
||||||
|
final String fontStyle = FontStyleOption.getValue();
|
||||||
|
if ("italic".equals(fontStyle) || "oblique".equals(fontStyle)) {
|
||||||
|
return ZLBoolean3.B3_TRUE;
|
||||||
|
} else if ("normal".equals(fontStyle)) {
|
||||||
|
return ZLBoolean3.B3_FALSE;
|
||||||
|
} else {
|
||||||
|
return ZLBoolean3.B3_UNDEFINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ZLBoolean3 isUnderlined() {
|
||||||
|
return ZLBoolean3.B3_UNDEFINED;
|
||||||
|
}
|
||||||
|
ZLBoolean3 isStrikedThrough() {
|
||||||
|
return ZLBoolean3.B3_UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte getAlignment() {
|
||||||
|
final String alignment = AlignmentOption.getValue();
|
||||||
|
if (alignment.length() == 0) {
|
||||||
|
return ZLTextAlignmentType.ALIGN_UNDEFINED;
|
||||||
|
} else if ("center".equals(alignment)) {
|
||||||
|
return ZLTextAlignmentType.ALIGN_CENTER;
|
||||||
|
} else if ("left".equals(alignment)) {
|
||||||
|
return ZLTextAlignmentType.ALIGN_LEFT;
|
||||||
|
} else if ("right".equals(alignment)) {
|
||||||
|
return ZLTextAlignmentType.ALIGN_RIGHT;
|
||||||
|
} else if ("justify".equals(alignment)) {
|
||||||
|
return ZLTextAlignmentType.ALIGN_JUSTIFY;
|
||||||
|
} else {
|
||||||
|
return ZLTextAlignmentType.ALIGN_UNDEFINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ZLBoolean3 allowHyphenations() {
|
||||||
|
final String hyphen = HyphenationOption.getValue();
|
||||||
|
if ("auto".equals(hyphen)) {
|
||||||
|
return ZLBoolean3.B3_TRUE;
|
||||||
|
} else if ("none".equals(hyphen)) {
|
||||||
|
return ZLBoolean3.B3_FALSE;
|
||||||
|
} else {
|
||||||
|
return ZLBoolean3.B3_UNDEFINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Map<String,Object> ourCache = new HashMap<String,Object>();
|
||||||
|
private static final Object ourNullObject = new Object();
|
||||||
|
private static ZLTextStyleEntry.Length parseLength(String value) {
|
||||||
|
if (value.length() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Object cached = ourCache.get(value);
|
||||||
|
if (cached != null) {
|
||||||
|
return cached == ourNullObject ? null : (ZLTextStyleEntry.Length)cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZLTextStyleEntry.Length length = null;
|
||||||
|
try {
|
||||||
|
if (value.endsWith("%")) {
|
||||||
|
length = new ZLTextStyleEntry.Length(
|
||||||
|
Short.valueOf(value.substring(0, value.length() - 1)),
|
||||||
|
ZLTextStyleEntry.SizeUnit.PERCENT
|
||||||
|
);
|
||||||
|
} else if (value.endsWith("em")) {
|
||||||
|
length = new ZLTextStyleEntry.Length(
|
||||||
|
(short)(100 * Double.valueOf(value.substring(0, value.length() - 2))),
|
||||||
|
ZLTextStyleEntry.SizeUnit.EM_100
|
||||||
|
);
|
||||||
|
} else if (value.endsWith("ex")) {
|
||||||
|
length = new ZLTextStyleEntry.Length(
|
||||||
|
(short)(100 * Double.valueOf(value.substring(0, value.length() - 2))),
|
||||||
|
ZLTextStyleEntry.SizeUnit.EX_100
|
||||||
|
);
|
||||||
|
} else if (value.endsWith("px")) {
|
||||||
|
length = new ZLTextStyleEntry.Length(
|
||||||
|
Short.valueOf(value.substring(0, value.length() - 2)),
|
||||||
|
ZLTextStyleEntry.SizeUnit.PIXEL
|
||||||
|
);
|
||||||
|
} else if (value.endsWith("pt")) {
|
||||||
|
length = new ZLTextStyleEntry.Length(
|
||||||
|
Short.valueOf(value.substring(0, value.length() - 2)),
|
||||||
|
ZLTextStyleEntry.SizeUnit.POINT
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
ourCache.put(value, length != null ? length : ourNullObject);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
}
|
|
@ -131,12 +131,12 @@ class ZLTextPartiallyDecoratedStyle extends ZLTextDecoratedStyle {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getSpaceBeforeInternal(ZLTextMetrics metrics) {
|
protected int getSpaceBeforeInternal(ZLTextMetrics metrics, int fontSize) {
|
||||||
return Parent.getSpaceBefore(metrics);
|
return Parent.getSpaceBefore(metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getSpaceAfterInternal(ZLTextMetrics metrics) {
|
protected int getSpaceAfterInternal(ZLTextMetrics metrics, int fontSize) {
|
||||||
return Parent.getSpaceAfter(metrics);
|
return Parent.getSpaceAfter(metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
package org.geometerplus.zlibrary.text.view.style;
|
package org.geometerplus.zlibrary.text.view.style;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.geometerplus.zlibrary.core.filesystem.ZLResourceFile;
|
import org.geometerplus.zlibrary.core.filesystem.ZLResourceFile;
|
||||||
import org.geometerplus.zlibrary.core.library.ZLibrary;
|
import org.geometerplus.zlibrary.core.library.ZLibrary;
|
||||||
import org.geometerplus.zlibrary.core.util.ZLBoolean3;
|
import org.geometerplus.zlibrary.core.util.ZLBoolean3;
|
||||||
|
@ -29,10 +31,16 @@ public class ZLTextStyleCollection {
|
||||||
public final String Screen;
|
public final String Screen;
|
||||||
private int myDefaultFontSize;
|
private int myDefaultFontSize;
|
||||||
private ZLTextBaseStyle myBaseStyle;
|
private ZLTextBaseStyle myBaseStyle;
|
||||||
|
private final ZLTextNGStyleDescription[] myDescriptionMap = new ZLTextNGStyleDescription[256];
|
||||||
private final ZLTextStyleDecoration[] myDecorationMap = new ZLTextStyleDecoration[256];
|
private final ZLTextStyleDecoration[] myDecorationMap = new ZLTextStyleDecoration[256];
|
||||||
|
|
||||||
public ZLTextStyleCollection(String screen) {
|
public ZLTextStyleCollection(String screen) {
|
||||||
Screen = screen;
|
Screen = screen;
|
||||||
|
final Map<Integer,ZLTextNGStyleDescription> descriptions =
|
||||||
|
new SimpleCSSReader().read(ZLResourceFile.createResourceFile("default/styles.css"));
|
||||||
|
for (Map.Entry<Integer,ZLTextNGStyleDescription> entry : descriptions.entrySet()) {
|
||||||
|
myDescriptionMap[entry.getKey() & 0xFF] = entry.getValue();
|
||||||
|
}
|
||||||
new TextStyleReader().readQuietly(ZLResourceFile.createResourceFile("default/styles.xml"));
|
new TextStyleReader().readQuietly(ZLResourceFile.createResourceFile("default/styles.xml"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +52,10 @@ public class ZLTextStyleCollection {
|
||||||
return myBaseStyle;
|
return myBaseStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ZLTextNGStyleDescription getDescription(byte kind) {
|
||||||
|
return myDescriptionMap[kind & 0xFF];
|
||||||
|
}
|
||||||
|
|
||||||
public ZLTextStyleDecoration getDecoration(byte kind) {
|
public ZLTextStyleDecoration getDecoration(byte kind) {
|
||||||
return myDecorationMap[kind & 0xFF];
|
return myDecorationMap[kind & 0xFF];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue