[gnumeric: 1/2] fixed various canvas related issues



commit bc0d9ed94035cc754723c7aa148efe7221793989
Author: Jean Brefort <jean brefort normalesup org>
Date:   Sun Aug 30 16:28:34 2009 +0200

    fixed various canvas related issues

 ChangeLog                                 |   11 +++++
 src/sheet-control-gui.c                   |    9 ++--
 src/sheet-object.c                        |   17 ++++++++
 src/style-border.c                        |   62 +---------------------------
 src/style-border.h                        |    3 +-
 src/widgets/ChangeLog                     |    8 ++++
 src/widgets/gnumeric-dashed-canvas-line.c |   44 ++++++++++++++++-----
 src/widgets/gnumeric-dashed-canvas-line.h |    5 +--
 8 files changed, 80 insertions(+), 79 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 548fba0..21ad8e3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2009-08-30  Jean Brefort  <jean brefort normalesup org>
+
+	* src/sheet-control-gui.c (scg_object_anchor_to_coords): fixed a
+	rounding error.
+	* src/sheet-object.c (sheet_object_clear_sheet),
+	(sheet_object_view_finalize), (sheet_object_view_class_init): don't
+	unref a finalized view.
+	* src/style-border.c (gnm_style_border_set_dash),
+	(style_border_set_gtk): rename and export gnm_style_border_set_dash.
+	* src/style-border.h: ditto.
+
 2009-08-27  Jean Brefort  <jean brefort normalesup org>
 
 	* src/gnm-so-filled.c (so_filled_item_view_class_init): deprecate the
diff --git a/src/sheet-control-gui.c b/src/sheet-control-gui.c
index 0e4eef3..a14f437 100644
--- a/src/sheet-control-gui.c
+++ b/src/sheet-control-gui.c
@@ -2423,14 +2423,15 @@ scg_object_anchor_to_coords (SheetControlGUI const *scg,
 	pixels[1] = scg_colrow_distance_get (scg, FALSE, 0, r->start.row);
 	pixels[3] = pixels[1] + scg_colrow_distance_get (scg, FALSE,
 		r->start.row, r->end.row);
+	/* add .5 to offsets so that the rounding is optimal */
 	pixels[0] += cell_offset_calc_pixel (sheet, r->start.col,
-		TRUE, anchor->offset[0]);
+		TRUE, anchor->offset[0]) + .5;
 	pixels[1] += cell_offset_calc_pixel (sheet, r->start.row,
-		FALSE, anchor->offset[1]);
+		FALSE, anchor->offset[1]) + .5;
 	pixels[2] += cell_offset_calc_pixel (sheet, r->end.col,
-		TRUE, anchor->offset[2]);
+		TRUE, anchor->offset[2]) + .5;
 	pixels[3] += cell_offset_calc_pixel (sheet, r->end.row,
-		FALSE, anchor->offset[3]);
+		FALSE, anchor->offset[3]) + .5;
 
 	direction = anchor->base.direction;
 	if (direction == GOD_ANCHOR_DIR_UNKNOWN)
diff --git a/src/sheet-object.c b/src/sheet-object.c
index 4cc50c2..0f83228 100644
--- a/src/sheet-object.c
+++ b/src/sheet-object.c
@@ -407,6 +407,7 @@ sheet_object_clear_sheet (SheetObject *so)
 	}
 
 	while (so->realized_list != NULL) {
+		g_object_set_qdata (G_OBJECT (so->realized_list->data), sov_so_quark, NULL);
 		g_object_unref (G_OBJECT (so->realized_list->data));
 		so->realized_list = g_list_remove (so->realized_list, so->realized_list->data);
 		
@@ -1083,6 +1084,8 @@ sheet_object_adjust_stacking (SheetObject *so, gint offset)
 
 /*****************************************************************************/
 
+static GObjectClass *view_parent_class;
+
 void
 sheet_object_view_set_bounds (SheetObjectView *sov,
 			      double const *coords, gboolean visible)
@@ -1148,8 +1151,22 @@ sheet_object_view_button_pressed (GocItem *item, int button, double x, double y)
 }
 
 static void
+sheet_object_view_finalize (GObject *obj)
+{
+	SheetObject *so = (SheetObject *) g_object_get_qdata (obj, sov_so_quark);
+	if (so)
+		so->realized_list = g_list_remove (so->realized_list, obj);
+	view_parent_class->finalize (obj);
+}
+
+static void
 sheet_object_view_class_init (GocItemClass *item_klass)
 {
+	GObjectClass *obj_klass = (GObjectClass *) item_klass;
+	view_parent_class = g_type_class_peek_parent (item_klass);
+
+	obj_klass->finalize = sheet_object_view_finalize;
+
 	item_klass->enter_notify = sheet_object_view_enter_notify;
 	item_klass->button_pressed = sheet_object_view_button_pressed;
 }
