diff --git a/uppsrc/DocTypes/ShowReport.cpp b/uppsrc/DocTypes/ShowReport.cpp index 2aba90613..da33b49bb 100644 --- a/uppsrc/DocTypes/ShowReport.cpp +++ b/uppsrc/DocTypes/ShowReport.cpp @@ -85,10 +85,18 @@ Image ReportCtrl::GetPage(int i) { if(pagei[ii] != i) { pagei[ii] = i; Size sz = Size(max(pagesize.cx - 2, 1), max(pagesize.cy - 2, 1)); - ImageDraw iw(sz); - iw.DrawRect(sz, White); - iw.DrawDrawing(0, 0, sz.cx, sz.cy, report->GetPage(i)); - page[ii] = iw; + if(HasPainter()) { + ImageBuffer ib(sz); + Fill(~ib, White(), ib.GetLength()); + PaintImageBuffer(ib, report->GetPage(i)); + page[ii] = ib; + } + else { + ImageDraw iw(sz); + iw.DrawRect(sz, White); + iw.DrawDrawing(0, 0, sz.cx, sz.cy, report->GetPage(i)); + page[ii] = iw; + } } return page[ii]; } diff --git a/uppsrc/Draw/Draw.cpp b/uppsrc/Draw/Draw.cpp index 793997ee6..29bfd2a92 100644 --- a/uppsrc/Draw/Draw.cpp +++ b/uppsrc/Draw/Draw.cpp @@ -336,16 +336,41 @@ bool Draw::IsPainting(int x, int y, int cx, int cy) const return IsPainting(RectC(x, y, cx, cy)); } -void (*DrawPaintingFn)(ImageBuffer& ib, const Painting& pw, Size sz, Point pos); +static void (*sIgfn)(ImageBuffer& ib, const Painting& pw, Size sz, Point pos); +static void (*sIwfn)(ImageBuffer& ib, const Drawing& p); -void RegisterDrawPaintingFn(void (*fn)(ImageBuffer& ib, const Painting& pw, Size sz, Point pos)) +void RegisterPaintingFns__(void (*ig)(ImageBuffer& ib, const Painting& pw, Size sz, Point pos), + void (*iw)(ImageBuffer& ib, const Drawing& p)) { - DrawPaintingFn = fn; + sIgfn = ig; + sIwfn = iw; +} + +bool HasPainter() +{ + return sIgfn && sIwfn; +} + +void PaintImageBuffer(ImageBuffer& ib, const Painting& p, Size sz, Point pos) +{ + if(sIgfn) + (*sIgfn)(ib, p, sz, pos); +} + +void PaintImageBuffer(ImageBuffer& ib, const Painting& p) +{ + PaintImageBuffer(ib, p, ib.GetSize(), Point(0, 0)); +} + +void PaintImageBuffer(ImageBuffer& ib, const Drawing& iw) +{ + if(sIwfn) + (*sIwfn)(ib, iw); } void Draw::DrawPaintingOp(const Rect& target, const Painting& pw) { - if(!DrawPaintingFn) + if(!HasPainter()) return; Size sz = target.GetSize(); if((sz.cx > 2000 || sz.cy > 1500) && IsPrinter()) { @@ -354,7 +379,7 @@ void Draw::DrawPaintingOp(const Rect& target, const Painting& pw) int ccy = min(sz.cy - yy, 100); ImageBuffer ib(sz.cx, ccy); Fill(~ib, RGBAZero(), ib.GetLength()); - DrawPaintingFn(ib, pw, sz, Point(0, yy)); + PaintImageBuffer(ib, pw, sz, Point(0, yy)); DrawImageBandRLE(*this, target.left, target.top + yy, ib, 16); yy += ccy; } @@ -362,7 +387,7 @@ void Draw::DrawPaintingOp(const Rect& target, const Painting& pw) else { ImageBuffer ib(sz); Fill(~ib, RGBAZero(), ib.GetLength()); - DrawPaintingFn(ib, pw, sz, Point(0, 0)); + PaintImageBuffer(ib, pw, sz, Point(0, 0)); DrawImage(target.left, target.top, ib); } } diff --git a/uppsrc/Draw/Draw.h b/uppsrc/Draw/Draw.h index 31f25333b..0f4828e7b 100644 --- a/uppsrc/Draw/Draw.h +++ b/uppsrc/Draw/Draw.h @@ -473,6 +473,11 @@ void SColorDkShadow_Write(Color c); inline Color InvertColor() { return Color(255, 0); } inline Color DefaultInk() { return Black(); } //TODO! +bool HasPainter(); +void PaintImageBuffer(ImageBuffer& ib, const Painting& p, Size sz, Point pos); +void PaintImageBuffer(ImageBuffer& ib, const Painting& p); +void PaintImageBuffer(ImageBuffer& ib, const Drawing& p); + class Draw { protected: bool palette:1; diff --git a/uppsrc/Draw/DrawData.cpp b/uppsrc/Draw/DrawData.cpp index 4ce1695ca..8a5e7fc6a 100644 --- a/uppsrc/Draw/DrawData.cpp +++ b/uppsrc/Draw/DrawData.cpp @@ -105,7 +105,7 @@ void Draw::DrawDataOp(int x, int y, int cx, int cy, const String& data, const ch if(cx > 2048 || cy > 2048) { int yy = 0; while(yy < cy) { - int ccy = min(cy - yy, 16); + int ccy = min(cy - yy, 32); ImageBuffer ib(cx, ccy); dd->Render(ib); DrawImageBandRLE(*this, x, y + yy, ib, 16); diff --git a/uppsrc/Painter/PaintPainting.cpp b/uppsrc/Painter/PaintPainting.cpp index 5ffdb76fd..382e8ddac 100644 --- a/uppsrc/Painter/PaintPainting.cpp +++ b/uppsrc/Painter/PaintPainting.cpp @@ -223,7 +223,7 @@ void Painter::Paint(const Painting& pic) } } -void PaintImageBuffer(ImageBuffer& ib, const Painting& p, Size sz, Point pos) +void PaintImageBufferPaintingFn(ImageBuffer& ib, const Painting& p, Size sz, Point pos) { BufferPainter sw(ib); Sizef psz = p.GetSize(); @@ -232,11 +232,22 @@ void PaintImageBuffer(ImageBuffer& ib, const Painting& p, Size sz, Point pos) sw.Paint(p); } -void RegisterDrawPaintingFn(void (*fn)(ImageBuffer& ib, const Painting& pw, Size sz, Point pos)); +void PaintImageBufferDrawingFn(ImageBuffer& ib, const Drawing& iw) +{ + BufferPainter sw(ib); + Sizef sz = ib.GetSize(); + Size isz = iw.GetSize(); + sw.Scale(sz.cx / isz.cx, sz.cy / isz.cy); + sw.DrawDrawing(0, 0, isz.cx, isz.cy, iw); +} + +void RegisterPaintingFns__(void (*ig)(ImageBuffer& ib, const Painting& pw, Size sz, Point pos), + void (*iw)(ImageBuffer& ib, const Drawing& p)); + INITBLOCK { - RegisterDrawPaintingFn(PaintImageBuffer); + RegisterPaintingFns__(PaintImageBufferPaintingFn, PaintImageBufferDrawingFn); } END_UPP_NAMESPACE diff --git a/uppsrc/Painter/Painter.cpp b/uppsrc/Painter/Painter.cpp index 1086c5b5a..b8044a7ab 100644 --- a/uppsrc/Painter/Painter.cpp +++ b/uppsrc/Painter/Painter.cpp @@ -1,266 +1,262 @@ -#include "Painter.h" - -NAMESPACE_UPP - -void Painter::OffsetOp(Point p) -{ - Begin(); - Translate(p.x, p.y); -} - -void Painter::RectPath(int x, int y, int cx, int cy) -{ - Move(x, y).Line(x + cx - 1, y).Line(x + cx - 1, y + cy - 1).Line(x, y + cy - 1).Close(); -} - -void Painter::RectPath(const Rect& r) -{ - RectPath(r.left, r.top, r.GetWidth(), r.GetHeight()); -} - -bool Painter::ClipOp(const Rect& r) -{ - Begin(); - RectPath(r); - Clip(); - return true; -} - -bool Painter::ClipoffOp(const Rect& r) -{ - Begin(); - RectPath(r); - Clip(); - Translate(r.left, r.top); - return true; -} - -bool Painter::ExcludeClipOp(const Rect& r) -{ - return true; -} - -bool Painter::IntersectClipOp(const Rect& r) -{ - RectPath(r); - Clip(); - return true; -} - -Rect Painter::GetClipOp() const -{ - return Rect(0, 0, 0, 0); -} - -bool Painter::IsPaintingOp(const Rect& r) const -{ - return true; -} - -void Painter::DrawRectOp(int x, int y, int cx, int cy, Color color) -{ - RTIMING("Rect"); - RectPath(x, y, cx, cy); - Fill(color); -} - -void Painter::DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color) -{ - RectPath(x, y, cx, cy); - Fill(img, Translate2D(x, y)); -} - -void Painter::DrawDataOp(int x, int y, int cx, int cy, const String& data, const char *id) -{ -} - -void Painter::DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color) -{ - Move(x1, y1); - Line(x2, y2); - Stroke(width, color); -} - -void Painter::DrawPolyPolylineOp(const Point *vertices, int vertex_count, const int *counts, - int count_count, int width, Color color, Color doxor) -{ -} - -void Painter::DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count, - const int *subpolygon_counts, int scc, const int *disjunct_polygon_counts, - int dpcc, Color color, int width, Color outline, uint64 pattern, Color doxor) -{ -} - -void Painter::DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color) -{ -} - -void Painter::DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor) -{ -} - -void Painter::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx) -{ - RTIMING("DrawTextOp"); - Begin(); - EvenOdd(true); - if(angle) - Rotate(angle * M_2PI / 36000); - if(n < 0) - n = wstrlen(text); - double *ddx = NULL; - Buffer h; - if(dx) { - h.Alloc(n); - ddx = h; - for(int i = 0; i < n; i++) - ddx[i] = dx[i]; - } - Text(x, y, text, font, n, ddx); - Fill(ink); - End(); -} - -Painter& Painter::Move(double x, double y) -{ - return Move(x, y, false); -} - -Painter& Painter::Line(double x, double y) -{ - return Line(x, y, false); -} - -Painter& Painter::Quadratic(double x1, double y1, double x, double y) -{ - return Quadratic(x1, y1, x, y, false); -} - -Painter& Painter::Quadratic(double x, double y) -{ - return Quadratic(x, y, false); -} - -Painter& Painter::Cubic(double x1, double y1, double x2, double y2, double x, double y) -{ - return Cubic(x1, y1, x2, y2, x, y, false); -} - -Painter& Painter::Cubic(double x2, double y2, double x, double y) -{ - return Cubic(x2, y2, x, y, false); -} - -Painter& Painter::RelMove(double x, double y) -{ - return Move(x, y, true); -} - -Painter& Painter::RelLine(double x, double y) -{ - return Line(x, y, true); -} - -Painter& Painter::RelQuadratic(double x1, double y1, double x, double y) -{ - return Quadratic(x1, y1, x, y, true); -} - -Painter& Painter::RelQuadratic(double x, double y) -{ - return Quadratic(x, y, true); -} - -Painter& Painter::RelCubic(double x1, double y1, double x2, double y2, double x, double y) -{ - return Cubic(x1, y1, x2, y2, x, y, true); -} - -Painter& Painter::RelCubic(double x2, double y2, double x, double y) -{ - return Cubic(x2, y2, x, y, true); -} - -Matrix2D GetImageLineMatrix(double x1, double y1, double x2, double y2, const Image& image) -{ - Matrix2D m; - Size sz = image.GetSize(); - m.scale(agg::calc_distance(x1, y1, x2, y2) / sz.cx); - if(fabs(x2 - x1) < fabs(y2 - y1) * 1e-6) - m.rotate(y2 > y1 ? M_PI_2 : -M_PI_2); - else - m.rotate(atan((y2 - y1) / (x2 - x1))); - m.translate(x1, y1); - return m; -} - -Painter& Painter::Fill(const Image& image, double x1, double y1, - double x2, double y2, dword flags) -{ - return Fill(image, GetImageLineMatrix(x1, y1, x2, y2, image), flags); -} - -Painter& Painter::Stroke(double width, const Image& image, double x1, double y1, - double x2, double y2, dword flags) -{ - return Stroke(width, image, GetImageLineMatrix(x1, y1, x2, y2, image), flags); -} - -Painter& Painter::Dash(const char *dash, double start) -{ - Vector d; - CParser p(dash); - try { - while(!p.IsEof()) - if(p.Char(':')) - start = p.ReadDouble(); - else - d.Add(p.ReadDouble()); - } - catch(CParser::Error) {} - Dash(d, start); - return *this; -} - -void Painter::Translate(double x, double y) -{ - Transform(Translate2D(x, y)); -} - -void Painter::Rotate(double a) -{ - Transform(Rotate2D(a)); -} - -void Painter::Scale(double scalex, double scaley) -{ - Transform(Scale2D(scalex, scaley)); -} - -void Painter::Scale(double scale) -{ - Transform(Scale2D(scale)); -} - -Painter& Painter::Ellipse(double x, double y, double rx, double ry) -{ - return Arc(x, y, rx, ry, 0, M_2PI); -} - -Painter& Painter::Circle(double x, double y, double r) -{ - return Ellipse(x, y, r, r); -} - -Painter& Painter::Rectangle(double x, double y, double cx, double cy) -{ - Move(x, y); - Line(x + cx, y); - Line(x + cx, y + cy); - Line(x, y + cy); - Close(); - return *this; -} - -END_UPP_NAMESPACE +#include "Painter.h" + +NAMESPACE_UPP + +void Painter::OffsetOp(Point p) +{ + Begin(); + Translate(p.x, p.y); +} + +void Painter::RectPath(int x, int y, int cx, int cy) +{ + Move(x, y).Line(x + cx - 1, y).Line(x + cx - 1, y + cy - 1).Line(x, y + cy - 1).Close(); +} + +void Painter::RectPath(const Rect& r) +{ + RectPath(r.left, r.top, r.GetWidth(), r.GetHeight()); +} + +bool Painter::ClipOp(const Rect& r) +{ + Begin(); + RectPath(r); + Clip(); + return true; +} + +bool Painter::ClipoffOp(const Rect& r) +{ + Begin(); + RectPath(r); + Clip(); + Translate(r.left, r.top); + return true; +} + +bool Painter::ExcludeClipOp(const Rect& r) +{ + return true; +} + +bool Painter::IntersectClipOp(const Rect& r) +{ + RectPath(r); + Clip(); + return true; +} + +Rect Painter::GetClipOp() const +{ + return Rect(0, 0, 0, 0); +} + +bool Painter::IsPaintingOp(const Rect& r) const +{ + return true; +} + +void Painter::DrawRectOp(int x, int y, int cx, int cy, Color color) +{ + RTIMING("Rect"); + RectPath(x, y, cx, cy); + Fill(color); +} + +void Painter::DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color) +{ + RectPath(x, y, cx, cy); + Fill(img, Translate2D(x, y)); +} + +void Painter::DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color) +{ + Move(x1, y1); + Line(x2, y2); + Stroke(width, color); +} + +void Painter::DrawPolyPolylineOp(const Point *vertices, int vertex_count, const int *counts, + int count_count, int width, Color color, Color doxor) +{ +} + +void Painter::DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count, + const int *subpolygon_counts, int scc, const int *disjunct_polygon_counts, + int dpcc, Color color, int width, Color outline, uint64 pattern, Color doxor) +{ +} + +void Painter::DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color) +{ +} + +void Painter::DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor) +{ +} + +void Painter::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx) +{ + RTIMING("DrawTextOp"); + Begin(); + EvenOdd(true); + if(angle) + Rotate(angle * M_2PI / 36000); + if(n < 0) + n = wstrlen(text); + double *ddx = NULL; + Buffer h; + if(dx) { + h.Alloc(n); + ddx = h; + for(int i = 0; i < n; i++) + ddx[i] = dx[i]; + } + Text(x, y, text, font, n, ddx); + Fill(ink); + End(); +} + +Painter& Painter::Move(double x, double y) +{ + return Move(x, y, false); +} + +Painter& Painter::Line(double x, double y) +{ + return Line(x, y, false); +} + +Painter& Painter::Quadratic(double x1, double y1, double x, double y) +{ + return Quadratic(x1, y1, x, y, false); +} + +Painter& Painter::Quadratic(double x, double y) +{ + return Quadratic(x, y, false); +} + +Painter& Painter::Cubic(double x1, double y1, double x2, double y2, double x, double y) +{ + return Cubic(x1, y1, x2, y2, x, y, false); +} + +Painter& Painter::Cubic(double x2, double y2, double x, double y) +{ + return Cubic(x2, y2, x, y, false); +} + +Painter& Painter::RelMove(double x, double y) +{ + return Move(x, y, true); +} + +Painter& Painter::RelLine(double x, double y) +{ + return Line(x, y, true); +} + +Painter& Painter::RelQuadratic(double x1, double y1, double x, double y) +{ + return Quadratic(x1, y1, x, y, true); +} + +Painter& Painter::RelQuadratic(double x, double y) +{ + return Quadratic(x, y, true); +} + +Painter& Painter::RelCubic(double x1, double y1, double x2, double y2, double x, double y) +{ + return Cubic(x1, y1, x2, y2, x, y, true); +} + +Painter& Painter::RelCubic(double x2, double y2, double x, double y) +{ + return Cubic(x2, y2, x, y, true); +} + +Matrix2D GetImageLineMatrix(double x1, double y1, double x2, double y2, const Image& image) +{ + Matrix2D m; + Size sz = image.GetSize(); + m.scale(agg::calc_distance(x1, y1, x2, y2) / sz.cx); + if(fabs(x2 - x1) < fabs(y2 - y1) * 1e-6) + m.rotate(y2 > y1 ? M_PI_2 : -M_PI_2); + else + m.rotate(atan((y2 - y1) / (x2 - x1))); + m.translate(x1, y1); + return m; +} + +Painter& Painter::Fill(const Image& image, double x1, double y1, + double x2, double y2, dword flags) +{ + return Fill(image, GetImageLineMatrix(x1, y1, x2, y2, image), flags); +} + +Painter& Painter::Stroke(double width, const Image& image, double x1, double y1, + double x2, double y2, dword flags) +{ + return Stroke(width, image, GetImageLineMatrix(x1, y1, x2, y2, image), flags); +} + +Painter& Painter::Dash(const char *dash, double start) +{ + Vector d; + CParser p(dash); + try { + while(!p.IsEof()) + if(p.Char(':')) + start = p.ReadDouble(); + else + d.Add(p.ReadDouble()); + } + catch(CParser::Error) {} + Dash(d, start); + return *this; +} + +void Painter::Translate(double x, double y) +{ + Transform(Translate2D(x, y)); +} + +void Painter::Rotate(double a) +{ + Transform(Rotate2D(a)); +} + +void Painter::Scale(double scalex, double scaley) +{ + Transform(Scale2D(scalex, scaley)); +} + +void Painter::Scale(double scale) +{ + Transform(Scale2D(scale)); +} + +Painter& Painter::Ellipse(double x, double y, double rx, double ry) +{ + return Arc(x, y, rx, ry, 0, M_2PI); +} + +Painter& Painter::Circle(double x, double y, double r) +{ + return Ellipse(x, y, r, r); +} + +Painter& Painter::Rectangle(double x, double y, double cx, double cy) +{ + Move(x, y); + Line(x + cx, y); + Line(x + cx, y + cy); + Line(x, y + cy); + Close(); + return *this; +} + +END_UPP_NAMESPACE diff --git a/uppsrc/Painter/Painter.h b/uppsrc/Painter/Painter.h index a3f420432..fe15543ee 100644 --- a/uppsrc/Painter/Painter.h +++ b/uppsrc/Painter/Painter.h @@ -84,7 +84,6 @@ protected: virtual void DrawRectOp(int x, int y, int cx, int cy, Color color); virtual void DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color); - virtual void DrawDataOp(int x, int y, int cx, int cy, const String& data, const char *id); virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color); virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count, diff --git a/uppsrc/Painter/Painting.h b/uppsrc/Painter/Painting.h index 5724a798e..47b75c166 100644 --- a/uppsrc/Painter/Painting.h +++ b/uppsrc/Painter/Painting.h @@ -138,3 +138,4 @@ public: }; void PaintImageBuffer(ImageBuffer& ib, const Painting& p, Size sz, Point pos); +void PaintImageBuffer(ImageBuffer& ib, const Drawing& p); diff --git a/uppsrc/Report/ReportDlg.cpp b/uppsrc/Report/ReportDlg.cpp index 2d888d291..28b0c597a 100644 --- a/uppsrc/Report/ReportDlg.cpp +++ b/uppsrc/Report/ReportDlg.cpp @@ -128,10 +128,18 @@ Image ReportView::GetPage(int i) { if(pagei[ii] != i) { pagei[ii] = i; Size sz = Size(max(pagesize.cx - 2, 1), max(pagesize.cy - 2, 1)); - ImageDraw iw(sz); - iw.DrawRect(sz, White); - iw.DrawDrawing(0, 0, sz.cx, sz.cy, report->GetPage(i)); - page[ii] = iw; + if(HasPainter()) { + ImageBuffer ib(sz); + Fill(~ib, White(), ib.GetLength()); + PaintImageBuffer(ib, report->GetPage(i)); + page[ii] = ib; + } + else { + ImageDraw iw(sz); + iw.DrawRect(sz, White); + iw.DrawDrawing(0, 0, sz.cx, sz.cy, report->GetPage(i)); + page[ii] = iw; + } } return page[ii]; }