aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dpi/downloads.cc3
-rw-r--r--dw/layout.cc6
-rw-r--r--dw/ooffloatsmgr.cc75
-rw-r--r--dw/ooffloatsmgr.hh2
-rw-r--r--dw/textblock.cc9
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 ();