changeset 1903:631c40949a94

port buffered drawing
author Johannes Hofmann <Johannes.Hofmann@gmx.de>
date Fri, 11 Feb 2011 22:55:45 +0100
parents 06fb15f69228
children a629521ec82a
files dw/fltkviewbase.cc dw/fltkviewbase.hh
diffstat 2 files changed, 74 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/dw/fltkviewbase.cc	Wed Feb 09 01:31:14 2011 +0000
+++ b/dw/fltkviewbase.cc	Fri Feb 11 22:55:45 2011 +0100
@@ -35,7 +35,32 @@
 namespace dw {
 namespace fltk {
 
-Fl_Image *FltkViewBase::backBuffer;
+FltkViewBase::BackBuffer::BackBuffer ()
+{
+   w = 0;
+   h = 0;
+   created = false;
+}
+
+FltkViewBase::BackBuffer::~BackBuffer ()
+{
+   if (created)
+      fl_delete_offscreen (offscreen);
+}
+
+void FltkViewBase::BackBuffer::setSize (int w, int h)
+{
+   if (!created || w > this->w || h > this->h) {
+      this->w = w;
+      this->h = h;
+      if (created)
+         fl_delete_offscreen (offscreen);
+      offscreen = fl_create_offscreen (w, h);
+      created = true;
+   }
+}
+
+FltkViewBase::BackBuffer *FltkViewBase::backBuffer;
 bool FltkViewBase::backBufferInUse;
 
 FltkViewBase::FltkViewBase (int x, int y, int w, int h, const char *label):
@@ -49,10 +74,10 @@
 #if 0
 PORT1.3
    exposeArea = NULL;
+#endif
    if (backBuffer == NULL) {
-      backBuffer = new Fl_Image ();
+      backBuffer = new BackBuffer ();
    }
-#endif
 }
 
 FltkViewBase::~FltkViewBase ()
@@ -62,10 +87,7 @@
 
 void FltkViewBase::setBufferedDrawing (bool b) {
    if (b && backBuffer == NULL) {
-#if 0
-PORT1.3 
-      backBuffer = new Fl_Image ();
-#endif
+      backBuffer = new BackBuffer ();
    } else if (!b && backBuffer != NULL) {
       delete backBuffer;
       backBuffer = NULL;
@@ -181,12 +203,37 @@
                rect->height,
                X, Y, W, H);
 
-   fl_color(bgColor);
-   fl_rectf(X, Y, W, H);
-
    core::Rectangle r (translateViewXToCanvasX (X),
                       translateViewYToCanvasY (Y), W, H);
-   theLayout->expose (this, &r);
+
+   if (r.isEmpty ())
+      return;
+
+   if (type == DRAW_BUFFERED && backBuffer && !backBufferInUse) {
+      backBufferInUse = true;
+      backBuffer->setSize (X + W, Y + H); // would be nicer to use (W, H)...
+      fl_begin_offscreen (backBuffer->offscreen);
+      fl_push_matrix ();
+      fl_color (bgColor);
+      fl_rectf (X, Y, W, H);
+      theLayout->expose (this, &r);
+      fl_pop_matrix ();
+      fl_end_offscreen ();
+      fl_copy_offscreen (X, Y, W, H, backBuffer->offscreen, X, Y);
+      backBufferInUse = false;
+   } else if (type == DRAW_BUFFERED || type == DRAW_CLIPPED) {
+      // if type == DRAW_BUFFERED but we do not have backBuffer available
+      // we fall back to clipped drawing
+      fl_push_clip (X, Y, W, H);
+      fl_color (bgColor);
+      fl_rectf (X, Y, W, H);
+      theLayout->expose (this, &r);
+      fl_pop_clip ();
+   } else {
+      fl_color (bgColor);
+      fl_rectf (X, Y, W, H);
+      theLayout->expose (this, &r);
+   }
 }
 
 void FltkViewBase::drawChildWidgets () {
--- a/dw/fltkviewbase.hh	Wed Feb 09 01:31:14 2011 +0000
+++ b/dw/fltkviewbase.hh	Fri Feb 11 22:55:45 2011 +0100
@@ -5,7 +5,7 @@
 #include <sys/time.h>     // for time_t in FreeBSD
 
 #include <FL/Fl_Group.H>
-#include <FL/Fl_Image.H>
+#include <FL/x.H>
 #include <FL/Fl_Scrollbar.H>
 
 #include "fltkcore.hh"
@@ -16,12 +16,26 @@
 class FltkViewBase: public FltkView, public Fl_Group
 {
 private:
+   class BackBuffer {
+      private:
+         int w;
+         int h;
+         bool created;
+
+      public:
+         Fl_Offscreen offscreen;
+      
+         BackBuffer ();
+         ~BackBuffer ();
+         void setSize(int w, int h);
+   };
+
    typedef enum { DRAW_PLAIN, DRAW_CLIPPED, DRAW_BUFFERED } DrawType;
 
    int bgColor;
    core::Region drawRegion;
    //::fltk::Rectangle *exposeArea;
-   static Fl_Image *backBuffer;
+   static BackBuffer *backBuffer;
    static bool backBufferInUse;
 
    void draw (const core::Rectangle *rect, DrawType type);