[goffice] fixed some canvas issues.
- From: Jean Bréfort <jbrefort src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [goffice] fixed some canvas issues.
- Date: Wed, 19 Aug 2009 08:38:18 +0000 (UTC)
commit a36382eb8abfaae017160c322278c2802d764bba
Author: Jean Brefort <jean brefort normalesup org>
Date: Wed Aug 19 10:37:47 2009 +0200
fixed some canvas issues.
ChangeLog | 6 +
goffice/canvas/Makefile.am | 2 +
goffice/canvas/goc-canvas.c | 49 ++++++---
goffice/canvas/goc-circle.c | 36 ++-----
goffice/canvas/goc-ellipse.c | 32 +++----
goffice/canvas/goc-item.c | 3 +
goffice/canvas/goc-line-impl.h | 41 +++++++
goffice/canvas/goc-line.c | 12 ++-
goffice/canvas/goc-polygon.c | 3 +-
goffice/canvas/goc-polyline.c | 219 ++++++++++++++++++++++++++++++++++++++
goffice/canvas/goc-polyline.h | 48 ++++++++
goffice/canvas/goc-rectangle.c | 15 +--
goffice/canvas/goc-styled-item.c | 36 ++++++-
goffice/canvas/goc-styled-item.h | 3 +
goffice/canvas/goc-text.c | 105 ++++++++++++++++++-
goffice/canvas/goc-text.h | 2 +
goffice/canvas/goc-widget.c | 24 ++++
goffice/canvas/goffice-canvas.h | 2 +
goffice/graph/gog-equation.c | 2 +-
po/ChangeLog | 4 +
po/POTFILES.in | 1 +
21 files changed, 562 insertions(+), 83 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 409fbfb..e4e41b6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2009-08-19 Jean Brefort <jean brefort normalesup org>
+
+ * goffice/canvas/Makefile.am: add gog-polyline.[c,h].
+ * goffice/canvas/*.[c,h]: fixed various issues.
+ * goffice/grph/gog-equation.c: make it compile with latest lasem code.
+
2009-08-15 Morten Welinder <terra gnome org>
* configure.in: Post-release bump.
diff --git a/goffice/canvas/Makefile.am b/goffice/canvas/Makefile.am
index 742fea4..0083dca 100644
--- a/goffice/canvas/Makefile.am
+++ b/goffice/canvas/Makefile.am
@@ -9,6 +9,7 @@ libgoffice_canvas_la_SOURCES = \
goc-item.c \
goc-line.c \
goc-pixbuf.c \
+ goc-polyline.c \
goc-polygon.c \
goc-rectangle.c \
goc-styled-item.c \
@@ -26,6 +27,7 @@ libgoffice_canvas_la_HEADERS = \
goc-item.h \
goc-line.h \
goc-pixbuf.h \
+ goc-polyline.h \
goc-polygon.h \
goc-rectangle.h \
goc-structs.h \
diff --git a/goffice/canvas/goc-canvas.c b/goffice/canvas/goc-canvas.c
index 7950916..8a3a929 100644
--- a/goffice/canvas/goc-canvas.c
+++ b/goffice/canvas/goc-canvas.c
@@ -53,9 +53,14 @@ expose_cb (GocCanvas *canvas, GdkEventExpose *event, G_GNUC_UNUSED gpointer data
static gboolean
button_press_cb (GocCanvas *canvas, GdkEventButton *event, G_GNUC_UNUSED gpointer data)
{
- double x = canvas->scroll_x1 + event->x / canvas->pixels_per_unit;
- double y = canvas->scroll_y1 + event->y / canvas->pixels_per_unit;
- GocItem *item = goc_canvas_get_item_at (canvas, x, y);
+ double x, y;
+ GocItem *item;
+
+ if (event->window != gtk_layout_get_bin_window (&canvas->base))
+ return TRUE;
+ x = canvas->scroll_x1 + event->x / canvas->pixels_per_unit;
+ y = canvas->scroll_y1 + event->y / canvas->pixels_per_unit;
+ item = goc_canvas_get_item_at (canvas, x, y);;
if (item) {
canvas->cur_event = (GdkEvent *) event;
if (event->type == GDK_2BUTTON_PRESS)
@@ -69,9 +74,14 @@ button_press_cb (GocCanvas *canvas, GdkEventButton *event, G_GNUC_UNUSED gpointe
static gboolean
button_release_cb (GocCanvas *canvas, GdkEventButton *event, G_GNUC_UNUSED gpointer data)
{
- double x = canvas->scroll_x1 + event->x / canvas->pixels_per_unit;
- double y = canvas->scroll_y1 + event->y / canvas->pixels_per_unit;
- GocItem *item = (canvas->grabbed_item != NULL)?
+ double x, y;
+ GocItem *item;
+
+ if (event->window != gtk_layout_get_bin_window (&canvas->base))
+ return TRUE;
+ x = canvas->scroll_x1 + event->x / canvas->pixels_per_unit;
+ y = canvas->scroll_y1 + event->y / canvas->pixels_per_unit;
+ item = (canvas->grabbed_item != NULL)?
canvas->grabbed_item:
goc_canvas_get_item_at (canvas, x, y);
if (item) {
@@ -85,9 +95,13 @@ button_release_cb (GocCanvas *canvas, GdkEventButton *event, G_GNUC_UNUSED gpoin
static gboolean
motion_cb (GocCanvas *canvas, GdkEventMotion *event, G_GNUC_UNUSED gpointer data)
{
- double x = canvas->scroll_x1 + event->x / canvas->pixels_per_unit;
- double y = canvas->scroll_y1 + event->y / canvas->pixels_per_unit;
+ double x, y;
GocItem *item;
+
+ if (event->window != gtk_layout_get_bin_window (&canvas->base))
+ return TRUE;
+ x = canvas->scroll_x1 + event->x / canvas->pixels_per_unit;
+ y = canvas->scroll_y1 + event->y / canvas->pixels_per_unit;
if (canvas->grabbed_item != NULL)
item = canvas->grabbed_item;
else
@@ -129,9 +143,14 @@ key_press_cb (GocCanvas *canvas, GdkEventKey* event, G_GNUC_UNUSED gpointer data
static gboolean
enter_notify_cb (GocCanvas *canvas, GdkEventCrossing* event, G_GNUC_UNUSED gpointer data)
{
- double x = canvas->scroll_x1 + event->x / canvas->pixels_per_unit;
- double y = canvas->scroll_y1 + event->y / canvas->pixels_per_unit;
- GocItem *item = goc_canvas_get_item_at (canvas, x, y);
+ double x, y;
+ GocItem *item;
+
+ if (event->window != gtk_layout_get_bin_window (&canvas->base))
+ return TRUE;
+ x = canvas->scroll_x1 + event->x / canvas->pixels_per_unit;
+ y = canvas->scroll_y1 + event->y / canvas->pixels_per_unit;
+ item = goc_canvas_get_item_at (canvas, x, y);;
if (item) {
canvas->last_item = item;
return GOC_ITEM_GET_CLASS (item)->enter_notify (item, x, y);
@@ -142,8 +161,12 @@ enter_notify_cb (GocCanvas *canvas, GdkEventCrossing* event, G_GNUC_UNUSED gpoin
static gboolean
leave_notify_cb (GocCanvas *canvas, GdkEventCrossing* event, G_GNUC_UNUSED gpointer data)
{
- double x = canvas->scroll_x1 + event->x / canvas->pixels_per_unit;
- double y = canvas->scroll_y1 + event->y / canvas->pixels_per_unit;
+ double x, y;
+
+ if (event->window != gtk_layout_get_bin_window (&canvas->base))
+ return TRUE;
+ x = canvas->scroll_x1 + event->x / canvas->pixels_per_unit;
+ y = canvas->scroll_y1 + event->y / canvas->pixels_per_unit;
if (canvas->last_item) {
gboolean result = GOC_ITEM_GET_CLASS (canvas->last_item)->leave_notify (canvas->last_item, x, y);
canvas->last_item = NULL;
diff --git a/goffice/canvas/goc-circle.c b/goffice/canvas/goc-circle.c
index b696375..d0eb18f 100644
--- a/goffice/canvas/goc-circle.c
+++ b/goffice/canvas/goc-circle.c
@@ -80,7 +80,7 @@ goc_circle_get_property (GObject *gobject, guint param_id,
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
return; /* NOTE : RETURN */
- }
+ }
}
static double
@@ -102,43 +102,21 @@ static void
goc_circle_draw (GocItem const *item, cairo_t *cr)
{
GocCircle *circle = GOC_CIRCLE (item);
- GOLineDashSequence *line_dash;
- cairo_pattern_t *pat = NULL;
- double width;
- GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (item));
+ double scale = (circle->radius > 0.)? circle->radius: 1.e-10;
cairo_save (cr);
goc_group_cairo_transform (item->parent, cr, circle->x, circle->y);
- cairo_scale (cr, circle->radius, circle->radius);
+ cairo_scale (cr, scale, scale);
cairo_arc (cr, 0., 0., 1., 0., 2 * M_PI);
cairo_restore (cr);
/* Fill the shape */
- pat = go_style_create_cairo_pattern (style, cr);
- if (pat) {
- cairo_set_source (cr, pat);
+ if (go_styled_object_set_cairo_fill (GO_STYLED_OBJECT (item), cr))
cairo_fill_preserve (cr);
- cairo_pattern_destroy (pat);
- }
/* Draw the line */
- width = (style->outline.width)? style->outline.width: 1.;
- cairo_set_line_width (cr, width);
- line_dash = go_line_dash_get_sequence (style->outline.dash_type, width);
- if (line_dash != NULL)
- cairo_set_dash (cr,
- line_dash->dash,
- line_dash->n_dash,
- line_dash->offset);
+ if (goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr))
+ cairo_stroke (cr);
else
- cairo_set_dash (cr, NULL, 0, 0);
- cairo_set_source_rgba (cr,
- UINT_RGBA_R (style->outline.color),
- UINT_RGBA_B (style->outline.color),
- UINT_RGBA_G (style->outline.color),
- UINT_RGBA_A (style->outline.color));
- cairo_stroke (cr);
-
- if (line_dash != NULL)
- go_line_dash_sequence_free (line_dash);
+ cairo_new_path (cr);
}
static void
diff --git a/goffice/canvas/goc-ellipse.c b/goffice/canvas/goc-ellipse.c
index 497a520..5e47601 100644
--- a/goffice/canvas/goc-ellipse.c
+++ b/goffice/canvas/goc-ellipse.c
@@ -65,8 +65,7 @@ goc_ellipse_set_property (GObject *gobject, guint param_id,
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
return; /* NOTE : RETURN */
}
- goc_item_invalidate (GOC_ITEM (gobject));
-
+ goc_item_bounds_changed (GOC_ITEM (ellipse));
}
static void
@@ -99,7 +98,6 @@ goc_ellipse_get_property (GObject *gobject, guint param_id,
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
return; /* NOTE : RETURN */
}
- goc_item_bounds_changed (GOC_ITEM (ellipse));
}
static void
@@ -129,6 +127,7 @@ goc_ellipse_distance (GocItem *item, double x, double y, GocItem **near_item)
double last = G_MAXDOUBLE, df, d2f, t, cs, sn,
a = ellipse->width / 2, b = ellipse->height / 2,
c = a * a - b * b;
+ int i;
*near_item = item;
x = fabs (x - ellipse->x - a);
y = fabs (y - ellipse->y - b);
@@ -146,7 +145,9 @@ goc_ellipse_distance (GocItem *item, double x, double y, GocItem **near_item)
/* initial value: */
t = atan2 (y, x);
/* iterate using the Newton method */
- while (1) {
+ /* iterate no more than 10 times which should be largely enough
+ just a security to avoid an infinite loop if something goes wrong */
+ for (i = 0; i < 10; i++) {
cs = cos (t);
sn = sin (t);
df = a * x * sn - b * y * cs - c * cs * sn;
@@ -163,30 +164,23 @@ goc_ellipse_distance (GocItem *item, double x, double y, GocItem **near_item)
static void
goc_ellipse_draw (GocItem const *item, cairo_t *cr)
-{
+{
GocEllipse *ellipse = GOC_ELLIPSE (item);
- cairo_pattern_t *pat = NULL;
- GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (item));
-
+ double scalex = (ellipse->width > 0.)? ellipse->width / 2.: 1.e-10,
+ scaley = (ellipse->height > 0.)? ellipse->height / 2.: 1.e-10;
+
cairo_save (cr);
goc_group_cairo_transform (item->parent, cr, ellipse->x, ellipse->y);
cairo_translate (cr, ellipse->width / 2., ellipse->height / 2.);
- cairo_scale (cr, ellipse->width / 2., ellipse->height / 2.);
+ cairo_scale (cr, scalex, scaley);
cairo_rotate (cr, ellipse->rotation);
cairo_arc (cr, 0., 0., 1., 0., 2 * M_PI);
cairo_restore (cr);
/* Fill the shape */
- pat = go_style_create_cairo_pattern (style, cr);
- if (pat) {
- cairo_set_source (cr, pat);
- if (style->outline.dash_type != GO_LINE_NONE)
- cairo_fill_preserve (cr);
- else
- cairo_fill (cr);
- cairo_pattern_destroy (pat);
- }
+ if (go_styled_object_set_cairo_fill (GO_STYLED_OBJECT (item), cr))
+ cairo_fill_preserve (cr);
/* Draw the line */
- if (go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr))
+ if (goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr))
cairo_stroke (cr);
else
cairo_new_path (cr);
diff --git a/goffice/canvas/goc-item.c b/goffice/canvas/goc-item.c
index dfb7007..3c5dbf3 100644
--- a/goffice/canvas/goc-item.c
+++ b/goffice/canvas/goc-item.c
@@ -85,6 +85,7 @@ goc_item_finalize (GObject *object)
GocItemClass *klass = GOC_ITEM_GET_CLASS (item);
if (klass->unrealize)
klass->unrealize (item);
+ item->cached_bounds = TRUE; /* avois a call to update_bounds */
goc_item_invalidate (item);
}
if (item->parent != NULL)
@@ -305,6 +306,8 @@ goc_item_parent_changed (GocItem *item)
void
goc_item_grab (GocItem *item)
{
+ if (item == goc_canvas_get_grabbed_item (item->canvas))
+ return;
g_return_if_fail (GOC_IS_ITEM (item));
goc_canvas_grab_item (item->canvas, item);
}
diff --git a/goffice/canvas/goc-line-impl.h b/goffice/canvas/goc-line-impl.h
new file mode 100644
index 0000000..112a5d9
--- /dev/null
+++ b/goffice/canvas/goc-line-impl.h
@@ -0,0 +1,41 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * goc-line-impl.h :
+ *
+ * Copyright (C) 2009 Jean Brefort (jean brefort normalesup 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_LINE_IMPL_H
+#define GOC_LINE_IMPL_H
+
+#include <goffice/goffice.h>
+
+G_BEGIN_DECLS
+
+struct _GocLine {
+ GocStyledItem base;
+
+ /* using these to avoid confusion with x0 and others in GocItem */
+ double startx, starty, endx, endy;
+};
+
+typedef GocStyledItemClass GocLineClass;
+
+G_END_DECLS
+
+#endif /* GOC_LINE_H */
diff --git a/goffice/canvas/goc-line.c b/goffice/canvas/goc-line.c
index 993a170..2048f0d 100644
--- a/goffice/canvas/goc-line.c
+++ b/goffice/canvas/goc-line.c
@@ -144,10 +144,18 @@ static void goc_line_draw (GocItem const *item, cairo_t *cr)
{
GocLine *line = GOC_LINE (item);
if (go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr)) {
+ /* try to avoid horizontal and vertical lines between two pixels */
+ double hoffs, voffs = ceil (go_styled_object_get_style (GO_STYLED_OBJECT (item))->line.width);
+ if (voffs <= 0.)
+ voffs = 1.;
+ hoffs = ((int) voffs & 1)? .5: 0.;
+ voffs = (line->starty == line->endy)? hoffs: 0.;
+ if (line->startx != line->endx)
+ hoffs = 0.;
cairo_save (cr);
- goc_group_cairo_transform (item->parent, cr, line->startx, line->starty);
+ goc_group_cairo_transform (item->parent, cr, hoffs + (int) line->startx, voffs + (int) line->starty);
cairo_move_to (cr, 0., 0.);
- cairo_line_to (cr, line->endx - line->startx, line->endy - line->starty);
+ cairo_line_to (cr, (int) (line->endx - line->startx), (int) (line->endy - line->starty));
cairo_stroke (cr);
cairo_restore (cr);
}
diff --git a/goffice/canvas/goc-polygon.c b/goffice/canvas/goc-polygon.c
index 64ff27b..9272f97 100644
--- a/goffice/canvas/goc-polygon.c
+++ b/goffice/canvas/goc-polygon.c
@@ -41,8 +41,7 @@ goc_polygon_set_property (GObject *gobject, guint param_id,
unsigned i;
GocPoints *points = (GocPoints *) g_value_get_boxed (value);
polygon->nb_points = points->n;
- if (polygon->points)
- g_free (polygon->points);
+ g_free (polygon->points);
polygon->points = g_new (GocPoint, points->n);
for (i = 0; i < points->n; i++)
polygon->points[i] = points->points[i];
diff --git a/goffice/canvas/goc-polyline.c b/goffice/canvas/goc-polyline.c
new file mode 100644
index 0000000..4557a7e
--- /dev/null
+++ b/goffice/canvas/goc-polyline.c
@@ -0,0 +1,219 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * goc-polyline.c :
+ *
+ * Copyright (C) 2009 Jean Brefort (jean brefort normalesup 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>
+
+enum {
+ POLYLINE_PROP_0,
+ POLYLINE_PROP_POINTS,
+ POLYLINE_PROP_SPLINE
+};
+
+static void
+goc_polyline_set_property (GObject *gobject, guint param_id,
+ GValue const *value, GParamSpec *pspec)
+{
+ GocPolyline *polyline = GOC_POLYLINE (gobject);
+
+ switch (param_id) {
+ case POLYLINE_PROP_POINTS: {
+ unsigned i;
+ GocPoints *points = (GocPoints *) g_value_get_boxed (value);
+ polyline->nb_points = points->n;
+ g_free (polyline->points);
+ polyline->points = g_new (GocPoint, points->n);
+ for (i = 0; i < points->n; i++)
+ polyline->points[i] = points->points[i];
+ break;
+ }
+ case POLYLINE_PROP_SPLINE:
+ polyline->use_spline = g_value_get_boolean (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_polyline_get_property (GObject *gobject, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ GocPolyline *polyline = GOC_POLYLINE (gobject);
+
+ switch (param_id) {
+ case POLYLINE_PROP_POINTS: {
+ unsigned i;
+ GocPoints *points = goc_points_new (polyline->nb_points);
+ for (i = 0; i < points->n; i++)
+ points->points[i] = polyline->points[i];
+ g_value_set_boxed (value, points);
+ goc_points_unref (points);
+ break;
+ }
+ case POLYLINE_PROP_SPLINE:
+ g_value_set_boolean (value, polyline->use_spline);
+ break;
+
+ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
+ return; /* NOTE : RETURN */
+ }
+}
+
+static void
+goc_polyline_update_bounds (GocItem *item)
+{
+ GocPolyline *polyline = GOC_POLYLINE (item);
+ GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (item));
+ double extra_width = style->line.width;
+ unsigned i;
+ if (extra_width <= 0.)
+ extra_width = 1.;
+ if (polyline->nb_points == 0)
+ return;
+ /* FIXME: implement the use_spline case */
+ item->x0 = item->x1 = polyline->points[0].x;
+ item->y0 = item->y1 = polyline->points[0].y;
+ for (i = 1; i < polyline->nb_points; i++) {
+ if (polyline->points[i].x < item->x0)
+ item->x0 = polyline->points[i].x;
+ else if (polyline->points[i].x > item->x1)
+ item->x1 = polyline->points[i].x;
+ if (polyline->points[i].y < item->y0)
+ item->y0 = polyline->points[i].y;
+ else if (polyline->points[i].y > item->y1)
+ item->y1 = polyline->points[i].y;
+ }
+ item->x0 -= extra_width;
+ item->y0 -= extra_width;
+ item->x1 -= extra_width;
+ item->y1 -= extra_width;
+}
+
+static double
+goc_polyline_distance (GocItem *item, double x, double y, GocItem **near_item)
+{
+ GocPolyline *polyline = GOC_POLYLINE (item);
+ GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (item));
+ /* FIXME: implement the use_spline case */
+ double extra_width = (style->outline.width)? style->outline.width /2.: .5;
+ double dx, dy, l, startx, starty, x_, y_, t, res;
+ unsigned i;
+
+ *near_item = item;
+ /* FIXME: not tested!!! */
+ /* first test if the point is inside the polygon */
+ startx = polyline->points[0].x;
+ starty = polyline->points[0].y;
+ res = hypot (polyline->points[polyline->nb_points - 1].x - x, polyline->points[polyline->nb_points - 1].y - y);
+ for (i = 0; i < polyline->nb_points; i++) {
+ dx = polyline->points[i].x - startx;
+ dy = polyline->points[i].y - starty;
+ l = hypot (dx, dy);
+ x_ = x - startx;
+ y_ = y - starty;
+ t = (x_ * dx + y_ * dy) / l;
+ y = (-x_ * dy + y_ * dx) / l;
+ x_ = t;
+ *near_item = item;
+ if (x < 0. ) {
+ t = hypot (x_, y_);
+ if (t < res)
+ res = t;
+ } else if (t <= l) {
+ if (y_ < res)
+ res = y_;
+ }
+ startx = polyline->points[i].x;
+ starty = polyline->points[i].y;
+ }
+ res -= extra_width; /* no need to be more precise */
+ return (res > 0.)? res: 0.;
+}
+
+static void
+goc_polyline_draw (GocItem const *item, cairo_t *cr)
+{
+ GocPolyline *polyline = GOC_POLYLINE (item);
+ unsigned i;
+ if (polyline->nb_points == 0)
+ return;
+ cairo_save (cr);
+ goc_group_cairo_transform (item->parent, cr, polyline->points[0].x, polyline->points[0].y);
+ cairo_move_to (cr, 0., 0.);
+ /* FIXME: implement the use_spline case */
+
+ for (i = 1; i < polyline->nb_points; i++)
+ cairo_line_to (cr, polyline->points[i].x - polyline->points[0].x,
+ polyline->points[i].y - polyline->points[0].y);
+
+ if (go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr))
+ cairo_stroke (cr);
+ else
+ cairo_new_path (cr);
+ cairo_restore (cr);
+}
+
+static void
+goc_polyline_init_style (G_GNUC_UNUSED GocStyledItem *item, GOStyle *style)
+{
+ style->interesting_fields = GO_STYLE_LINE;
+ if (style->line.auto_dash)
+ style->line.dash_type = GO_LINE_SOLID;
+ if (style->line.auto_color)
+ style->line.color = RGBA_BLACK;
+}
+
+static void
+goc_polyline_class_init (GocItemClass *item_klass)
+{
+ GObjectClass *obj_klass = (GObjectClass *) item_klass;
+ GocStyledItemClass *gsi_klass = (GocStyledItemClass *) item_klass;
+
+ gsi_klass->init_style = goc_polyline_init_style;
+
+ obj_klass->get_property = goc_polyline_get_property;
+ obj_klass->set_property = goc_polyline_set_property;
+ g_object_class_install_property (obj_klass, POLYLINE_PROP_POINTS,
+ g_param_spec_boxed ("points", _("points"), _("The polyline vertices"),
+ GOC_TYPE_POINTS,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE));
+ g_object_class_install_property (obj_klass, POLYLINE_PROP_SPLINE,
+ g_param_spec_boolean ("use-spline",
+ _("Use spline"),
+ _("Use a Bezier cubic spline as line"),
+ FALSE,
+ GSF_PARAM_STATIC | G_PARAM_READABLE));
+
+ item_klass->update_bounds = goc_polyline_update_bounds;
+ item_klass->distance = goc_polyline_distance;
+ item_klass->draw = goc_polyline_draw;
+}
+
+GSF_CLASS (GocPolyline, goc_polyline,
+ goc_polyline_class_init, NULL,
+ GOC_TYPE_STYLED_ITEM)
diff --git a/goffice/canvas/goc-polyline.h b/goffice/canvas/goc-polyline.h
new file mode 100644
index 0000000..0cf7fd9
--- /dev/null
+++ b/goffice/canvas/goc-polyline.h
@@ -0,0 +1,48 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * goc-polyline.h :
+ *
+ * Copyright (C) 2009 Jean Brefort (jean brefort normalesup 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_POLYLINE_H
+#define GOC_POLYLINE_H
+
+#include <goffice/goffice.h>
+
+G_BEGIN_DECLS
+
+typedef GocStyledItemClass GocPolylineClass;
+
+struct _GocPolyline {
+ GocStyledItem base;
+
+ GocPoint *points;
+ unsigned nb_points;
+ gboolean use_spline;
+};
+
+#define GOC_TYPE_POLYLINE (goc_polyline_get_type ())
+#define GOC_POLYLINE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOC_TYPE_POLYLINE, GocPolyline))
+#define GOC_IS_POLYLINE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOC_TYPE_POLYLINE))
+
+GType goc_polyline_get_type (void);
+
+G_END_DECLS
+
+#endif /* GOC_POLYLINE_H */
diff --git a/goffice/canvas/goc-rectangle.c b/goffice/canvas/goc-rectangle.c
index fce6d1f..0cd02e9 100644
--- a/goffice/canvas/goc-rectangle.c
+++ b/goffice/canvas/goc-rectangle.c
@@ -145,8 +145,6 @@ static void
goc_rectangle_draw (GocItem const *item, cairo_t *cr)
{
GocRectangle *rect = GOC_RECTANGLE (item);
- cairo_pattern_t *pat = NULL;
- GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (item));
cairo_save (cr);
goc_group_cairo_transform (item->parent, cr, rect->x, rect->y);
@@ -154,17 +152,10 @@ goc_rectangle_draw (GocItem const *item, cairo_t *cr)
cairo_rectangle (cr, 0., 0., rect->width, rect->height);
cairo_restore (cr);
/* Fill the shape */
- pat = go_style_create_cairo_pattern (style, cr);
- if (pat) {
- cairo_set_source (cr, pat);
- if (style->outline.dash_type != GO_LINE_NONE)
- cairo_fill_preserve (cr);
- else
- cairo_fill (cr);
- cairo_pattern_destroy (pat);
- }
+ if (go_styled_object_set_cairo_fill (GO_STYLED_OBJECT (item), cr))
+ cairo_fill_preserve (cr);
/* Draw the line */
- if (go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr))
+ if (goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr))
cairo_stroke (cr);
else
cairo_new_path (cr);
diff --git a/goffice/canvas/goc-styled-item.c b/goffice/canvas/goc-styled-item.c
index 8a7ac9e..e065af1 100644
--- a/goffice/canvas/goc-styled-item.c
+++ b/goffice/canvas/goc-styled-item.c
@@ -29,7 +29,8 @@
enum {
STYLED_ITEM_PROP_0,
- STYLED_ITEM_PROP_STYLE
+ STYLED_ITEM_PROP_STYLE,
+ STYLED_ITEM_SCALE_LINE_WIDTH
};
enum {
@@ -47,6 +48,7 @@ goc_styled_item_set_property (GObject *obj, guint param_id,
GValue const *value, GParamSpec *pspec)
{
GocStyledItem *gsi = GOC_STYLED_ITEM (obj);
+ GocItem *item = GOC_ITEM (obj);
gboolean resize = FALSE;
switch (param_id) {
@@ -59,7 +61,11 @@ goc_styled_item_set_property (GObject *obj, guint param_id,
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
return; /* NOTE : RETURN */
}
- goc_item_invalidate (GOC_ITEM (obj));
+ if (resize) {
+ goc_item_invalidate (item);
+ goc_item_bounds_changed (item);
+ }
+ goc_item_invalidate (item);
}
static void
@@ -133,12 +139,19 @@ goc_styled_item_class_init (GocItemClass *goc_klass)
_("A pointer to the GOStyle object"),
go_style_get_type (),
GSF_PARAM_STATIC | G_PARAM_READWRITE | GO_PARAM_PERSISTENT));
+ g_object_class_install_property (gobject_klass, STYLED_ITEM_SCALE_LINE_WIDTH,
+ g_param_spec_boolean ("scale-line-width",
+ _("Scale line width"),
+ _("Whether to scale the line width or not when zooming"),
+ TRUE,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE));
}
static void
goc_styled_item_init (GocStyledItem *gsi)
{
gsi->style = GO_STYLE (g_object_new (go_style_get_type (), NULL)); /* use the defaults */
+ gsi->scale_line_width = TRUE;
}
static gboolean
@@ -217,3 +230,22 @@ GSF_CLASS_FULL (GocStyledItem, goc_styled_item, NULL, NULL,
goc_styled_item_class_init, NULL, goc_styled_item_init,
GOC_TYPE_ITEM, 0,
GSF_INTERFACE (goc_styled_item_so_init, GO_TYPE_STYLED_OBJECT))
+
+gboolean
+goc_styled_item_set_cairo_line (GocStyledItem const *gsi, cairo_t *cr)
+{
+ double width = 0.;
+ gboolean result;
+ g_return_val_if_fail (GOC_IS_STYLED_ITEM (gsi), FALSE);
+
+ /* scale the line width */
+ if (gsi->scale_line_width) {
+ width = gsi->style->outline.width;
+ gsi->style->outline.width *= goc_canvas_get_pixels_per_unit (GOC_ITEM (gsi)->canvas);
+ }
+ result = go_styled_object_set_cairo_line (GO_STYLED_OBJECT (gsi), cr);
+ /* restore the line width */
+ if (gsi->scale_line_width)
+ gsi->style->outline.width = width;
+ return result;
+}
diff --git a/goffice/canvas/goc-styled-item.h b/goffice/canvas/goc-styled-item.h
index 45d4276..107ba88 100644
--- a/goffice/canvas/goc-styled-item.h
+++ b/goffice/canvas/goc-styled-item.h
@@ -31,6 +31,7 @@ struct _GocStyledItem {
GocItem base;
GOStyle *style;
+ gboolean scale_line_width;
};
typedef struct {
@@ -50,6 +51,8 @@ typedef struct {
GType goc_styled_item_get_type (void);
+gboolean goc_styled_item_set_cairo_line (GocStyledItem const *gsi, cairo_t *cr);
+
G_END_DECLS
#endif /* GOC_STYLED_ITEM_H */
diff --git a/goffice/canvas/goc-text.c b/goffice/canvas/goc-text.c
index 4708fdc..2c8742c 100644
--- a/goffice/canvas/goc-text.c
+++ b/goffice/canvas/goc-text.c
@@ -32,7 +32,11 @@ enum {
TEXT_PROP_ROTATION,
TEXT_PROP_ANCHOR,
TEXT_PROP_TEXT,
- TEXT_PROP_ATTRIBUTES
+ TEXT_PROP_ATTRIBUTES,
+ TEXT_PROP_CLIP,
+ TEXT_PROP_CLIP_WIDTH,
+ TEXT_PROP_CLIP_HEIGHT,
+ TEXT_PROP_WRAP_WIDTH
};
static GocItemClass *parent_class;
@@ -76,6 +80,30 @@ goc_text_set_property (GObject *gobject, guint param_id,
pango_layout_set_attributes (text->layout, text->attributes);
break;
}
+
+ case TEXT_PROP_CLIP:
+ text->clipped = g_value_get_boolean (value);
+ break;
+
+ case TEXT_PROP_CLIP_WIDTH:
+ text->clip_width = g_value_get_double (value);
+ break;
+
+ case TEXT_PROP_CLIP_HEIGHT:
+ text->clip_height = g_value_get_double (value);
+ break;
+
+ case TEXT_PROP_WRAP_WIDTH:
+ text->wrap_width = g_value_get_double (value);
+ if (text->layout) {
+ if (text->wrap_width > 0) {
+ pango_layout_set_width (text->layout, text->wrap_width * PANGO_SCALE);
+ pango_layout_set_wrap (text->layout, PANGO_WRAP_WORD);
+ } else
+ pango_layout_set_width (text->layout, -1);
+ }
+ break;
+
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
return; /* NOTE : RETURN */
}
@@ -116,6 +144,22 @@ goc_text_get_property (GObject *gobject, guint param_id,
g_value_set_boxed (value, text->attributes);
break;
+ case TEXT_PROP_CLIP:
+ g_value_set_boolean (value, text->clipped);
+ break;
+
+ case TEXT_PROP_CLIP_WIDTH:
+ break;
+ g_value_set_double (value, text->clip_width);
+
+ case TEXT_PROP_CLIP_HEIGHT:
+ g_value_set_double (value, text->clip_height);
+ break;
+
+ case TEXT_PROP_WRAP_WIDTH:
+ g_value_set_double (value, text->wrap_width);
+ break;
+
default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
return; /* NOTE : RETURN */
}
@@ -125,14 +169,22 @@ static void
goc_text_realize (GocItem *item)
{
GocText *text = GOC_TEXT (item);
+ GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (item));
if (parent_class->realize)
(*parent_class->realize) (item);
text->layout = pango_layout_new (gtk_widget_get_pango_context (GTK_WIDGET (item->canvas)));
- pango_layout_set_text (text->layout, text->text, -1);
+ pango_layout_set_font_description (text->layout, style->font.font->desc);
+ if (text->text)
+ pango_layout_set_text (text->layout, text->text, -1);
if (text->attributes)
pango_layout_set_attributes (text->layout, text->attributes);
+ if (text->wrap_width > 0) {
+ pango_layout_set_width (text->layout, text->wrap_width * PANGO_SCALE);
+ pango_layout_set_wrap (text->layout, PANGO_WRAP_WORD_CHAR);
+ } else
+ pango_layout_set_width (text->layout, -1);
goc_item_bounds_changed (item);
}
@@ -241,10 +293,17 @@ goc_text_draw (GocItem const *item, cairo_t *cr)
{
GocText *text = GOC_TEXT (item);
double x = text->x, y = text->y;
- PangoLayout *pl = pango_cairo_create_layout (cr);
+ PangoLayout *pl;
GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (item));
+ if (!text->text)
+ return;
+ pl = pango_cairo_create_layout (cr);
pango_layout_set_font_description (pl, style->font.font->desc);
pango_layout_set_text (pl, text->text, -1);
+ if (text->wrap_width > 0) {
+ pango_layout_set_width (pl, text->wrap_width * PANGO_SCALE);
+ pango_layout_set_wrap (pl, PANGO_WRAP_WORD_CHAR);
+ }
if (text->attributes)
pango_layout_set_attributes (pl, text->attributes);
/* FIXME: take rotation into account */
@@ -290,6 +349,10 @@ goc_text_draw (GocItem const *item, cairo_t *cr)
cairo_set_source_rgb (cr, 0., 0., 0.);
goc_group_cairo_transform (item->parent, cr, x, y);
cairo_move_to (cr, 0., 0.);
+ if (text->clip_height > 0. && text->clip_width > 0.) {
+ cairo_rectangle (cr, 0., 0., text->clip_width, text->clip_height);
+ cairo_clip (cr);
+ }
pango_cairo_show_layout (cr, pl);
cairo_restore (cr);
g_object_unref (pl);
@@ -304,9 +367,20 @@ goc_text_init_style (G_GNUC_UNUSED GocStyledItem *item, GOStyle *style)
}
static void
+goc_text_style_changed (GOStyledObject *obj)
+{
+ GOStyle *style = go_styled_object_get_style (obj);
+ GocText *text = GOC_TEXT (obj);
+ if (text->layout)
+ pango_layout_set_font_description (text->layout, style->font.font->desc);
+ goc_item_bounds_changed (GOC_ITEM (obj));
+}
+
+static void
goc_text_class_init (GocItemClass *item_klass)
{
GObjectClass *obj_klass = (GObjectClass *) item_klass;
+ GOStyledObjectClass *gso_klass = (GOStyledObjectClass *) item_klass;
GocStyledItemClass *gsi_klass = (GocStyledItemClass *) item_klass;
parent_class = g_type_class_peek_parent (item_klass);
@@ -346,8 +420,33 @@ goc_text_class_init (GocItemClass *item_klass)
g_param_spec_boxed ("attributes", _("Attributes"), _("The attributes list as a PangoAttrList"),
PANGO_TYPE_ATTR_LIST,
GSF_PARAM_STATIC | G_PARAM_READWRITE));
+ g_object_class_install_property (obj_klass, TEXT_PROP_CLIP,
+ g_param_spec_boolean ("clip",
+ _("Clip"),
+ _("Whether to clip or not"),
+ FALSE,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE));
+ g_object_class_install_property (obj_klass, TEXT_PROP_CLIP_WIDTH,
+ g_param_spec_double ("clip-width",
+ _("Clip width"),
+ _("Clip width for the text"),
+ 0., G_MAXDOUBLE, 0.,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE));
+ g_object_class_install_property (obj_klass, TEXT_PROP_CLIP_HEIGHT,
+ g_param_spec_double ("clip-height",
+ _("Clip height"),
+ _("Clip height for the text"),
+ 0., G_MAXDOUBLE, 0.,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE));
+ g_object_class_install_property (obj_klass, TEXT_PROP_WRAP_WIDTH,
+ g_param_spec_double ("wrap-width",
+ _("Wrap width"),
+ _("Wrap width for the text"),
+ 0., G_MAXDOUBLE, 0.,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE));
gsi_klass->init_style = goc_text_init_style;
+ gso_klass->style_changed = goc_text_style_changed;
item_klass->update_bounds = goc_text_update_bounds;
item_klass->distance = goc_text_distance;
diff --git a/goffice/canvas/goc-text.h b/goffice/canvas/goc-text.h
index c15a87c..4d25685 100644
--- a/goffice/canvas/goc-text.h
+++ b/goffice/canvas/goc-text.h
@@ -32,6 +32,8 @@ struct _GocText {
double rotation; /* rotation around the center in radians */
double x, y, w, h;
+ gboolean clipped;
+ double clip_width, clip_height, wrap_width;
char *text;
GtkAnchorType anchor;
PangoAttrList *attributes;
diff --git a/goffice/canvas/goc-widget.c b/goffice/canvas/goc-widget.c
index 7c1da33..3ceb3d3 100644
--- a/goffice/canvas/goc-widget.c
+++ b/goffice/canvas/goc-widget.c
@@ -27,6 +27,27 @@
#include <math.h>
+static gboolean
+enter_notify_cb (G_GNUC_UNUSED GtkWidget *w, GdkEventCrossing *event, GocWidget *item)
+{
+ item->base.canvas->cur_event = (GdkEvent *) event;
+ return GOC_ITEM_GET_CLASS (item->base.parent)->enter_notify (GOC_ITEM (item->base.parent),
+ (event->x + item->x) / item->base.canvas->pixels_per_unit + item->base.canvas->scroll_x1,
+ (event->y + item->y) / item->base.canvas->pixels_per_unit + item->base.canvas->scroll_y1);
+}
+
+static gboolean
+button_press_cb (G_GNUC_UNUSED GtkWidget *w, GdkEventButton *event, GocWidget *item)
+{
+ item->base.canvas->cur_event = (GdkEvent *) event;
+ if (event->button != 3)
+ return FALSE;
+ return GOC_ITEM_GET_CLASS (item->base.parent)->button_pressed (GOC_ITEM (item->base.parent),
+ event->button,
+ (event->x + item->x) / item->base.canvas->pixels_per_unit + item->base.canvas->scroll_x1,
+ (event->y + item->y) / item->base.canvas->pixels_per_unit + item->base.canvas->scroll_y1);
+}
+
enum {
WIDGET_PROP_0,
WIDGET_PROP_WIDGET,
@@ -89,6 +110,9 @@ goc_widget_set_property (GObject *obj, guint param_id,
gtk_widget_show (widget);
gtk_layout_put (GTK_LAYOUT (GOC_ITEM (item)->canvas), widget, item->x, item->y);
goc_widget_notify_scrolled (GOC_ITEM (item));
+ /* we need to propagate some signals to the parent item */
+ g_signal_connect (widget, "enter-notify-event", G_CALLBACK (enter_notify_cb), obj);
+ g_signal_connect (widget, "button-press-event", G_CALLBACK (button_press_cb), obj);
return;
}
case WIDGET_PROP_X:
diff --git a/goffice/canvas/goffice-canvas.h b/goffice/canvas/goffice-canvas.h
index ca00fbf..6e9c089 100644
--- a/goffice/canvas/goffice-canvas.h
+++ b/goffice/canvas/goffice-canvas.h
@@ -33,6 +33,7 @@ typedef struct _GocItem GocItem;
typedef struct _GocGroup GocGroup;
typedef struct _GocLine GocLine;
typedef struct _GocPixbuf GocPixbuf;
+typedef struct _GocPolyline GocPolyline;
typedef struct _GocPolygon GocPolygon;
typedef struct _GocRectangle GocRectangle;
typedef struct _GocCircle GocCircle;
@@ -58,6 +59,7 @@ G_END_DECLS
#include <goffice/canvas/goc-group.h>
#include <goffice/canvas/goc-line.h>
#include <goffice/canvas/goc-pixbuf.h>
+#include <goffice/canvas/goc-polyline.h>
#include <goffice/canvas/goc-polygon.h>
#include <goffice/canvas/goc-rectangle.h>
#include <goffice/canvas/goc-text.h>
diff --git a/goffice/graph/gog-equation.c b/goffice/graph/gog-equation.c
index 38b227d..d1e4802 100644
--- a/goffice/graph/gog-equation.c
+++ b/goffice/graph/gog-equation.c
@@ -211,7 +211,7 @@ gog_equation_update (GogObject *obj)
else
itex = g_string_append (itex, "$$");
- mathml = lsm_mathml_document_new_from_itex (itex->str);
+ mathml = lsm_mathml_document_new_from_itex (itex->str, itex->len, NULL);
/* Keep the last valid mathml document if the itex -> mathml conversion fails.
* It keep the equation from disappearing when the current equation entry is not a
diff --git a/po/ChangeLog b/po/ChangeLog
index fd0c2d4..9f95b8a 100644
--- a/po/ChangeLog
+++ b/po/ChangeLog
@@ -1,3 +1,7 @@
+2009-08-19 Jean Brefort <jean brefort normalesup org>
+
+ * POTFILES.in: updated file list.
+
2009-08-15 Morten Welinder <terra gnome org>
* Release 0.7.9
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9f3150f..914f39f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -43,6 +43,7 @@ goffice/canvas/goc-graph.c
goffice/canvas/goc-group.c
goffice/canvas/goc-line.c
goffice/canvas/goc-pixbuf.c
+goffice/canvas/goc-polyline.c
goffice/canvas/goc-polygon.c
goffice/canvas/goc-rectangle.c
goffice/canvas/goc-styled-item.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]