summaryrefslogtreecommitdiffstats
path: root/src/2geom/svg-path-parser.h
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2015-04-27 23:39:29 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2015-04-27 23:39:29 +0000
commitc883d7627a479c8c5b6a9f77b9841fa5631572ad (patch)
treefba1186e26a8cc85a1b0728425bef6f2e9aeccd9 /src/2geom/svg-path-parser.h
parentextensions. ink2canvas.py - do not parse html comments. (Bug 1446204) (diff)
downloadinkscape-c883d7627a479c8c5b6a9f77b9841fa5631572ad.tar.gz
inkscape-c883d7627a479c8c5b6a9f77b9841fa5631572ad.zip
2Geom sync - initial commit
(bzr r14059.2.1)
Diffstat (limited to 'src/2geom/svg-path-parser.h')
-rw-r--r--src/2geom/svg-path-parser.h137
1 files changed, 116 insertions, 21 deletions
diff --git a/src/2geom/svg-path-parser.h b/src/2geom/svg-path-parser.h
index 163fbe5c4..6478ba468 100644
--- a/src/2geom/svg-path-parser.h
+++ b/src/2geom/svg-path-parser.h
@@ -30,48 +30,143 @@
*
*/
-#ifndef SEEN_SVG_PATH_PARSER_H
-#define SEEN_SVG_PATH_PARSER_H
+#ifndef LIB2GEOM_SEEN_SVG_PATH_PARSER_H
+#define LIB2GEOM_SEEN_SVG_PATH_PARSER_H
-#include <vector>
+#include <iostream>
#include <iterator>
#include <stdexcept>
+#include <vector>
#include <2geom/exception.h>
#include <2geom/point.h>
#include <2geom/path-sink.h>
namespace Geom {
-void parse_svg_path(char const *str, PathSink &sink) throw(SVGPathParseError);
+/** @brief Read SVG path data and feed it to a PathSink
+ *
+ * This class provides an interface to an SVG path data parser written in Ragel.
+ * It supports parsing the path data either at once or block-by-block.
+ * Use the parse() functions to parse complete data and the feed() and finish()
+ * functions to parse partial data.
+ *
+ * The parser will call the appropriate methods on the PathSink supplied
+ * at construction. To store the path in memory as a PathVector, pass
+ * a PathBuilder. You can also use one of the freestanding helper functions
+ * if you don't need to parse data block-by-block.
+ *
+ * @ingroup Paths
+ */
+class SVGPathParser {
+public:
+ SVGPathParser(PathSink &sink);
+
+ /** @brief Reset internal state.
+ * Discards the internal state associated with partially parsed data,
+ * letting you start from scratch. Note that any partial data written
+ * to the path sink is not affected - you need to clear it yourself. */
+ void reset();
+
+ /** @brief Parse a C-style string.
+ * The path sink is flushed and the internal state is reset after this call.
+ * Note that the state is not reset before this method, so you can use it to
+ * process the last block of partial data.
+ * @param str String to parse
+ * @param len Length of string or -1 if null-terminated */
+ void parse(char const *str, int len = -1);
+ /** @brief Parse an STL string. */
+ void parse(std::string const &s);
+
+ /** @brief Parse a part of path data stored in a C-style string.
+ * This method does not reset internal state, so it can be called multiple
+ * times to parse successive blocks of a longer SVG path data string.
+ * To finish parsing, call finish() after the final block or call parse()
+ * with the last block of data.
+ * @param str String to parse
+ * @param len Length of string or -1 if null-terminated */
+ void feed(char const *str, int len = -1);
+ /** @brief Parse a part of path data stored in an STL string. */
+ void feed(std::string const &s);
-inline std::vector<Path> parse_svg_path(char const *str) throw(SVGPathParseError) {
- typedef std::vector<Path> Subpaths;
- typedef std::back_insert_iterator<Subpaths> Inserter;
-
- Subpaths subpaths;
- Inserter iter(subpaths);
- PathIteratorSink<Inserter> generator(iter);
+ /** @brief Finalize parsing.
+ * After the last block of data was submitted with feed(), call this method
+ * to finalize parsing, flush the path sink and reset internal state.
+ * You should not call this after parse(). */
+ void finish();
+
+private:
+ bool _absolute;
+ Point _current;
+ Point _initial;
+ Point _cubic_tangent;
+ Point _quad_tangent;
+ std::vector<Coord> _params;
+ PathSink &_sink;
+
+ int cs;
+ std::string _number_part;
+
+ void _push(Coord value);
+ Coord _pop();
+ bool _pop_flag();
+ Coord _pop_coord(Geom::Dim2 axis);
+ Point _pop_point();
+ void _moveTo(Point const &p);
+ void _lineTo(Point const &p);
+ void _curveTo(Point const &c0, Point const &c1, Point const &p);
+ void _quadTo(Point const &c, Point const &p);
+ void _arcTo(double rx, double ry, double angle,
+ bool large_arc, bool sweep, Point const &p);
+ void _closePath();
+
+ void _parse(char const *str, char const *strend, bool finish);
+};
+
+/** @brief Feed SVG path data to the specified sink
+ * @ingroup Paths */
+void parse_svg_path(char const *str, PathSink &sink);
+/** @brief Feed SVG path data to the specified sink
+ * @ingroup Paths */
+inline void parse_svg_path(std::string const &str, PathSink &sink) {
+ parse_svg_path(str.c_str(), sink);
+}
+/** Feed SVG path data from a C stream to the specified sink
+ * @ingroup Paths */
+void parse_svg_path_file(FILE *fi, PathSink &sink);
+
+/** @brief Create path vector from SVG path data stored in a C string
+ * @ingroup Paths */
+inline PathVector parse_svg_path(char const *str) {
+ PathVector ret;
+ SubpathInserter iter(ret);
+ PathIteratorSink<SubpathInserter> generator(iter);
parse_svg_path(str, generator);
- return subpaths;
+ return ret;
}
-inline std::vector<Path> read_svgd_f(FILE * fi) throw(SVGPathParseError) {
- /// @bug The 10kB length limit should be removed
- char input[1024 * 10];
- fgets(input, 1024 * 10, fi);
- return parse_svg_path(input);
+/** @brief Create path vector from a C stream with SVG path data
+ * @ingroup Paths */
+inline PathVector read_svgd_f(FILE * fi) {
+ PathVector ret;
+ SubpathInserter iter(ret);
+ PathIteratorSink<SubpathInserter> generator(iter);
+
+ parse_svg_path_file(fi, generator);
+ return ret;
}
-inline std::vector<Path> read_svgd(char const * name) throw(SVGPathParseError) {
- FILE* fi = fopen(name, "r");
+/** @brief Create path vector from SVG path data stored in a file
+ * @ingroup Paths */
+inline PathVector read_svgd(char const *filename) {
+ FILE* fi = fopen(filename, "r");
if(fi == NULL) throw(std::runtime_error("Error opening file"));
- std::vector<Path> out = read_svgd_f(fi);
+ PathVector out = read_svgd_f(fi);
fclose(fi);
return out;
}
-}
+} // end namespace Geom
#endif
/*