summaryrefslogtreecommitdiff
path: root/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx
diff options
context:
space:
mode:
authorManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2021-02-26 18:00:07 +0100
committerManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2021-05-31 08:28:06 +0200
commitb027d2ba57a8e0d6f0862e0a891ddd5dee4b02e2 (patch)
tree3ed894bd9a891337804367a09de500ff060be640 /src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx
parentd95dd7acc4af3a4bd521d151ba3576b91d8ace53 (diff)
Windows platform: use GDI+ to antialias oblique lines and curves.
Diffstat (limited to 'src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx')
-rw-r--r--src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx
index e7aac901c..76b546092 100644
--- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx
+++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx
@@ -211,3 +211,95 @@ void Fl_GDI_Graphics_Driver::restore_clip() {
if (r) unscale_clip(r);
}
}
+
+#if USE_GDIPLUS
+
+void Fl_GDIplus_Graphics_Driver::line(int x, int y, int x1, int y1) {
+ if (!active) return Fl_Scalable_Graphics_Driver::line(x, y, x1, y1);
+ bool AA = !(x == x1 || y == y1);
+ Gdiplus::Graphics graphics_(gc_);
+ graphics_.ScaleTransform(scale(), scale());
+ pen_->SetColor(gdiplus_color_);
+ if (AA) graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
+ graphics_.DrawLine(pen_, x, y, x1, y1);
+}
+
+void Fl_GDIplus_Graphics_Driver::line(int x, int y, int x1, int y1, int x2, int y2) {
+ if (!active) return Fl_Scalable_Graphics_Driver::line(x, y, x1, y1, x2, y2);
+ line(x, y, x1, y1);
+ line(x1, y1, x2, y2);
+}
+
+void Fl_GDIplus_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2) {
+ if (!active) return Fl_Scalable_Graphics_Driver::loop(x0, y0, x1, y1, x2, y2);
+ Gdiplus::GraphicsPath path;
+ Gdiplus::Point gdi2_p[3] = {Gdiplus::Point(x0, y0), Gdiplus::Point(x1, y1), Gdiplus::Point(x2, y2)};
+ path.AddLines(gdi2_p, 3);
+ path.CloseFigure();
+ Gdiplus::Graphics graphics_(gc_);
+ graphics_.ScaleTransform(scale(), scale());
+ pen_->SetColor(gdiplus_color_);
+ graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
+ graphics_.DrawPath(pen_, &path);
+}
+
+#define fl_min(a,b) (a < b ? a : b)
+#define fl_max(a,b) (a > b ? a : b)
+void Fl_GDIplus_Graphics_Driver::loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
+ if ( (x0 == x3 && x1 == x2 && y0 == y1 && y3 == y2) ||
+ (x0 == x1 && y1 == y2 && x2 == x3 && y3 == y0) ) { // rectangular loop
+ int left = fl_min(x0, fl_min(x1, fl_min(x2, x3)));
+ int right = fl_max(x0, fl_max(x1, fl_max(x2, x3)));
+ int top = fl_min(y0, fl_min(y1, fl_min(y2, y3)));
+ int bottom = fl_max(y0, fl_max(y1, fl_max(y2, y3)));
+ rect(left, top, right-left+1, bottom-top+1);
+ } else {
+ if (!active) return Fl_Scalable_Graphics_Driver::loop(x0, y0, x1, y1, x2, y2, x3, y3);
+ Gdiplus::GraphicsPath path;
+ Gdiplus::PointF gdi2_p[4] = {Gdiplus::PointF(x0+1-line_width_/2.f, y0+1-line_width_/2.f), Gdiplus::PointF(x1+1-line_width_/2.f, y1+1-line_width_/2.f), Gdiplus::PointF(x2+1-line_width_/2.f, y2+1-line_width_/2.f), Gdiplus::PointF(x3+1-line_width_/2.f, y3+1-line_width_/2.f)};
+ path.AddLines(gdi2_p, 4);
+ path.CloseFigure();
+ Gdiplus::Graphics graphics_(gc_);
+ graphics_.ScaleTransform(scale(), scale());
+ pen_->SetColor(gdiplus_color_);
+ graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
+ graphics_.DrawPath(pen_, &path);
+ }
+}
+
+void Fl_GDIplus_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2) {
+ if (!active) return Fl_Scalable_Graphics_Driver::polygon(x0, y0, x1, y1, x2, y2);
+ Gdiplus::GraphicsPath path;
+ path.AddLine(x0, y0, x1, y1);
+ path.AddLine(x1, y1, x2, y2);
+ path.CloseFigure();
+ Gdiplus::Graphics graphics_(gc_);
+ graphics_.ScaleTransform(scale(), scale());
+ brush_->SetColor(gdiplus_color_);
+ graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
+ graphics_.FillPath(brush_, &path);
+}
+
+void Fl_GDIplus_Graphics_Driver::polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
+ if ( (x0 == x3 && x1 == x2 && y0 == y1 && y3 == y2) ||
+ (x0 == x1 && y1 == y2 && x2 == x3 && y3 == y0) ) {
+ int left = fl_min(x0, fl_min(x1, fl_min(x2, x3)));
+ int right = fl_max(x0, fl_max(x1, fl_max(x2, x3)));
+ int top = fl_min(y0, fl_min(y1, fl_min(y2, y3)));
+ int bottom = fl_max(y0, fl_max(y1, fl_max(y2, y3)));
+ rectf(left, top, right-left, bottom-top);
+ } else {
+ if (!active) return Fl_Scalable_Graphics_Driver::polygon(x0, y0, x1, y1, x2, y2, x3, y3);
+ Gdiplus::GraphicsPath path;
+ path.AddLine(x0, y0, x1, y1);
+ path.AddLine(x1, y1, x2, y2);
+ path.AddLine(x2, y2, x3, y3);
+ path.CloseFigure();
+ Gdiplus::Graphics graphics_(gc_);
+ graphics_.ScaleTransform(scale(), scale());
+ brush_->SetColor(gdiplus_color_);
+ graphics_.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
+ graphics_.FillPath(brush_, &path);
+ }
+}
+#endif