[goffice] add RTL support to the canvas



commit de8ac6ffe16e25e3f7484f4de54fc3a4a638fbe0
Author: Jean Brefort <jean brefort normalesup org>
Date:   Sun Aug 23 16:54:39 2009 +0200

    add RTL support to  the canvas

 ChangeLog                      |   15 ++++++++
 goffice/canvas/goc-canvas.c    |   76 ++++++++++++++++++++++++++++++++++++----
 goffice/canvas/goc-canvas.h    |   11 ++++++
 goffice/canvas/goc-ellipse.c   |    4 +-
 goffice/canvas/goc-graph.c     |   15 ++++++--
 goffice/canvas/goc-group.c     |    5 ++-
 goffice/canvas/goc-line.c      |   65 +++++++++++++++++++++++++++++++++-
 goffice/canvas/goc-line.h      |    2 +
 goffice/canvas/goc-pixbuf.c    |   15 +++++---
 goffice/canvas/goc-polygon.c   |    3 +-
 goffice/canvas/goc-polyline.c  |    3 +-
 goffice/canvas/goc-rectangle.c |   12 +++++--
 goffice/canvas/goc-text.c      |    2 +-
 13 files changed, 200 insertions(+), 28 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index ebfaeba..3e079f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2009-08-23  Jean Brefort  <jean brefort normalesup org>
+
+	* goffice/canvas/goc-canvas.c: add RTL support tothe canvas.
+	* goffice/canvas/goc-canvas.h: ditto.
+	* goffice/canvas/goc-ellipse.c: ditto.
+	* goffice/canvas/goc-graph.c: ditto.
+	* goffice/canvas/goc-group.c: ditto.
+	* goffice/canvas/goc-line.c: ditto.
+	* goffice/canvas/goc-line.h: ditto.
+	* goffice/canvas/goc-pixbuf.c: ditto.
+	* goffice/canvas/goc-polygon.c: ditto.
+	* goffice/canvas/goc-polyline.c: ditto.
+	* goffice/canvas/goc-rectangle.c: ditto.
+	* goffice/canvas/goc-text.c: ditto.
+
 2009-08-19  Jean Brefort  <jean brefort normalesup org>
 
 	* configure.in: test for gtk_layout_get_bin_window.
diff --git a/goffice/canvas/goc-canvas.c b/goffice/canvas/goc-canvas.c
index 084f8de..ed223e1 100644
--- a/goffice/canvas/goc-canvas.c
+++ b/goffice/canvas/goc-canvas.c
@@ -40,9 +40,14 @@ expose_cb (GocCanvas *canvas, GdkEventExpose *event, G_GNUC_UNUSED gpointer data
        if (event->count)
 		return TRUE;
 	goc_item_get_bounds (GOC_ITEM (canvas->root),&x0, &y0, &x1, &y1);
-	ax0 = (double) event->area.x / canvas->pixels_per_unit + canvas->scroll_x1;
+	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;
+	} 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;
+	}
 	ay0 = (double) event->area.y / canvas->pixels_per_unit + canvas->scroll_y1;
