diff options
-rw-r--r-- | dw/style.hh | 36 | ||||
-rw-r--r-- | dw/table.cc | 72 | ||||
-rw-r--r-- | dw/table.hh | 4 | ||||
-rw-r--r-- | dw/textblock.cc | 17 | ||||
-rw-r--r-- | dw/textblock_linebreaking.cc | 4 |
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); } |