[goffice] cleaned code and implement arrow head.



commit 44cb1fc1ab5ea09797015a461d6a6403a327a667
Author: Jean Brefort <jean brefort normalesup org>
Date:   Tue Aug 25 10:55:46 2009 +0200

    cleaned code and implement arrow head.

 ChangeLog                   |    8 +++++
 goffice/canvas/goc-canvas.c |   46 +++++++++++++------------------
 goffice/canvas/goc-canvas.h |    8 ++---
 goffice/canvas/goc-graph.c  |    2 +-
 goffice/canvas/goc-group.c  |    2 +-
 goffice/canvas/goc-line.c   |   64 ++++++++++++++++++++++++++++++++-----------
 6 files changed, 80 insertions(+), 50 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 7337547..b667b22 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2009-08-25  Jean Brefort  <jean brefort normalesup org>
+
+	* goffice/canvas/goc-canvas.c: cleaned things.
+	* goffice/canvas/goc-canvas.h: ditto.
+	* goffice/canvas/goc-graph.c: ditto.
+	* goffice/canvas/goc-group.c: ditto.
+	* goffice/canvas/goc-line.c: implement arrow head.
+
 2009-08-23  Morten Welinder  <terra gnome org>
 
 	* goffice/utils/go-color.h (PIXEL_*): Kill unused macros.