-	ax1 = ((double) event->area.x + event->area.width) / canvas->pixels_per_unit + canvas->scroll_x1;
 	ay1 = ((double) event->area.y + event->area.height) / canvas->pixels_per_unit + canvas->scroll_y1;
 	if (x0 <= ax1 && x1 >= ax0 && y0 <= ay1 && y1 >= ay0) {
 		cairo_t *cr = gdk_cairo_create (event->window);
@@ -62,7 +67,9 @@ 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->scroll_x1 +  event->x / canvas->pixels_per_unit;
+	x = (canvas->direction == GOC_DIRECTION_RTL)?
+		canvas->scroll_x1 +  (canvas->wwidth - 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);;	
 	if (item) {
@@ -83,7 +90,9 @@ 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->scroll_x1 +  event->x / canvas->pixels_per_unit;
+	x = (canvas->direction == GOC_DIRECTION_RTL)?
+		canvas->scroll_x1 +  (canvas->wwidth - 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)?
 		canvas->grabbed_item:
@@ -104,7 +113,10 @@ motion_cb (GocCanvas *canvas, GdkEventMotion *event, G_GNUC_UNUSED gpointer data
 
 	if (event->window != gtk_layout_get_bin_window (&canvas->base))
 		return TRUE;
-	x = canvas->scroll_x1 +  event->x / canvas->pixels_per_unit;
+
+	x = (canvas->direction == GOC_DIRECTION_RTL)?
+		canvas->scroll_x1 +  (canvas->wwidth - 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) 
 		item = canvas->grabbed_item;
@@ -152,7 +164,9 @@ 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->scroll_x1 +  event->x / canvas->pixels_per_unit;
+	x = (canvas->direction == GOC_DIRECTION_RTL)?
+		canvas->scroll_x1 +  (canvas->wwidth - 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);;	
 	if (item) {
@@ -169,7 +183,9 @@ 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->scroll_x1 +  event->x / canvas->pixels_per_unit;
+	x = (canvas->direction == GOC_DIRECTION_RTL)?
+		canvas->scroll_x1 +  (canvas->wwidth - 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) {
 		gboolean result = GOC_ITEM_GET_CLASS (canvas->last_item)->leave_notify (canvas->last_item, x, y);
@@ -343,6 +359,11 @@ goc_canvas_invalidate (GocCanvas *canvas, double x0, double y0, double x1, doubl
 		x1 = canvas->wwidth;
 	if (y1 > canvas->wheight)
 		y1 = canvas->wheight;
+	if (canvas->direction == GOC_DIRECTION_RTL) {
+		double tmp = x0;
+		x0 = canvas->wwidth - x1;
+		x1 = canvas->wwidth - tmp;
+	}
 	if (x1 > x0 && y1 > y0)
 		gtk_widget_queue_draw_area (GTK_WIDGET (canvas),
 					    (int) floor (x0), (int) floor (y0),
@@ -398,3 +419,44 @@ goc_canvas_get_cur_event (GocCanvas *canvas)
 	g_return_val_if_fail (GOC_IS_CANVAS (canvas), NULL);
 	return canvas->cur_event;
 }
+
+void
+goc_canvas_set_direction (GocCanvas *canvas, GocDirection direction)
+{
+	g_return_if_fail (GOC_IS_CANVAS (canvas) && direction < GOC_DIRECTION_MAX);
+	canvas->direction = direction;
+	goc_canvas_invalidate (canvas, -G_MAXDOUBLE, -G_MAXDOUBLE, G_MAXDOUBLE, G_MAXDOUBLE);
+}
+
+GocDirection
+goc_canvas_get_direction (GocCanvas *canvas)
+{
+	g_return_val_if_fail (GOC_IS_CANVAS (canvas), GOC_DIRECTION_MAX);
+	return canvas->direction;
+}
+
+void
+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;
+		else
+			*x_ = (double) x / canvas->pixels_per_unit + canvas->scroll_x1;
+	}
+	if (y_)
+		*y_ = (double) y / canvas->pixels_per_unit + canvas->scroll_y1;
+}
+
+void
+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;
+		else
+			*x_ = (x - canvas->scroll_x1) * canvas->pixels_per_unit;
+	}
+	if (y_)
+		*y_ = (y - canvas->scroll_y1) * canvas->pixels_per_unit;
+}
diff --git a/goffice/canvas/goc-canvas.h b/goffice/canvas/goc-canvas.h
index c9143b5..31e74d4 100644
--- a/goffice/canvas/goc-canvas.h
+++ b/goffice/canvas/goc-canvas.h
@@ -28,6 +28,12 @@
 
 G_BEGIN_DECLS
 
+typedef enum {
+	GOC_DIRECTION_LTR,
+	GOC_DIRECTION_RTL,
+	GOC_DIRECTION_MAX
+} GocDirection;
+
 struct _GocCanvas {
 	GtkLayout base;
 	double scroll_x1, scroll_y1;
@@ -39,6 +45,7 @@ struct _GocCanvas {
 	GocItem	*last_item;
 	GODoc *document;
 	GdkEvent *cur_event;
+	GocDirection direction;
 };
 
 typedef GtkLayoutClass GocCanvasClass;
@@ -65,6 +72,10 @@ GocItem		*goc_canvas_get_grabbed_item (GocCanvas *canvas);
 void		 goc_canvas_set_document (GocCanvas *canvas, GODoc *document);
 GODoc		*goc_canvas_get_document (GocCanvas *canvas);
 GdkEvent	*goc_canvas_get_cur_event (GocCanvas *canvas);
+void		 goc_canvas_set_direction (GocCanvas *canvas, GocDirection direction);
+GocDirection     goc_canvas_get_direction (GocCanvas *canvas);
+void		 goc_canvas_w2c (GocCanvas *canvas, int x, int y, double *x_, double *y_);
+void		 goc_canvas_c2w (GocCanvas *canvas, double x, double y, int *x_, int *y_);
 G_END_DECLS
 
 #endif  /* GOC_CANVAS_H */
diff --git a/goffice/canvas/goc-ellipse.c b/goffice/canvas/goc-ellipse.c
index 5e47601..43e9aba 100644
--- a/goffice/canvas/goc-ellipse.c
+++ b/goffice/canvas/goc-ellipse.c
@@ -168,10 +168,10 @@ goc_ellipse_draw (GocItem const *item, cairo_t *cr)
 	GocEllipse *ellipse = GOC_ELLIPSE (item);
 	double  scalex = (ellipse->width > 0.)? ellipse->width / 2.: 1.e-10,
 		scaley = (ellipse->height > 0.)? ellipse->height / 2.: 1.e-10;
-	    
+	double sign = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1.: 1.;
 	cairo_save (cr);
 	goc_group_cairo_transform (item->parent, cr, ellipse->x, ellipse->y);
-	cairo_translate (cr, ellipse->width / 2., ellipse->height / 2.);
+	cairo_translate (cr, scalex * sign, scaley);
 	cairo_scale (cr, scalex, scaley);
 	cairo_rotate (cr, ellipse->rotation);
 	cairo_arc (cr, 0., 0., 1., 0., 2 * M_PI);
diff --git a/goffice/canvas/goc-graph.c b/goffice/canvas/goc-graph.c
index 3995abb..f2bcb04 100644
--- a/goffice/canvas/goc-graph.c
+++ b/goffice/canvas/goc-graph.c
@@ -175,13 +175,20 @@ goc_graph_draw (GocItem const *item, cairo_t *cr)
 	GocGraph *graph = GOC_GRAPH (item);
 	GocCanvas *canvas = item->canvas;
 	cairo_surface_t *surf;
-	double x0 = item->x0, y0 = item->y0;
+	double x0, y0 = item->y0;
 	if (graph->renderer == NULL)
 		return;
-	goc_group_adjust_coords (item->parent, &x0, &y0);
+	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;
+	} else {
+		x0 = item->x0;
+		goc_group_adjust_coords (item->parent, &x0, &y0);
+		x0 = (int) (x0 - canvas->scroll_x1) * canvas->pixels_per_unit;
+	}
 	cairo_save (cr);
-	cairo_translate (cr,
-	                 (int) (x0 - canvas->scroll_x1) * canvas->pixels_per_unit,
+	cairo_translate (cr, x0,
 	                 (int) (y0 - canvas->scroll_y1) * canvas->pixels_per_unit);
 	/* scaling only there gives a better rendering, and allows for caching */
 	gog_renderer_update (graph->renderer,
diff --git a/goffice/canvas/goc-group.c b/goffice/canvas/goc-group.c
index d917bff..a678930 100644
--- a/goffice/canvas/goc-group.c
+++ b/goffice/canvas/goc-group.c
@@ -333,6 +333,9 @@ void goc_group_cairo_transform (GocGroup const *group, cairo_t *cr, double x, do
 	else {
 		GocCanvas *canvas = GOC_ITEM (group)->canvas;
 		cairo_scale (cr, canvas->pixels_per_unit, canvas->pixels_per_unit);
-		cairo_translate (cr, x - canvas->scroll_x1, y - canvas->scroll_y1);
+		if (canvas->direction == GOC_DIRECTION_RTL)
+			cairo_translate (cr, canvas->wwidth / 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 2048f0d..d32b71e 100644
--- a/goffice/canvas/goc-line.c
+++ b/goffice/canvas/goc-line.c
@@ -30,7 +30,11 @@ enum {
 	LINE_PROP_X0,
 	LINE_PROP_Y0,
 	LINE_PROP_X1,
-	LINE_PROP_Y1
+	LINE_PROP_Y1,
+	LINE_PROP_ARROWHEAD,
+	LINE_PROP_ARROW_SHAPE_A,
+	LINE_PROP_ARROW_SHAPE_B,
+	LINE_PROP_ARROW_SHAPE_C
 };
 
 static void
@@ -56,6 +60,22 @@ goc_line_set_property (GObject *gobject, guint param_id,
 		line->endy = g_value_get_double (value);
 		break;
 
+	case LINE_PROP_ARROWHEAD:
+		line->arrowhead = g_value_get_boolean (value);
+		break;
+
+	case LINE_PROP_ARROW_SHAPE_A:
+		line->headA = g_value_get_double (value);
+		break;
+
+	case LINE_PROP_ARROW_SHAPE_B:
+		line->headA = g_value_get_double (value);
+		break;
+
+	case LINE_PROP_ARROW_SHAPE_C:
+		line->headA = g_value_get_double (value);
+		break;
+
 	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
 		return; /* NOTE : RETURN */
 	}
@@ -85,6 +105,22 @@ goc_line_get_property (GObject *gobject, guint param_id,
 		g_value_set_double (value, line->endy);
 		break;
 
+	case LINE_PROP_ARROWHEAD:
+		g_value_set_boolean (value, line->arrowhead);
+		break;
+
+	case LINE_PROP_ARROW_SHAPE_A:
+		g_value_set_double (value, line->headA);
+		break;
+
+	case LINE_PROP_ARROW_SHAPE_B:
+		g_value_set_double (value, line->headB);
+		break;
+
+	case LINE_PROP_ARROW_SHAPE_C:
+		g_value_set_double (value, line->headC);
+		break;
+
 	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
 		return; /* NOTE : RETURN */
 	}
@@ -143,6 +179,7 @@ goc_line_distance (GocItem *item, double x, double y, GocItem **near_item)
 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);
@@ -155,7 +192,7 @@ static void goc_line_draw (GocItem const *item, cairo_t *cr)
 		cairo_save (cr);
 		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, (int) (line->endx - line->startx), (int) (line->endy - line->starty));
+		cairo_line_to (cr, (int) (line->endx - line->startx) * sign, (int) (line->endy - line->starty));
 		cairo_stroke (cr);
 		cairo_restore (cr);
 	}
@@ -207,6 +244,30 @@ goc_line_class_init (GocItemClass *item_klass)
 			_("The line end y coordinate"),
 			-G_MAXDOUBLE, G_MAXDOUBLE, 0.,
 			GSF_PARAM_STATIC | G_PARAM_READWRITE));
+	g_object_class_install_property (obj_klass, LINE_PROP_ARROWHEAD,
+		g_param_spec_boolean ("arrowhead",
+			_("Arrow head"),
+			_("Wether to add an arrow head atthe end of the line or not"),
+			FALSE,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE));
+	g_object_class_install_property (obj_klass, LINE_PROP_ARROW_SHAPE_A,
+		g_param_spec_double ("arrow-shape-a",
+			_("Arrow head shape A"),
+			_("The distance from tip of arrow head to center"),
+			0, G_MAXDOUBLE, 0.,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE));
+	g_object_class_install_property (obj_klass, LINE_PROP_ARROW_SHAPE_B,
+		g_param_spec_double ("arrow-shape-b",
+			_("Arrow head shape B"),
+			_("The distance from tip of arrow head to trailing point, measured along shaft"),
+			0, G_MAXDOUBLE, 0.,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE));
+	g_object_class_install_property (obj_klass, LINE_PROP_ARROW_SHAPE_C,
+		g_param_spec_double ("arrow-shape-c",
+			_("Arrow head shape C"),
+			_("The distance of trailing points from outside edge of shaft"),
+			0, G_MAXDOUBLE, 0.,
+			GSF_PARAM_STATIC | G_PARAM_READWRITE));
 
 	item_klass->update_bounds = goc_line_update_bounds;
 	item_klass->distance = goc_line_distance;
diff --git a/goffice/canvas/goc-line.h b/goffice/canvas/goc-line.h
index 08090c1..86290ef 100644
--- a/goffice/canvas/goc-line.h
+++ b/goffice/canvas/goc-line.h
@@ -32,6 +32,8 @@ struct _GocLine {
 
 	/* using these to avoid confusion with x0 and others in GocItem */
 	double startx, starty, endx, endy;
+	gboolean arrowhead;
+	double headA, headB, headC;
 };
 
 typedef GocStyledItemClass GocLineClass;
diff --git a/goffice/canvas/goc-pixbuf.c b/goffice/canvas/goc-pixbuf.c
index 905881b..4defeb0 100644
--- a/goffice/canvas/goc-pixbuf.c
+++ b/goffice/canvas/goc-pixbuf.c
@@ -139,10 +139,10 @@ goc_pixbuf_update_bounds (GocItem *item)
 	if (!pixbuf->pixbuf)
 		return;
 	/* FIXME: take rotation into account */
-	item->x0 = pixbuf->x;
-	item->y0 = pixbuf->y;
-	item->x1 = pixbuf->x + ((pixbuf->width > 0.)? pixbuf->width: gdk_pixbuf_get_width (pixbuf->pixbuf));
-	item->y1 = pixbuf->y + ((pixbuf->height > 0.)? pixbuf->height: gdk_pixbuf_get_height (pixbuf->pixbuf));
+	item->x0 = floor (pixbuf->x);
+	item->y0 = floor (pixbuf->y);
+	item->x1 = ceil (pixbuf->x + ((pixbuf->width > 0.)? pixbuf->width: gdk_pixbuf_get_width (pixbuf->pixbuf)));
+	item->y1 = ceil (pixbuf->y + ((pixbuf->height > 0.)? pixbuf->height: gdk_pixbuf_get_height (pixbuf->pixbuf)));
 }
 
 static double
@@ -181,6 +181,7 @@ goc_pixbuf_draw (GocItem const *item, cairo_t *cr)
 	cairo_pattern_t *pat;
 	double height, width;
 	double scalex = 1., scaley = 1.;
+	int x;
 
 	if (pixbuf->pixbuf == NULL)
 		return;
@@ -200,11 +201,13 @@ goc_pixbuf_draw (GocItem const *item, cairo_t *cr)
 		scaley = height / gdk_pixbuf_get_height (pixbuf->pixbuf);
 	}
 	cairo_save (cr);
