xref: /haiku/src/apps/icon-o-matic/import_export/svg/DocumentBuilder.h (revision 55b40aa53a835472ec7952b138ae4256203d02e4)
1 /*
2  * Copyright 2006, 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 "PathTokenizer.h"
43 
44 class Icon;
45 class SVGImporter;
46 class Transformable;
47 
48 namespace agg {
49 namespace svg {
50 
51 class SVGGradient;
52 
53 // Basic path attributes
54 struct path_attributes {
55 
56 	unsigned		index;
57 	rgba8			fill_color;
58 	rgba8			stroke_color;
59 	double			opacity;
60 	bool			fill_flag;
61 	bool			stroke_flag;
62 	bool			even_odd_flag;
63 	line_join_e		line_join;
64 	line_cap_e		line_cap;
65 	double			miter_limit;
66 	double			stroke_width;
67 	trans_affine	transform;
68 
69 	char			stroke_url[64];
70 	char			fill_url[64];
71 
72 	// Empty constructor
73 	path_attributes() :
74 		index			(0),
75 		fill_color		(rgba(0,0,0)),
76 		stroke_color	(rgba(0,0,0)),
77 		opacity			(1.0),
78 		fill_flag		(true),
79 		stroke_flag		(false),
80 		even_odd_flag	(false),
81 		line_join		(miter_join),
82 		line_cap		(butt_cap),
83 		miter_limit		(4.0),
84 		stroke_width	(1.0),
85 		transform		()
86 	{
87 		stroke_url[0] = 0;
88 		fill_url[0] = 0;
89 	}
90 
91 	// Copy constructor
92 	path_attributes(const path_attributes& attr) :
93 		index			(attr.index),
94 		fill_color		(attr.fill_color),
95 		stroke_color	(attr.stroke_color),
96 		opacity			(attr.opacity),
97 		fill_flag		(attr.fill_flag),
98 		stroke_flag		(attr.stroke_flag),
99 		even_odd_flag	(attr.even_odd_flag),
100 		line_join		(attr.line_join),
101 		line_cap		(attr.line_cap),
102 		miter_limit		(attr.miter_limit),
103 		stroke_width	(attr.stroke_width),
104 		transform		(attr.transform)
105 	{
106 		sprintf(stroke_url, "%s", attr.stroke_url);
107 		sprintf(fill_url, "%s", attr.fill_url);
108 	}
109 
110 	// Copy constructor with new index value
111 	path_attributes(const path_attributes& attr, unsigned idx) :
112 		index			(idx),
113 		fill_color		(attr.fill_color),
114 		stroke_color	(attr.stroke_color),
115 		fill_flag		(attr.fill_flag),
116 		stroke_flag		(attr.stroke_flag),
117 		even_odd_flag	(attr.even_odd_flag),
118 		line_join		(attr.line_join),
119 		line_cap		(attr.line_cap),
120 		miter_limit		(attr.miter_limit),
121 		stroke_width	(attr.stroke_width),
122 		transform		(attr.transform)
123 	{
124 		sprintf(stroke_url, "%s", attr.stroke_url);
125 		sprintf(fill_url, "%s", attr.fill_url);
126 	}
127 };
128 
129 class DocumentBuilder {
130  public:
131 
132 	typedef pod_bvector<path_attributes>		attr_storage;
133 
134 								DocumentBuilder();
135 
136 			void				remove_all();
137 
138 	// Use these functions as follows:
139 	// begin_path() when the XML tag <path> comes ("start_element" handler)
140 	// parse_path() on "d=" tag attribute
141 	// end_path() when parsing of the entire tag is done.
142 			void				begin_path();
143 			void				parse_path(PathTokenizer& tok);
144 			void				end_path();
145 
146 	// The following functions are essentially a "reflection" of
147 	// the respective SVG path commands.
148 			void				move_to(double x, double y, bool rel = false);	// M, m
149 			void				line_to(double x,  double y, bool rel = false);	// L, l
150 			void				hline_to(double x, bool rel = false);			// H, h
151 			void				vline_to(double y, bool rel = false);			// V, v
152 			void				curve3(double x1, double y1,					// Q, q
153 									   double x,  double y, bool rel = false);
154 			void				curve3(double x, double y, bool rel = false);	// T, t
155 			void				curve4(double x1, double y1,					// C, c
156 									   double x2, double y2,
157 									   double x,  double y, bool rel = false);
158 			void				curve4(double x2, double y2,					// S, s
159 									   double x,  double y, bool rel = false);
160 			void				elliptical_arc(double rx, double ry,
161 											   double angle,
162 											   bool large_arc_flag,
163 											   bool sweep_flag,
164 											   double x, double y,
165 											   bool rel = false);				// A, a
166 			void				close_subpath();								// Z, z
167 
168 /*			template<class VertexSource>
169 			void				add_path(VertexSource& vs,
170 										 unsigned path_id = 0,
171 										 bool solid_path = true)
172 								{
173 									fPathStorage.add_path(vs, path_id, solid_path);
174 								}*/
175 
176 			void				SetTitle(const char* title);
177 			void				SetDimensions(uint32 width, uint32 height, BRect viewBox);
178 
179 
180 			// Call these functions on <g> tag (start_element, end_element respectively)
181 			void				push_attr();
182 			void				pop_attr();
183 
184 			// Attribute setting functions.
185 			void				fill(const rgba8& f);
186 			void				stroke(const rgba8& s);
187 			void				even_odd(bool flag);
188 			void				stroke_width(double w);
189 			void				fill_none();
190 			void				fill_url(const char* url);
191 			void				stroke_none();
192 			void				stroke_url(const char* url);
193 			void				opacity(double op);
194 			void				fill_opacity(double op);
195 			void				stroke_opacity(double op);
196 			void				line_join(line_join_e join);
197 			void				line_cap(line_cap_e cap);
198 			void				miter_limit(double ml);
199 			trans_affine&		transform();
200 
201 /*			// Make all polygons CCW-oriented
202 			void				arrange_orientations()
203 			{
204 				fPathStorage.arrange_orientations_all_paths(path_flags_ccw);
205 			}*/
206 
207 			unsigned			operator [](unsigned idx)
208 	        {
209 	            fTransform = fAttributesStorage[idx].transform;
210 	            return fAttributesStorage[idx].index;
211 	        }
212 
213 			status_t			GetIcon(Icon* icon,
214 										SVGImporter* importer,
215 										const char* fallbackName);
216 
217 			void				StartGradient(bool radial = false);
218 			void				EndGradient();
219 			SVGGradient*		CurrentGradient() const
220 									{ return fCurrentGradient; }
221 
222  private:
223 			void				_AddGradient(SVGGradient* gradient);
224 			SVGGradient*		_GradientAt(int32 index) const;
225 			SVGGradient*		_FindGradient(const char* name) const;
226 			status_t			_AddShape(path_attributes& attributes,
227 										  bool outline,
228 										  const Transformable& transform,
229 										  Icon* icon);
230 
231 			path_attributes&	cur_attr();
232 
233 			path_storage		fPathStorage;
234 			attr_storage		fAttributesStorage;
235 			attr_storage		fAttributesStack;
236 
237 			trans_affine		fTransform;
238 
239 			BList				fGradients;
240 			SVGGradient*		fCurrentGradient;
241 
242 			uint32				fWidth;
243 			uint32				fHeight;
244 			BRect				fViewBox;
245 			BString				fTitle;
246 };
247 
248 } // namespace svg
249 } // namespace agg
250 
251 #endif // DOCUMENT_BUILD_H
252