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

CSS-like file for default styles definitions

This commit is contained in:
Nikolay Pultsin 2014-06-05 06:36:25 +01:00
parent 22840e800e
commit 09f30f873f
19 changed files with 691 additions and 102 deletions

100
assets/default/styles.css Normal file
View 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;
}

View file

@ -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>

View file

@ -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__ */

View file

@ -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))) {

View file

@ -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);

View file

@ -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;
}; };

View file

@ -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));
} }
} }

View file

@ -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;
} }
} }

View file

@ -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;

View file

@ -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,6 +151,11 @@ abstract class ZLTextViewBase extends ZLView {
private void applyControl(ZLTextControlElement control) { private void applyControl(ZLTextControlElement control) {
if (control.IsStart) { if (control.IsStart) {
final ZLTextNGStyleDescription description =
getTextStyleCollection().getDescription(control.Kind);
if (description != null) {
setTextStyle(new ZLTextNGStyle(myTextStyle, description));
} else {
final ZLTextStyleDecoration decoration = final ZLTextStyleDecoration decoration =
getTextStyleCollection().getDecoration(control.Kind); getTextStyleCollection().getDecoration(control.Kind);
if (control instanceof ZLTextHyperlinkControlElement) { if (control instanceof ZLTextHyperlinkControlElement) {
@ -163,6 +163,7 @@ abstract class ZLTextViewBase extends ZLView {
} else { } else {
setTextStyle(decoration.createDecoratedStyle(myTextStyle)); setTextStyle(decoration.createDecoratedStyle(myTextStyle));
} }
}
} else { } else {
setTextStyle(myTextStyle.Parent); setTextStyle(myTextStyle.Parent);
} }

View file

@ -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;
}
}

View file

@ -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 =

View file

@ -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() {

View file

@ -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()) {

View file

@ -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();
} }

View 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 + "]";
}
}

View file

@ -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;
}
}

View file

@ -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);
} }

View file

@ -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];
} }