-	goc_group_cairo_transform (item->parent, cr, pixbuf->x, pixbuf->y);
+	x = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)?
+		pixbuf->x + pixbuf->width: pixbuf->x;
+	goc_group_cairo_transform (item->parent, cr, x, (int) pixbuf->y);
 	cairo_rotate (cr, pixbuf->rotation);
 	if (scalex != 1. || scaley != 1.)
 		cairo_scale (cr, scalex, scaley);
-	cairo_rectangle (cr, 0., 0., width, height);
+	cairo_rectangle (cr, 0., 0., ceil (width), ceil (height));
 	cairo_set_source (cr, pat);
 	cairo_pattern_destroy (pat);
         cairo_fill (cr);
diff --git a/goffice/canvas/goc-polygon.c b/goffice/canvas/goc-polygon.c
index 9272f97..65cf3ad 100644
--- a/goffice/canvas/goc-polygon.c
+++ b/goffice/canvas/goc-polygon.c
@@ -175,6 +175,7 @@ goc_polygon_draw (GocItem const *item, cairo_t *cr)
 {
 	GocPolygon *polygon = GOC_POLYGON (item);
 	unsigned i;
+	double sign = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1: 1;
 	if (polygon->nb_points == 0)
 		return;
 	cairo_save (cr);
@@ -183,7 +184,7 @@ goc_polygon_draw (GocItem const *item, cairo_t *cr)
 	/* FIXME: implement the use_spline case */
 
 	for (i = 1; i < polygon->nb_points; i++)
-		cairo_line_to (cr, polygon->points[i].x - polygon->points[0].x,
+		cairo_line_to (cr, (polygon->points[i].x - polygon->points[0].x) * sign,
 		               polygon->points[i].y - polygon->points[0].y);
 	cairo_close_path (cr);
 
diff --git a/goffice/canvas/goc-polyline.c b/goffice/canvas/goc-polyline.c
index 4557a7e..f16975d 100644
--- a/goffice/canvas/goc-polyline.c
+++ b/goffice/canvas/goc-polyline.c
@@ -160,6 +160,7 @@ goc_polyline_draw (GocItem const *item, cairo_t *cr)
 {
 	GocPolyline *polyline = GOC_POLYLINE (item);
 	unsigned i;
+	double sign = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1: 1;
 	if (polyline->nb_points == 0)
 		return;
 	cairo_save (cr);
@@ -168,7 +169,7 @@ goc_polyline_draw (GocItem const *item, cairo_t *cr)
 	/* 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,
+		cairo_line_to (cr, (polyline->points[i].x - polyline->points[0].x) * sign,
 		               polyline->points[i].y - polyline->points[0].y);
 
 	if (go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr))
diff --git a/goffice/canvas/goc-rectangle.c b/goffice/canvas/goc-rectangle.c
index 0cd02e9..7ae50d9 100644
--- a/goffice/canvas/goc-rectangle.c
+++ b/goffice/canvas/goc-rectangle.c
@@ -145,11 +145,17 @@ static void
 goc_rectangle_draw (GocItem const *item, cairo_t *cr)
 {
 	GocRectangle *rect = GOC_RECTANGLE (item);
-
+	double hoffs, voffs = ceil (go_styled_object_get_style (GO_STYLED_OBJECT (item))->outline.width);
+	if (voffs <= 0.)
+		voffs = 1.;
+	hoffs = ((int) voffs & 1)? .5: 0.;
+	voffs = hoffs;
+	if (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)
+		hoffs += (int) rect->width;
 	cairo_save (cr);
-	goc_group_cairo_transform (item->parent, cr, rect->x, rect->y);
+	goc_group_cairo_transform (item->parent, cr, hoffs + (int) rect->x, voffs + (int) rect->y);
 	cairo_rotate (cr, rect->rotation);
-	cairo_rectangle (cr, 0., 0., rect->width, rect->height);
+	cairo_rectangle (cr, 0., 0., (int) rect->width, (int)rect->height);
 	cairo_restore (cr);
 	/* Fill the shape */
 	if (go_styled_object_set_cairo_fill (GO_STYLED_OBJECT (item), cr))
diff --git a/goffice/canvas/goc-text.c b/goffice/canvas/goc-text.c
index 2c8742c..b44d389 100644
--- a/goffice/canvas/goc-text.c
+++ b/goffice/canvas/goc-text.c
@@ -292,7 +292,7 @@ static void
 goc_text_draw (GocItem const *item, cairo_t *cr)
 {
 	GocText *text = GOC_TEXT (item);
-	double x = text->x, y = text->y;
+	double x = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? text->x + text->w: text->x, y = text->y;
 	PangoLayout *pl;
 	GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (item));
 	if (!text->text)



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