From 76bf9232b0a508381bb454e2de90bfa0c623465d Mon Sep 17 00:00:00 2001 From: cxl Date: Thu, 15 Jan 2009 00:19:15 +0000 Subject: [PATCH] Painting, PaintingPainter, Painter::Paint(Painting) git-svn-id: svn://ultimatepp.org/upp/trunk@747 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Painter/PaintPainting.cpp | 226 +++++++++++++++++++++++++++++ uppsrc/Painter/Painter.h | 9 +- uppsrc/Painter/Painter.upp | 3 + uppsrc/Painter/Painting.cpp | 236 +++++++++++++++++++++++++++++++ uppsrc/Painter/Painting.h | 124 ++++++++++++++++ 5 files changed, 597 insertions(+), 1 deletion(-) create mode 100644 uppsrc/Painter/PaintPainting.cpp create mode 100644 uppsrc/Painter/Painting.cpp create mode 100644 uppsrc/Painter/Painting.h diff --git a/uppsrc/Painter/PaintPainting.cpp b/uppsrc/Painter/PaintPainting.cpp new file mode 100644 index 000000000..b6a7feee0 --- /dev/null +++ b/uppsrc/Painter/PaintPainting.cpp @@ -0,0 +1,226 @@ +#include "Painter.h" + +NAMESPACE_UPP + +template +void sGet(T& r, StringStream& ss) +{ + ss.Get(&r, sizeof(T)); +} + + +template +T sGet(StringStream& ss) +{ + T r; + ss.Get(&r, sizeof(T)); + return r; +} + +inline +Pointf sGetPoint(StringStream& ss) +{ + Pointf p; + p.x = sGet(ss); + p.y = sGet(ss); + return p; +} + +void Painter::Paint(const Painting& pic) +{ + StringStream ss(pic.cmd); + Pointf p, p1, p2; + Color c, c1; + Value v; + int f, ch, n, hasdx; + Matrix2D m; + double r, w; + Font fnt; + int ii = 0; + for(;;) { + int cmd = ss.Get(); + if(cmd < 0) + return; + bool rel = cmd & 1; + switch(cmd) { + case PAINTING_CLEAR: + Clear(sGet(ss)); + break; + case PAINTING_MOVE: + case PAINTING_MOVE_REL: + p = sGetPoint(ss); + Move(p.x, p.y, rel); + break; + case PAINTING_LINE: + case PAINTING_LINE_REL: + p = sGetPoint(ss); + Line(p.x, p.y, rel); + break; + case PAINTING_QUADRATIC: + case PAINTING_QUADRATIC_REL: + p1 = sGetPoint(ss); + p = sGetPoint(ss); + Quadratic(p1.x, p1.y, p.x, p.y, rel); + break; + case PAINTING_QUADRATIC_S: + case PAINTING_QUADRATIC_S_REL: + p = sGetPoint(ss); + Quadratic(p.x, p.y, rel); + break; + case PAINTING_CUBIC: + case PAINTING_CUBIC_REL: + p1 = sGetPoint(ss); + p2 = sGetPoint(ss); + p = sGetPoint(ss); + Cubic(p1.x, p1.y, p2.x, p2.y, p.x, p.y, rel); + break; + case PAINTING_CUBIC_S: + case PAINTING_CUBIC_S_REL: + p2 = sGetPoint(ss); + p = sGetPoint(ss); + Cubic(p2.x, p2.y, p.x, p.y, rel); + break; + case PAINTING_CLOSE: + Close(); + break; + case PAINTING_FILL_SOLID: + Fill(sGet(ss)); + break; + case PAINTING_FILL_IMAGE: + sGet(m, ss); + f = ss.Get(); + if(ii >= pic.data.GetCount()) + return; + v = pic.data[ii++]; + if(!v.Is()) + return; + Fill((Image)v, m, f); + break; + case PAINTING_FILL_GRADIENT: + p = sGetPoint(ss); + sGet(c, ss); + p1 = sGetPoint(ss); + sGet(c1, ss); + f = ss.Get(); + Fill(p.x, p.y, c, p1.x, p1.y, c1, f); + break; + case PAINTING_FILL_RADIAL: + p = sGetPoint(ss); + sGet(c, ss); + p1 = sGetPoint(ss); + sGet(r, ss); + sGet(c1, ss); + f = ss.Get(); + Fill(p.x, p.y, c, p1.x, p1.y, r, c1, f); + break; + case PAINTING_STROKE_SOLID: + sGet(w, ss); + sGet(c, ss); + Stroke(w, c); + break; + case PAINTING_STROKE_IMAGE: + sGet(w, ss); + sGet(m, ss); + f = ss.Get(); + if(ii >= pic.data.GetCount()) + return; + v = pic.data[ii++]; + if(!v.Is()) + return; + Stroke(w, (Image)v, m, f); + break; + case PAINTING_STROKE_GRADIENT: + sGet(w, ss); + p = sGetPoint(ss); + sGet(c, ss); + p1 = sGetPoint(ss); + sGet(c1, ss); + f = ss.Get(); + Stroke(w, p.x, p.y, c, p1.x, p1.y, c1, f); + break; + case PAINTING_STROKE_RADIAL: + sGet(w, ss); + p = sGetPoint(ss); + sGet(c, ss); + p1 = sGetPoint(ss); + sGet(r, ss); + sGet(c1, ss); + f = ss.Get(); + Stroke(w, p.x, p.y, c, p1.x, p1.y, r, c1, f); + break; + case PAINTING_CLIP: + Clip(); + break; + case PAINTING_CHARACTER: + p = sGetPoint(ss); + ch = ss.Get32(); + sGet(fnt, ss); + Character(p.x, p.y, ch, fnt); + break; + case PAINTING_TEXT: + { + p = sGetPoint(ss); + n = ss.Get32(); + hasdx = ss.Get(); + sGet(fnt, ss); + Buffer txt(n); + Buffer dx(hasdx * n); + for(int i = 0; i < n; i++) { + txt[i] = ss.Get32(); + if(hasdx) + sGet(dx[i], ss); + } + Text(p.x, p.y, txt, fnt, n, hasdx ? ~dx : NULL); + } + break; + case PAINTING_COLORSTOP: + sGet(r, ss); + sGet(c, ss); + ColorStop(r, c); + break; + case PAINTING_CLEARSTOPS: + ClearStops(); + break; + case PAINTING_OPACITY: + Opacity(sGet(ss)); + break; + case PAINTING_LINECAP: + LineCap(ss.Get()); + break; + case PAINTING_LINEJOIN: + LineJoin(ss.Get()); + break; + case PAINTING_MITERLIMIT: + MiterLimit(ss.Get()); + break; + case PAINTING_EVENODD: + EvenOdd(ss.Get()); + break; + case PAINTING_DASH: + { + n = ss.Get32(); + Vector dash; + for(int i = 0; i < n; i++) + dash.Add(sGet(ss)); + r = sGet(ss); + Dash(dash, r); + } + break; + case PAINTING_TRANSFORM: + sGet(m, ss); + Transform(m); + break; + case PAINTING_BEGIN: + Begin(); + break; + case PAINTING_END: + End(); + break; + case PAINTING_BEGINMASK: + BeginMask(); + break; + } + } +} + +END_UPP_NAMESPACE \ No newline at end of file diff --git a/uppsrc/Painter/Painter.h b/uppsrc/Painter/Painter.h index 088f4165f..ee7cd6354 100644 --- a/uppsrc/Painter/Painter.h +++ b/uppsrc/Painter/Painter.h @@ -66,13 +66,15 @@ enum { FILL_REPEAT = FILL_HREPEAT|FILL_VREPEAT, FILL_REFLECT = FILL_HREFLECT|FILL_VREFLECT, - FILL_FAST = 256, + FILL_FAST = 128, GRADIENT_PAD = 0, GRADIENT_REPEAT = 1, GRADIENT_REFLECT = 2, }; +class Painting; + class Painter : public Draw { protected: virtual void OffsetOp(Point p); @@ -159,6 +161,8 @@ private: void RectPath(int x, int y, int cx, int cy); void RectPath(const Rect& r); + static RGBA GetRGBA(StringStream& ss); + public: void Clear(const RGBA& color); @@ -244,9 +248,12 @@ public: void Rotate(double a); void Scale(double scalex, double scaley); void Scale(double scale); + + void Paint(const Painting& p); }; #include "BufferPainter.h" +#include "Painting.h" END_UPP_NAMESPACE diff --git a/uppsrc/Painter/Painter.upp b/uppsrc/Painter/Painter.upp index dde3e3802..8707804cd 100644 --- a/uppsrc/Painter/Painter.upp +++ b/uppsrc/Painter/Painter.upp @@ -19,6 +19,9 @@ file Stroke.cpp, Clip.cpp, Mask.cpp, + Painting.h, + Painting.cpp, + PaintPainting.cpp, agg readonly separator, agg_array.h, agg_alpha_mask_u8.h, diff --git a/uppsrc/Painter/Painting.cpp b/uppsrc/Painter/Painting.cpp new file mode 100644 index 000000000..03136b5ed --- /dev/null +++ b/uppsrc/Painter/Painting.cpp @@ -0,0 +1,236 @@ +#include "Painter.h" + +NAMESPACE_UPP + +void PaintingPainter::ClearOp(const RGBA& color) +{ + Put(PAINTING_CLEAR); + Put(color); +} + +void PaintingPainter::MoveOp(double x, double y, bool rel) +{ + Put(PAINTING_MOVE + rel); + Putf(x, y); +} + +void PaintingPainter::LineOp(double x, double y, bool rel) +{ + Put(PAINTING_LINE + rel); + Putf(x, y); +} + +void PaintingPainter::QuadraticOp(double x1, double y1, double x, double y, bool rel) +{ + Put(PAINTING_QUADRATIC + rel); + Putf(x1, y1); + Putf(x, y); +} + +void PaintingPainter::QuadraticOp(double x, double y, bool rel) +{ + Put(PAINTING_QUADRATIC_S + rel); + Putf(x, y); +} + +void PaintingPainter::CubicOp(double x1, double y1, double x2, double y2, double x, double y, bool rel) +{ + Put(PAINTING_CUBIC + rel); + Putf(x1, y1); + Putf(x2, y2); + Putf(x, y); +} + +void PaintingPainter::CubicOp(double x2, double y2, double x, double y, bool rel) +{ + Put(PAINTING_CUBIC_S + rel); + Putf(x2, y2); + Putf(x, y); +} + +void PaintingPainter::CloseOp() +{ + Put(PAINTING_CLOSE); +} + +void PaintingPainter::FillOp(const RGBA& color) +{ + Put(PAINTING_FILL_SOLID); + Put(color); +} + +void PaintingPainter::FillOp(const Image& image, const Matrix2D& transsrc, dword flags) +{ + Put(PAINTING_FILL_IMAGE); + Putf(transsrc); + Put(flags); + data.Add(image); +} + +void PaintingPainter::FillOp(double x1, double y1, const RGBA& color1, double x2, double y2, const RGBA& color2, int style) +{ + Put(PAINTING_FILL_GRADIENT); + Putf(x1, y1); + Put(color1); + Putf(x2, y2); + Put(color2); + Put(style); +} + +void PaintingPainter::FillOp(double fx, double fy, const RGBA& color1, double x, double y, double r, const RGBA& color2, int style) +{ + Put(PAINTING_FILL_RADIAL); + Putf(fx, fy); + Put(color1); + Putf(x, y); + Putf(r); + Put(color2); + Put(style); +} + +void PaintingPainter::StrokeOp(double width, const RGBA& color) +{ + Put(PAINTING_STROKE_SOLID); + Putf(width); + Put(color); +} + +void PaintingPainter::StrokeOp(double width, const Image& image, const Matrix2D& transsrc, dword flags) +{ + Put(PAINTING_STROKE_IMAGE); + Putf(width); + Putf(transsrc); + Put(flags); + data.Add(image); +} + +void PaintingPainter::StrokeOp(double width, double x1, double y1, const RGBA& color1, double x2, double y2, const RGBA& color2, int style) +{ + Put(PAINTING_STROKE_GRADIENT); + Put(color1); + Put(color2); + Put(style); + Putf(width); + Putf(x1, y1); + Putf(x2, y2); +} + +void PaintingPainter::StrokeOp(double width, double fx, double fy, const RGBA& color1, double x, double y, double r, const RGBA& color2, int style) +{ + Put(PAINTING_STROKE_RADIAL); + Put(color1); + Put(color2); + Put(style); + Putf(width); + Putf(fx, fy); + Putf(x, y); + Putf(r); +} + +void PaintingPainter::ClipOp() +{ + Put(PAINTING_CLIP); +} + +void PaintingPainter::CharacterOp(double x, double y, int ch, Font fnt) +{ + Put(PAINTING_CHARACTER); + Put32(ch); + Put(fnt); +} + +void PaintingPainter::TextOp(double x, double y, const wchar *text, Font fnt, int n, double *dx) +{ + Put(PAINTING_TEXT); + Putf(x, y); + Put32(n); + Put((bool)dx); + Put(fnt); + for(int i = 0; i < n; i++) { + Put32(text[i]); + if(dx) + Putf(dx[i]); + } +} + +void PaintingPainter::ColorStopOp(double pos, const RGBA& color) +{ + Put(PAINTING_COLORSTOP); + Putf(pos); + Put(color); +} + +void PaintingPainter::ClearStopsOp() +{ + Put(PAINTING_CLEARSTOPS); +} + +void PaintingPainter::OpacityOp(double o) +{ + Put(PAINTING_OPACITY); + Putf(o); +} + +void PaintingPainter::LineCapOp(int linecap) +{ + Put(PAINTING_LINECAP); + Put(linecap); +} + +void PaintingPainter::LineJoinOp(int linejoin) +{ + Put(PAINTING_LINEJOIN); + Put(linejoin); +} + +void PaintingPainter::MiterLimitOp(double l) +{ + Put(PAINTING_MITERLIMIT); + Putf(l); +} + +void PaintingPainter::EvenOddOp(bool evenodd) +{ + Put(PAINTING_EVENODD); + Put(evenodd); +} + +void PaintingPainter::DashOp(const Vector& dash, double start) +{ + Put(PAINTING_DASH); + Put32(dash.GetCount()); + for(int i = 0; i < dash.GetCount(); i++) + Putf(dash[i]); + Putf(start); +} + +void PaintingPainter::TransformOp(const Matrix2D& m) +{ + Put(PAINTING_TRANSFORM); + Putf(m); +} + +void PaintingPainter::BeginOp() +{ + Put(PAINTING_BEGIN); +} + +void PaintingPainter::EndOp() +{ + Put(PAINTING_END); +} + +void PaintingPainter::BeginMaskOp() +{ + Put(PAINTING_BEGINMASK); +} + +Painting PaintingPainter::GetResult() +{ + Painting p; + p.cmd = cmd.GetResult(); + p.data = data; + return p; +} + +END_UPP_NAMESPACE diff --git a/uppsrc/Painter/Painting.h b/uppsrc/Painter/Painting.h new file mode 100644 index 000000000..93d2efef4 --- /dev/null +++ b/uppsrc/Painter/Painting.h @@ -0,0 +1,124 @@ +class Painting { + String cmd; + ValueArray data; + + friend class PaintingPainter; + friend class Painter; +}; + +enum { + PAINTING_EOF, + PAINTING_CLEAR, + + PAINTING_MOVE, + PAINTING_MOVE_REL, + PAINTING_LINE, + PAINTING_LINE_REL, + PAINTING_QUADRATIC, + PAINTING_QUADRATIC_REL, + PAINTING_QUADRATIC_S, + PAINTING_QUADRATIC_S_REL, + PAINTING_CUBIC, + PAINTING_CUBIC_REL, + PAINTING_CUBIC_S, + PAINTING_CUBIC_S_REL, + PAINTING_CLOSE, + + PAINTING_FILL_SOLID, + PAINTING_FILL_IMAGE, + PAINTING_FILL_GRADIENT, + PAINTING_FILL_RADIAL, + + PAINTING_STROKE_SOLID, + PAINTING_STROKE_IMAGE, + PAINTING_STROKE_GRADIENT, + PAINTING_STROKE_RADIAL, + + PAINTING_CLIP, + + PAINTING_CHARACTER, + PAINTING_TEXT, + + PAINTING_COLORSTOP, + PAINTING_CLEARSTOPS, + PAINTING_OPACITY, + PAINTING_LINECAP, + PAINTING_LINEJOIN, + PAINTING_MITERLIMIT, + PAINTING_EVENODD, + PAINTING_DASH, + + PAINTING_TRANSFORM, + PAINTING_BEGIN, + PAINTING_END, + PAINTING_BEGINMASK, +}; + +class PaintingPainter : public Painter { + StringStream cmd; + ValueArray data; + + void Put(int c) { cmd.Put(c); } + void Put32(int c) { cmd.Put32(c); } + void Put(const RGBA& c) { cmd.Put(&c, sizeof(RGBA)); } + void Putf(double d) { cmd.Put(&d, sizeof(double)); } + void Putf(double x, double y) { Putf(x); Putf(y); } + void Putf(const Matrix2D& m) { cmd.Put(&m, sizeof(Matrix2D)); } + void Put(const Font& f) { cmd.Put(&f, sizeof(Font)); } + +protected: + virtual void ClearOp(const RGBA& color); + + virtual void MoveOp(double x, double y, bool rel); + virtual void LineOp(double x, double y, bool rel); + virtual void QuadraticOp(double x1, double y1, double x, double y, bool rel); + virtual void QuadraticOp(double x, double y, bool rel); + virtual void CubicOp(double x1, double y1, double x2, double y2, double x, double y, bool rel); + virtual void CubicOp(double x2, double y2, double x, double y, bool rel); + virtual void CloseOp(); + + virtual void FillOp(const RGBA& color); + virtual void FillOp(const Image& image, const Matrix2D& transsrc, dword flags); + virtual void FillOp(double x1, double y1, const RGBA& color1, + double x2, double y2, const RGBA& color2, + int style); + virtual void FillOp(double fx, double fy, const RGBA& color1, + double x1, double y1, double r, const RGBA& color2, + int style); + + virtual void StrokeOp(double width, const RGBA& rgba); + virtual void StrokeOp(double width, const Image& image, const Matrix2D& transsrc, + dword flags); + virtual void StrokeOp(double width, double x1, double y1, const RGBA& color1, + double x2, double y2, const RGBA& color2, + int style); + virtual void StrokeOp(double width, double fx, double fy, const RGBA& color1, + double x, double y, double r, const RGBA& color2, + int style); + + virtual void ClipOp(); + + virtual void CharacterOp(double x, double y, int ch, Font fnt); + virtual void TextOp(double x, double y, const wchar *text, Font fnt, int n = -1, double *dx = NULL); + + virtual void ColorStopOp(double pos, const RGBA& color); + virtual void ClearStopsOp(); + + virtual void OpacityOp(double o); + virtual void LineCapOp(int linecap); + virtual void LineJoinOp(int linejoin); + virtual void MiterLimitOp(double l); + virtual void EvenOddOp(bool evenodd); + virtual void DashOp(const Vector& dash, double start); + + virtual void TransformOp(const Matrix2D& m); + + virtual void BeginOp(); + virtual void EndOp(); + + virtual void BeginMaskOp(); + +public: + Painting GetResult(); + operator Painting() { return GetResult(); } +};