[goffice] Add arrow heads to arcs.
- From: Jean Bréfort <jbrefort src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] Add arrow heads to arcs.
- Date: Fri, 5 Mar 2010 08:08:17 +0000 (UTC)
commit 196a2d11b48d6a4205c83db8c9eaa25232c56737
Author: Jean Brefort <jean brefort normalesup org>
Date: Fri Mar 5 09:04:12 2010 +0100
Add arrow heads to arcs.
ChangeLog | 14 +++
goffice/canvas/goc-arc.c | 209 ++++++++++++++++++++------------------
goffice/canvas/goc-ellipse.c | 2 +-
goffice/canvas/goc-rectangle.c | 7 +-
goffice/canvas/goc-styled-item.c | 1 +
5 files changed, 132 insertions(+), 101 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index e759dbc..cb5992b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2010-03-05 Valek Filippov <frob gnome org>
+
+ * goffice/canvas/goc-arc.c (goc_arc_start), (goc_arc_end),
+ (prepare_draw_arrow), (goc_arc_prepare_draw),
+ (goc_arc_update_bounds), (goc_arc_distance), (goc_arc_draw): support
+ arrow heads.
+ * goffice/canvas/goc-ellipse.c (goc_ellipse_prepare_draw): fix rtl.
+ * goffice/canvas/goc-rectangle.c (goc_rectangle_prepare_draw): ditto.
+
+2010-03-03 Jean Brefort <jean brefort normalesup org>
+
+ * goffice/canvas/goc-styled-item.c (goc_styled_item_style_changed): call
+ goc_item_bounds_changed.
+
2010-03-04 Valek Filippov <frob gnome org>
* goffice/canvas/goc-arc.c (goc_arc_prepare_draw),
diff --git a/goffice/canvas/goc-arc.c b/goffice/canvas/goc-arc.c
index 0701f4a..9b9328f 100644
--- a/goffice/canvas/goc-arc.c
+++ b/goffice/canvas/goc-arc.c
@@ -159,67 +159,105 @@ goc_arc_get_property (GObject *gobject, guint param_id,
}
}
-#if 0
static void
-handle_arrow_bounds (GOArrow const *arrow, GocItem *item)
-{
- /*
- * Do not calculate things precisely, just add enough room
- * in all directions.
- */
-
- switch (arrow->typ) {
- case GO_ARROW_NONE:
- break;
- case GO_ARROW_KITE: {
- double d = hypot (arrow->b, arrow->c);
- item->x0 -= d;
- item->x1 += d;
- item->y0 -= d;
- item->y1 += d;
- break;
- }
- case GO_ARROW_OVAL: {
- double d = MAX (arrow->a, arrow->b);
- item->x0 -= d;
- item->x1 += d;
- item->y0 -= d;
- item->y1 += d;
- break;
- }
- default:
- g_assert_not_reached ();
- }
-}
-
-static void
-goc_arc_start (GocItem const *item, double x, double y)
+goc_arc_start (GocItem const *item, double *x, double *y, double *phi)
{
GocArc *arc = GOC_ARC (item);
double x1, y1, s;
-
+ double sign = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1.: 1.;
+
x1 = arc->xr * cos (atan2 (arc->xr / arc->yr * sin (arc->ang1), cos (arc->ang1)));
y1 = arc->yr * sin (atan2 (arc->xr / arc->yr * sin (arc->ang1), cos (arc->ang1)));
s = sqrt (x1 * x1 + y1 * y1);
- x = arc->xc + s * cos (arc->ang1 - arc->rotation);
- y = arc->yc - s * sin (arc->ang1 - arc->rotation);
+ (*x) = arc->xc + s * cos (arc->ang1 - arc->rotation) * sign;
+ (*y) = arc->yc - s * sin (arc->ang1 - arc->rotation);
+ (*phi) = atan2 (arc->yr * arc->yr * x1, arc->xr * arc->xr * y1) + arc->rotation;
+ if (-1 == sign) {
+ (*phi) += M_PI;
+ }
}
static void
-goc_arc_end (GocItem const *item, double x, double y)
+goc_arc_end (GocItem const *item, double *x, double *y, double *phi)
{
GocArc *arc = GOC_ARC (item);
double x1, y1, s;
-
+ double sign = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1.: 1.;
+
x1 = arc->xr * cos (atan2 (arc->xr / arc->yr * sin (arc->ang2), cos (arc->ang2)));
y1 = arc->yr * sin (atan2 (arc->xr / arc->yr * sin (arc->ang2), cos (arc->ang2)));
s = sqrt (x1 * x1 + y1 * y1);
+
+ (*x) = arc->xc + s * cos (arc->ang2 - arc->rotation) * sign;
+ (*y) = arc->yc - s * sin (arc->ang2 - arc->rotation);
+ (*phi) = atan2 (arc->yr * arc->yr * x1, arc->xr * arc->xr * y1) + arc->rotation + M_PI;
+ if (-1 == sign) {
+ (*phi) += M_PI;
+ }
+}
+
+static void
+prepare_draw_arrow (GocItem const *item, cairo_t *cr, gboolean end, gboolean flag)
+{
+ double w, x, y, phi;
+ GocArc *arc = GOC_ARC (item);
+ GOArrow arrow;
+ GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (item));
+ double sign = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1.: 1.;
+
+ w = style->line.width? style->line.width / 2.0: 0.5;
+
+ if (0 == end) {
+ arrow = arc->start_arrow;
+ goc_arc_start (item, &x, &y, &phi);
+ } else {
+ arrow = arc->end_arrow;
+ goc_arc_end (item, &x, &y, &phi);
+ }
+
+ cairo_save (cr);
+ if (1 == flag) {
+ goc_group_cairo_transform (item->parent, cr, arc->xc, arc->yc);
+ } else {
+ cairo_translate (cr, arc->xc, arc->yc);
+ }
- x = arc->xc + s * cos (arc->ang2 - arc->rotation);
- y = arc->yc - s * sin (arc->ang2 - arc->rotation);
+ switch (arrow.typ) {
+ case GO_ARROW_KITE:
+ cairo_save (cr);
+ cairo_translate (cr, x - arc->xc, y - arc->yc);
+ cairo_rotate (cr, phi * sign);
+ cairo_move_to (cr, -arrow.a, w);
+ cairo_line_to (cr, -arrow.b, w + arrow.c);
+ if (w > 0.5) {
+ cairo_line_to (cr, 0., w);
+ cairo_line_to (cr, 0., -w);
+ } else {
+ cairo_line_to (cr, 0., 0.);
+ }
+ cairo_line_to (cr, -arrow.b, -w - arrow.c);
+ cairo_line_to (cr, -arrow.a, -w);
+ cairo_close_path (cr);
+ cairo_restore (cr);
+ break;
+
+ case GO_ARROW_OVAL:
+ cairo_save (cr);
+ cairo_translate (cr, x - arc->xc, y - arc->yc);
+ cairo_rotate (cr, phi * sign);
+ cairo_scale (cr, arrow.a * sign, arrow.b);
+ cairo_move_to (cr, sign, 0.);
+ cairo_arc (cr, 0., 0., 1., 0., 2 * M_PI);
+ cairo_close_path (cr);
+ cairo_restore (cr);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ cairo_restore (cr);
}
-#endif
static gboolean
goc_arc_prepare_draw (GocItem const *item, cairo_t *cr, gboolean flag)
@@ -237,7 +275,7 @@ goc_arc_prepare_draw (GocItem const *item, cairo_t *cr, gboolean flag)
} else {
cairo_translate (cr, arc->xc, arc->yc);
}
- cairo_rotate (cr, arc->rotation);
+ cairo_rotate (cr, arc->rotation * sign);
ecc = arc->xr / arc->yr;
cairo_scale (cr, arc->xr * sign, arc->yr);
cairo_arc_negative (cr, 0., 0., 1., -atan2 (ecc * sin (arc->ang1), cos (arc->ang1)), -atan2 (ecc * sin (arc->ang2), cos (arc->ang2)));
@@ -246,6 +284,7 @@ goc_arc_prepare_draw (GocItem const *item, cairo_t *cr, gboolean flag)
if (arc->type > 0)
cairo_close_path (cr); // gives "Chord"
cairo_restore (cr);
+
return TRUE;
}
@@ -254,11 +293,16 @@ goc_arc_update_bounds (GocItem *item)
{
cairo_surface_t *surface;
cairo_t *cr;
+ GocArc *arc = GOC_ARC (item);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
cr = cairo_create (surface);
if (goc_arc_prepare_draw (item, cr, 0)) {
+ if (arc->start_arrow.typ != GO_ARROW_NONE)
+ prepare_draw_arrow (item, cr, 0, 0);
+ if (arc->end_arrow.typ != GO_ARROW_NONE)
+ prepare_draw_arrow (item, cr, 1, 0);
cairo_stroke_extents (cr, &item->x0, &item->y0, &item->x1, &item->y1);
}
@@ -287,16 +331,26 @@ goc_arc_distance (GocItem *item, double x, double y, GocItem **near_item)
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
cr = cairo_create (surface);
- if (goc_arc_prepare_draw (item, cr, 0)){
+ if (goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr) &&
+ (arc->start_arrow.typ != GO_ARROW_NONE || arc->end_arrow.typ != GO_ARROW_NONE)) {
+ if (arc->start_arrow.typ != GO_ARROW_NONE)
+ prepare_draw_arrow (item, cr, 0, 0);
+ if (arc->end_arrow.typ != GO_ARROW_NONE)
+ prepare_draw_arrow (item, cr, 1, 0);
+ if (cairo_in_fill (cr, x, y)) {
+ res = 0;
+ }
+ }
+
+ if (goc_arc_prepare_draw (item, cr, 0)) {
// Filled OR both fill and stroke are none
if ((arc->type > 0 && 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 && !goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr))) {
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 (goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr) && cairo_in_stroke (cr, x, y))
res = 0;
- }
}
cairo_destroy (cr);
@@ -305,62 +359,23 @@ goc_arc_distance (GocItem *item, double x, double y, GocItem **near_item)
return res;
}
-#if 0
static void
-draw_arrow (GOArrow const *arrow, cairo_t *cr, GOStyle *style,
- double *endx, double *endy, double phi)
+goc_arc_draw (GocItem const *item, cairo_t *cr)
{
- double l, w;
-
- if (arrow->typ == GO_ARROW_NONE)
- return;
-
- l = hypot (*endx, *endy);
- w = style->line.width ? style->line.width / 2.0 : 0.5;
-
- switch (arrow->typ) {
- case GO_ARROW_KITE:
- cairo_save (cr);
- cairo_translate (cr, (int) *endx, (int) *endy);
- cairo_rotate (cr, phi);
- cairo_move_to (cr, -arrow->a, w);
- cairo_line_to (cr, -arrow->b, w + arrow->c);
- cairo_line_to (cr, 0., 0.);
- cairo_line_to (cr, -arrow->b, -w - arrow->c);
- cairo_line_to (cr, -arrow->a, -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) -= arrow->a * *endx / l;
- (*endy) -= arrow->a * *endy / l;
- } else
- *endx = *endy = 0.;
- break;
+ GocArc *arc = GOC_ARC (item);
+
- case GO_ARROW_OVAL:
- cairo_save (cr);
- cairo_translate (cr, *endx, *endy);
- cairo_rotate (cr, phi);
- cairo_scale (cr, arrow->a, arrow->b);
- cairo_arc (cr, 0., 0., 1., 0., 2 * M_PI);
- cairo_set_source_rgba (cr, GO_COLOR_TO_CAIRO (style->line.color));
- cairo_fill (cr);
- cairo_restore (cr);
- break;
+ cairo_save(cr);
- default:
- g_assert_not_reached ();
+ if (go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr)) {
+ if (arc->start_arrow.typ != GO_ARROW_NONE)
+ prepare_draw_arrow (item, cr, 0, 1);
+ if (arc->end_arrow.typ != GO_ARROW_NONE)
+ prepare_draw_arrow (item, cr, 1, 1);
+ cairo_fill_preserve (cr);
+ cairo_stroke (cr);
}
-}
-#endif
-static void
-goc_arc_draw (GocItem const *item, cairo_t *cr)
-{
- GocArc *arc = GOC_ARC (item);
-
cairo_save(cr);
if (goc_arc_prepare_draw (item, cr, 1)) {
if (arc->type > 0 && go_styled_object_set_cairo_fill (GO_STYLED_OBJECT (item), cr))
diff --git a/goffice/canvas/goc-ellipse.c b/goffice/canvas/goc-ellipse.c
index f824682..ac8ac2b 100644
--- a/goffice/canvas/goc-ellipse.c
+++ b/goffice/canvas/goc-ellipse.c
@@ -122,7 +122,7 @@ goc_ellipse_prepare_draw (GocItem const *item, cairo_t *cr, gboolean flag)
} else {
cairo_translate (cr, ellipse->x + ellipse->width/2., ellipse->y + ellipse->height/2.);
}
- cairo_rotate (cr, ellipse->rotation);
+ 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);
cairo_restore (cr);
diff --git a/goffice/canvas/goc-rectangle.c b/goffice/canvas/goc-rectangle.c
index 6732b6e..c6f9ef6 100644
--- a/goffice/canvas/goc-rectangle.c
+++ b/goffice/canvas/goc-rectangle.c
@@ -111,7 +111,8 @@ static gboolean
goc_rectangle_prepare_draw (GocItem const *item, cairo_t *cr, gboolean flag)
{
GocRectangle *rect = GOC_RECTANGLE (item);
-
+ double sign = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1.: 1.;
+
if (0 == rect->width && 0 == rect->height)
return FALSE;
@@ -121,8 +122,8 @@ goc_rectangle_prepare_draw (GocItem const *item, cairo_t *cr, gboolean flag)
} else {
cairo_translate (cr, rect->x, rect->y);
}
- cairo_rotate (cr, rect->rotation);
- cairo_rectangle (cr, 0., 0., (int) rect->width, (int)rect->height);
+ cairo_rotate (cr, rect->rotation * sign);
+ cairo_rectangle (cr, 0., 0., (int) rect->width * sign, (int) rect->height);
cairo_restore (cr);
return TRUE;
}
diff --git a/goffice/canvas/goc-styled-item.c b/goffice/canvas/goc-styled-item.c
index a00c3d7..c596f92 100644
--- a/goffice/canvas/goc-styled-item.c
+++ b/goffice/canvas/goc-styled-item.c
@@ -223,6 +223,7 @@ goc_styled_item_apply_theme (GOStyledObject *gsi, GOStyle *style)
static void
goc_styled_item_style_changed (GOStyledObject *gsi)
{
+ goc_item_bounds_changed (GOC_ITEM (gsi));
g_signal_emit (G_OBJECT (gsi),
goc_styled_item_signals [STYLE_CHANGED], 0, GOC_STYLED_ITEM (gsi)->style);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]