Alvin wrote:

> Hello all,
> 
> Anyone know how to draw the widgets contained in a Fl_Scroll into an image
> file? [snipped]

Thank you Albrecht and Ian for the pointers. I managed to implement 
something that seems to work.

I have pasted my working implementation at the end of this message.

Note that children_bbox() is not a Fl_Scroll function but one I added to my 
Fl_Canvas class that calculates the bounding box around the children. This 
way I can determine the size of the image when the widgets do not fully 
overlap.

Concerning fl_read_image() in my last post, I had a typo. The first argument 
was the name of the variable I was using to capture the return buffer. 
However, as expected, the variable was not 0'd (it had garbage in it).

E.G.
   uchar *offscreenImage = fl_read_image(offscreenImage, 0, 0, ww, hh, 0);

   the "offscreenImage" as the first arg is wrong. I needed to do:

   uchar *offscreenImage = fl_read_image(NULL, 0, 0, ww, hh, 0);

The other trick I figured out is that, in my situation, the children needed 
to be moved to (0,0) otherwise they drew themselves at their offset within 
the canvas. My moving to (0,0) they draw at the original of the offscreen 
buffer.

Fl_RGB_Image* Fl_Canvas::capture()
{
   if(children() <= 2)
      return NULL;

   // Determine the bounding box around all the children. We only
   // use ww and hh as it gives us the rectangle around all the children.
   // Note that xx yy is just where the bounding box is in space.
   int xx, yy, ww, hh;
   children_bbox(xx, yy, ww, hh);

   // This needs to be called. It sets up the low-level display stuff
   window()->make_current();

   // setup the offscreen and RGB buffers
   Fl_Offscreen offscr   = fl_create_offscreen(ww, hh);
   uchar *offscreenImage = NULL;

   // force children to draw into the offscreen buffer
   fl_begin_offscreen(offscr);
   {
      Fl_Widget *o = NULL;
      int ox = 0;
      int oy = 0;
      for(int i = 0; i < children(); i++)
      {
         o = child(i);

         // force widget to draw if its not a Fl_Scroll's scrollbar and the
         // widget is visible
         if((o != &hscrollbar) && (o != &scrollbar) && o->visible())
         {
            // Move widget so it's not relative to canvas. Place it at (0,0)
            // in offscreen buffer
            ox = o->x();
            oy = o->y();
            o->position(0,0);

            o->redraw();
            o->draw();

            // restore widgets position
            o->position(ox, oy);
         }
      }

      // Annotate the image with some text.
      fl_font(FL_TIMES_BOLD, 45);

      int tw = 0, th = 0;
      fl_measure("Hello, World!", tw, th, 1);
      fl_rectf((ww-tw)/2, (hh-th)/2, tw+20, th+20, FL_BLUE);

      fl_color(FL_RED);
      fl_draw("Hello, World!", (ww-tw)/2 + 10, (hh-th)/2 + th);

      // copy the offscreen buff to our image buffer
      offscreenImage = fl_read_image(NULL, 0, 0, ww, hh, 0);
   }
   fl_end_offscreen();

   // Pack a Fl_RGB_Image and force its dtor to do the cleanup
   Fl_RGB_Image *rgb_img = new Fl_RGB_Image(offscreenImage, ww, hh, 3);
   rgb_img->alloc_array = 1;

   return rgb_img;
}

_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to