[goffice] Implemented GocPath.



commit a9329cf99b919dd86e1224c0d36adc9421774c3b
Author: Valek Filippov <frob gnome org>
Date:   Fri Apr 9 16:32:34 2010 -0400

    Implemented GocPath.

 ChangeLog                  |    6 +
 NEWS                       |    2 +-
 goffice/canvas/Makefile.am |    2 +
 goffice/canvas/goc-path.c  |  274 ++++++++++++++++++++++++++++++++++++++++++++
 goffice/canvas/goc-path.h  |   48 ++++++++
 5 files changed, 331 insertions(+), 1 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index a2473f7..b9c8d75 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2010-04-09  Valek Filippov  <frob gnome org>
+
+	* goffice/canvas/goc-path.c: add Path support
+	* goffice/canvas/goc-path.h: ditto
+	* goffice/canvas/Makefile.am: ditto
+
 2010-04-09  Jean Brefort  <jean brefort normalesup org>
 
 	* goffice/utils/go-path.c (go_path_new), (go_path_free),
diff --git a/NEWS b/NEWS
index cdc80d9..c85e217 100644
--- a/NEWS
+++ b/NEWS
@@ -11,7 +11,7 @@ Valek:
 	* Fix distance calculation for arc, ellipse, polygon, polyline,
 	  and rectangle.
 	* Support rotation for text on canvas.
-	* Add PolyPolygon
+	* Add PolyPolygon and Path
 
 --------------------------------------------------------------------------
 goffice 0.8.1:
diff --git a/goffice/canvas/Makefile.am b/goffice/canvas/Makefile.am
index 993131b..20b4913 100644
--- a/goffice/canvas/Makefile.am
+++ b/goffice/canvas/Makefile.am
@@ -9,6 +9,7 @@ libgoffice_canvas_la_SOURCES =	\
 	goc-group.c		\
 	goc-item.c		\
 	goc-line.c		\
+	goc-path.c		\
 	goc-pixbuf.c		\
 	goc-polyline.c		\
 	goc-polygon.c		\
@@ -28,6 +29,7 @@ libgoffice_canvas_la_HEADERS =	\
 	goc-group.h		\
 	goc-item.h		\
 	goc-line.h		\
+	goc-path.h		\
 	goc-pixbuf.h		\
 	goc-polyline.h		\
 	goc-polygon.h		\
