[goffice] New goc_canvas_invalidate_region().



commit 5d5ac371ff56c05f41cd9799fe5c78c2e6c1ccc5
Author: Jean Brefort <jean brefort normalesup org>
Date:   Mon Oct 27 16:25:38 2014 +0100

    New goc_canvas_invalidate_region().

 ChangeLog                                |    7 ++
 docs/reference/goffice-0.10-sections.txt |    5 ++
 goffice/canvas/goc-canvas.c              |  105 +++++++++++++++++++++++++----
 goffice/canvas/goc-canvas.h              |    1 +
 goffice/math/go-dtoa.c                   |    2 +-
 goffice/utils/go-emf.c                   |    2 +-
 goffice/utils/go-unit.h                  |    2 +-
 7 files changed, 106 insertions(+), 18 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 14f2547..08375fc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2014-10-27  Jean Brefort  <jean brefort normalesup org>
+
+       * goffice/canvas/goc-canvas.c (goc_canvas_draw),
+       (goc_canvas_finalize), (goc_canvas_init), (goc_canvas_invalidate),
+       (goc_canvas_invalidate_region): add new goc_canvas_invalidate_region().
+       * goffice/canvas/goc-canvas.h: ditto.
+
 2014-09-27  Morten Welinder  <terra gnome org>
 
        * goffice/gtk/go-combo-box.c (cb_state_flags_change): Don't use
diff --git a/docs/reference/goffice-0.10-sections.txt b/docs/reference/goffice-0.10-sections.txt
index 7a82891..286fd6f 100644
--- a/docs/reference/goffice-0.10-sections.txt
+++ b/docs/reference/goffice-0.10-sections.txt
@@ -1944,6 +1944,8 @@ go_tanpil
 <SUBSECTION Private>
 GOQuad
 GOQuadl
+GOQuad_
+GOQuadl_
 </SECTION>
 
 <SECTION>
@@ -1978,6 +1980,8 @@ go_quad_matrix_transposel
 <SUBSECTION Private>
 GOQuadMatrix
 GOQuadMatrixl
+GOQuadMatrix_
+GOQuadMatrixl_
 </SECTION>
 
 <SECTION>
@@ -2381,6 +2385,7 @@ goc_canvas_get_scroll_position
 goc_canvas_get_width
 goc_canvas_grab_item
 goc_canvas_invalidate
+goc_canvas_invalidate_region
 goc_canvas_render
 goc_canvas_scroll_to
 goc_canvas_set_direction
diff --git a/goffice/canvas/goc-canvas.c b/goffice/canvas/goc-canvas.c
index b8a6379..03acc86 100644
--- a/goffice/canvas/goc-canvas.c
+++ b/goffice/canvas/goc-canvas.c
@@ -24,6 +24,12 @@
 #include <gsf/gsf-impl-utils.h>
 #include <math.h>
 
+typedef struct {
+        GocItem *invalidated_item;
+        cairo_region_t *invalid_region;
+        gboolean done;
+ } GocCanvasPrivate;
+
 /**
  * SECTION: goc-canvas
  * @short_description: The canvas widget
@@ -51,23 +57,59 @@ goc_canvas_draw (GtkWidget *widget, cairo_t *cr)
        double clip_x1, clip_y1, clip_x2, clip_y2;
        GocCanvas *canvas = GOC_CANVAS (widget);
        GdkEventExpose *event = (GdkEventExpose *) gtk_get_current_event ();
-
-       cairo_clip_extents (cr, &clip_x1, &clip_y1, &clip_x2, &clip_y2);
-
-       goc_item_get_bounds (GOC_ITEM (canvas->root),&x0, &y0, &x1, &y1);
-       if (canvas->direction == GOC_DIRECTION_RTL) {
-               ax1 = (double) (canvas->width - clip_x1) / canvas->pixels_per_unit + canvas->scroll_x1;
-               ax0 = (double) (canvas->width - clip_x2) / canvas->pixels_per_unit + canvas->scroll_x1;
-       } else {
-               ax0 = (double) clip_x1 / canvas->pixels_per_unit + canvas->scroll_x1;
-               ax1 = ((double) clip_x1 + event->area.width) / canvas->pixels_per_unit + canvas->scroll_x1;
+       GocCanvasPrivate *priv = (GocCanvasPrivate *) canvas->priv;
+       cairo_rectangle_list_t *l = cairo_copy_clip_rectangle_list (cr);
+       int i;
+
+       if (GOC_IS_ITEM (priv->invalidated_item) && priv->invalid_region) {
+               /* evaluate the cairo clipped region and compare with the saved one */
+               cairo_region_t *region;
+               cairo_rectangle_int_t rect[l->num_rectangles];
+           for (i= 0; i  < l->num_rectangles; i++) {
+                       rect[i].x = l->rectangles[i].x;
+                       rect[i].y = l->rectangles[i].y;
+                       rect[i].width = l->rectangles[i].width;
+                       rect[i].height = l->rectangles[i].height;
+               }
+               region = cairo_region_create_rectangles (rect, l->num_rectangles);
+               if (cairo_region_equal (priv->invalid_region, region)) {
+                       cairo_rectangle_list_destroy (l);
+                       cairo_region_destroy (region);
+                       /* looks like each time we call gtk_widget_queue_draw*,
+                          the draw event is fired twice */
+                       if (priv->done) {
+                               priv->invalidated_item = NULL;
+                               cairo_region_destroy (priv->invalid_region);
+                               priv->invalid_region = NULL;
+                       } else {
+                               goc_item_draw (priv->invalidated_item, cr);
+                               priv->done = TRUE;
+                       }
+                       return TRUE;
+               }
        }
