~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/svg/SVGPathUtilities.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) Research In Motion Limited 2010, 2012. 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 "SVGPathUtilities.h"
 
24
 
 
25
#include "Path.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"
 
38
 
 
39
namespace WebCore {
 
40
 
 
41
static SVGPathBuilder* globalSVGPathBuilder(Path& result)
 
42
{
 
43
    static SVGPathBuilder* s_builder = 0;
 
44
    if (!s_builder)
 
45
        s_builder = new SVGPathBuilder;
 
46
 
 
47
    s_builder->setCurrentPath(&result);
 
48
    return s_builder;
 
49
}
 
50
 
 
51
static SVGPathSegListBuilder* globalSVGPathSegListBuilder(SVGPathElement* element, SVGPathSegRole role, SVGPathSegList& result)
 
52
{
 
53
    static SVGPathSegListBuilder* s_builder = 0;
 
54
    if (!s_builder)
 
55
        s_builder = new SVGPathSegListBuilder;
 
56
 
 
57
    s_builder->setCurrentSVGPathElement(element);
 
58
    s_builder->setCurrentSVGPathSegList(result);
 
59
    s_builder->setCurrentSVGPathSegRole(role);
 
60
    return s_builder;
 
61
}
 
62
 
 
63
static SVGPathByteStreamBuilder* globalSVGPathByteStreamBuilder(SVGPathByteStream* result)
 
64
{
 
65
    static SVGPathByteStreamBuilder* s_builder = 0;
 
66
    if (!s_builder)
 
67
        s_builder = new SVGPathByteStreamBuilder;
 
68
 
 
69
    s_builder->setCurrentByteStream(result);
 
70
    return s_builder;
 
71
}
 
72
 
 
73
static SVGPathStringBuilder* globalSVGPathStringBuilder()
 
74
{
 
75
    static SVGPathStringBuilder* s_builder = 0;
 
76
    if (!s_builder)
 
77
        s_builder = new SVGPathStringBuilder;
 
78
 
 
79
    return s_builder;
 
80
}
 
81
 
 
82
static SVGPathTraversalStateBuilder* globalSVGPathTraversalStateBuilder(PathTraversalState& traversalState, float length)
 
83
{
 
84
    static SVGPathTraversalStateBuilder* s_builder = 0;
 
85
    if (!s_builder)
 
86
        s_builder = new SVGPathTraversalStateBuilder;
 
87
 
 
88
    s_builder->setCurrentTraversalState(&traversalState);
 
89
    s_builder->setDesiredLength(length);
 
90
    return s_builder;
 
91
}
 
92
 
 
93
static SVGPathParser* globalSVGPathParser(SVGPathSource* source, SVGPathConsumer* consumer)
 
94
{
 
95
    static SVGPathParser* s_parser = 0;
 
96
    if (!s_parser)
 
97
        s_parser = new SVGPathParser;
 
98
 
 
99
    s_parser->setCurrentSource(source);
 
100
    s_parser->setCurrentConsumer(consumer);
 
101
    return s_parser;
 
102
}
 
103
 
 
104
static SVGPathBlender* globalSVGPathBlender()
 
105
{
 
106
    static SVGPathBlender* s_blender = 0;
 
107
    if (!s_blender)
 
108
        s_blender = new SVGPathBlender;
 
109
 
 
110
    return s_blender;
 
111
}
 
112
 
 
113
bool buildPathFromString(const String& d, Path& result)
 
114
{
 
115
    if (d.isEmpty())
 
116
        return false;
 
117
 
 
118
    SVGPathBuilder* builder = globalSVGPathBuilder(result);
 
119
 
 
120
    OwnPtr<SVGPathStringSource> source = SVGPathStringSource::create(d);
 
121
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
 
122
    bool ok = parser->parsePathDataFromSource(NormalizedParsing);
 
123
    parser->cleanup();
 
124
    return ok;
 
125
}
 
126
 
 
127
bool buildSVGPathByteStreamFromSVGPathSegList(const SVGPathSegList& list, SVGPathByteStream* result, PathParsingMode parsingMode)
 
128
{
 
129
    ASSERT(result);
 
130
    result->clear();
 
131
    if (list.isEmpty())
 
132
        return false;
 
133
 
 
134
    SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result);
 
135
 
 
136
    OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(list);
 
137
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
 
138
    bool ok = parser->parsePathDataFromSource(parsingMode);
 
139
    parser->cleanup();
 
140
    return ok;
 
141
}
 
