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