Fix fl_overlay_rect() under X11 and Windows when GUI is scaled.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12891 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Manolo Gouy 2018-05-03 08:37:58 +00:00
parent 5da16bbd36
commit bd4679f8d4
3 changed files with 29 additions and 13 deletions

View File

@ -206,8 +206,8 @@ void Fl_Graphics_Driver::cache_size(Fl_Image *img, int &width, int &height)
width = width * scale();
height = height * scale();
} else {
width = (width+1) * scale();
height = (height+1) * scale();
width = (width+1) * scale() - 1;
height = (height+1) * scale() - 1;
}
}

View File

@ -503,7 +503,15 @@ Fl_WinAPI_Screen_Driver::read_win_rectangle(
int h) // I - Height of area to read
{
float s = Fl_Surface_Device::surface()->driver()->scale();
return read_win_rectangle_unscaled(X*s, Y*s, w*s, h*s);
int ws, hs;
if (int(s) == s) { ws = w * s; hs = h * s;}
else {
ws = (w+1)*s-1;
hs = (h+1)*s-1;
if (ws < 1) ws = 1;
if (hs < 1) hs = 1;
}
return read_win_rectangle_unscaled(X*s, Y*s, ws, hs);
}
Fl_RGB_Image *Fl_WinAPI_Screen_Driver::read_win_rectangle_unscaled(int X, int Y, int w, int h)

View File

@ -786,10 +786,18 @@ Fl_RGB_Image *Fl_X11_Screen_Driver::read_win_rectangle(int X, int Y, int w, int
# endif // __sgi
float s = Fl_Surface_Device::surface()->driver()->scale();
int ws, hs;
if (int(s) == s) { ws = w * s; hs = h * s;}
else {
ws = (w+1)*s-1;
hs = (h+1)*s-1;
if (ws < 1) ws = 1;
if (hs < 1) hs = 1;
}
if (!image) {
// fetch absolute coordinates
int dx, dy, sx, sy, sw, sh;
int dx, dy, dxs, dys, sx, sy, sw, sh;
Window child_win;
Fl_Window *win;
@ -797,17 +805,17 @@ Fl_RGB_Image *Fl_X11_Screen_Driver::read_win_rectangle(int X, int Y, int w, int
else win = fl_find(fl_window);
if (win) {
XTranslateCoordinates(fl_display, fl_window,
RootWindow(fl_display, fl_screen), X*s, Y*s, &dx, &dy, &child_win);
dx /= s; dy /= s;
RootWindow(fl_display, fl_screen), X*s, Y*s, &dxs, &dys, &child_win);
dx = dxs/s; dy = dys/s;
// screen dimensions
Fl::screen_xywh(sx, sy, sw, sh, win->driver()->screen_num());
}
if (!win || (dx >= sx && dy >= sy && dx + w <= sx+sw && dy + h <= sy+sh)) {
if (!win || (dx >= sx && dy >= sy && dxs + ws <= (sx+sw)*s && dys + hs <= (sy+sh)*s) ) {
// the image is fully contained, we can use the traditional method
// however, if the window is obscured etc. the function will still fail. Make sure we
// catch the error and continue, otherwise an exception will be thrown.
XErrorHandler old_handler = XSetErrorHandler(xgetimageerrhandler);
image = XGetImage(fl_display, fl_window, int(X*s), int(Y*s), w*s < 1 ? 1 : int(w*s), h*s < 1 ? 1 : int(h*s), AllPlanes, ZPixmap);
image = XGetImage(fl_display, fl_window, int(X*s), int(Y*s), ws, hs, AllPlanes, ZPixmap);
XSetErrorHandler(old_handler);
} else {
// image is crossing borders, determine visible region
@ -818,9 +826,9 @@ Fl_RGB_Image *Fl_X11_Screen_Driver::read_win_rectangle(int X, int Y, int w, int
// allocate the image
int bpp = fl_visual->depth + ((fl_visual->depth / 8) % 2) * 8;
char* buf = (char*)malloc(bpp / 8 * int(w*s) * int(h*s));
char* buf = (char*)malloc((bpp / 8) * ws * hs);
image = XCreateImage(fl_display, fl_visual->visual,
fl_visual->depth, ZPixmap, 0, buf, w*s, h*s, bpp, 0);
fl_visual->depth, ZPixmap, 0, buf, ws, hs, bpp, 0);
if (!image) {
if (buf) free(buf);
return 0;
@ -839,8 +847,8 @@ Fl_RGB_Image *Fl_X11_Screen_Driver::read_win_rectangle(int X, int Y, int w, int
if (!image) return 0;
if (s != 1) {
w = w*s < 1 ? 1 : int(w*s);
h = h*s < 1 ? 1 : int(h*s);
w = ws;
h = hs;
}
#ifdef DEBUG