aboutsummaryrefslogtreecommitdiff
path: root/dw/textblock.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dw/textblock.cc')
-rw-r--r--dw/textblock.cc78
1 files changed, 56 insertions, 22 deletions
diff --git a/dw/textblock.cc b/dw/textblock.cc
index 0bf4b08a..bfa59502 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -536,6 +536,48 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
showMissingLines ();
+ // In some cases, this allocation results in child allocation which
+ // exceed the top of this allocation, which will then result in an
+ // endless resize idle cascade and CPU hogging (when floats come
+ // into play).
+ //
+ // Example:
+ //
+ // <div id="id1" style="height: 50px">
+ // <div id="id2">...</div>
+ // <div>
+ //
+ // Assume that the inner section, div#id2, has a height of 200px =
+ // 100px (ascent) + 100px (descent). For the outer section,
+ // div#id1, this will be initially calculated for the size, but
+ // then (because of CSS 'height') reduced to 50px = 50px (ascent) +
+ // 0px (descent). Without the following correction, the inner
+ // section (div#id2) would be allocated at 50px top of the
+ // allocation of the outer section: childAllocation->y =
+ // allocation->y - 50.
+ //
+ // For this reason, we calculat "childBaseAllocation", which will
+ // avoid this case; in the example above, the height will be 50px =
+ // 100px (ascent) - 50px (descent: negative).
+
+ childBaseAllocation.x = allocation->x;
+ childBaseAllocation.y = allocation->y;
+ childBaseAllocation.width = allocation->width;
+ childBaseAllocation.ascent =
+ misc::max (allocation->ascent,
+ // Reconstruct the initial size; see
+ // Textblock::sizeRequestImpl.
+ (lines->size () > 0 ? lines->getRef(0)->boxAscent : 0)
+ + verticalOffset + getStyle()->boxOffsetY ());
+ childBaseAllocation.descent =
+ allocation->ascent + allocation->descent - childBaseAllocation.ascent;
+
+ DBG_OBJ_SET_NUM ("childBaseAllocation.x", childBaseAllocation.x);
+ DBG_OBJ_SET_NUM ("childBaseAllocation.y", childBaseAllocation.y);
+ DBG_OBJ_SET_NUM ("childBaseAllocation.width", childBaseAllocation.width);
+ DBG_OBJ_SET_NUM ("childBaseAllocation.ascent", childBaseAllocation.ascent);
+ DBG_OBJ_SET_NUM ("childBaseAllocation.descent", childBaseAllocation.descent);
+
if (containingBlock->outOfFlowMgr)
containingBlock->outOfFlowMgr->sizeAllocateStart (this, allocation);
@@ -557,7 +599,7 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
// Especially for floats, allocation->width may be different
// from the line break width, so that for centered and right
// text, the offsets have to be recalculated again.
- calcTextOffset (lineIndex, allocation->width);
+ calcTextOffset (lineIndex, childBaseAllocation.width);
line = lines->getRef (lineIndex);
xCursor = line->textOffset;
@@ -576,10 +618,10 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
"allocating widget in flow: line %d, word %d",
lineIndex, wordIndex);
- childAllocation.x = xCursor + allocation->x;
+ childAllocation.x = xCursor + childBaseAllocation.x;
DBG_OBJ_MSGF ("resize", 1, "childAllocation.x = %d + %d = %d",
- xCursor, allocation->x, childAllocation.x);
+ xCursor, childBaseAllocation.x, childAllocation.x);
/** \todo Justification within the line is done here. */
@@ -590,27 +632,13 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
/* align=bottom (base line) */
/* Commented lines break the n2 and n3 test cases at
* http://www.dillo.org/test/img/ */
- childAllocation.y =
- lineYOffsetCanvasAllocation (line, allocation)
+ childAllocation.y = lineYOffsetCanvas (line)
+ (line->boxAscent - word->size.ascent)
- word->content.widget->getStyle()->margin.top;
- DBG_OBJ_MSG_START ();
- DBG_OBJ_MSGF ("resize", 1,
- "lineYOffsetWidgetAllocation (...) = %d + (%d - %d) "
- "= %d",
- line->top, allocation->ascent,
- lines->getRef(0)->boxAscent,
- lineYOffsetWidgetAllocation (line, allocation));
- DBG_OBJ_MSGF ("resize", 1,
- "lineYOffsetCanvasAllocation (...) = %d + %d = %d",
- allocation->y,
- lineYOffsetWidgetAllocation (line, allocation),
- lineYOffsetCanvasAllocation (line, allocation));
- DBG_OBJ_MSG_END ();
DBG_OBJ_MSGF ("resize", 1,
"childAllocation.y = %d + (%d - %d) - %d = %d",
- lineYOffsetCanvasAllocation (line, allocation),
+ lineYOffsetCanvas (line),
line->boxAscent, word->size.ascent,
word->content.widget->getStyle()->margin.top,
childAllocation.y);
@@ -657,7 +685,7 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
core::Content::BREAK)) {
int childChangedY =
- misc::min(childAllocation.y - allocation->y +
+ misc::min(childAllocation.y - childBaseAllocation.y +
childAllocation.ascent + childAllocation.descent,
oldChildAllocation->y - this->allocation.y +
oldChildAllocation->ascent +
@@ -693,7 +721,7 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
y = allocation->y + allocation->ascent + allocation->descent;
} else {
Line *line = lines->getRef(findLineOfWord (anchor->wordIndex));
- y = lineYOffsetCanvasAllocation (line, allocation);
+ y = lineYOffsetCanvas (line);
}
changeAnchor (anchor->name, y);
}
@@ -1568,11 +1596,13 @@ int Textblock::findLineIndexWhenNotAllocated (int y)
int Textblock::findLineIndexWhenAllocated (int y)
{
assert (wasAllocated ());
- return findLineIndex (y, allocation.ascent);
+ return findLineIndex (y, childBaseAllocation.ascent);
}
int Textblock::findLineIndex (int y, int ascent)
{
+ DBG_OBJ_ENTER ("events", 0, "findLineIndex", "%d, %d", y, ascent);
+
core::Allocation alloc;
alloc.ascent = ascent; // More is not needed.
@@ -1601,6 +1631,10 @@ int Textblock::findLineIndex (int y, int ascent)
* Dw_page_find_link() --EG
* That function has now been inlined into Dw_page_motion_notify() --JV
*/
+
+ DBG_OBJ_MSGF ("events", 1, "=> %d", low);
+ DBG_OBJ_LEAVE ();
+
return low;
}