[goffice] Implemented GocPath.
- From: Valek Frob <frob src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] Implemented GocPath.
- Date: Fri, 9 Apr 2010 20:36:00 +0000 (UTC)
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]