summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/2geom/include/2geom/path-sink.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/2geom/include/2geom/path-sink.h')
-rw-r--r--src/3rdparty/2geom/include/2geom/path-sink.h253
1 files changed, 253 insertions, 0 deletions
diff --git a/src/3rdparty/2geom/include/2geom/path-sink.h b/src/3rdparty/2geom/include/2geom/path-sink.h
new file mode 100644
index 0000000..35bd1cd
--- /dev/null
+++ b/src/3rdparty/2geom/include/2geom/path-sink.h
@@ -0,0 +1,253 @@
+/**
+ * \file
+ * \brief callback interface for SVG path data
+ *//*
+ * Copyright 2007 MenTaLguY <mental@rydia.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ */
+
+#ifndef LIB2GEOM_SEEN_PATH_SINK_H
+#define LIB2GEOM_SEEN_PATH_SINK_H
+
+#include <2geom/forward.h>
+#include <2geom/pathvector.h>
+#include <2geom/curves.h>
+#include <iterator>
+
+namespace Geom {
+
+
+/** @brief Callback interface for processing path data.
+ *
+ * PathSink provides an interface that allows one to easily write
+ * code which processes path data, for instance when converting
+ * between path formats used by different graphics libraries.
+ * It is also useful for writing algorithms which must do something
+ * for each curve in the path.
+ *
+ * To store a path in a new format, implement the virtual methods
+ * for segments in a derived class and call feed().
+ *
+ * @ingroup Paths
+ */
+class PathSink {
+public:
+ /** @brief Move to a different point without creating a segment.
+ * Usually starts a new subpath. */
+ virtual void moveTo(Point const &p) = 0;
+ /// Output a line segment.
+ virtual void lineTo(Point const &p) = 0;
+ /// Output a quadratic Bezier segment.
+ virtual void curveTo(Point const &c0, Point const &c1, Point const &p) = 0;
+ /// Output a cubic Bezier segment.
+ virtual void quadTo(Point const &c, Point const &p) = 0;
+ /** @brief Output an elliptical arc segment.
+ * See the EllipticalArc class for the documentation of parameters. */
+ virtual void arcTo(Coord rx, Coord ry, Coord angle,
+ bool large_arc, bool sweep, Point const &p) = 0;
+
+ /// Close the current path with a line segment.
+ virtual void closePath() = 0;
+ /** @brief Flush any internal state of the generator.
+ * This call should implicitly finish the current subpath.
+ * Calling this method should be idempotent, because the default
+ * implementations of path() and pathvector() will call it
+ * multiple times in a row. */
+ virtual void flush() = 0;
+ // Get the current point, e.g. where the initial point of the next segment will be.
+ //virtual Point currentPoint() const = 0;
+
+ /** @brief Undo the last segment.
+ * This method is optional.
+ * @return true true if a segment was erased, false otherwise. */
+ virtual bool backspace() { return false; }
+
+ // these have a default implementation
+ virtual void feed(Curve const &c, bool moveto_initial = true);
+ /** @brief Output a subpath.
+ * Calls the appropriate segment methods according to the contents
+ * of the passed subpath. You can override this function.
+ * NOTE: if you override only some of the feed() functions,
+ * always write this in the derived class:
+ * @code
+ using PathSink::feed;
+ @endcode
+ * Otherwise the remaining methods will be hidden. */
+ virtual void feed(Path const &p);
+ /** @brief Output a path.
+ * Calls feed() on each path in the vector. You can override this function. */
+ virtual void feed(PathVector const &v);
+ /// Output an axis-aligned rectangle, using moveTo, lineTo and closePath.
+ virtual void feed(Rect const &);
+ /// Output a circle as two elliptical arcs.
+ virtual void feed(Circle const &e);
+ /// Output an ellipse as two elliptical arcs.
+ virtual void feed(Ellipse const &e);
+
+ virtual ~PathSink() {}
+};
+
+/** @brief Store paths to an output iterator
+ * @ingroup Paths */
+template <typename OutputIterator>
+class PathIteratorSink : public PathSink {
+public:
+ explicit PathIteratorSink(OutputIterator out)
+ : _in_path(false), _out(out) {}
+
+ void moveTo(Point const &p) override {
+ flush();
+ _path.start(p);
+ _start_p = p;
+ _in_path = true;
+ }
+//TODO: what if _in_path = false?
+
+ /** @brief Detect if the builder is in a path and thus will NOT
+ create a new moveTo command when given the next line
+ @return true if the builder is inside a subpath.
+ */
+ bool inPath() const {
+ return _in_path;
+ }
+
+ void lineTo(Point const &p) override {
+ // check for implicit moveto, like in: "M 1,1 L 2,2 z l 2,2 z"
+ if (!_in_path) {
+ moveTo(_start_p);
+ }
+ _path.template appendNew<LineSegment>(p);
+ }
+
+ void quadTo(Point const &c, Point const &p) override {
+ // check for implicit moveto, like in: "M 1,1 L 2,2 z l 2,2 z"
+ if (!_in_path) {
+ moveTo(_start_p);
+ }
+ _path.template appendNew<QuadraticBezier>(c, p);
+ }
+
+ void curveTo(Point const &c0, Point const &c1, Point const &p) override {
+ // check for implicit moveto, like in: "M 1,1 L 2,2 z l 2,2 z"
+ if (!_in_path) {
+ moveTo(_start_p);
+ }
+ _path.template appendNew<CubicBezier>(c0, c1, p);
+ }
+
+ void arcTo(Coord rx, Coord ry, Coord angle,
+ bool large_arc, bool sweep, Point const &p) override
+ {
+ // check for implicit moveto, like in: "M 1,1 L 2,2 z l 2,2 z"
+ if (!_in_path) {
+ moveTo(_start_p);
+ }
+ _path.template appendNew<EllipticalArc>(rx, ry, angle,
+ large_arc, sweep, p);
+ }
+
+ bool backspace() override
+ {
+ if (_in_path && _path.size() > 0) {
+ _path.erase_last();
+ return true;
+ }
+ return false;
+ }
+
+ void append(Path const &other)
+ {
+ if (!_in_path) {
+ moveTo(other.initialPoint());
+ }
+ _path.append(other);
+ }
+
+ void closePath() override {
+ if (_in_path) {
+ _path.close();
+ flush();
+ }
+ }
+
+ void flush() override {
+ if (_in_path) {
+ _in_path = false;
+ *_out++ = _path;
+ _path.clear();
+ }
+ }
+
+ void setStitching(bool s) {
+ _path.setStitching(s);
+ }
+
+ using PathSink::feed;
+ void feed(Path const &other) override
+ {
+ flush();
+ *_out++ = other;
+ }
+
+protected:
+ bool _in_path;
+ OutputIterator _out;
+ Path _path;
+ Point _start_p;
+};
+
+typedef std::back_insert_iterator<PathVector> SubpathInserter;
+
+/** @brief Store paths to a PathVector
+ * @ingroup Paths */
+class PathBuilder : public PathIteratorSink<SubpathInserter> {
+private:
+ PathVector _pathset;
+public:
+ /// Create a builder that outputs to an internal pathvector.
+ PathBuilder() : PathIteratorSink<SubpathInserter>(SubpathInserter(_pathset)) {}
+ /// Create a builder that outputs to pathvector given by reference.
+ PathBuilder(PathVector &pv) : PathIteratorSink<SubpathInserter>(SubpathInserter(pv)) {}
+
+ /// Retrieve the path
+ PathVector const &peek() const {return _pathset;}
+ /// Clear the stored path vector
+ void clear() { _pathset.clear(); }
+};
+
+}
+
+#endif
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :