[fbreader] Added limited support for left/right auto margins

They only work if width property is set, otherwise they are ignored.
Top/bottom don't work at all (and never did)
This commit is contained in:
Slava Monich 2015-08-18 01:22:59 +03:00
parent 97ce479c50
commit f30d83bf39
7 changed files with 74 additions and 21 deletions

View file

@ -147,7 +147,7 @@ bool StyleSheetTable::parseMargin(const std::string &toParse, short &size, ZLTex
return true; return true;
} else if (toParse == "auto") { } else if (toParse == "auto") {
size = 0; size = 0;
unit = ZLTextStyleEntry::SIZE_UNIT_PIXEL; unit = ZLTextStyleEntry::SIZE_UNIT_AUTO;
return true; return true;
} else { } else {
return false; return false;
@ -307,6 +307,7 @@ void StyleSheetTable::updateTextStyle(ZLTextStyleEntry &entry, const AttributeMa
} else { } else {
if (ZLTextStyleEntry::parseLength(value, size, unit)) { if (ZLTextStyleEntry::parseLength(value, size, unit)) {
switch (unit) { switch (unit) {
case ZLTextStyleEntry::SIZE_UNIT_AUTO:
case ZLTextStyleEntry::SIZE_UNIT_PIXEL: case ZLTextStyleEntry::SIZE_UNIT_PIXEL:
// What to do with pixels? // What to do with pixels?
break; break;
@ -355,6 +356,9 @@ void StyleSheetTable::updateTextStyle(ZLTextStyleEntry &entry, const AttributeMa
entry.setOpacity((unsigned char)((value < 0) ? 0 : (value > 255) ? 255 : value)); entry.setOpacity((unsigned char)((value < 0) ? 0 : (value > 255) ? 255 : value));
} }
static const std::string WIDTH("width");
setLength(entry, ZLTextStyleEntry::LENGTH_WIDTH, styles, WIDTH);
// Margins will overwrite padding, sorry // Margins will overwrite padding, sorry
static const std::string PADDING_TOP("padding-top"); static const std::string PADDING_TOP("padding-top");
static const std::string PADDING_BOTTOM("padding-bottom"); static const std::string PADDING_BOTTOM("padding-bottom");

View file

@ -39,7 +39,6 @@ size_t ZLTextEntry::dataLength() const {
int ZLTextStyleEntry::hlength(int size, SizeUnit unit, const Metrics &metrics) int ZLTextStyleEntry::hlength(int size, SizeUnit unit, const Metrics &metrics)
{ {
switch (unit) { switch (unit) {
default:
case SIZE_UNIT_PIXEL: case SIZE_UNIT_PIXEL:
return size; return size;
case SIZE_UNIT_EM_100: case SIZE_UNIT_EM_100:
@ -48,13 +47,15 @@ int ZLTextStyleEntry::hlength(int size, SizeUnit unit, const Metrics &metrics)
return (size * metrics.FontXHeight + 50) / 100; return (size * metrics.FontXHeight + 50) / 100;
case SIZE_UNIT_PERCENT: case SIZE_UNIT_PERCENT:
return (size * metrics.FullWidth + 50) / 100; return (size * metrics.FullWidth + 50) / 100;
case SIZE_UNIT_AUTO:
return metrics.FullWidth / 2;
} }
return 0;
} }
int ZLTextStyleEntry::vlength(int size, SizeUnit unit, const Metrics &metrics) int ZLTextStyleEntry::vlength(int size, SizeUnit unit, const Metrics &metrics)
{ {
switch (unit) { switch (unit) {
default:
case SIZE_UNIT_PIXEL: case SIZE_UNIT_PIXEL:
return size; return size;
case SIZE_UNIT_EM_100: case SIZE_UNIT_EM_100:
@ -63,20 +64,26 @@ int ZLTextStyleEntry::vlength(int size, SizeUnit unit, const Metrics &metrics)
return (size * metrics.FontXHeight + 50) / 100; return (size * metrics.FontXHeight + 50) / 100;
case SIZE_UNIT_PERCENT: case SIZE_UNIT_PERCENT:
return (size * metrics.FullHeight + 50) / 100; return (size * metrics.FullHeight + 50) / 100;
case SIZE_UNIT_AUTO:
return metrics.FullHeight / 2;
} }
return 0;
} }
short ZLTextStyleEntry::length(Length name, const Metrics &metrics) const { short ZLTextStyleEntry::length(Length name, const Metrics &metrics) const {
switch (name) { switch (name) {
default:
case LENGTH_LEFT_INDENT: case LENGTH_LEFT_INDENT:
case LENGTH_RIGHT_INDENT: case LENGTH_RIGHT_INDENT:
case LENGTH_FIRST_LINE_INDENT_DELTA: case LENGTH_FIRST_LINE_INDENT_DELTA:
case LENGTH_WIDTH:
return hlength(myLengths[name].Size, myLengths[name].Unit, metrics); return hlength(myLengths[name].Size, myLengths[name].Unit, metrics);
case LENGTH_SPACE_BEFORE: case LENGTH_SPACE_BEFORE:
case LENGTH_SPACE_AFTER: case LENGTH_SPACE_AFTER:
return vlength(myLengths[name].Size, myLengths[name].Unit, metrics); return vlength(myLengths[name].Size, myLengths[name].Unit, metrics);
case NUMBER_OF_LENGTHS:
break;
} }
return 0;
} }
ZLTextStyleEntry::ZLTextStyleEntry(char *address) { ZLTextStyleEntry::ZLTextStyleEntry(char *address) {

View file

@ -68,7 +68,8 @@ public:
SIZE_UNIT_PIXEL, SIZE_UNIT_PIXEL,
SIZE_UNIT_EM_100, SIZE_UNIT_EM_100,
SIZE_UNIT_EX_100, SIZE_UNIT_EX_100,
SIZE_UNIT_PERCENT SIZE_UNIT_PERCENT,
SIZE_UNIT_AUTO
}; };
struct Metrics { struct Metrics {
@ -86,7 +87,8 @@ 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_WIDTH = 5,
NUMBER_OF_LENGTHS = 6
}; };
private: private:
@ -111,6 +113,8 @@ public:
bool isEmpty() const; bool isEmpty() const;
bool lengthSupported(Length name) const; bool lengthSupported(Length name) const;
bool autoLeftRightMargins() const;
SizeUnit lengthUnit(Length name) const;
short length(Length name, const Metrics &metrics) const; short length(Length name, const Metrics &metrics) const;
short length(Length name, SizeUnit &unit) const; short length(Length name, SizeUnit &unit) const;
void setLength(Length name, short length, SizeUnit unit); void setLength(Length name, short length, SizeUnit unit);
@ -374,12 +378,18 @@ inline bool ZLTextStyleEntry::operator == (const ZLTextStyleEntry &other) const
inline ZLTextStyleEntry &ZLTextStyleEntry::operator = (const ZLTextStyleEntry &other) { reset(); apply(other); return *this; } inline ZLTextStyleEntry &ZLTextStyleEntry::operator = (const ZLTextStyleEntry &other) { reset(); apply(other); return *this; }
inline bool ZLTextStyleEntry::lengthSupported(Length name) const { return (myMask & (1 << name)) != 0; } inline bool ZLTextStyleEntry::lengthSupported(Length name) const { return (myMask & (1 << name)) != 0; }
inline ZLTextStyleEntry::SizeUnit ZLTextStyleEntry::lengthUnit(Length name) const { return myLengths[name].Unit; }
inline short ZLTextStyleEntry::length(Length name, SizeUnit &unit) const { unit = myLengths[name].Unit; return myLengths[name].Size; } inline short ZLTextStyleEntry::length(Length name, SizeUnit &unit) const { unit = myLengths[name].Unit; return myLengths[name].Size; }
inline void ZLTextStyleEntry::setLength(Length name, short length, SizeUnit unit) { inline void ZLTextStyleEntry::setLength(Length name, short length, SizeUnit unit) {
myLengths[name].Size = length; myLengths[name].Size = length;
myLengths[name].Unit = unit; myLengths[name].Unit = unit;
myMask |= 1 << name; myMask |= 1 << name;
} }
inline bool ZLTextStyleEntry::autoLeftRightMargins() const {
return (myMask & ((1 << LENGTH_LEFT_INDENT) | (1 << LENGTH_RIGHT_INDENT))) == ((1 << LENGTH_LEFT_INDENT) | (1 << LENGTH_RIGHT_INDENT)) &&
myLengths[LENGTH_LEFT_INDENT].Unit == SIZE_UNIT_AUTO &&
myLengths[LENGTH_RIGHT_INDENT].Unit == SIZE_UNIT_AUTO;
}
inline bool ZLTextStyleEntry::opacitySupported() const { return (myMask & SUPPORT_OPACITY) != 0; } inline bool ZLTextStyleEntry::opacitySupported() const { return (myMask & SUPPORT_OPACITY) != 0; }
inline unsigned char ZLTextStyleEntry::opacity() const { return myOpacity; } inline unsigned char ZLTextStyleEntry::opacity() const { return myOpacity; }

View file

@ -75,13 +75,13 @@ short ZLTextFullDecoratedStyle::spaceAfter(const ZLTextStyleEntry::Metrics &metr
} }
short ZLTextFullDecoratedStyle::lineStartIndent(const ZLTextStyleEntry::Metrics &metrics, bool rtl) const { short ZLTextFullDecoratedStyle::lineStartIndent(const ZLTextStyleEntry::Metrics &metrics, bool rtl) const {
return base()->lineEndIndent(metrics, rtl) + (rtl ? return base()->lineStartIndent(metrics, rtl) + (rtl ?
ZLTextStyleEntry::hlength(myDecoration.LineEndIndentOption.value(), myDecoration.LineEndIndentOptionUnit, metrics) : ZLTextStyleEntry::hlength(myDecoration.LineEndIndentOption.value(), myDecoration.LineEndIndentOptionUnit, metrics) :
ZLTextStyleEntry::hlength(myDecoration.LineStartIndentOption.value(), myDecoration.LineStartIndentOptionUnit, metrics)); ZLTextStyleEntry::hlength(myDecoration.LineStartIndentOption.value(), myDecoration.LineStartIndentOptionUnit, metrics));
} }
short ZLTextFullDecoratedStyle::lineEndIndent(const ZLTextStyleEntry::Metrics &metrics, bool rtl) const { short ZLTextFullDecoratedStyle::lineEndIndent(const ZLTextStyleEntry::Metrics &metrics, bool rtl) const {
return base()->lineStartIndent(metrics, rtl) + (rtl ? return base()->lineEndIndent(metrics, rtl) + (rtl ?
ZLTextStyleEntry::hlength(myDecoration.LineStartIndentOption.value(), myDecoration.LineStartIndentOptionUnit, metrics) : ZLTextStyleEntry::hlength(myDecoration.LineStartIndentOption.value(), myDecoration.LineStartIndentOptionUnit, metrics) :
ZLTextStyleEntry::hlength(myDecoration.LineEndIndentOption.value(), myDecoration.LineEndIndentOptionUnit, metrics)); ZLTextStyleEntry::hlength(myDecoration.LineEndIndentOption.value(), myDecoration.LineEndIndentOptionUnit, metrics));
} }
@ -193,28 +193,51 @@ short ZLTextForcedStyle::lineStartIndent(const ZLTextStyleEntry::Metrics &metric
ZLTextStyleEntry::Length lengthType = rtl ? ZLTextStyleEntry::Length lengthType = rtl ?
ZLTextStyleEntry::LENGTH_RIGHT_INDENT : ZLTextStyleEntry::LENGTH_RIGHT_INDENT :
ZLTextStyleEntry::LENGTH_LEFT_INDENT; ZLTextStyleEntry::LENGTH_LEFT_INDENT;
if (myEntry.lengthSupported(lengthType)) { if (!myEntry.lengthSupported(lengthType)) {
const short baseLen = base()->lineStartIndent(metrics, rtl);
ZLTextStyleEntry::Metrics adjusted(metrics);
adjusted.FullWidth -= baseLen + base()->lineEndIndent(metrics, rtl);
return baseLen + myEntry.length(lengthType, adjusted);
} else {
return base()->lineStartIndent(metrics, rtl); return base()->lineStartIndent(metrics, rtl);
} }
const short baseLen = base()->lineStartIndent(metrics, rtl);
ZLTextStyleEntry::Metrics adjusted(metrics);
adjusted.FullWidth -= baseLen + base()->lineEndIndent(metrics, rtl);
if (adjusted.FullWidth < 0) adjusted.FullWidth = 0;
if (myEntry.lengthUnit(lengthType) != ZLTextStyleEntry::SIZE_UNIT_AUTO) {
return baseLen + myEntry.length(lengthType, adjusted);
}
if (myEntry.autoLeftRightMargins() && myEntry.lengthSupported(ZLTextStyleEntry::LENGTH_WIDTH)) {
int x = adjusted.FullWidth - myEntry.length(ZLTextStyleEntry::LENGTH_WIDTH, adjusted);
if (x < 0) x = 0;
return x/2;
}
return baseLen;
} }
short ZLTextForcedStyle::lineEndIndent(const ZLTextStyleEntry::Metrics &metrics, bool rtl) const { short ZLTextForcedStyle::lineEndIndent(const ZLTextStyleEntry::Metrics &metrics, bool rtl) const {
ZLTextStyleEntry::Length lengthType = rtl ? ZLTextStyleEntry::Length lengthType = rtl ?
ZLTextStyleEntry::LENGTH_LEFT_INDENT : ZLTextStyleEntry::LENGTH_LEFT_INDENT :
ZLTextStyleEntry::LENGTH_RIGHT_INDENT; ZLTextStyleEntry::LENGTH_RIGHT_INDENT;
if (myEntry.lengthSupported(lengthType)) {
const short baseLen = base()->lineEndIndent(metrics, rtl); if (!myEntry.lengthSupported(lengthType)) {
ZLTextStyleEntry::Metrics adjusted(metrics); return base()->lineStartIndent(metrics, rtl);
adjusted.FullWidth -= baseLen + base()->lineStartIndent(metrics, rtl);
return baseLen + myEntry.length(lengthType, adjusted);
} else {
return base()->lineEndIndent(metrics, rtl);
} }
const short baseLen = base()->lineEndIndent(metrics, rtl);
ZLTextStyleEntry::Metrics adjusted(metrics);
adjusted.FullWidth -= baseLen + base()->lineStartIndent(metrics, rtl);
if (adjusted.FullWidth < 0) adjusted.FullWidth = 0;
if (myEntry.lengthUnit(lengthType) != ZLTextStyleEntry::SIZE_UNIT_AUTO) {
return baseLen + myEntry.length(lengthType, adjusted);
}
if (myEntry.autoLeftRightMargins() && myEntry.lengthSupported(ZLTextStyleEntry::LENGTH_WIDTH)) {
int x = adjusted.FullWidth - myEntry.length(ZLTextStyleEntry::LENGTH_WIDTH, adjusted);
if (x < 0) x = 0;
return x/2;
}
return baseLen;
} }
short ZLTextForcedStyle::spaceBefore(const ZLTextStyleEntry::Metrics &metrics) const { short ZLTextForcedStyle::spaceBefore(const ZLTextStyleEntry::Metrics &metrics) const {

View file

@ -104,11 +104,13 @@
color: #333333; color: #333333;
} }
.table { .table {
width: 100%;
margin-bottom: 16px; margin-bottom: 16px;
margin-top: 0; margin-top: 0;
text-indent: 0; text-indent: 0;
} }
.table1 { .table1 {
width: 100%;
margin-bottom: 16px; margin-bottom: 16px;
margin-top: 0; margin-top: 0;
text-indent: 0; text-indent: 0;

View file

@ -4,6 +4,9 @@ body.cover {
margin-top: 0; margin-top: 0;
margin-right: 0; margin-right: 0;
} }
svg.cover-svg {
width: 100%;
}
.z { .z {
margin-right: 8px; margin-right: 8px;
font-family: "Times New Roman", "serif"; font-family: "Times New Roman", "serif";

View file

@ -79,6 +79,9 @@ dump_length(
case ZLTextStyleEntry::SIZE_UNIT_PERCENT: case ZLTextStyleEntry::SIZE_UNIT_PERCENT:
out << length->Size << "%"; out << length->Size << "%";
break; break;
case ZLTextStyleEntry::SIZE_UNIT_AUTO:
out << "auto";
break;
} }
} }
out << ";\n"; out << ";\n";
@ -90,6 +93,7 @@ dump_style(
const StyleSheetTable::Style& style, const StyleSheetTable::Style& style,
std::ostream& out) std::ostream& out)
{ {
dump_length(style.TextStyle, ZLTextStyleEntry::LENGTH_WIDTH, "width", out);
dump_length(style.TextStyle, ZLTextStyleEntry::LENGTH_LEFT_INDENT, "margin-left", out); dump_length(style.TextStyle, ZLTextStyleEntry::LENGTH_LEFT_INDENT, "margin-left", out);
dump_length(style.TextStyle, ZLTextStyleEntry::LENGTH_SPACE_AFTER, "margin-bottom", out); dump_length(style.TextStyle, ZLTextStyleEntry::LENGTH_SPACE_AFTER, "margin-bottom", out);
dump_length(style.TextStyle, ZLTextStyleEntry::LENGTH_SPACE_BEFORE, "margin-top", out); dump_length(style.TextStyle, ZLTextStyleEntry::LENGTH_SPACE_BEFORE, "margin-top", out);