[goffice] New goc_canvas_invalidate_region().
- From: Jean Bréfort <jbrefort src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] New goc_canvas_invalidate_region().
- Date: Mon, 27 Oct 2014 15:26:15 +0000 (UTC)
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]