FLTK logo

[master] 569fec2 - Unification of scaled coordinate calculations in class Fl_Scalable_Graphics_Driver

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] 569fec2 - Unification of scaled coordinate calculations in class Fl_Scalable_Graphics_Driver "ManoloFLTK" Mar 11, 2021  
 
commit 569fec25e0454c4e4b98dcc383143a357ca50b55
Author:     ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
AuthorDate: Thu Mar 11 16:05:20 2021 +0100
Commit:     ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
CommitDate: Thu Mar 11 16:05:32 2021 +0100

    Unification of scaled coordinate calculations in class Fl_Scalable_Graphics_Driver
    
    Most coordinate calculations are done with the new inline function
     int Fl_Scalable_Graphics_Driver::floor(int coord)
    that is used by both the Windows and X11 platforms.

 FL/Fl_Graphics_Driver.H                            |  38 ++---
 src/Fl_Graphics_Driver.cxx                         | 178 +++++++++++----------
 src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx     |   2 +-
 src/drivers/GDI/Fl_GDI_Graphics_Driver.H           |  41 ++---
 src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx         |   8 +-
 src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx    |   7 +-
 .../GDI/Fl_GDI_Graphics_Driver_line_style.cxx      |   7 +-
 src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx    | 145 +++++------------
 src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx     |   6 +-
 src/drivers/X11/Fl_X11_Screen_Driver.cxx           |   3 +-
 src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H         |  31 ++--
 src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx       |  27 +---
 src/drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx  |  19 ++-
 .../Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx      |  20 +--
 src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx |  23 +--
 .../Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx    |  18 ++-
 src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx  | 141 ++++++----------
 .../Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx        |   4 +-
 18 files changed, 315 insertions(+), 403 deletions(-)

diff --git FL/Fl_Graphics_Driver.H FL/Fl_Graphics_Driver.H
index 845b416..974f1be 100644
--- FL/Fl_Graphics_Driver.H
+++ FL/Fl_Graphics_Driver.H
@@ -419,6 +419,11 @@ struct Fl_Fontdesc {
 class FL_EXPORT Fl_Scalable_Graphics_Driver : public Fl_Graphics_Driver {
 public:
   Fl_Scalable_Graphics_Driver();
+  // This function aims to compute accurately int(x * s) in
+  // presence of rounding errors existing with floating point numbers
+  // and that sometimes differ between 32 and 64 bits.
+  static inline int floor(int x, float s) { return int(x * s + 0.001f); }
+  inline int floor(int x) { return Fl_Scalable_Graphics_Driver::floor(x, scale()); }
 protected:
   int line_width_;
   virtual Fl_Region scale_clip(float f);
@@ -426,29 +431,24 @@ protected:
   virtual void point(int x, int y);
   virtual void point_unscaled(float x, float y);
   virtual void rect(int x, int y, int w, int h);
-  virtual void rect_unscaled(float x, float y, float w, float h);
   virtual void rectf(int x, int y, int w, int h);
-  virtual void rectf_unscaled(float x, float y, float w, float h);
+  virtual void rectf_unscaled(int x, int y, int w, int h);
   virtual void line(int x, int y, int x1, int y1);
-  virtual void line_unscaled(float x, float y, float x1, float y1);
+  virtual void line_unscaled(int x, int y, int x1, int y1);
   virtual void line(int x, int y, int x1, int y1, int x2, int y2);
-  virtual void line_unscaled(float x, float y, float x1, float y1, float x2, float y2);
+  virtual void line_unscaled(int x, int y, int x1, int y1, int x2, int y2);
   virtual void xyline(int x, int y, int x1);
-  virtual void xyline(int x, int y, int x1, int y2);
-  virtual void xyline(int x, int y, int x1, int y2, int x3);
-  virtual void xyline_unscaled(float x, float y, float x1);
+  virtual void xyline_unscaled(int x, int y, int x1);
   virtual void yxline(int x, int y, int y1);
-  virtual void yxline(int x, int y, int y1, int x2);
-  virtual void yxline(int x, int y, int y1, int x2, int y3);
-  virtual void yxline_unscaled(float x, float y, float y1);
+  virtual void yxline_unscaled(int x, int y, int y1);
   virtual void loop(int x0, int y0, int x1, int y1, int x2, int y2);
-  virtual void loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2);
+  virtual void loop_unscaled(int x0, int y0, int x1, int y1, int x2, int y2);
   virtual void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
-  virtual void loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
+  virtual void loop_unscaled(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
   virtual void polygon(int x0, int y0, int x1, int y1, int x2, int y2);
-  virtual void polygon_unscaled(float x0, float y0, float x1, float y1, float x2, float y2);
+  virtual void polygon_unscaled(int x0, int y0, int x1, int y1, int x2, int y2);
   virtual void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
-  virtual void polygon_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
+  virtual void polygon_unscaled(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
   virtual void circle(double x, double y, double r);
   virtual void ellipse_unscaled(double xt, double yt, double rx, double ry);
   virtual void font(Fl_Font face, Fl_Fontsize size);
@@ -475,12 +475,12 @@ protected:
   virtual void rtl_draw_unscaled(const char* str, int n, int x, int y);
   virtual void arc(double x, double y, double r, double start, double end);
   virtual void arc(int x, int y, int w, int h, double a1, double a2);
-  virtual void arc_unscaled(float x, float y, float w, float h, double a1, double a2);
+  virtual void arc_unscaled(int x, int y, int w, int h, double a1, double a2);
   virtual void pie(int x, int y, int w, int h, double a1, double a2);
-  virtual void pie_unscaled(float x, float y, float w, float h, double a1, double a2);
+  virtual void pie_unscaled(int x, int y, int w, int h, double a1, double a2);
   virtual void line_style(int style, int width=0, char* dashes=0);
-  virtual void line_style_unscaled(int style, float width, char* dashes);
-  void draw_image_rescale(void *buf, Fl_Draw_Image_Cb cb, int X, int Y, int W, int H, int D, int L, bool mono, float s);
+  virtual void line_style_unscaled(int style, int width, char* dashes);
+  void draw_image_rescale(void *buf, Fl_Draw_Image_Cb cb, int X, int Y, int W, int H, int D, int L, bool mono);
   virtual void draw_image_unscaled(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0);
   virtual void draw_image_unscaled(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3);
   void draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0);
@@ -494,6 +494,8 @@ protected:
   void vertex(double x, double y);
   virtual float override_scale();
   virtual void restore_scale(float);
+  virtual void *change_pen_width(int lwidth);
+  virtual void reset_pen_width(void *data);
 };
 #endif // FL_DOXYGEN
 
diff --git src/Fl_Graphics_Driver.cxx src/Fl_Graphics_Driver.cxx
index f1164c1..5386d52 100644
--- src/Fl_Graphics_Driver.cxx
+++ src/Fl_Graphics_Driver.cxx
@@ -345,14 +345,14 @@ void Fl_Graphics_Driver::xyline(int x, int y, int x1) {
 }
 
 void Fl_Graphics_Driver::xyline(int x, int y, int x1, int y2) {
-  line(x, y, x1, y);
-  line(x1, y, x1, y2);
+  xyline(x, y, x1);
+  yxline(x1, y, y2);
 }
 
 void Fl_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) {
-  line(x, y, x1, y);
-  line(x1, y, x1, y2);
-  line(x1, y2, x3, y2);
+  xyline(x, y, x1);
+  yxline(x1, y, y2);
+  xyline(x1, y2, x3);
 }
 
 void Fl_Graphics_Driver::yxline(int x, int y, int y1) {
@@ -360,14 +360,14 @@ void Fl_Graphics_Driver::yxline(int x, int y, int y1) {
 }
 
 void Fl_Graphics_Driver::yxline(int x, int y, int y1, int x2) {
-  line(x, y, x, y1);
-  line(x, y1, x2, y1);
+  yxline(x, y, y1);
+  xyline(x, y1, x2);
 }
 
 void Fl_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) {
-  line(x, y, x, y1);
-  line(x, y1, x2, y1);
-  line(x2, y1, x2, y3);
+  yxline(x, y, y1);
+  xyline(x, y1, x2);
+  yxline(x2, y1, y3);
 }
 
 void Fl_Graphics_Driver::line(int x, int y, int x1, int y1, int x2, int y2) {
@@ -692,72 +692,79 @@ Fl_Scalable_Graphics_Driver::Fl_Scalable_Graphics_Driver() : Fl_Graphics_Driver(
 
 void Fl_Scalable_Graphics_Driver::rect(int x, int y, int w, int h)
 {
-  if (int(scale()) == scale()) {
-    rect_unscaled(x * scale(), y * scale(), w * scale(), h * scale());
-  } else {
-    if (w > 0 && h > 0) {
-      xyline(x, y, x+w-1);
-      yxline(x, y, y+h-1);
-      yxline(x+w-1, y, y+h-1);
-      xyline(x, y+h-1, x+w-1);
-    }
+  if (w > 0 && h > 0) {
+    xyline(x, y, x+w-1);
+    yxline(x, y, y+h-1);
+    yxline(x+w-1, y, y+h-1);
+    xyline(x, y+h-1, x+w-1);
   }
 }
 
 void Fl_Scalable_Graphics_Driver::rectf(int x, int y, int w, int h)
 {
-  rectf_unscaled(x * scale(), y * scale(), w * scale(), h * scale());
+  if (w <= 0 || h <= 0) return;
+  rectf_unscaled(this->floor(x), this->floor(y),
+                 this->floor(x + w) - this->floor(x), this->floor(y + h) - this->floor(y));
 }
 
 void Fl_Scalable_Graphics_Driver::point(int x, int y) {
-  point_unscaled(x * scale(), y * scale());
+  rectf(x, y, 1, 1);
 }
 
 void Fl_Scalable_Graphics_Driver::line(int x, int y, int x1, int y1) {
   if (y == y1) xyline(x, y, x1);
   else if (x == x1) yxline(x, y, y1);
-  else line_unscaled( x*scale(), y*scale(), x1*scale(), y1*scale());
+  else line_unscaled(this->floor(x), this->floor(y), this->floor(x1), this->floor(y1));
 }
 
 void Fl_Scalable_Graphics_Driver::line(int x, int y, int x1, int y1, int x2, int y2) {
-  if ( (y == y1 || x == x1) && (y2 == y1 || x2 == x1) ) { // only horizontal or vertical lines
-    line(x, y, x1, y1);
-    line(x1, y1, x2, y2);
-  } else line_unscaled( x*scale(), y*scale(), x1*scale(), y1*scale(), x2*scale(), y2*scale());
+  line_unscaled(this->floor(x), this->floor(y), this->floor(x1), this->floor(y1), this->floor(x2), this->floor(y2));
 }
 
 void Fl_Scalable_Graphics_Driver::xyline(int x, int y, int x1) {
-  xyline_unscaled(x*scale(), y*scale(), x1*scale());
-}
-
-void Fl_Scalable_Graphics_Driver::xyline(int x, int y, int x1, int y2) {
-  xyline(x, y, x1);
-  yxline(x1, y, y2);
-}
-
-void Fl_Scalable_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) {
-  xyline(x, y, x1);
-  yxline(x1, y, y2);
-  xyline(x1, y2, x3);
+  if (y < 0) return;
+  float s = scale(); int s_int = int(s);
+  int xx = (x < x1 ? x : x1);
+  int xx1 = (x < x1 ? x1 : x);
+  if (s != s_int && line_width_ <= s_int) {
+    int lwidth = this->floor((y+1)) - this->floor(y);
+    bool need_change_width = (lwidth != s_int);
+    void *data = NULL;
+    if (need_change_width) data = change_pen_width(lwidth);
+    xyline_unscaled(this->floor(xx), this->floor(y) + int(lwidth/2.f), this->floor(xx1+1)-1);
+    if (need_change_width) reset_pen_width(data);
+  } else {
+    y = this->floor(y);
+    if (line_width_ <= s_int) y += int(s/2.f);
+    xyline_unscaled(this->floor(xx), y, this->floor(xx1+1) - 1);
+  }
 }
 
 void Fl_Scalable_Graphics_Driver::yxline(int x, int y, int y1) {
-  yxline_unscaled(x*scale(), y*scale(), y1*scale());
+  if (x < 0) return;
+  float s = scale();  int s_int = int(s);
+  int yy = (y < y1 ? y : y1);
+  int yy1 = (y < y1 ? y1 : y);
+  if (s != s_int && line_width_ <= s_int) {
+    int lwidth = (this->floor((x+1)) - this->floor(x));
+    bool need_change_width = (lwidth != s_int);
+    void *data = NULL;
+    if (need_change_width) data = change_pen_width(lwidth);
+    yxline_unscaled(this->floor(x) + int(lwidth/2.f), this->floor(yy), this->floor(yy1+1) - 1);
+    if (need_change_width) reset_pen_width(data);
+  } else {
+    x = this->floor(x);
+    if (line_width_ <= s_int) x += int(s/2.f);
+    yxline_unscaled(x, this->floor(yy), this->floor(yy1+1) - 1);
+  }
 }
 
-void Fl_Scalable_Graphics_Driver::yxline(int x, int y, int y1, int x2) {
-  yxline(x, y, y1);
-  xyline(x, y1, x2);
-}
+void *Fl_Scalable_Graphics_Driver::change_pen_width(int lwidth) {return NULL;}
 
-void Fl_Scalable_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) {
-  yxline(x, y, y1);
-  xyline(x, y1, x2);
-  yxline(x2, y1, y3);
-}
+void Fl_Scalable_Graphics_Driver::reset_pen_width(void *data){}
 
 void Fl_Scalable_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2) {
-  loop_unscaled(x0*scale(), y0*scale(), x1*scale(), y1*scale(), x2*scale(), y2*scale());
+  loop_unscaled(floor(x0), floor(y0), floor(x1), floor(y1), floor(x2), floor(y2));
 }
 
 void Fl_Scalable_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
