diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2021-03-11 16:05:20 +0100 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2021-03-11 16:05:32 +0100 |
| commit | 569fec25e0454c4e4b98dcc383143a357ca50b55 (patch) | |
| tree | c38048366a56a901a66465fdaca6628d0e03405a /src/drivers/GDI | |
| parent | bd6c9854342094e2de8183aaab740804c1a6fc1f (diff) | |
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.
Diffstat (limited to 'src/drivers/GDI')
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Copy_Surface_Driver.cxx | 2 | ||||
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Graphics_Driver.H | 41 | ||||
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx | 8 | ||||
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx | 7 | ||||
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx | 7 | ||||
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx | 145 |
6 files changed, 69 insertions, 141 deletions
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 <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 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); -} - -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); } |
