1 struct BoundsPainter : public NilPainter {
2 	virtual void   MoveOp(const Pointf& p, bool rel);
3 	virtual void   LineOp(const Pointf& p, bool rel);
4 	virtual void   QuadraticOp(const Pointf& p1, const Pointf& p, bool rel);
5 	virtual void   QuadraticOp(const Pointf& p, bool rel);
6 	virtual void   CubicOp(const Pointf& p1, const Pointf& p2, const Pointf& p, bool rel);
7 	virtual void   CubicOp(const Pointf& p2, const Pointf& p, bool rel);
8 	virtual void   ArcOp(const Pointf& c, const Pointf& r, double angle, double sweep, bool rel);
9 	virtual void   SvgArcOp(const Pointf& r, double xangle, bool large, bool sweep,
10 	                        const Pointf& p, bool rel);
11 	virtual void   CloseOp();
12 	virtual void   DivOp();
13 
14 	virtual void   ClipOp();
15 
16 	virtual void   TextOp(const Pointf& p, const wchar *text, Font fnt, int n = -1,
17 	                      const double *dx = NULL);
18 	virtual void   CharacterOp(const Pointf& p, int ch, Font fnt);
19 
20 	virtual void   TransformOp(const Xform2D& m);
21 	virtual void   BeginOp();
22 	virtual void   EndOp();
23 
24 
25 	void Finish(double width = 0);
26 
27 	Painter& sw;
28 	Rectf    boundingbox;
29 	Pointf   current, qcontrol, ccontrol;
30 
31 	Array<Xform2D> mtx;
32 	Rectf      svg_boundingbox;
33 	NilPainter nil;
34 
35 	void  Bounds(Pointf p);
36 
37 	void  Quadratic(const Pointf& p1, const Pointf& p);
38 	void  Cubic(const Pointf& p1, const Pointf& p2, const Pointf& p);
39 
40 	void  New();
GetBoundsPainter41 	const Rectf& Get() { return boundingbox; }
42 
43 	bool  compute_svg_boundingbox;
44 
BoundsPainterBoundsPainter45 	BoundsPainter(Painter& sw) : sw(sw) { New(); mtx.Add(); svg_boundingbox = Null; compute_svg_boundingbox = false; }
46 };
47 
48 struct SvgParser {
49 	Painter& sw;
50 
51 	void ParseSVG(const char *svg, const char *folder);
52 
53 	struct Stop : Moveable<Stop> {
54 		RGBA   color;
55 		double offset;
56 	};
57 
58 	struct Gradient {
59 		bool   resolved;
60 		bool   radial;
61 		Pointf a, b, c, f;
62 		double r;
63 		int    style;
64 		bool   user_space; // TODO: Cascade!
65 		String transform;
66 
67 		Vector<Stop> stop;
68 
69 		String href;
70 	};
71 
72 	ArrayMap<String, Gradient> gradient;
73 
74 	struct State {
75 		double opacity;
76 
77 		int    fill_gradient;
78 		Color  fill;
79 		double fill_opacity;
80 
81 		int    stroke_gradient;
82 		Color  stroke;
83 		double stroke_width;
84 		double stroke_opacity;
85 
86 		String dash_array;
87 		double dash_offset;
88 
89 		int    text_anchor; // 0 left, 1 middle, 2 right
90 
91 		Font   font;
92 
93 		const XmlNode *n;
94 	};
95 
96 	const XmlNode *current = NULL;
97 	Array<State>   state;
98 	bool           closed;
99 	Pointf         prev;
100 	Xform2D        lastTransform;
101 	BoundsPainter  bp;
102 	VectorMap<String, const XmlNode*> idmap;
103 	VectorMap<String, String> classes;
104 
105 	void Reset();
106 
107 	static Color GetTextColor(const String& color);
108 	static Color GetColor(const String& text);
109 
110 	void    ProcessValue(const String& key, const String& value);
111 	void    Style(const char *style);
112 	Xform2D Transform(const char *transform);
113 
TxtSvgParser114 	String Txt(const char *id)                  { return current ? current->Attr(id) : String(); }
115 	double Dbl(const char *id, double def = 0)  { return Nvl(StrDbl(Txt(id)), def); }
116 
117 	void StartElement(const XmlNode& n);
118 	void EndElement();
119 	void StrokeFinishElement();
120 	void FinishElement();
121 	void DoGradient(int gi, bool stroke);
122 	void Poly(const XmlNode& n, bool line);
123 	void Items(const XmlNode& n, int depth);
124 	void Element(const XmlNode& n, int depth, bool dosymbols = false);
125 	void ParseGradient(const XmlNode& n, bool radial);
126 	void ResolveGradient(int i);
127 	void MapIds(const XmlNode& n);
128 
129 	bool   ReadBool(CParser& p);
130 	double ReadDouble(CParser& p);
131 	Pointf ReadPoint0(CParser& p, bool rel);
132 	Pointf ReadPoint(CParser& p, bool rel);
133 	void   Path(const char *s);
134 
135 	bool Parse(const char *xml);
136 
137 	Event<String, String&> resloader;
138 
139 	SvgParser(Painter& sw);
140 };
141