diff options
Diffstat (limited to 'dw')
-rw-r--r-- | dw/outofflowmgr.cc | 34 | ||||
-rw-r--r-- | dw/outofflowmgr.hh | 8 | ||||
-rw-r--r-- | dw/textblock.hh | 3 | ||||
-rw-r--r-- | dw/textblock_linebreaking.cc | 61 |
4 files changed, 95 insertions, 11 deletions
diff --git a/dw/outofflowmgr.cc b/dw/outofflowmgr.cc index 62386b15..2e6171ad 100644 --- a/dw/outofflowmgr.cc +++ b/dw/outofflowmgr.cc @@ -2026,6 +2026,40 @@ bool OutOfFlowMgr::hasFloat (Textblock *textblock, Side side, int y, int h, return first != -1; } +int OutOfFlowMgr::getLeftFloatHeight (Textblock *textblock, int y, int h, + Textblock *lastGB, int lastExtIndex) +{ + return getFloatHeight (textblock, LEFT, y, h, lastGB, lastExtIndex); +} + +int OutOfFlowMgr::getRightFloatHeight (Textblock *textblock, int y, int h, + Textblock *lastGB, int lastExtIndex) +{ + return getFloatHeight (textblock, RIGHT, y, h, lastGB, lastExtIndex); +} + +// Calculate height from the position *y*. +int OutOfFlowMgr::getFloatHeight (Textblock *textblock, Side side, int y, int h, + Textblock *lastGB, int lastExtIndex) +{ + DBG_OBJ_ENTER ("border", 0, "getFloatHeight", "%p, %s, %d, %d, %p, %d", + textblock, side == LEFT ? "LEFT" : "RIGHT", y, h, + lastGB, lastExtIndex); + + SortedFloatsVector *list = getFloatsListForTextblock (textblock, side); + int first = list->findFirst (textblock, y, h, lastGB, lastExtIndex); + assert (first != -1); /* This method must not be called when there is no + float on the respective side. */ + + Float *vloat = list->get(first); + ensureFloatSize (vloat); + int height = vloat->size.ascent + vloat->size.descent + vloat->yReal - y; + + DBG_OBJ_MSGF ("border", 1, "=> %d", height); + DBG_OBJ_LEAVE (); + return height; +} + /** * Returns position relative to the textblock "tb". */ diff --git a/dw/outofflowmgr.hh b/dw/outofflowmgr.hh index 19205717..a89e8662 100644 --- a/dw/outofflowmgr.hh +++ b/dw/outofflowmgr.hh @@ -316,6 +316,9 @@ private: bool hasFloat (Textblock *textblock, Side side, int y, int h, Textblock *lastGB, int lastExtIndex); + int getFloatHeight (Textblock *textblock, Side side, int y, int h, + Textblock *lastGB, int lastExtIndex); + int getClearPosition (Textblock *tb, Side side); void ensureFloatSize (Float *vloat); @@ -426,6 +429,11 @@ public: bool hasFloatRight (Textblock *textblock, int y, int h, Textblock *lastGB, int lastExtIndex); + int getLeftFloatHeight (Textblock *textblock, int y, int h, + Textblock *lastGB, int lastExtIndex); + int getRightFloatHeight (Textblock *textblock, int y, int h, + Textblock *lastGB, int lastExtIndex); + int getClearPosition (Textblock *tb); inline static bool isRefOutOfFlow (int ref) diff --git a/dw/textblock.hh b/dw/textblock.hh index 7b62dd3b..c83c7c83 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -544,6 +544,7 @@ protected: outOfFlowMgr->get...Border, or 0, if outOfFlowMgr is NULL */ + int newLineLeftFloatHeight, newLineRightFloatHeight; // Ascent and descent of the newly constructed line, i. e. maximum // of all words ascent/descent since the end of the last line. Not @@ -566,7 +567,7 @@ protected: void getWordExtremes (Word *word, core::Extremes *extremes); void justifyLine (Line *line, int diff); Line *addLine (int firstWord, int lastWord, int newLastOofPos, - bool temporary); + bool temporary, int minHeight); void calcWidgetSize (core::Widget *widget, core::Requisition *size); void rewrap (); void fillParagraphs (); diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc index beae36da..4f53954b 100644 --- a/dw/textblock_linebreaking.cc +++ b/dw/textblock_linebreaking.cc @@ -346,10 +346,12 @@ void Textblock::justifyLine (Line *line, int diff) Textblock::Line *Textblock::addLine (int firstWord, int lastWord, - int newLastOofPos, bool temporary) + int newLastOofPos, bool temporary, + int minHeight) { - DBG_OBJ_ENTER ("construct.line", 0, "addLine", "%d, %d", - firstWord, lastWord); + DBG_OBJ_ENTER ("construct.line", 0, "addLine", "%d, %d, %d, %s, %d", + firstWord, lastWord, newLastOofPos, + temporary ? "true" : "false", minHeight); DBG_OBJ_MSGF ("construct.line", 0, "=> %d", lines->size ()); int lineWidth; @@ -383,7 +385,7 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord, if(!temporary) { // If the last line was temporary, this will be temporary, too, even // if not requested. - if (lines->size () == 1 || nonTemporaryLines == lines->size () -1) + if (lines->size () == 1 || nonTemporaryLines == lines->size () - 1) nonTemporaryLines = lines->size (); } @@ -441,8 +443,9 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord, // Especially empty lines (possible when there are floats) have // zero height, which may cause endless loops. For this reasons, - // the height should be positive. - line->boxAscent = misc::max (line->boxAscent, 1); + // the height should be positive (assuming the caller passed + // minHeight > 0). + line->boxAscent = misc::max (line->boxAscent, minHeight); DBG_OBJ_MSGF ("construct.line", 1, "top = %d\n", line->top); DBG_OBJ_MSGF ("construct.line", 1, "boxAscent = %d\n", line->boxAscent); @@ -760,7 +763,27 @@ int Textblock::wrapWordInFlow (int wordIndex, bool wrapAll) DBG_OBJ_MSG_END (); } while (floatHandled); - addLine (firstIndex, breakPos, lastFloatPos, tempNewLine); + int minHeight; + if (firstIndex <= breakPos) + // Not an empty line: calculate line height from contents. + minHeight = 1; + else { + // Empty line. Too avoid too many lines one pixel high, we + // use the float heights. + if (newLineHasFloatLeft && newLineHasFloatRight) + minHeight = misc::max (misc::min (newLineLeftFloatHeight, + newLineRightFloatHeight), + 1); + else if (newLineHasFloatLeft && !newLineHasFloatRight) + minHeight = misc::max (newLineLeftFloatHeight, 1); + else if (!newLineHasFloatLeft && newLineHasFloatRight) + minHeight = misc::max (newLineRightFloatHeight, 1); + else + // May this happen? + minHeight = 1; + } + + addLine (firstIndex, breakPos, lastFloatPos, tempNewLine, minHeight); DBG_OBJ_MSGF ("construct.word", 1, "accumulating again from %d to %d\n", @@ -1938,20 +1961,38 @@ void Textblock::calcBorders (int lastOofRef, int height) newLineRightBorder = containingBlock->outOfFlowMgr->getRightBorder (this, y, height, this, effOofRef); + newLineLeftFloatHeight = newLineHasFloatLeft ? + containingBlock->outOfFlowMgr->getLeftFloatHeight (this, y, height, + this, effOofRef) : + 0; + newLineRightFloatHeight = newLineHasFloatRight ? + containingBlock->outOfFlowMgr->getRightFloatHeight (this, y, height, + this, effOofRef) : + 0; DBG_OBJ_MSGF ("construct.line", 1, - "%d (%s) / %d (%s), at %d (%d), until %d = " + "%d * %d (%s) / %d * %d (%s), at %d (%d), until %d = " "max (%d, %d - 1)", - newLineLeftBorder, newLineHasFloatLeft ? "true" : "false", - newLineRightBorder, newLineHasFloatRight ? "true" : "false", + newLineLeftBorder, newLineLeftFloatHeight, + newLineHasFloatLeft ? "true" : "false", + newLineRightBorder, newLineRightFloatHeight, + newLineHasFloatRight ? "true" : "false", y, height, effOofRef, lastOofRef, firstWordOfLine); } else { newLineHasFloatLeft = newLineHasFloatRight = false; newLineLeftBorder = newLineRightBorder = 0; + newLineLeftFloatHeight = newLineRightFloatHeight = 0; DBG_OBJ_MSG ("construct.line", 0, "<i>no CB of OOFM</i>"); } + DBG_OBJ_SET_BOOL ("newLineHasFloatLeft", newLineHasFloatLeft); + DBG_OBJ_SET_BOOL ("newLineHasFloatRight", newLineHasFloatRight); + DBG_OBJ_SET_NUM ("newLineLeftBorder", newLineLeftBorder); + DBG_OBJ_SET_NUM ("newLineRightBorder", newLineRightBorder); + DBG_OBJ_SET_NUM ("newLineLeftFloatHeight", newLineLeftFloatHeight); + DBG_OBJ_SET_NUM ("newLineRightFloatHeight", newLineRightFloatHeight); + DBG_OBJ_LEAVE (); } |