[dia] svg: retain current point over path split
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] svg: retain current point over path split
- Date: Sat, 10 Sep 2011 13:29:04 +0000 (UTC)
commit 71090b449e69271375233415b4a5bcbe48636ecb
Author: Hans Breuer <hans breuer org>
Date: Sun Aug 7 17:06:54 2011 +0200
svg: retain current point over path split
SVGs with relative movement produced wrong results, when that
path was split (e.g. car.svg from Inkscape examples). Now the
current_point is retained across the splitting loop.
Slightly related: handle a second move command directly after
the initial one gracefully (there are too many borked SVG generators;))
lib/dia_svg.c | 22 +++++++++++++++++++---
lib/dia_svg.h | 2 +-
objects/custom/shape_info.c | 3 ++-
plug-ins/svg/svg-import.c | 3 ++-
4 files changed, 24 insertions(+), 6 deletions(-)
---
diff --git a/lib/dia_svg.c b/lib/dia_svg.c
index 5451498..54f3a26 100644
--- a/lib/dia_svg.c
+++ b/lib/dia_svg.c
@@ -570,6 +570,7 @@ _path_arc(GArray *points, double cpx, double cpy,
* the string was completely parsed. This should be used for
* calling the function until it is fully parsed.
* @param closed Whether the path was closed.
+ * @param current_point to retain it over splitting
* @returns Array of BezPoint objects, or NULL if an error occurred.
* The caller is responsible for freeing the array.
* @bug This function is way too long (324 lines). So dont touch it. please!
@@ -580,7 +581,7 @@ _path_arc(GArray *points, double cpx, double cpy,
* NOPE: Dia is capable to handle beziers and the file has given us some so WHY should be break it in to pieces ???
*/
GArray*
-dia_svg_parse_path(const gchar *path_str, gchar **unparsed, gboolean *closed)
+dia_svg_parse_path(const gchar *path_str, gchar **unparsed, gboolean *closed, Point *current_point)
{
enum {
PATH_MOVE, PATH_LINE, PATH_HLINE, PATH_VLINE, PATH_CURVE,
@@ -597,6 +598,10 @@ dia_svg_parse_path(const gchar *path_str, gchar **unparsed, gboolean *closed)
*closed = FALSE;
*unparsed = NULL;
+ /* when splitting into pieces, we have to maintain current_point accross them */
+ if (current_point)
+ last_point = *current_point;
+
points = g_array_new(FALSE, FALSE, sizeof(BezPoint));
g_array_set_size(points, 0);
@@ -744,6 +749,10 @@ dia_svg_parse_path(const gchar *path_str, gchar **unparsed, gboolean *closed)
/* actually parse the path component */
switch (last_type) {
case PATH_MOVE:
+#ifndef MULTI_MOVE_BEZIER
+ if (points->len > 1)
+ g_warning ("Only first point should be 'move'");
+#endif
bez.type = BEZ_MOVE_TO;
bez.p1.x = g_ascii_strtod(path, &path);
path_chomp(path);
@@ -756,7 +765,12 @@ dia_svg_parse_path(const gchar *path_str, gchar **unparsed, gboolean *closed)
last_point = bez.p1;
last_control = bez.p1;
last_open = bez.p1;
- g_array_append_val(points, bez);
+#ifndef MULTI_MOVE_BEZIER
+ if (points->len == 1) /* stupid svg, but we can handle it */
+ g_array_index(points,BezPoint,0) = bez;
+ else
+#endif
+ g_array_append_val(points, bez);
break;
case PATH_LINE:
bez.type = BEZ_LINE_TO;
@@ -917,7 +931,7 @@ dia_svg_parse_path(const gchar *path_str, gchar **unparsed, gboolean *closed)
path_chomp(path);
MORETOPARSE:
if (need_next_element) {
- /* check if there really is mor to be parsed */
+ /* check if there really is more to be parsed */
if (path[0] != 0)
*unparsed = path;
break; /* while */
@@ -931,6 +945,8 @@ MORETOPARSE:
if (points->len < 2) {
g_array_set_size(points, 0);
}
+ if (current_point)
+ *current_point = last_point;
return points;
}
diff --git a/lib/dia_svg.h b/lib/dia_svg.h
index 4588201..0240f4d 100644
--- a/lib/dia_svg.h
+++ b/lib/dia_svg.h
@@ -61,7 +61,7 @@ void dia_svg_style_init (DiaSvgStyle *gs, DiaSvgStyle *parent_style);
void dia_svg_style_copy (DiaSvgStyle *dest, DiaSvgStyle *src);
void dia_svg_parse_style(xmlNodePtr node, DiaSvgStyle *s, real user_scale);
/* parse the svg sub format for pathes int an array of BezPoint */
-GArray *dia_svg_parse_path(const gchar *path_str, gchar **unparsed, gboolean *closed);
+GArray *dia_svg_parse_path(const gchar *path_str, gchar **unparsed, gboolean *closed, Point *current_point);
DiaMatrix *dia_svg_parse_transform(const gchar *trans, real scale);
gchar *dia_svg_from_matrix(const DiaMatrix *matrix, real scale);
diff --git a/objects/custom/shape_info.c b/objects/custom/shape_info.c
index f4e457e..443502a 100644
--- a/objects/custom/shape_info.c
+++ b/objects/custom/shape_info.c
@@ -155,9 +155,10 @@ parse_path(ShapeInfo *info, const char *path_str, DiaSvgStyle *s, const char* fi
GArray *points;
gchar *pathdata = (gchar *)path_str, *unparsed;
gboolean closed = FALSE;
+ Point current_point = {0.0, 0.0};
do {
- points = dia_svg_parse_path (pathdata, &unparsed, &closed);
+ points = dia_svg_parse_path (pathdata, &unparsed, &closed, ¤t_point);
if (points->len > 0) {
if (g_array_index(points, BezPoint, 0).type != BEZ_MOVE_TO) {
diff --git a/plug-ins/svg/svg-import.c b/plug-ins/svg/svg-import.c
index 90a58f5..3130fe0 100644
--- a/plug-ins/svg/svg-import.c
+++ b/plug-ins/svg/svg-import.c
@@ -305,6 +305,7 @@ read_path_svg(xmlNodePtr node, DiaSvgStyle *parent_style, GList *list)
gboolean closed = FALSE;
gint i;
DiaMatrix *matrix = NULL;
+ Point current_point = {0.0, 0.0};
str = (char *) xmlGetProp(node, (const xmlChar *)"transform");
if (str) {
@@ -314,7 +315,7 @@ read_path_svg(xmlNodePtr node, DiaSvgStyle *parent_style, GList *list)
pathdata = str = (char *) xmlGetProp(node, (const xmlChar *)"d");
do {
- bezpoints = dia_svg_parse_path (pathdata, &unparsed, &closed);
+ bezpoints = dia_svg_parse_path (pathdata, &unparsed, &closed, ¤t_point);
if (bezpoints && bezpoints->len > 0) {
if (g_array_index(bezpoints, BezPoint, 0).type != BEZ_MOVE_TO) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]