-       ay0 = (double) clip_y1 / canvas->pixels_per_unit + canvas->scroll_y1;
-       ay1 = (double) clip_y2 / canvas->pixels_per_unit + canvas->scroll_y1;
-       if (x0 <= ax1 && x1 >= ax0 && y0 <= ay1 && y1 >= ay0) {
-               canvas->cur_event = (GdkEvent *) event;
-               goc_item_draw_region (GOC_ITEM (canvas->root), cr, ax0, ay0, ax1, ay1);
+       goc_item_get_bounds (GOC_ITEM (canvas->root),&x0, &y0, &x1, &y1);
+    for (i= 0; i  < l->num_rectangles; i++) {
+               clip_x1 = l->rectangles[i].x;
+               clip_y1 = l->rectangles[i].y;
+               clip_x2 = clip_x1 + l->rectangles[i].width;
+               clip_y2 = clip_y1 + l->rectangles[i].height;
+
+               if (canvas->direction == GOC_DIRECTION_RTL) {
+                       ax1 = (double) (canvas->width - clip_x1) / canvas->pixels_per_unit + 
canvas->scroll_x1;
+                       ax0 = (double) (canvas->width - clip_x2) / canvas->pixels_per_unit + 
canvas->scroll_x1;
+               } else {
+                       ax0 = (double) clip_x1 / canvas->pixels_per_unit + canvas->scroll_x1;
+                       ax1 = ((double) clip_x1 + event->area.width) / canvas->pixels_per_unit + 
canvas->scroll_x1;
+               }
+               ay0 = (double) clip_y1 / canvas->pixels_per_unit + canvas->scroll_y1;
+               ay1 = (double) clip_y2 / canvas->pixels_per_unit + canvas->scroll_y1;
+               if (x0 <= ax1 && x1 >= ax0 && y0 <= ay1 && y1 >= ay0) {
+                       canvas->cur_event = (GdkEvent *) event;
+                       goc_item_draw_region (GOC_ITEM (canvas->root), cr, ax0, ay0, ax1, ay1);
+               }
        }
+       cairo_rectangle_list_destroy (l);
        return TRUE;
 }
 
@@ -248,7 +290,11 @@ static void
 goc_canvas_finalize (GObject *obj)
 {
        GocCanvas *canvas = GOC_CANVAS (obj);
+       GocCanvasPrivate *priv = (GocCanvasPrivate *) canvas->priv;
        g_object_unref (canvas->root);
+       if (priv->invalid_region != NULL)
+               cairo_region_destroy (priv->invalid_region);
+       g_free (canvas->priv);
        parent_klass->finalize (obj);
 }
 
@@ -288,6 +334,7 @@ goc_canvas_init (GocCanvas *canvas)
        canvas->root = GOC_GROUP (g_object_new (GOC_TYPE_GROUP, NULL));
        canvas->root->base.canvas = canvas;
        canvas->pixels_per_unit = 1.;
