[goffice] Fixed more doc issues and add some GOPath new API.



commit 14a989acc7ec45316e125652291630b1bfe2357b
Author: Jean Brefort <jean brefort normalesup org>
Date:   Mon Aug 20 14:24:40 2012 +0200

    Fixed more doc issues and add some GOPath new API.

 ChangeLog                         |   10 +
 docs/reference/goffice-docs.xml   |    1 +
 goffice/graph/gog-styled-object.c |    8 +
 goffice/utils/go-cairo.c          |  180 +-------------
 goffice/utils/go-path.c           |  506 ++++++++++++++++++++++++++++++++++++-
 goffice/utils/go-path.h           |   10 +-
 6 files changed, 538 insertions(+), 177 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index ff1a35a..ae2a93f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2012-08-20  Jean Brefort  <jean brefort normalesup org>
+
+	* docs/reference/goffice-docs.xml: fixed a few more doc issues.
+	* goffice/graph/gog-styled-object.c (gog_styled_object_class_init): ditto.
+	* goffice/utils/go-cairo.c (go_cairo_emit_svg_path): use
+	go_path_new_from_svg().
+	* goffice/utils/go-path.c (go_path_scale),
+	(go_path_new_from_svg), (go_path_new_from_odf_enhanced_path): new functions.
+	* goffice/utils/go-path.h: ditto.
+
 2012-08-16  Jean Brefort  <jean brefort normalesup org>
 
 	* configure.in: requires libgsf-1 >= 1.14.23 for introspection.
diff --git a/docs/reference/goffice-docs.xml b/docs/reference/goffice-docs.xml
index 2e0794b..8567871 100644
--- a/docs/reference/goffice-docs.xml
+++ b/docs/reference/goffice-docs.xml
@@ -161,6 +161,7 @@
 		<chapter>
 			<title>File utilities</title>
 			<xi:include href="xml/go-file.xml"/>
+			<xi:include href="xml/file.xml"/>
 			<xi:include href="xml/go-file-opener.xml"/>
 			<xi:include href="xml/go-file-saver.xml"/>
 			<xi:include href="xml/go-url.xml"/>
diff --git a/goffice/graph/gog-styled-object.c b/goffice/graph/gog-styled-object.c
index 231f6b6..cab83bd 100644
--- a/goffice/graph/gog-styled-object.c
+++ b/goffice/graph/gog-styled-object.c
@@ -188,6 +188,14 @@ gog_styled_object_class_init (GogObjectClass *gog_klass)
 	GObjectClass *gobject_klass = (GObjectClass *) gog_klass;
 	GogStyledObjectClass *style_klass = (GogStyledObjectClass *) gog_klass;
 
