From 569fec25e0454c4e4b98dcc383143a357ca50b55 Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Thu, 11 Mar 2021 16:05:20 +0100 Subject: [PATCH] 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 ++++++++++-------- .../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 +- .../GDI/Fl_GDI_Graphics_Driver_arci.cxx | 7 +- .../GDI/Fl_GDI_Graphics_Driver_line_style.cxx | 7 +- .../GDI/Fl_GDI_Graphics_Driver_rect.cxx | 145 +++++--------- .../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 +-- .../Xlib/Fl_Xlib_Graphics_Driver_arci.cxx | 19 +- .../Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx | 20 +- .../Xlib/Fl_Xlib_Graphics_Driver_image.cxx | 23 +-- .../Fl_Xlib_Graphics_Driver_line_style.cxx | 18 +- .../Xlib/Fl_Xlib_Graphics_Driver_rect.cxx | 145 ++++++-------- .../Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx | 4 +- 18 files changed, 317 insertions(+), 405 deletions(-) diff --git a/FL/Fl_Graphics_Driver.H b/FL/Fl_Graphics_Driver.H index 845b416d5..974f1be3c 100644 --- a/FL/Fl_Graphics_Driver.H +++ b/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 a/src/Fl_Graphics_Driver.cxx b/src/Fl_Graphics_Driver.cxx index f1164c19e..5386d5290 100644 --- a/src/Fl_Graphics_Driver.cxx +++ b/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(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::line_unscaled(float x, float y, float x1, float y1, float x2, float y2) {} +void Fl_Scalable_Graphics_Driver::xyline_unscaled(int x, int y, int x1) {} -void Fl_Scalable_Graphics_Driver::xyline_unscaled(float x, float y, float x1) {} +void Fl_Scalable_Graphics_Driver::yxline_unscaled(int x, int y, int y1) {} -void Fl_Scalable_Graphics_Driver::yxline_unscaled(float x, float y, float y1) {} +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) {} +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::loop_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) {} -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(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 a/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx b/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx index b73c72e8d..9ba2db85f 100644 --- a/src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx +++ b/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 a/src/drivers/GDI/Fl_GDI_Graphics_Driver.H b/src/drivers/GDI/Fl_GDI_Graphics_Driver.H index 4ec7bce82..cf8ae3e98 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.H +++ b/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 a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx index 09dd6fa45..3fe721907 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx +++ b/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 a/src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx index 9bd3aaa44..32a5c1689 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx @@ -30,8 +30,9 @@ #include #include -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 a/src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx index 18fba5fb8..2cf6d8260 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx +++ b/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 a/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx index 4a8daebb1..e7aac901c 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx +++ b/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); + return 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::reset_pen_width(void *data) { + DeleteObject(SelectObject(gc_, (HPEN)data)); } -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_unscaled(int x, int y, int x1) { + MoveToEx(gc_, x, y, 0L); + LineTo(gc_, x1+1 , y); } -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); +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::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::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::yxline(int x, int y, int y1, int x2) { - yxline(x, y, y1); - xyline(x, y1, x2); +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::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::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(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::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 a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx index eb437b965..5747f16a4 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx +++ b/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 a/src/drivers/X11/Fl_X11_Screen_Driver.cxx b/src/drivers/X11/Fl_X11_Screen_Driver.cxx index 33f087d36..f9242671f 100644 --- a/src/drivers/X11/Fl_X11_Screen_Driver.cxx +++ b/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 a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H index b59365795..7ee34a9b5 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H +++ b/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 a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx index 3bb14e93c..6401efa97 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx +++ b/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 a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx index 381ac0d97..4897cf723 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx +++ b/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 a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx index 2f38a8275..a8039df46 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx +++ b/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 a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx index 9361e5d4a..9b2fc6970 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx +++ b/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 a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx index 606b82920..1aaeceea1 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx +++ b/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 a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx index 4a2b48af9..7bf905fd5 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx +++ b/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; +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(int x, int y, int w, int h) { + x += floor(offset_x_); + y += floor(offset_y_); if (!clip_rect(x, y, w, h)) - XDrawRectangle(fl_display, fl_window, gc_, x+line_delta_, y+line_delta_, w, h); + XFillRectangle(fl_display, fl_window, gc_, x, y, w, h); } -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); - 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::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::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); +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::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::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::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::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::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::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 a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx index 2f1608d13..59b3e58eb 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx +++ b/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_;