diff options
-rw-r--r-- | dpi/downloads.cc | 3 | ||||
-rw-r--r-- | dw/layout.cc | 6 | ||||
-rw-r--r-- | dw/ooffloatsmgr.cc | 75 | ||||
-rw-r--r-- | dw/ooffloatsmgr.hh | 2 | ||||
-rw-r--r-- | dw/textblock.cc | 9 |
5 files changed, 51 insertions, 44 deletions
diff --git a/dpi/downloads.cc b/dpi/downloads.cc index 771098e5..f4bca3e7 100644 --- a/dpi/downloads.cc +++ b/dpi/downloads.cc @@ -520,7 +520,8 @@ void DLItem::log_text_add(const char *buf, ssize_t st) if (isdigit(*q++ = *p)) { // keep here } else if (*p == 'K') { - for (--q; isdigit(q[-1]); --q) ; log_state = ST_discard; + for (--q; isdigit(q[-1]); --q) ; + log_state = ST_discard; } else { log_state = ST_copy; } diff --git a/dw/layout.cc b/dw/layout.cc index 32586cd5..09e27cdb 100644 --- a/dw/layout.cc +++ b/dw/layout.cc @@ -1301,13 +1301,15 @@ void Layout::viewportSizeChanged (View *view, int width, int height) /* If size changes, redraw this view. */ if (viewportWidth != width || viewportHeight != height) { + canvasHeightGreater = false; // reset value here viewportWidth = width; viewportHeight = height; + containerSizeChanged (); + DBG_OBJ_SET_SYM ("canvasHeightGreater", + canvasHeightGreater ? "true" : "false"); DBG_OBJ_SET_NUM ("viewportWidth", viewportWidth); DBG_OBJ_SET_NUM ("viewportHeight", viewportHeight); - - containerSizeChanged (); } DBG_OBJ_LEAVE (); diff --git a/dw/ooffloatsmgr.cc b/dw/ooffloatsmgr.cc index 5cc01b79..721d74ac 100644 --- a/dw/ooffloatsmgr.cc +++ b/dw/ooffloatsmgr.cc @@ -338,8 +338,8 @@ OOFFloatsMgr::OOFFloatsMgr (OOFAwareWidget *container, int oofmIndex) leftFloatsMark = rightFloatsMark = 0; lastLeftTBIndex = lastRightTBIndex = 0; - floatRef = -1; - DBG_OBJ_SET_NUM ("floatRef", floatRef); + SizeChanged = true; + DBG_OBJ_SET_BOOL ("SizeChanged", SizeChanged); containerAllocation = *(container->getAllocation()); @@ -630,34 +630,35 @@ OOFFloatsMgr::Float *OOFFloatsMgr::findFloatByWidget (Widget *widget) return vloat; } +/* + * Currently this is a compound recursion for textblocks: + * markSizeChange -> updateReference -> queueResize -> markSizeChange + * One way to see it is as a widget tree coverage problem. i.e. to cover all + * the nodes that need a resize when a float changes its size. + * The coverage logic of it is shared between resize code and mark code (here). + * + * This implementation works for all the test cases so far. It relies on the + * fact that Widget::queueResize should be called whenever a widget changes its + * size. When "SizeChanged" is true, we notify the parent, when not, just the + * following textblocks. + */ void OOFFloatsMgr::markSizeChange (int ref) { DBG_OBJ_ENTER ("resize.oofm", 0, "markSizeChange", "%d", ref); - // We implement "incremental resizing" (kind of), by remembering the largest - // value for "ref", in "floatRef". It is reset again in getSize(), which is - // called by sizeRequest(). - if (floatRef == -1 || ref > floatRef) { - Float *vloat; - - if (isSubRefLeftFloat (ref)) - vloat = leftFloats->get (getFloatIndexFromSubRef (ref)); - else if (isSubRefRightFloat (ref)) - vloat = rightFloats->get (getFloatIndexFromSubRef (ref)); - else { - assertNotReached(); - vloat = NULL; // compiler happiness - } + // When "SizeChanged" is true, we know this float changed its size. + // This helps to prune redundant passes. + // "SizeChanged" is set by getSize(), which is called by sizeRequest(). - vloat->dirty = true; - DBG_OBJ_SET_BOOL_O (vloat->getWidget (), "<Float>.dirty", vloat->dirty); + SortedFloatsVector *list; + list = isSubRefLeftFloat(ref) ? leftFloats : rightFloats; + Float *vloat = list->get (getFloatIndexFromSubRef (ref)); + + vloat->dirty = true; + DBG_OBJ_SET_BOOL_O (vloat->getWidget (), "<Float>.dirty", vloat->dirty); + + updateGenerators (vloat); - updateGenerators (vloat); - - floatRef = ref; - DBG_OBJ_SET_NUM ("floatRef", floatRef); - } - DBG_OBJ_LEAVE (); } @@ -668,22 +669,28 @@ void OOFFloatsMgr::updateGenerators (Float *vloat) { DBG_OBJ_ENTER ("resize.oofm", 0, "updateGenerators", "#%d [%p]", vloat->index, vloat->getWidget ()); - + assert (vloat->getWidget()->getWidgetReference() != NULL); - + int first = getOOFAwareWidget(vloat->generator)->index; DBG_OBJ_MSGF ("resize.oofm", 1, "updating from %d", first); - - tbInfos->get(first)->getOOFAwareWidget() - ->updateReference (vloat->getWidget()->getWidgetReference() - ->parentRef); - + + //printf("IN markSizeChange %p ref %d SzCh=%d\n", this, ref, + // (int)SizeChanged); + + if (SizeChanged) + tbInfos->get(first)->getOOFAwareWidget() + ->updateReference (vloat->getWidget()->getWidgetReference() + ->parentRef); + for (int i = first + 1; i < tbInfos->size(); i++) tbInfos->get(i)->getOOFAwareWidget()->updateReference(0); + SizeChanged = false; // Done. + DBG_OBJ_LEAVE (); } - + /** * `y` is given relative to the container. */ @@ -755,7 +762,7 @@ void OOFFloatsMgr::tellPosition1 (Widget *widget, int x, int y) ensureFloatSize (vloat); int oldYReal = vloat->yReal; - + // "yReal" may change due to collisions (see below). vloat->yReq = vloat->yReal = y; @@ -955,7 +962,7 @@ void OOFFloatsMgr::getSize (Requisition *cbReq, int *oofWidth, int *oofHeight) *oofHeight = max (oofHeightLeft, oofHeightRight) + container->boxRestHeight (); - floatRef = -1; + SizeChanged = true; DBG_OBJ_SET_NUM ("floatRef", floatRef); DBG_OBJ_MSGF ("resize.oofm", 1, diff --git a/dw/ooffloatsmgr.hh b/dw/ooffloatsmgr.hh index cae57dd5..2b297b92 100644 --- a/dw/ooffloatsmgr.hh +++ b/dw/ooffloatsmgr.hh @@ -165,7 +165,7 @@ private: TBInfo> *tbInfosByOOFAwareWidget; int lastLeftTBIndex, lastRightTBIndex, leftFloatsMark, rightFloatsMark; - int floatRef; + bool SizeChanged; void moveExternalIndices (lout::container::typed::Vector<Float> *list, int oldStartIndex, int diff); diff --git a/dw/textblock.cc b/dw/textblock.cc index 615e6f11..a92832b9 100644 --- a/dw/textblock.cc +++ b/dw/textblock.cc @@ -3046,12 +3046,9 @@ void Textblock::updateReference (int ref) { DBG_OBJ_ENTER ("resize", 0, "updateReference", "%d", ref); - // This method can be optimized: nothing must be done when (i) there are no - // words, *and* (ii) there is no float clearance. If the second is not the - // case, `queueResize` must still be called, since `extraSpace.top` may be - // changed. - - if (!(words->size () == 0 && getStyle()->clear == core::style::CLEAR_NONE)) + // Only `queueResize` when there're words or float clearance + // (float clearance may change `extraSpace.top`). + if (words->size () > 0 || getStyle()->clear != core::style::CLEAR_NONE) queueResize (ref, false); DBG_OBJ_LEAVE (); |