aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Geerken <devnull@localhost>2014-08-29 19:00:08 +0200
committerSebastian Geerken <devnull@localhost>2014-08-29 19:00:08 +0200
commit9430132423d99689de9c02db79df60fd1b4a5703 (patch)
tree8dd8f75e27d9789be5146560ef6557ef59fc589e
parentcd2b7abca85195e32eff716ed15aa0b9051fe46a (diff)
parent16607bb593346401334d0988b2b25a3df3b5ce0d (diff)
Merge with main repo.
-rw-r--r--dw/outofflowmgr.cc34
-rw-r--r--dw/table.cc14
-rw-r--r--dw/textblock.cc78
-rw-r--r--dw/textblock.hh22
4 files changed, 110 insertions, 38 deletions
diff --git a/dw/outofflowmgr.cc b/dw/outofflowmgr.cc
index 70f55fb0..3dd09ebd 100644
--- a/dw/outofflowmgr.cc
+++ b/dw/outofflowmgr.cc
@@ -217,16 +217,36 @@ int OutOfFlowMgr::Float::ComparePosition::compare (Object *o1, Object *o2)
bool a2 = fl2->getWidget () ? fl2->getWidget()->wasAllocated () : true;
DBG_OBJ_MSGF_O ("border", 2, oofm,
- "float 1 allocated: %s; float 2 allocated: %s",
- a1 ? "yes" : "no", a2 ? "yes" : "no");
+ "float 1 (%p) allocated: %s; float 2 (%p) allocated: %s",
+ fl1->getWidget (), a1 ? "yes" : "no", fl2->getWidget (),
+ a2 ? "yes" : "no");
if (a1 && a2) {
- int fly1 = fl1->getWidget() ? fl1->getWidget()->getAllocation()->y :
- oofm->getAllocation(fl1->generatingBlock)->y + fl1->yReal;
- int fly2 = fl2->getWidget() ? fl2->getWidget()->getAllocation()->y :
- oofm->getAllocation(fl2->generatingBlock)->y + fl2->yReal;
- DBG_OBJ_MSGF_O ("border", 2, oofm, "y diff = %d - %d", fly1, fly2);
+ int fly1, fly2;
+
+ if (fl1->getWidget()) {
+ fly1 = fl1->getWidget()->getAllocation()->y;
+ DBG_OBJ_MSGF_O ("border", 2, oofm, "fly1 = %d", fly1);
+ } else {
+ fly1 = oofm->getAllocation(fl1->generatingBlock)->y + fl1->yReal;
+ DBG_OBJ_MSGF_O ("border", 2, oofm, "fly1 = %d + %d = %d",
+ oofm->getAllocation(fl1->generatingBlock)->y,
+ fl1->yReal, fly1);
+ }
+
+ if (fl2->getWidget()) {
+ fly2 = fl2->getWidget()->getAllocation()->y;
+ DBG_OBJ_MSGF_O ("border", 2, oofm, "fly2 = %d", fly2);
+ } else {
+ fly2 = oofm->getAllocation(fl2->generatingBlock)->y + fl2->yReal;
+ DBG_OBJ_MSGF_O ("border", 2, oofm, "fly2 = %d + %d = %d",
+ oofm->getAllocation(fl2->generatingBlock)->y,
+ fl2->yReal, fly2);
+ }
+
r = fly1 - fly2;
+
+ DBG_OBJ_MSGF_O ("border", 2, oofm, "r = %d - %d = %d", fly1, fly2, r);
} else if (a1 && !a2)
r = -1;
else if (!a1 && a2)
diff --git a/dw/table.cc b/dw/table.cc
index 9922543f..746856c7 100644
--- a/dw/table.cc
+++ b/dw/table.cc
@@ -259,6 +259,20 @@ int Table::calcAvailWidthForDescendant (Widget *child)
for (int i = 0; i < children->get(n)->cell.colspanEff; i++)
width += colWidths->get (col + i);
width = misc::max (width, 0);
+
+ if (child != actualChild) {
+ // For table cells (direct children: child == actualChild),
+ // CSS 'width' is already regarded in the column calculation.
+ // However, for children of the table cells, CSS 'width' must
+ // be regarded here.
+
+ int corrWidth = width;
+ child->calcFinalWidth (child->getStyle(), -1, this, 0, true,
+ &corrWidth);
+
+ // But better not exceed it ... (TODO: Only here?)
+ width = misc::min (width, corrWidth);
+ }
}
}
}
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;
}
diff --git a/dw/textblock.hh b/dw/textblock.hh
index 5e8986b3..3abe1f41 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -475,6 +475,9 @@ protected:
friend class TextblockIterator;
+ // See sizeAllocateImpl for details. It is also used elsewhere.
+ core::Allocation childBaseAllocation;
+
/* These fields provide some ad-hoc-functionality, used by sub-classes. */
bool hasListitemValue; /* If true, the first word of the page is treated
specially (search in source). */
@@ -637,24 +640,25 @@ protected:
return getTextblockForLine (lineNo) == NULL;
}
- inline int lineYOffsetWidgetAllocation (Line *line,
- core::Allocation *allocation)
+ inline int _lineYOffsetWidgetAllocation (Line *line,
+ core::Allocation *allocation)
{
return line->top + (allocation->ascent - lines->getRef(0)->boxAscent);
}
inline int lineYOffsetWidget (Line *line)
{
- return lineYOffsetWidgetAllocation (line, &allocation);
+ return _lineYOffsetWidgetAllocation (line, &childBaseAllocation);
}
/**
- * Like lineYOffsetCanvas, but with the allocation as parameter.
+ * Like lineYOffsetCanvas, but with the allocation as parameter. Rarely used
+ * outside of lineYOffsetCanvas.
*/
- inline int lineYOffsetCanvasAllocation (Line *line,
+ inline int _lineYOffsetCanvasAllocation (Line *line,
core::Allocation *allocation)
{
- return allocation->y + lineYOffsetWidgetAllocation (line, allocation);
+ return allocation->y + _lineYOffsetWidgetAllocation (line, allocation);
}
/**
@@ -662,7 +666,7 @@ protected:
*/
inline int lineYOffsetCanvas (Line *line)
{
- return lineYOffsetCanvasAllocation(line, &allocation);
+ return _lineYOffsetCanvasAllocation(line, &childBaseAllocation);
}
inline int lineYOffsetWidgetI (int lineIndex)
@@ -673,8 +677,8 @@ protected:
inline int lineYOffsetWidgetIAllocation (int lineIndex,
core::Allocation *allocation)
{
- return lineYOffsetWidgetAllocation (lines->getRef (lineIndex),
- allocation);
+ return _lineYOffsetWidgetAllocation (lines->getRef (lineIndex),
+ allocation);
}
inline int lineYOffsetCanvasI (int lineIndex)