FLTK logo

[master] 2f50640 - X11+XRender platform: more accurate drawing of RGB images when GUI is scaled.

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[master] 2f50640 - X11+XRender platform: more accurate drawing of RGB images when GUI is scaled. "ManoloFLTK" Nov 25, 2021  
 
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 ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.