aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dw/outofflowmgr.cc34
-rw-r--r--dw/outofflowmgr.hh8
-rw-r--r--dw/textblock.hh3
-rw-r--r--dw/textblock_linebreaking.cc61
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 ();
}