summaryrefslogtreecommitdiff
path: root/src/Fl_Screen_Driver.cxx
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2018-02-09 13:48:22 +0000
committerManolo Gouy <Manolo>2018-02-09 13:48:22 +0000
commitc472d5d8b76e17e4dd537ca20c9bfb144b06189c (patch)
treefbe64110002b5d36127631c37cc5d1bb44f86318 /src/Fl_Screen_Driver.cxx
parentb78b2f7f5f24b98640d31bb8ee7b573703e8cc19 (diff)
Fix fl_read_image() under MacOS platform when GUI is rescaled.
This commit also simplifies the platform-dependent support of fl_read_image(): only Fl_XXX_Screen_Driver::read_win_rectangle() contains platform-specific code to capture pixels from the current window or from an offscreen buffer. Platform-independent function Fl_Screen_Driver::traverse_to_gl_subwindows() captures subwindows that intersect with the area fl_read_image() targets. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12653 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Screen_Driver.cxx')
-rw-r--r--src/Fl_Screen_Driver.cxx57
1 files changed, 10 insertions, 47 deletions
diff --git a/src/Fl_Screen_Driver.cxx b/src/Fl_Screen_Driver.cxx
index b10aa13ac..2dffcd7a5 100644
--- a/src/Fl_Screen_Driver.cxx
+++ b/src/Fl_Screen_Driver.cxx
@@ -141,45 +141,22 @@ void Fl_Screen_Driver::compose_reset() {
Fl::compose_state = 0;
}
-uchar *Fl_Screen_Driver::read_image(uchar *p, int X, int Y, int w, int h, int alpha) {
- uchar *image_data = NULL;
- Fl_RGB_Image *img;
- if (fl_find(fl_window) == 0) { // read from off_screen buffer
- img = read_win_rectangle(p, X, Y, w, h, alpha);
- if (!img) {
- return NULL;
- }
- img->alloc_array = 1;
- } else {
- img = traverse_to_gl_subwindows(Fl_Window::current(), p, X, Y, w, h, alpha, NULL);
- }
- if (img) {
- if (img->w() != w) {
- Fl_RGB_Image *img2 = (Fl_RGB_Image*)img->copy(w, h);
- delete img;
- img = img2;
- }
- img->alloc_array = 0;
- image_data = (uchar*)img->array;
- delete img;
- }
- return image_data;
-}
-
void Fl_Screen_Driver::write_image_inside(Fl_RGB_Image *to, Fl_RGB_Image *from, int to_x, int to_y)
/* Copy the image "from" inside image "to" with its top-left angle at coordinates to_x, to_y.
-Image depth can differ between "to" and "from".
+Image depths can differ between "to" and "from".
*/
{
int to_ld = (to->ld() == 0? to->w() * to->d() : to->ld());
int from_ld = (from->ld() == 0? from->w() * from->d() : from->ld());
uchar *tobytes = (uchar*)to->array + to_y * to_ld + to_x * to->d();
const uchar *frombytes = from->array;
+ int need_alpha = (from->d() == 3 && to->d() == 4);
for (int i = 0; i < from->h(); i++) {
if (from->d() == to->d()) memcpy(tobytes, frombytes, from->w() * from->d());
else {
for (int j = 0; j < from->w(); j++) {
memcpy(tobytes + j * to->d(), frombytes + j * from->d(), from->d());
+ if (need_alpha) *(tobytes + j * to->d() + 3) = 0xff;
}
}
tobytes += to_ld;
@@ -193,45 +170,31 @@ Image depth can differ between "to" and "from".
Arguments when this function is initially called:
g: a window or GL window
- p: as in fl_read_image()
x,y,w,h: a rectangle in window g's coordinates
- alpha: as in fl_read_image()
full_img: NULL
Arguments when this function recursively calls itself:
g: an Fl_Group
- p: as above
x,y,w,h: a rectangle in g's coordinates if g is a window, or in g's parent window coords if g is a group
- alpha: as above
full_img: NULL, or a previously captured image that encompasses the x,y,w,h rectangle and that
will be partially overwritten with the new capture
Return value:
- An Fl_RGB_Image* of depth 4 if alpha>0 or 3 if alpha = 0 containing the captured pixels.
+ An Fl_RGB_Image*, the depth of which is platform-dependent, containing the captured pixels.
*/
-Fl_RGB_Image *Fl_Screen_Driver::traverse_to_gl_subwindows(Fl_Group *g, uchar *p, int x, int y, int w, int h, int alpha,
+Fl_RGB_Image *Fl_Screen_Driver::traverse_to_gl_subwindows(Fl_Group *g, int x, int y, int w, int h,
Fl_RGB_Image *full_img)
{
if ( g->as_gl_window() ) {
Fl_Plugin_Manager pm("fltk:device");
Fl_Device_Plugin *pi = (Fl_Device_Plugin*)pm.plugin("opengl.device.fltk.org");
if (!pi) return full_img;
- Fl_RGB_Image *img = pi->rectangle_capture(g, x, y, w, h);
- if (full_img) full_img = img;
- else {
- uchar *data = ( p ? p : new uchar[img->w() * img->h() * (alpha?4:3)] );
- full_img = new Fl_RGB_Image(data, img->w(), img->h(), alpha?4:3);
- if (!p) full_img->alloc_array = 1;
- if (alpha) memset(data, alpha, img->w() * img->h() * 4);
- write_image_inside(full_img, img, 0, 0);
- delete img;
- }
+ full_img = pi->rectangle_capture(g, x, y, w, h);
}
else if ( g->as_window() && (!full_img || (g->window() && g->window()->as_gl_window())) ) {
// the starting window or one inside a GL window
if (full_img) g->as_window()->make_current();
- int alloc_img = (full_img != NULL || p == NULL); // false means use p, don't alloc new memory for image
- full_img = Fl::screen_driver()->read_win_rectangle( (alloc_img ? NULL : p), x, y, w, h, alpha);
+ full_img = Fl::screen_driver()->read_win_rectangle(x, y, w, h);
}
int n = g->children();
for (int i = 0; i < n; i++) {
@@ -249,8 +212,8 @@ Fl_RGB_Image *Fl_Screen_Driver::traverse_to_gl_subwindows(Fl_Group *g, uchar *p,
if (origin_y + height > c->y() + c->h()) height = c->y() + c->h() - origin_y;
if (origin_y + height > y + h) height = y + h - origin_y;
if (width > 0 && height > 0) {
- Fl_RGB_Image *img = traverse_to_gl_subwindows(c->as_window(), p, origin_x - c->x(),
- origin_y - c->y(), width, height, alpha, full_img);
+ Fl_RGB_Image *img = traverse_to_gl_subwindows(c->as_window(), origin_x - c->x(),
+ origin_y - c->y(), width, height, full_img);
if (img == full_img) continue;
int top;
if (c->as_gl_window()) {
@@ -264,7 +227,7 @@ Fl_RGB_Image *Fl_Screen_Driver::traverse_to_gl_subwindows(Fl_Group *g, uchar *p,
delete img;
}
}
- else traverse_to_gl_subwindows(c->as_group(), p, x, y, w, h, alpha, full_img);
+ else traverse_to_gl_subwindows(c->as_group(), x, y, w, h, full_img);
}
return full_img;
}