summaryrefslogtreecommitdiff
path: root/src/drivers/GDI
diff options
context:
space:
mode:
authorManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2021-03-11 16:05:20 +0100
committerManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2021-03-11 16:05:32 +0100
commit569fec25e0454c4e4b98dcc383143a357ca50b55 (patch)
treec38048366a56a901a66465fdaca6628d0e03405a /src/drivers/GDI
parentbd6c9854342094e2de8183aaab740804c1a6fc1f (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.cxx2
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver.H41
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx8
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_arci.cxx7
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx7
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx145
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);
}