diff --git a/src/style-border.c b/src/style-border.c
index 0d3e66d..2ff22c9 100644
--- a/src/style-border.c
+++ b/src/style-border.c
@@ -285,62 +285,6 @@ gnm_style_border_get_orientation (GnmStyleBorderLocation type)
 	}
 }
 
-void
-gnm_style_border_set_gc_dash (GdkGC *gc, GnmStyleBorderType const i)
-{
-	GdkLineStyle style = GDK_LINE_SOLID;
-
-	g_return_if_fail (gc != NULL);
-	g_return_if_fail (i >= GNM_STYLE_BORDER_NONE);
-	g_return_if_fail (i < GNM_STYLE_BORDER_MAX);
-
-	if (style_border_data[i].pattern != NULL)
-		style = GDK_LINE_ON_OFF_DASH;
-
-	/* NOTE : Tricky.  We Use CAP_NOT_LAST because with butt lines
-	 * of width > 0 seem to exclude the far point (under Xfree86-4).
-	 * The Docs for X11R6 say that NotLast will give the same behavior for
-	 * lines of width 0.  Strangely the R5 docs say this for 0 AND 1.
-	 */
-	gdk_gc_set_line_attributes (gc, style_border_data[i].width, style,
-				    GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
-
-	if (style_border_data[i].pattern != NULL) {
-		struct LineDotPattern const * const pat =
-			style_border_data[i].pattern;
-
-		gdk_gc_set_dashes (gc, style_border_data[i].offset,
-				   (gint8 *)pat->pattern, pat->elements);
-	}
-
-	/* The background should never be drawn */
-	gdk_gc_set_rgb_bg_color (gc, &gs_white);
-}
-
-static inline GdkGC *
-style_border_get_gc (GnmBorder const *border, GdkDrawable *drawable)
-{
-	GdkScreen *this_screen;
-	if (border == NULL)
-		return NULL;
-
-	this_screen = gdk_drawable_get_screen (drawable);
-	if (border->gc_screen != this_screen) {
-		if (border->gc)
-			g_object_unref (G_OBJECT (border->gc));
-		if (border->gc_screen)
-			g_object_unref (G_OBJECT (border->gc_screen));
-		((GnmBorder *)border)->gc = gdk_gc_new (drawable);
-		((GnmBorder *)border)->gc_screen = this_screen;
-		g_object_ref (this_screen);
-		gnm_style_border_set_gc_dash (border->gc, border->line_type);
-		gdk_gc_set_rgb_fg_color (border->gc, &border->color->gdk_color);
-	}
-
-	return border->gc;
-}
-
-
 GnmBorder *
 gnm_style_border_ref (GnmBorder *border)
 {
@@ -579,8 +523,8 @@ style_border_vmargins (GnmBorder const * const * prev_vert,
 	return FALSE;
 }
 
-static void
-style_border_set_gtk_dash (GnmStyleBorderType const i,
+void
+gnm_style_border_set_dash (GnmStyleBorderType const i,
 			   cairo_t *context)
 {
 	GdkLineStyle style = GDK_LINE_SOLID;
@@ -614,7 +558,7 @@ style_border_set_gtk (GnmBorder const * const border,
 	if (border == NULL)
 		return FALSE;
 
-	style_border_set_gtk_dash (border->line_type, context);
+	gnm_style_border_set_dash (border->line_type, context);
 	cairo_set_source_rgb (context,
 			      border->color->gdk_color.red   / (double) 0xffff,
 			      border->color->gdk_color.green / (double) 0xffff,
diff --git a/src/style-border.h b/src/style-border.h
index c579cbb..9b79924 100644
--- a/src/style-border.h
+++ b/src/style-border.h
@@ -81,8 +81,7 @@ gboolean gnm_style_border_visible_in_blank (GnmBorder const *border);
 GnmStyleBorderOrientation gnm_style_border_get_orientation (GnmStyleBorderLocation type);
 
 gint   gnm_style_border_get_width   (GnmStyleBorderType const line_type);
-void   gnm_style_border_set_gc_dash (GdkGC *gc,
-				     GnmStyleBorderType const line_type);
+void gnm_style_border_set_dash (GnmStyleBorderType const i, cairo_t *context);
 
 void gnm_style_borders_row_draw (GnmBorder const * const * prev_vert,
 				 GnmStyleRow const *sr,
diff --git a/src/widgets/ChangeLog b/src/widgets/ChangeLog
index 4645151..d383b9d 100644
--- a/src/widgets/ChangeLog
+++ b/src/widgets/ChangeLog
@@ -1,3 +1,11 @@
+2009-08-30  Jean Brefort  <jean brefort normalesup org>
+
+	* gnumeric-dashed-canvas-line.c (line_draw), (double_line_draw),
+	(gnumeric_dashed_canvas_line_draw),
+	(gnumeric_dashed_canvas_line_class_init),
+	(gnumeric_dashed_canvas_line_set_dash_index): fixed dashes rendering.
+	* gnumeric-dashed-canvas-line.h: ditto.
+
 2009-08-25  Jean Brefort  <jean brefort normalesup org>
 
 	reviewed by: <delete if not using a buddy>
diff --git a/src/widgets/gnumeric-dashed-canvas-line.c b/src/widgets/gnumeric-dashed-canvas-line.c
index 2f76c07..0d1e81f 100644
--- a/src/widgets/gnumeric-dashed-canvas-line.c
+++ b/src/widgets/gnumeric-dashed-canvas-line.c
@@ -32,6 +32,35 @@ hypothenuse (double xlength, double ylength)
 
 }
 
+static void
+line_draw (GocItem const *item, GnmStyleBorderType const i, cairo_t *cr)
+{
+	GocLine *line = GOC_LINE (item);
+	double sign = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1: 1;
+	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 (line->startx == line->endx && line->starty == line->endy)
+		return;
+	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 ((endx != 0. || endy!= 0.) && go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr)) {
+		gnm_style_border_set_dash (i, cr);
+		/* try to avoid horizontal and vertical lines between two pixels */
+		cairo_move_to (cr, 0., 0.);
+		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);
+}
+
 /*
  * Draw a double line
  * NOTE: We only support a single straight line segment here.
@@ -72,7 +101,7 @@ hypothenuse (double xlength, double ylength)
  * (x0,y0) - B is the y offset from y0 of the start of this line.
  */
 static void
-double_line_draw (GocItem const *item, cairo_t *cr)
+double_line_draw (GocItem const *item, GnmStyleBorderType const i, cairo_t *cr)
 {
 	double coords[4];
 	double length, xdiff, ydiff, xoffs, yoffs;
@@ -94,15 +123,13 @@ double_line_draw (GocItem const *item, cairo_t *cr)
 	line->starty = coords[1] + yoffs;
 	line->endx = coords[2] + xoffs;
 	line->endy = coords[3] + yoffs;
-	gnumeric_dashed_canvas_line_class->
-		real_draw (item, cr);
+	line_draw (item, i, cr);
 
 	line->startx = coords[0] - xoffs;
 	line->starty = coords[1] - yoffs;
 	line->endx = coords[2] - xoffs;
 	line->endy = coords[3] - yoffs;
-	gnumeric_dashed_canvas_line_class->
-		real_draw (item, cr);
+	line_draw (item, i, cr);
 
 	line->startx = coords[0];
 	line->starty = coords[1];
@@ -116,10 +143,9 @@ gnumeric_dashed_canvas_line_draw (GocItem const *item, cairo_t *cr)
 	GnumericDashedCanvasLine *line = GNUMERIC_DASHED_CANVAS_LINE (item);
 
 	if (line->dash_style_index == GNM_STYLE_BORDER_DOUBLE)
-		double_line_draw (item, cr);
+		double_line_draw (item, line->dash_style_index, cr);
 	else {
-		gnumeric_dashed_canvas_line_class->
-			real_draw (item, cr);
+		line_draw (item, line->dash_style_index, cr);
 	}
 }
 
@@ -132,7 +158,6 @@ gnumeric_dashed_canvas_line_class_init (GnumericDashedCanvasLineClass *klass)
 
 	item_class = (GocItemClass *) klass;
 
-	klass->real_draw = item_class->draw;
 	item_class->draw = &gnumeric_dashed_canvas_line_draw;
 }
 
@@ -154,7 +179,6 @@ gnumeric_dashed_canvas_line_set_dash_index (GnumericDashedCanvasLine *line,
 	GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (line));
 	line->dash_style_index = indx;
 	style->line.width = width;
-	style->line.dash_type = (indx == GNM_STYLE_BORDER_DOUBLE)? GNM_STYLE_BORDER_THIN: indx;
 
 	goc_item_invalidate (GOC_ITEM (line));
 }
diff --git a/src/widgets/gnumeric-dashed-canvas-line.h b/src/widgets/gnumeric-dashed-canvas-line.h
index 652461e..8be223b 100644
--- a/src/widgets/gnumeric-dashed-canvas-line.h
+++ b/src/widgets/gnumeric-dashed-canvas-line.h
@@ -18,10 +18,7 @@
 
 
 typedef struct _GnumericDashedCanvasLine GnumericDashedCanvasLine;
-typedef struct {
-	GocLineClass base;
-	void (*real_draw) (GocItem const *item, cairo_t *cr);
-} GnumericDashedCanvasLineClass;
+typedef GocLineClass GnumericDashedCanvasLineClass;
 
 struct _GnumericDashedCanvasLine {
 	GocLine line;



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