diff --git a/goffice/canvas/goc-path.c b/goffice/canvas/goc-path.c
new file mode 100644
index 0000000..ed9dde6
--- /dev/null
+++ b/goffice/canvas/goc-path.c
@@ -0,0 +1,274 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * goc-path.c :
+ *
+ * Copyright (C) 2010 Valek FIlippov (frob gnome org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
+ * USA
+ */
+
+#include <goffice/goffice-config.h>
+#include <goffice/goffice.h>
+#include <gsf/gsf-impl-utils.h>
+#include <glib/gi18n-lib.h>
+#include <math.h>
+
+/**
+ * SECTION:goc-path
+ * @short_description: Path item.
+ *
+ * #GocPath implements path drawing in the canvas.
+**/
+
+enum {
+	PATH_PROP_0,
+	PATH_PROP_X,
+	PATH_PROP_Y,
+	PATH_PROP_ROTATION,
+	PATH_PROP_CLOSED,
+	PATH_PROP_PATH,
+};
+
+static void
+goc_path_set_property (GObject *gobject, guint param_id,
+				    GValue const *value, GParamSpec *pspec)
+{
+	GocPath *path = GOC_PATH (gobject);
+
+	switch (param_id) {
+	case PATH_PROP_X:
+		path->x = g_value_get_double (value);
+		break;
+
+	case PATH_PROP_Y:
+		path->y = g_value_get_double (value);
+		break;
+
+	case PATH_PROP_ROTATION:
+		path->rotation = g_value_get_double (value);
+		break;
+		
+	case PATH_PROP_CLOSED:
+		path->closed = g_value_get_boolean (value);
+		break;
+		
+	case PATH_PROP_PATH:
+		path->path = g_value_peek_pointer (value);
+		break;
+
+	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
+		return; /* NOTE : RETURN */
+	}
+	goc_item_bounds_changed (GOC_ITEM (gobject));
+}
+
+static void
+goc_path_get_property (GObject *gobject, guint param_id,
+				    GValue *value, GParamSpec *pspec)
+{
+	GocPath *path = GOC_PATH (gobject);
+
+	switch (param_id) {
+	case PATH_PROP_X:
+		g_value_set_double (value, path->x);
+		break;
+
+	case PATH_PROP_Y:
+		g_value_set_double (value, path->y);
+		break;
+
+	case PATH_PROP_ROTATION:
+		g_value_set_double (value, path->rotation);
+		break;
+
+	case PATH_PROP_CLOSED:
+		g_value_set_boolean (value, path->closed);
+		break;
+
+	case PATH_PROP_PATH:
+		g_value_set_boxed (value, &path->path);
+		break;
+
+	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
+		return; /* NOTE : RETURN */
+	}
+}
+
+static gboolean
+goc_path_prepare_draw (GocItem const *item, cairo_t *cr, gboolean flag)
+{
+	GocPath *path = GOC_PATH (item);
+	double sign = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1: 1;
+	double rsign = sign;
+
+	cairo_save (cr);
+	if (1 == flag) {
+		goc_group_cairo_transform (item->parent, cr, path->x , path->y);
+		sign = 1;
+	} else {
+		cairo_translate (cr, path->x , path->y);
+		rsign = 1;
+	}
+	cairo_rotate (cr, path->rotation * rsign);
+	go_path_to_cairo (path->path, GO_PATH_DIRECTION_FORWARD, cr);
+	cairo_restore (cr);
+
+	return TRUE;
+}
+
+static void
+goc_path_update_bounds (GocItem *item)
+{
+	cairo_surface_t *surface;
+	cairo_t *cr;
+
+	surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+	cr = cairo_create (surface);
+
+	if (goc_path_prepare_draw (item, cr, 0)) {
+		goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr);
+		cairo_stroke_extents (cr, &item->x0, &item->y0, &item->x1, &item->y1);
+	}
+
+	cairo_destroy (cr);
+	cairo_surface_destroy (surface);
+}
+
+static double
+goc_path_distance (GocItem *item, double x, double y, GocItem **near_item)
+{
+	GocPath *path = GOC_PATH (item);
+	GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (item));
+	double tmp_width = 0;
+	double res = 20;
+	double ppu = goc_canvas_get_pixels_per_unit (item->canvas);
+	cairo_surface_t *surface;
+	cairo_t *cr;
+
+	*near_item = item;
+	tmp_width = style->line.width;
+	if (style->line.width * ppu < 5)
+		style->line.width = 5. / (ppu * ppu);
+	else
+		style->line.width /= ppu;
+	surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+	cr = cairo_create (surface);
+
+	if (goc_path_prepare_draw (item, cr, 0)) {
+		// Filled OR both fill and stroke are none
+		if ((path->closed && style->fill.type != GO_STYLE_FILL_NONE) ||
+			(style->fill.type == GO_STYLE_FILL_NONE && !goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr))) {
+			if (cairo_in_fill (cr, x, y))
+				res = 0;
+		}
+		if (goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr) && cairo_in_stroke (cr, x, y))
+			res = 0;
+	}
+
+	cairo_destroy (cr);
+	cairo_surface_destroy (surface);
+	style->line.width = tmp_width;
+	return res;
+}
+
+static void
+goc_path_draw (GocItem const *item, cairo_t *cr)
+{
+	GocPath *path = GOC_PATH (item);
+
+	cairo_save(cr);
+	if (goc_path_prepare_draw (item, cr, 1)) {
+		if (path->closed && go_styled_object_set_cairo_fill (GO_STYLED_OBJECT (item), cr))
+			cairo_fill_preserve (cr);
+		if (goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr)) {
+			cairo_stroke (cr);
+		} else {
+			cairo_new_path (cr);
+		}
+	}
+	cairo_restore(cr);
+}
+
+static void
+goc_path_init_style (G_GNUC_UNUSED GocStyledItem *item, GOStyle *style)
+{
+	GocPath *path = GOC_PATH (item);
+
+	style->interesting_fields = GO_STYLE_OUTLINE | GO_STYLE_FILL;
+	if (style->line.auto_dash)
+		style->line.dash_type = GO_LINE_SOLID;
+	if (style->line.auto_color)
+		style->line.color = GO_COLOR_BLACK;
+	if (style->line.auto_fore)
+		style->line.fore  = 0;
+	if (path->closed) {
+		if (style->fill.auto_type)
+			style->fill.type  = GO_STYLE_FILL_PATTERN;
+		if (style->fill.auto_fore)
+			style->fill.pattern.fore = GO_COLOR_BLACK;
+		if (style->fill.auto_back)
+			style->fill.pattern.back = GO_COLOR_WHITE;
+	}
+}
+
+static void
+goc_path_class_init (GocItemClass *item_klass)
+{
+	GObjectClass *obj_klass = (GObjectClass *) item_klass;
+	GocStyledItemClass *gsi_klass = (GocStyledItemClass *) item_klass;
+
+	gsi_klass->init_style = goc_path_init_style;
+
+	obj_klass->get_property = goc_path_get_property;
+	obj_klass->set_property = goc_path_set_property;
+	g_object_class_install_property (obj_klass, PATH_PROP_X,
+		g_param_spec_double ("x",
+			_("x"),
+			_("The path first point x coordinate"),
+			-G_MAXDOUBLE, G_MAXDOUBLE, 0.,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE));
+	g_object_class_install_property (obj_klass, PATH_PROP_Y,
+		g_param_spec_double ("y",
+			_("y"),
+			_("The path first point y coordinate"),
+			-G_MAXDOUBLE, G_MAXDOUBLE, 0.,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE));
+	g_object_class_install_property (obj_klass, PATH_PROP_ROTATION,
+		g_param_spec_double ("rotation",
+			_("Rotation"),
+			_("The rotation around first point position"),
+			0., 2 * M_PI, 0.,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE));
+	g_object_class_install_property (obj_klass, PATH_PROP_CLOSED,
+		g_param_spec_boolean ("closed",
+			_("Closed"),
+			_("The flag for closed path"),
+			FALSE,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE));
+	g_object_class_install_property (obj_klass, PATH_PROP_PATH,
+		g_param_spec_boxed ("path",
+			_("Path"),
+			_("The path points"),
+			GO_TYPE_PATH,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE));
+	item_klass->update_bounds = goc_path_update_bounds;
+	item_klass->distance = goc_path_distance;
+	item_klass->draw = goc_path_draw;
+}
+
+GSF_CLASS (GocPath, goc_path,
+	   goc_path_class_init, NULL,
+	   GOC_TYPE_STYLED_ITEM)
diff --git a/goffice/canvas/goc-path.h b/goffice/canvas/goc-path.h
new file mode 100644
index 0000000..bc0090e
--- /dev/null
+++ b/goffice/canvas/goc-path.h
@@ -0,0 +1,48 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * goc-path.h :
+ *
+ * Copyright (C) 2010 Valek Filippov (frob gnome org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
+ * USA
+ */
+
+#ifndef GOC_PATH_H
+#define GOC_PATH_H
+
+#include <goffice/goffice.h>
+
+G_BEGIN_DECLS
+
+struct _GocPath {
+	GocStyledItem base;
+
+	double rotation, x, y;
+	gboolean closed;
+	GOPath *path;
+};
+
+typedef GocStyledItemClass GocPathClass;
+
+#define GOC_TYPE_PATH	(goc_path_get_type ())
+#define GOC_PATH(o)	(G_TYPE_CHECK_INSTANCE_CAST ((o), GOC_TYPE_PATH, GocPath))
+#define GOC_IS_PATH(o)	(G_TYPE_CHECK_INSTANCE_TYPE ((o), GOC_TYPE_PATH))
+
+GType goc_path_get_type (void);
+
+G_END_DECLS
+
+#endif  /* GOC_PATH_H */



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