+	/**
+	 * GogStyledObject::style-changed:
+	 * @object: the object on which the signal is emitted
+	 * @style: The new #GOStyle
+	 *
+	 * The ::style-changed signal is emitted after the style has been changed
+	 * by a call to go_styled_object_set_style().
+	 **/
 	gog_styled_object_signals [STYLE_CHANGED] = g_signal_new ("style-changed",
 		G_TYPE_FROM_CLASS (gog_klass),
 		G_SIGNAL_RUN_LAST,
diff --git a/goffice/utils/go-cairo.c b/goffice/utils/go-cairo.c
index 0871b7d..39ec88a 100644
--- a/goffice/utils/go-cairo.c
+++ b/goffice/utils/go-cairo.c
@@ -20,154 +20,9 @@
  */
 
 #include <goffice/utils/go-cairo.h>
+#include <goffice/goffice.h>
 #include <math.h>
 
-static void
-skip_spaces (char **path)
-{
-	while (**path == ' ')
-		(*path)++;
-}
-
-static void
-skip_comma_and_spaces (char **path)
-{
-	while (**path == ' ' || **path == ',')
-		(*path)++;
-}
-
-static gboolean
-parse_value (char **path, double *x)
-{
-	char *end, *c;
-	gboolean integer_part = FALSE;
-	gboolean fractional_part = FALSE;
-	gboolean exponent_part = FALSE;
-	double mantissa = 0.0;
-	double exponent =0.0;
-	double divisor;
-	gboolean mantissa_sign = 1.0;
-	gboolean exponent_sign = 1.0;
-
-	c = *path;
-
-	if (*c == '-') {
-		mantissa_sign = -1.0;
-		c++;
-	} else if (*c == '+')
-		c++;
-
-	if (*c >= '0' && *c <= '9') {
-		integer_part = TRUE;
-		mantissa = *c - '0';
-		c++;
-
-		while (*c >= '0' && *c <= '9') {
-			mantissa = mantissa * 10.0 + *c - '0';
-			c++;
-		}
-	}
-
-
-	if (*c == '.')
-		c++;
-	else if (!integer_part)
-		return FALSE;
-
-	if (*c >= '0' && *c <= '9') {
-		fractional_part = TRUE;
-		mantissa += (*c - '0') * 0.1;
-		divisor = 0.01;
-		c++;
-
-		while (*c >= '0' && *c <= '9') {
-			mantissa += (*c - '0') * divisor;
-			divisor *= 0.1;
-			c++;
-		}
-	}
-
-	if (!fractional_part && !integer_part)
-		return FALSE;
-
-	end = c;
-
-	if (*c == 'E' || *c == 'e') {
-		c++;
-
-		if (*c == '-') {
-			exponent_sign = -1.0;
-			c++;
-		} else if (*c == '+')
-			c++;
-
-		if (*c >= '0' && *c <= '9') {
-			exponent_part = TRUE;
-			exponent = *c - '0';
-			c++;
-
-			while (*c >= '0' && *c <= '9') {
-				exponent = exponent * 10.0 + *c - '0';
-				c++;
-			}
-		}
-
-	}
-
-	if (exponent_part) {
-		end = c;
-		*x = mantissa_sign * mantissa * pow (10.0, exponent_sign * exponent);
-	} else
-		*x = mantissa_sign * mantissa;
-
-	*path = end;
-
-	return TRUE;
-}
-
-static gboolean
-parse_values (char **path, unsigned int n_values, double *values)
-{
-	char *ptr = *path;
-	unsigned int i;
-
-	skip_comma_and_spaces (path);
-
-	for (i = 0; i < n_values; i++) {
-		if (!parse_value (path, &values[i])) {
-			*path = ptr;
-			return FALSE;
-		}
-		skip_comma_and_spaces (path);
-	}
-
-	return TRUE;
-}
-
-static void
-emit_function_2 (char **path, cairo_t *cr,
-		 void (*cairo_func) (cairo_t *, double, double))
-{
-	double values[2];
-
-	skip_spaces (path);
-
-	while (parse_values (path, 2, values))
-		cairo_func (cr, values[0], values[1]);
-}
-
-static void
-emit_function_6 (char **path, cairo_t *cr,
-		 void (*cairo_func) (cairo_t *, double, double, double ,double, double, double))
-{
-	double values[6];
-
-	skip_spaces (path);
-
-	while (parse_values (path, 6, values))
-		cairo_func (cr, values[0], values[1], values[2], values[3], values[4], values[5]);
-}
-
 /**
  * go_cairo_emit_svg_path:
  * @cr: a cairo context
@@ -181,39 +36,14 @@ void
 go_cairo_emit_svg_path (cairo_t *cr, char const *path)
 {
 	char *ptr;
+	GOPath *go_path;
 
 	if (path == NULL)
 		return;
 
-	ptr = (char *) path;
-
-	skip_spaces (&ptr);
-
-	while (*ptr != '\0') {
-		if (*ptr == 'M') {
-			ptr++;
-			emit_function_2 (&ptr, cr, cairo_move_to);
-		} else if (*ptr == 'm') {
-			ptr++;
-			emit_function_2 (&ptr, cr, cairo_rel_move_to);
-		} else if (*ptr == 'L') {
-			ptr++;
-			emit_function_2 (&ptr, cr, cairo_line_to);
-		} else if (*ptr == 'l') {
-			ptr++;
-			emit_function_2 (&ptr, cr, cairo_rel_line_to);
-		} else if (*ptr == 'C') {
-			ptr++;
-			emit_function_6 (&ptr, cr, cairo_curve_to);
-		} else if (*ptr == 'c') {
-			ptr++;
-			emit_function_6 (&ptr, cr, cairo_rel_curve_to);
-		} else if (*ptr == 'Z' || *ptr == 'z') {
-			ptr++;
-			cairo_close_path (cr);
-		} else
-			ptr++;
-	}
+	go_path = go_path_new_from_svg (path);
+	go_path_to_cairo (go_path, GO_PATH_DIRECTION_FORWARD, cr);
+	go_path_free (go_path);
 }
 
 gboolean
diff --git a/goffice/utils/go-path.c b/goffice/utils/go-path.c
index 5ccebad..9c3f5c2 100644
--- a/goffice/utils/go-path.c
+++ b/goffice/utils/go-path.c
@@ -109,6 +109,14 @@
  * GOPathDirection:
  * @GO_PATH_DIRECTION_FORWARD: go through the pass from start to end.
  * @GO_PATH_DIRECTION_BACKWARD:  go through the pass from end to start.
+ * @GO_PATH_DIRECTION_FORWARD_SKIP_NO_FILL: go through the pass from start to end,
+ * skipping segments markes as no-fill.
+ * @GO_PATH_DIRECTION_BACKWARD_SKIP_NO_FILL:  go through the pass from end to start,
+ * skipping segments markes as no-fill.
+ * @GO_PATH_DIRECTION_FORWARD_SKIP_NO_STROKE: go through the pass from start to end,
+ * skipping segments markes as no-stroke.
+ * @GO_PATH_DIRECTION_BACKWARD_SKIP_NO_STROKE:  go through the pass from end to start,
+ * skipping segments markes as no-stroke.
  **/
 
 #define GO_PATH_DEFAULT_BUFFER_SIZE 64
@@ -120,7 +128,8 @@ typedef enum _GOPathAction {
 	GO_PATH_ACTION_MOVE_TO 		= 0,
 	GO_PATH_ACTION_LINE_TO 		= 1,
 	GO_PATH_ACTION_CURVE_TO 	= 2,
-	GO_PATH_ACTION_CLOSE_PATH 	= 3
+	GO_PATH_ACTION_CLOSE_PATH 	= 3,
+	GO_PATH_ACTION_CHANGE_STATE
 } GOPathAction;
 
 static int action_n_args[4] = { 1, 1, 3, 0};
@@ -755,3 +764,498 @@ GOPath *go_path_append (GOPath *path1, GOPath const *path2)
 			   (GOPathClosePathFunc) go_path_append_close, path1);
 	return path1;
 }
