X11+XRender platform: more accurate drawing of RGB images when GUI is scaled.
RGB images are now drawn to a size that exactly fit discretised rectangles when non integral GUI scaling values are used.
This commit is contained in:
parent
bf470919f7
commit
2f50640732
@ -774,8 +774,10 @@ Fl_RGB_Image *Fl_X11_Screen_Driver::read_win_rectangle(int X, int Y, int w, int
|
||||
Window xid = (win && !allow_outside ? fl_xid(win) : fl_window);
|
||||
|
||||
float s = allow_outside ? Fl::screen_driver()->scale(win->screen_num()) : Fl_Surface_Device::surface()->driver()->scale();
|
||||
int Xs = Fl_Scalable_Graphics_Driver::floor(X, s), Ys = Fl_Scalable_Graphics_Driver::floor(Y, s),
|
||||
ws = Fl_Scalable_Graphics_Driver::floor(X+w, s) - Xs, hs = Fl_Scalable_Graphics_Driver::floor(Y+h, s) - Ys;
|
||||
int Xs = Fl_Scalable_Graphics_Driver::floor(X, s);
|
||||
int Ys = Fl_Scalable_Graphics_Driver::floor(Y, s);
|
||||
int ws = Fl_Scalable_Graphics_Driver::floor(X+w, s) - Xs;
|
||||
int hs = Fl_Scalable_Graphics_Driver::floor(Y+h, s) - Ys;
|
||||
|
||||
# ifdef __sgi
|
||||
if (XReadDisplayQueryExtension(fl_display, &i, &i)) {
|
||||
@ -800,12 +802,14 @@ Fl_RGB_Image *Fl_X11_Screen_Driver::read_win_rectangle(int X, int Y, int w, int
|
||||
sw = screens[ns].width;
|
||||
sh = screens[ns].height;
|
||||
}
|
||||
#if ! HAVE_XRENDER
|
||||
if (win && !allow_outside && int(s) != s) {
|
||||
ws = (w+1) * s; // approximates what Fl_Graphics_Driver::cache_size() does
|
||||
hs = (h+1) * s;
|
||||
if (Xs + ws >= int(win->w()*s)) ws = win->w()*s - Xs -1;
|
||||
if (Ys + hs >= int(win->h()*s)) hs = win->h()*s - Ys -1;
|
||||
}
|
||||
#endif
|
||||
if (win && Xs + ws >= int(win->w()*s)) ws = win->w()*s - Xs -1;
|
||||
if (win && Ys + hs >= int(win->h()*s)) hs = win->h()*s - Ys -1;
|
||||
if (ws < 1) ws = 1;
|
||||
if (hs < 1) hs = 1;
|
||||
if (!win || (dx >= sx && dy >= sy && dx + ws <= sx+sw && dy + hs <= sy+sh) ) {
|
||||
|
||||
@ -772,9 +772,15 @@ void Fl_Xlib_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP
|
||||
if (!*Fl_Graphics_Driver::id(rgb)) {
|
||||
cache(rgb);
|
||||
}
|
||||
push_clip(XP, YP, WP, HP);
|
||||
int Wfull = rgb->w(), Hfull = rgb->h(), offset = 0;
|
||||
cache_size(rgb, Wfull, Hfull);
|
||||
float s = scale();
|
||||
int Xs = Fl_Scalable_Graphics_Driver::floor(XP - cx, s);
|
||||
int Wfull = Fl_Scalable_Graphics_Driver::floor(XP - cx + rgb->w(), s) - Xs ;
|
||||
int Ys = Fl_Scalable_Graphics_Driver::floor(YP - cy, s);
|
||||
int Hfull = Fl_Scalable_Graphics_Driver::floor(YP - cy + rgb->h(), s) - Ys;
|
||||
if (Wfull == 0 || Hfull == 0) return;
|
||||
bool need_clip = (cx || cy || WP < rgb->w() || HP < rgb->h());
|
||||
if (need_clip) push_clip(XP, YP, WP, HP);
|
||||
int offset = 0;
|
||||
if (Wfull > rgb->data_w() || Hfull > rgb->data_h()) {
|
||||
// When enlarging while drawing with XRender, 1 pixel around target area seems unpainted,
|
||||
// so we increase a bit the target area and move it 1 pixel to left and top.
|
||||
@ -783,9 +789,9 @@ void Fl_Xlib_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP
|
||||
}
|
||||
scale_and_render_pixmap( *Fl_Graphics_Driver::id(rgb), rgb->d(),
|
||||
rgb->data_w() / double(Wfull), rgb->data_h() / double(Hfull),
|
||||
floor(XP-cx) + floor(offset_x_) - offset, floor(YP-cy) + floor(offset_y_) - offset,
|
||||
Xs + this->floor(offset_x_) - offset, Ys + this->floor(offset_y_) - offset,
|
||||
Wfull, Hfull);
|
||||
pop_clip();
|
||||
if (need_clip) pop_clip();
|
||||
}
|
||||
|
||||
/* Draws with Xrender an Fl_Offscreen with optional scaling and accounting for transparency if necessary.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user