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
OwnPtr<SVGPathByteStream> appendedByteStream = SVGPathByteStream::create();
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
OwnPtr<SVGPathByteStream> 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, FloatPoint& 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();