1 /*
2 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21
22 #if ENABLE(SVG)
23 #include "SVGPathParserFactory.h"
24
25 #include "PathTraversalState.h"
26 #include "SVGPathBlender.h"
27 #include "SVGPathBuilder.h"
28 #include "SVGPathByteStreamBuilder.h"
29 #include "SVGPathByteStreamSource.h"
30 #include "SVGPathElement.h"
31 #include "SVGPathParser.h"
32 #include "SVGPathSegListBuilder.h"
33 #include "SVGPathSegListSource.h"
34 #include "SVGPathStringBuilder.h"
35 #include "SVGPathStringSource.h"
36 #include "SVGPathTraversalStateBuilder.h"
37
38 namespace WebCore {
39
globalSVGPathBuilder(Path & result)40 static SVGPathBuilder* globalSVGPathBuilder(Path& result)
41 {
42 static SVGPathBuilder* s_builder = 0;
43 if (!s_builder)
44 s_builder = new SVGPathBuilder;
45
46 s_builder->setCurrentPath(&result);
47 return s_builder;
48 }
49
globalSVGPathSegListBuilder(SVGPathElement * element,SVGPathSegRole role,SVGPathSegList & result)50 static SVGPathSegListBuilder* globalSVGPathSegListBuilder(SVGPathElement* element, SVGPathSegRole role, SVGPathSegList& result)
51 {
52 static SVGPathSegListBuilder* s_builder = 0;
53 if (!s_builder)
54 s_builder = new SVGPathSegListBuilder;
55
56 s_builder->setCurrentSVGPathElement(element);
57 s_builder->setCurrentSVGPathSegList(result);
58 s_builder->setCurrentSVGPathSegRole(role);
59 return s_builder;
60 }
61
globalSVGPathByteStreamBuilder(SVGPathByteStream * result)62 static SVGPathByteStreamBuilder* globalSVGPathByteStreamBuilder(SVGPathByteStream* result)
63 {
64 static SVGPathByteStreamBuilder* s_builder = 0;
65 if (!s_builder)
66 s_builder = new SVGPathByteStreamBuilder;
67
68 s_builder->setCurrentByteStream(result);
69 return s_builder;
70 }
71
globalSVGPathStringBuilder()72 static SVGPathStringBuilder* globalSVGPathStringBuilder()
73 {
74 static SVGPathStringBuilder* s_builder = 0;
75 if (!s_builder)
76 s_builder = new SVGPathStringBuilder;
77
78 return s_builder;
79 }
80
globalSVGPathTraversalStateBuilder(PathTraversalState & traversalState,float length)81 static SVGPathTraversalStateBuilder* globalSVGPathTraversalStateBuilder(PathTraversalState& traversalState, float length)
82 {
83 static SVGPathTraversalStateBuilder* s_builder = 0;
84 if (!s_builder)
85 s_builder = new SVGPathTraversalStateBuilder;
86
87 s_builder->setCurrentTraversalState(&traversalState);
88 s_builder->setDesiredLength(length);
89 return s_builder;
90 }
91
globalSVGPathParser(SVGPathSource * source,SVGPathConsumer * consumer)92 static SVGPathParser* globalSVGPathParser(SVGPathSource* source, SVGPathConsumer* consumer)
93 {
94 static SVGPathParser* s_parser = 0;
95 if (!s_parser)
96 s_parser = new SVGPathParser;
97
98 s_parser->setCurrentSource(source);
99 s_parser->setCurrentConsumer(consumer);
100 return s_parser;
101 }
102
globalSVGPathBlender()103 static SVGPathBlender* globalSVGPathBlender()
104 {
105 static SVGPathBlender* s_blender = 0;
106 if (!s_blender)
107 s_blender = new SVGPathBlender;
108
109 return s_blender;
110 }
111
self()112 SVGPathParserFactory* SVGPathParserFactory::self()
113 {
114 static SVGPathParserFactory* s_instance = 0;
115 if (!s_instance)
116 s_instance = new SVGPathParserFactory;
117
118 return s_instance;
119 }
120
SVGPathParserFactory()121 SVGPathParserFactory::SVGPathParserFactory()
122 {
123 }
124
~SVGPathParserFactory()125 SVGPathParserFactory::~SVGPathParserFactory()
126 {
127 }
128
buildPathFromString(const String & d,Path & result)129 bool SVGPathParserFactory::buildPathFromString(const String& d, Path& result)
130 {
131 if (d.isEmpty())
132 return false;
133
134 SVGPathBuilder* builder = globalSVGPathBuilder(result);
135
136 OwnPtr<SVGPathStringSource> source = SVGPathStringSource::create(d);
137 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
138 bool ok = parser->parsePathDataFromSource(NormalizedParsing);
139 parser->cleanup();
140 return ok;
141 }
142
buildSVGPathByteStreamFromSVGPathSegList(const SVGPathSegList & list,OwnPtr<SVGPathByteStream> & result,PathParsingMode parsingMode)143 bool SVGPathParserFactory::buildSVGPathByteStreamFromSVGPathSegList(const SVGPathSegList& list, OwnPtr<SVGPathByteStream>& result, PathParsingMode parsingMode)
144 {
145 result = SVGPathByteStream::create();
146 if (list.isEmpty())
147 return false;
148
149 SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result.get());
150
151 OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(list);
152 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
153 bool ok = parser->parsePathDataFromSource(parsingMode);
154 parser->cleanup();
155 return ok;
156 }
157
buildPathFromByteStream(SVGPathByteStream * stream,Path & result)158 bool SVGPathParserFactory::buildPathFromByteStream(SVGPathByteStream* stream, Path& result)
159 {
160 ASSERT(stream);
161 if (stream->isEmpty())
162 return false;
163
164 SVGPathBuilder* builder = globalSVGPathBuilder(result);
165
166 OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
167 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
168 bool ok = parser->parsePathDataFromSource(NormalizedParsing);
169 parser->cleanup();
170 return ok;
171 }
172
buildSVGPathSegListFromByteStream(SVGPathByteStream * stream,SVGPathElement * element,SVGPathSegList & result,PathParsingMode parsingMode)173 bool SVGPathParserFactory::buildSVGPathSegListFromByteStream(SVGPathByteStream* stream, SVGPathElement* element, SVGPathSegList& result, PathParsingMode parsingMode)
174 {
175 ASSERT(stream);
176 if (stream->isEmpty())
177 return false;
178
179 SVGPathSegListBuilder* builder = globalSVGPathSegListBuilder(element, parsingMode == NormalizedParsing ? PathSegNormalizedRole : PathSegUnalteredRole, result);
180
181 OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
182 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
183 bool ok = parser->parsePathDataFromSource(parsingMode);
184 parser->cleanup();
185 return ok;
186 }
187
buildStringFromByteStream(SVGPathByteStream * stream,String & result,PathParsingMode parsingMode)188 bool SVGPathParserFactory::buildStringFromByteStream(SVGPathByteStream* stream, String& result, PathParsingMode parsingMode)
189 {
190 ASSERT(stream);
191 if (stream->isEmpty())
192 return false;
193
194 SVGPathStringBuilder* builder = globalSVGPathStringBuilder();
195
196 OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
197 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
198 bool ok = parser->parsePathDataFromSource(parsingMode);
199 result = builder->result();
200 parser->cleanup();
201 return ok;
202 }
203
buildStringFromSVGPathSegList(const SVGPathSegList & list,String & result,PathParsingMode parsingMode)204 bool SVGPathParserFactory::buildStringFromSVGPathSegList(const SVGPathSegList& list, String& result, PathParsingMode parsingMode)
205 {
206 result = String();
207 if (list.isEmpty())
208 return false;
209
210 SVGPathStringBuilder* builder = globalSVGPathStringBuilder();
211
212 OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(list);
213 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
214 bool ok = parser->parsePathDataFromSource(parsingMode);
215 result = builder->result();
216 parser->cleanup();
217 return ok;
218 }
219
buildSVGPathByteStreamFromString(const String & d,OwnPtr<SVGPathByteStream> & result,PathParsingMode parsingMode)220 bool SVGPathParserFactory::buildSVGPathByteStreamFromString(const String& d, OwnPtr<SVGPathByteStream>& result, PathParsingMode parsingMode)
221 {
222 result = SVGPathByteStream::create();
223 if (d.isEmpty())
224 return false;
225
226 SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result.get());
227
228 OwnPtr<SVGPathStringSource> source = SVGPathStringSource::create(d);
229 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
230 bool ok = parser->parsePathDataFromSource(parsingMode);
231 parser->cleanup();
232 return ok;
233 }
234
buildAnimatedSVGPathByteStream(SVGPathByteStream * fromStream,SVGPathByteStream * toStream,OwnPtr<SVGPathByteStream> & result,float progress)235 bool SVGPathParserFactory::buildAnimatedSVGPathByteStream(SVGPathByteStream* fromStream, SVGPathByteStream* toStream, OwnPtr<SVGPathByteStream>& result, float progress)
236 {
237 ASSERT(fromStream);
238 ASSERT(toStream);
239 result = SVGPathByteStream::create();
240 if (fromStream->isEmpty() || toStream->isEmpty())
241 return false;
242
243 SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result.get());
244
245 OwnPtr<SVGPathByteStreamSource> fromSource = SVGPathByteStreamSource::create(fromStream);
246 OwnPtr<SVGPathByteStreamSource> toSource = SVGPathByteStreamSource::create(toStream);
247 SVGPathBlender* blender = globalSVGPathBlender();
248 bool ok = blender->blendAnimatedPath(progress, fromSource.get(), toSource.get(), builder);
249 blender->cleanup();
250 return ok;
251 }
252
getSVGPathSegAtLengthFromSVGPathByteStream(SVGPathByteStream * stream,float length,unsigned long & pathSeg)253 bool SVGPathParserFactory::getSVGPathSegAtLengthFromSVGPathByteStream(SVGPathByteStream* stream, float length, unsigned long& pathSeg)
254 {
255 ASSERT(stream);
256 if (stream->isEmpty())
257 return false;
258
259 PathTraversalState traversalState(PathTraversalState::TraversalSegmentAtLength);
260 SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length);
261
262 OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
263 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
264 bool ok = parser->parsePathDataFromSource(NormalizedParsing);
265 pathSeg = builder->pathSegmentIndex();
266 parser->cleanup();
267 return ok;
268 }
269
270 }
271
272 #endif
273