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