|
commit 2f506407327762ce30b4d895c856baa7f681d9bc
Author: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
AuthorDate: Thu Nov 25 11:19:10 2021 +0100
Commit: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
CommitDate: Thu Nov 25 11:19:10 2021 +0100
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.
src/drivers/X11/Fl_X11_Screen_Driver.cxx | 12 ++++++++----
src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx | 16 +++++++++++-----
2 files changed, 19 insertions(+), 9 deletions(-)
diff --git src/drivers/X11/Fl_X11_Screen_Driver.cxx src/drivers/X11/Fl_X11_Screen_Driver.cxx
index 1dbd521..4fd36ed 100644
--- src/drivers/X11/Fl_X11_Screen_Driver.cxx
+++ src/drivers/X11/Fl_X11_Screen_Driver.cxx
@@ -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) ) {
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx
index 216f582..92ee525 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx
@@ -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.
[ Direct Link to Message ] | |