From c32d6a511a3cfaac68050ba311c30be7b04949bb Mon Sep 17 00:00:00 2001 From: cxl Date: Sun, 18 Jan 2009 12:18:30 +0000 Subject: [PATCH] Painter: fixed stroke bug git-svn-id: svn://ultimatepp.org/upp/trunk@783 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Painter/BufferPainter.h | 8 ++++++- uppsrc/Painter/Fill.cpp | 4 ++-- uppsrc/Painter/Stroke.cpp | 44 ++++++++++++++++++---------------- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/uppsrc/Painter/BufferPainter.h b/uppsrc/Painter/BufferPainter.h index 7d8a1f5bd..0174bea5b 100644 --- a/uppsrc/Painter/BufferPainter.h +++ b/uppsrc/Painter/BufferPainter.h @@ -224,6 +224,11 @@ private: Rectf pathrect; Pointf current, ccontrol, qcontrol; + struct StrokeInfo { + bool evenodd; + path_storage path; + }; + void PathPoint0(double x, double y); void PathPoint(double& x, double& y, bool rel); void EndPoint(double& x, double& y, bool rel); @@ -231,7 +236,8 @@ private: bool PathVisible(double d) const; Pointf Current() const { return current; } Rectf PathRect() const { return pathrect; } - path_storage MakeStroke(double width); + StrokeInfo BeginStroke(double width); + void EndStroke(StrokeInfo& f); Pointf ReadPoint(CParser& p, bool rel); void RenderClip(byte *t); void MakeGradient(RGBA *t, RGBA color1, RGBA color2, int cx); diff --git a/uppsrc/Painter/Fill.cpp b/uppsrc/Painter/Fill.cpp index 1e0c2086d..7458e41d8 100644 --- a/uppsrc/Painter/Fill.cpp +++ b/uppsrc/Painter/Fill.cpp @@ -76,7 +76,7 @@ struct UppImageAggSpan { x = minmax(x, 0, maxx); else if(hstyle == FILL_HREFLECT) - x = (x + ax) / cx & 1 ? (x + ax) % cx : (ax - x - 1) % cx; + x = (x + ax) / cx & 1 ? (ax - x - 1) % cx : (x + ax) % cx; else if(hstyle == FILL_HREPEAT) x = (x + ax) % cx; @@ -84,7 +84,7 @@ struct UppImageAggSpan { y = minmax(y, 0, maxy); else if(vstyle == FILL_VREFLECT) - y = (y + ay) / cy & 1 ? (y + ay) % cy : (ay - y - 1) % cy; + y = (y + ay) / cy & 1 ? (ay - y - 1) % cy : (y + ay) % cy; else if(vstyle == FILL_VREPEAT) y = (y + ay) % cy; diff --git a/uppsrc/Painter/Stroke.cpp b/uppsrc/Painter/Stroke.cpp index d71c3abb7..0643584d2 100644 --- a/uppsrc/Painter/Stroke.cpp +++ b/uppsrc/Painter/Stroke.cpp @@ -2,14 +2,14 @@ NAMESPACE_UPP -BufferPainter::path_storage BufferPainter::MakeStroke(double width) +BufferPainter::StrokeInfo BufferPainter::BeginStroke(double width) { + StrokeInfo f; double scl = pathattr.mtx.scale(); curved.approximation_scale(scl); curved.angle_tolerance(0.0); if(width * scl > 1.0) curved.angle_tolerance(0.2); - path_storage b; if(pathattr.dash.GetCount()) { agg::conv_dash dashed(curved); dashed.Set(&pathattr.dash, pathattr.dash_start); @@ -19,7 +19,7 @@ BufferPainter::path_storage BufferPainter::MakeStroke(double width) curved_stroked.line_cap((agg::line_cap_e)pathattr.cap); curved_stroked.miter_limit(pathattr.miter_limit); curved_stroked.approximation_scale(scl); - b.concat_path(curved_stroked); + f.path.concat_path(curved_stroked); } else { agg::conv_stroke curved_stroked(curved); @@ -28,47 +28,49 @@ BufferPainter::path_storage BufferPainter::MakeStroke(double width) curved_stroked.line_cap((agg::line_cap_e)pathattr.cap); curved_stroked.miter_limit(pathattr.miter_limit); curved_stroked.approximation_scale(scl); - b.concat_path(curved_stroked); + f.path.concat_path(curved_stroked); } - return b; + Swap(f.path, path); + f.evenodd = pathattr.evenodd; + pathattr.evenodd = false; + inpath = false; + return f; +} + +void BufferPainter::EndStroke(StrokeInfo& f) +{ + Swap(f.path, path); + pathattr.evenodd = f.evenodd; } void BufferPainter::StrokeOp(double width, const RGBA& color) { - path_storage b = MakeStroke(width); - Swap(b, path); - inpath = false; + StrokeInfo f = BeginStroke(width); Fill(color); - Swap(b, path); + EndStroke(f); } void BufferPainter::StrokeOp(double width, const Image& image, const Matrix2D& transsrc, dword flags) { - path_storage b = MakeStroke(width); - Swap(b, path); - inpath = false; + StrokeInfo f = BeginStroke(width); Fill(image, transsrc, flags); - Swap(b, path); + EndStroke(f); } void BufferPainter::StrokeOp(double width, double x1, double y1, const RGBA& color1, double x2, double y2, const RGBA& color2, int style) { - path_storage b = MakeStroke(width); - Swap(b, path); - inpath = false; + StrokeInfo f = BeginStroke(width); Fill(x1, y1, color1, x2, y2, color2, style); - Swap(b, path); + EndStroke(f); } void BufferPainter::StrokeOp(double width, double fx, double fy, const RGBA& color1, double x, double y, double r, const RGBA& color2, int style) { - path_storage b = MakeStroke(width); - Swap(b, path); - inpath = false; + StrokeInfo f = BeginStroke(width); Fill(fx, fy, color1, x, y, r, color2, style); - Swap(b, path); + EndStroke(f); } END_UPP_NAMESPACE