[goffice] GocItemArc: protect drawing against invalid arrow sizes.



commit 322e20822b7ffe12f18e201513ae15a1ce6153e1
Author: Morten Welinder <terra gnome org>
Date:   Wed Feb 11 11:36:49 2015 -0500

    GocItemArc: protect drawing against invalid arrow sizes.
    
    This code should be using go_arrow_draw.  We don't need multiple
    copies of this.

 ChangeLog                |    3 +++
 goffice/canvas/goc-arc.c |   33 +++++++++++++++++++--------------
 2 files changed, 22 insertions(+), 14 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index afc136c..2ac7b28 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2015-02-11  Morten Welinder  <terra gnome org>
 
+       * goffice/canvas/goc-arc.c (prepare_draw_arrow): Protect oval
+       drawing against invalid sizes.
+
        * goffice/canvas/goc-line.c (goc_line_draw): Avoid overflow.
        Round a bit more consistently.
        (draw_arrow): Use go_arrow_draw.
diff --git a/goffice/canvas/goc-arc.c b/goffice/canvas/goc-arc.c
index 8b3eee1..56e544a 100644
--- a/goffice/canvas/goc-arc.c
+++ b/goffice/canvas/goc-arc.c
@@ -201,19 +201,19 @@ prepare_draw_arrow (GocItem const *item, cairo_t *cr, gboolean end, gboolean fla
 {
        double w, x, y, phi;
        GocArc *arc = GOC_ARC (item);
-       GOArrow arrow;
+       GOArrow const *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.;
        double rsign = sign;
 
        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;
+       if (end) {
+               arrow = &arc->end_arrow;
                goc_arc_end (item, &x, &y, &phi);
+       } else {
+               arrow = &arc->start_arrow;
+               goc_arc_start (item, &x, &y, &phi);
        }
 
        cairo_save (cr);
@@ -225,21 +225,23 @@ prepare_draw_arrow (GocItem const *item, cairo_t *cr, gboolean end, gboolean fla
                rsign = 1;
        }
 
-       switch (arrow.typ) {
+#warning "FIXME: this should use go_arrow_draw"
+
+       switch (arrow->typ) {
        case GO_ARROW_KITE:
                cairo_save (cr);
                cairo_translate (cr, (x - arc->xc) * sign, y - arc->yc);
                cairo_rotate (cr, phi * rsign);
-               cairo_move_to (cr, -arrow.a * sign,  w);
-               cairo_line_to (cr, -arrow.b * sign, w + arrow.c);
+               cairo_move_to (cr, -arrow->a * sign,  w);
+               cairo_line_to (cr, -arrow->b * sign, 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 * sign, -w - arrow.c);
-               cairo_line_to (cr, -arrow.a * sign, -w);
+               cairo_line_to (cr, -arrow->b * sign, -w - arrow->c);
+               cairo_line_to (cr, -arrow->a * sign, -w);
                cairo_close_path (cr);
                cairo_restore (cr);
                break;
@@ -248,9 +250,12 @@ prepare_draw_arrow (GocItem const *item, cairo_t *cr, gboolean end, gboolean fla
                cairo_save (cr);
                cairo_translate (cr, (x - arc->xc) * sign, y - arc->yc);
                cairo_rotate (cr, phi * rsign);
-               cairo_scale (cr, arrow.a * sign, arrow.b);
-               cairo_move_to (cr, 0., 0.);
-               cairo_arc (cr, 0., 0., 1., 0., 2 * M_PI);
+               if (arrow->a > 0 && arrow->b > 0) {
+                       cairo_scale (cr, arrow->a * sign, arrow->b);
+                       cairo_move_to (cr, 0., 0.);
+                       cairo_arc (cr, 0., 0., 1., 0., 2 * M_PI);
+               } else
+                       cairo_move_to (cr, 0., 0.);
                cairo_close_path (cr);
                cairo_restore (cr);
                break;


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