summaryrefslogtreecommitdiff
path: root/Source/WebCore/svg/SVGPathUtilities.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
commit2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch)
tree988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebCore/svg/SVGPathUtilities.cpp
parentdd91e772430dc294e3bf478c119ef8d43c0a3358 (diff)
downloadqtwebkit-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.cpp315
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