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