@@ -775,17 +782,16 @@ void Fl_Scalable_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, i
     H = abs(y0 - y1);
     rect(X, Y, W + 1, H + 1);
   } else {
-    float s = scale();
-    loop_unscaled(x0*s, y0*s, x1*s, y1*s, x2*s, y2*s, x3*s, y3*s);
+    loop_unscaled(floor(x0), floor(y0), floor(x1), floor(y1), floor(x2), floor(y2), floor(x3), floor(y3));
   }
 }
 
 void Fl_Scalable_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2) {
-  polygon_unscaled(x0*scale(), y0*scale(), x1*scale(), y1*scale(), x2*scale(), y2*scale());
+  polygon_unscaled(floor(x0), floor(y0), floor(x1), floor(y1), floor(x2), floor(y2));
 }
 
 void Fl_Scalable_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
-  polygon_unscaled(x0*scale(), y0*scale(), x1*scale(), y1*scale(), x2*scale(), y2*scale(), x3*scale(), y3*scale());
+  polygon_unscaled(floor(x0), floor(y0), floor(x1), floor(y1), floor(x2), floor(y2), floor(x3), floor(y3));
 }
 
 void Fl_Scalable_Graphics_Driver::circle(double x, double y, double r) {
@@ -837,7 +843,7 @@ int Fl_Scalable_Graphics_Driver::descent() {
 void Fl_Scalable_Graphics_Driver::draw(const char *str, int n, int x, int y) {
   if (!size_ || !font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE);
   Fl_Region r2 = scale_clip(scale());
-  draw_unscaled(str, n, int(x*scale()), int(y*scale()));
+  draw_unscaled(str, n, floor(x), floor(y));
   unscale_clip(r2);
 }
 
@@ -848,7 +854,7 @@ void Fl_Scalable_Graphics_Driver::draw(const char *str, int n, float x, float y)
 void Fl_Scalable_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) {
   if (!size_ || !font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE);
   Fl_Region r2 = scale_clip(scale());
-  draw_unscaled(angle, str, n, int(x*scale()), int(y*scale()));
+  draw_unscaled(angle, str, n, floor(x), floor(y));
   unscale_clip(r2);
 }
 
@@ -856,8 +862,13 @@ void Fl_Scalable_Graphics_Driver::rtl_draw(const char* str, int n, int x, int y)
   rtl_draw_unscaled(str, n, int(x * scale()), int(y * scale()));
 }
 
