1
0
Fork 0
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:
Nikolay Pultsin 2012-05-09 03:48:14 +01:00
parent cbf156e8d5
commit c281770998
10 changed files with 100 additions and 74 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -194,15 +194,9 @@ public class ZLTextPlainModel implements ZLTextModel, ZLTextStyleEntry.Feature {
entry.setLength(i, size, unit);
}
}
if (ZLTextStyleEntry.isFeatureSupported(mask, ALIGNMENT_TYPE) ||
ZLTextStyleEntry.isFeatureSupported(mask, FONT_SIZE_MAGNIFICATION)) {
if (ZLTextStyleEntry.isFeatureSupported(mask, ALIGNMENT_TYPE)) {
final short value = (short)data[dataOffset++];
if (ZLTextStyleEntry.isFeatureSupported(mask, ALIGNMENT_TYPE)) {
entry.setAlignmentType((byte)(value & 0xFF));
}
if (ZLTextStyleEntry.isFeatureSupported(mask, FONT_SIZE_MAGNIFICATION)) {
entry.setFontSizeMagnification((byte)((value >> 8) & 0xFF));
}
entry.setAlignmentType((byte)(value & 0xFF));
}
if (ZLTextStyleEntry.isFeatureSupported(mask, FONT_FAMILY)) {
final short familyLength = (short)data[dataOffset++];

View file

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

View file

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