+       canvas->priv = g_new0 (GocCanvasPrivate, 1);
 #ifdef GOFFICE_WITH_GTK
        gtk_widget_add_events (w,
                               GDK_POINTER_MOTION_MASK |
@@ -489,6 +536,34 @@ goc_canvas_invalidate (GocCanvas *canvas, double x0, double y0, double x1, doubl
 #endif
 }
 
+
+/**
+ * goc_canvas_invalidate_region:
+ * @canvas: #GocCanvas
+ * @item: the item to redraw
+ * @region: the region to redraw
+ *
+ * Invalidates a region of the canvas. Only @item will be redrawn if the next
+ * draw event is called with a cairo contest clipped to @region. Used in
+ * gnumeric for the walking ants cursor.
+ **/
+void
+goc_canvas_invalidate_region (GocCanvas *canvas, GocItem *item, cairo_region_t *region)
+{
+       GocCanvasPrivate *priv;
+
+       g_return_if_fail (GOC_IS_CANVAS (canvas));
+       g_return_if_fail (item && region);
+
+       priv = (GocCanvasPrivate *) canvas->priv;
+       if (priv->invalid_region != NULL)
+               cairo_region_destroy (priv->invalid_region);
+       priv->invalidated_item = item;
+       priv->invalid_region = cairo_region_reference (region);
+       priv->done = FALSE;
+       gtk_widget_queue_draw_region (GTK_WIDGET (canvas), region);
+}
+
 /**
  * goc_canvas_get_realized:
  * @canvas: #GocCanvas
diff --git a/goffice/canvas/goc-canvas.h b/goffice/canvas/goc-canvas.h
index 86ce4cd..41f205e 100644
--- a/goffice/canvas/goc-canvas.h
+++ b/goffice/canvas/goc-canvas.h
@@ -75,6 +75,7 @@ void           goc_canvas_get_scroll_position (GocCanvas *canvas, double *x, double *y);
 void            goc_canvas_set_pixels_per_unit (GocCanvas *canvas, double pixels_per_unit);
 double          goc_canvas_get_pixels_per_unit (GocCanvas *canvas);
 void            goc_canvas_invalidate (GocCanvas *canvas, double x0, double y0, double x1, double y1);
+void            goc_canvas_invalidate_region (GocCanvas *canvas, GocItem *item, cairo_region_t *region);
 gboolean         goc_canvas_get_realized (GocCanvas *canvas);
 GocItem                *goc_canvas_get_item_at (GocCanvas *canvas, double x, double y);
 void            goc_canvas_grab_item (GocCanvas *canvas, GocItem *item);
diff --git a/goffice/math/go-dtoa.c b/goffice/math/go-dtoa.c
index 579ad38..c5451b7 100644
--- a/goffice/math/go-dtoa.c
+++ b/goffice/math/go-dtoa.c
@@ -316,7 +316,7 @@ static int fmt_fp(FAKE_FILE *f, long double y, int w, int p, int fl, int t)
                if (z>d+1) z=d+1;
        }
        for (; z>a && !z[-1]; z--);
-       
+
        if ((t|32)=='g') {
                if (!p) p++;
                if (p>e && e>=-4) {
diff --git a/goffice/utils/go-emf.c b/goffice/utils/go-emf.c
index 76dce7d..6b7f15b 100644
--- a/goffice/utils/go-emf.c
+++ b/goffice/utils/go-emf.c
@@ -3334,7 +3334,7 @@ go_emf_selectobject (GOEmfState *state)
                        if (state->curDC->font != NULL)
                                go_font_unref (state->curDC->font);
                        state->curDC->font = go_font_new_by_desc (desc);
-                       rotation = (double) font->escape / 10.; 
+                       rotation = (double) font->escape / 10.;
                        if (rotation < 0.)
                                rotation += 360.;
                        state->curDC->text_rotation = (360. - rotation) / 180. * M_PI;
diff --git a/goffice/utils/go-unit.h b/goffice/utils/go-unit.h
index 54c9e47..9f8ef5f 100644
--- a/goffice/utils/go-unit.h
+++ b/goffice/utils/go-unit.h
@@ -29,7 +29,7 @@ G_BEGIN_DECLS
 typedef struct _GoUnit GoUnit;
 
 typedef enum  {
-       GO_UNIT_UNKNOWN = -1,   
+       GO_UNIT_UNKNOWN = -1,
        GO_UNIT_METER,
        GO_UNIT_CENTIMETER,
        GO_UNIT_INCH,


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