mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-05 19:42:17 +02:00
CSS support (in progress)
This commit is contained in:
parent
cbf156e8d5
commit
c281770998
10 changed files with 100 additions and 74 deletions
2
TODO.1.5
2
TODO.1.5
|
@ -34,6 +34,7 @@ DONE encodings list for native plugins
|
|||
DONE parse tag lists like 'h1,h2,h3'
|
||||
** "metric" style params
|
||||
** font size
|
||||
DONE font size: smaller and larger
|
||||
** underline
|
||||
** strikethrough
|
||||
** embedded fonts
|
||||
|
@ -43,6 +44,7 @@ DONE encodings list for native plugins
|
|||
** embedded tags in selectors (h2 p { font-family: helvetica })
|
||||
** colors
|
||||
** backgrounds
|
||||
** don't apply "fbreader internal" font size settings before CSS "smaller" or "larger"
|
||||
* предупреждение "не могу открыть зашифрованный файл"
|
||||
* API от Paragon
|
||||
* Two-page view
|
||||
|
|
|
@ -75,7 +75,7 @@ static bool parseLength(const std::string &toParse, short &size, ZLTextStyleEntr
|
|||
return false;
|
||||
}
|
||||
|
||||
void StyleSheetTable::setLength(ZLTextStyleEntry &entry, ZLTextStyleEntry::Feature fetureId, const AttributeMap &map, const std::string &attributeName) {
|
||||
void StyleSheetTable::setLength(ZLTextStyleEntry &entry, ZLTextStyleEntry::Feature featureId, const AttributeMap &map, const std::string &attributeName) {
|
||||
StyleSheetTable::AttributeMap::const_iterator it = map.find(attributeName);
|
||||
if (it == map.end()) {
|
||||
return;
|
||||
|
@ -85,7 +85,7 @@ void StyleSheetTable::setLength(ZLTextStyleEntry &entry, ZLTextStyleEntry::Featu
|
|||
short size;
|
||||
ZLTextStyleEntry::SizeUnit unit;
|
||||
if (parseLength(values[0], size, unit)) {
|
||||
entry.setLength(fetureId, size, unit);
|
||||
entry.setLength(featureId, size, unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -195,20 +195,34 @@ shared_ptr<ZLTextStyleEntry> StyleSheetTable::createControl(const AttributeMap &
|
|||
|
||||
const std::vector<std::string> &fontSize = values(styles, "font-size");
|
||||
if (!fontSize.empty()) {
|
||||
bool doSetFontSize = true;
|
||||
short size = 100;
|
||||
ZLTextStyleEntry::SizeUnit unit = ZLTextStyleEntry::SIZE_UNIT_PERCENT;
|
||||
if (fontSize[0] == "xx-small") {
|
||||
entry->setFontSizeMagnification(-3);
|
||||
size = 58;
|
||||
} else if (fontSize[0] == "x-small") {
|
||||
entry->setFontSizeMagnification(-2);
|
||||
size = 69;
|
||||
} else if (fontSize[0] == "small") {
|
||||
entry->setFontSizeMagnification(-1);
|
||||
size = 83;
|
||||
} else if (fontSize[0] == "medium") {
|
||||
entry->setFontSizeMagnification(0);
|
||||
size = 100;
|
||||
} else if (fontSize[0] == "large") {
|
||||
entry->setFontSizeMagnification(1);
|
||||
size = 120;
|
||||
} else if (fontSize[0] == "x-large") {
|
||||
entry->setFontSizeMagnification(2);
|
||||
size = 144;
|
||||
} else if (fontSize[0] == "xx-large") {
|
||||
entry->setFontSizeMagnification(3);
|
||||
size = 173;
|
||||
} else if (fontSize[0] == "smaller") {
|
||||
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_SMALLER, true);
|
||||
doSetFontSize = false;
|
||||
} else if (fontSize[0] == "larger") {
|
||||
entry->setFontModifier(ZLTextStyleEntry::FONT_MODIFIER_LARGER, true);
|
||||
doSetFontSize = false;
|
||||
} else if (!parseLength(fontSize[0], size, unit)) {
|
||||
doSetFontSize = false;
|
||||
}
|
||||
if (doSetFontSize) {
|
||||
entry->setLength(ZLTextStyleEntry::LENGTH_FONT_SIZE, size, unit);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -508,12 +508,14 @@ bool XHTMLReader::readFile(const ZLFile &file, const std::string &referenceName)
|
|||
return readDocument(file);
|
||||
}
|
||||
|
||||
void XHTMLReader::addStyleEntry(const std::string tag, const std::string aClass) {
|
||||
bool XHTMLReader::addStyleEntry(const std::string tag, const std::string aClass) {
|
||||
shared_ptr<ZLTextStyleEntry> entry = myStyleSheetTable.control(tag, aClass);
|
||||
if (!entry.isNull()) {
|
||||
myModelReader.addStyleEntry(*entry);
|
||||
myStyleEntryStack.push_back(entry);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void XHTMLReader::startElementHandler(const char *tag, const char **attributes) {
|
||||
|
@ -548,6 +550,7 @@ void XHTMLReader::startElementHandler(const char *tag, const char **attributes)
|
|||
shared_ptr<ZLTextStyleEntry> entry = myStyleParser.parseString(style);
|
||||
myModelReader.addStyleEntry(*entry);
|
||||
myStyleEntryStack.push_back(entry);
|
||||
} else {
|
||||
}
|
||||
myCSSStack.push_back(myStyleEntryStack.size() - sizeBefore);
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ private:
|
|||
|
||||
void beginParagraph();
|
||||
void endParagraph();
|
||||
void addStyleEntry(const std::string tag, const std::string aClass);
|
||||
bool addStyleEntry(const std::string tag, const std::string aClass);
|
||||
|
||||
private:
|
||||
BookReader &myModelReader;
|
||||
|
|
|
@ -279,8 +279,7 @@ void ZLTextModel::addStyleEntry(const ZLTextStyleEntry &entry) {
|
|||
len += 4; // each supported length
|
||||
}
|
||||
}
|
||||
if (entry.isFeatureSupported(ZLTextStyleEntry::ALIGNMENT_TYPE) ||
|
||||
entry.isFeatureSupported(ZLTextStyleEntry::FONT_SIZE_MAGNIFICATION)) {
|
||||
if (entry.isFeatureSupported(ZLTextStyleEntry::ALIGNMENT_TYPE)) {
|
||||
len += 2;
|
||||
}
|
||||
ZLUnicodeUtil::Ucs2String fontFamily;
|
||||
|
@ -319,10 +318,9 @@ void ZLTextModel::addStyleEntry(const ZLTextStyleEntry &entry) {
|
|||
*address++ = 0;
|
||||
}
|
||||
}
|
||||
if (entry.isFeatureSupported(ZLTextStyleEntry::ALIGNMENT_TYPE) ||
|
||||
entry.isFeatureSupported(ZLTextStyleEntry::FONT_SIZE_MAGNIFICATION)) {
|
||||
if (entry.isFeatureSupported(ZLTextStyleEntry::ALIGNMENT_TYPE)) {
|
||||
*address++ = entry.myAlignmentType;
|
||||
*address++ = entry.myFontSizeMagnification;
|
||||
*address++ = 0;
|
||||
}
|
||||
if (entry.isFeatureSupported(ZLTextStyleEntry::FONT_FAMILY)) {
|
||||
address = ZLCachedMemoryAllocator::writeString(address, fontFamily);
|
||||
|
|
|
@ -49,6 +49,8 @@ short ZLTextStyleEntry::length(Feature featureId, const Metrics &metrics) const
|
|||
case LENGTH_SPACE_BEFORE:
|
||||
case LENGTH_SPACE_AFTER:
|
||||
return (myLengths[featureId].Size * metrics.FullHeight + 50) / 100;
|
||||
case LENGTH_FONT_SIZE:
|
||||
return (myLengths[featureId].Size * metrics.FontSize + 50) / 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,8 @@ public:
|
|||
FONT_MODIFIER_UNDERLINED = 1 << 2,
|
||||
FONT_MODIFIER_STRIKEDTHROUGH = 1 << 3,
|
||||
FONT_MODIFIER_SMALLCAPS = 1 << 4,
|
||||
FONT_MODIFIER_SMALLER = 1 << 5,
|
||||
FONT_MODIFIER_LARGER = 1 << 6,
|
||||
};
|
||||
|
||||
enum Feature {
|
||||
|
@ -59,11 +61,11 @@ public:
|
|||
LENGTH_FIRST_LINE_INDENT_DELTA = 2,
|
||||
LENGTH_SPACE_BEFORE = 3,
|
||||
LENGTH_SPACE_AFTER = 4,
|
||||
NUMBER_OF_LENGTHS = 5,
|
||||
LENGTH_FONT_SIZE = 5,
|
||||
NUMBER_OF_LENGTHS = 6,
|
||||
ALIGNMENT_TYPE = NUMBER_OF_LENGTHS,
|
||||
FONT_SIZE_MAGNIFICATION = NUMBER_OF_LENGTHS + 1,
|
||||
FONT_FAMILY = NUMBER_OF_LENGTHS + 2,
|
||||
FONT_STYLE_MODIFIER = NUMBER_OF_LENGTHS + 3,
|
||||
FONT_FAMILY = NUMBER_OF_LENGTHS + 1,
|
||||
FONT_STYLE_MODIFIER = NUMBER_OF_LENGTHS + 2,
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -89,9 +91,6 @@ public:
|
|||
ZLBoolean3 fontModifier(FontModifier modifier) const;
|
||||
void setFontModifier(FontModifier modifier, bool on);
|
||||
|
||||
signed char fontSizeMagnification() const;
|
||||
void setFontSizeMagnification(signed char fontSizeMagnification);
|
||||
|
||||
const std::string &fontFamily() const;
|
||||
void setFontFamily(const std::string &fontFamily);
|
||||
|
||||
|
@ -102,13 +101,12 @@ private:
|
|||
ZLTextAlignmentType myAlignmentType;
|
||||
unsigned char mySupportedFontModifier;
|
||||
unsigned char myFontModifier;
|
||||
signed char myFontSizeMagnification;
|
||||
std::string myFontFamily;
|
||||
|
||||
friend class ZLTextModel;
|
||||
};
|
||||
|
||||
inline ZLTextStyleEntry::ZLTextStyleEntry() : myFeatureMask(0), myAlignmentType(ALIGN_UNDEFINED), mySupportedFontModifier(0), myFontModifier(0), myFontSizeMagnification(0) {}
|
||||
inline ZLTextStyleEntry::ZLTextStyleEntry() : myFeatureMask(0), myAlignmentType(ALIGN_UNDEFINED), mySupportedFontModifier(0), myFontModifier(0) {}
|
||||
inline ZLTextStyleEntry::~ZLTextStyleEntry() {}
|
||||
|
||||
inline ZLTextStyleEntry::Metrics::Metrics(int fontSize, int fontXHeight, int fullWidth, int fullHeight) : FontSize(fontSize), FontXHeight(fontXHeight), FullWidth(fullWidth), FullHeight(fullHeight) {}
|
||||
|
@ -146,12 +144,6 @@ inline void ZLTextStyleEntry::setFontModifier(FontModifier modifier, bool on) {
|
|||
}
|
||||
}
|
||||
|
||||
inline signed char ZLTextStyleEntry::fontSizeMagnification() const { return myFontSizeMagnification; }
|
||||
inline void ZLTextStyleEntry::setFontSizeMagnification(signed char fontSizeMagnification) {
|
||||
myFeatureMask |= 1 << FONT_SIZE_MAGNIFICATION;
|
||||
myFontSizeMagnification = fontSizeMagnification;
|
||||
}
|
||||
|
||||
inline const std::string &ZLTextStyleEntry::fontFamily() const { return myFontFamily; }
|
||||
inline void ZLTextStyleEntry::setFontFamily(const std::string &fontFamily) {
|
||||
myFeatureMask |= 1 << FONT_FAMILY;
|
||||
|
|
|
@ -194,16 +194,10 @@ public class ZLTextPlainModel implements ZLTextModel, ZLTextStyleEntry.Feature {
|
|||
entry.setLength(i, size, unit);
|
||||
}
|
||||
}
|
||||
if (ZLTextStyleEntry.isFeatureSupported(mask, ALIGNMENT_TYPE) ||
|
||||
ZLTextStyleEntry.isFeatureSupported(mask, FONT_SIZE_MAGNIFICATION)) {
|
||||
final short value = (short)data[dataOffset++];
|
||||
if (ZLTextStyleEntry.isFeatureSupported(mask, ALIGNMENT_TYPE)) {
|
||||
final short value = (short)data[dataOffset++];
|
||||
entry.setAlignmentType((byte)(value & 0xFF));
|
||||
}
|
||||
if (ZLTextStyleEntry.isFeatureSupported(mask, FONT_SIZE_MAGNIFICATION)) {
|
||||
entry.setFontSizeMagnification((byte)((value >> 8) & 0xFF));
|
||||
}
|
||||
}
|
||||
if (ZLTextStyleEntry.isFeatureSupported(mask, FONT_FAMILY)) {
|
||||
final short familyLength = (short)data[dataOffset++];
|
||||
entry.setFontFamily(new String(data, dataOffset, familyLength));
|
||||
|
|
|
@ -28,11 +28,11 @@ public final class ZLTextStyleEntry {
|
|||
int LENGTH_FIRST_LINE_INDENT_DELTA = 2;
|
||||
int LENGTH_SPACE_BEFORE = 3;
|
||||
int LENGTH_SPACE_AFTER = 4;
|
||||
int NUMBER_OF_LENGTHS = 5;
|
||||
int LENGTH_FONT_SIZE = 5;
|
||||
int NUMBER_OF_LENGTHS = 6;
|
||||
int ALIGNMENT_TYPE = NUMBER_OF_LENGTHS;
|
||||
int FONT_SIZE_MAGNIFICATION = NUMBER_OF_LENGTHS + 1;
|
||||
int FONT_FAMILY = NUMBER_OF_LENGTHS + 2;
|
||||
int FONT_STYLE_MODIFIER = NUMBER_OF_LENGTHS + 3;
|
||||
int FONT_FAMILY = NUMBER_OF_LENGTHS + 1;
|
||||
int FONT_STYLE_MODIFIER = NUMBER_OF_LENGTHS + 2;
|
||||
}
|
||||
|
||||
public interface FontModifier {
|
||||
|
@ -41,16 +41,32 @@ public final class ZLTextStyleEntry {
|
|||
byte FONT_MODIFIER_UNDERLINED = 1 << 2;
|
||||
byte FONT_MODIFIER_STRIKEDTHROUGH = 1 << 3;
|
||||
byte FONT_MODIFIER_SMALLCAPS = 1 << 4;
|
||||
byte FONT_MODIFIER_SMALLER = 1 << 5;
|
||||
byte FONT_MODIFIER_LARGER = 1 << 6;
|
||||
}
|
||||
|
||||
public interface SizeUnit {
|
||||
byte SIZE_UNIT_PIXEL = 0;
|
||||
byte SIZE_UNIT_EM_100 = 1;
|
||||
byte SIZE_UNIT_EX_100 = 2;
|
||||
byte SIZE_UNIT_PERCENT = 3;
|
||||
byte PIXEL = 0;
|
||||
byte EM_100 = 1;
|
||||
byte EX_100 = 2;
|
||||
byte PERCENT = 3;
|
||||
}
|
||||
|
||||
class Length {
|
||||
public class Metrics {
|
||||
public final int FontSize;
|
||||
public final int FontXHeight;
|
||||
public final int FullWidth;
|
||||
public final int FullHeight;
|
||||
|
||||
public Metrics(int fontSize, int fontXHeight, int fullWidth, int fullHeight) {
|
||||
FontSize = fontSize;
|
||||
FontXHeight = fontXHeight;
|
||||
FullWidth = fullWidth;
|
||||
FullHeight = fullHeight;
|
||||
}
|
||||
}
|
||||
|
||||
private class Length {
|
||||
public final short Size;
|
||||
public final byte Unit;
|
||||
|
||||
|
@ -64,7 +80,6 @@ public final class ZLTextStyleEntry {
|
|||
|
||||
private Length[] myLengths = new Length[Feature.NUMBER_OF_LENGTHS];
|
||||
private byte myAlignmentType;
|
||||
private byte myFontSizeMagnification;
|
||||
private String myFontFamily;
|
||||
private byte mySupportedFontModifiers;
|
||||
private byte myFontModifiers;
|
||||
|
@ -85,11 +100,30 @@ public final class ZLTextStyleEntry {
|
|||
myLengths[featureId] = new Length(size, unit);
|
||||
}
|
||||
|
||||
/*
|
||||
public Length getLength(int featureId) {
|
||||
return myLengths[featureId];
|
||||
public int getLength(int featureId, Metrics metrics) {
|
||||
switch (myLengths[featureId].Unit) {
|
||||
default:
|
||||
case SizeUnit.PIXEL:
|
||||
return myLengths[featureId].Size;
|
||||
case SizeUnit.EM_100:
|
||||
return (myLengths[featureId].Size * metrics.FontSize + 50) / 100;
|
||||
case SizeUnit.EX_100:
|
||||
return (myLengths[featureId].Size * metrics.FontXHeight + 50) / 100;
|
||||
case SizeUnit.PERCENT:
|
||||
switch (featureId) {
|
||||
default:
|
||||
case Feature.LENGTH_LEFT_INDENT:
|
||||
case Feature.LENGTH_RIGHT_INDENT:
|
||||
case Feature.LENGTH_FIRST_LINE_INDENT_DELTA:
|
||||
return (myLengths[featureId].Size * metrics.FullWidth + 50) / 100;
|
||||
case Feature.LENGTH_SPACE_BEFORE:
|
||||
case Feature.LENGTH_SPACE_AFTER:
|
||||
return (myLengths[featureId].Size * metrics.FullHeight + 50) / 100;
|
||||
case Feature.LENGTH_FONT_SIZE:
|
||||
return (myLengths[featureId].Size * metrics.FontSize + 50) / 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void setAlignmentType(byte alignmentType) {
|
||||
myFeatureMask |= 1 << Feature.ALIGNMENT_TYPE;
|
||||
|
@ -100,15 +134,6 @@ public final class ZLTextStyleEntry {
|
|||
return myAlignmentType;
|
||||
}
|
||||
|
||||
void setFontSizeMagnification(byte fontSizeMagnification) {
|
||||
myFeatureMask |= 1 << Feature.FONT_SIZE_MAGNIFICATION;
|
||||
myFontSizeMagnification = fontSizeMagnification;
|
||||
}
|
||||
|
||||
public byte getFontSizeMagnification() {
|
||||
return myFontSizeMagnification;
|
||||
}
|
||||
|
||||
void setFontFamily(String fontFamily) {
|
||||
myFeatureMask |= 1 << Feature.FONT_FAMILY;
|
||||
myFontFamily = fontFamily;
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
package org.geometerplus.zlibrary.text.view.style;
|
||||
|
||||
import org.geometerplus.zlibrary.core.util.ZLBoolean3;
|
||||
|
||||
import org.geometerplus.zlibrary.text.view.ZLTextStyle;
|
||||
import org.geometerplus.zlibrary.text.model.ZLTextStyleEntry;
|
||||
|
||||
|
@ -35,14 +37,17 @@ public class ZLTextExplicitlyDecoratedStyle extends ZLTextStyle implements ZLTex
|
|||
return Base.getFontFamily();
|
||||
}
|
||||
public int getFontSize() {
|
||||
if (myEntry.getFontModifier(FONT_MODIFIER_LARGER) == ZLBoolean3.B3_TRUE) {
|
||||
return Base.getFontSize() * 120 / 100;
|
||||
}
|
||||
if (myEntry.getFontModifier(FONT_MODIFIER_SMALLER) == ZLBoolean3.B3_TRUE) {
|
||||
return Base.getFontSize() * 100 / 120;
|
||||
}
|
||||
// TODO: implement
|
||||
return Base.getFontSize();
|
||||
}
|
||||
|
||||
public boolean isBold() {
|
||||
if (!myEntry.isFeatureSupported(FONT_STYLE_MODIFIER)) {
|
||||
return Base.isBold();
|
||||
}
|
||||
switch (myEntry.getFontModifier(FONT_MODIFIER_BOLD)) {
|
||||
case B3_TRUE:
|
||||
return true;
|
||||
|
@ -53,9 +58,6 @@ public class ZLTextExplicitlyDecoratedStyle extends ZLTextStyle implements ZLTex
|
|||
}
|
||||
}
|
||||
public boolean isItalic() {
|
||||
if (!myEntry.isFeatureSupported(FONT_STYLE_MODIFIER)) {
|
||||
return Base.isItalic();
|
||||
}
|
||||
switch (myEntry.getFontModifier(FONT_MODIFIER_ITALIC)) {
|
||||
case B3_TRUE:
|
||||
return true;
|
||||
|
@ -66,9 +68,6 @@ public class ZLTextExplicitlyDecoratedStyle extends ZLTextStyle implements ZLTex
|
|||
}
|
||||
}
|
||||
public boolean isUnderline() {
|
||||
if (!myEntry.isFeatureSupported(FONT_STYLE_MODIFIER)) {
|
||||
return Base.isUnderline();
|
||||
}
|
||||
switch (myEntry.getFontModifier(FONT_MODIFIER_UNDERLINED)) {
|
||||
case B3_TRUE:
|
||||
return true;
|
||||
|
@ -79,9 +78,6 @@ public class ZLTextExplicitlyDecoratedStyle extends ZLTextStyle implements ZLTex
|
|||
}
|
||||
}
|
||||
public boolean isStrikeThrough() {
|
||||
if (!myEntry.isFeatureSupported(FONT_STYLE_MODIFIER)) {
|
||||
return Base.isStrikeThrough();
|
||||
}
|
||||
switch (myEntry.getFontModifier(FONT_MODIFIER_STRIKEDTHROUGH)) {
|
||||
case B3_TRUE:
|
||||
return true;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue