.cosmetics

git-svn-id: svn://ultimatepp.org/upp/trunk@5260 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2012-08-05 11:37:38 +00:00
parent 7a19b0db3a
commit 9cf2cfae5d
4 changed files with 757 additions and 748 deletions

View file

@ -1,411 +1,411 @@
#ifndef _Painter_Painter_h_
#define _Painter_Painter_h_
#include <Draw/Draw.h>
#define PAINTER_TIMING(x) // RTIMING(x)
NAMESPACE_UPP
struct Xform2D {
Pointf x, y, t;
Pointf GetScaleXY() const;
double GetScale() const;
bool IsRegular() const;
Pointf Transform(const Pointf& f) const;
Pointf Transform(double x, double y) const;
static Xform2D Identity();
static Xform2D Translation(double x, double y);
static Xform2D Scale(double sx, double sy);
static Xform2D Scale(double scale);
static Xform2D Rotation(double fi);
static Xform2D Sheer(double fi);
Xform2D();
};
Xform2D operator*(const Xform2D& a, const Xform2D& b);
Xform2D Inverse(const Xform2D& m);
enum {
LINECAP_BUTT,
LINECAP_SQUARE,
LINECAP_ROUND,
LINEJOIN_MITER,
LINEJOIN_ROUND,
LINEJOIN_BEVEL,
FILL_EXACT = 0,
FILL_HPAD = 1,
FILL_HREPEAT = 2,
FILL_HREFLECT = 3,
FILL_VPAD = 4,
FILL_VREPEAT = 8,
FILL_VREFLECT = 12,
FILL_PAD = FILL_HPAD|FILL_VPAD,
FILL_REPEAT = FILL_HREPEAT|FILL_VREPEAT,
FILL_REFLECT = FILL_HREFLECT|FILL_VREFLECT,
FILL_FAST = 128,
GRADIENT_PAD = 0,
GRADIENT_REPEAT = 1,
GRADIENT_REFLECT = 2,
};
class Painter : public Draw {
public:
virtual dword GetInfo() const;
virtual void OffsetOp(Point p);
virtual bool ClipOp(const Rect& r);
virtual bool ClipoffOp(const Rect& r);
virtual bool ExcludeClipOp(const Rect& r);
virtual bool IntersectClipOp(const Rect& r);
virtual bool IsPaintingOp(const Rect& r) const;
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 DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color);
virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count, const int *counts,
int count_count, int width, Color color, Color doxor);
virtual void 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);
virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color);
virtual void DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor);
virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx);
virtual void DrawPaintingOp(const Rect& target, const Painting& p);
protected:
virtual void ClearOp(const RGBA& color) = 0;
virtual void MoveOp(const Pointf& p, bool rel) = 0;
virtual void LineOp(const Pointf& p, bool rel) = 0;
virtual void QuadraticOp(const Pointf& p1, const Pointf& p, bool rel) = 0;
virtual void QuadraticOp(const Pointf& p, bool rel) = 0;
virtual void CubicOp(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel) = 0;
virtual void CubicOp(const Pointf& p2, const Pointf& p, bool rel) = 0;
virtual void ArcOp(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel) = 0;
virtual void SvgArcOp(const Pointf& r, double xangle, bool large, bool sweep,
const Pointf& p, bool rel) = 0;
virtual void CloseOp() = 0;
virtual void DivOp() = 0;
virtual void FillOp(const RGBA& color) = 0;
virtual void FillOp(const Image& image, const Xform2D& transsrc, dword flags) = 0;
virtual void FillOp(const Pointf& p1, const RGBA& color1,
const Pointf& p2, const RGBA& color2,
int style) = 0;
virtual void FillOp(const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2,
int style) = 0;
virtual void StrokeOp(double width, const RGBA& rgba) = 0;
virtual void StrokeOp(double width, const Image& image, const Xform2D& transsrc,
dword flags) = 0;
virtual void StrokeOp(double width, const Pointf& p1, const RGBA& color1,
const Pointf& p2, const RGBA& color2,
int style) = 0;
virtual void StrokeOp(double width, const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2,
int style) = 0;
virtual void ClipOp() = 0;
virtual void CharacterOp(const Pointf& p, int ch, Font fnt) = 0;
virtual void TextOp(const Pointf& p, const wchar *text, Font fnt, int n = -1,
double *dx = NULL);
virtual void ColorStopOp(double pos, const RGBA& color) = 0;
virtual void ClearStopsOp() = 0;
virtual void OpacityOp(double o) = 0;
virtual void LineCapOp(int linecap) = 0;
virtual void LineJoinOp(int linejoin) = 0;
virtual void MiterLimitOp(double l) = 0;
virtual void EvenOddOp(bool evenodd) = 0;
virtual void DashOp(const Vector<double>& dash, double start = 0) = 0;
virtual void InvertOp(bool invert) = 0;
virtual void TransformOp(const Xform2D& m) = 0;
virtual void BeginOp() = 0;
virtual void EndOp() = 0;
virtual void BeginMaskOp() = 0;
virtual void BeginOnPathOp(double q, bool absolute) = 0;
protected:
static bool ReadBool(CParser& p);
static double ReadDouble(CParser& p);
static Pointf ReadPoint(CParser& p);
void DoArc0(double theta, double th_sweep, const Xform2D& m);
void DoArc(const Pointf& c, const Pointf& r, double angle, double sweep, double xangle);
void DoSvgArc(const Pointf& rr, double xangle, int large, int sweep,
const Pointf& p, const Pointf& p0);
void DrawLineStroke(int width, Color color);
public:
void Clear(const RGBA& color);
Painter& Move(const Pointf& p, bool rel);
Painter& Move(const Pointf& p);
Painter& Move(double x, double y, bool rel);
Painter& Move(double x, double y);
Painter& RelMove(const Pointf& p);
Painter& RelMove(double x, double y);
Painter& Line(const Pointf& p, bool rel);
Painter& Line(const Pointf& p);
Painter& Line(double x, double y, bool rel);
Painter& Line(double x, double y);
Painter& RelLine(const Pointf& p);
Painter& RelLine(double x, double y);
Painter& Quadratic(const Pointf& p1, const Pointf& p, bool rel);
Painter& Quadratic(const Pointf& p1, const Pointf& p);
Painter& Quadratic(const Pointf& p);
Painter& Quadratic(double x, double y, bool rel);
Painter& Quadratic(double x1, double y1, double x, double y, bool rel);
Painter& Quadratic(const Pointf& p, bool rel);
Painter& Quadratic(double x1, double y1, double x, double y);
Painter& Quadratic(double x, double y);
Painter& RelQuadratic(const Pointf& p1, const Pointf& p);
Painter& RelQuadratic(double x1, double y1, double x, double y);
Painter& RelQuadratic(double x, double y);
Painter& RelQuadratic(const Pointf& p);
Painter& Cubic(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel);
Painter& Cubic(const Pointf& p2, const Pointf& p, bool rel);
Painter& Cubic(const Pointf& p1, const Pointf& p2, const Pointf& p);
Painter& Cubic(const Pointf& p2, const Pointf& p);
Painter& Cubic(double x1, double y1, double x2, double y2, double x, double y, bool rel);
Painter& Cubic(double x2, double y2, double x, double y, bool rel);
Painter& Cubic(double x1, double y1, double x2, double y2, double x, double y);
Painter& Cubic(double x2, double y2, double x, double y);
Painter& RelCubic(const Pointf& p1, const Pointf& p2, const Pointf& p);
Painter& RelCubic(const Pointf& p2, const Pointf& p);
Painter& RelCubic(double x1, double y1, double x2, double y2, double x, double y);
Painter& RelCubic(double x2, double y2, double x, double y);
Painter& Arc(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel);
Painter& Arc(const Pointf& c, double rx, double ry, double angle, double sweep, bool rel);
Painter& Arc(const Pointf& c, double r, double angle, double sweep, bool rel);
Painter& Arc(double x, double y, double rx, double ry, double angle, double sweep, bool rel);
Painter& Arc(double x, double y, double r, double angle, double sweep, bool rel);
Painter& Arc(const Pointf& c, const Pointf& r, double angle, double sweep);
Painter& Arc(const Pointf& c, double rx, double ry, double angle, double sweep);
Painter& Arc(const Pointf& c, double r, double angle, double sweep);
Painter& Arc(double x, double y, double rx, double ry, double angle, double sweep);
Painter& Arc(double x, double y, double r, double angle, double sweep);
Painter& RelArc(const Pointf& c, const Pointf& r, double angle, double sweep);
Painter& RelArc(const Pointf& c, double rx, double ry, double angle, double sweep);
Painter& RelArc(const Pointf& c, double r, double angle, double sweep);
Painter& RelArc(double x, double y, double rx, double ry, double angle, double sweep);
Painter& RelArc(double x, double y, double r, double angle, double sweep);
Painter& SvgArc(const Pointf& r, double xangle, bool large, bool sweep, const Pointf& p, bool rel);
Painter& SvgArc(double rx, double ry, double xangle, bool large, bool sweep, const Pointf& p, bool rel);
Painter& SvgArc(double rx, double ry, double xangle, bool large, bool sweep, double x, double y, bool rel);
Painter& SvgArc(const Pointf& r, double xangle, bool large, bool sweep, const Pointf& p);
Painter& SvgArc(double rx, double ry, double xangle, bool large, bool sweep, const Pointf& p);
Painter& SvgArc(double rx, double ry, double xangle, bool large, bool sweep, double x, double y);
Painter& RelSvgArc(const Pointf& r, double xangle, bool large, bool sweep, const Pointf& p);
Painter& RelSvgArc(double rx, double ry, double xangle, bool large, bool sweep, const Pointf& p);
Painter& RelSvgArc(double rx, double ry, double xangle, bool large, bool sweep, double x, double y);
Painter& Close();
Painter& Div();
Painter& Path(CParser& p);
Painter& Path(const char *path);
Painter& Fill(const RGBA& color);
Painter& Fill(const Image& image, const Xform2D& transsrc = Xform2D::Identity(), dword flags = 0);
Painter& Fill(const Image& image, Pointf p1, Pointf p2, dword flags = 0);
Painter& Fill(const Image& image, double x1, double y1, double x2, double y2,
dword flags = 0);
Painter& Fill(const Pointf& p1, const RGBA& color1,
const Pointf& p2, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Fill(double x1, double y1, const RGBA& color1,
double x2, double y2, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Fill(const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Fill(double fx, double fy, const RGBA& color1,
double cx, double cy, double r, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Fill(const Pointf& c, const RGBA& color1,
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& Stroke(double width, const RGBA& color);
Painter& Stroke(double width, const Image& image, const Xform2D& transsrc, dword flags = 0);
Painter& Stroke(double width, const Image& image, const Pointf& p1, const Pointf& p2,
dword flags = 0);
Painter& Stroke(double width, const Image& image, double x1, double y1, double x2, double y2,
dword flags = 0);
Painter& Stroke(double width, const Pointf& p1, const RGBA& color1,
const Pointf& p2, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Stroke(double width, double x1, double y1, const RGBA& color1,
double x2, double y2, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Stroke(double width, const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Stroke(double width, double fx, double fy, const RGBA& color1,
double cx, double cy, double r, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Stroke(double width, const Pointf& c, const RGBA& color1,
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& Clip();
Painter& Character(const Pointf& p, int ch, Font fnt);
Painter& Character(double x, double y, int ch, Font fnt);
Painter& Text(const Pointf& p, const wchar *text, Font fnt, int n = -1, double *dx = NULL);
Painter& Text(double x, double y, const wchar *text, Font fnt, int n = -1, double *dx = NULL);
Painter& Text(const Pointf& p, const WString& s, Font fnt, double *dx = NULL);
Painter& Text(double x, double y, const WString& s, Font fnt, double *dx = NULL);
Painter& Text(const Pointf& p, const String& s, Font fnt, double *dx = NULL);
Painter& Text(double x, double y, const String& s, Font fnt, double *dx = NULL);
Painter& Text(const Pointf& p, const char *text, Font fnt, int n = -1, double *dx = NULL);
Painter& Text(double x, double y, const char *text, Font fnt, int n = -1, double *dx = NULL);
void Begin();
void End();
void BeginMask();
void BeginOnPath(double q, bool absolute = false);
Painter& ColorStop(double pos, const RGBA& color);
Painter& ClearStops();
Painter& Opacity(double o);
Painter& LineCap(int linecap);
Painter& LineJoin(int linejoin);
Painter& MiterLimit(double l);
Painter& EvenOdd(bool evenodd = true);
Painter& Dash(const Vector<double>& dash, double start);
Painter& Dash(const char *dash, double start = 0);
Painter& Invert(bool b = true);
Painter& Transform(const Xform2D& m);
Painter& Translate(double x, double y);
Painter& Translate(const Pointf& p);
Painter& Rotate(double a);
Painter& Scale(double scalex, double scaley);
Painter& Scale(double scale);
void Paint(const Painting& p);
Painter& Rectangle(double x, double y, double cx, double cy);
Painter& RoundedRectangle(double x, double y, double cx, double cy, double r);
Painter& Ellipse(double x, double y, double rx, double ry);
Painter& Circle(double x, double y, double r);
Painter& RectPath(int x, int y, int cx, int cy);
Painter& RectPath(const Rect& r);
};
void PaintCharacterSys(Painter& sw, double x, double y, int ch, Font fnt);
void PaintCharacter(Painter& sw, const Pointf& p, int ch, Font fnt);
#include "Painter.hpp"
#include "Painting.h"
#include "BufferPainter.h"
class ImageBuffer__ {
protected:
ImageBuffer ib;
public:
ImageBuffer__(Size sz) : ib(sz) {}
};
class ImagePainter : private ImageBuffer__, public BufferPainter {
public:
ImagePainter(Size sz, int mode = MODE_ANTIALIASED);
ImagePainter(int cx, int cy, int mode = MODE_ANTIALIASED);
Image GetResult() { return ImageBuffer__::ib; }
operator Image() { return GetResult(); }
};
class DrawPainter : public ImagePainter {
Draw& w;
public:
DrawPainter(Draw& w, Size sz, int mode = MODE_ANTIALIASED);
~DrawPainter();
};
class NilPainter : public Painter {
protected:
virtual void ClearOp(const RGBA& color);
virtual void MoveOp(const Pointf& p, bool rel);
virtual void LineOp(const Pointf& p, bool rel);
virtual void QuadraticOp(const Pointf& p1, const Pointf& p, bool rel);
virtual void QuadraticOp(const Pointf& p, bool rel);
virtual void CubicOp(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel);
virtual void CubicOp(const Pointf& p2, const Pointf& p, bool rel);
virtual void ArcOp(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel);
virtual void SvgArcOp(const Pointf& r, double xangle, bool large, bool sweep,
const Pointf& p, bool rel);
virtual void CloseOp();
virtual void DivOp();
virtual void FillOp(const RGBA& color);
virtual void FillOp(const Image& image, const Xform2D& transsrc, dword flags);
virtual void FillOp(const Pointf& p1, const RGBA& color1,
const Pointf& p2, const RGBA& color2,
int style);
virtual void FillOp(const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2,
int style);
virtual void StrokeOp(double width, const RGBA& rgba);
virtual void StrokeOp(double width, const Image& image, const Xform2D& transsrc,
dword flags);
virtual void StrokeOp(double width, const Pointf& p1, const RGBA& color1,
const Pointf& p2, const RGBA& color2,
int style);
virtual void StrokeOp(double width, const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2,
int style);
virtual void ClipOp();
virtual void CharacterOp(const Pointf& p, int ch, Font fnt);
virtual void TextOp(const Pointf& p, 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<double>& dash, double start);
virtual void InvertOp(bool invert);
virtual void TransformOp(const Xform2D& m);
virtual void BeginOp();
virtual void EndOp();
virtual void BeginMaskOp();
virtual void BeginOnPathOp(double q, bool abs);
};
END_UPP_NAMESPACE
#endif
#ifndef _Painter_Painter_h_
#define _Painter_Painter_h_
#include <Draw/Draw.h>
#define PAINTER_TIMING(x) // RTIMING(x)
NAMESPACE_UPP
struct Xform2D {
Pointf x, y, t;
Pointf GetScaleXY() const;
double GetScale() const;
bool IsRegular() const;
Pointf Transform(const Pointf& f) const;
Pointf Transform(double x, double y) const;
static Xform2D Identity();
static Xform2D Translation(double x, double y);
static Xform2D Scale(double sx, double sy);
static Xform2D Scale(double scale);
static Xform2D Rotation(double fi);
static Xform2D Sheer(double fi);
Xform2D();
};
Xform2D operator*(const Xform2D& a, const Xform2D& b);
Xform2D Inverse(const Xform2D& m);
enum {
LINECAP_BUTT,
LINECAP_SQUARE,
LINECAP_ROUND,
LINEJOIN_MITER,
LINEJOIN_ROUND,
LINEJOIN_BEVEL,
FILL_EXACT = 0,
FILL_HPAD = 1,
FILL_HREPEAT = 2,
FILL_HREFLECT = 3,
FILL_VPAD = 4,
FILL_VREPEAT = 8,
FILL_VREFLECT = 12,
FILL_PAD = FILL_HPAD|FILL_VPAD,
FILL_REPEAT = FILL_HREPEAT|FILL_VREPEAT,
FILL_REFLECT = FILL_HREFLECT|FILL_VREFLECT,
FILL_FAST = 128,
GRADIENT_PAD = 0,
GRADIENT_REPEAT = 1,
GRADIENT_REFLECT = 2,
};
class Painter : public Draw {
public:
virtual dword GetInfo() const;
virtual void OffsetOp(Point p);
virtual bool ClipOp(const Rect& r);
virtual bool ClipoffOp(const Rect& r);
virtual bool ExcludeClipOp(const Rect& r);
virtual bool IntersectClipOp(const Rect& r);
virtual bool IsPaintingOp(const Rect& r) const;
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 DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color);
virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count, const int *counts,
int count_count, int width, Color color, Color doxor);
virtual void 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);
virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color);
virtual void DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor);
virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx);
virtual void DrawPaintingOp(const Rect& target, const Painting& p);
protected:
virtual void ClearOp(const RGBA& color) = 0;
virtual void MoveOp(const Pointf& p, bool rel) = 0;
virtual void LineOp(const Pointf& p, bool rel) = 0;
virtual void QuadraticOp(const Pointf& p1, const Pointf& p, bool rel) = 0;
virtual void QuadraticOp(const Pointf& p, bool rel) = 0;
virtual void CubicOp(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel) = 0;
virtual void CubicOp(const Pointf& p2, const Pointf& p, bool rel) = 0;
virtual void ArcOp(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel) = 0;
virtual void SvgArcOp(const Pointf& r, double xangle, bool large, bool sweep,
const Pointf& p, bool rel) = 0;
virtual void CloseOp() = 0;
virtual void DivOp() = 0;
virtual void FillOp(const RGBA& color) = 0;
virtual void FillOp(const Image& image, const Xform2D& transsrc, dword flags) = 0;
virtual void FillOp(const Pointf& p1, const RGBA& color1,
const Pointf& p2, const RGBA& color2,
int style) = 0;
virtual void FillOp(const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2,
int style) = 0;
virtual void StrokeOp(double width, const RGBA& rgba) = 0;
virtual void StrokeOp(double width, const Image& image, const Xform2D& transsrc,
dword flags) = 0;
virtual void StrokeOp(double width, const Pointf& p1, const RGBA& color1,
const Pointf& p2, const RGBA& color2,
int style) = 0;
virtual void StrokeOp(double width, const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2,
int style) = 0;
virtual void ClipOp() = 0;
virtual void CharacterOp(const Pointf& p, int ch, Font fnt) = 0;
virtual void TextOp(const Pointf& p, const wchar *text, Font fnt, int n = -1,
double *dx = NULL);
virtual void ColorStopOp(double pos, const RGBA& color) = 0;
virtual void ClearStopsOp() = 0;
virtual void OpacityOp(double o) = 0;
virtual void LineCapOp(int linecap) = 0;
virtual void LineJoinOp(int linejoin) = 0;
virtual void MiterLimitOp(double l) = 0;
virtual void EvenOddOp(bool evenodd) = 0;
virtual void DashOp(const Vector<double>& dash, double start = 0) = 0;
virtual void InvertOp(bool invert) = 0;
virtual void TransformOp(const Xform2D& m) = 0;
virtual void BeginOp() = 0;
virtual void EndOp() = 0;
virtual void BeginMaskOp() = 0;
virtual void BeginOnPathOp(double q, bool absolute) = 0;
protected:
static bool ReadBool(CParser& p);
static double ReadDouble(CParser& p);
static Pointf ReadPoint(CParser& p);
void DoArc0(double theta, double th_sweep, const Xform2D& m);
void DoArc(const Pointf& c, const Pointf& r, double angle, double sweep, double xangle);
void DoSvgArc(const Pointf& rr, double xangle, int large, int sweep,
const Pointf& p, const Pointf& p0);
void DrawLineStroke(int width, Color color);
public:
void Clear(const RGBA& color);
Painter& Move(const Pointf& p, bool rel);
Painter& Move(const Pointf& p);
Painter& Move(double x, double y, bool rel);
Painter& Move(double x, double y);
Painter& RelMove(const Pointf& p);
Painter& RelMove(double x, double y);
Painter& Line(const Pointf& p, bool rel);
Painter& Line(const Pointf& p);
Painter& Line(double x, double y, bool rel);
Painter& Line(double x, double y);
Painter& RelLine(const Pointf& p);
Painter& RelLine(double x, double y);
Painter& Quadratic(const Pointf& p1, const Pointf& p, bool rel);
Painter& Quadratic(const Pointf& p1, const Pointf& p);
Painter& Quadratic(const Pointf& p);
Painter& Quadratic(double x, double y, bool rel);
Painter& Quadratic(double x1, double y1, double x, double y, bool rel);
Painter& Quadratic(const Pointf& p, bool rel);
Painter& Quadratic(double x1, double y1, double x, double y);
Painter& Quadratic(double x, double y);
Painter& RelQuadratic(const Pointf& p1, const Pointf& p);
Painter& RelQuadratic(double x1, double y1, double x, double y);
Painter& RelQuadratic(double x, double y);
Painter& RelQuadratic(const Pointf& p);
Painter& Cubic(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel);
Painter& Cubic(const Pointf& p2, const Pointf& p, bool rel);
Painter& Cubic(const Pointf& p1, const Pointf& p2, const Pointf& p);
Painter& Cubic(const Pointf& p2, const Pointf& p);
Painter& Cubic(double x1, double y1, double x2, double y2, double x, double y, bool rel);
Painter& Cubic(double x2, double y2, double x, double y, bool rel);
Painter& Cubic(double x1, double y1, double x2, double y2, double x, double y);
Painter& Cubic(double x2, double y2, double x, double y);
Painter& RelCubic(const Pointf& p1, const Pointf& p2, const Pointf& p);
Painter& RelCubic(const Pointf& p2, const Pointf& p);
Painter& RelCubic(double x1, double y1, double x2, double y2, double x, double y);
Painter& RelCubic(double x2, double y2, double x, double y);
Painter& Arc(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel);
Painter& Arc(const Pointf& c, double rx, double ry, double angle, double sweep, bool rel);
Painter& Arc(const Pointf& c, double r, double angle, double sweep, bool rel);
Painter& Arc(double x, double y, double rx, double ry, double angle, double sweep, bool rel);
Painter& Arc(double x, double y, double r, double angle, double sweep, bool rel);
Painter& Arc(const Pointf& c, const Pointf& r, double angle, double sweep);
Painter& Arc(const Pointf& c, double rx, double ry, double angle, double sweep);
Painter& Arc(const Pointf& c, double r, double angle, double sweep);
Painter& Arc(double x, double y, double rx, double ry, double angle, double sweep);
Painter& Arc(double x, double y, double r, double angle, double sweep);
Painter& RelArc(const Pointf& c, const Pointf& r, double angle, double sweep);
Painter& RelArc(const Pointf& c, double rx, double ry, double angle, double sweep);
Painter& RelArc(const Pointf& c, double r, double angle, double sweep);
Painter& RelArc(double x, double y, double rx, double ry, double angle, double sweep);
Painter& RelArc(double x, double y, double r, double angle, double sweep);
Painter& SvgArc(const Pointf& r, double xangle, bool large, bool sweep, const Pointf& p, bool rel);
Painter& SvgArc(double rx, double ry, double xangle, bool large, bool sweep, const Pointf& p, bool rel);
Painter& SvgArc(double rx, double ry, double xangle, bool large, bool sweep, double x, double y, bool rel);
Painter& SvgArc(const Pointf& r, double xangle, bool large, bool sweep, const Pointf& p);
Painter& SvgArc(double rx, double ry, double xangle, bool large, bool sweep, const Pointf& p);
Painter& SvgArc(double rx, double ry, double xangle, bool large, bool sweep, double x, double y);
Painter& RelSvgArc(const Pointf& r, double xangle, bool large, bool sweep, const Pointf& p);
Painter& RelSvgArc(double rx, double ry, double xangle, bool large, bool sweep, const Pointf& p);
Painter& RelSvgArc(double rx, double ry, double xangle, bool large, bool sweep, double x, double y);
Painter& Close();
Painter& Div();
Painter& Path(CParser& p);
Painter& Path(const char *path);
Painter& Fill(const RGBA& color);
Painter& Fill(const Image& image, const Xform2D& transsrc = Xform2D::Identity(), dword flags = 0);
Painter& Fill(const Image& image, Pointf p1, Pointf p2, dword flags = 0);
Painter& Fill(const Image& image, double x1, double y1, double x2, double y2,
dword flags = 0);
Painter& Fill(const Pointf& p1, const RGBA& color1,
const Pointf& p2, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Fill(double x1, double y1, const RGBA& color1,
double x2, double y2, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Fill(const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Fill(double fx, double fy, const RGBA& color1,
double cx, double cy, double r, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Fill(const Pointf& c, const RGBA& color1,
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& Stroke(double width, const RGBA& color);
Painter& Stroke(double width, const Image& image, const Xform2D& transsrc, dword flags = 0);
Painter& Stroke(double width, const Image& image, const Pointf& p1, const Pointf& p2,
dword flags = 0);
Painter& Stroke(double width, const Image& image, double x1, double y1, double x2, double y2,
dword flags = 0);
Painter& Stroke(double width, const Pointf& p1, const RGBA& color1,
const Pointf& p2, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Stroke(double width, double x1, double y1, const RGBA& color1,
double x2, double y2, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Stroke(double width, const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Stroke(double width, double fx, double fy, const RGBA& color1,
double cx, double cy, double r, const RGBA& color2, int style = GRADIENT_PAD);
Painter& Stroke(double width, const Pointf& c, const RGBA& color1,
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& Clip();
Painter& Character(const Pointf& p, int ch, Font fnt);
Painter& Character(double x, double y, int ch, Font fnt);
Painter& Text(const Pointf& p, const wchar *text, Font fnt, int n = -1, double *dx = NULL);
Painter& Text(double x, double y, const wchar *text, Font fnt, int n = -1, double *dx = NULL);
Painter& Text(const Pointf& p, const WString& s, Font fnt, double *dx = NULL);
Painter& Text(double x, double y, const WString& s, Font fnt, double *dx = NULL);
Painter& Text(const Pointf& p, const String& s, Font fnt, double *dx = NULL);
Painter& Text(double x, double y, const String& s, Font fnt, double *dx = NULL);
Painter& Text(const Pointf& p, const char *text, Font fnt, int n = -1, double *dx = NULL);
Painter& Text(double x, double y, const char *text, Font fnt, int n = -1, double *dx = NULL);
void Begin();
void End();
void BeginMask();
void BeginOnPath(double q, bool absolute = false);
Painter& ColorStop(double pos, const RGBA& color);
Painter& ClearStops();
Painter& Opacity(double o);
Painter& LineCap(int linecap);
Painter& LineJoin(int linejoin);
Painter& MiterLimit(double l);
Painter& EvenOdd(bool evenodd = true);
Painter& Dash(const Vector<double>& dash, double start);
Painter& Dash(const char *dash, double start = 0);
Painter& Invert(bool b = true);
Painter& Transform(const Xform2D& m);
Painter& Translate(double x, double y);
Painter& Translate(const Pointf& p);
Painter& Rotate(double a);
Painter& Scale(double scalex, double scaley);
Painter& Scale(double scale);
void Paint(const Painting& p);
Painter& Rectangle(double x, double y, double cx, double cy);
Painter& RoundedRectangle(double x, double y, double cx, double cy, double r);
Painter& Ellipse(double x, double y, double rx, double ry);
Painter& Circle(double x, double y, double r);
Painter& RectPath(int x, int y, int cx, int cy);
Painter& RectPath(const Rect& r);
};
void PaintCharacterSys(Painter& sw, double x, double y, int ch, Font fnt);
void PaintCharacter(Painter& sw, const Pointf& p, int ch, Font fnt);
#include "Painter.hpp"
#include "Painting.h"
#include "BufferPainter.h"
class ImageBuffer__ {
protected:
ImageBuffer ib;
public:
ImageBuffer__(Size sz) : ib(sz) {}
};
class ImagePainter : private ImageBuffer__, public BufferPainter {
public:
ImagePainter(Size sz, int mode = MODE_ANTIALIASED);
ImagePainter(int cx, int cy, int mode = MODE_ANTIALIASED);
Image GetResult() { return ImageBuffer__::ib; }
operator Image() { return GetResult(); }
};
class DrawPainter : public ImagePainter {
Draw& w;
public:
DrawPainter(Draw& w, Size sz, int mode = MODE_ANTIALIASED);
~DrawPainter();
};
class NilPainter : public Painter {
protected:
virtual void ClearOp(const RGBA& color);
virtual void MoveOp(const Pointf& p, bool rel);
virtual void LineOp(const Pointf& p, bool rel);
virtual void QuadraticOp(const Pointf& p1, const Pointf& p, bool rel);
virtual void QuadraticOp(const Pointf& p, bool rel);
virtual void CubicOp(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel);
virtual void CubicOp(const Pointf& p2, const Pointf& p, bool rel);
virtual void ArcOp(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel);
virtual void SvgArcOp(const Pointf& r, double xangle, bool large, bool sweep,
const Pointf& p, bool rel);
virtual void CloseOp();
virtual void DivOp();
virtual void FillOp(const RGBA& color);
virtual void FillOp(const Image& image, const Xform2D& transsrc, dword flags);
virtual void FillOp(const Pointf& p1, const RGBA& color1,
const Pointf& p2, const RGBA& color2,
int style);
virtual void FillOp(const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2,
int style);
virtual void StrokeOp(double width, const RGBA& rgba);
virtual void StrokeOp(double width, const Image& image, const Xform2D& transsrc,
dword flags);
virtual void StrokeOp(double width, const Pointf& p1, const RGBA& color1,
const Pointf& p2, const RGBA& color2,
int style);
virtual void StrokeOp(double width, const Pointf& f, const RGBA& color1,
const Pointf& c, double r, const RGBA& color2,
int style);
virtual void ClipOp();
virtual void CharacterOp(const Pointf& p, int ch, Font fnt);
virtual void TextOp(const Pointf& p, 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<double>& dash, double start);
virtual void InvertOp(bool invert);
virtual void TransformOp(const Xform2D& m);
virtual void BeginOp();
virtual void EndOp();
virtual void BeginMaskOp();
virtual void BeginOnPathOp(double q, bool abs);
};
END_UPP_NAMESPACE
#endif

View file

@ -1,103 +1,103 @@
#include "Painter.h"
#define LLOG(x) // DLOG(x)
NAMESPACE_UPP
void Rasterizer::CvLine(double x1, double y1, double x2, double y2)
{
LLOG("CvLine " << x1 << ", " << y1 << " - " << x2 << ", " << y2);
LineRaw(Q8X(x1), Q8Y(y1), Q8X(x2), Q8Y(y2));
}
void Rasterizer::LineClip(double x1, double y1, double x2, double y2)
{
if(y1 < cliprect.top) {
if(y2 < cliprect.top)
return;
x1 = (x2 - x1) * (cliprect.top - y1) / (y2 - y1) + x1;
y1 = cliprect.top;
}
else
if(y1 > cliprect.bottom) {
if(y2 > cliprect.bottom)
return;
x1 = (x2 - x1) * (cliprect.bottom - y1) / (y2 - y1) + x1;
y1 = cliprect.bottom;
}
if(y2 < cliprect.top) {
x2 = (x2 - x1) * (cliprect.top - y1) / (y2 - y1) + x1;
y2 = cliprect.top;
}
else
if(y2 > cliprect.bottom) {
x2 = (x2 - x1) * (cliprect.bottom - y1) / (y2 - y1) + x1;
y2 = cliprect.bottom;
}
double y, yy;
if(x1 < cliprect.left) {
if(x2 < cliprect.left) {
CvLine(cliprect.left, y1, cliprect.left, y2);
return;
}
y = (y2 - y1) * (cliprect.left - x1) / (x2 - x1) + y1;
if(x2 > cliprect.right) {
yy = (y2 - y1) * (cliprect.right - x1) / (x2 - x1) + y1;
CvLine(cliprect.left, y1, cliprect.left, y);
CvLine(cliprect.left, y, cliprect.right, yy);
CvLine(cliprect.right, yy, cliprect.right, y2);
return;
}
CvLine(cliprect.left, y1, cliprect.left, y);
CvLine(cliprect.left, y, x2, y2);
return;
}
else
if(x1 > cliprect.right) {
if(x2 > cliprect.right) {
CvLine(cliprect.right, y1, cliprect.right, y2);
return;
}
y = (y2 - y1) * (cliprect.right - x1) / (x2 - x1) + y1;
if(x2 < cliprect.left) {
yy = (y2 - y1) * (cliprect.left - x1) / (x2 - x1) + y1;
CvLine(cliprect.right, y1, cliprect.right, y);
CvLine(cliprect.right, y, cliprect.left, yy);
CvLine(cliprect.left, yy, cliprect.left, y2);
return;
}
CvLine(cliprect.right, y1, cliprect.right, y);
CvLine(cliprect.right, y, x2, y2);
return;
}
if(x2 < cliprect.left) {
y = (y2 - y1) * (cliprect.left - x1) / (x2 - x1) + y1;
CvLine(x1, y1, cliprect.left, y);
CvLine(cliprect.left, y, cliprect.left, y2);
return;
}
else
if(x2 > cliprect.right) {
y = (y2 - y1) * (cliprect.right - x1) / (x2 - x1) + y1;
CvLine(x1, y1, cliprect.right, y);
CvLine(cliprect.right, y, cliprect.right, y2);
return;
}
CvLine(x1, y1, x2, y2);
}
void Rasterizer::Move(const Pointf& p)
{
LLOG("Rasterizer::Move " << p);
p0 = p;
}
void Rasterizer::Line(const Pointf& p)
{
PAINTER_TIMING("Line");
LLOG("Rasterizer::Line " << p);
LineClip(p0.x, p0.y, p.x, p.y);
p0 = p;
}
END_UPP_NAMESPACE
#include "Painter.h"
#define LLOG(x) // DLOG(x)
NAMESPACE_UPP
void Rasterizer::CvLine(double x1, double y1, double x2, double y2)
{
LLOG("CvLine " << x1 << ", " << y1 << " - " << x2 << ", " << y2);
LineRaw(Q8X(x1), Q8Y(y1), Q8X(x2), Q8Y(y2));
}
void Rasterizer::LineClip(double x1, double y1, double x2, double y2)
{
if(y1 < cliprect.top) {
if(y2 < cliprect.top)
return;
x1 = (x2 - x1) * (cliprect.top - y1) / (y2 - y1) + x1;
y1 = cliprect.top;
}
else
if(y1 > cliprect.bottom) {
if(y2 > cliprect.bottom)
return;
x1 = (x2 - x1) * (cliprect.bottom - y1) / (y2 - y1) + x1;
y1 = cliprect.bottom;
}
if(y2 < cliprect.top) {
x2 = (x2 - x1) * (cliprect.top - y1) / (y2 - y1) + x1;
y2 = cliprect.top;
}
else
if(y2 > cliprect.bottom) {
x2 = (x2 - x1) * (cliprect.bottom - y1) / (y2 - y1) + x1;
y2 = cliprect.bottom;
}
double y, yy;
if(x1 < cliprect.left) {
if(x2 < cliprect.left) {
CvLine(cliprect.left, y1, cliprect.left, y2);
return;
}
y = (y2 - y1) * (cliprect.left - x1) / (x2 - x1) + y1;
if(x2 > cliprect.right) {
yy = (y2 - y1) * (cliprect.right - x1) / (x2 - x1) + y1;
CvLine(cliprect.left, y1, cliprect.left, y);
CvLine(cliprect.left, y, cliprect.right, yy);
CvLine(cliprect.right, yy, cliprect.right, y2);
return;
}
CvLine(cliprect.left, y1, cliprect.left, y);
CvLine(cliprect.left, y, x2, y2);
return;
}
else
if(x1 > cliprect.right) {
if(x2 > cliprect.right) {
CvLine(cliprect.right, y1, cliprect.right, y2);
return;
}
y = (y2 - y1) * (cliprect.right - x1) / (x2 - x1) + y1;
if(x2 < cliprect.left) {
yy = (y2 - y1) * (cliprect.left - x1) / (x2 - x1) + y1;
CvLine(cliprect.right, y1, cliprect.right, y);
CvLine(cliprect.right, y, cliprect.left, yy);
CvLine(cliprect.left, yy, cliprect.left, y2);
return;
}
CvLine(cliprect.right, y1, cliprect.right, y);
CvLine(cliprect.right, y, x2, y2);
return;
}
if(x2 < cliprect.left) {
y = (y2 - y1) * (cliprect.left - x1) / (x2 - x1) + y1;
CvLine(x1, y1, cliprect.left, y);
CvLine(cliprect.left, y, cliprect.left, y2);
return;
}
else
if(x2 > cliprect.right) {
y = (y2 - y1) * (cliprect.right - x1) / (x2 - x1) + y1;
CvLine(x1, y1, cliprect.right, y);
CvLine(cliprect.right, y, cliprect.right, y2);
return;
}
CvLine(x1, y1, x2, y2);
}
void Rasterizer::Move(const Pointf& p)
{
LLOG("Rasterizer::Move " << p);
p0 = p;
}
void Rasterizer::Line(const Pointf& p)
{
PAINTER_TIMING("Line");
LLOG("Rasterizer::Line " << p);
LineClip(p0.x, p0.y, p.x, p.y);
p0 = p;
}
END_UPP_NAMESPACE

View file

@ -1,234 +1,240 @@
#include "Painter.h"
#include "Fillers.h"
NAMESPACE_UPP
void BufferPainter::ClearOp(const RGBA& color)
{
UPP::Fill(~ib, color, ib.GetLength());
}
struct BufferPainter::OnPathTarget : LinearPathConsumer {
Vector<BufferPainter::PathLine> path;
Pointf pos;
double len;
virtual void Move(const Pointf& p) {
BufferPainter::PathLine& t = path.Add();
t.len = 0;
pos = t.p = p;
}
virtual void Line(const Pointf& p) {
BufferPainter::PathLine& t = path.Add();
len += (t.len = Distance(pos, p));
pos = t.p = p;
}
OnPathTarget() { len = 0; pos = Pointf(0, 0); }
};
Buffer<ClippingLine> BufferPainter::RenderPath(double width, SpanSource *ss, const RGBA& color)
{
Buffer<ClippingLine> newclip;
if(width == 0) {
current = Null;
return newclip;
}
Transformer trans(pathattr.mtx);
Stroker stroker;
Dasher dasher;
OnPathTarget onpathtarget;
bool evenodd = pathattr.evenodd;
bool regular = pathattr.mtx.IsRegular() && width < 0 && !ischar;
double tolerance;
LinearPathConsumer *g = &rasterizer;
if(regular)
tolerance = 0.3;
else {
trans.target = g;
g = &trans;
tolerance = 0.3 / attr.mtx.GetScale();
}
if(width == ONPATH) {
g = &onpathtarget;
regular = false;
}
else
if(width > 0) {
stroker.Init(width, pathattr.miter_limit, tolerance, pathattr.cap, pathattr.join);
stroker.target = g;
if(pathattr.dash.GetCount()) {
dasher.Init(pathattr.dash, pathattr.dash_start);
dasher.target = &stroker;
g = &dasher;
}
else
g = &stroker;
evenodd = false;
}
else
Close();
byte *data = path.data;
int opacity = int(256 * pathattr.opacity);
Pointf pos = Pointf(0, 0);
int i = 0;
Rasterizer::Filler *rg;
SpanFiller span_filler;
SolidFiller solid_filler;
SubpixelFiller subpixel_filler;
ClipFiller clip_filler(render_cx);
NoAAFillerFilter noaa_filler;
MaskFillerFilter mf;
bool doclip = width == CLIP;
subpixel_filler.sbuffer = subpixel;
subpixel_filler.invert = pathattr.invert;
if(doclip) {
rg = &clip_filler;
newclip.Alloc(ib.GetHeight());
}
else
if(ss) {
if(!span)
span.Alloc((subpixel ? 3 : 1) * ib.GetWidth() + 3);
if(subpixel) {
subpixel_filler.ss = ss;
subpixel_filler.buffer = span;
subpixel_filler.alpha = opacity;
rg = &subpixel_filler;
}
else {
span_filler.ss = ss;
span_filler.buffer = span;
span_filler.alpha = opacity;
rg = &span_filler;
}
}
else {
if(subpixel) {
subpixel_filler.color = Mul8(color, opacity);
subpixel_filler.ss = NULL;
rg = &subpixel_filler;
}
else {
solid_filler.c = Mul8(color, opacity);
solid_filler.invert = pathattr.invert;
rg = &solid_filler;
}
}
if(mode == MODE_NOAA) {
noaa_filler.Set(rg);
rg = &noaa_filler;
}
for(;;) {
if(i >= path.type.GetCount() || path.type[i] == DIV) {
g->End();
if(width != ONPATH) {
for(int y = rasterizer.MinY(); y <= rasterizer.MaxY(); y++) {
solid_filler.t = subpixel_filler.t = span_filler.t = ib[y];
subpixel_filler.end = subpixel_filler.t + ib.GetWidth();
span_filler.y = subpixel_filler.y = y;
Rasterizer::Filler *rf = rg;
if(clip.GetCount()) {
const ClippingLine& s = clip.Top()[y];
if(s.IsEmpty()) goto empty;
if(!s.IsFull()) {
mf.Set(rg, s);
rf = &mf;
}
}
if(doclip)
clip_filler.Clear();
rasterizer.Render(y, *rf, evenodd);
if(doclip)
clip_filler.Finish(newclip[y]);
empty:;
}
rasterizer.Reset();
}
if(i >= path.type.GetCount())
break;
}
else
switch(path.type[i]) {
case MOVE: {
const LinearData *d = (LinearData *)data;
data += sizeof(LinearData);
g->Move(pos = regular ? pathattr.mtx.Transform(d->p) : d->p);
break;
}
case LINE: {
const LinearData *d = (LinearData *)data;
data += sizeof(LinearData);
g->Line(pos = regular ? pathattr.mtx.Transform(d->p) : d->p);
break;
}
case QUADRATIC: {
const QuadraticData *d = (QuadraticData *)data;
data += sizeof(QuadraticData);
if(regular) {
Pointf p = pathattr.mtx.Transform(d->p);
ApproximateQuadratic(*g, pos, pathattr.mtx.Transform(d->p1), p, tolerance);
pos = p;
}
else {
ApproximateQuadratic(*g, pos, d->p1, d->p, tolerance);
pos = d->p;
}
break;
}
case CUBIC: {
const CubicData *d = (CubicData *)data;
data += sizeof(CubicData);
if(regular) {
Pointf p = pathattr.mtx.Transform(d->p);
ApproximateCubic(*g, pos, pathattr.mtx.Transform(d->p1),
pathattr.mtx.Transform(d->p2), p, tolerance);
pos = p;
}
else {
ApproximateCubic(*g, pos, d->p1, d->p2, d->p, tolerance);
pos = d->p;
}
break;
}
case CHAR:
ApproximateChar(*g, *(CharData *)data, tolerance);
data += sizeof(CharData);
break;
default:
NEVER();
return newclip;
}
i++;
}
current = Null;
if(width == ONPATH) {
onpath = onpathtarget.path;
pathlen = onpathtarget.len;
}
return newclip;
}
void BufferPainter::FillOp(const RGBA& color)
{
RenderPath(FILL, NULL, color);
}
void BufferPainter::StrokeOp(double width, const RGBA& color)
{
RenderPath(width, NULL, color);
}
void BufferPainter::ClipOp()
{
Buffer<ClippingLine> newclip = RenderPath(CLIP, NULL, RGBAZero());
if(attr.hasclip)
clip.Top() = newclip;
else {
clip.Add() = newclip;
attr.hasclip = true;
attr.cliplevel = clip.GetCount();
}
}
END_UPP_NAMESPACE
#include "Painter.h"
#include "Fillers.h"
NAMESPACE_UPP
void BufferPainter::ClearOp(const RGBA& color)
{
UPP::Fill(~ib, color, ib.GetLength());
}
struct BufferPainter::OnPathTarget : LinearPathConsumer {
Vector<BufferPainter::PathLine> path;
Pointf pos;
double len;
virtual void Move(const Pointf& p) {
BufferPainter::PathLine& t = path.Add();
t.len = 0;
pos = t.p = p;
}
virtual void Line(const Pointf& p) {
BufferPainter::PathLine& t = path.Add();
len += (t.len = Distance(pos, p));
pos = t.p = p;
}
OnPathTarget() { len = 0; pos = Pointf(0, 0); }
};
Buffer<ClippingLine> BufferPainter::RenderPath(double width, SpanSource *ss, const RGBA& color)
{
PAINTER_TIMING("RenderPath");
Buffer<ClippingLine> newclip;
if(width == 0) {
current = Null;
return newclip;
}
Transformer trans(pathattr.mtx);
Stroker stroker;
Dasher dasher;
OnPathTarget onpathtarget;
bool evenodd = pathattr.evenodd;
bool regular = pathattr.mtx.IsRegular() && width < 0 && !ischar;
double tolerance;
LinearPathConsumer *g = &rasterizer;
if(regular)
tolerance = 0.3;
else {
trans.target = g;
g = &trans;
tolerance = 0.3 / attr.mtx.GetScale();
}
if(width == ONPATH) {
g = &onpathtarget;
regular = false;
}
else
if(width > 0) {
stroker.Init(width, pathattr.miter_limit, tolerance, pathattr.cap, pathattr.join);
stroker.target = g;
if(pathattr.dash.GetCount()) {
dasher.Init(pathattr.dash, pathattr.dash_start);
dasher.target = &stroker;
g = &dasher;
}
else
g = &stroker;
evenodd = false;
}
else
Close();
byte *data = path.data;
int opacity = int(256 * pathattr.opacity);
Pointf pos = Pointf(0, 0);
int i = 0;
Rasterizer::Filler *rg;
SpanFiller span_filler;
SolidFiller solid_filler;
SubpixelFiller subpixel_filler;
ClipFiller clip_filler(render_cx);
NoAAFillerFilter noaa_filler;
MaskFillerFilter mf;
bool doclip = width == CLIP;
subpixel_filler.sbuffer = subpixel;
subpixel_filler.invert = pathattr.invert;
if(doclip) {
rg = &clip_filler;
newclip.Alloc(ib.GetHeight());
}
else
if(ss) {
if(!span)
span.Alloc((subpixel ? 3 : 1) * ib.GetWidth() + 3);
if(subpixel) {
subpixel_filler.ss = ss;
subpixel_filler.buffer = span;
subpixel_filler.alpha = opacity;
rg = &subpixel_filler;
}
else {
span_filler.ss = ss;
span_filler.buffer = span;
span_filler.alpha = opacity;
rg = &span_filler;
}
}
else {
if(subpixel) {
subpixel_filler.color = Mul8(color, opacity);
subpixel_filler.ss = NULL;
rg = &subpixel_filler;
}
else {
solid_filler.c = Mul8(color, opacity);
solid_filler.invert = pathattr.invert;
rg = &solid_filler;
}
}
if(mode == MODE_NOAA) {
noaa_filler.Set(rg);
rg = &noaa_filler;
}
PAINTER_TIMING("RenderPath2");
for(;;) {
if(i >= path.type.GetCount() || path.type[i] == DIV) {
g->End();
if(width != ONPATH) {
PAINTER_TIMING("Fill");
for(int y = rasterizer.MinY(); y <= rasterizer.MaxY(); y++) {
solid_filler.t = subpixel_filler.t = span_filler.t = ib[y];
subpixel_filler.end = subpixel_filler.t + ib.GetWidth();
span_filler.y = subpixel_filler.y = y;
Rasterizer::Filler *rf = rg;
if(clip.GetCount()) {
const ClippingLine& s = clip.Top()[y];
if(s.IsEmpty()) goto empty;
if(!s.IsFull()) {
mf.Set(rg, s);
rf = &mf;
}
}
if(doclip)
clip_filler.Clear();
rasterizer.Render(y, *rf, evenodd);
if(doclip)
clip_filler.Finish(newclip[y]);
empty:;
}
rasterizer.Reset();
}
if(i >= path.type.GetCount())
break;
}
else
switch(path.type[i]) {
case MOVE: {
const LinearData *d = (LinearData *)data;
data += sizeof(LinearData);
g->Move(pos = regular ? pathattr.mtx.Transform(d->p) : d->p);
break;
}
case LINE: {
PAINTER_TIMING("LINE");
const LinearData *d = (LinearData *)data;
data += sizeof(LinearData);
g->Line(pos = regular ? pathattr.mtx.Transform(d->p) : d->p);
break;
}
case QUADRATIC: {
PAINTER_TIMING("QUADRATIC");
const QuadraticData *d = (QuadraticData *)data;
data += sizeof(QuadraticData);
if(regular) {
Pointf p = pathattr.mtx.Transform(d->p);
ApproximateQuadratic(*g, pos, pathattr.mtx.Transform(d->p1), p, tolerance);
pos = p;
}
else {
ApproximateQuadratic(*g, pos, d->p1, d->p, tolerance);
pos = d->p;
}
break;
}
case CUBIC: {
PAINTER_TIMING("CUBIC");
const CubicData *d = (CubicData *)data;
data += sizeof(CubicData);
if(regular) {
Pointf p = pathattr.mtx.Transform(d->p);
ApproximateCubic(*g, pos, pathattr.mtx.Transform(d->p1),
pathattr.mtx.Transform(d->p2), p, tolerance);
pos = p;
}
else {
ApproximateCubic(*g, pos, d->p1, d->p2, d->p, tolerance);
pos = d->p;
}
break;
}
case CHAR:
ApproximateChar(*g, *(CharData *)data, tolerance);
data += sizeof(CharData);
break;
default:
NEVER();
return newclip;
}
i++;
}
current = Null;
if(width == ONPATH) {
onpath = onpathtarget.path;
pathlen = onpathtarget.len;
}
return newclip;
}
void BufferPainter::FillOp(const RGBA& color)
{
RenderPath(FILL, NULL, color);
}
void BufferPainter::StrokeOp(double width, const RGBA& color)
{
RenderPath(width, NULL, color);
}
void BufferPainter::ClipOp()
{
Buffer<ClippingLine> newclip = RenderPath(CLIP, NULL, RGBAZero());
if(attr.hasclip)
clip.Top() = newclip;
else {
clip.Add() = newclip;
attr.hasclip = true;
attr.cliplevel = clip.GetCount();
}
}
END_UPP_NAMESPACE

View file

@ -89,8 +89,10 @@ struct sMakeGlyph : LRUCache<Value, GlyphKey>::Maker {
void BufferPainter::ApproximateChar(LinearPathConsumer& t, const CharData& ch, double tolerance)
{
PAINTER_TIMING("ApproximateChar");
Value v;
INTERLOCKED {
PAINTER_TIMING("ApproximateChar::Fetch");
static LRUCache<Value, GlyphKey> cache;
cache.Shrink(500000);
sMakeGlyph h;
@ -118,6 +120,7 @@ void BufferPainter::ApproximateChar(LinearPathConsumer& t, const CharData& ch, d
t.Move(p + ch.p);
}
else {
PAINTER_TIMING("ApproximateChar::Line");
p.y = g[i++];
t.Line(p + ch.p);
}