Alvin wrote:
Hello Albrecht and Ian,
Thanks for the tips. But I am still having some issues. Before I forget, I
am using FLTK 1.3.x r6786.
This is where what I have now:
[ code removed]
[ more problem descriptions removed ]
I took your last version and made it work as a complete program.
This is just a demonstration - no cleanup is done, which would
have to be done for production code.
IMHO your main problem is (was) that you didn't manage to get
all the x/y translations correct. The appended file does it
right, but I used some (other) dirty tricks to remove the
scrollbars, starting with your last version. The previous
version with the explicit loop would be easier and without
these dirty tricks ;-)
To the x/y translations: You must be aware that the offscreen works
like a full window, and that the child draw() methods add their
x/y coordinates to draw at the correct positions. However, the
scroll mechanism can add *negative* offsets to the widgets, so that
they are positioned more to the left and top. That's why I suggested
to resize() the Fl_Canvas to (0,0) temporary, and to set the scrollbars
to their initial position (0,0) as well.
Without this (see appended file), you need to create the offscreen image
as wide as Fl_Canvas' x() + your (correctly calculated) xdim, and the
hight must be calculated similarly:
// Determine the full (unscrolled) size of the canvas area
int xdim = x() + w();
int ydim = y() + h();
if(hscrollbar.visible())
xdim += (int)hscrollbar.maximum();
if(scrollbar.visible())
ydim += (int)scrollbar.maximum();
Then, when you read the image data, you can cut the desired portion
by using:
uchar *offscreenImage =
fl_read_image(0, x(), y(), xdim-x(), ydim-y());
thus reducing the image size again.
(Now think about, what would be, if x() and y() would be 0 :-) .
That's why I suggested the canvas resizing).
Now, try the compiled program with the scrollbars in their (0,0)
position and in different positions...
Albrecht
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <FL/Fl.H>
#include <FL/x.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Scroll.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_RGB_Image.H>
#include <FL/fl_draw.h>
class Fl_Canvas : public Fl_Scroll {
int xx_;
public:
Fl_Canvas(int X, int Y, int W, int H, const char *L=0);
Fl_RGB_Image *capture();
};
Fl_Canvas::Fl_Canvas (int X, int Y, int W, int H, const char *L) :
Fl_Scroll (X,Y,W,H,L)
{
xx_ = 0;
}
Fl_RGB_Image* Fl_Canvas::capture()
{
if(children() <= 2)
return NULL;
// Determine the full (unscrolled) size of the canvas area
int xdim = x() + w();
int ydim = y() + h();
if(hscrollbar.visible())
xdim += (int)hscrollbar.maximum();
if(scrollbar.visible())
ydim += (int)scrollbar.maximum();
window()->make_current();
// setup the offscreen buffer
Fl_Offscreen offscr = fl_create_offscreen(xdim, ydim);
// force children to draw into the offscreen buffer
fl_begin_offscreen(offscr);
fl_color(color());
fl_rectf(0,0,xdim,ydim); // draw background
// resize(x(),y(),w(),h()); // fix scrollbars
// scroll_to (0,0); // position children !
// hack: remove scrollbars temporarily
Fl_Scrollbar *hsb = &hscrollbar;
Fl_Scrollbar *vsb = &scrollbar;
remove(hsb); remove(vsb);
redraw(); // make it really draw something !
Fl_Group::draw_children(); // don't draw the box
// hack: add the scrollbars again
add(hsb); add(vsb);
// resize(x(),y(),w(),h()); // fix everything
// Annotate the image...write on the image
fl_rectf(x()+100, y()+100, 150, 100, FL_BLACK);
fl_color(FL_WHITE);
fl_font(FL_TIMES, 15);
fl_draw("Hello, World!", x()+125, y()+125);
uchar *offscreenImage =
fl_read_image(0, x(), y(), xdim-x(), ydim-y());
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, xdim-x(), ydim-y(),
3);
rgb_img->alloc_array = 1;
return rgb_img;
}
static Fl_Canvas *canvas = 0;
static void button_cb (Fl_Widget *, void *) {
Fl_RGB_Image *img = canvas->capture();
if (img && img->w()>0 && img->h()>0 && img->d()>0) {
Fl_Window *tw = new Fl_Window (img->w(),img->h(),"captured image");
Fl_Box *b = new Fl_Box(0,0,img->w(),img->h());
b->box(FL_FLAT_BOX);
b->image(img);
tw->end();
tw->show();
}
}
int main (int argc, char **argv)
{
Fl_Window *win = new Fl_Window (800,600,"capture test");
canvas = new Fl_Canvas (100,100,600,400);
canvas->box(FL_DOWN_BOX);
Fl_Box *box1 = new Fl_Box (100,100,100,100,"Box 1");
box1->color(FL_RED);
box1->box(FL_FLAT_BOX);
box1->align(FL_ALIGN_INSIDE|FL_ALIGN_CENTER);
Fl_Box *box2 = new Fl_Box (650,450,100,100,"Box 2");
box2->color(FL_YELLOW);
box2->box(FL_FLAT_BOX);
box2->align(FL_ALIGN_INSIDE|FL_ALIGN_CENTER);
canvas->end();
Fl_Button *button = new Fl_Button (20,520,60,30,"capture");
button->callback(button_cb);
win->end();
win->show(argc,argv);
return Fl::run();
}
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk