[goffice] Implement poygon splitting.



commit 20c0478ad8c63eae0495d8fb5f3de54d6533aab3
Author: Jean Brefort <jean brefort normalesup org>
Date:   Fri Mar 26 08:39:11 2010 +0100

    Implement poygon splitting.

 ChangeLog                               |   11 ++++
 docs/reference/goffice-0.8-sections.txt |    7 +++
 goffice/canvas/goc-polygon.c            |   51 ++++++++++++++++++-
 goffice/canvas/goc-utils.c              |   85 +++++++++++++++++++++++++++++++
 goffice/canvas/goc-utils.h              |   15 ++++++
 5 files changed, 168 insertions(+), 1 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 401801d..1f61f67 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2010-03-26  Jean Brefort  <jean brefort normalesup org>
+
+	* docs/reference/goffice-0.8-sections.txt: new entries.
+	* goffice/canvas/goc-polygon.c (goc_polygon_priv_free),
+	(goc_polygon_set_property), (goc_polygon_get_property),
+	(goc_polygon_class_init), (goc_polygon_init): implement polygon splitting.
+	* goffice/canvas/goc-utils.c (goc_int_array_new),
+	(goc_int_array_ref), (goc_int_array_unref),
+	(goc_int_array_get_type): ditto.
+	* goffice/canvas/goc-utils.h: ditto.
+
 2010-03-25  Morten Welinder  <terra gnome org>
 
 	* goffice/app/go-conf-keyfile.c (go_conf_add_monitor,
diff --git a/docs/reference/goffice-0.8-sections.txt b/docs/reference/goffice-0.8-sections.txt
index 8dfcf16..d467869 100644
--- a/docs/reference/goffice-0.8-sections.txt
+++ b/docs/reference/goffice-0.8-sections.txt
@@ -3121,9 +3121,16 @@ GocPoints
 goc_points_new
 goc_points_ref
 goc_points_unref
+GocIntArray
+goc_int_array_new
+goc_int_array_ref
+goc_int_array_unref
+
 <SUBSECTION Standard>
 goc_points_get_type
 GOC_TYPE_POINTS
+goc_int_array_get_type
+GOC_TYPE_INT_ARRAY
 </SECTION>
 
 ###############################################################################
diff --git a/goffice/canvas/goc-polygon.c b/goffice/canvas/goc-polygon.c
index 91a3398..5a602b6 100644
--- a/goffice/canvas/goc-polygon.c
+++ b/goffice/canvas/goc-polygon.c
@@ -36,12 +36,22 @@ enum {
 	POLYGON_PROP_POINTS,
 	POLYGON_PROP_SPLINE,
 	POLYGON_PROP_FILL_RULE,
+	POLYGON_PROP_SIZES
 };
 
 typedef struct {
 	gboolean fill_rule;
+	unsigned nb_sizes;
+	int *sizes;
 } GocPolygonPriv;
 
+static void goc_polygon_priv_free (gpointer data)
+{
+	GocPolygonPriv *priv = (GocPolygonPriv *) data;
+	g_free (priv->sizes);
+	g_free (priv);
+}
+
 static GocStyledItemClass *parent_class;
 
 static void
@@ -71,6 +81,10 @@ goc_polygon_set_property (GObject *gobject, guint param_id,
 				polygon->points[i] = points->points[i];
 		} else
 			polygon->points = NULL;
+		/* reset sizes */
+		g_free (priv->sizes);
+		priv->sizes = NULL;
+		priv->nb_sizes = 0;
 		break;
 	}
 	case POLYGON_PROP_SPLINE:
@@ -79,6 +93,25 @@ goc_polygon_set_property (GObject *gobject, guint param_id,
 	case POLYGON_PROP_FILL_RULE:
 		priv->fill_rule = g_value_get_boolean (value);
 		break;
+	case POLYGON_PROP_SIZES: {
+		unsigned i, avail = polygon->nb_points - 3;
+		GocIntArray *array = (GocIntArray *) g_value_get_boxed (value);
+		g_free (priv->sizes);
+		priv->sizes = NULL;
+		priv->nb_sizes = 0;
+		for (i = 0; i < array->n; i++) {
+			if (array->vals[i] < 3 || array->vals[i] > (int) avail)
+				break;
+			avail -= array->vals[i];
+			priv->nb_sizes++;
+		}
+		if (priv->nb_sizes > 0) {
+			priv->sizes = g_new (int, priv->nb_sizes);
+			for (i = 0; i < priv->nb_sizes; i++)
+				priv->sizes[i] = array->vals[i];
+		}
+		break;
+	}
 
 	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
 		return; /* NOTE : RETURN */
@@ -120,6 +153,15 @@ goc_polygon_get_property (GObject *gobject, guint param_id,
 	case POLYGON_PROP_FILL_RULE:
 		g_value_set_boolean (value, priv->fill_rule);
 		break;
+	case POLYGON_PROP_SIZES: {
+		unsigned i;
+		GocIntArray *array = goc_int_array_new (priv->nb_sizes);
+		for (i = 0; i < array->n; i++)
+			array->vals[i] = priv->sizes[i];
+		g_value_set_boxed (value, array);
+		goc_int_array_unref (array);
+		break;
+	}
 
 	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
 		return; /* NOTE : RETURN */
@@ -294,6 +336,13 @@ goc_polygon_class_init (GocItemClass *item_klass)
 				      _("Set fill rule to winding or even/odd"),
 				      FALSE,
 				      GSF_PARAM_STATIC | G_PARAM_READWRITE));
+        g_object_class_install_property (obj_klass, POLYGON_PROP_SIZES,
+                 g_param_spec_boxed ("sizes", _("sizes"),
+				     _("If set, the polygon will be split as several polygons according to the given sizes. "
+				         "Each size must be at least 3. Values following an invalid value will be discarded. "
+				         "Setting the \"points\" property will reset the sizes."),
+				     GOC_TYPE_INT_ARRAY,
+				     GSF_PARAM_STATIC | G_PARAM_READWRITE));
 
 	item_klass->update_bounds = goc_polygon_update_bounds;
 	item_klass->distance = goc_polygon_distance;
@@ -304,7 +353,7 @@ static void
 goc_polygon_init (GocPolygon *polygon)
 {
 	GocPolygonPriv *priv = g_new0 (GocPolygonPriv, 1);
-	g_object_set_data_full (G_OBJECT (polygon), "polygon-private", priv, g_free);
+	g_object_set_data_full (G_OBJECT (polygon), "polygon-private", priv, goc_polygon_priv_free);
 }
 
 GSF_CLASS (GocPolygon, goc_polygon,
diff --git a/goffice/canvas/goc-utils.c b/goffice/canvas/goc-utils.c
index af67072..5243492 100644
--- a/goffice/canvas/goc-utils.c
+++ b/goffice/canvas/goc-utils.c
@@ -106,3 +106,88 @@ goc_points_get_type (void)
 
     return type_points;
 }
+
+
+/**
+ * GocIntArray:
+ * @n: the size of the array.
+ * @vals: The embedded values.
+ *
+ * A boxed type used to hold an array of integers.
+ * Since: 0.8.2
+ **/
+
+/**
+ * goc_int_array_new:
+ * @n: the number of integers in the array.
+ *
+ * Creates a new #GocIntArray instances with @n values initialized to 0.
+ * The values can be changed using direct access:
+ *
+ * <programlisting>
+ *      GocIntArray array = goc_int_array_new (2);
+ *      array->vals[0] = my_first_int;
+ *      array->vals[1] = my_second_int;
+ * </programlisting>
+ *
+ * Returns: the newly created #GocIntArray with an initial references count of 1.
+ * Since: 0.8.2
+ **/
+
+GocIntArray *
+goc_int_array_new (unsigned n)
+{
+	GocIntArray *array = g_new (GocIntArray, 1);
+	array->n = n;
+	array->refs = 1;
+	array->vals = g_new0 (int, n);
+	return array;
+}
+
+/**
+ * goc_int_array_ref :
+ * @array: #GocIntArray
+ *
+ * Increases the references count of @array by 1.
+ * Returns: the referenced #GocIntArray.
+ * Since: 0.8.2
+ **/
+GocIntArray *
+goc_int_array_ref (GocIntArray *array)
+{
+	array->refs++;
+	return array;
+}
+
+/**
+ * goc_int_array_unref:
+ * @array: #GocIntArray
+ *
+ * Decreases the references count of @array by 1, and destroys it if the
+ * references count becomes 0.
+ * Since: 0.8.2
+ **/
+void
+goc_int_array_unref (GocIntArray *array)
+{
+	array->refs--;
+	if (array->refs == 0) {
+		g_free (array->vals);
+		array->vals = NULL;
+		g_free (array);
+	}
+}
+
+GType
+goc_int_array_get_type (void)
+{
+    static GType type_int_array = 0;
+
+    if (!type_int_array)
+	type_int_array = g_boxed_type_register_static
+	    ("GocIntArray",
+	     (GBoxedCopyFunc) goc_int_array_ref,
+	     (GBoxedFreeFunc) goc_int_array_unref);
+
+    return type_int_array;
+}
diff --git a/goffice/canvas/goc-utils.h b/goffice/canvas/goc-utils.h
index 8523912..16723da 100644
--- a/goffice/canvas/goc-utils.h
+++ b/goffice/canvas/goc-utils.h
@@ -39,4 +39,19 @@ GocPoints       *goc_points_new (unsigned n);
 GocPoints	*goc_points_ref (GocPoints *points);
 void		 goc_points_unref (GocPoints *points);
 
+typedef struct {
+	/*< private >*/
+	unsigned refs;
+	/*< public >*/
+	unsigned n;
+	int *vals;
+} GocIntArray;
+
+GType goc_int_array_get_type (void);
+#define GOC_TYPE_INT_ARRAY goc_int_array_get_type ()
+
+GocIntArray     *goc_int_array_new (unsigned n);
+GocIntArray     *goc_int_array_ref (GocIntArray *array);
+void		 goc_int_array_unref (GocIntArray *array);
+
 #endif  /* GOC_UTILS_H */



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