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
46class SVGImporter;
47
48_BEGIN_ICON_NAMESPACE
49	class Icon;
50	class Transformable;
51_END_ICON_NAMESPACE
52
53_USING_ICON_NAMESPACE
54
55namespace agg {
56namespace svg {
57
58class SVGGradient;
59
60// Basic path attributes
61struct 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
136class 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