changeset 1671:7fe586a2c260

fix redraw optimization When a widget changes it's height, this may affect the position of other words in the same line. Take care by only applying the redraw optimization if there are no other words in the line. This special case is quite common e.g with nested <div>'s or table based layouts and the redraw optimization avoids unnecessary redraws. Reported by: Dennis Nezic
author Johannes Hofmann <Johannes.Hofmann@gmx.de>
date Thu, 29 Apr 2010 15:36:43 +0200
parents 8bace2ec6321
children 2ad866aed0a1
files dw/textblock.cc
diffstat 1 files changed, 19 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/dw/textblock.cc	Wed Apr 28 16:57:27 2010 +0000
+++ b/dw/textblock.cc	Thu Apr 29 15:36:43 2010 +0200
@@ -397,14 +397,27 @@
                 * child might be a table covering the whole page so we would
                 * end up redrawing the whole screen over and over.
                 * The drawing of the child content is left to the child itself.
+                * However this optimization is only possible if the widget is
+                * the only word in the line apart from an optional BREAK.
+                * Otherwise the height change of the widget could change the
+                * position of other words in the line, requiring a
+                * redraw of the complete line.
                 */
-               int childChangedY =
-                  misc::min(childAllocation.y - allocation->y +
-                     childAllocation.ascent + childAllocation.descent,
-                     oldChildAllocation->y - this->allocation.y +
-                     oldChildAllocation->ascent + oldChildAllocation->descent);
+               if (line->lastWord == line->firstWord ||
+                   (line->lastWord == line->firstWord + 1 &&
+                    words->getRef (line->lastWord)->content.type ==
+                    core::Content::BREAK)) {
 
-               redrawY = misc::min (redrawY, childChangedY);
+                  int childChangedY =
+                     misc::min(childAllocation.y - allocation->y +
+                        childAllocation.ascent + childAllocation.descent,
+                        oldChildAllocation->y - this->allocation.y +
+                        oldChildAllocation->ascent + oldChildAllocation->descent);
+
+                  redrawY = misc::min (redrawY, childChangedY);
+               } else {
+                  redrawY = misc::min (redrawY, lineYOffsetWidget (line));
+               }
             }
 
             word->content.widget->sizeAllocate (&childAllocation);