1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-05 10:49:24 +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' DONE parse tag lists like 'h1,h2,h3'
** "metric" style params ** "metric" style params
** font size ** font size
DONE font size: smaller and larger
** underline ** underline
** strikethrough ** strikethrough
** embedded fonts ** embedded fonts
@ -43,6 +44,7 @@ DONE encodings list for native plugins
** embedded tags in selectors (h2 p { font-family: helvetica }) ** embedded tags in selectors (h2 p { font-family: helvetica })
** colors ** colors
** backgrounds ** backgrounds
** don't apply "fbreader internal" font size settings before CSS "smaller" or "larger"
* предупреждение "не могу открыть зашифрованный файл" * предупреждение "не могу открыть зашифрованный файл"
* API от Paragon * API от Paragon
* Two-page view * Two-page view

View file

@ -75,7 +75,7 @@ static bool parseLength(const std::string &toParse, short &size, ZLTextStyleEntr
return false; 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); StyleSheetTable::AttributeMap::const_iterator it = map.find(attributeName);
if (it == map.end()) { if (it == map.end()) {
return; return;
@ -85,7 +85,7 @@ void StyleSheetTable::setLength(ZLTextStyleEntry &entry, ZLTextStyleEntry::Featu
short size; short size;
ZLTextStyleEntry::SizeUnit unit; ZLTextStyleEntry::SizeUnit unit;
if (parseLength(values[0], size, 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"); const std::vector<std::string> &fontSize = values(styles, "font-size");
if (!fontSize.empty()) { if (!fontSize.empty()) {
bool doSetFontSize = true;
short size = 100;
ZLTextStyleEntry::SizeUnit unit = ZLTextStyleEntry::SIZE_UNIT_PERCENT;
if (fontSize[0] == "xx-small") { if (fontSize[0] == "xx-small") {
entry->setFontSizeMagnification(-3); size = 58;
} else if (fontSize[0] == "x-small") { } else if (fontSize[0] == "x-small") {
entry->setFontSizeMagnification(-2); size = 69;
} else if (fontSize[0] == "small") { } else if (fontSize[0] == "small") {
entry->setFontSizeMagnification(-1); size = 83;
} else if (fontSize[0] == "medium") { } else if (fontSize[0] == "medium") {
entry->setFontSizeMagnification(0); size = 100;
} else if (fontSize[0] == "large") { } else if (fontSize[0] == "large") {
entry->setFontSizeMagnification(1); size = 120;
} else if (fontSize[0] == "x-large") { } else if (fontSize[0] == "x-large") {
entry->setFontSizeMagnification(2); size = 144;
} else if (fontSize[0] == "xx-large") { } 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); 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); shared_ptr<ZLTextStyleEntry> entry = myStyleSheetTable.control(tag, aClass);
if (!entry.isNull()) { if (!entry.isNull()) {
myModelReader.addStyleEntry(*entry); myModelReader.addStyleEntry(*entry);
myStyleEntryStack.push_back(entry); myStyleEntryStack.push_back(entry);
return true;
} }
return false;
} }
void XHTMLReader::startElementHandler(const char *tag, const char **attributes) { 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); shared_ptr<ZLTextStyleEntry> entry = myStyleParser.parseString(style);
myModelReader.addStyleEntry(*entry); myModelReader.addStyleEntry(*entry);
myStyleEntryStack.push_back(entry); myStyleEntryStack.push_back(entry);
} else {
} }
myCSSStack.push_back(myStyleEntryStack.size() - sizeBefore); myCSSStack.push_back(myStyleEntryStack.size() - sizeBefore);
} }

View file

@ -73,7 +73,7 @@ private:
void beginParagraph(); void beginParagraph();
void endParagraph(); void endParagraph();
void addStyleEntry(const std::string tag, const std::string aClass); bool addStyleEntry(const std::string tag, const std::string aClass);
private: private:
BookReader &myModelReader; BookReader &myModelReader;

View file

