2 * Copyright (C) Research In Motion Limited 2010, 2012. All rights reserved.
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.
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.
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.
23 #include "SVGPathUtilities.h"
26 #include "PathTraversalState.h"
27 #include "SVGPathBlender.h"
28 #include "SVGPathBuilder.h"
29 #include "SVGPathByteStreamBuilder.h"
30 #include "SVGPathByteStreamSource.h"
31 #include "SVGPathElement.h"
32 #include "SVGPathParser.h"
33 #include "SVGPathSegListBuilder.h"
34 #include "SVGPathSegListSource.h"
35 #include "SVGPathStringBuilder.h"
36 #include "SVGPathStringSource.h"
37 #include "SVGPathTraversalStateBuilder.h"
41 static SVGPathBuilder* globalSVGPathBuilder(Path& result)
43 static SVGPathBuilder* s_builder = 0;
45 s_builder = new SVGPathBuilder;
47 s_builder->setCurrentPath(&result);
51 static SVGPathSegListBuilder* globalSVGPathSegListBuilder(SVGPathElement* element, SVGPathSegRole role, SVGPathSegList& result)
53 static SVGPathSegListBuilder* s_builder = 0;
55 s_builder = new SVGPathSegListBuilder;
57 s_builder->setCurrentSVGPathElement(element);
58 s_builder->setCurrentSVGPathSegList(result);
59 s_builder->setCurrentSVGPathSegRole(role);
63 static SVGPathByteStreamBuilder* globalSVGPathByteStreamBuilder(SVGPathByteStream* result)
65 static SVGPathByteStreamBuilder* s_builder = 0;
67 s_builder = new SVGPathByteStreamBuilder;
69 s_builder->setCurrentByteStream(result);
73 static SVGPathStringBuilder* globalSVGPathStringBuilder()
75 static SVGPathStringBuilder* s_builder = 0;
77 s_builder = new SVGPathStringBuilder;
82 static SVGPathTraversalStateBuilder* globalSVGPathTraversalStateBuilder(PathTraversalState& traversalState, float length)
84 static SVGPathTraversalStateBuilder* s_builder = 0;
86 s_builder = new SVGPathTraversalStateBuilder;
88 s_builder->setCurrentTraversalState(&traversalState);
89 s_builder->setDesiredLength(length);
93 static SVGPathParser* globalSVGPathParser(SVGPathSource* source, SVGPathConsumer* consumer)
95 static SVGPathParser* s_parser = 0;
97 s_parser = new SVGPathParser;
99 s_parser->setCurrentSource(source);
100 s_parser->setCurrentConsumer(consumer);
104 static SVGPathBlender* globalSVGPathBlender()
106 static SVGPathBlender* s_blender = 0;
108 s_blender = new SVGPathBlender;
113 bool buildPathFromString(const String& d, Path& result)
118 SVGPathBuilder* builder = globalSVGPathBuilder(result);
120 OwnPtr<SVGPathStringSource> source = SVGPathStringSource::create(d);
121 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
122 bool ok = parser->parsePathDataFromSource(NormalizedParsing);
127 bool buildSVGPathByteStreamFromSVGPathSegList(const SVGPathSegList& list, SVGPathByteStream* result, PathParsingMode parsingMode)
134 SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result);
136 OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(list);
137 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
138 bool ok = parser->parsePathDataFromSource(parsingMode);
143 bool appendSVGPathByteStreamFromSVGPathSeg(PassRefPtr<SVGPathSeg> pathSeg, SVGPathByteStream* result, PathParsingMode parsingMode)
146 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists!
147 ASSERT(parsingMode == UnalteredParsing);
149 SVGPathSegList appendedItemList(PathSegUnalteredRole);
150 appendedItemList.append(pathSeg);
151 auto appendedByteStream = std::make_unique<SVGPathByteStream>();
153 SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(appendedByteStream.get());
154 OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(appendedItemList);
155 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
156 bool ok = parser->parsePathDataFromSource(parsingMode, false);
160 result->append(appendedByteStream.get());
165 bool buildPathFromByteStream(SVGPathByteStream* stream, Path& result)
168 if (stream->isEmpty())
171 SVGPathBuilder* builder = globalSVGPathBuilder(result);
173 OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
174 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
175 bool ok = parser->parsePathDataFromSource(NormalizedParsing);
180 bool buildSVGPathSegListFromByteStream(SVGPathByteStream* stream, SVGPathElement* element, SVGPathSegList& result, PathParsingMode parsingMode)
183 if (stream->isEmpty())
186 SVGPathSegListBuilder* builder = globalSVGPathSegListBuilder(element, parsingMode == NormalizedParsing ? PathSegNormalizedRole : PathSegUnalteredRole, result);
188 OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
189 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
190 bool ok = parser->parsePathDataFromSource(parsingMode);
195 bool buildStringFromByteStream(SVGPathByteStream* stream, String& result, PathParsingMode parsingMode)
198 if (stream->isEmpty())
201 SVGPathStringBuilder* builder = globalSVGPathStringBuilder();
203 OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
204 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
205 bool ok = parser->parsePathDataFromSource(parsingMode);
206 result = builder->result();
211 bool buildStringFromSVGPathSegList(const SVGPathSegList& list, String& result, PathParsingMode parsingMode)
217 SVGPathStringBuilder* builder = globalSVGPathStringBuilder();
219 OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(list);
220 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
221 bool ok = parser->parsePathDataFromSource(parsingMode);
222 result = builder->result();
227 bool buildSVGPathByteStreamFromString(const String& d, SVGPathByteStream* result, PathParsingMode parsingMode)
234 SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result);
236 OwnPtr<SVGPathStringSource> source = SVGPathStringSource::create(d);
237 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
238 bool ok = parser->parsePathDataFromSource(parsingMode);
243 bool buildAnimatedSVGPathByteStream(SVGPathByteStream* fromStream, SVGPathByteStream* toStream, SVGPathByteStream* result, float progress)
248 ASSERT(toStream != result);
251 if (toStream->isEmpty())
254 SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result);
256 OwnPtr<SVGPathByteStreamSource> fromSource = SVGPathByteStreamSource::create(fromStream);
257 OwnPtr<SVGPathByteStreamSource> toSource = SVGPathByteStreamSource::create(toStream);
258 SVGPathBlender* blender = globalSVGPathBlender();
259 bool ok = blender->blendAnimatedPath(progress, fromSource.get(), toSource.get(), builder);
264 bool addToSVGPathByteStream(SVGPathByteStream* fromStream, SVGPathByteStream* byStream, unsigned repeatCount)
268 if (fromStream->isEmpty() || byStream->isEmpty())
271 SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(fromStream);
273 auto fromStreamCopy = fromStream->copy();
276 OwnPtr<SVGPathByteStreamSource> fromSource = SVGPathByteStreamSource::create(fromStreamCopy.get());
277 OwnPtr<SVGPathByteStreamSource> bySource = SVGPathByteStreamSource::create(byStream);
278 SVGPathBlender* blender = globalSVGPathBlender();
279 bool ok = blender->addAnimatedPath(fromSource.get(), bySource.get(), builder, repeatCount);
284 bool getSVGPathSegAtLengthFromSVGPathByteStream(SVGPathByteStream* stream, float length, unsigned& pathSeg)
287 if (stream->isEmpty())
290 PathTraversalState traversalState(PathTraversalState::TraversalSegmentAtLength);
291 SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length);
293 OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
294 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
295 bool ok = parser->parsePathDataFromSource(NormalizedParsing);
296 pathSeg = builder->pathSegmentIndex();
301 bool getTotalLengthOfSVGPathByteStream(SVGPathByteStream* stream, float& totalLength)
304 if (stream->isEmpty())
307 PathTraversalState traversalState(PathTraversalState::TraversalTotalLength);
308 SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, 0);
310 OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
311 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
312 bool ok = parser->parsePathDataFromSource(NormalizedParsing);
313 totalLength = builder->totalLength();
318 bool getPointAtLengthOfSVGPathByteStream(SVGPathByteStream* stream, float length, SVGPoint& point)
321 if (stream->isEmpty())
324 PathTraversalState traversalState(PathTraversalState::TraversalPointAtLength);
325 SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length);
327 OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
328 SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
329 bool ok = parser->parsePathDataFromSource(NormalizedParsing);
330 point = builder->currentPoint();