diff options
-rw-r--r-- | dw/outofflowmgr.cc | 34 | ||||
-rw-r--r-- | dw/table.cc | 14 | ||||
-rw-r--r-- | dw/textblock.cc | 78 | ||||
-rw-r--r-- | dw/textblock.hh | 22 |
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) |