@ -279,8 +279,7 @@ void ZLTextModel::addStyleEntry(const ZLTextStyleEntry &entry) {
len += 4; // each supported length len += 4; // each supported length
} }
} }
if (entry.isFeatureSupported(ZLTextStyleEntry::ALIGNMENT_TYPE) || if (entry.isFeatureSupported(ZLTextStyleEntry::ALIGNMENT_TYPE)) {
entry.isFeatureSupported(ZLTextStyleEntry::FONT_SIZE_MAGNIFICATION)) {
len += 2; len += 2;
} }
ZLUnicodeUtil::Ucs2String fontFamily; ZLUnicodeUtil::Ucs2String fontFamily;
@ -319,10 +318,9 @@ void ZLTextModel::addStyleEntry(const ZLTextStyleEntry &entry) {
*address++ = 0; *address++ = 0;
} }
} }
if (entry.isFeatureSupported(ZLTextStyleEntry::ALIGNMENT_TYPE) || if (entry.isFeatureSupported(ZLTextStyleEntry::ALIGNMENT_TYPE)) {
entry.isFeatureSupported(ZLTextStyleEntry::FONT_SIZE_MAGNIFICATION)) {
*address++ = entry.myAlignmentType; *address++ = entry.myAlignmentType;
*address++ = entry.myFontSizeMagnification; *address++ = 0;
} }
if (entry.isFeatureSupported(ZLTextStyleEntry::FONT_FAMILY)) { if (entry.isFeatureSupported(ZLTextStyleEntry::FONT_FAMILY)) {
address = ZLCachedMemoryAllocator::writeString(address, fontFamily); 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_BEFORE:
case LENGTH_SPACE_AFTER: case LENGTH_SPACE_AFTER:
return (myLengths[featureId].Size * metrics.FullHeight + 50) / 100; 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_UNDERLINED = 1 << 2,
FONT_MODIFIER_STRIKEDTHROUGH = 1 << 3, FONT_MODIFIER_STRIKEDTHROUGH = 1 << 3,
FONT_MODIFIER_SMALLCAPS = 1 << 4, FONT_MODIFIER_SMALLCAPS = 1 << 4,
FONT_MODIFIER_SMALLER = 1 << 5,
FONT_MODIFIER_LARGER = 1 << 6,
}; };
enum Feature { enum Feature {
@ -59,11 +61,11 @@ public:
LENGTH_FIRST_LINE_INDENT_DELTA = 2, LENGTH_FIRST_LINE_INDENT_DELTA = 2,
LENGTH_SPACE_BEFORE = 3, LENGTH_SPACE_BEFORE = 3,
LENGTH_SPACE_AFTER = 4, LENGTH_SPACE_AFTER = 4,
NUMBER_OF_LENGTHS = 5, LENGTH_FONT_SIZE = 5,
NUMBER_OF_LENGTHS = 6,
ALIGNMENT_TYPE = NUMBER_OF_LENGTHS, ALIGNMENT_TYPE = NUMBER_OF_LENGTHS,
FONT_SIZE_MAGNIFICATION = NUMBER_OF_LENGTHS + 1, FONT_FAMILY = NUMBER_OF_LENGTHS + 1,
FONT_FAMILY = NUMBER_OF_LENGTHS + 2, FONT_STYLE_MODIFIER = NUMBER_OF_LENGTHS + 2,
FONT_STYLE_MODIFIER = NUMBER_OF_LENGTHS + 3,
}; };
private: private:
@ -89,9 +91,6 @@ public:
ZLBoolean3 fontModifier(FontModifier modifier) const; ZLBoolean3 fontModifier(FontModifier modifier) const;
void setFontModifier(FontModifier modifier, bool on); void setFontModifier(FontModifier modifier, bool on);
signed char fontSizeMagnification() const;
void setFontSizeMagnification(signed char fontSizeMagnification);
const std::string &fontFamily() const; const std::string &fontFamily() const;
void setFontFamily(const std::string &fontFamily); void setFontFamily(const std::string &fontFamily);
@ -102,13 +101,12 @@ private:
ZLTextAlignmentType myAlignmentType; ZLTextAlignmentType myAlignmentType;
unsigned char mySupportedFontModifier; unsigned char mySupportedFontModifier;
unsigned char myFontModifier; unsigned char myFontModifier;
signed char myFontSizeMagnification;
std::string myFontFamily; std::string myFontFamily;
friend class ZLTextModel; 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::~ZLTextStyleEntry() {}
inline ZLTextStyleEntry::Metrics::Metrics(int fontSize, int fontXHeight, int fullWidth, int fullHeight) : FontSize(fontSize), FontXHeight(fontXHeight), FullWidth(fullWidth), FullHeight(fullHeight) {} 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 const std::string &ZLTextStyleEntry::fontFamily() const { return myFontFamily; }
inline void ZLTextStyleEntry::setFontFamily(const std::string &fontFamily) { inline void ZLTextStyleEntry::setFontFamily(const std::string &fontFamily) {
myFeatureMask |= 1 << FONT_FAMILY; myFeatureMask |= 1 << FONT_FAMILY;

View file

@ -194,16 +194,10 @@ public class ZLTextPlainModel implements ZLTextModel, ZLTextStyleEntry.Feature {
entry.setLength(i, size, unit); 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)) { if (ZLTextStyleEntry.isFeatureSupported(mask, ALIGNMENT_TYPE)) {
final short value = (short)data[dataOffset++];
entry.setAlignmentType((byte)(value & 0xFF)); entry.setAlignmentType((byte)(value & 0xFF));
} }
if (ZLTextStyleEntry.isFeatureSupported(mask, FONT_SIZE_MAGNIFICATION)) {
entry.setFontSizeMagnification((byte)((value >> 8) & 0xFF));
}
}
if (ZLTextStyleEntry.isFeatureSupported(mask, FONT_FAMILY)) { if (ZLTextStyleEntry.isFeatureSupported(mask, FONT_FAMILY)) {
final short familyLength = (short)data[dataOffset++]; final short familyLength = (short)data[dataOffset++];
entry.setFontFamily(new String(data, dataOffset, familyLength)); entry.setFontFamily(new String(data, dataOffset, familyLength));

View file

@ -28,11 +28,11 @@ public final class ZLTextStyleEntry {
int LENGTH_FIRST_LINE_INDENT_DELTA = 2; int LENGTH_FIRST_LINE_INDENT_DELTA = 2;
int LENGTH_SPACE_BEFORE = 3; int LENGTH_SPACE_BEFORE = 3;
int LENGTH_SPACE_AFTER = 4; 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 ALIGNMENT_TYPE = NUMBER_OF_LENGTHS;
int FONT_SIZE_MAGNIFICATION = NUMBER_OF_LENGTHS + 1; int FONT_FAMILY = NUMBER_OF_LENGTHS + 1;
int FONT_FAMILY = NUMBER_OF_LENGTHS + 2; int FONT_STYLE_MODIFIER = NUMBER_OF_LENGTHS + 2;
int FONT_STYLE_MODIFIER = NUMBER_OF_LENGTHS + 3;
} }
public interface FontModifier { public interface FontModifier {
@ -41,16 +41,32 @@ public final class ZLTextStyleEntry {
byte FONT_MODIFIER_UNDERLINED = 1 << 2; byte FONT_MODIFIER_UNDERLINED = 1 << 2;
byte FONT_MODIFIER_STRIKEDTHROUGH = 1 << 3; byte FONT_MODIFIER_STRIKEDTHROUGH = 1 << 3;
byte FONT_MODIFIER_SMALLCAPS = 1 << 4; byte FONT_MODIFIER_SMALLCAPS = 1 << 4;
byte FONT_MODIFIER_SMALLER = 1 << 5;
byte FONT_MODIFIER_LARGER = 1 << 6;
} }
public interface SizeUnit { public interface SizeUnit {
byte SIZE_UNIT_PIXEL = 0; byte PIXEL = 0;
byte SIZE_UNIT_EM_100 = 1; byte EM_100 = 1;
byte SIZE_UNIT_EX_100 = 2; byte EX_100 = 2;
byte SIZE_UNIT_PERCENT = 3; 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 short Size;
public final byte Unit; public final byte Unit;
@ -64,7 +80,6 @@ public final class ZLTextStyleEntry {
private Length[] myLengths = new Length[Feature.NUMBER_OF_LENGTHS]; private Length[] myLengths = new Length[Feature.NUMBER_OF_LENGTHS];
private byte myAlignmentType; private byte myAlignmentType;
private byte myFontSizeMagnification;
private String myFontFamily; private String myFontFamily;
private byte mySupportedFontModifiers; private byte mySupportedFontModifiers;
private byte myFontModifiers; private byte myFontModifiers;
@ -85,11 +100,30 @@ public final class ZLTextStyleEntry {
myLengths[featureId] = new Length(size, unit); myLengths[featureId] = new Length(size, unit);
} }
/* public int getLength(int featureId, Metrics metrics) {
public Length getLength(int featureId) { switch (myLengths[featureId].Unit) {
return myLengths[featureId]; 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) { void setAlignmentType(byte alignmentType) {
myFeatureMask |= 1 << Feature.ALIGNMENT_TYPE; myFeatureMask |= 1 << Feature.ALIGNMENT_TYPE;
@ -100,15 +134,6 @@ public final class ZLTextStyleEntry {
return myAlignmentType; return myAlignmentType;
} }
void setFontSizeMagnification(byte fontSizeMagnification) {
myFeatureMask |= 1 << Feature.FONT_SIZE_MAGNIFICATION;
myFontSizeMagnification = fontSizeMagnification;
}
public byte getFontSizeMagnification() {
return myFontSizeMagnification;
}
void setFontFamily(String fontFamily) { void setFontFamily(String fontFamily) {
myFeatureMask |= 1 << Feature.FONT_FAMILY; myFeatureMask |= 1 << Feature.FONT_FAMILY;
myFontFamily = fontFamily; myFontFamily = fontFamily;

View file

@ -19,6 +19,8 @@
package org.geometerplus.zlibrary.text.view.style; 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.view.ZLTextStyle;
import org.geometerplus.zlibrary.text.model.ZLTextStyleEntry; import org.geometerplus.zlibrary.text.model.ZLTextStyleEntry;
@ -35,14 +37,17 @@ public class ZLTextExplicitlyDecoratedStyle extends ZLTextStyle implements ZLTex
return Base.getFontFamily(); return Base.getFontFamily();
} }
public int getFontSize() { 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 // TODO: implement
return Base.getFontSize(); return Base.getFontSize();
} }
public boolean isBold() { public boolean isBold() {
if (!myEntry.isFeatureSupported(FONT_STYLE_MODIFIER)) {
return Base.isBold();
}
switch (myEntry.getFontModifier(FONT_MODIFIER_BOLD)) { switch (myEntry.getFontModifier(FONT_MODIFIER_BOLD)) {
case B3_TRUE: case B3_TRUE:
return true; return true;
@ -53,9 +58,6 @@ public class ZLTextExplicitlyDecoratedStyle extends ZLTextStyle implements ZLTex
} }
} }
public boolean isItalic() { public boolean isItalic() {
if (!myEntry.isFeatureSupported(FONT_STYLE_MODIFIER)) {
return Base.isItalic();
}
switch (myEntry.getFontModifier(FONT_MODIFIER_ITALIC)) { switch (myEntry.getFontModifier(FONT_MODIFIER_ITALIC)) {
case B3_TRUE: case B3_TRUE:
return true; return true;
@ -66,9 +68,6 @@ public class ZLTextExplicitlyDecoratedStyle extends ZLTextStyle implements ZLTex
} }
} }
public boolean isUnderline() { public boolean isUnderline() {
if (!myEntry.isFeatureSupported(FONT_STYLE_MODIFIER)) {
return Base.isUnderline();
}
switch (myEntry.getFontModifier(FONT_MODIFIER_UNDERLINED)) { switch (myEntry.getFontModifier(FONT_MODIFIER_UNDERLINED)) {
case B3_TRUE: case B3_TRUE:
return true; return true;
@ -79,9 +78,6 @@ public class ZLTextExplicitlyDecoratedStyle extends ZLTextStyle implements ZLTex
} }
} }
public boolean isStrikeThrough() { public boolean isStrikeThrough() {
if (!myEntry.isFeatureSupported(FONT_STYLE_MODIFIER)) {
return Base.isStrikeThrough();
}
switch (myEntry.getFontModifier(FONT_MODIFIER_STRIKEDTHROUGH)) { switch (myEntry.getFontModifier(FONT_MODIFIER_STRIKEDTHROUGH)) {
case B3_TRUE: case B3_TRUE:
return true; return true;