diff --git a/goffice/canvas/goc-canvas.c b/goffice/canvas/goc-canvas.c
index ed223e1..82c2142 100644
--- a/goffice/canvas/goc-canvas.c
+++ b/goffice/canvas/goc-canvas.c
@@ -41,8 +41,8 @@ expose_cb (GocCanvas *canvas, GdkEventExpose *event, G_GNUC_UNUSED gpointer data
 		return TRUE;
 	goc_item_get_bounds (GOC_ITEM (canvas->root),&x0, &y0, &x1, &y1);
 	if (canvas->direction == GOC_DIRECTION_RTL) {
-		ax1 = (double)  (canvas->wwidth - event->area.x) / canvas->pixels_per_unit + canvas->scroll_x1;
-		ax0 = (double) (canvas->wwidth - event->area.x - event->area.width) / canvas->pixels_per_unit + canvas->scroll_x1;
+		ax1 = (double)  (canvas->width - event->area.x) / canvas->pixels_per_unit + canvas->scroll_x1;
+		ax0 = (double) (canvas->width - event->area.x - event->area.width) / canvas->pixels_per_unit + canvas->scroll_x1;
 	} else {
 		ax0 = (double) event->area.x / canvas->pixels_per_unit + canvas->scroll_x1;
 		ax1 = ((double) event->area.x + event->area.width) / canvas->pixels_per_unit + canvas->scroll_x1;
@@ -68,7 +68,7 @@ button_press_cb (GocCanvas *canvas, GdkEventButton *event, G_GNUC_UNUSED gpointe
 	if (event->window != gtk_layout_get_bin_window (&canvas->base))
 		return TRUE;
 	x = (canvas->direction == GOC_DIRECTION_RTL)?
-		canvas->scroll_x1 +  (canvas->wwidth - event->x) / canvas->pixels_per_unit:
+		canvas->scroll_x1 +  (canvas->width - event->x) / canvas->pixels_per_unit:
 		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);;	
@@ -91,7 +91,7 @@ button_release_cb (GocCanvas *canvas, GdkEventButton *event, G_GNUC_UNUSED gpoin
 	if (event->window != gtk_layout_get_bin_window (&canvas->base))
 		return TRUE;
 	x = (canvas->direction == GOC_DIRECTION_RTL)?
-		canvas->scroll_x1 +  (canvas->wwidth - event->x) / canvas->pixels_per_unit:
+		canvas->scroll_x1 +  (canvas->width - event->x) / canvas->pixels_per_unit:
 		canvas->scroll_x1 +  event->x / canvas->pixels_per_unit;
 	y = canvas->scroll_y1 + event->y / canvas->pixels_per_unit;
 	item = (canvas->grabbed_item != NULL)?
@@ -115,7 +115,7 @@ motion_cb (GocCanvas *canvas, GdkEventMotion *event, G_GNUC_UNUSED gpointer data
 		return TRUE;
 
 	x = (canvas->direction == GOC_DIRECTION_RTL)?
-		canvas->scroll_x1 +  (canvas->wwidth - event->x) / canvas->pixels_per_unit:
+		canvas->scroll_x1 +  (canvas->width - event->x) / canvas->pixels_per_unit:
 		canvas->scroll_x1 +  event->x / canvas->pixels_per_unit;
 	y = canvas->scroll_y1 + event->y / canvas->pixels_per_unit;
 	if (canvas->grabbed_item != NULL) 
@@ -165,7 +165,7 @@ enter_notify_cb (GocCanvas *canvas, GdkEventCrossing* event, G_GNUC_UNUSED gpoin
 	if (event->window != gtk_layout_get_bin_window (&canvas->base))
 		return TRUE;
 	x = (canvas->direction == GOC_DIRECTION_RTL)?
-		canvas->scroll_x1 +  (canvas->wwidth - event->x) / canvas->pixels_per_unit:
+		canvas->scroll_x1 +  (canvas->width - event->x) / canvas->pixels_per_unit:
 		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);;	
@@ -184,7 +184,7 @@ leave_notify_cb (GocCanvas *canvas, GdkEventCrossing* event, G_GNUC_UNUSED gpoin
 	if (event->window != gtk_layout_get_bin_window (&canvas->base))
 		return TRUE;
 	x = (canvas->direction == GOC_DIRECTION_RTL)?
-		canvas->scroll_x1 +  (canvas->wwidth - event->x) / canvas->pixels_per_unit:
+		canvas->scroll_x1 +  (canvas->width - event->x) / canvas->pixels_per_unit:
 		canvas->scroll_x1 +  event->x / canvas->pixels_per_unit;
 	y = canvas->scroll_y1 + event->y / canvas->pixels_per_unit;
 	if (canvas->last_item) {
@@ -198,8 +198,8 @@ leave_notify_cb (GocCanvas *canvas, GdkEventCrossing* event, G_GNUC_UNUSED gpoin
 static void
 size_changed_cb (GocCanvas *canvas, GtkAllocation *alloc, G_GNUC_UNUSED gpointer data)
 {
-	canvas->wwidth = alloc->width;
-	canvas->wheight = alloc->height;
+	canvas->width = alloc->width;
+	canvas->height = alloc->height;
 }
 
 static void
@@ -274,22 +274,14 @@ goc_canvas_get_root (GocCanvas *canvas)
 	return canvas->root;
 }
 
-void
-goc_canvas_set_scroll_region (GocCanvas *canvas, double width, double height)
-{
-	g_return_if_fail (GOC_IS_CANVAS (canvas));
-	canvas->width = width;
-	canvas->height = height;
-}
-
-double
+int
 goc_canvas_get_width (GocCanvas *canvas)
 {
 	g_return_val_if_fail (GOC_IS_CANVAS (canvas), 0);
 	return canvas->width;
 }
 
-double
+int
 goc_canvas_get_height (GocCanvas *canvas)
 {
 	g_return_val_if_fail (GOC_IS_CANVAS (canvas), 0);
@@ -355,14 +347,14 @@ goc_canvas_invalidate (GocCanvas *canvas, double x0, double y0, double x1, doubl
 		x0 = 0;
 	if (y0 < 0)
 		y0 = 0;
-	if (x1 > canvas->wwidth)
-		x1 = canvas->wwidth;
-	if (y1 > canvas->wheight)
-		y1 = canvas->wheight;
+	if (x1 > canvas->width)
+		x1 = canvas->width;
+	if (y1 > canvas->height)
+		y1 = canvas->height;
 	if (canvas->direction == GOC_DIRECTION_RTL) {
 		double tmp = x0;
-		x0 = canvas->wwidth - x1;
-		x1 = canvas->wwidth - tmp;
+		x0 = canvas->width - x1;
+		x1 = canvas->width - tmp;
 	}
 	if (x1 > x0 && y1 > y0)
 		gtk_widget_queue_draw_area (GTK_WIDGET (canvas),
@@ -440,7 +432,7 @@ goc_canvas_w2c (GocCanvas *canvas, int x, int y, double *x_, double *y_)
 {
 	if (x_) {
 		if (canvas->direction == GOC_DIRECTION_RTL)
-			*x_ = (double)  (canvas->wwidth - x) / canvas->pixels_per_unit + canvas->scroll_x1;
+			*x_ = (double)  (canvas->width - x) / canvas->pixels_per_unit + canvas->scroll_x1;
 		else
 			*x_ = (double) x / canvas->pixels_per_unit + canvas->scroll_x1;
 	}
@@ -453,7 +445,7 @@ goc_canvas_c2w (GocCanvas *canvas, double x, double y, int *x_, int *y_)
 {
 	if (x_) {
 		if (canvas->direction == GOC_DIRECTION_RTL)
-			*x_ = canvas->wwidth - (x - canvas->scroll_x1) * canvas->pixels_per_unit;
+			*x_ = canvas->width - (x - canvas->scroll_x1) * canvas->pixels_per_unit;
 		else
 			*x_ = (x - canvas->scroll_x1) * canvas->pixels_per_unit;
 	}
diff --git a/goffice/canvas/goc-canvas.h b/goffice/canvas/goc-canvas.h
index 31e74d4..84ac411 100644
--- a/goffice/canvas/goc-canvas.h
+++ b/goffice/canvas/goc-canvas.h
@@ -38,8 +38,7 @@ struct _GocCanvas {
 	GtkLayout base;
 	double scroll_x1, scroll_y1;
 	double pixels_per_unit;
-	double width, height;
-	int wwidth, wheight;
+	int width, height;
 	GocGroup *root;
 	GocItem *grabbed_item;
 	GocItem	*last_item;
@@ -57,9 +56,8 @@ typedef GtkLayoutClass GocCanvasClass;
 GType goc_canvas_get_type (void);
 
 GocGroup	*goc_canvas_get_root (GocCanvas *canvas);
-void		 goc_canvas_set_scroll_region (GocCanvas *canvas, double width, double height);
-double		 goc_canvas_get_width (GocCanvas *canvas);
-double		 goc_canvas_get_height (GocCanvas *canvas);
+int		 goc_canvas_get_width (GocCanvas *canvas);
+int		 goc_canvas_get_height (GocCanvas *canvas);
 void		 goc_canvas_scroll_to (GocCanvas *canvas, double x, double y);
 void		 goc_canvas_get_scroll_position (GocCanvas *canvas, double *x, double *y);
 void		 goc_canvas_set_pixels_per_unit (GocCanvas *canvas, double pixels_per_unit);
diff --git a/goffice/canvas/goc-graph.c b/goffice/canvas/goc-graph.c
index f2bcb04..fec97f4 100644
--- a/goffice/canvas/goc-graph.c
+++ b/goffice/canvas/goc-graph.c
@@ -181,7 +181,7 @@ goc_graph_draw (GocItem const *item, cairo_t *cr)
 	if (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL) {
 		x0 = item->x1;
 		goc_group_adjust_coords (item->parent, &x0, &y0);
-		x0 = canvas->wwidth - (int) (x0 - canvas->scroll_x1) * canvas->pixels_per_unit;
+		x0 = canvas->width - (int) (x0 - canvas->scroll_x1) * canvas->pixels_per_unit;
 	} else {
 		x0 = item->x0;
 		goc_group_adjust_coords (item->parent, &x0, &y0);
diff --git a/goffice/canvas/goc-group.c b/goffice/canvas/goc-group.c
index a678930..85fb7c9 100644
--- a/goffice/canvas/goc-group.c
+++ b/goffice/canvas/goc-group.c
@@ -334,7 +334,7 @@ void goc_group_cairo_transform (GocGroup const *group, cairo_t *cr, double x, do
 		GocCanvas *canvas = GOC_ITEM (group)->canvas;
 		cairo_scale (cr, canvas->pixels_per_unit, canvas->pixels_per_unit);
 		if (canvas->direction == GOC_DIRECTION_RTL)
-			cairo_translate (cr, canvas->wwidth / canvas->pixels_per_unit - (x - canvas->scroll_x1), y - canvas->scroll_y1);
+			cairo_translate (cr, canvas->width / canvas->pixels_per_unit - (x - canvas->scroll_x1), y - canvas->scroll_y1);
 		else
 			cairo_translate (cr, x - canvas->scroll_x1, y - canvas->scroll_y1);
 	}
diff --git a/goffice/canvas/goc-line.c b/goffice/canvas/goc-line.c
index d32b71e..eab5a05 100644
--- a/goffice/canvas/goc-line.c
+++ b/goffice/canvas/goc-line.c
@@ -69,11 +69,11 @@ goc_line_set_property (GObject *gobject, guint param_id,
 		break;
 
 	case LINE_PROP_ARROW_SHAPE_B:
-		line->headA = g_value_get_double (value);
+		line->headB = g_value_get_double (value);
 		break;
 
 	case LINE_PROP_ARROW_SHAPE_C:
-		line->headA = g_value_get_double (value);
+		line->headC = g_value_get_double (value);
 		break;
 
 	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
@@ -131,9 +131,8 @@ goc_line_update_bounds (GocItem *item)
 {
 	GocLine *line = GOC_LINE (item);
 	GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (item));
-	/* FIXME: take rotation into account */
 	double extra_width = style->line.width /2.;
-	/* fix me, take ends and orientation into account */
+	/* fix me, take arrow head into account */
 	if (extra_width <= 0.)
 		extra_width = .5;
 	if (line->startx < line->endx) {
@@ -150,6 +149,13 @@ goc_line_update_bounds (GocItem *item)
 		item->y0 = line->endy - extra_width;
 		item->y1 = line->starty + extra_width;
 	}
+	if (line->arrowhead) {
+		/* do not calculate things precisely, just add headC in all directions */
+		item->x0 -= line->headC;
+		item->x1 += line->headC;
+		item->y0 -= line->headC;
+		item->y1 += line->headC;
+	}
 }
 
 static double
@@ -173,6 +179,7 @@ goc_line_distance (GocItem *item, double x, double y, GocItem **near_item)
 		return hypot (t - l, y);
 	style = go_styled_object_get_style (GO_STYLED_OBJECT (item));
 	t = y - style->line.width / 2.;
+	/* FIXME: do we need to take the arrow end into account? */
 	return (t > 0.)? t: 0.;
 }
 
@@ -180,22 +187,47 @@ static void goc_line_draw (GocItem const *item, cairo_t *cr)
 {
 	GocLine *line = GOC_LINE (item);
 	double sign = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1: 1;
-        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.;
+	double endx = (line->endx - line->startx) * sign, endy = line->endy - line->starty;
+	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, hoffs + (int) line->startx, voffs + (int) line->starty);
+	if (line->arrowhead) {
+		GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (item));
+		double l = hypot (endx, endy), w = (style->line.width)? style->line.width / 2.: .5;
+		/* display the arrow head */
 		cairo_save (cr);
-		goc_group_cairo_transform (item->parent, cr, hoffs + (int) line->startx, voffs + (int) line->starty);
+		cairo_translate (cr, (int) endx, (int) endy);
+		cairo_rotate (cr, atan2 (endy, endx));
+		cairo_move_to (cr, -line->headA, w);
+		cairo_line_to (cr, -line->headB, w + line->headC);
+		cairo_line_to (cr, 0., 0.);
+		cairo_line_to (cr, -line->headB, -w - line->headC);
+		cairo_line_to (cr, -line->headA, -w);
+		cairo_close_path (cr);
+		cairo_set_source_rgba (cr, GO_COLOR_TO_CAIRO (style->line.color));
+		cairo_fill (cr);
+		cairo_restore (cr);
+		if (l > 0.) {
+			endx -= line->headA * endx / l;
+			endy -= line->headA * endy / l;
+		} else
+			endx = endy = 0.;
+	}
+        if ((endx != 0. || endy!= 0.) && go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr)) {
+		/* try to avoid horizontal and vertical lines between two pixels */
 		cairo_move_to (cr, 0., 0.);
-		cairo_line_to (cr, (int) (line->endx - line->startx) * sign, (int) (line->endy - line->starty));
+		endx = (endx > 0.)? ceil (endx): floor (endx);
+		endy = (endy > 0.)? ceil (endy): floor (endy);
+		cairo_line_to (cr, endx, endy);
 		cairo_stroke (cr);
-		cairo_restore (cr);
 	}
+	cairo_restore (cr);
 }
 
 static void



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