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