diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-07 11:21:11 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-07 11:21:11 +0200 |
commit | 2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch) | |
tree | 988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebCore/svg/SVGPathUtilities.cpp | |
parent | dd91e772430dc294e3bf478c119ef8d43c0a3358 (diff) | |
download | qtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz |
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/WebCore/svg/SVGPathUtilities.cpp')
-rw-r--r-- | Source/WebCore/svg/SVGPathUtilities.cpp | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/Source/WebCore/svg/SVGPathUtilities.cpp b/Source/WebCore/svg/SVGPathUtilities.cpp new file mode 100644 index 000000000..a5af9e704 --- /dev/null +++ b/Source/WebCore/svg/SVGPathUtilities.cpp @@ -0,0 +1,315 @@ +/* + * Copyright (C) Research In Motion Limited 2010, 2012. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#if ENABLE(SVG) +#include "SVGPathUtilities.h" + +#include "Path.h" +#include "PathTraversalState.h" +#include "SVGPathBlender.h" +#include "SVGPathBuilder.h" +#include "SVGPathByteStreamBuilder.h" +#include "SVGPathByteStreamSource.h" +#include "SVGPathElement.h" +#include "SVGPathParser.h" +#include "SVGPathSegListBuilder.h" +#include "SVGPathSegListSource.h" +#include "SVGPathStringBuilder.h" +#include "SVGPathStringSource.h" +#include "SVGPathTraversalStateBuilder.h" + +namespace WebCore { + +static SVGPathBuilder* globalSVGPathBuilder(Path& result) +{ + static SVGPathBuilder* s_builder = 0; + if (!s_builder) + s_builder = new SVGPathBuilder; + + s_builder->setCurrentPath(&result); + return s_builder; +} + +static SVGPathSegListBuilder* globalSVGPathSegListBuilder(SVGPathElement* element, SVGPathSegRole role, SVGPathSegList& result) +{ + static SVGPathSegListBuilder* s_builder = 0; + if (!s_builder) + s_builder = new SVGPathSegListBuilder; + + s_builder->setCurrentSVGPathElement(element); + s_builder->setCurrentSVGPathSegList(result); + s_builder->setCurrentSVGPathSegRole(role); + return s_builder; +} + +static SVGPathByteStreamBuilder* globalSVGPathByteStreamBuilder(SVGPathByteStream* result) +{ + static SVGPathByteStreamBuilder* s_builder = 0; + if (!s_builder) + s_builder = new SVGPathByteStreamBuilder; + + s_builder->setCurrentByteStream(result); + return s_builder; +} + +static SVGPathStringBuilder* globalSVGPathStringBuilder() +{ + static SVGPathStringBuilder* s_builder = 0; + if (!s_builder) + s_builder = new SVGPathStringBuilder; + + return s_builder; +} + +static SVGPathTraversalStateBuilder* globalSVGPathTraversalStateBuilder(PathTraversalState& traversalState, float length) +{ + static SVGPathTraversalStateBuilder* s_builder = 0; + if (!s_builder) + s_builder = new SVGPathTraversalStateBuilder; + + s_builder->setCurrentTraversalState(&traversalState); + s_builder->setDesiredLength(length); + return s_builder; +} + +static SVGPathParser* globalSVGPathParser(SVGPathSource* source, SVGPathConsumer* consumer) +{ + static SVGPathParser* s_parser = 0; + if (!s_parser) + s_parser = new SVGPathParser; + + s_parser->setCurrentSource(source); + s_parser->setCurrentConsumer(consumer); + return s_parser; +} + +static SVGPathBlender* globalSVGPathBlender() +{ + static SVGPathBlender* s_blender = 0; + if (!s_blender) + s_blender = new SVGPathBlender; + + return s_blender; +} + +bool buildPathFromString(const String& d, Path& result) +{ + if (d.isEmpty()) + return false; + + SVGPathBuilder* builder = globalSVGPathBuilder(result); + + OwnPtr<SVGPathStringSource> source = SVGPathStringSource::create(d); + SVGPathParser* parser = globalSVGPathParser(source.get(), builder); + bool ok = parser->parsePathDataFromSource(NormalizedParsing); + parser->cleanup(); + return ok; +} + +bool buildSVGPathByteStreamFromSVGPathSegList(const SVGPathSegList& list, SVGPathByteStream* result, PathParsingMode parsingMode) +{ + ASSERT(result); + result->clear(); + if (list.isEmpty()) + return false; + + SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result); + + OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(list); + SVGPathParser* parser = globalSVGPathParser(source.get(), builder); + bool ok = parser->parsePathDataFromSource(parsingMode); + parser->cleanup(); + return ok; +} + +bool buildPathFromByteStream(SVGPathByteStream* stream, Path& result) +{ + ASSERT(stream); + if (stream->isEmpty()) + return false; + + SVGPathBuilder* builder = globalSVGPathBuilder(result); + + OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream); + SVGPathParser* parser = globalSVGPathParser(source.get(), builder); + bool ok = parser->parsePathDataFromSource(NormalizedParsing); + parser->cleanup(); + return ok; +} + +bool buildSVGPathSegListFromByteStream(SVGPathByteStream* stream, SVGPathElement* element, SVGPathSegList& result, PathParsingMode parsingMode) +{ + ASSERT(stream); + if (stream->isEmpty()) + return false; + + SVGPathSegListBuilder* builder = globalSVGPathSegListBuilder(element, parsingMode == NormalizedParsing ? PathSegNormalizedRole : PathSegUnalteredRole, result); + + OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream); + SVGPathParser* parser = globalSVGPathParser(source.get(), builder); + bool ok = parser->parsePathDataFromSource(parsingMode); + parser->cleanup(); + return ok; +} + +bool buildStringFromByteStream(SVGPathByteStream* stream, String& result, PathParsingMode parsingMode) +{ + ASSERT(stream); + if (stream->isEmpty()) + return false; + + SVGPathStringBuilder* builder = globalSVGPathStringBuilder(); + + OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream); + SVGPathParser* parser = globalSVGPathParser(source.get(), builder); + bool ok = parser->parsePathDataFromSource(parsingMode); + result = builder->result(); + parser->cleanup(); + return ok; +} + +bool buildStringFromSVGPathSegList(const SVGPathSegList& list, String& result, PathParsingMode parsingMode) +{ + result = String(); + if (list.isEmpty()) + return false; + + SVGPathStringBuilder* builder = globalSVGPathStringBuilder(); + + OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(list); + SVGPathParser* parser = globalSVGPathParser(source.get(), builder); + bool ok = parser->parsePathDataFromSource(parsingMode); + result = builder->result(); + parser->cleanup(); + return ok; +} + +bool buildSVGPathByteStreamFromString(const String& d, SVGPathByteStream* result, PathParsingMode parsingMode) +{ + ASSERT(result); + result->clear(); + if (d.isEmpty()) + return false; + + SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result); + + OwnPtr<SVGPathStringSource> source = SVGPathStringSource::create(d); + SVGPathParser* parser = globalSVGPathParser(source.get(), builder); + bool ok = parser->parsePathDataFromSource(parsingMode); + parser->cleanup(); + return ok; +} + +bool buildAnimatedSVGPathByteStream(SVGPathByteStream* fromStream, SVGPathByteStream* toStream, SVGPathByteStream* result, float progress) +{ + ASSERT(fromStream); + ASSERT(toStream); + ASSERT(result); + ASSERT(toStream != result); + + result->clear(); + if (toStream->isEmpty()) + return false; + + SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result); + + OwnPtr<SVGPathByteStreamSource> fromSource = SVGPathByteStreamSource::create(fromStream); + OwnPtr<SVGPathByteStreamSource> toSource = SVGPathByteStreamSource::create(toStream); + SVGPathBlender* blender = globalSVGPathBlender(); + bool ok = blender->blendAnimatedPath(progress, fromSource.get(), toSource.get(), builder); + blender->cleanup(); + return ok; +} + +bool addToSVGPathByteStream(SVGPathByteStream* fromStream, SVGPathByteStream* byStream, unsigned repeatCount) +{ + ASSERT(fromStream); + ASSERT(byStream); + if (fromStream->isEmpty() || byStream->isEmpty()) + return false; + + SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(fromStream); + + OwnPtr<SVGPathByteStream> fromStreamCopy = fromStream->copy(); + fromStream->clear(); + + OwnPtr<SVGPathByteStreamSource> fromSource = SVGPathByteStreamSource::create(fromStreamCopy.get()); + OwnPtr<SVGPathByteStreamSource> bySource = SVGPathByteStreamSource::create(byStream); + SVGPathBlender* blender = globalSVGPathBlender(); + bool ok = blender->addAnimatedPath(fromSource.get(), bySource.get(), builder, repeatCount); + blender->cleanup(); + return ok; +} + +bool getSVGPathSegAtLengthFromSVGPathByteStream(SVGPathByteStream* stream, float length, unsigned& pathSeg) +{ + ASSERT(stream); + if (stream->isEmpty()) + return false; + + PathTraversalState traversalState(PathTraversalState::TraversalSegmentAtLength); + SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length); + + OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream); + SVGPathParser* parser = globalSVGPathParser(source.get(), builder); + bool ok = parser->parsePathDataFromSource(NormalizedParsing); + pathSeg = builder->pathSegmentIndex(); + parser->cleanup(); + return ok; +} + +bool getTotalLengthOfSVGPathByteStream(SVGPathByteStream* stream, float& totalLength) +{ + ASSERT(stream); + if (stream->isEmpty()) + return false; + + PathTraversalState traversalState(PathTraversalState::TraversalTotalLength); + SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, 0); + + OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream); + SVGPathParser* parser = globalSVGPathParser(source.get(), builder); + bool ok = parser->parsePathDataFromSource(NormalizedParsing); + totalLength = builder->totalLength(); + parser->cleanup(); + return ok; +} + +bool getPointAtLengthOfSVGPathByteStream(SVGPathByteStream* stream, float length, FloatPoint& point) +{ + ASSERT(stream); + if (stream->isEmpty()) + return false; + + PathTraversalState traversalState(PathTraversalState::TraversalPointAtLength); + SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length); + + OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream); + SVGPathParser* parser = globalSVGPathParser(source.get(), builder); + bool ok = parser->parsePathDataFromSource(NormalizedParsing); + point = builder->currentPoint(); + parser->cleanup(); + return ok; +} + +} + +#endif |