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="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="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="6" name="Epigraph" fontSizeDelta="-2" italic="true" leftIndent="80" 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="14" name="Date" leftIndent="40" 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="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="15" partial="true" name="Internal 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="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="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>
|
||||
|
|
|
@ -65,6 +65,8 @@ enum FBTextKind {
|
|||
H6 = 36,
|
||||
EXTERNAL_HYPERLINK = 37,
|
||||
//BOOK_HYPERLINK = 38,
|
||||
|
||||
XHTML_TAG_P = 51,
|
||||
};
|
||||
|
||||
#endif /* __FBTEXTKIND_H__ */
|
||||
|
|
|
@ -60,6 +60,10 @@ void XHTMLTagAction::endParagraph(XHTMLReader &reader) {
|
|||
reader.endParagraph();
|
||||
}
|
||||
|
||||
void XHTMLTagAction::restartParagraph(XHTMLReader &reader) {
|
||||
reader.restartParagraph();
|
||||
}
|
||||
|
||||
class XHTMLGlobalTagAction : public XHTMLTagAction {
|
||||
|
||||
private:
|
||||
|
@ -96,7 +100,11 @@ public:
|
|||
|
||||
class XHTMLTagParagraphAction : public XHTMLTextModeTagAction {
|
||||
|
||||
private:
|
||||
const FBTextKind myTextKind;
|
||||
|
||||
public:
|
||||
XHTMLTagParagraphAction(FBTextKind textKind = (FBTextKind)-1);
|
||||
void doAtStart(XHTMLReader &reader, const char **xmlattributes);
|
||||
void doAtEnd(XHTMLReader &reader);
|
||||
};
|
||||
|
@ -286,8 +294,14 @@ void XHTMLTagLinkAction::doAtStart(XHTMLReader &reader, const char **xmlattribut
|
|||
void XHTMLTagLinkAction::doAtEnd(XHTMLReader&) {
|
||||
}
|
||||
|
||||
XHTMLTagParagraphAction::XHTMLTagParagraphAction(FBTextKind textKind) : myTextKind(textKind) {
|
||||
}
|
||||
|
||||
void XHTMLTagParagraphAction::doAtStart(XHTMLReader &reader, const char**) {
|
||||
if (!reader.myNewParagraphInProgress) {
|
||||
if (myTextKind != -1) {
|
||||
bookReader(reader).pushKind(myTextKind);
|
||||
}
|
||||
beginParagraph(reader);
|
||||
reader.myNewParagraphInProgress = true;
|
||||
}
|
||||
|
@ -295,6 +309,9 @@ void XHTMLTagParagraphAction::doAtStart(XHTMLReader &reader, const char**) {
|
|||
|
||||
void XHTMLTagParagraphAction::doAtEnd(XHTMLReader &reader) {
|
||||
endParagraph(reader);
|
||||
if (myTextKind != -1) {
|
||||
bookReader(reader).popKind();
|
||||
}
|
||||
}
|
||||
|
||||
void XHTMLTagBodyAction::doAtStart(XHTMLReader &reader, const char**) {
|
||||
|
@ -316,8 +333,7 @@ void XHTMLTagRestartParagraphAction::doAtStart(XHTMLReader &reader, const char**
|
|||
if (reader.myCurrentParagraphIsEmpty) {
|
||||
bookReader(reader).addFixedHSpace(1);
|
||||
}
|
||||
endParagraph(reader);
|
||||
beginParagraph(reader);
|
||||
restartParagraph(reader);
|
||||
}
|
||||
|
||||
void XHTMLTagRestartParagraphAction::doAtEnd(XHTMLReader&) {
|
||||
|
@ -496,12 +512,15 @@ void XHTMLTagParagraphWithControlAction::doAtEnd(XHTMLReader &reader) {
|
|||
|
||||
void XHTMLTagPreAction::doAtStart(XHTMLReader &reader, const char**) {
|
||||
reader.myPreformatted = true;
|
||||
bookReader(reader).pushKind(XHTML_TAG_P);
|
||||
bookReader(reader).pushKind(PREFORMATTED);
|
||||
beginParagraph(reader);
|
||||
bookReader(reader).addControl(PREFORMATTED, true);
|
||||
}
|
||||
|
||||
void XHTMLTagPreAction::doAtEnd(XHTMLReader &reader) {
|
||||
endParagraph(reader);
|
||||
bookReader(reader).popKind();
|
||||
bookReader(reader).popKind();
|
||||
reader.myPreformatted = false;
|
||||
}
|
||||
|
||||
|
@ -543,7 +562,7 @@ void XHTMLReader::fillTagTable() {
|
|||
//addAction("font", new XHTMLTagAction());
|
||||
addAction("style", new XHTMLTagStyleAction());
|
||||
|
||||
addAction("p", new XHTMLTagParagraphAction());
|
||||
addAction("p", new XHTMLTagParagraphAction(XHTML_TAG_P));
|
||||
addAction("h1", new XHTMLTagParagraphWithControlAction(H1));
|
||||
addAction("h2", new XHTMLTagParagraphWithControlAction(H2));
|
||||
addAction("h3", new XHTMLTagParagraphWithControlAction(H3));
|
||||
|
@ -787,41 +806,12 @@ void XHTMLReader::endElementHandler(const char *tag) {
|
|||
void XHTMLReader::beginParagraph() {
|
||||
myCurrentParagraphIsEmpty = true;
|
||||
myModelReader.beginParagraph();
|
||||
bool doBlockSpaceBefore = false;
|
||||
for (std::vector<shared_ptr<ZLTextStyleEntry> >::const_iterator it = myStyleEntryStack.begin(); it != myStyleEntryStack.end(); ++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() {
|
||||
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) {
|
||||
addTextStyleEntry(*myStyleEntryStack.back());
|
||||
myStyleEntryStack.pop_back();
|
||||
|
@ -829,6 +819,25 @@ void XHTMLReader::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) {
|
||||
switch (myReadState) {
|
||||
case XHTML_READ_NOTHING:
|
||||
|
@ -845,11 +854,9 @@ void XHTMLReader::characterDataHandler(const char *text, std::size_t len) {
|
|||
if (myCurrentParagraphIsEmpty) {
|
||||
myModelReader.addFixedHSpace(1);
|
||||
}
|
||||
endParagraph();
|
||||
restartParagraph();
|
||||
text += 1;
|
||||
len -= 1;
|
||||
beginParagraph();
|
||||
myModelReader.addControl(PREFORMATTED, true);
|
||||
}
|
||||
std::size_t spaceCounter = 0;
|
||||
while (spaceCounter < len && std::isspace((unsigned char)*(text + spaceCounter))) {
|
||||
|
|
|
@ -59,6 +59,7 @@ protected:
|
|||
static const std::string &pathPrefix(XHTMLReader &reader);
|
||||
static void beginParagraph(XHTMLReader &reader);
|
||||
static void endParagraph(XHTMLReader &reader);
|
||||
static void restartParagraph(XHTMLReader &reader);
|
||||
};
|
||||
|
||||
class XHTMLReader : public ZLXMLReader {
|
||||
|
@ -93,6 +94,7 @@ private:
|
|||
|
||||
void beginParagraph();
|
||||
void endParagraph();
|
||||
void restartParagraph();
|
||||
bool addTextStyleEntry(const std::string tag, const std::string aClass);
|
||||
void addTextStyleEntry(const ZLTextStyleEntry &entry);
|
||||
|
||||
|
|
|
@ -60,4 +60,6 @@ public interface FBTextKind {
|
|||
byte H6 = 36;
|
||||
byte EXTERNAL_HYPERLINK = 37;
|
||||
//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 int DPI;
|
||||
public final int DefaultFontSize;
|
||||
public final int FontSize;
|
||||
public final int FontXHeight;
|
||||
public final int FullWidth;
|
||||
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;
|
||||
DefaultFontSize = defaultFontSize;
|
||||
FontSize = fontSize;
|
||||
FontXHeight = fontXHeight;
|
||||
FullWidth = fullWidth;
|
||||
FullHeight = fullHeight;
|
||||
}
|
||||
|
@ -46,14 +42,14 @@ public final class ZLTextMetrics {
|
|||
}
|
||||
final ZLTextMetrics oo = (ZLTextMetrics)o;
|
||||
return
|
||||
FontSize == oo.FontSize &&
|
||||
FontXHeight == oo.FontXHeight &&
|
||||
DPI == oo.DPI &&
|
||||
DefaultFontSize == oo.DefaultFontSize &&
|
||||
FullWidth == oo.FullWidth &&
|
||||
FullHeight == oo.FullHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
|
||||
private class Length {
|
||||
public static class Length {
|
||||
public final short Size;
|
||||
public final byte Unit;
|
||||
|
||||
Length(short size, byte unit) {
|
||||
public Length(short size, byte unit) {
|
||||
Size = size;
|
||||
Unit = unit;
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ public abstract class ZLTextStyleEntry {
|
|||
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) {
|
||||
default:
|
||||
case Feature.LENGTH_LEFT_INDENT:
|
||||
|
@ -104,26 +104,31 @@ public abstract class ZLTextStyleEntry {
|
|||
case Feature.LENGTH_SPACE_AFTER:
|
||||
return metrics.FullHeight;
|
||||
case Feature.LENGTH_FONT_SIZE:
|
||||
return metrics.FontSize;
|
||||
return fontSize;
|
||||
}
|
||||
}
|
||||
|
||||
public final int getLength(int featureId, ZLTextMetrics metrics) {
|
||||
switch (myLengths[featureId].Unit) {
|
||||
public final int getLength(int featureId, ZLTextMetrics metrics, int baseFontSize) {
|
||||
return compute(myLengths[featureId], metrics, baseFontSize, featureId);
|
||||
}
|
||||
|
||||
public static int compute(Length length, ZLTextMetrics metrics, int baseFontSize, int featureId) {
|
||||
switch (length.Unit) {
|
||||
default:
|
||||
case SizeUnit.PIXEL:
|
||||
return myLengths[featureId].Size * metrics.FontSize / metrics.DefaultFontSize;
|
||||
return length.Size * baseFontSize / metrics.DefaultFontSize;
|
||||
// we understand "point" as "1/2 point"
|
||||
case SizeUnit.POINT:
|
||||
return myLengths[featureId].Size
|
||||
* metrics.DPI * metrics.FontSize
|
||||
return length.Size
|
||||
* metrics.DPI * baseFontSize
|
||||
/ 72 / metrics.DefaultFontSize / 2;
|
||||
case SizeUnit.EM_100:
|
||||
return (myLengths[featureId].Size * metrics.FontSize + 50) / 100;
|
||||
return (length.Size * baseFontSize + 50) / 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:
|
||||
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);
|
||||
|
||||
final int strHeight = getWordHeight() + getContext().getDescent();
|
||||
final int effectiveHeight = (int) (textHeight - (getTextStyle().getSpaceBefore(metrics())
|
||||
+ getTextStyle().getSpaceAfter(metrics())) / charsPerParagraph);
|
||||
final int effectiveHeight = (int)
|
||||
(textHeight -
|
||||
(getTextStyle().getSpaceBefore(metrics())
|
||||
+ getTextStyle().getSpaceAfter(metrics()) / 2) / charsPerParagraph);
|
||||
final int linesPerPage = effectiveHeight / strHeight;
|
||||
|
||||
return charsPerLine * linesPerPage;
|
||||
|
|
|
@ -52,14 +52,9 @@ abstract class ZLTextViewBase extends ZLView {
|
|||
// be returned from this method enen in multi-thread environment
|
||||
ZLTextMetrics m = myMetrics;
|
||||
if (m == null) {
|
||||
final ZLTextStyleCollection collection = getTextStyleCollection();
|
||||
final ZLTextBaseStyle base = collection.getBaseStyle();
|
||||
m = new ZLTextMetrics(
|
||||
ZLibrary.Instance().getDisplayDPI(),
|
||||
collection.getDefaultFontSize(),
|
||||
base.getFontSize(),
|
||||
// TODO: font X height
|
||||
base.getFontSize() * 15 / 10,
|
||||
getTextStyleCollection().getDefaultFontSize(),
|
||||
// TODO: screen area width
|
||||
100,
|
||||
// TODO: screen area height
|
||||
|
@ -156,6 +151,11 @@ abstract class ZLTextViewBase extends ZLView {
|
|||
|
||||
private void applyControl(ZLTextControlElement control) {
|
||||
if (control.IsStart) {
|
||||
final ZLTextNGStyleDescription description =
|
||||
getTextStyleCollection().getDescription(control.Kind);
|
||||
if (description != null) {
|
||||
setTextStyle(new ZLTextNGStyle(myTextStyle, description));
|
||||
} else {
|
||||
final ZLTextStyleDecoration decoration =
|
||||
getTextStyleCollection().getDecoration(control.Kind);
|
||||
if (control instanceof ZLTextHyperlinkControlElement) {
|
||||
|
@ -163,6 +163,7 @@ abstract class ZLTextViewBase extends ZLView {
|
|||
} else {
|
||||
setTextStyle(decoration.createDecoratedStyle(myTextStyle));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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 =
|
||||
new ZLBooleanOption("Style", "css:textAlignment", true);
|
||||
public final ZLBooleanOption UseCSSMarginsOption =
|
||||
new ZLBooleanOption("Style", "css:margins", true);
|
||||
public final ZLBooleanOption UseCSSFontSizeOption =
|
||||
new ZLBooleanOption("Style", "css:fontSize", true);
|
||||
public final ZLBooleanOption UseCSSFontFamilyOption =
|
||||
|
|
|
@ -65,8 +65,8 @@ public abstract class ZLTextDecoratedStyle extends ZLTextStyle {
|
|||
private void initMetricsCache(ZLTextMetrics metrics) {
|
||||
myMetrics = metrics;
|
||||
myFontSize = getFontSizeInternal(metrics);
|
||||
mySpaceBefore = getSpaceBeforeInternal(metrics);
|
||||
mySpaceAfter = getSpaceAfterInternal(metrics);
|
||||
mySpaceBefore = getSpaceBeforeInternal(metrics, myFontSize);
|
||||
mySpaceAfter = getSpaceAfterInternal(metrics, myFontSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -94,7 +94,7 @@ public abstract class ZLTextDecoratedStyle extends ZLTextStyle {
|
|||
}
|
||||
return mySpaceBefore;
|
||||
}
|
||||
protected abstract int getSpaceBeforeInternal(ZLTextMetrics metrics);
|
||||
protected abstract int getSpaceBeforeInternal(ZLTextMetrics metrics, int fontSize);
|
||||
|
||||
@Override
|
||||
public final int getSpaceAfter(ZLTextMetrics metrics) {
|
||||
|
@ -103,7 +103,7 @@ public abstract class ZLTextDecoratedStyle extends ZLTextStyle {
|
|||
}
|
||||
return mySpaceAfter;
|
||||
}
|
||||
protected abstract int getSpaceAfterInternal(ZLTextMetrics metrics);
|
||||
protected abstract int getSpaceAfterInternal(ZLTextMetrics metrics, int fontSize);
|
||||
|
||||
@Override
|
||||
public final boolean isItalic() {
|
||||
|
|
|
@ -69,19 +69,22 @@ public class ZLTextExplicitlyDecoratedStyle extends ZLTextDecoratedStyle impleme
|
|||
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.getFontModifier(FONT_MODIFIER_INHERIT) == ZLBoolean3.B3_TRUE) {
|
||||
return Parent.Parent.getFontSize(metrics);
|
||||
return baseFontSize;
|
||||
}
|
||||
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) {
|
||||
return Parent.Parent.getFontSize(metrics) * 100 / 120;
|
||||
return baseFontSize * 100 / 120;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
@ -153,26 +156,26 @@ public class ZLTextExplicitlyDecoratedStyle extends ZLTextDecoratedStyle impleme
|
|||
return Parent.getVerticalShift();
|
||||
}
|
||||
@Override
|
||||
protected int getSpaceBeforeInternal(ZLTextMetrics metrics) {
|
||||
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSFontFamilyOption.getValue()) {
|
||||
protected int getSpaceBeforeInternal(ZLTextMetrics metrics, int fontSize) {
|
||||
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSMarginsOption.getValue()) {
|
||||
return Parent.getSpaceBefore(metrics);
|
||||
}
|
||||
|
||||
if (!myEntry.isFeatureSupported(LENGTH_SPACE_BEFORE)) {
|
||||
return Parent.getSpaceBefore(metrics);
|
||||
}
|
||||
return myEntry.getLength(LENGTH_SPACE_BEFORE, metrics);
|
||||
return myEntry.getLength(LENGTH_SPACE_BEFORE, metrics, fontSize);
|
||||
}
|
||||
@Override
|
||||
protected int getSpaceAfterInternal(ZLTextMetrics metrics) {
|
||||
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSFontFamilyOption.getValue()) {
|
||||
protected int getSpaceAfterInternal(ZLTextMetrics metrics, int fontSize) {
|
||||
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSMarginsOption.getValue()) {
|
||||
return Parent.getSpaceAfter(metrics);
|
||||
}
|
||||
|
||||
if (!myEntry.isFeatureSupported(LENGTH_SPACE_AFTER)) {
|
||||
return Parent.getSpaceAfter(metrics);
|
||||
}
|
||||
return myEntry.getLength(LENGTH_SPACE_AFTER, metrics);
|
||||
return myEntry.getLength(LENGTH_SPACE_AFTER, metrics, fontSize);
|
||||
}
|
||||
public byte getAlignment() {
|
||||
if (myEntry instanceof ZLTextCSSStyleEntry && !BaseStyle.UseCSSTextAlignmentOption.getValue()) {
|
||||
|
|
|
@ -54,12 +54,12 @@ public class ZLTextFullyDecoratedStyle extends ZLTextPartiallyDecoratedStyle {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected int getSpaceBeforeInternal(ZLTextMetrics metrics) {
|
||||
protected int getSpaceBeforeInternal(ZLTextMetrics metrics, int fontSize) {
|
||||
return myFullDecoration.SpaceBeforeOption.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSpaceAfterInternal(ZLTextMetrics metrics) {
|
||||
protected int getSpaceAfterInternal(ZLTextMetrics metrics, int fontSize) {
|
||||
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
|
||||
protected int getSpaceBeforeInternal(ZLTextMetrics metrics) {
|
||||
protected int getSpaceBeforeInternal(ZLTextMetrics metrics, int fontSize) {
|
||||
return Parent.getSpaceBefore(metrics);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSpaceAfterInternal(ZLTextMetrics metrics) {
|
||||
protected int getSpaceAfterInternal(ZLTextMetrics metrics, int fontSize) {
|
||||
return Parent.getSpaceAfter(metrics);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
package org.geometerplus.zlibrary.text.view.style;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.geometerplus.zlibrary.core.filesystem.ZLResourceFile;
|
||||
import org.geometerplus.zlibrary.core.library.ZLibrary;
|
||||
import org.geometerplus.zlibrary.core.util.ZLBoolean3;
|
||||
|
@ -29,10 +31,16 @@ public class ZLTextStyleCollection {
|
|||
public final String Screen;
|
||||
private int myDefaultFontSize;
|
||||
private ZLTextBaseStyle myBaseStyle;
|
||||
private final ZLTextNGStyleDescription[] myDescriptionMap = new ZLTextNGStyleDescription[256];
|
||||
private final ZLTextStyleDecoration[] myDecorationMap = new ZLTextStyleDecoration[256];
|
||||
|
||||
public ZLTextStyleCollection(String 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"));
|
||||
}
|
||||
|
||||
|
@ -44,6 +52,10 @@ public class ZLTextStyleCollection {
|
|||
return myBaseStyle;
|
||||
}
|
||||
|
||||
public ZLTextNGStyleDescription getDescription(byte kind) {
|
||||
return myDescriptionMap[kind & 0xFF];
|
||||
}
|
||||
|
||||
public ZLTextStyleDecoration getDecoration(byte kind) {
|
||||
return myDecorationMap[kind & 0xFF];
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue