Hi, below is an initial patch that improves scrolling performance of dillo-fltk by copying screen data instead of rerendering it. It's based on Scroll.cxx from fltk. The difference is noticeable mostly when scrolling large images especially within a remote X11 session. The newly introduced scrollDX / scrollDY could probabely be combined with the existing oldScrollX / oldScrollY variables. Regards, Johannes diff --git a/dw-testbed-0.0.43j/dw/fltkviewbase.cc b/dw-testbed-0.0.43j/dw/fltkviewbase.cc --- a/dw-testbed-0.0.43j/dw/fltkviewbase.cc +++ b/dw-testbed-0.0.43j/dw/fltkviewbase.cc @@ -54,18 +54,16 @@ void FltkViewBase::draw () Group::draw (); - if (damage () & DAMAGE_EXPOSE) { - setcolor (bgColor); - ::fltk::Rectangle rect (0, 0, w(), h()); - fillrect (rect); - - core::Rectangle area; - area.x = translateViewXToCanvasX (0); - area.y = translateViewYToCanvasY (0); - area.width = translateViewXToCanvasX (0 + w ()) - 0; - area.height = translateViewYToCanvasY (0 + h ()) - 0; - theLayout->expose (this, &area); - } + setcolor (bgColor); + ::fltk::Rectangle rect (0, 0, w(), h()); + fillrect (rect); + + core::Rectangle area; + area.x = translateViewXToCanvasX (0); + area.y = translateViewYToCanvasY (0); + area.width = translateViewXToCanvasX (0 + w ()) - 0; + area.height = translateViewYToCanvasY (0 + h ()) - 0; + theLayout->expose (this, &area); } core::ButtonState getDwButtonState () diff --git a/dw-testbed-0.0.43j/dw/fltkviewport.cc b/dw-testbed-0.0.43j/dw/fltkviewport.cc --- a/dw-testbed-0.0.43j/dw/fltkviewport.cc +++ b/dw-testbed-0.0.43j/dw/fltkviewport.cc @@ -131,8 +131,8 @@ void FltkViewport::hscrollbarChanged () { int oldScrollX = scrollX; scrollX = hscrollbar->value (); - /** \bug Inefficient */ - redraw (DAMAGE_EXPOSE); + scrollDX = scrollX - oldScrollX; + redraw (DAMAGE_SCROLL); updateCanvasWidgets (oldScrollX, scrollY); theLayout->scrollPosChanged (this, scrollX, scrollY); } @@ -141,8 +141,8 @@ void FltkViewport::vscrollbarChanged () { int oldScrollY = scrollY; scrollY = vscrollbar->value (); - /** \bug Inefficient */ - redraw (DAMAGE_EXPOSE); + scrollDY = scrollY - oldScrollY; + redraw (DAMAGE_SCROLL); updateCanvasWidgets (scrollX, oldScrollY); theLayout->scrollPosChanged (this, scrollX, scrollY); } @@ -163,6 +163,25 @@ void FltkViewport::layout () { theLayout->viewportSizeChanged (this, w(), h()); adjustScrollbarsAndGadgetsAllocation (); +} + +void FltkViewport::draw_area (void *data, const Rectangle& cr ) +{ + FltkViewport *vp = (FltkViewport*) data; + push_clip(cr); + + vp->FltkWidgetView::draw (); + + //draw_child (*hscrollbar); + //draw_child (*vscrollbar); + + for(Iterator <TypedPointer < ::fltk::Widget> > it = vp->gadgets->iterator (); + it.hasNext (); ) { + ::fltk::Widget *widget = it.getNext()->getTypedValue (); + vp->draw_child (*widget); + } + + pop_clip(); } void FltkViewport::draw () @@ -170,20 +189,16 @@ void FltkViewport::draw () int hdiff = vscrollbar->visible () ? SCROLLBAR_THICKNESS : 0; int vdiff = hscrollbar->visible () ? SCROLLBAR_THICKNESS : 0; Rectangle cr (0, 0, w () - hdiff, h () - vdiff); - push_clip(cr); - - FltkWidgetView::draw (); - - //draw_child (*hscrollbar); - //draw_child (*vscrollbar); - - for(Iterator <TypedPointer < ::fltk::Widget> > it = gadgets->iterator (); - it.hasNext (); ) { - ::fltk::Widget *widget = it.getNext()->getTypedValue (); - draw_child (*widget); - } - - pop_clip(); + int d = damage(); + + if (d == DAMAGE_SCROLL) { + scrollrect(cr, -scrollDX, -scrollDY, draw_area, this); + } else { + draw_area(this, cr); + } + + scrollDX = 0; + scrollDY = 0; } int FltkViewport::handle (int event) @@ -205,8 +220,9 @@ int FltkViewport::handle (int event) case PageUpKey: oldScrollY = scrollY; scrollY -= vscrollbar->pagesize (); + scrollDY = scrollY - oldScrollY; adjustScrollbarValues (); - redraw (DAMAGE_EXPOSE); + redraw (DAMAGE_SCROLL); updateCanvasWidgets (scrollX, oldScrollY); theLayout->scrollPosChanged (this, scrollX, scrollY); return 1; @@ -214,8 +230,9 @@ int FltkViewport::handle (int event) case PageDownKey: oldScrollY = scrollY; scrollY += vscrollbar->pagesize (); + scrollDY = scrollY - oldScrollY; adjustScrollbarValues (); - redraw (DAMAGE_EXPOSE); + redraw (DAMAGE_SCROLL); updateCanvasWidgets (scrollX, oldScrollY); theLayout->scrollPosChanged (this, scrollX, scrollY); return 1; @@ -254,12 +271,13 @@ void FltkViewport::scrollTo (int x, int void FltkViewport::scrollTo (int x, int y) { int oldScrollX = scrollX; - //int oldScrollY = scrollY; + int oldScrollY = scrollY; scrollX = x; scrollY = y; + scrollDX = scrollX - oldScrollX; + scrollDY = scrollY - oldScrollY; adjustScrollbarValues (); - /** \bug Inefficient */ - redraw (DAMAGE_EXPOSE); + redraw (DAMAGE_SCROLL); updateCanvasWidgets (oldScrollX, scrollY); } diff --git a/dw-testbed-0.0.43j/dw/fltkviewport.hh b/dw-testbed-0.0.43j/dw/fltkviewport.hh --- a/dw-testbed-0.0.43j/dw/fltkviewport.hh +++ b/dw-testbed-0.0.43j/dw/fltkviewport.hh @@ -20,6 +20,7 @@ private: enum { SCROLLBAR_THICKNESS = 15 }; int scrollX, scrollY; + int scrollDX, scrollDY; ::fltk::Scrollbar *vscrollbar, *hscrollbar; @@ -35,6 +36,7 @@ private: static void vscrollbarCallback (Widget *vscrollbar, void *viewportPtr); void updateCanvasWidgets (int oldScrollX, int oldScrollY); + static void draw_area (void *data, const Rectangle& cr); protected: int translateViewXToCanvasX (int x);