From 83efc68a28ff563798c3cd0859f28c10bcb937bb Mon Sep 17 00:00:00 2001 From: cxl Date: Sun, 21 Dec 2014 19:08:48 +0000 Subject: [PATCH] Painter: SVG related issues git-svn-id: svn://ultimatepp.org/upp/trunk@7988 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Painter/BufferPainter.h | 10 +++++++++- uppsrc/Painter/Gradient.cpp | 12 ++++++------ uppsrc/Painter/Image.cpp | 16 ++++++++++++---- uppsrc/Painter/PaintPainting.icpp | 18 ++++++++++++++++++ uppsrc/Painter/Painter.cpp | 29 ++++++++++++++++++++++++----- uppsrc/Painter/Painter.h | 16 ++++++++++++++++ uppsrc/Painter/Painting.cpp | 23 +++++++++++++++++++++++ uppsrc/Painter/Painting.h | 8 ++++++++ uppsrc/Painter/RadialGradient.cpp | 24 ++++++++++++++++++++---- uppsrc/Painter/Xform2D.cpp | 1 - 10 files changed, 136 insertions(+), 21 deletions(-) diff --git a/uppsrc/Painter/BufferPainter.h b/uppsrc/Painter/BufferPainter.h index fc0bcff6e..637a19ca0 100644 --- a/uppsrc/Painter/BufferPainter.h +++ b/uppsrc/Painter/BufferPainter.h @@ -229,6 +229,8 @@ protected: virtual void FillOp(const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style); + virtual void FillOp(const Pointf& f, const RGBA& color1, const RGBA& color2, + const Xform2D& transsrc, int style); virtual void StrokeOp(double width, const RGBA& rgba); virtual void StrokeOp(double width, const Image& image, const Xform2D& transsrc, @@ -242,6 +244,9 @@ protected: virtual void StrokeOp(double width, const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style); + virtual void StrokeOp(double width, const Pointf& f, + const RGBA& color1, const RGBA& color2, + const Xform2D& transsrc, int style); virtual void ClipOp(); @@ -351,7 +356,10 @@ private: void RenderImage(double width, const Image& image, const Xform2D& transsrc, dword flags); void RenderRadial(double width, const Pointf& f, const RGBA& color1, - const Pointf& c, double r, const RGBA& color2, int style); + const Pointf& c, double r, const RGBA& color2, + const Xform2D& m, int style); + void RenderRadial(double width, const Pointf& f, const RGBA& color1, const RGBA& color2, + const Xform2D& transsrc, int style); void MakeGradient(RGBA color1, RGBA color2, int cx); void Gradient(const RGBA& color1, const RGBA& color2, const Pointf& p1, const Pointf& p2); void ColorStop0(Attr& a, double pos, const RGBA& color); diff --git a/uppsrc/Painter/Gradient.cpp b/uppsrc/Painter/Gradient.cpp index 21765dafb..8c3ef4666 100644 --- a/uppsrc/Painter/Gradient.cpp +++ b/uppsrc/Painter/Gradient.cpp @@ -48,7 +48,7 @@ void BufferPainter::FillOp(const Pointf& p1, const RGBA& color1, const Pointf& p { Gradient(color1, color2, p1, p2); Fill(gradient, p1, p2, - FILL_VPAD | + FILL_VPAD | (style & FILL_FAST) | (style == GRADIENT_PAD ? FILL_HPAD : style == GRADIENT_REPEAT ? FILL_HREPEAT : FILL_HREFLECT)); } @@ -56,8 +56,8 @@ void BufferPainter::FillOp(const Pointf& p1, const RGBA& color1, const Pointf& p void BufferPainter::FillOp(const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style) { MakeGradient(color1, color2, 500); - Fill(gradient, transsrc * Xform2D::Scale(1.0 / 500), - FILL_VPAD | + Fill(gradient, Xform2D::Scale(1.0 / 500) * transsrc, + FILL_VPAD | (style & FILL_FAST) | (style == GRADIENT_PAD ? FILL_HPAD : style == GRADIENT_REPEAT ? FILL_HREPEAT : FILL_HREFLECT)); } @@ -66,7 +66,7 @@ void BufferPainter::StrokeOp(double width, const Pointf& p1, const RGBA& color1, { Gradient(color1, color2, p1, p2); Stroke(width, gradient, p1, p2, - FILL_VPAD | + FILL_VPAD | (style & FILL_FAST) | (style == GRADIENT_PAD ? FILL_HPAD : style == GRADIENT_REPEAT ? FILL_HREPEAT : FILL_HREFLECT)); } @@ -74,8 +74,8 @@ void BufferPainter::StrokeOp(double width, const Pointf& p1, const RGBA& color1, void BufferPainter::StrokeOp(double width, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style) { MakeGradient(color1, color2, 500); - Stroke(width, gradient, transsrc * Xform2D::Scale(1.0 / 500), - FILL_VPAD | + Stroke(width, gradient, Xform2D::Scale(1.0 / 500) * transsrc, + FILL_VPAD | (style & FILL_FAST) | (style == GRADIENT_PAD ? FILL_HPAD : style == GRADIENT_REPEAT ? FILL_HREPEAT : FILL_HREFLECT)); } diff --git a/uppsrc/Painter/Image.cpp b/uppsrc/Painter/Image.cpp index b2f3ab49b..9a0ad58e0 100644 --- a/uppsrc/Painter/Image.cpp +++ b/uppsrc/Painter/Image.cpp @@ -34,14 +34,15 @@ Image DownScale(const Image& img, int nx, int ny) ASSERT(nx > 0 && ny > 0); Size ssz = img.GetSize(); Size tsz = Size((ssz.cx + nx - 1) / nx, (ssz.cy + ny - 1) / ny); - int div = nx * ny; Buffer b(tsz.cx); ImageBuffer ib(tsz); RGBA *it = ~ib; int scx0 = ssz.cx / nx * nx; + Buffer div(tsz.cx); for(int yy = 0; yy < ssz.cy; yy += ny) { for(int i = 0; i < tsz.cx; i++) b[i].Clear(); + memset(div, 0, tsz.cx * sizeof(int)); for(int yi = 0; yi < ny; yi++) { int y = yy + yi; if(y < ssz.cy) { @@ -49,18 +50,25 @@ Image DownScale(const Image& img, int nx, int ny) const RGBA *e = s + scx0; const RGBA *e2 = s + ssz.cx; RGBAV *t = ~b; + int *dv = div; while(s < e) { - for(int n = nx; n--;) + for(int n = nx; n--;) { t->Put(*s++); + (*dv)++; + } t++; + dv++; } - while(s < e2) + while(s < e2) { t->Put(*s++); + (*dv)++; + } } } const RGBAV *s = ~b; + const int *dv = div; for(int x = 0; x < tsz.cx; x++) - *it++ = (s++)->Get(div); + *it++ = (s++)->Get(*dv++); } return ib; } diff --git a/uppsrc/Painter/PaintPainting.icpp b/uppsrc/Painter/PaintPainting.icpp index 5f97271df..c4cbd218d 100644 --- a/uppsrc/Painter/PaintPainting.icpp +++ b/uppsrc/Painter/PaintPainting.icpp @@ -123,6 +123,14 @@ void Painter::Paint(const Painting& pic) f = ss.Get(); FillOp(c, c1, m, f); break; + case PAINTING_FILL_RADIAL_X: + sGet(p1, ss); + sGet(c, ss); + sGet(c1, ss); + sGet(m, ss); + f = ss.Get(); + FillOp(p1, c, c1, m, f); + break; case PAINTING_FILL_RADIAL: sGet(p, ss); sGet(c, ss); @@ -166,6 +174,16 @@ void Painter::Paint(const Painting& pic) FillOp(c, c1, m, f); StrokeOp(w, c, c1, m, f); break; + case PAINTING_STROKE_RADIAL_X: + sGet(w, ss); + sGet(p1, ss); + sGet(c, ss); + sGet(c1, ss); + sGet(m, ss); + f = ss.Get(); + FillOp(c, c1, m, f); + StrokeOp(w, p1, c, c1, m, f); + break; case PAINTING_STROKE_RADIAL: sGet(w, ss); sGet(p, ss); diff --git a/uppsrc/Painter/Painter.cpp b/uppsrc/Painter/Painter.cpp index 15434780b..9d1b0c890 100644 --- a/uppsrc/Painter/Painter.cpp +++ b/uppsrc/Painter/Painter.cpp @@ -383,6 +383,18 @@ Painter& Painter::Fill(double x, double y, const RGBA& color1, double r, const R return Fill(Pointf(x, y), color1, r, color2, style); } +Painter& Painter::Fill(const Pointf& f, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style) +{ + FillOp(f, color1, color2, transsrc, style); + return *this; +} + +Painter& Painter::Stroke(double width, const Pointf& f, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style) +{ + StrokeOp(width, f, color1, color2, transsrc, style); + return *this; +} + Painter& Painter::Translate(double x, double y) { Transform(Xform2D::Translation(x, y)); @@ -534,13 +546,18 @@ Painter& Painter::Rectangle(double x, double y, double cx, double cy) Painter& Painter::RoundedRectangle(double x, double y, double cx, double cy, double r) { - ASSERT(r >= 0); + return RoundedRectangle(x, y, cx, cy, r, r); +} + +Painter& Painter::RoundedRectangle(double x, double y, double cx, double cy, double rx, double ry) +{ + ASSERT(rx >= 0 && ry >= 0); if (cx < 0) { x += cx; cx = -cx;} if (cy < 0) { y += cy; cy = -cy;} - Move(x + r, y).Arc(x + r, y + r, r, r, -M_PI / 2, -M_PI / 2) - .Line(x, y + cy - r).Arc(x + r, y + cy - r, r, r, M_PI, -M_PI / 2) - .Line(x + cx - r, y + cy).Arc(x + cx - r, y + cy - r, r, r, M_PI / 2, -M_PI / 2) - .Line(x + cx, y + r).Arc(x + cx - r, y + r, r, r, 0, -M_PI / 2).Line(x + r, y); + Move(x + rx, y).Arc(x + rx, y + ry, rx, ry, -M_PI / 2, -M_PI / 2) + .Line(x, y + cy - ry).Arc(x + rx, y + cy - ry, rx, ry, M_PI, -M_PI / 2) + .Line(x + cx - rx, y + cy).Arc(x + cx - rx, y + cy - ry, rx, ry, M_PI / 2, -M_PI / 2) + .Line(x + cx, y + ry).Arc(x + cx - rx, y + ry, rx, ry, 0, -M_PI / 2).Line(x + rx, y); return *this; } @@ -570,11 +587,13 @@ void NilPainter::FillOp(const Image& image, const Xform2D& transsrc, dword flags void NilPainter::FillOp(const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style) {} void NilPainter::FillOp(const Pointf& p1, const RGBA& color1, const Pointf& p2, const RGBA& color2, int style) {} void NilPainter::FillOp(const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style) {} +void NilPainter::FillOp(const Pointf& f, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style) {} void NilPainter::StrokeOp(double width, const RGBA& rgba) {} void NilPainter::StrokeOp(double width, const Image& image, const Xform2D& transsrc, dword flags) {} void NilPainter::StrokeOp(double width, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style) {} void NilPainter::StrokeOp(double width, const Pointf& p1, const RGBA& color1, const Pointf& p2, const RGBA& color2, int style) {} void NilPainter::StrokeOp(double width, const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style) {} +void NilPainter::StrokeOp(double width, const Pointf& f, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style) {} void NilPainter::ClipOp() {} void NilPainter::CharacterOp(const Pointf& p, int ch, Font fnt) {} void NilPainter::TextOp(const Pointf& p, const wchar *text, Font fnt, int n, double *dx) {} diff --git a/uppsrc/Painter/Painter.h b/uppsrc/Painter/Painter.h index 4e5520372..fa356a8f1 100644 --- a/uppsrc/Painter/Painter.h +++ b/uppsrc/Painter/Painter.h @@ -109,6 +109,8 @@ protected: int style) = 0; virtual void FillOp(const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style) = 0; + virtual void FillOp(const Pointf& f, const RGBA& color1, const RGBA& color2, + const Xform2D& transsrc, int style) = 0; virtual void StrokeOp(double width, const RGBA& rgba) = 0; virtual void StrokeOp(double width, const Image& image, const Xform2D& transsrc, @@ -121,6 +123,9 @@ protected: virtual void StrokeOp(double width, const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style) = 0; + virtual void StrokeOp(double width, const Pointf& f, + const RGBA& color1, const RGBA& color2, + const Xform2D& transsrc, int style) = 0; virtual void ClipOp() = 0; @@ -251,6 +256,8 @@ public: double r, const RGBA& color2, int style = GRADIENT_PAD); Painter& Fill(double x, double y, const RGBA& color1, double r, const RGBA& color2, int style = GRADIENT_PAD); + Painter& Fill(const Pointf& f, const RGBA& color1, const RGBA& color2, + const Xform2D& transsrc, int style = GRADIENT_PAD); Painter& Stroke(double width, const RGBA& color); Painter& Stroke(double width, const Image& image, const Xform2D& transsrc, dword flags = 0); @@ -272,6 +279,9 @@ public: double r, const RGBA& color2, int style = GRADIENT_PAD); Painter& Stroke(double width, double x, double y, const RGBA& color1, double r, const RGBA& color2, int style = GRADIENT_PAD); + Painter& Stroke(double width, const Pointf& f, + const RGBA& color1, const RGBA& color2, + const Xform2D& transsrc, int style = GRADIENT_PAD); Painter& Clip(); @@ -314,6 +324,7 @@ public: Painter& Rectangle(double x, double y, double cx, double cy); Painter& RoundedRectangle(double x, double y, double cx, double cy, double r); + Painter& RoundedRectangle(double x, double y, double cx, double cy, double r1, double r2); Painter& Ellipse(double x, double y, double rx, double ry); Painter& Circle(double x, double y, double r); @@ -378,6 +389,8 @@ protected: virtual void FillOp(const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style); + virtual void FillOp(const Pointf& f, const RGBA& color1, const RGBA& color2, + const Xform2D& transsrc, int style); virtual void StrokeOp(double width, const RGBA& rgba); virtual void StrokeOp(double width, const Image& image, const Xform2D& transsrc, @@ -391,6 +404,9 @@ protected: virtual void StrokeOp(double width, const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style); + virtual void StrokeOp(double width, const Pointf& f, + const RGBA& color1, const RGBA& color2, + const Xform2D& transsrc, int style); virtual void ClipOp(); diff --git a/uppsrc/Painter/Painting.cpp b/uppsrc/Painter/Painting.cpp index 558e36827..5baeb1f0e 100644 --- a/uppsrc/Painter/Painting.cpp +++ b/uppsrc/Painter/Painting.cpp @@ -111,6 +111,29 @@ void PaintingPainter::FillOp(const RGBA& color1, const RGBA& color2, const Xform Put(style); } +void PaintingPainter::FillOp(const Pointf& f, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style) +{ + Put(PAINTING_FILL_RADIAL_X); + Putf(f); + Put(color1); + Put(color2); + Putf(transsrc); + Put(style); +} + +void PaintingPainter::StrokeOp(double width, const Pointf& f, const RGBA& color1, + const RGBA& color2, const Xform2D& transsrc, int style) +{ + Put(PAINTING_FILL_RADIAL_X); + Putf(width); + Putf(f); + Put(color1); + Put(color2); + Putf(transsrc); + Put(style); +} + + void PaintingPainter::FillOp(const Pointf& f, const RGBA& color1, const Pointf& p, double r, const RGBA& color2, int style) { diff --git a/uppsrc/Painter/Painting.h b/uppsrc/Painter/Painting.h index 93e2f384b..b56b53bee 100644 --- a/uppsrc/Painter/Painting.h +++ b/uppsrc/Painter/Painting.h @@ -54,6 +54,9 @@ enum { PAINTING_FILL_GRADIENT_X, PAINTING_STROKE_GRADIENT_X, + + PAINTING_FILL_RADIAL_X, + PAINTING_STROKE_RADIAL_X, }; class PaintingPainter : public Painter { @@ -94,6 +97,8 @@ protected: virtual void FillOp(const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style); + virtual void FillOp(const Pointf& f, const RGBA& color1, const RGBA& color2, + const Xform2D& transsrc, int style); virtual void StrokeOp(double width, const RGBA& rgba); virtual void StrokeOp(double width, const Image& image, const Xform2D& transsrc, @@ -106,6 +111,9 @@ protected: virtual void StrokeOp(double width, const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style); + virtual void StrokeOp(double width, const Pointf& f, + const RGBA& color1, const RGBA& color2, + const Xform2D& transsrc, int style); virtual void ClipOp(); diff --git a/uppsrc/Painter/RadialGradient.cpp b/uppsrc/Painter/RadialGradient.cpp index 1a180709e..798e8fd2a 100644 --- a/uppsrc/Painter/RadialGradient.cpp +++ b/uppsrc/Painter/RadialGradient.cpp @@ -55,10 +55,10 @@ struct PainterRadialSpan : SpanSource { }; void BufferPainter::RenderRadial(double width, const Pointf& f, const RGBA& color1, - const Pointf& c, double r, const RGBA& color2, int style) + const Pointf& c, double r, const RGBA& color2, + const Xform2D& m, int style) { PainterRadialSpan sg; - Xform2D m = pathattr.mtx; sg.interpolator.Set(Inverse(m)); sg.style = style; sg.Set(c.x, c.y, r, f.x, f.y); @@ -69,12 +69,28 @@ void BufferPainter::RenderRadial(double width, const Pointf& f, const RGBA& colo void BufferPainter::FillOp(const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style) { - RenderRadial(-1, f, color1, c, r, color2, style); + RenderRadial(-1, f, color1, c, r, color2, pathattr.mtx, style); } void BufferPainter::StrokeOp(double width, const Pointf& f, const RGBA& color1, const Pointf& c, double r, const RGBA& color2, int style) { - RenderRadial(width, f, color1, c, r, color2, style); + RenderRadial(width, f, color1, c, r, color2, pathattr.mtx, style); +} + +void BufferPainter::RenderRadial(double width, const Pointf& f, const RGBA& color1, + const RGBA& color2, const Xform2D& transsrc, int style) +{ + RenderRadial(width, f, color1, Pointf(0, 0), 1, color2, transsrc * pathattr.mtx, style); +} + +void BufferPainter::FillOp(const Pointf& f, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style) +{ + RenderRadial(-1, f, color1, color2, transsrc, style); +} + +void BufferPainter::StrokeOp(double width, const Pointf& f, const RGBA& color1, const RGBA& color2, const Xform2D& transsrc, int style) +{ + RenderRadial(width, f, color1, color2, transsrc, style); } END_UPP_NAMESPACE diff --git a/uppsrc/Painter/Xform2D.cpp b/uppsrc/Painter/Xform2D.cpp index 479c3ccdd..f28d6e784 100644 --- a/uppsrc/Painter/Xform2D.cpp +++ b/uppsrc/Painter/Xform2D.cpp @@ -51,7 +51,6 @@ Xform2D operator*(const Xform2D& a, const Xform2D& b) Xform2D Xform2D::Translation(double x, double y) { Xform2D m; - m.x.x = m.y.y = 1; m.t = Pointf(x, y); return m; }