142
 
 
143
bool appendSVGPathByteStreamFromSVGPathSeg(PassRefPtr<SVGPathSeg> pathSeg, SVGPathByteStream* result, PathParsingMode parsingMode)
 
144
{
 
145
    ASSERT(result);
 
146
    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists!
 
147
    ASSERT(parsingMode == UnalteredParsing);
 
148
 
 
149
    SVGPathSegList appendedItemList(PathSegUnalteredRole);
 
150
    appendedItemList.append(pathSeg);
 
151
    OwnPtr<SVGPathByteStream> appendedByteStream = SVGPathByteStream::create();
 
152
 
 
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);
 
157
    parser->cleanup();
 
158
 
 
159
    if (ok)
 
160
        result->append(appendedByteStream.get());
 
161
 
 
162
    return ok;
 
163
}
 
164
 
 
165
bool buildPathFromByteStream(SVGPathByteStream* stream, Path& result)
 
166
{
 
167
    ASSERT(stream);
 
168
    if (stream->isEmpty())
 
169
        return false;
 
170
 
 
171
    SVGPathBuilder* builder = globalSVGPathBuilder(result);
 
172
 
 
173
    OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
 
174
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
 
175
    bool ok = parser->parsePathDataFromSource(NormalizedParsing);
 
176
    parser->cleanup();
 
177
    return ok;
 
178
}
 
179
 
 
180
bool buildSVGPathSegListFromByteStream(SVGPathByteStream* stream, SVGPathElement* element, SVGPathSegList& result, PathParsingMode parsingMode)
 
181
{
 
182
    ASSERT(stream);
 
183
    if (stream->isEmpty())
 
184
        return false; 
 
185
 
 
186
    SVGPathSegListBuilder* builder = globalSVGPathSegListBuilder(element, parsingMode == NormalizedParsing ? PathSegNormalizedRole : PathSegUnalteredRole, result);
 
187
 
 
188
    OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
 
189
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
 
190
    bool ok = parser->parsePathDataFromSource(parsingMode);
 
191
    parser->cleanup();
 
192
    return ok;
 
193
}
 
194
 
 
195
bool buildStringFromByteStream(SVGPathByteStream* stream, String& result, PathParsingMode parsingMode)
 
196
{
 
197
    ASSERT(stream);
 
198
    if (stream->isEmpty())
 
199
        return false; 
 
200
 
 
201
    SVGPathStringBuilder* builder = globalSVGPathStringBuilder();
 
202
 
 
203
    OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
 
204
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
 
205
    bool ok = parser->parsePathDataFromSource(parsingMode);
 
206
    result = builder->result();
 
207
    parser->cleanup();
 
208
    return ok;
 
209
}
 
210
 
 
211
bool buildStringFromSVGPathSegList(const SVGPathSegList& list, String& result, PathParsingMode parsingMode)
 
212
{
 
213
    result = String();
 
214
    if (list.isEmpty())
 
215
        return false;
 
216
 
 
217
    SVGPathStringBuilder* builder = globalSVGPathStringBuilder();
 
218
 
 
219
    OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(list);
 
220
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
 
221
    bool ok = parser->parsePathDataFromSource(parsingMode);
 
222
    result = builder->result();
 
223
    parser->cleanup();
 
224
    return ok;
 
225
}
 