+
+/******************************************************************************/
+struct PathScaleClosure {
+	GOPath *path;
+	double scale_x, scale_y;
+};
+
+static void
+go_path_scale_move_to (struct PathScaleClosure *closure,
+                        GOPathPoint const *point)
+{
+	go_path_move_to (closure->path,
+	                 point->x * closure->scale_x,
+	                 point->y * closure->scale_y);
+}
+
+static void
+go_path_scale_line_to (struct PathScaleClosure *closure,
+                        GOPathPoint const *point)
+{
+	go_path_line_to (closure->path,
+	                 point->x * closure->scale_x,
+	                 point->y * closure->scale_y);
+}
+
+static void
+go_path_scale_curve_to (struct PathScaleClosure *closure,
+                         GOPathPoint const *point0,
+                         GOPathPoint const *point1,
+                         GOPathPoint const *point2)
+{
+	go_path_curve_to (closure->path,
+	                  point0->x * closure->scale_x,
+	                  point0->y * closure->scale_y,
+	                  point1->x * closure->scale_x,
+	                  point1->y * closure->scale_y,
+	                  point2->x * closure->scale_x,
+	                  point2->y * closure->scale_y);
+}
+
+static void
+go_path_scale_close (struct PathScaleClosure *closure)
+{
+	go_path_close (closure->path);
+}
+
+/**
+ * go_path_scale:
+ * @path: #GOPath
+ * @scale_x: horizontal scale.
+ * @scale_y: vertical scale.
+ *
+ * Builds a scaled.
+ * Returns: (transfer full): the scaled path.
+ **/
+GOPath *
+go_path_scale (GOPath *path, double scale_x, double scale_y)
+{
+	struct PathScaleClosure closure;
+	closure.path = go_path_new ();
+	closure.scale_x = scale_x;
+	closure.scale_y = scale_y;
+	go_path_interpret (path, GO_PATH_DIRECTION_FORWARD,
+	                   (GOPathMoveToFunc) go_path_scale_move_to,
+	                   (GOPathLineToFunc) go_path_scale_line_to,
+	                   (GOPathCurveToFunc) go_path_scale_curve_to,
+	                   (GOPathClosePathFunc) go_path_scale_close, &closure);
+	return closure.path;
+}
+
+/******************************************************************************/
+
+char *
+go_path_to_svg (GOPath *path)
+{
+	return NULL; /* FIXME */
+}
+
+/*******************************************************************************
+  * Paths from string
+ ******************************************************************************/
+
+static void
+skip_spaces (char **src)
+{
+	while (**src == ' ')
+		(*src)++;
+}
+
+static void
+skip_comma_and_spaces (char **src)
+{
+	while (**src == ' ' || **src == ',')
+		(*src)++;
+}
+
+static gboolean
+parse_value (char **src, double *x)
+{
+	char *end, *c;
+	gboolean integer_part = FALSE;
+	gboolean fractional_part = FALSE;
+	gboolean exponent_part = FALSE;
+	double mantissa = 0.0;
+	double exponent =0.0;
+	double divisor;
+	gboolean mantissa_sign = 1.0;
+	gboolean exponent_sign = 1.0;
+
+	c = *src;
+
+	if (*c == '-') {
+		mantissa_sign = -1.0;
+		c++;
+	} else if (*c == '+')
+		c++;
+
+	if (*c >= '0' && *c <= '9') {
+		integer_part = TRUE;
+		mantissa = *c - '0';
+		c++;
+
+		while (*c >= '0' && *c <= '9') {
+			mantissa = mantissa * 10.0 + *c - '0';
+			c++;
+		}
+	}
+
+
+	if (*c == '.')
+		c++;
+	else if (!integer_part)
+		return FALSE;
+
+	if (*c >= '0' && *c <= '9') {
+		fractional_part = TRUE;
+		mantissa += (*c - '0') * 0.1;
+		divisor = 0.01;
+		c++;
+
+		while (*c >= '0' && *c <= '9') {
+			mantissa += (*c - '0') * divisor;
+			divisor *= 0.1;
+			c++;
+		}
+	}
+
+	if (!fractional_part && !integer_part)
+		return FALSE;
+
+	end = c;
+
+	if (*c == 'E' || *c == 'e') {
+		c++;
+
+		if (*c == '-') {
+			exponent_sign = -1.0;
+			c++;
+		} else if (*c == '+')
+			c++;
+
+		if (*c >= '0' && *c <= '9') {
+			exponent_part = TRUE;
+			exponent = *c - '0';
+			c++;
+
+			while (*c >= '0' && *c <= '9') {
+				exponent = exponent * 10.0 + *c - '0';
+				c++;
+			}
+		}
+
+	}
+
+	if (exponent_part) {
+		end = c;
+		*x = mantissa_sign * mantissa * pow (10.0, exponent_sign * exponent);
+	} else
+		*x = mantissa_sign * mantissa;
+
+	*src = end;
+
+	return TRUE;
+}
+
+static gboolean
+parse_values (char **src, unsigned int n_values, double *values)
+{
+	char *ptr = *src;
+	unsigned int i;
+
+	skip_comma_and_spaces (src);
+
+	for (i = 0; i < n_values; i++) {
+		if (!parse_value (src, &values[i])) {
+			*src = ptr;
+			return FALSE;
+		}
+		skip_comma_and_spaces (src);
+	}
+
+	return TRUE;
+}
+
+static void
+emit_function_2 (char **src, GOPath *path,
+                 void (*path_func) (GOPath *, double, double),
+                 gboolean relative, double *lastx, double *lasty)
+{
+	double values[2];
+
+	skip_spaces (src);
+
+	while (parse_values (src, 2, values)) {
+		if (relative) {
+			*lastx += values[0];
+			*lasty += values[1];
+		} else {
+			*lastx = values[0];
+			*lasty = values[1];
+		}
+		path_func (path, *lastx, *lasty);
+	}
+}
+
+static void
+emit_function_6 (char **src, GOPath *path,
+                 void (*path_func) (GOPath *, double, double, double ,double, double, double),
+                 gboolean relative, double *lastx, double *lasty)
+{
+	double values[6];
+
+	skip_spaces (src);
+
+	while (parse_values (src, 6, values)) {
+		if (relative) {
+			values[0] += *lastx;
+			values[1] += *lasty;
+			values[2] += *lastx;
+			values[3] += *lasty;
+			*lastx += values[4];
+			*lasty += values[5];
+		} else {
+			*lastx = values[4];
+			*lasty = values[5];
+		}
+		path_func (path, values[0], values[1], values[2], values[3], *lastx, *lasty);
+	}
+}
+
+static void
+emit_function_8 (char **src, GOPath *path,
+                 void (*path_func) (GOPath *, double, double, double ,double, double, double, double ,double),
+                 gboolean relative, double *lastx, double *lasty)
+{
+	double values[8];
+
+	skip_spaces (src);
+
+	while (parse_values (src, 8, values)) {
+		if (relative) {
+			values[0] += *lastx;
+			values[1] += *lasty;
+			values[2] += *lastx;
+			values[3] += *lasty;
+			values[4] += *lastx;
+			values[5] += *lasty;
+			*lastx += values[6];
+			*lasty += values[7];
+		} else {
+			*lastx = values[6];
+			*lasty = values[7];
+		}
+		path_func (path, values[0], values[1], values[2], values[3], values[4], values[5], *lastx, *lasty);
+	}
+}
+
+static void
+emit_quadratic (char **src, GOPath *path,
+                 gboolean relative, double *lastx, double *lasty)
+{
+	double values[4];
+
+	skip_spaces (src);
+
+	while (parse_values (src, 4, values)) {
+		if (relative) {
+			values[0] += *lastx;
+			values[1] += *lasty;
+			values[2] += *lastx;
+			values[3] += *lasty;
+		}
+		go_path_curve_to (path,
+		                  (*lastx + 2 * values[0]) / 3.,
+		                  (*lasty + 2 * values[1]) / 3.,
+		                  (2 * values[0] + values[2]) / 3.,
+		                  (2 * values[1] + values[3]) / 3.,
+		                  values[2], values[3]);
+		*lastx += values[2];
+		*lasty += values[3];
+	}
+}
+
+/**
+ * go_path_new_from_svg:
+ * @src: an SVG path.
+ *
+ * Returns: (transfer full): the newly allocated #GOPath.
+ **/
+GOPath *
+go_path_new_from_svg (char const *src)
+{
+	GOPath *path;
+	char *ptr;
+	double lastx = 0., lasty = 0.;
+
+	if (src == NULL)
+		return NULL;
+
+	path = go_path_new ();
+	ptr = (char *) src;
+
+	skip_spaces (&ptr);
+
+	while (*ptr != '\0') {
+		switch (*ptr) {
+		case 'A':
+			ptr++;
+			break;
+		case 'a':
+			ptr++;
+			break;
+		case 'M':
+			ptr++;
+			emit_function_2 (&ptr, path, go_path_move_to, FALSE, &lastx, &lasty);
+			break;
+		case 'm':
+			ptr++;
+			emit_function_2 (&ptr, path, go_path_move_to, TRUE, &lastx, &lasty);
+			break;
+		case 'H':
+			ptr++;
+			break;
+		case 'h':
+			ptr++;
+			break;
+		case 'L':
+			ptr++;
+			emit_function_2 (&ptr, path, go_path_line_to, FALSE, &lastx, &lasty);
+			break;
+		case 'l':
+			ptr++;
+			emit_function_2 (&ptr, path, go_path_line_to, TRUE, &lastx, &lasty);
+			break;
+		case 'C':
+			ptr++;
+			emit_function_6 (&ptr, path, go_path_curve_to, FALSE, &lastx, &lasty);
+			break;
+		case 'c':
+			ptr++;
+			emit_function_6 (&ptr, path, go_path_curve_to, TRUE, &lastx, &lasty);
+			break;
+		case 'Q':
+			ptr++;
+			emit_quadratic (&ptr, path, FALSE, &lastx, &lasty);
+			break;
+		case 'q':
+			ptr++;
+			emit_quadratic (&ptr, path, TRUE, &lastx, &lasty);
+			break;
+		case 'S':
+			ptr++;
+			break;
+		case 's':
+			ptr++;
+			break;
+		case 'T':
+			ptr++;
+			break;
+		case 't':
+			ptr++;
+			break;
+		case 'V':
+			ptr++;
+			break;
+		case 'v':
+			ptr++;
+			break;
+		case 'Z':
+		case 'z':
+			ptr++;
+			go_path_close (path);
+			break;
+		default:
+			ptr++;
+			break;
+		}
+	}
+	return path;
+}
+
+static void
+go_path_line_arc_to (GOPath *path, double x0, double x1, double x2, double x3,
+                     double x4, double x5, double x6, double x7)
+{
+}
+
+static void
+go_path_move_arc_to (GOPath *path, double x0, double x1, double x2, double x3,
+                     double x4, double x5, double x6, double x7)
+{
+}
+
+/**
+ * go_path_new_from_odf_enhanced_path:
+ * @src: an ODF enhanced path.
+ *
+ * Returns: (transfer full): the newly alocated #GOPath.
+ **/
+GOPath *
+go_path_new_from_odf_enhanced_path (char const *src, GHashTable const *variables)
+{
+	GOPath *path;
+	char *ptr;
+	double lastx = 0., lasty = 0.;
+
+	if (src == NULL)
+		return NULL;
+
+	path = go_path_new ();
+	ptr = (char *) src;
+
+	skip_spaces (&ptr);
+
+	while (*ptr != '\0') {
+		switch (*ptr) {
+		case 'A':
+			ptr++;
+			emit_function_8 (&ptr, path, go_path_line_arc_to, FALSE, &lastx, &lasty);
+			break;
+		case 'B':
+			ptr++;
+			emit_function_8 (&ptr, path, go_path_move_arc_to, FALSE, &lastx, &lasty);
+			break;
+		case 'C':
+			ptr++;
+			emit_function_6 (&ptr, path, go_path_curve_to, FALSE, &lastx, &lasty);
+			break;
+		case 'F':
+			ptr++;
+			break;
+		case 'L':
+			ptr++;
+			emit_function_2 (&ptr, path, go_path_line_to, FALSE, &lastx, &lasty);
+			break;
+		case 'M':
+			ptr++;
+			emit_function_2 (&ptr, path, go_path_move_to, FALSE, &lastx, &lasty);
+			break;
+		case 'Q':
+			ptr++;
+			emit_quadratic (&ptr, path, FALSE, &lastx, &lasty);
+			break;
+		case 'S':
+			ptr++;
+			break;
+		case 'T':
+			ptr++;
+			break;
+		case 'U':
+			ptr++;
+			break;
+		case 'V':
+			ptr++;
+			break;
+		case 'W':
+			ptr++;
+			break;
+		case 'X':
+			ptr++;
+			break;
+		case 'Y':
+			ptr++;
+			break;
+		case 'Z':
+			ptr++;
+			go_path_close (path);
+			break;
+		default:
+			ptr++;
+			break;
+		}
+}
+	return path;
+}
diff --git a/goffice/utils/go-path.h b/goffice/utils/go-path.h
index 55234c7..8bfc926 100644
--- a/goffice/utils/go-path.h
+++ b/goffice/utils/go-path.h
@@ -37,7 +37,11 @@ G_BEGIN_DECLS
 
 typedef enum {
 	GO_PATH_DIRECTION_FORWARD,
-	GO_PATH_DIRECTION_BACKWARD
+	GO_PATH_DIRECTION_BACKWARD,
+	GO_PATH_DIRECTION_FORWARD_SKIP_NO_FILL,
+	GO_PATH_DIRECTION_BACKWARD_SKIP_NO_FILL,
+	GO_PATH_DIRECTION_FORWARD_SKIP_NO_STROKE,
+	GO_PATH_DIRECTION_BACKWARD_SKIP_NO_STROKE
 } GOPathDirection;
 
 typedef enum {
@@ -64,6 +68,8 @@ GType   go_path_get_type (void);
 #define GO_IS_PATH(x) ((x) != NULL)
 
 GOPath *go_path_new 	      	(void);
+GOPath *go_path_new_from_svg    (char const *src);
+GOPath *go_path_new_from_odf_enhanced_path (char const *src, GHashTable const *variables);
 void 	go_path_clear	      	(GOPath *path);
 GOPath *go_path_ref          	(GOPath *path);
 void    go_path_free          	(GOPath *path);
@@ -110,6 +116,8 @@ void    go_path_to_cairo	(GOPath const *path,
 
 GOPath *go_path_copy		(GOPath const *path);
 GOPath *go_path_append		(GOPath *path1, GOPath const *path2);
+GOPath *go_path_scale       (GOPath *path, double scale_x, double scale_y);
+char   *go_path_to_svg      (GOPath *path);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]