xref: /haiku/src/apps/icon-o-matic/import_export/svg/DocumentBuilder.h (revision a085e81e62d7a860f809b4fb7c7bf5654c396985)
1 /*
2  * Copyright 2006-2007, Haiku. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Stephan Aßmus <superstippi@gmx.de>
7  */
8 
9 //----------------------------------------------------------------------------
10 // Anti-Grain Geometry - Version 2.2
11 // Copyright (C) 2002-2004 Maxim Shemanarev (http://www.antigrain.com)
12 //
13 // Permission to copy, use, modify, sell and distribute this software
14 // is granted provided this copyright notice appears in all copies.
15 // This software is provided "as is" without express or implied
16 // warranty, and with no claim as to its suitability for any purpose.
17 //
18 //----------------------------------------------------------------------------
19 // Contact: mcseem@antigrain.com
20 //		  mcseemagg@yahoo.com
21 //		  http://www.antigrain.com
22 //----------------------------------------------------------------------------
23 
24 #ifndef DOCUMENT_BUILD_H
25 #define DOCUMENT_BUILD_H
26 
27 #include <stdio.h>
28 
29 #include <List.h>
30 #include <Rect.h>
31 #include <String.h>
32 
33 #include <agg_array.h>
34 #include <agg_color_rgba.h>
35 #include <agg_conv_transform.h>
36 #include <agg_conv_stroke.h>
37 #include <agg_conv_contour.h>
38 #include <agg_conv_curve.h>
39 #include <agg_path_storage.h>
40 #include <agg_rasterizer_scanline_aa.h>
41 
42 #include "IconBuild.h"
43 #include "PathTokenizer.h"
44 
45 
46 class SVGImporter;
47 
48 _BEGIN_ICON_NAMESPACE
49 	class Icon;
50 	class Transformable;
51 _END_ICON_NAMESPACE
52 
53 _USING_ICON_NAMESPACE
54 
55 namespace agg {
56 namespace svg {
57 
58 class SVGGradient;
59 
60 // Basic path attributes
61 struct path_attributes {
62 
63 	unsigned		index;
64 	rgba8			fill_color;
65 	rgba8			stroke_color;
66 	double			opacity;
67 	bool			fill_flag;
68 	bool			stroke_flag;
69 	bool			even_odd_flag;
70 	line_join_e		line_join;
71 	line_cap_e		line_cap;
72 	double			miter_limit;
73 	double			stroke_width;
74 	trans_affine	transform;
75 
76 	char			stroke_url[64];
77 	char			fill_url[64];
78 
79 	// Empty constructor
80 	path_attributes() :
81 		index			(0),
82 		fill_color		(rgba(0,0,0)),
83 		stroke_color	(rgba(0,0,0)),
84 		opacity			(1.0),
85 		fill_flag		(true),
86 		stroke_flag		(false),
87 		even_odd_flag	(false),
88 		line_join		(miter_join),
89 		line_cap		(butt_cap),
90 		miter_limit		(4.0),
91 		stroke_width	(1.0),
92 		transform		()
93 	{
94 		stroke_url[0] = 0;
95 		fill_url[0] = 0;
96 	}
97 
98 	// Copy constructor
99 	path_attributes(const path_attributes& attr) :
100 		index			(attr.index),
101 		fill_color		(attr.fill_color),
102 		stroke_color	(attr.stroke_color),
103 		opacity			(attr.opacity),
104 		fill_flag		(attr.fill_flag),
105 		stroke_flag		(attr.stroke_flag),
106 		even_odd_flag	(attr.even_odd_flag),
107 		line_join		(attr.line_join),
108 		line_cap		(attr.line_cap),
109 		miter_limit		(attr.miter_limit),
110 		stroke_width	(attr.stroke_width),
111 		transform		(attr.transform)
112 	{
113 		sprintf(stroke_url, "%s", attr.stroke_url);
114 		sprintf(fill_url, "%s", attr.fill_url);
115 	}
116 
117 	// Copy constructor with new index value
118 	path_attributes(const path_attributes& attr, unsigned idx) :
119 		index			(idx),
120 		fill_color		(attr.fill_color),
121 		stroke_color	(attr.stroke_color),
122 		fill_flag		(attr.fill_flag),
123 		stroke_flag		(attr.stroke_flag),
124 		even_odd_flag	(attr.even_odd_flag),
125 		line_join		(attr.line_join),
126 		line_cap		(attr.line_cap),
127 		miter_limit		(attr.miter_limit),
128 		stroke_width	(attr.stroke_width),
129 		transform		(attr.transform)
130 	{
131 		sprintf(stroke_url, "%s", attr.stroke_url);
132 		sprintf(fill_url, "%s", attr.fill_url);
133 	}
134 };
135 
136 class DocumentBuilder {
137  public:
138 
139 	typedef pod_bvector<path_attributes>		attr_storage;
140 
141 								DocumentBuilder();
142 
143 			void				remove_all();
144 
145 	// Use these functions as follows:
146 	// begin_path() when the XML tag <path> comes ("start_element" handler)
147 	// parse_path() on "d=" tag attribute
148 	// end_path() when parsing of the entire tag is done.
149 			void				begin_path();
150 			void				parse_path(PathTokenizer& tok);
151 			void				end_path();
152 
153 	// The following functions are essentially a "reflection" of
154 	// the respective SVG path commands.
155 			void				move_to(double x, double y, bool rel = false);	// M, m
156 			void				line_to(double x,  double y, bool rel = false);	// L, l
157 			void				hline_to(double x, bool rel = false);			// H, h
158 			void				vline_to(double y, bool rel = false);			// V, v
159 			void				curve3(double x1, double y1,					// Q, q
160 									   double x,  double y, bool rel = false);
161 			void				curve3(double x, double y, bool rel = false);	// T, t
162 			void				curve4(double x1, double y1,					// C, c
163 									   double x2, double y2,
164 									   double x,  double y, bool rel = false);
165 			void				curve4(double x2, double y2,					// S, s
166 									   double x,  double y, bool rel = false);
167 			void				elliptical_arc(double rx, double ry,
168 											   double angle,
169 											   bool large_arc_flag,
170 											   bool sweep_flag,
171 											   double x, double y,
172 											   bool rel = false);				// A, a
173 			void				close_subpath();								// Z, z
174 
175 /*			template<class VertexSource>
176 			void				add_path(VertexSource& vs,
177 										 unsigned path_id = 0,
178 										 bool solid_path = true)
179 								{
180 									fPathStorage.add_path(vs, path_id, solid_path);
181 								}*/
182 
183 			void				SetTitle(const char* title);
184 			void				SetDimensions(uint32 width, uint32 height, BRect viewBox);
185 
186 
187 			// Call these functions on <g> tag (start_element, end_element respectively)
188 			void				push_attr();
189 			void				pop_attr();
190 
191 			// Attribute setting functions.
192 			void				fill(const rgba8& f);
193 			void				stroke(const rgba8& s);
194 			void				even_odd(bool flag);
195 			void				stroke_width(double w);
196 			void				fill_none();
197 			void				fill_url(const char* url);
198 			void				stroke_none();
199 			void				stroke_url(const char* url);
200 			void				opacity(double op);
201 			void				fill_opacity(double op);
202 			void				stroke_opacity(double op);
203 			void				line_join(line_join_e join);
204 			void				line_cap(line_cap_e cap);
205 			void				miter_limit(double ml);
206 			trans_affine&		transform();
207 
208 /*			// Make all polygons CCW-oriented
209 			void				arrange_orientations()
210 			{
211 				fPathStorage.arrange_orientations_all_paths(path_flags_ccw);
212 			}*/
213 
214 			unsigned			operator [](unsigned idx)
215 	        {
216 	            fTransform = fAttributesStorage[idx].transform;
217 	            return fAttributesStorage[idx].index;
218 	        }
219 
220 			status_t			GetIcon(Icon* icon,
221 										SVGImporter* importer,
222 										const char* fallbackName);
223 
224 			void				StartGradient(bool radial = false);
225 			void				EndGradient();
226 			SVGGradient*		CurrentGradient() const
227 									{ return fCurrentGradient; }
228 
229  private:
230 			void				_AddGradient(SVGGradient* gradient);
231 			SVGGradient*		_GradientAt(int32 index) const;
232 			SVGGradient*		_FindGradient(const char* name) const;
233 			status_t			_AddShape(path_attributes& attributes,
234 										  bool outline,
235 										  const Transformable& transform,
236 										  Icon* icon);
237 
238 			path_attributes&	cur_attr();
239 
240 			path_storage		fPathStorage;
241 			attr_storage		fAttributesStorage;
242 			attr_storage		fAttributesStack;
243 
244 			trans_affine		fTransform;
245 
246 			BList				fGradients;
247 			SVGGradient*		fCurrentGradient;
248 
249 			uint32				fWidth;
250 			uint32				fHeight;
251 			BRect				fViewBox;
252 			BString				fTitle;
253 };
254 
255 } // namespace svg
256 } // namespace agg
257 
258 #endif // DOCUMENT_BUILD_H
259