[goffice] Fixed various canvas issues.
- From: Jean Bréfort <jbrefort src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] Fixed various canvas issues.
- Date: Wed, 20 Mar 2013 13:01:46 +0000 (UTC)
commit 463ca2afa236da1a56782c987d61b0e608b4099a
Author: Jean Brefort <jean brefort normalesup org>
Date: Wed Mar 20 13:00:43 2013 +0100
Fixed various canvas issues.
ChangeLog | 21 +++++++++++
docs/reference/goffice-0.10-sections.txt | 2 +
goffice/canvas/goc-ellipse.c | 33 ++++++++++++++---
goffice/canvas/goc-path.c | 14 +++++---
goffice/canvas/goc-polygon.c | 20 +++++++++--
goffice/canvas/goc-polyline.c | 57 +++++++++++++++++-------------
goffice/canvas/goc-rectangle.c | 12 ++++--
goffice/canvas/goc-styled-item.c | 31 ++++++++++++++++-
goffice/canvas/goc-styled-item.h | 2 +
9 files changed, 148 insertions(+), 44 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 6e147e1..3f0cdc7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2013-03-20 Jean Brefort <jean brefort normalesup org>
+
+ * goffice/canvas/goc-ellipse.c (goc_ellipse_prepare_draw),
+ (goc_ellipse_update_bounds), (goc_ellipse_distance),
+ (goc_ellipse_draw): fixed line width.
+ * goffice/canvas/goc-path.c (goc_path_prepare_draw),
+ (goc_path_update_bounds), (goc_path_draw): fixed line width and position
+ in RTL canvas.
+ * goffice/canvas/goc-polygon.c (goc_polygon_prepare_path),
+ (goc_polygon_update_bounds), (goc_polygon_distance),
+ (goc_polygon_draw): ditto.
+ * goffice/canvas/goc-polyline.c (goc_polyline_prepare_draw),
+ (goc_polyline_draw): ditto.
+ * goffice/canvas/goc-rectangle.c (goc_rectangle_prepare_draw),
+ (goc_rectangle_update_bounds), (goc_rectangle_draw): fixed line width.
+ * goffice/canvas/goc-styled-item.c
+ (goc_styled_item_set_cairo_line),
+ (goc_styled_item_get_scale_line_width),
+ (goc_styled_item_set_scale_line_width): new helper functions.
+ * goffice/canvas/goc-styled-item.h: ditto.
+
2013-03-20 Morten Welinder <terra gnome org>
* goffice/gtk/go-font-sel.c (reload_faces): Use
diff --git a/docs/reference/goffice-0.10-sections.txt b/docs/reference/goffice-0.10-sections.txt
index da3709a..dc3c6cd 100644
--- a/docs/reference/goffice-0.10-sections.txt
+++ b/docs/reference/goffice-0.10-sections.txt
@@ -2444,6 +2444,8 @@ GocRect
GocStyledItem
GocStyledItemClass
goc_styled_item_set_cairo_line
+goc_styled_item_get_scale_line_width
+goc_styled_item_set_scale_line_width
<SUBSECTION Standard>
GOC_IS_STYLED_ITEM
GOC_STYLED_ITEM
diff --git a/goffice/canvas/goc-ellipse.c b/goffice/canvas/goc-ellipse.c
index 269463a..c79a4bd 100644
--- a/goffice/canvas/goc-ellipse.c
+++ b/goffice/canvas/goc-ellipse.c
@@ -115,13 +115,13 @@ goc_ellipse_prepare_draw (GocItem const *item, cairo_t *cr, gboolean flag)
if (0 == ellipse->width && 0 == ellipse->height)
return FALSE;
- cairo_save (cr);
_goc_item_transform (item, cr, flag);
if (1 == flag) {
goc_group_cairo_transform (item->parent, cr, ellipse->x + ellipse->width/2., ellipse->y +
ellipse->height/2.);
} else {
cairo_translate (cr, ellipse->x + ellipse->width/2., ellipse->y + ellipse->height/2.);
}
+ cairo_save (cr);
cairo_rotate (cr, ellipse->rotation * sign);
cairo_scale (cr, ellipse->width/2. * sign, ellipse->height/2.);
cairo_arc (cr, 0., 0., 1., 0., 2 * M_PI);
@@ -134,12 +134,20 @@ goc_ellipse_update_bounds (GocItem *item)
{
cairo_surface_t *surface;
cairo_t *cr;
+ gboolean set_line,
+ scale_line_width = goc_styled_item_get_scale_line_width (GOC_STYLED_ITEM (item));
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1 , 1);
cr = cairo_create (surface);
+ cairo_save (cr);
if (goc_ellipse_prepare_draw (item, cr, 0)) {
- if (go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr))
+ if (!scale_line_width)
+ cairo_restore (cr);
+ set_line = go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr);
+ if (scale_line_width)
+ cairo_restore (cr);
+ if (set_line)
cairo_stroke_extents (cr, &item->x0, &item->y0, &item->x1, &item->y1);
else if (go_style_is_fill_visible (go_styled_object_get_style (GO_STYLED_OBJECT (item))))
cairo_fill_extents (cr, &item->x0, &item->y0, &item->x1, &item->y1);
@@ -163,6 +171,8 @@ goc_ellipse_distance (GocItem *item, double x, double y, GocItem **near_item)
double ppu = goc_canvas_get_pixels_per_unit (item->canvas);
cairo_surface_t *surface;
cairo_t *cr;
+ gboolean set_line,
+ scale_line_width = goc_styled_item_get_scale_line_width (GOC_STYLED_ITEM (item));
if (0 == ellipse->width && 0 == ellipse->height)
return res;
@@ -176,14 +186,21 @@ goc_ellipse_distance (GocItem *item, double x, double y, GocItem **near_item)
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
cr = cairo_create (surface);
+ cairo_save (cr);
if (goc_ellipse_prepare_draw (item, cr, 0)) {
/* Filled OR both fill and stroke are none */
+ if (!scale_line_width)
+ cairo_restore (cr);
+ set_line = go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr);
+ if (scale_line_width)
+ cairo_restore (cr);
+ if (set_line)
if (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))) {
+ (style->fill.type == GO_STYLE_FILL_NONE && !set_line)) {
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)) {
+ if (set_line && cairo_in_stroke (cr, x, y)) {
res = 0;
}
}
@@ -197,16 +214,20 @@ goc_ellipse_distance (GocItem *item, double x, double y, GocItem **near_item)
static void
goc_ellipse_draw (GocItem const *item, cairo_t *cr)
{
+ gboolean scale_line_width = goc_styled_item_get_scale_line_width (GOC_STYLED_ITEM (item));
cairo_save(cr);
if (goc_ellipse_prepare_draw (item, cr, 1)) {
go_styled_object_fill (GO_STYLED_OBJECT (item), cr, TRUE);
- if (goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr)) {
+ if (!scale_line_width)
+ cairo_restore (cr);
+ if (go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr)) {
cairo_stroke (cr);
} else {
cairo_new_path (cr);
}
}
- cairo_restore(cr);
+ if (scale_line_width)
+ cairo_restore(cr);
}
static void
diff --git a/goffice/canvas/goc-path.c b/goffice/canvas/goc-path.c
index 0d40ced..268dbc6 100644
--- a/goffice/canvas/goc-path.c
+++ b/goffice/canvas/goc-path.c
@@ -126,18 +126,16 @@ goc_path_prepare_draw (GocItem const *item, cairo_t *cr, gboolean flag)
double sign = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1: 1;
double rsign = sign;
- cairo_save (cr);
_goc_item_transform (item, cr, flag);
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_scale (cr, sign, 1.);
cairo_rotate (cr, path->rotation * rsign);
go_path_to_cairo (path->path, GO_PATH_DIRECTION_FORWARD, cr);
- cairo_restore (cr);
return TRUE;
}
@@ -151,8 +149,10 @@ goc_path_update_bounds (GocItem *item)
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
cr = cairo_create (surface);
+ cairo_save (cr);
if (goc_path_prepare_draw (item, cr, 0)) {
goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr);
+ cairo_restore (cr);
cairo_stroke_extents (cr, &item->x0, &item->y0, &item->x1, &item->y1);
}
@@ -201,19 +201,23 @@ static void
goc_path_draw (GocItem const *item, cairo_t *cr)
{
GocPath *path = GOC_PATH (item);
+ gboolean scale_line_width = goc_styled_item_get_scale_line_width (GOC_STYLED_ITEM (item));
cairo_save(cr);
cairo_set_fill_rule (cr, path->fill_rule? CAIRO_FILL_RULE_EVEN_ODD: CAIRO_FILL_RULE_WINDING);
if (goc_path_prepare_draw (item, cr, 1)) {
if (path->closed)
go_styled_object_fill (GO_STYLED_OBJECT (item), cr, TRUE);
- if (goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr)) {
+ if (!scale_line_width)
+ cairo_restore (cr);
+ if (go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr)) {
cairo_stroke (cr);
} else {
cairo_new_path (cr);
}
}
- cairo_restore(cr);
+ if (scale_line_width)
+ cairo_restore(cr);
}
static void
diff --git a/goffice/canvas/goc-polygon.c b/goffice/canvas/goc-polygon.c
index 79f2b89..b3c680b 100644
--- a/goffice/canvas/goc-polygon.c
+++ b/goffice/canvas/goc-polygon.c
@@ -179,7 +179,8 @@ goc_polygon_prepare_path (GocItem const *item, cairo_t *cr, gboolean flag)
go_bezier_spline_to_cairo (spline, cr, goc_canvas_get_direction (item->canvas) ==
GOC_DIRECTION_RTL);
cairo_restore (cr);
} else {
- double sign = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1: 1;
+ /* sign is meaningful only for drawing, so if flag == 0, sign must be 1 */
+ double sign = (flag && goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1: 1;
if (polygon->nb_sizes > 0) {
snum = 0;
for (j = 0; j < (int) polygon->nb_sizes; j++) {
@@ -219,12 +220,14 @@ goc_polygon_update_bounds (GocItem *item)
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
cr = cairo_create (surface);
+ cairo_save (cr);
_goc_item_transform (item, cr, FALSE);
if (go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr))
mode = 1;
else if (go_style_is_fill_visible (go_styled_object_get_style (GO_STYLED_OBJECT (item))))
mode = 2;
if (mode && goc_polygon_prepare_path (item, cr, 0)) {
+ cairo_restore (cr);
if (mode == 1)
cairo_stroke_extents (cr, &item->x0, &item->y0, &item->x1, &item->y1);
else
@@ -245,6 +248,8 @@ goc_polygon_distance (GocItem *item, double x, double y, GocItem **near_item)
double res = G_MAXDOUBLE;
double ppu = goc_canvas_get_pixels_per_unit (item->canvas);
double tmp_width = 0;
+ gboolean tmp_auto_dash = style->line.auto_dash;
+ GOLineDashType tmp_dash_type = style->line.dash_type;
cairo_surface_t *surface;
cairo_t *cr;
@@ -259,11 +264,13 @@ goc_polygon_distance (GocItem *item, double x, double y, GocItem **near_item)
style->line.width /= ppu;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
cr = cairo_create (surface);
+ cairo_save (cr);
goc_polygon_prepare_path (item, cr, 0);
+ cairo_restore (cr);
if (go_style_is_fill_visible (style)) {
if (cairo_in_fill (cr, x, y))
res = 0;
- else if ((item->x1 - item->x0 < 5 || item->y1 - item->y0 < 5) && style->line.dash_type ==
GO_LINE_NONE) {
+ else if ((item->x1 - item->x0 < 5 || item->y1 - item->y0 < 5) && style->line.dash_type ==
tmp_dash_type) {
style->line.dash_type = GO_LINE_SOLID;
style->line.auto_dash = FALSE;
}
@@ -278,23 +285,30 @@ goc_polygon_distance (GocItem *item, double x, double y, GocItem **near_item)
cairo_destroy (cr);
cairo_surface_destroy (surface);
style->line.width = tmp_width;
+ style->line.auto_dash = tmp_auto_dash;
+ style->line.dash_type = tmp_dash_type;
+printf("x=%g x0=%g x1=%g\n",x,item->x0,item->x1);
return res;
}
static void
goc_polygon_draw (GocItem const *item, cairo_t *cr)
{
+ gboolean scale_line_width = goc_styled_item_get_scale_line_width (GOC_STYLED_ITEM (item));
cairo_save (cr);
_goc_item_transform (item, cr, TRUE);
if (goc_polygon_prepare_path (item, cr, 1)) {
go_styled_object_fill (GO_STYLED_OBJECT (item), cr, TRUE);
+ if (!scale_line_width)
+ cairo_restore (cr);
if (go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr))
cairo_stroke (cr);
else
cairo_new_path (cr);
}
- cairo_restore (cr);
+ if (scale_line_width)
+ cairo_restore (cr);
}
static void
diff --git a/goffice/canvas/goc-polyline.c b/goffice/canvas/goc-polyline.c
index 7738669..a98acb8 100644
--- a/goffice/canvas/goc-polyline.c
+++ b/goffice/canvas/goc-polyline.c
@@ -110,7 +110,9 @@ goc_polyline_prepare_draw (GocItem const *item, cairo_t *cr, gboolean flag)
{
GocPolyline *polyline = GOC_POLYLINE (item);
unsigned i;
+ gboolean scale_line_width = goc_styled_item_get_scale_line_width (GOC_STYLED_ITEM (item));
+ cairo_save (cr);
_goc_item_transform (item, cr, flag);
if (polyline->nb_points == 0)
return FALSE;
@@ -121,35 +123,41 @@ goc_polyline_prepare_draw (GocItem const *item, cairo_t *cr, gboolean flag)
} else {
cairo_move_to (cr, polyline->points[0].x, polyline->points[0].y);
}
- if (goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr)) {
- if (polyline->use_spline) {
- GOBezierSpline *spline = (GOBezierSpline *) g_object_get_data (G_OBJECT (polyline),
"spline");
- cairo_save (cr);
- if (flag == 0)
- cairo_translate (cr, polyline->points[0].x, polyline->points[0].y);
- go_bezier_spline_to_cairo (spline, cr, goc_canvas_get_direction (item->canvas) ==
GOC_DIRECTION_RTL);
- cairo_restore (cr);
- } else {
- double sign = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1: 1;
- gboolean prev_valid = TRUE;
- for (i = 1; i < polyline->nb_points; i++) {
- if (go_finite (polyline->points[i].x)) {
- if (prev_valid)
- cairo_line_to (cr, (polyline->points[i].x -
polyline->points[0].x * flag) * sign,
- polyline->points[i].y - polyline->points[0].y * flag);
- else {
- cairo_move_to (cr, (polyline->points[i].x -
polyline->points[0].x * flag) * sign,
- polyline->points[i].y - polyline->points[0].y * flag);
- prev_valid = TRUE;
- }
- } else
- prev_valid = FALSE;
- }
+ if (polyline->use_spline) {
+ GOBezierSpline *spline = (GOBezierSpline *) g_object_get_data (G_OBJECT (polyline), "spline");
+ cairo_save (cr);
+ if (flag == 0)
+ cairo_translate (cr, polyline->points[0].x, polyline->points[0].y);
+ go_bezier_spline_to_cairo (spline, cr, goc_canvas_get_direction (item->canvas) ==
GOC_DIRECTION_RTL);
+ cairo_restore (cr);
+ } else {
+ double sign = (flag && goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1: 1;
+ gboolean prev_valid = TRUE;
+ for (i = 1; i < polyline->nb_points; i++) {
+ if (go_finite (polyline->points[i].x)) {
+ if (prev_valid)
+ cairo_line_to (cr, (polyline->points[i].x - polyline->points[0].x *
flag) * sign,
+ polyline->points[i].y - polyline->points[0].y * flag);
+ else {
+ cairo_move_to (cr, (polyline->points[i].x - polyline->points[0].x *
flag) * sign,
+ polyline->points[i].y - polyline->points[0].y * flag);
+ prev_valid = TRUE;
+ }
+ } else
+ prev_valid = FALSE;
}
+ }
+ if (!scale_line_width)
+ cairo_restore (cr);
+ if (goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr)) {
+ if (!scale_line_width)
+ cairo_restore (cr);
return TRUE;
}
+ if (!scale_line_width)
+ cairo_restore (cr);
return FALSE;
}
@@ -211,7 +219,6 @@ goc_polyline_distance (GocItem *item, double x, double y, GocItem **near_item)
static void
goc_polyline_draw (GocItem const *item, cairo_t *cr)
{
- cairo_save (cr);
if (goc_polyline_prepare_draw (item, cr, 1)) {
cairo_stroke (cr);
}
diff --git a/goffice/canvas/goc-rectangle.c b/goffice/canvas/goc-rectangle.c
index ae4ac37..1cc9ac5 100644
--- a/goffice/canvas/goc-rectangle.c
+++ b/goffice/canvas/goc-rectangle.c
@@ -143,7 +143,6 @@ goc_rectangle_prepare_draw (GocItem const *item, cairo_t *cr, gboolean flag)
if (0 == rect->width && 0 == rect->height)
return FALSE;
- cairo_save (cr);
_goc_item_transform (item, cr, flag);
if (1 == flag) {
goc_group_cairo_transform (item->parent, cr, rect->x, rect->y);
@@ -200,7 +199,6 @@ goc_rectangle_prepare_draw (GocItem const *item, cairo_t *cr, gboolean flag)
}
cairo_close_path (cr);
}
- cairo_restore (cr);
return TRUE;
}
@@ -213,7 +211,9 @@ goc_rectangle_update_bounds (GocItem *item)
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1 , 1);
cr = cairo_create (surface);
+ cairo_save (cr);
if (goc_rectangle_prepare_draw (item, cr, 0)) {
+ cairo_restore (cr);
if (go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr))
cairo_stroke_extents (cr, &item->x0, &item->y0, &item->x1, &item->y1);
else if (go_style_is_fill_visible (go_styled_object_get_style (GO_STYLED_OBJECT (item))))
@@ -272,16 +272,20 @@ goc_rectangle_distance (GocItem *item, double x, double y, GocItem **near_item)
static void
goc_rectangle_draw (GocItem const *item, cairo_t *cr)
{
+ gboolean scale_line_width = goc_styled_item_get_scale_line_width (GOC_STYLED_ITEM (item));
cairo_save(cr);
if (goc_rectangle_prepare_draw (item, cr, 1)) {
go_styled_object_fill (GO_STYLED_OBJECT (item), cr, TRUE);
- if (goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr)) {
+ if (!scale_line_width)
+ cairo_restore (cr);
+ if (go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr)) {
cairo_stroke (cr);
} else {
cairo_new_path (cr);
}
}
- cairo_restore(cr);
+ if (scale_line_width)
+ cairo_restore (cr);
}
static void
diff --git a/goffice/canvas/goc-styled-item.c b/goffice/canvas/goc-styled-item.c
index 2fd05b9..3721160 100644
--- a/goffice/canvas/goc-styled-item.c
+++ b/goffice/canvas/goc-styled-item.c
@@ -257,7 +257,7 @@ GSF_CLASS_FULL (GocStyledItem, goc_styled_item, NULL, NULL,
GSF_INTERFACE (goc_styled_item_so_init, GO_TYPE_STYLED_OBJECT))
/**
- * goc_styled_item_set_cairo_line :
+ * goc_styled_item_set_cairo_line:
* @gsi: #GocStyledItem
* @cr: #cairo_t
*
@@ -289,3 +289,32 @@ goc_styled_item_set_cairo_line (GocStyledItem const *gsi, cairo_t *cr)
gsi->style->line.width = width;
return result;
}
+
+/**
+ * goc_styled_item_set_scale_line_width:
+ * @gsi: #GocStyledItem
+ *
+ * This function returns %TRUE if the line width needs to be scaled. It will
+ * always return %FALSE if the line width is 0.
+ * Returns: whether the line width needs to be scaled.
+ **/
+gboolean goc_styled_item_get_scale_line_width (GocStyledItem const *gsi)
+{
+ g_return_val_if_fail (GOC_IS_STYLED_ITEM (gsi), FALSE);
+ return gsi->scale_line_width && gsi->style->line.width > 0.;
+}
+
+/**
+ * goc_styled_item_set_scale_line_width:
+ * @gsi: #GocStyledItem
+ * @scale_line_width: boolean
+ *
+ * Sets whether the line width needs to be scaled according to the current
+ * canvas resolution and the item transformation. It will be ignored if the
+ * line width is 0. Default value is %TRUE.
+ **/
+void goc_styled_item_set_scale_line_width (GocStyledItem *gsi, gboolean scale_line_width)
+{
+ g_return_if_fail (GOC_IS_STYLED_ITEM (gsi));
+ gsi->scale_line_width = scale_line_width;
+}
diff --git a/goffice/canvas/goc-styled-item.h b/goffice/canvas/goc-styled-item.h
index d5e6e99..c939296 100644
--- a/goffice/canvas/goc-styled-item.h
+++ b/goffice/canvas/goc-styled-item.h
@@ -60,6 +60,8 @@ struct _GocStyledItemClass {
GType goc_styled_item_get_type (void);
gboolean goc_styled_item_set_cairo_line (GocStyledItem const *gsi, cairo_t *cr);
+gboolean goc_styled_item_get_scale_line_width (GocStyledItem const *gsi);
+void goc_styled_item_set_scale_line_width (GocStyledItem *gsi, gboolean scale_line_width);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]