226
 
 
227
bool buildSVGPathByteStreamFromString(const String& d, SVGPathByteStream* result, PathParsingMode parsingMode)
 
228
{
 
229
    ASSERT(result);
 
230
    result->clear();
 
231
    if (d.isEmpty())
 
232
        return false;
 
233
 
 
234
    SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result);
 
235
 
 
236
    OwnPtr<SVGPathStringSource> source = SVGPathStringSource::create(d);
 
237
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
 
238
    bool ok = parser->parsePathDataFromSource(parsingMode);
 
239
    parser->cleanup();
 
240
    return ok;
 
241
}
 
242
 
 
243
bool buildAnimatedSVGPathByteStream(SVGPathByteStream* fromStream, SVGPathByteStream* toStream, SVGPathByteStream* result, float progress)
 
244
{
 
245
    ASSERT(fromStream);
 
246
    ASSERT(toStream);
 
247
    ASSERT(result);
 
248
    ASSERT(toStream != result);
 
249
 
 
250
    result->clear();
 
251
    if (toStream->isEmpty())
 
252
        return false;
 
253
 
 
254
    SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result);
 
255
 
 
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);
 
260
    blender->cleanup();
 
261
    return ok;
 
262
}
 
263
 
 
264
bool addToSVGPathByteStream(SVGPathByteStream* fromStream, SVGPathByteStream* byStream, unsigned repeatCount)
 
265
{
 
266
    ASSERT(fromStream);
 
267
    ASSERT(byStream);
 
268
    if (fromStream->isEmpty() || byStream->isEmpty())
 
269
        return false;
 
270
 
 
271
    SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(fromStream);
 
272
 
 
273
    OwnPtr<SVGPathByteStream> fromStreamCopy = fromStream->copy();
 
274
    fromStream->clear();
 
275
 
 
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);
 
280
    blender->cleanup();
 
281
    return ok;
 
282
}
 
283
 
 
284
bool getSVGPathSegAtLengthFromSVGPathByteStream(SVGPathByteStream* stream, float length, unsigned& pathSeg)
 
285
{
 
286
    ASSERT(stream);
 
287
    if (stream->isEmpty())
 
288
        return false;
 
289
 
 
290
    PathTraversalState traversalState(PathTraversalState::TraversalSegmentAtLength);
 
291
    SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length);
 
292
 
 
293
    OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
 
294
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
 
295
    bool ok = parser->parsePathDataFromSource(NormalizedParsing);
 
296
    pathSeg = builder->pathSegmentIndex();
 
297
    parser->cleanup();
 
298
    return ok;
 
299
}
 
300
 
 
301
bool getTotalLengthOfSVGPathByteStream(SVGPathByteStream* stream, float& totalLength)
 
302
{
 
303
    ASSERT(stream);
 
304
    if (stream->isEmpty())
 
305
        return false;
 
306
    
 
307
    PathTraversalState traversalState(PathTraversalState::TraversalTotalLength);
 
308
    SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, 0);
 
309
    
 
310
    OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
 
311
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
 
312
    bool ok = parser->parsePathDataFromSource(NormalizedParsing);
 
313
    totalLength = builder->totalLength();
 
314
    parser->cleanup();
 
315
    return ok;
 
316
}
 
317
 
 
318
bool getPointAtLengthOfSVGPathByteStream(SVGPathByteStream* stream, float length, FloatPoint& point)
 
319
{
 
320
    ASSERT(stream);
 
321
    if (stream->isEmpty())
 
322
        return false;
 
323
    
 
324
    PathTraversalState traversalState(PathTraversalState::TraversalPointAtLength);
 
325
    SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length);
 
326
    
 
327
    OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
 
328
    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
 
329
    bool ok = parser->parsePathDataFromSource(NormalizedParsing);
 
330
    point = builder->currentPoint();
 
331
    parser->cleanup();
 
332
    return ok;
 
333
}
 
334
 
 
335
}
 
336
 
 
337
#endif