-void Fl_Scalable_Graphics_Driver::arc(int x,int y,int w,int h,double a1,double a2) {
-  arc_unscaled(x * scale(), y * scale(), w * scale(), h * scale(), a1, a2);
+void Fl_Scalable_Graphics_Driver::arc(int x, int y, int w, int h, double a1, double a2) {
+  float s = scale();
+  int xx = floor(x) + int((s-1)/2);
+  int yy = floor(y) + int((s-1)/2);
+  w = floor(x+w) - xx - 1 + line_width_/2 - int(s-1);
+  h = floor(y+h) - yy - 1 + line_width_/2 - int(s-1);
+  arc_unscaled(xx, yy, w, h, a1, a2);
 }
 
 void Fl_Scalable_Graphics_Driver::arc(double x, double y, double r, double start, double end) {
@@ -865,18 +876,22 @@ void Fl_Scalable_Graphics_Driver::arc(double x, double y, double r, double start
 }
 
 void Fl_Scalable_Graphics_Driver::pie(int x,int y,int w,int h,double a1,double a2) {
-  pie_unscaled(x * scale(), y * scale(), w * scale(), h * scale(), a1, a2);
+  int xx = floor(x) - 1;
+  int yy = floor(y) - 1;
+  w = floor(x+w) - xx;
+  h = floor(y+h) - yy;
+  pie_unscaled(xx, yy, w, h, a1, a2);
 }
 
 void Fl_Scalable_Graphics_Driver::line_style(int style, int width, char* dashes) {
   if (width == 0) line_width_ = int(scale() < 2 ? 0 : scale());
   else line_width_ = int(width>0 ? width*scale() : -width*scale());
-  line_style_unscaled(style, float(line_width_), dashes);
+  line_style_unscaled(style, line_width_, dashes);
 }
 
 /* read the image data from a pointer or with a callback, scale it, and draw it */
 void Fl_Scalable_Graphics_Driver::draw_image_rescale(void *buf, Fl_Draw_Image_Cb cb,
-                                                     int X, int Y, int W, int H, int D, int L, bool mono, float s) {
+                                                     int X, int Y, int W, int H, int D, int L, bool mono) {
   int aD = abs(D);
   if (L == 0) L = W*aD;
   int depth = mono ? (aD%2==0?2:1) : aD;
@@ -899,12 +914,12 @@ void Fl_Scalable_Graphics_Driver::draw_image_rescale(void *buf, Fl_Draw_Image_Cb
   rgb->alloc_array = 1;
   Fl_RGB_Scaling keep = Fl_Image::RGB_scaling();
   Fl_Image::RGB_scaling(Fl_Image::scaling_algorithm());
-  Fl_RGB_Image *scaled_rgb = (Fl_RGB_Image*)rgb->copy(int(ceil(W * s)), int(ceil(H * s)));
+  Fl_RGB_Image *scaled_rgb = (Fl_RGB_Image*)rgb->copy(floor(X+W)-floor(X), floor(Y+H)-floor(Y));
   Fl_Image::RGB_scaling(keep);
   delete rgb;
   if (scaled_rgb) {
-    Fl_Region r2 = scale_clip(s);
-    draw_image_unscaled(scaled_rgb->array, int(X * s), int(Y * s), scaled_rgb->w(), scaled_rgb->h(), depth);
+    Fl_Region r2 = scale_clip(scale());
+    draw_image_unscaled(scaled_rgb->array, floor(X), floor(Y), scaled_rgb->w(), scaled_rgb->h(), depth);
     unscale_clip(r2);
     delete scaled_rgb;
   }
@@ -914,7 +929,7 @@ void Fl_Scalable_Graphics_Driver::draw_image(const uchar* buf, int X,int Y,int W
   if (scale() == 1) {
     draw_image_unscaled(buf, X,Y,W,H,D,L);
   } else {
-    draw_image_rescale((void*)buf, NULL, X, Y, W, H, D, L, false, scale());
+    draw_image_rescale((void*)buf, NULL, X, Y, W, H, D, L, false);
   }
 }
 
@@ -922,7 +937,7 @@ void Fl_Scalable_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data, in
   if (scale() == 1) {
     draw_image_unscaled(cb, data, X,Y,W,H,D);
   } else {
-    draw_image_rescale(data, cb, X, Y, W, H, D, 0, false, scale());
+    draw_image_rescale(data, cb, X, Y, W, H, D, 0, false);
   }
 }
 
@@ -930,7 +945,7 @@ void Fl_Scalable_Graphics_Driver::draw_image_mono(const uchar* buf, int X,int Y,
   if (scale() == 1) {
     draw_image_mono_unscaled(buf, X,Y,W,H,D,L);
   } else {
-    draw_image_rescale((void*)buf, NULL, X, Y, W, H, D, L, true, scale());
+    draw_image_rescale((void*)buf, NULL, X, Y, W, H, D, L, true);
   }
 }
 
@@ -938,7 +953,7 @@ void Fl_Scalable_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb cb, void* dat
   if (scale() == 1) {
     draw_image_mono_unscaled(cb, data, X,Y,W,H,D);
   } else {
-    draw_image_rescale(data, cb, X, Y, W, H, D, 0, true, scale());
+    draw_image_rescale(data, cb, X, Y, W, H, D, 0, true);
   }
 }
 
@@ -961,25 +976,26 @@ Fl_Region Fl_Scalable_Graphics_Driver::scale_clip(float f) { return 0; }
 
 void Fl_Scalable_Graphics_Driver::point_unscaled(float x, float y) {}
 
-void Fl_Scalable_Graphics_Driver::rect_unscaled(float x, float y, float w, float h) {}
+void Fl_Scalable_Graphics_Driver::rectf_unscaled(int x, int y, int w, int h) {}
 
-void Fl_Scalable_Graphics_Driver::rectf_unscaled(float x, float y, float w, float h) {}
+void Fl_Scalable_Graphics_Driver::line_unscaled(int x, int y, int x1, int y1) {}
 
-void Fl_Scalable_Graphics_Driver::line_unscaled(float x, float y, float x1, float y1) {}
-
-void Fl_Scalable_Graphics_Driver::line_unscaled(float x, float y, float x1, float y1, float x2, float y2) {}
+void Fl_Scalable_Graphics_Driver::line_unscaled(int x, int y, int x1, int y1, int x2, int y2) {
+  line_unscaled(x, y, x1, y1);
+  line_unscaled(x1, y1, x2, y2);
+}
 
-void Fl_Scalable_Graphics_Driver::xyline_unscaled(float x, float y, float x1) {}
+void Fl_Scalable_Graphics_Driver::xyline_unscaled(int x, int y, int x1) {}
 
-void Fl_Scalable_Graphics_Driver::yxline_unscaled(float x, float y, float y1) {}
+void Fl_Scalable_Graphics_Driver::yxline_unscaled(int x, int y, int y1) {}
 
-void Fl_Scalable_Graphics_Driver::loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2) {}
+void Fl_Scalable_Graphics_Driver::loop_unscaled(int x0, int y0, int x1, int y1, int x2, int y2) {}
 
-void Fl_Scalable_Graphics_Driver::loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) {}
+void Fl_Scalable_Graphics_Driver::loop_unscaled(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {}
 
-void Fl_Scalable_Graphics_Driver::polygon_unscaled(float x0, float y0, float x1, float y1, float x2, float y2) {}
+void Fl_Scalable_Graphics_Driver::polygon_unscaled(int x0, int y0, int x1, int y1, int x2, int y2) {}
 
-void Fl_Scalable_Graphics_Driver::polygon_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) {}
+void Fl_Scalable_Graphics_Driver::polygon_unscaled(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {}
 
 void Fl_Scalable_Graphics_Driver::ellipse_unscaled(double xt, double yt, double rx, double ry) {}
 
@@ -1003,11 +1019,11 @@ void Fl_Scalable_Graphics_Driver::draw_unscaled(int angle, const char *str, int
 
 void Fl_Scalable_Graphics_Driver::rtl_draw_unscaled(const char* str, int n, int x, int y) {}
 
-void Fl_Scalable_Graphics_Driver::arc_unscaled(float x, float y, float w, float h, double a1, double a2) {}
+void Fl_Scalable_Graphics_Driver::arc_unscaled(int x, int y, int w, int h, double a1, double a2) {}
 
-void Fl_Scalable_Graphics_Driver::pie_unscaled(float x, float y, float w, float h, double a1, double a2) {}
+void Fl_Scalable_Graphics_Driver::pie_unscaled(int x, int y, int w, int h, double a1, double a2) {}
 
-void Fl_Scalable_Graphics_Driver::line_style_unscaled(int style, float width, char* dashes) {}
+void Fl_Scalable_Graphics_Driver::line_style_unscaled(int style, int width, char* dashes) {}
 
 void Fl_Scalable_Graphics_Driver::draw_image_unscaled(const uchar* buf, int X,int Y,int W,int H, int D, int L) {}
 
diff --git src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx
index b73c72e..9ba2db8 100644
--- src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx
+++ src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx
@@ -75,7 +75,7 @@ Fl_GDI_Copy_Surface_Driver::~Fl_GDI_Copy_Surface_Driver() {
       SetClipboardData (CF_ENHMETAFILE, hmf);
       // then put a BITMAP version of the graphics in the clipboard
       float scaling = driver()->scale();
-      int W = Fl_GDI_Graphics_Driver::floor(width, scaling), H = Fl_GDI_Graphics_Driver::floor(height, scaling);
+      int W = Fl_Scalable_Graphics_Driver::floor(width, scaling), H = Fl_Scalable_Graphics_Driver::floor(height, scaling);
       RECT rect = {0, 0, W, H};
       Fl_Image_Surface *surf = new Fl_Image_Surface(W, H);
       Fl_Surface_Device::push_current(surf);
diff --git src/drivers/GDI/Fl_GDI_Graphics_Driver.H src/drivers/GDI/Fl_GDI_Graphics_Driver.H
index 4ec7bce..cf8ae3e 100644
--- src/drivers/GDI/Fl_GDI_Graphics_Driver.H
+++ src/drivers/GDI/Fl_GDI_Graphics_Driver.H
@@ -57,11 +57,6 @@ public:
   char can_do_alpha_blending();
   virtual void gc(void *ctxt) { gc_ = (HDC)ctxt; global_gc(); }
   virtual void *gc() {return gc_;}
-  // This function aims to compute accurately int(x * s) in
-  // presence of rounding errors existing with floating point numbers
-  // and that sometimes differ between 32 and 64 bits.
-  static inline int floor(int x, float s) { return int(x * s + 0.001f); }
-  inline int floor(int x) { return Fl_GDI_Graphics_Driver::floor(x, scale()); }
 
   // --- bitmap stuff
   Fl_Bitmask create_bitmask(int w, int h, const uchar *array);
@@ -101,21 +96,16 @@ protected:
   void transformed_vertex0(float x, float y);
   void fixloop();
   virtual void point(int x, int y);
-  virtual void rect(int x, int y, int w, int h);
   void focus_rect(int x, int y, int w, int h);
-  virtual void rectf(int x, int y, int w, int h);
-  virtual void line_unscaled(float x, float y, float x1, float y1);
-  virtual void line_unscaled(float x, float y, float x1, float y1, float x2, float y2);
-  virtual void xyline(int x, int y, int x1);
-  virtual void xyline(int x, int y, int x1, int y2);
-  virtual void xyline(int x, int y, int x1, int y2, int x3);
-  virtual void yxline(int x, int y, int y1);
-  virtual void yxline(int x, int y, int y1, int x2);
-  virtual void yxline(int x, int y, int y1, int x2, int y3);
-  virtual void loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2);
-  virtual void loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
-  virtual void polygon_unscaled(float x0, float y0, float x1, float y1, float x2, float y2);
-  virtual void polygon_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
+  virtual void rectf_unscaled(int x, int y, int w, int h);
+  virtual void line_unscaled(int x, int y, int x1, int y1);
+  virtual void line_unscaled(int x, int y, int x1, int y1, int x2, int y2);
+  virtual void xyline_unscaled(int x, int y, int x1);
+  virtual void yxline_unscaled(int x, int y, int y1);
+  virtual void loop_unscaled(int x0, int y0, int x1, int y1, int x2, int y2);
+  virtual void loop_unscaled(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
+  virtual void polygon_unscaled(int x0, int y0, int x1, int y1, int x2, int y2);
+  virtual void polygon_unscaled(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
   // --- clipping
   void push_clip(int x, int y, int w, int h);
   int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H);
@@ -131,14 +121,9 @@ protected:
   void end_complex_polygon();
   void gap();
   virtual void ellipse_unscaled(double xt, double yt, double rx, double ry);
-  // --- implementation is in src/fl_arc.cxx which includes src/cfg_gfx/xxx_arc.cxx if needed
-  // using void Fl_Graphics_Driver::arc(double x, double y, double r, double start, double end);
-  // --- implementation is in src/fl_arci.cxx which includes src/cfg_gfx/xxx_arci.cxx
-  virtual void arc_unscaled(float x, float y, float w, float h, double a1, double a2);
-  virtual void pie_unscaled(float x, float y, float w, float h, double a1, double a2);
-  // --- implementation is in src/fl_line_style.cxx which includes src/cfg_gfx/xxx_line_style.cxx
-  virtual void line_style_unscaled(int style, float width, char* dashes);
-  // --- implementation is in src/fl_color.cxx which includes src/cfg_gfx/xxx_color.cxx
+  virtual void arc_unscaled(int x, int y, int w, int h, double a1, double a2);
+  virtual void pie_unscaled(int x, int y, int w, int h, double a1, double a2);
+  virtual void line_style_unscaled(int style, int width, char* dashes);
   void color(Fl_Color c);
   Fl_Color color() { return color_; }
   void color(uchar r, uchar g, uchar b);
@@ -153,6 +138,8 @@ protected:
   void global_gc();
   virtual void overlay_rect(int x, int y, int w , int h);
   virtual void cache_size(Fl_Image *img, int &width, int &height);
+  virtual void* change_pen_width(int width);
+  virtual void reset_pen_width(void *data);
 };
 
 
diff --git src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
index 09dd6fa..3fe7219 100644
--- src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
+++ src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
@@ -261,13 +261,13 @@ HRGN Fl_GDI_Graphics_Driver::scale_region(HRGN r, float f, Fl_GDI_Graphics_Drive
     }
     RECT *rects = (RECT*)&(pdata->Buffer);
     for (DWORD i = 0; i < pdata->rdh.nCount; i++) {
-      int x = Fl_GDI_Graphics_Driver::floor(rects[i].left, f) + pt.x;
-      int y = Fl_GDI_Graphics_Driver::floor(rects[i].top, f) + pt.y;
+      int x = Fl_Scalable_Graphics_Driver::floor(rects[i].left, f) + pt.x;
+      int y = Fl_Scalable_Graphics_Driver::floor(rects[i].top, f) + pt.y;
       RECT R2;
       R2.left = x;
       R2.top  = y;
-      R2.right = Fl_GDI_Graphics_Driver::floor(rects[i].right, f) + pt.x - x + R2.left;
-      R2.bottom = Fl_GDI_Graphics_Driver::floor(rects[i].bottom, f) + pt.y - y + R2.top;
+      R2.right = Fl_Scalable_Graphics_Driver::floor(rects[i].right, f) + pt.x - x + R2.left;
+      R2.bottom = Fl_Scalable_Graphics_Driver::floor(rects[i].bottom, f) + pt.y - y + R2.top;
       rects[i] = R2;
     }
     r = ExtCreateRegion(NULL, size, pdata);
diff --git src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx
index 9bd3aaa..32a5c16 100644
--- src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx
+++ src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx
@@ -30,8 +30,9 @@
 #include <FL/math.h>
 #include <FL/platform.H>
 
-void Fl_GDI_Graphics_Driver::arc_unscaled(float x, float y, float w, float h, double a1, double a2) {
+void Fl_GDI_Graphics_Driver::arc_unscaled(int x, int y, int w, int h, double a1, double a2) {
   if (w <= 0 || h <= 0) return;
+  w++; h++;
   int xa = int( x+w/2+int(w*cos(a1/180.0*M_PI)) );
   int ya = int( y+h/2-int(h*sin(a1/180.0*M_PI)) );
   int xb = int( x+w/2+int(w*cos(a2/180.0*M_PI)) );
@@ -42,9 +43,11 @@ void Fl_GDI_Graphics_Driver::arc_unscaled(float x, float y, float w, float h, do
   } else Arc(gc_, int(x), int(y), int(x+w), int(y+h), xa, ya, xb, yb);
 }
 
-void Fl_GDI_Graphics_Driver::pie_unscaled(float x, float y, float w, float h, double a1, double a2) {
+void Fl_GDI_Graphics_Driver::pie_unscaled(int x, int y, int w, int h, double a1, double a2) {
   if (w <= 0 || h <= 0) return;
   if (a1 == a2) return;
+  x++; y++; w--; h--;
+  if (scale() >= 3) {x++; y++; w-=2; h-=2;}
   int xa = int( x+w/2+int(w*cos(a1/180.0*M_PI)) );
   int ya = int( y+h/2-int(h*sin(a1/180.0*M_PI)) );
   int xb = int( x+w/2+int(w*cos(a2/180.0*M_PI)) );
diff --git src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx
index 18fba5f..2cf6d82 100644
--- src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx
+++ src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx
@@ -27,7 +27,7 @@
 #include "Fl_GDI_Graphics_Driver.H"
 
 
-void Fl_GDI_Graphics_Driver::line_style_unscaled(int style, float width, char* dashes) {
+void Fl_GDI_Graphics_Driver::line_style_unscaled(int style, int width, char* dashes) {
 
   // According to Bill, the "default" cap and join should be the
   // "fastest" mode supported for the platform.  I don't know why
@@ -45,11 +45,10 @@ void Fl_GDI_Graphics_Driver::line_style_unscaled(int style, float width, char* d
   } else {
     s1 |= style & 0xff; // allow them to pass any low 8 bits for style
   }
-  if ((style || n) && !width) width = scale(); // fix cards that do nothing for 0?
+  if ((style || n) && !width) width = int(scale()); // fix cards that do nothing for 0?
   if (!fl_current_xmap) color(FL_BLACK);
   LOGBRUSH penbrush = {BS_SOLID,fl_RGB(),0}; // can this be fl_brush()?
-  int tw = ( width < 1.f ? 1 : int(width) );
-  HPEN newpen = ExtCreatePen(s1, tw, &penbrush, n, n ? a : 0);
+  HPEN newpen = ExtCreatePen(s1, width, &penbrush, n, n ? a : 0);
   if (!newpen) {
     Fl::error("fl_line_style(): Could not create GDI pen object.");
     return;
diff --git src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx
index 4a8daeb..e7aac90 100644
--- src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx
+++ src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx
@@ -47,16 +47,6 @@ void Fl_GDI_Graphics_Driver::overlay_rect(int x, int y, int w , int h) {
   LineTo(gc_, x, y);
 }
 
-void Fl_GDI_Graphics_Driver::rect(int x, int y, int w, int h)
-{
-  if (w > 0 && h > 0) {
-    xyline(x, y, (x+w-1));
-    yxline(x, y, (y+h-1));
-    yxline((x+w-1), y, (y+h-1));
-    xyline(x, (y+h-1), (x+w-1));
-  }
-}
-
 void Fl_GDI_Graphics_Driver::focus_rect(int x, int y, int w, int h) {
   // Windows 95/98/ME do not implement the dotted line style, so draw
   // every other pixel around the focus area...
@@ -71,127 +61,76 @@ void Fl_GDI_Graphics_Driver::focus_rect(int x, int y, int w, int h) {
   for (yy = h; yy > 0; yy--, i++) if (i & 1) SetPixel(gc_, x, y+yy, c);
 }
 
-void Fl_GDI_Graphics_Driver::rectf(int x, int y, int w, int h) {
-  if (w<=0 || h<=0) return;
+void Fl_GDI_Graphics_Driver::rectf_unscaled(int x, int y, int w, int h) {
   RECT rect;
-  rect.left = this->floor(x); rect.top = this->floor(y);
-  rect.right = this->floor(x + w); rect.bottom = this->floor(y + h);
+  rect.left = x; rect.top = y;
+  rect.right = (x + w); rect.bottom = (y + h);
   FillRect(gc_, &rect, fl_brush());
 }
 
-void Fl_GDI_Graphics_Driver::line_unscaled(float x, float y, float x1, float y1) {
-  MoveToEx(gc_, int(x), int(y), 0L);
-  LineTo(gc_, int(x1), int(y1));
-  SetPixel(gc_, int(x1), int(y1), fl_RGB());
+void Fl_GDI_Graphics_Driver::line_unscaled(int x, int y, int x1, int y1) {
+  MoveToEx(gc_, x, y, 0L);
+  LineTo(gc_, x1, y1);
+  SetPixel(gc_, x1, y1, fl_RGB());
 }
 
-void Fl_GDI_Graphics_Driver::line_unscaled(float x, float y, float x1, float y1, float x2, float y2) {
-  MoveToEx(gc_, int(x), int(y), 0L);
-  LineTo(gc_, int(x1), int(y1));
-  LineTo(gc_, int(x2), int(y2));
-  SetPixel(gc_, int(x2), int(y2), fl_RGB());
+void Fl_GDI_Graphics_Driver::line_unscaled(int x, int y, int x1, int y1, int x2, int y2) {
+  MoveToEx(gc_, x, y, 0L);
+  LineTo(gc_, x1, y1);
+  LineTo(gc_, x2, y2);
+  SetPixel(gc_, x2, y2, fl_RGB());
 }
 
-static HPEN change_pen_width(int width, HDC gc) { // set the width of the pen, return previous pen
+void* Fl_GDI_Graphics_Driver::change_pen_width(int width) { // set the width of the pen, return previous pen
   LOGBRUSH penbrush = {BS_SOLID, fl_RGB(), 0};
   HPEN newpen = ExtCreatePen(PS_GEOMETRIC | PS_ENDCAP_FLAT | PS_JOIN_ROUND, width, &penbrush, 0, 0);
-  return (HPEN)SelectObject(gc, newpen);
-}
-
-void Fl_GDI_Graphics_Driver::xyline(int x, int y, int x1) {
-  if (y < 0) return;
-  float s = scale();
-  int xx = (x < x1 ? x : x1);
-  int xx1 = (x < x1 ? x1 : x);
-  if (s != int(s) && line_width_ <= int(s)) {
-    int lwidth = this->floor((y+1)) - this->floor(y);
-    bool need_pen = (lwidth != int(s));
-    HPEN oldpen = (need_pen ? change_pen_width(lwidth, gc_) : NULL);
-    MoveToEx(gc_, this->floor(xx), this->floor(y) + int(lwidth/2.f) , 0L);
-    LineTo(gc_, this->floor((xx1+1)), this->floor(y) + int(lwidth/2.f));
-    if (need_pen) {
-      DeleteObject(SelectObject(gc_, oldpen));
-    }
-  } else {
-    y = int((y + 0.5f) * s);
-    MoveToEx(gc_, this->floor(xx), y, 0L);
-    LineTo(gc_, this->floor(xx1) + int(s) , y);
-  }
-}
-
-void Fl_GDI_Graphics_Driver::xyline(int x, int y, int x1, int y2) {
-  xyline(x, y, x1);
-  yxline(x1, y, y2);
-}
-
-void Fl_GDI_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) {
-  xyline(x, y, x1);
-  yxline(x1, y, y2);
-  xyline(x1, y2, x3);
+  return SelectObject(gc_, newpen);
 }
 
-void Fl_GDI_Graphics_Driver::yxline(int x, int y, int y1) {
-  if (x < 0) return;
-  double s = scale();
-  int yy = (y < y1 ? y : y1);
-  int yy1 = (y < y1 ? y1 : y);
-  if (s != int(s) && line_width_ <= int(s)) {
-    int lwidth = (this->floor((x+1)) - this->floor(x));
-    bool need_pen = (lwidth != int(s));
-    HPEN oldpen = (need_pen ? change_pen_width(lwidth, gc_) : NULL);
-    MoveToEx(gc_, this->floor(x) + int(lwidth/2.f), this->floor(yy), 0L);
-    LineTo(gc_, this->floor(x) + int(lwidth/2.f), this->floor((yy1+1)) );
-    if (need_pen) {
-      DeleteObject(SelectObject(gc_, oldpen));
-    }
-  } else {
-    x = int((x + 0.5f) * s);
-    MoveToEx(gc_, x, this->floor(yy), 0L);
-    LineTo(gc_, x, this->floor(yy1) + int(s));
-  }
+void Fl_GDI_Graphics_Driver::reset_pen_width(void *data) {
+  DeleteObject(SelectObject(gc_, (HPEN)data));
 }
 
-void Fl_GDI_Graphics_Driver::yxline(int x, int y, int y1, int x2) {
-  yxline(x, y, y1);
-  xyline(x, y1, x2);
+void Fl_GDI_Graphics_Driver::xyline_unscaled(int x, int y, int x1) {
+  MoveToEx(gc_, x, y, 0L);
+  LineTo(gc_, x1+1 , y);
 }
 
-void Fl_GDI_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) {
-  yxline(x, y, y1);
-  xyline(x, y1, x2);
-  yxline(x2, y1, y3);
+void Fl_GDI_Graphics_Driver::yxline_unscaled(int x, int y, int y1) {
+  MoveToEx(gc_, x, y, 0L);
+  LineTo(gc_, x, y1+1);
 }
 
-void Fl_GDI_Graphics_Driver::loop_unscaled(float x, float y, float x1, float y1, float x2, float y2) {
-  MoveToEx(gc_, int(x), int(y), 0L);
-  LineTo(gc_, int(x1), int(y1));
-  LineTo(gc_, int(x2), int(y2));
-  LineTo(gc_, int(x), int(y));
+void Fl_GDI_Graphics_Driver::loop_unscaled(int x, int y, int x1, int y1, int x2, int y2) {
+  MoveToEx(gc_, x, y, 0L);
+  LineTo(gc_, x1, y1);
+  LineTo(gc_, x2, y2);
+  LineTo(gc_, x, y);
 }
 
-void Fl_GDI_Graphics_Driver::loop_unscaled(float x, float y, float x1, float y1, float x2, float y2, float x3, float y3) {
-  MoveToEx(gc_, int(x), int(y), 0L);
-  LineTo(gc_, int(x1), int(y1));
-  LineTo(gc_, int(x2), int(y2));
-  LineTo(gc_, int(x3), int(y3));
-  LineTo(gc_, int(x), int(y));
+void Fl_GDI_Graphics_Driver::loop_unscaled(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
+  MoveToEx(gc_, x, y, 0L);
+  LineTo(gc_, x1, y1);
+  LineTo(gc_, x2, y2);
+  LineTo(gc_, x3, y3);
+  LineTo(gc_, x, y);
 }
 
-void Fl_GDI_Graphics_Driver::polygon_unscaled(float x, float y, float x1, float y1, float x2, float y2) {
+void Fl_GDI_Graphics_Driver::polygon_unscaled(int x, int y, int x1, int y1, int x2, int y2) {
   POINT p[3];
-  p[0].x = int(x);  p[0].y = int(y);
-  p[1].x = int(x1); p[1].y = int(y1);
-  p[2].x = int(x2); p[2].y = int(y2);
+  p[0].x = x;  p[0].y = y;
+  p[1].x = x1; p[1].y = y1;
+  p[2].x = x2; p[2].y = y2;
   SelectObject(gc_, fl_brush());
   Polygon(gc_, p, 3);
 }
 
-void Fl_GDI_Graphics_Driver::polygon_unscaled(float x, float y, float x1, float y1, float x2, float y2, float x3, float y3) {
+void Fl_GDI_Graphics_Driver::polygon_unscaled(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
   POINT p[4];
-  p[0].x = int(x);  p[0].y = int(y);
-  p[1].x = int(x1); p[1].y = int(y1);
-  p[2].x = int(x2); p[2].y = int(y2);
-  p[3].x = int(x3); p[3].y = int(y3);
+  p[0].x = x;  p[0].y = y;
+  p[1].x = x1; p[1].y = y1;
+  p[2].x = x2; p[2].y = y2;
+  p[3].x = x3; p[3].y = y3;
   SelectObject(gc_, fl_brush());
   Polygon(gc_, p, 4);
 }
diff --git src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
index eb437b9..5747f16 100644
--- src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
+++ src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
@@ -501,12 +501,12 @@ Fl_WinAPI_Screen_Driver::read_win_rectangle(
   int ws, hs;
   if (int(s) == s) { ws = w * int(s); hs = h * int(s);}
   else {
-    ws = Fl_GDI_Graphics_Driver::floor(w+1, s); // approximates what Fl_Graphics_Driver::cache_size() does
-    hs = Fl_GDI_Graphics_Driver::floor(h+1, s);
+    ws = Fl_Scalable_Graphics_Driver::floor(X+w, s) - Fl_Scalable_Graphics_Driver::floor(X, s),
+    hs = Fl_Scalable_Graphics_Driver::floor(Y+h, s) - Fl_Scalable_Graphics_Driver::floor(Y, s);
     if (ws < 1) ws = 1;
     if (hs < 1) hs = 1;
   }
-  return read_win_rectangle_unscaled(Fl_GDI_Graphics_Driver::floor(X, s), Fl_GDI_Graphics_Driver::floor(Y, s), ws, hs, win);
+  return read_win_rectangle_unscaled(Fl_Scalable_Graphics_Driver::floor(X, s), Fl_Scalable_Graphics_Driver::floor(Y, s), ws, hs, win);
 }
 
 Fl_RGB_Image *Fl_WinAPI_Screen_Driver::read_win_rectangle_unscaled(int X, int Y, int w, int h, Fl_Window *win)
diff --git src/drivers/X11/Fl_X11_Screen_Driver.cxx src/drivers/X11/Fl_X11_Screen_Driver.cxx
index 33f087d..f924267 100644
--- src/drivers/X11/Fl_X11_Screen_Driver.cxx
+++ src/drivers/X11/Fl_X11_Screen_Driver.cxx
@@ -774,7 +774,8 @@ 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 ws = w * s, hs = h * s, Xs = X*s, Ys = Y*s;
+  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;
 
 #  ifdef __sgi
   if (XReadDisplayQueryExtension(fl_display, &i, &i)) {
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
index b593657..7ee34a9 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
@@ -57,7 +57,6 @@ private:
   unsigned depth_; // depth of translation stack
   int stack_x_[FL_XLIB_GRAPHICS_TRANSLATION_STACK_SIZE]; // translation stack allowing cumulative translations
   int stack_y_[FL_XLIB_GRAPHICS_TRANSLATION_STACK_SIZE];
-  int line_delta_;
   virtual void set_current_();
   int clip_max_; // +/- x/y coordinate limit (16-bit coordinate space)
   virtual void draw_fixed(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
@@ -139,18 +138,17 @@ public:
 protected:
   virtual void transformed_vertex0(float x, float y);
   void fixloop();
-  // --- implementation is in src/fl_rect.cxx which includes src/cfg_gfx/xlib_rect.cxx
-  virtual void point_unscaled(float x, float y);
-  virtual void rect_unscaled(float x, float y, float w, float h);
-  virtual void rectf_unscaled(float x, float y, float w, float h);
-  virtual void line_unscaled(float x, float y, float x1, float y1);
-  virtual void line_unscaled(float x, float y, float x1, float y1, float x2, float y2);
-  virtual void xyline_unscaled(float x, float y, float x1);
-  virtual void yxline_unscaled(float x, float y, float y1);
-  virtual void loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2);
-  virtual void loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
-  virtual void polygon_unscaled(float x0, float y0, float x1, float y1, float x2, float y2);
-  virtual void polygon_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
+  virtual void focus_rect(int x, int y, int w, int h);
+  virtual void rectf_unscaled(int x, int y, int w, int h);
+  virtual void line_unscaled(int x, int y, int x1, int y1);
+  virtual void xyline_unscaled(int x, int y, int x1);
+  virtual void *change_pen_width(int lwidth);
+  virtual void reset_pen_width(void *data);
+  virtual void yxline_unscaled(int x, int y, int y1);
+  virtual void loop_unscaled(int x0, int y0, int x1, int y1, int x2, int y2);
+  virtual void loop_unscaled(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
+  virtual void polygon_unscaled(int x0, int y0, int x1, int y1, int x2, int y2);
+  virtual void polygon_unscaled(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
 
   // Scaling and clipping stuff for internal usage.
   // Currently specific to Fl_Xlib_Graphics_Driver (16-bit coordinate clipping)
@@ -194,10 +192,9 @@ protected:
   void end_complex_polygon();
   void gap();
   virtual void ellipse_unscaled(double xt, double yt, double rx, double ry);
-  // --- implementation is in src/fl_arci.cxx which includes src/cfg_gfx/xxx_arci.cxx
-  virtual void arc_unscaled(float x, float y, float w, float h, double a1, double a2);
-  virtual void pie_unscaled(float x, float y, float w, float h, double a1, double a2);
-  virtual void line_style_unscaled(int style, float width, char* dashes);
+  virtual void arc_unscaled(int x, int y, int w, int h, double a1, double a2);
+  virtual void pie_unscaled(int x, int y, int w, int h, double a1, double a2);
+  virtual void line_style_unscaled(int style, int width, char* dashes);
   void color(Fl_Color c);
   void set_color(Fl_Color i, unsigned int c);
   void free_color(Fl_Color i, int overlay);
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx
index 3bb14e9..6401efa 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx
@@ -50,7 +50,6 @@ GC fl_gc = 0;
 Fl_Xlib_Graphics_Driver::Fl_Xlib_Graphics_Driver(void) {
   mask_bitmap_ = NULL;
   p = NULL;
-  line_delta_ = 0;
 #if USE_PANGO
   Fl_Graphics_Driver::font(0, 0);
 #endif
@@ -76,17 +75,6 @@ void Fl_Xlib_Graphics_Driver::scale(float f) {
     Fl_Graphics_Driver::scale(f);
     //fprintf(stderr, "scale=%.2f\n", scale_);
     line_style(FL_SOLID); // scale also default line width
-    /* Scaling >= 2 transforms 1-pixel wide lines into wider lines.
-     X11 draws 2-pixel wide lines so that half of the line width is above or at left
-     of a 1-pixel wide line that would be drawn with the same coordinates.
-     Thus, if the line starts at coordinates (0,0) half of the line width is invisible.
-     Similarly, if the line ends at w()-1 the last pixel of the window is not drawn.
-     What is wanted when scale_ == 2 is a visible 2-pixel wide line in the first case,
-     and a line at the window's edge in the 2nd case.
-     Setting line_delta_ to 1 and offsetting all line, rectangle, text and clip
-     coordinates by line_delta_ achieves what is wanted until scale_ <= 3.5.
-     */
-    line_delta_ =  (scale() > 1.9/*1.75*/ ? 1 : 0);
   }
 #endif
 }
@@ -109,8 +97,8 @@ void Fl_Xlib_Graphics_Driver::transformed_vertex0(float fx, float fy) {
       p_size = p ? 2*p_size : 16;
       p = (XPOINT*)realloc((void*)p, p_size*sizeof(*p));
     }
-    p[n].x = x + line_delta_;
-    p[n].y = y + line_delta_;
+    p[n].x = x ;
+    p[n].y = y ;
     n++;
   }
 }
@@ -242,15 +230,12 @@ void Fl_Xlib_Graphics_Driver::font_name(int num, const char *name) {
 Region Fl_Xlib_Graphics_Driver::scale_clip(float f) {
   Region r = rstack[rstackptr];
   if (r == 0 || (f == 1 && offset_x_ == 0 && offset_y_ == 0) ) return 0;
-  int deltaf = f/2;
   Region r2 = XCreateRegion();
   for (int i = 0; i < r->numRects; i++) {
-    int x = (r->rects[i].x1 + offset_x_)*f;
-    int y = (r->rects[i].y1 + offset_y_)*f;
-    int w = int((r->rects[i].x2 + offset_x_) * f) - x;
-    int h = int((r->rects[i].y2 + offset_y_) * f) - y;
-    x += line_delta_ - deltaf;
-    y += line_delta_ - deltaf;
+    int x = floor(r->rects[i].x1 + offset_x_, f);
+    int y = floor(r->rects[i].y1 + offset_y_, f);
+    int w = floor((r->rects[i].x2 + offset_x_) , f) - x;
+    int h = floor((r->rects[i].y2 + offset_y_) , f) - y;
     Region R = XRectangleRegion(x, y, w, h);
     XUnionRegion(R, r2, r2);
     ::XDestroyRegion(R);
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx src/drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx
index 381ac0d..4897cf7 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx
@@ -24,15 +24,18 @@
   \brief Utility functions for drawing circles using integers
 */
 
-void Fl_Xlib_Graphics_Driver::arc_unscaled(float x,float y,float w,float h,double a1,double a2) {
+void Fl_Xlib_Graphics_Driver::arc_unscaled(int x, int y, int w, int h, double a1, double a2) {
   if (w <= 0 || h <= 0) return;
-  XDrawArc(fl_display, fl_window, gc_, int(x+offset_x_*scale()), int(y+offset_y_*scale()), int(w-1), int(h-1), int(a1*64),int((a2-a1)*64));
+  x += floor(offset_x_);
+  y += floor(offset_y_);
+  XDrawArc(fl_display, fl_window, gc_, x, y, w, h, int(a1*64),int((a2-a1)*64));
 }
 
-void Fl_Xlib_Graphics_Driver::pie_unscaled(float x,float y,float w,float h,double a1,double a2) {
-  if (w <= 0 || h <= 0) return;
-  x += offset_x_*scale();
-  y += offset_y_*scale();
-  XDrawArc(fl_display, fl_window, gc_, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64));
-  XFillArc(fl_display, fl_window, gc_, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64));
+void Fl_Xlib_Graphics_Driver::pie_unscaled(int x, int y, int w, int h, double a1,double a2) {
+  if (w <= 2 || h <= 2) return;
+  x += floor(offset_x_);
+  y += floor(offset_y_);
+  int extra = scale() >= 3 ? 1 : 0;
+  XDrawArc(fl_display, fl_window, gc_, x+1+extra, y+1+extra, w-2-2*extra, h-2-2*extra, int(a1*64), int((a2-a1)*64));
+  XFillArc(fl_display, fl_window, gc_, x+1, y+1, w-2, h-2, int(a1*64), int((a2-a1)*64));
 }
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
index 2f38a82..a8039df 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
@@ -779,8 +779,8 @@ void Fl_Xlib_Graphics_Driver::text_extents_unscaled(const char *c, int n, int &d
 
   w = gi.width;
   h = gi.height;
-  dx = -gi.x + line_delta_;
-  dy = -gi.y + line_delta_;
+  dx = -gi.x ;
+  dy = -gi.y ;
   correct_extents(scale(), dx, dy, w, h);
 }
 
@@ -788,10 +788,10 @@ void Fl_Xlib_Graphics_Driver::draw_unscaled(const char *str, int n, int x, int y
 
   // transform coordinates and clip if outside 16-bit space (STR 2798)
 
-  int x1 = x + offset_x_ * scale() + line_delta_;
+  int x1 = x + floor(offset_x_) ;
   if (x1 < clip_min() || x1 > clip_max()) return;
 
-  int y1 = y + offset_y_ * scale() + line_delta_;
+  int y1 = y + floor(offset_y_) ;
   if (y1 < clip_min() || y1 > clip_max()) return;
 
 #if USE_OVERLAY
@@ -870,7 +870,7 @@ void Fl_Xlib_Graphics_Driver::drawUCS4(const void *str, int n, int x, int y) {
   color.color.blue  = ((int)b)*0x101;
   color.color.alpha = 0xffff;
 
-  XftDrawString32(draw_, &color, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, x+offset_x_*scale()+line_delta_, y+offset_y_*scale()+line_delta_, (FcChar32 *)str, n);
+  XftDrawString32(draw_, &color, ((Fl_Xlib_Font_Descriptor*)font_descriptor())->font, x+floor(offset_x_), y+floor(offset_y_), (FcChar32 *)str, n);
 }
 
 
@@ -1256,12 +1256,12 @@ void Fl_Xlib_Graphics_Driver::font_unscaled(Fl_Font fnum, Fl_Fontsize size) {
 }
 
 void Fl_Xlib_Graphics_Driver::draw_unscaled(const char *str, int n, int x, int y) {
-  do_draw(0, str, n, x+offset_x_*scale(), y+offset_y_*scale());
+  do_draw(0, str, n, x + floor(offset_x_), y + floor(offset_y_));
 }
 
 void Fl_Xlib_Graphics_Driver::draw_unscaled(int angle, const char *str, int n, int x, int y) {
   PangoMatrix mat = PANGO_MATRIX_INIT; // 1.6
-  pango_matrix_translate(&mat, x+offset_x_*scale(), y+offset_y_*scale()); // 1.6
+  pango_matrix_translate(&mat, x + floor(offset_x_), y + floor(offset_y_)); // 1.6
   double l = width_unscaled(str, n);
   pango_matrix_rotate(&mat, angle); // 1.6
   pango_context_set_matrix(pctxt_, &mat); // 1.6
@@ -1275,7 +1275,7 @@ void Fl_Xlib_Graphics_Driver::draw_unscaled(int angle, const char *str, int n, i
 }
 
 void Fl_Xlib_Graphics_Driver::rtl_draw_unscaled(const char* str, int n, int x, int y) {
-  do_draw(1, str, n, x+offset_x_*scale(), y+offset_y_*scale());
+  do_draw(1, str, n, x+floor(offset_x_), y+floor(offset_y_));
 }
 
 /* Compute dx, dy, w, h so that fl_rect(x+dx, y+dy, w, h) is the bounding box
@@ -1343,8 +1343,8 @@ void Fl_Xlib_Graphics_Driver::do_draw(int from_right, const char *str, int n, in
   if (from_right) {
     x -= w;
   }
-  pango_xft_render_layout(draw_, &color, playout_, (x + line_delta_)*PANGO_SCALE,
-                          (y - y_correction + line_delta_ - lheight + desc)*PANGO_SCALE ); // 1.8
+  pango_xft_render_layout(draw_, &color, playout_, x * PANGO_SCALE,
+                          (y - y_correction  - lheight + desc) * PANGO_SCALE ); // 1.8
   }
 
 double Fl_Xlib_Graphics_Driver::width_unscaled(const char* str, int n) {
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx
index 9361e5d..9b2fc69 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx
@@ -580,7 +580,7 @@ void Fl_Xlib_Graphics_Driver::draw_image_unscaled(const uchar* buf, int x, int y
   if (alpha) d ^= FL_IMAGE_WITH_ALPHA;
   const int mono = (d>-3 && d<3);
 
-  innards(buf,x+offset_x_*scale(),y+offset_y_*scale(),w,h,d,l,mono,0,0,alpha,gc_);
+  innards(buf,x+floor(offset_x_),y+floor(offset_y_),w,h,d,l,mono,0,0,alpha,gc_);
 }
 
 void Fl_Xlib_Graphics_Driver::draw_image_unscaled(Fl_Draw_Image_Cb cb, void* data,
@@ -590,16 +590,16 @@ void Fl_Xlib_Graphics_Driver::draw_image_unscaled(Fl_Draw_Image_Cb cb, void* dat
   if (alpha) d ^= FL_IMAGE_WITH_ALPHA;
   const int mono = (d>-3 && d<3);
 
-  innards(0,x+offset_x_*scale(),y+offset_y_*scale(),w,h,d,0,mono,cb,data,alpha,gc_);
+  innards(0,x+floor(offset_x_),y+floor(offset_y_),w,h,d,0,mono,cb,data,alpha,gc_);
 }
 
 void Fl_Xlib_Graphics_Driver::draw_image_mono_unscaled(const uchar* buf, int x, int y, int w, int h, int d, int l){
-  innards(buf,x+offset_x_*scale(),y+offset_y_*scale(),w,h,d,l,1,0,0,0,gc_);
+  innards(buf,x+floor(offset_x_),y+floor(offset_y_),w,h,d,l,1,0,0,0,gc_);
 }
 
 void Fl_Xlib_Graphics_Driver::draw_image_mono_unscaled(Fl_Draw_Image_Cb cb, void* data,
                    int x, int y, int w, int h,int d) {
-  innards(0,x+offset_x_*scale(),y+offset_y_*scale(),w,h,d,0,1,cb,data,0,gc_);
+  innards(0,x+floor(offset_x_),y+floor(offset_y_),w,h,d,0,1,cb,data,0,gc_);
 }
 
 void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) {
@@ -623,8 +623,8 @@ void Fl_Xlib_Graphics_Driver::delete_bitmask(Fl_Bitmask bm) {
 }
 
 void Fl_Xlib_Graphics_Driver::draw_fixed(Fl_Bitmap *bm, int X, int Y, int W, int H, int cx, int cy) {
-  X = (X+offset_x_)*scale();
-  Y = (Y+offset_y_)*scale();
+  X = floor(X)+floor(offset_x_);
+  Y = floor(Y)+floor(offset_y_);
   cache_size(bm, W, H);
   cx *= scale(); cy *= scale();
   XSetStipple(fl_display, gc_, *Fl_Graphics_Driver::id(bm));
@@ -737,8 +737,8 @@ void Fl_Xlib_Graphics_Driver::cache(Fl_RGB_Image *img) {
 
 
 void Fl_Xlib_Graphics_Driver::draw_fixed(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, int cy) {
-  X = (X+offset_x_)*scale();
-  Y = (Y+offset_y_)*scale();
+  X = floor(X)+floor(offset_x_);
+  Y = floor(Y)+floor(offset_y_);
   cache_size(img, W, H);
   cx *= scale(); cy *= scale();
   if (img->d() == 1 || img->d() == 3) {
@@ -783,7 +783,8 @@ 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),
-                          (XP-cx + offset_x_)*scale()-offset, (YP-cy + offset_y_)*scale()-offset, Wfull, Hfull);
+                          floor(XP-cx) + floor(offset_x_) - offset, floor(YP-cy) + floor(offset_y_) - offset,
+                          Wfull, Hfull);
   pop_clip();
 }
 
@@ -851,8 +852,8 @@ void Fl_Xlib_Graphics_Driver::cache(Fl_Bitmap *bm) {
 }
 
 void Fl_Xlib_Graphics_Driver::draw_fixed(Fl_Pixmap *pxm, int X, int Y, int W, int H, int cx, int cy) {
-  X = (X+offset_x_)*scale();
-  Y = (Y+offset_y_)*scale();
+  X = floor(X)+floor(offset_x_);
+  Y = floor(Y)+floor(offset_y_);
   cache_size(pxm, W, H);
   cx *= scale(); cy *= scale();
   Fl_Region r2 = scale_clip(scale());
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx src/drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx
index 606b829..1aaecee 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx
@@ -26,7 +26,7 @@
 
 #include "Fl_Xlib_Graphics_Driver.H"
 
-void Fl_Xlib_Graphics_Driver::line_style_unscaled(int style, float width, char* dashes) {
+void Fl_Xlib_Graphics_Driver::line_style_unscaled(int style, int width, char* dashes) {
 
   int ndashes = dashes ? strlen(dashes) : 0;
   // emulate the Windows dash patterns on X
@@ -61,3 +61,19 @@ if (*dashes == 0) ndashes = 0;//against error with very small scaling
                      Cap[(style>>8)&3], Join[(style>>12)&3]);
   if (ndashes) XSetDashes(fl_display, gc_, 0, dashes, ndashes);
 }
+
+void *Fl_Xlib_Graphics_Driver::change_pen_width(int lwidth) {
+  XGCValues *gc_values = (XGCValues*)malloc(sizeof(XGCValues));
+  gc_values->line_width = lwidth;
+  XChangeGC(fl_display, gc_, GCLineWidth, gc_values);
+  gc_values->line_width = line_width_;
+  line_width_ = lwidth;
+  return gc_values;
+}
+
+void Fl_Xlib_Graphics_Driver::reset_pen_width(void *data) {
+  XGCValues *gc_values = (XGCValues*)data;
+  line_width_ = gc_values->line_width;
+  XChangeGC(fl_display, gc_, GCLineWidth, gc_values);
+  delete gc_values;
+}
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx
index 4a2b48a..7bf905f 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx
@@ -208,123 +208,86 @@ void Fl_Xlib_Graphics_Driver::XDestroyRegion(Fl_Region r) {
 
 // --- line and polygon drawing
 
-// called only when scale_ has integer value
-void Fl_Xlib_Graphics_Driver::rect_unscaled(float fx, float fy, float fw, float fh) {
-  if (fw<=0 || fh<=0) return;
-  int deltaf = scale() >= 2 ? scale()-1 : 0;
-  fx += offset_x_*scale(); fy += offset_y_*scale();
-  int x = fx; int y = fy;
-  int w = int(fw) - 1 - deltaf;
-  int h = int(fh) - 1 - deltaf;
-  if (!clip_rect(x, y, w, h))
-    XDrawRectangle(fl_display, fl_window, gc_, x+line_delta_, y+line_delta_, w, h);
+void Fl_Xlib_Graphics_Driver::focus_rect(int x, int y, int w, int h)
+{
+  w = this->floor(x + w) - this->floor(x);
+  h = this->floor(y + h) - this->floor(y);
+  x = this->floor(x) + floor(offset_x_);
+  y = this->floor(y) + floor(offset_y_);
+  if (!clip_rect(x, y, w, h)) {
+    line_style(FL_DOT);
+    XDrawRectangle(fl_display, fl_window, gc_, x, y, w, h);
+    line_style(FL_SOLID);
+  }
 }
 
-void Fl_Xlib_Graphics_Driver::rectf_unscaled(float fx, float fy, float fw, float fh) {
-  if (fw<=0 || fh<=0) return;
-  int deltaf = scale() >= 2 ? scale()/2 : 0;
-  fx += offset_x_*scale(); fy += offset_y_*scale();
-  int x = fx-deltaf; int y = fy-deltaf;
-  // make sure no unfilled area lies between rectf(x,y,w,h) and  rectf(x+w,y,1,h) or rectf(x,y+w,w,1)
-  int w = int(int(fx/scale()+fw/scale()+0.5)*scale()) - int(fx);
-  int h = int(int(fy/scale()+fh/scale()+0.5)*scale()) - int(fy);
+void Fl_Xlib_Graphics_Driver::rectf_unscaled(int x, int y, int w, int h) {
+  x += floor(offset_x_);
+  y += floor(offset_y_);
   if (!clip_rect(x, y, w, h))
-    XFillRectangle(fl_display, fl_window, gc_, x+line_delta_, y+line_delta_, w, h);
-}
-
-void Fl_Xlib_Graphics_Driver::point_unscaled(float fx, float fy) {
-  int deltaf = scale() >= 2 ? scale()/2 : 0;
-  int x = fx+offset_x_*scale()-deltaf;
-  int y = fy+offset_y_*scale()-deltaf;
-  int width = scale() >= 1 ? scale() : 1;
-  // *FIXME* This needs X coordinate clipping:
-  XFillRectangle(fl_display, fl_window, gc_, x+line_delta_, y+line_delta_, width, width);
+    XFillRectangle(fl_display, fl_window, gc_, x, y, w, h);
 }
 
-void Fl_Xlib_Graphics_Driver::line_unscaled(float x, float y, float x1, float y1) {
-  if (x == x1) yxline_unscaled(x, y, y1);
-  else if (y == y1) xyline_unscaled(x, y, x1);
-  else draw_clipped_line(x+offset_x_*scale()+line_delta_, y+offset_y_*scale()+line_delta_, x1+offset_x_*scale()+line_delta_, y1+offset_y_*scale()+line_delta_);
-}
-
-void Fl_Xlib_Graphics_Driver::line_unscaled(float x, float y, float x1, float y1, float x2, float y2) {
-  XPoint p[3];
-  p[0].x = x+offset_x_*scale()+line_delta_;  p[0].y = y+offset_y_*scale()+line_delta_;
-  p[1].x = x1+offset_x_*scale()+line_delta_; p[1].y = y1+offset_y_*scale()+line_delta_;
-  p[2].x = x2+offset_x_*scale()+line_delta_; p[2].y = y2+offset_y_*scale()+line_delta_;
-  // *FIXME* This needs X coordinate clipping!
-  XDrawLines(fl_display, fl_window, gc_, p, 3, 0);
+void Fl_Xlib_Graphics_Driver::line_unscaled(int x, int y, int x1, int y1) {
+   draw_clipped_line(x + this->floor(offset_x_) , y + this->floor(offset_y_) ,
+                    x1 + this->floor(offset_x_) , y1 + this->floor(offset_y_) );
 }
 
-void Fl_Xlib_Graphics_Driver::xyline_unscaled(float x, float y, float x1) {
-  x+=offset_x_*scale(); y+=offset_y_*scale(); x1 += offset_x_*scale();
-  int tw = line_width_ ? line_width_ : 1; // true line width
-  if (x > x1) { float exch = x; x = x1; x1 = exch; }
-  int ix = clip_xy(x+line_delta_); if (scale() >= 2) ix -= int(scale()/2);
-  int iy = clip_xy(y+line_delta_);
-  // make sure that line output by xyline(a,b,c) extends to pixel just at left of where xyline(c+1,b,d) begins
-  int ix1 = int(x1/scale()+1.5)*scale()-1;
-  ix1 += line_delta_; if (scale() >= 4) ix1 -= 1;
-  draw_clipped_line(ix, iy, ix1, iy);
-  // make sure no unfilled area lies between xyline(x,y,x1) and xyline(x,y+1,x1)
-  if (y+line_delta_ + scale() >= iy + tw+1 - 0.001 )
-    draw_clipped_line(ix, iy+1, ix1, iy+1);
+void Fl_Xlib_Graphics_Driver::xyline_unscaled(int x, int y, int x1) {
+  if (line_width_ >= 2) x1++;
+  x += floor(offset_x_) ;
+  y += floor(offset_y_) ;
+  x1 += floor(offset_x_) ;
+  draw_clipped_line(x, y, x1, y);
 }
 
-void Fl_Xlib_Graphics_Driver::yxline_unscaled(float x, float y, float y1) {
-  x+=offset_x_*scale(); y+=offset_y_*scale(); y1 += offset_y_*scale();
-  int tw = line_width_ ? line_width_ : 1; // true line width
-  if (y > y1) { float exch = y; y = y1; y1 = exch; }
-  int ix = clip_xy(x+line_delta_);
-  int iy = clip_xy(y+line_delta_); if (scale() >= 2) iy -= int(scale()/2);
-  int iy1 = int(y1/scale()+1.5)*scale()-1;
-  // make sure that line output by yxline(a,b,c) extends to pixel just above where yxline(a,c+1,d) begins
-  iy1 += line_delta_; if (scale() >= 4) iy1 -= 1;
-  draw_clipped_line(ix, iy, ix, iy1);
-  // make sure no unfilled area lies between yxline(x,y,y1) and yxline(x+1,y,y1)
-  if (x+line_delta_+scale() >= ix + tw+1 -0.001)
-    draw_clipped_line(ix+1, iy, ix+1, iy1);
+void Fl_Xlib_Graphics_Driver::yxline_unscaled(int x, int y, int y1) {
+  if (line_width_ >= 2) y1++;
+  x += floor(offset_x_) ;
+  y += floor(offset_y_) ;
+  y1 += floor(offset_y_) ;
+  draw_clipped_line(x, y, x, y1);
 }
 
-void Fl_Xlib_Graphics_Driver::loop_unscaled(float x, float y, float x1, float y1, float x2, float y2) {
+void Fl_Xlib_Graphics_Driver::loop_unscaled(int x, int y, int x1, int y1, int x2, int y2) {
   XPoint p[4];
-  p[0].x = x +offset_x_*scale()+line_delta_;  p[0].y = y +offset_y_*scale()+line_delta_;
-  p[1].x = x1 +offset_x_*scale()+line_delta_; p[1].y = y1 +offset_y_*scale()+line_delta_;
-  p[2].x = x2 +offset_x_*scale()+line_delta_; p[2].y = y2 +offset_y_*scale()+line_delta_;
-  p[3].x = x +offset_x_*scale()+line_delta_;  p[3].y = y +offset_y_*scale()+line_delta_;
+  p[0].x = x + floor(offset_x_) ;  p[0].y = y + floor(offset_y_) ;
+  p[1].x = x1 + floor(offset_x_) ; p[1].y = y1 + floor(offset_y_) ;
+  p[2].x = x2 + floor(offset_x_) ; p[2].y = y2 + floor(offset_y_) ;
+  p[3].x = p[0].x;  p[3].y = p[0].y;
   // *FIXME* This needs X coordinate clipping!
   XDrawLines(fl_display, fl_window, gc_, p, 4, 0);
 }
 
-void Fl_Xlib_Graphics_Driver::loop_unscaled(float x, float y, float x1, float y1, float x2, float y2, float x3, float y3) {
+void Fl_Xlib_Graphics_Driver::loop_unscaled(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
   XPoint p[5];
-  p[0].x = x+offset_x_*scale()+line_delta_;  p[0].y = y+offset_y_*scale()+line_delta_;
-  p[1].x = x1 +offset_x_*scale()+line_delta_; p[1].y = y1+offset_y_*scale()+line_delta_;
-  p[2].x = x2+offset_x_*scale()+line_delta_; p[2].y = y2+offset_y_*scale()+line_delta_;
-  p[3].x = x3+offset_x_*scale()+line_delta_; p[3].y = y3+offset_y_*scale()+line_delta_;
-  p[4].x = x+offset_x_*scale()+line_delta_;  p[4].y = y+offset_y_*scale()+line_delta_;
+  p[0].x = x + floor(offset_x_) ;  p[0].y = y + floor(offset_y_) ;
+  p[1].x = x1 + floor(offset_x_) ; p[1].y = y1 + floor(offset_y_) ;
+  p[2].x = x2 + floor(offset_x_) ; p[2].y = y2 + floor(offset_y_) ;
+  p[3].x = x3 + floor(offset_x_) ; p[3].y = y3 + floor(offset_y_) ;
+  p[4].x = p[0].x;  p[4].y = p[0].y;
   // *FIXME* This needs X coordinate clipping!
   XDrawLines(fl_display, fl_window, gc_, p, 5, 0);
 }
 
-void Fl_Xlib_Graphics_Driver::polygon_unscaled(float x, float y, float x1, float y1, float x2, float y2) {
+void Fl_Xlib_Graphics_Driver::polygon_unscaled(int x, int y, int x1, int y1, int x2, int y2) {
   XPoint p[4];
-  p[0].x = x+offset_x_*scale()+line_delta_;  p[0].y = y+offset_y_*scale()+line_delta_;
-  p[1].x = x1+offset_x_*scale()+line_delta_; p[1].y = y1+offset_y_*scale()+line_delta_;
-  p[2].x = x2+offset_x_*scale()+line_delta_; p[2].y = y2+offset_y_*scale()+line_delta_;
-  p[3].x = x+offset_x_*scale()+line_delta_;  p[3].y = y+offset_y_*scale()+line_delta_;
+  p[0].x = x + floor(offset_x_) ;  p[0].y = y + floor(offset_y_) ;
+  p[1].x = x1 + floor(offset_x_) ; p[1].y = y1 + floor(offset_y_) ;
+  p[2].x = x2 + floor(offset_x_) ; p[2].y = y2 + floor(offset_y_) ;
+  p[3].x = p[0].x;  p[3].y = p[0].y;
   // *FIXME* This needs X coordinate clipping!
   XFillPolygon(fl_display, fl_window, gc_, p, 3, Convex, 0);
   XDrawLines(fl_display, fl_window, gc_, p, 4, 0);
 }
 
-void Fl_Xlib_Graphics_Driver::polygon_unscaled(float x, float y, float x1, float y1, float x2, float y2, float x3, float y3) {
+void Fl_Xlib_Graphics_Driver::polygon_unscaled(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
   XPoint p[5];
-  p[0].x = x+offset_x_*scale()+line_delta_;  p[0].y = y+offset_y_*scale()+line_delta_;
-  p[1].x = x1+offset_x_*scale()+line_delta_; p[1].y = y1+offset_y_*scale()+line_delta_;
-  p[2].x = x2+offset_x_*scale()+line_delta_; p[2].y = y2+offset_y_*scale()+line_delta_;
-  p[3].x = x3+offset_x_*scale()+line_delta_; p[3].y = y3+offset_y_*scale()+line_delta_;
-  p[4].x = x+offset_x_*scale()+line_delta_;  p[4].y = y+offset_y_*scale()+line_delta_;
+  p[0].x = x + floor(offset_x_) ;  p[0].y = y + floor(offset_y_) ;
+  p[1].x = x1 + floor(offset_x_) ; p[1].y = y1 + floor(offset_y_) ;
+  p[2].x = x2 + floor(offset_x_) ; p[2].y = y2 + floor(offset_y_) ;
+  p[3].x = x3 + floor(offset_x_) ; p[3].y = y3 + floor(offset_y_) ;
+  p[4].x = p[0].x;  p[4].y = p[0].y;
   // *FIXME* This needs X coordinate clipping!
   XFillPolygon(fl_display, fl_window, gc_, p, 4, Convex, 0);
   XDrawLines(fl_display, fl_window, gc_, p, 5, 0);
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx src/drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx
index 2f1608d..59b3e58 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx
@@ -43,7 +43,7 @@ void Fl_Xlib_Graphics_Driver::end_line() {
 void Fl_Xlib_Graphics_Driver::end_loop() {
   fixloop();
   if (n>2) {
-    transformed_vertex0(p[0].x - line_delta_, p[0].y - line_delta_);
+    transformed_vertex0(p[0].x , p[0].y );
   }
   end_line();
 }
@@ -60,7 +60,7 @@ void Fl_Xlib_Graphics_Driver::end_polygon() {
 void Fl_Xlib_Graphics_Driver::gap() {
   while (n>gap_+2 && p[n-1].x == p[gap_].x && p[n-1].y == p[gap_].y) n--;
   if (n > gap_+2) {
-    transformed_vertex0(p[gap_].x - line_delta_, p[gap_].y - line_delta_);
+    transformed_vertex0(p[gap_].x, p[gap_].y);
     gap_ = n;
   } else {
     n = gap_;
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'.