aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dw/style.hh36
-rw-r--r--dw/table.cc72
-rw-r--r--dw/table.hh4
-rw-r--r--dw/textblock.cc17
-rw-r--r--dw/textblock_linebreaking.cc4
5 files changed, 91 insertions, 42 deletions
diff --git a/dw/style.hh b/dw/style.hh
index 7c00ac1f..c86446a3 100644
--- a/dw/style.hh
+++ b/dw/style.hh
@@ -396,12 +396,44 @@ inline bool isRelLength(Length l) { return (l & 3) == 3; }
/** \brief Returns the value of a length in pixels, as an integer. */
inline int absLengthVal(Length l) { return l >> 2; }
-/** \brief Returns the value of a percentage, relative to 1, as a double. */
+/** \brief Returns the value of a percentage, relative to 1, as a double.
+ *
+ * When possible, do not use this function directly; it may be removed
+ * soon. Instead, use multiplyWithPerLength or multiplyWithPerLengthRounded.
+ */
inline double perLengthVal(Length l) { return (double)(l & ~3) / (1 << 18); }
-/** \brief Returns the value of a relative length, as a float. */
+/** \brief Returns the value of a relative length, as a float.
+ *
+ * When possible, do not use this function directly; it may be removed
+ * soon.
+ */
inline double relLengthVal(Length l) { return (double)(l & ~3) / (1 << 18); }
+/**
+ * \brief Multiply an int with a percentage length, returning int.
+ *
+ * Use this instead of perLengthVal, when possible.
+ */
+inline int multiplyWithPerLength(int x, Length l) {
+ return x * perLengthVal(l);
+}
+
+/**
+ * \brief Like multiplyWithPerLength, but rounds to nearest integer
+ * instead of down.
+ *
+ * (This function exists for backward compatibility.)
+ */
+inline int multiplyWithPerLengthRounded (int x, Length l) {
+ return lout::misc::roundInt (x * perLengthVal(l));
+}
+
+inline int multiplyWithRelLength(int x, Length l) {
+ return x * relLengthVal(l);
+}
+
+
enum {
/** \brief Represents "auto" lengths. */
LENGTH_AUTO = 0
diff --git a/dw/table.cc b/dw/table.cc
index b1a66b77..59a725f9 100644
--- a/dw/table.cc
+++ b/dw/table.cc
@@ -60,7 +60,7 @@ Table::Table(bool limitTextWidth)
rowStyle = new misc::SimpleVector <core::style::Style*> (8);
hasColPercent = 0;
- colPercents = new misc::SimpleVector <float> (8);
+ colPercents = new misc::SimpleVector <core::style::Length> (8);
redrawX = 0;
redrawY = 0;
@@ -501,9 +501,9 @@ void Table::forceCalcCellSizes ()
* as defined by CSS2.)
*/
totalWidth =
- (int)(availWidth
- * misc::min (core::style::perLengthVal (getStyle()->width),
- 1.0));
+ misc::min (core::style::multiplyWithPerLength (availWidth,
+ getStyle()->width),
+ availWidth);
} else if (getStyle()->width == core::style::LENGTH_AUTO) {
totalWidth = availWidth;
forceTotalWidth = 0;
@@ -658,7 +658,7 @@ void Table::forceCalcColumnExtremes ()
for (int col = 0; col < numCols; col++) {
colExtremes->getRef(col)->minWidth = 0;
colExtremes->getRef(col)->maxWidth = 0;
- colPercents->set(col, LEN_AUTO);
+ colPercents->set(col, core::style::LENGTH_AUTO);
for (int row = 0; row < numRows; row++) {
int n = row * numCols + col;
@@ -698,13 +698,15 @@ void Table::forceCalcColumnExtremes ()
// Also fill the colPercents array in this pass
if (core::style::isPerLength (width)) {
hasColPercent = 1;
- if (colPercents->get(col) == LEN_AUTO)
- colPercents->set(col, core::style::perLengthVal(width));
+ if (colPercents->get(col) == core::style::LENGTH_AUTO)
+ colPercents->set(col, width);
} else if (core::style::isAbsLength (width)) {
// We treat LEN_ABS as a special case of LEN_AUTO.
/*
* if (colPercents->get(col) == LEN_AUTO)
* colPercents->set(col, LEN_ABS);
+ *
+ * (Hint: that's old code!)
*/
}
} else {
@@ -766,13 +768,13 @@ void Table::forceCalcColumnExtremes ()
}
}
- // This numbers will help if the span has percents.
+ // These values will help if the span has percents.
int spanHasColPercent = 0;
int availSpanMinW = spanMinW;
float cumSpanPercent = 0.0f;
for (int i = col; i < col + cs; ++i) {
- if (colPercents->get(i) > 0.0f) {
- cumSpanPercent += colPercents->get(i);
+ if (core::style::isPerLength (colPercents->get(i))) {
+ cumSpanPercent += core::style::perLengthVal (colPercents->get(i));
++spanHasColPercent;
} else
availSpanMinW -= colExtremes->getRef(i)->minWidth;
@@ -849,17 +851,18 @@ void Table::apportion2 (int totalWidth, int forceTotalWidth)
#endif
int minAutoWidth = 0, maxAutoWidth = 0, availAutoWidth = totalWidth;
for (int col = 0; col < numCols; col++) {
- if (colPercents->get(col) == LEN_ABS) { // set absolute lengths
+ if (core::style::isAbsLength (colPercents->get(col))) {
+ // set absolute lengths
setColWidth (col, colExtremes->get(col).minWidth);
}
- if (colPercents->get(col) == LEN_AUTO) {
+ if (colPercents->get(col) == core::style::LENGTH_AUTO) {
maxAutoWidth += colExtremes->get(col).maxWidth;
minAutoWidth += colExtremes->get(col).minWidth;
} else
availAutoWidth -= colWidths->get(col);
}
- if (!maxAutoWidth) // no LEN_AUTO cols!
+ if (!maxAutoWidth) // no core::style::LENGTH_AUTO cols!
return;
colWidths->setSize (colExtremes->size (), 0);
@@ -879,7 +882,7 @@ void Table::apportion2 (int totalWidth, int forceTotalWidth)
col, colExtremes->getRef(col)->minWidth,
colExtremes->get(col).maxWidth);
- if (colPercents->get(col) != LEN_AUTO)
+ if (colPercents->get(col) != core::style::LENGTH_AUTO)
continue;
int colMinWidth = colExtremes->getRef(col)->minWidth;
@@ -936,7 +939,7 @@ void Table::apportion_percentages2(int totalWidth, int forceTotalWidth)
// It has only a table-wide percentage. Apportion non-absolute widths.
int sumMaxWidth = 0, perAvailWidth = totalWidth;
for (int col = 0; col < numCols; col++) {
- if (colPercents->get(col) == LEN_ABS)
+ if (core::style::isAbsLength (colPercents->get(col)))
perAvailWidth -= colExtremes->getRef(col)->maxWidth;
else
sumMaxWidth += colExtremes->getRef(col)->maxWidth;
@@ -947,7 +950,7 @@ void Table::apportion_percentages2(int totalWidth, int forceTotalWidth)
for (int col = 0; col < numCols; col++) {
int max_wi = colExtremes->getRef(col)->maxWidth, new_wi;
- if (colPercents->get(col) != LEN_ABS) {
+ if (!core::style::isAbsLength (colPercents->get(col))) {
new_wi =
misc::max (colExtremes->getRef(col)->minWidth,
(int)((float)max_wi * perAvailWidth/sumMaxWidth));
@@ -972,12 +975,13 @@ void Table::apportion_percentages2(int totalWidth, int forceTotalWidth)
int hasAutoCol = 0;
int sumMinWidth = 0, sumMaxWidth = 0, sumMinNonPer = 0, sumMaxNonPer = 0;
for (int col = 0; col < numCols; col++) {
- if (colPercents->get(col) > 0.0f) {
- cumPercent += colPercents->get(col);
+ if (core::style::isPerLength (colPercents->get(col))) {
+ cumPercent += core::style::perLengthVal (colPercents->get(col));
} else {
sumMinNonPer += colExtremes->getRef(col)->minWidth;
sumMaxNonPer += colExtremes->getRef(col)->maxWidth;
- hasAutoCol += (colPercents->get(col) == LEN_AUTO);
+ if (colPercents->get(col) == core::style::LENGTH_AUTO)
+ hasAutoCol++;
}
sumMinWidth += colExtremes->getRef(col)->minWidth;
sumMaxWidth += colExtremes->getRef(col)->maxWidth;
@@ -990,10 +994,12 @@ void Table::apportion_percentages2(int totalWidth, int forceTotalWidth)
if (!forceTotalWidth) {
if (sumMaxNonPer == 0 || cumPercent < 0.99f) {
// only percentage columns, or cumPercent < 100% => restrict width
- int totW = (int)(sumMaxNonPer/(1.0f-cumPercent));
+ int totW = (int)(sumMaxNonPer / (1.0f - cumPercent));
for (int col = 0; col < numCols; col++) {
- totW = misc::max (totW, (int)(colExtremes->getRef(col)->maxWidth
- / colPercents->get(col)));
+ totW = misc::max
+ (totW,
+ (int)(colExtremes->getRef(col)->maxWidth
+ / core::style::perLengthVal (colPercents->get(col))));
}
totalWidth = misc::min (totW, totalWidth);
}
@@ -1019,8 +1025,9 @@ void Table::apportion_percentages2(int totalWidth, int forceTotalWidth)
for (int col = 0; col < numCols; col++) {
int colMinWidth = colExtremes->getRef(col)->minWidth;
- if (colPercents->get(col) >= 0.0f) {
- int w = (int)(workingWidth * colPercents->get(col));
+ if (core::style::isPerLength (colPercents->get(col))) {
+ int w = core::style::multiplyWithPerLength (workingWidth,
+ colPercents->get(col));
if (w < colMinWidth)
w = colMinWidth;
else if (curPerWidth - colMinWidth + w > workingWidth)
@@ -1055,8 +1062,19 @@ void Table::apportion_percentages2(int totalWidth, int forceTotalWidth)
// We'll honor totalWidth by expanding the percentage cols.
int extraWidth = totalWidth - curPerWidth - sumMinNonPer;
for (int col = 0; col < numCols; col++) {
- if (colPercents->get(col) >= 0.0f) {
- int d = (int)(extraWidth * colPercents->get(col)/cumPercent);
+ if (core::style::isPerLength (colPercents->get(col))) {
+ // This could cause rounding errors:
+ //
+ // int d =
+ // core::dw::multiplyWithPerLength (extraWidth,
+ // colPercents->get(col))
+ // / cumPercent;
+ //
+ // Thus the "old" way:
+ int d =
+ (int)(extraWidth *
+ core::style::perLengthVal (colPercents->get(col))
+ / cumPercent);
setColWidth (col, colWidths->get(col) + d);
}
}
@@ -1073,7 +1091,7 @@ void Table::apportion_percentages2(int totalWidth, int forceTotalWidth)
#ifdef DBG
MSG("APP_P, percent={");
for (int col = 0; col < numCols; col++)
- MSG("%f ", colPercents->get(col));
+ MSG("%f ", core::dw::_getPerVal (colPercents->get(col)));
MSG("}\n");
MSG("APP_P, result ={ ");
for (int col = 0; col < numCols; col++)
diff --git a/dw/table.hh b/dw/table.hh
index b8feb835..1d14ec07 100644
--- a/dw/table.hh
+++ b/dw/table.hh
@@ -393,11 +393,9 @@ private:
/**
* hasColPercent becomes true when any cell specifies a percentage width.
- * A negative value in colPercents means LEN_AUTO or LEN_ABS.
*/
- enum { LEN_AUTO = -1, LEN_ABS = -2};
int hasColPercent;
- lout::misc::SimpleVector<float> *colPercents;
+ lout::misc::SimpleVector<core::style::Length> *colPercents;
inline bool childDefined(int n)
{
diff --git a/dw/textblock.cc b/dw/textblock.cc
index cd301871..3bedcdba 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -807,8 +807,8 @@ void Textblock::calcWidgetSize (core::Widget *widget, core::Requisition *size)
size->width = core::style::absLengthVal (wstyle->width)
+ wstyle->boxDiffWidth ();
else
- size->width = (int) (core::style::perLengthVal (wstyle->width)
- * availWidth);
+ size->width =
+ core::style::multiplyWithPerLength (availWidth, wstyle->width);
if (wstyle->height == core::style::LENGTH_AUTO) {
size->ascent = requisition.ascent;
@@ -820,9 +820,10 @@ void Textblock::calcWidgetSize (core::Widget *widget, core::Requisition *size)
+ wstyle->boxDiffHeight ();
size->descent = 0;
} else {
- double len = core::style::perLengthVal (wstyle->height);
- size->ascent = (int) (len * availAscent);
- size->descent = (int) (len * availDescent);
+ size->ascent =
+ core::style::multiplyWithPerLength (wstyle->height, availAscent);
+ size->descent =
+ core::style::multiplyWithPerLength (wstyle->height, availDescent);
}
}
@@ -1475,9 +1476,9 @@ void Textblock::calcTextSize (const char *text, size_t len,
if (core::style::isAbsLength (style->lineHeight))
height = core::style::absLengthVal(style->lineHeight);
else
- height = lout::misc::roundInt (
- core::style::perLengthVal(style->lineHeight) *
- style->font->size);
+ height =
+ core::style::multiplyWithPerLengthRounded (style->font->size,
+ style->lineHeight);
leading = height - style->font->size;
size->ascent += leading / 2;
diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc
index 61e58cdb..226dc3c7 100644
--- a/dw/textblock_linebreaking.cc
+++ b/dw/textblock_linebreaking.cc
@@ -1102,8 +1102,8 @@ void Textblock::initLine1Offset (int wordIndex)
/* don't use text-indent when nesting blocks */
} else {
if (core::style::isPerLength(getStyle()->textIndent)) {
- indent = misc::roundInt(this->availWidth *
- core::style::perLengthVal (getStyle()->textIndent));
+ indent = core::style::multiplyWithPerLengthRounded
+ (this->availWidth, getStyle()->textIndent);
} else {
indent = core::style::absLengthVal (getStyle()->textIndent);
}