[nautilus/rendering-cleanup: 6/15] [eel] Port the eel canvas to rendering-cleanup-next
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus/rendering-cleanup: 6/15] [eel] Port the eel canvas to rendering-cleanup-next
- Date: Sun, 26 Sep 2010 18:13:41 +0000 (UTC)
commit 004e7d1ac1824c00fb4e49deac2a057d4f95b45e
Author: Christian Persch <chpe gnome org>
Date: Thu Sep 16 15:04:00 2010 +0200
[eel] Port the eel canvas to rendering-cleanup-next
eel/eel-canvas-rect-ellipse.c | 24 +++-----
eel/eel-canvas.c | 129 ++++++++++++++++++++++++++++-------------
eel/eel-canvas.h | 4 +-
3 files changed, 99 insertions(+), 58 deletions(-)
---
diff --git a/eel/eel-canvas-rect-ellipse.c b/eel/eel-canvas-rect-ellipse.c
index 688e289..f88cf30 100644
--- a/eel/eel-canvas-rect-ellipse.c
+++ b/eel/eel-canvas-rect-ellipse.c
@@ -630,7 +630,7 @@ static void eel_canvas_rect_init (EelCanvasRect *rect);
static void eel_canvas_rect_finalize (GObject *object);
static void eel_canvas_rect_realize (EelCanvasItem *item);
-static void eel_canvas_rect_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose);
+static void eel_canvas_rect_draw (EelCanvasItem *item, cairo_t *cr, cairo_region_t *region);
static double eel_canvas_rect_point (EelCanvasItem *item, double x, double y, int cx, int cy,
EelCanvasItem **actual_item);
@@ -751,10 +751,9 @@ eel_canvas_set_source_color (cairo_t *cr,
#define DASH_ON 0.8
#define DASH_OFF 1.7
static void
-eel_canvas_rect_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose)
+eel_canvas_rect_draw (EelCanvasItem *item, cairo_t *cr, cairo_region_t *region)
{
EelCanvasRE *re;
- cairo_t *cr;
double x1, y1, x2, y2;
int cx1, cy1, cx2, cy2;
double i2w_dx, i2w_dy;
@@ -777,10 +776,8 @@ eel_canvas_rect_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose
if (cx2 <= cx1 || cy2 <= cy1 ) {
return;
}
-
- cr = gdk_cairo_create (drawable);
- gdk_cairo_region (cr, expose->region);
- cairo_clip (cr);
+
+ cairo_save (cr);
if (re->fill_set) {
eel_canvas_set_source_color (cr, re->fill_color);
@@ -812,7 +809,7 @@ eel_canvas_rect_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose
cairo_stroke (cr);
}
- cairo_destroy (cr);
+ cairo_restore (cr);
}
static double
@@ -1001,7 +998,7 @@ eel_canvas_rect_update (EelCanvasItem *item, double i2w_dx, double i2w_dy, gint
static void eel_canvas_ellipse_class_init (EelCanvasEllipseClass *klass);
-static void eel_canvas_ellipse_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose);
+static void eel_canvas_ellipse_draw (EelCanvasItem *item, cairo_t *cr, cairo_region_t *region);
static double eel_canvas_ellipse_point (EelCanvasItem *item, double x, double y, int cx, int cy,
EelCanvasItem **actual_item);
@@ -1047,12 +1044,11 @@ eel_canvas_ellipse_class_init (EelCanvasEllipseClass *klass)
}
static void
-eel_canvas_ellipse_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose)
+eel_canvas_ellipse_draw (EelCanvasItem *item, cairo_t *cr, cairo_region_t *region)
{
EelCanvasRE *re;
int x1, y1, x2, y2;
double i2w_dx, i2w_dy;
- cairo_t *cr;
re = EEL_CANVAS_RE (item);
@@ -1071,9 +1067,7 @@ eel_canvas_ellipse_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExp
re->y2 + i2w_dy,
&x2, &y2);
- cr = gdk_cairo_create (drawable);
- gdk_cairo_region (cr, expose->region);
- cairo_clip (cr);
+ cairo_save (cr);
cairo_save (cr);
cairo_translate (cr, (x1 + x2) / 2., (y1 + y2) / 2.);
@@ -1097,7 +1091,7 @@ eel_canvas_ellipse_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExp
cairo_stroke_preserve (cr);
}
- cairo_destroy (cr);
+ cairo_restore (cr);
}
static double
diff --git a/eel/eel-canvas.c b/eel/eel-canvas.c
index 87def99..eace07a 100644
--- a/eel/eel-canvas.c
+++ b/eel/eel-canvas.c
@@ -69,6 +69,7 @@
#include <gdk/gdkprivate.h>
#include <gtk/gtk.h>
#include <glib/gi18n-lib.h>
+#include <cairo/cairo-gobject.h>
#include "eel-canvas.h"
#include "eel-marshal.h"
@@ -1155,8 +1156,9 @@ static void eel_canvas_group_update (EelCanvasItem *item,
static void eel_canvas_group_unrealize (EelCanvasItem *item);
static void eel_canvas_group_map (EelCanvasItem *item);
static void eel_canvas_group_unmap (EelCanvasItem *item);
-static void eel_canvas_group_draw (EelCanvasItem *item, GdkDrawable *drawable,
- GdkEventExpose *expose);
+static void eel_canvas_group_draw (EelCanvasItem *item,
+ cairo_t *cr,
+ cairo_region_t *region);
static double eel_canvas_group_point (EelCanvasItem *item, double x, double y,
int cx, int cy,
EelCanvasItem **actual_item);
@@ -1468,8 +1470,9 @@ eel_canvas_group_unmap (EelCanvasItem *item)
/* Draw handler for canvas groups */
static void
-eel_canvas_group_draw (EelCanvasItem *item, GdkDrawable *drawable,
- GdkEventExpose *expose)
+eel_canvas_group_draw (EelCanvasItem *item,
+ cairo_t *cr,
+ cairo_region_t *region)
{
EelCanvasGroup *group;
GList *list;
@@ -1489,8 +1492,8 @@ eel_canvas_group_draw (EelCanvasItem *item, GdkDrawable *drawable,
child_rect.width = child->x2 - child->x1 + 1;
child_rect.height = child->y2 - child->y1 + 1;
- if (cairo_region_contains_rectangle (expose->region, &child_rect) != CAIRO_REGION_OVERLAP_OUT)
- (* EEL_CANVAS_ITEM_GET_CLASS (child)->draw) (child, drawable, expose);
+ if (cairo_region_contains_rectangle (region, &child_rect) != CAIRO_REGION_OVERLAP_OUT)
+ EEL_CANVAS_ITEM_GET_CLASS (child)->draw (child, cr, region);
}
}
}
@@ -1720,8 +1723,8 @@ static gint eel_canvas_button (GtkWidget *widget,
GdkEventButton *event);
static gint eel_canvas_motion (GtkWidget *widget,
GdkEventMotion *event);
-static gint eel_canvas_expose (GtkWidget *widget,
- GdkEventExpose *event);
+static gint eel_canvas_draw (GtkWidget *widget,
+ cairo_t *cr);
static gint eel_canvas_key (GtkWidget *widget,
GdkEventKey *event);
static gint eel_canvas_crossing (GtkWidget *widget,
@@ -1732,10 +1735,7 @@ static gint eel_canvas_focus_out (GtkWidget *widget,
GdkEventFocus *event);
static void eel_canvas_request_update_real (EelCanvas *canvas);
static void eel_canvas_draw_background (EelCanvas *canvas,
- int x,
- int y,
- int width,
- int height);
+ cairo_t *cr);
static GtkLayoutClass *canvas_parent_class;
@@ -2033,7 +2033,7 @@ eel_canvas_class_init (EelCanvasClass *klass)
widget_class->button_press_event = eel_canvas_button;
widget_class->button_release_event = eel_canvas_button;
widget_class->motion_notify_event = eel_canvas_motion;
- widget_class->expose_event = eel_canvas_expose;
+ widget_class->draw = eel_canvas_draw;
widget_class->key_press_event = eel_canvas_key;
widget_class->key_release_event = eel_canvas_key;
widget_class->enter_notify_event = eel_canvas_crossing;
@@ -2045,14 +2045,14 @@ eel_canvas_class_init (EelCanvasClass *klass)
klass->request_update = eel_canvas_request_update_real;
canvas_signals[DRAW_BACKGROUND] =
- g_signal_new ("draw_background",
+ g_signal_new ("draw-background",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (EelCanvasClass, draw_background),
NULL, NULL,
- eel_marshal_VOID__INT_INT_INT_INT,
- G_TYPE_NONE, 4,
- G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ CAIRO_GOBJECT_TYPE_CONTEXT);
atk_registry_set_factory_type (atk_get_default_registry (),
EEL_TYPE_CANVAS,
@@ -2859,18 +2859,67 @@ eel_canvas_focus_out (GtkWidget *widget, GdkEventFocus *event)
return FALSE;
}
+
+static cairo_region_t *
+eel_cairo_get_clip_region (cairo_t *cr)
+{
+ cairo_rectangle_list_t *list;
+ cairo_region_t *region;
+ int i;
+
+ list = cairo_copy_clip_rectangle_list (cr);
+ if (list->status == CAIRO_STATUS_CLIP_NOT_REPRESENTABLE) {
+ cairo_rectangle_int_t clip_rect;
+
+ cairo_rectangle_list_destroy (list);
+
+ if (!gdk_cairo_get_clip_rectangle (cr, &clip_rect))
+ return NULL;
+ return cairo_region_create_rectangle (&clip_rect);
+ }
+
+
+ region = cairo_region_create ();
+ for (i = list->num_rectangles - 1; i >= 0; --i) {
+ cairo_rectangle_t *rect = &list->rectangles[i];
+ cairo_rectangle_int_t clip_rect;
+
+ clip_rect.x = floor (rect->x);
+ clip_rect.y = floor (rect->y);
+ clip_rect.width = ceil (rect->x + rect->width) - clip_rect.x;
+ clip_rect.height = ceil (rect->y + rect->height) - clip_rect.y;
+
+ if (cairo_region_union_rectangle (region, &clip_rect) != CAIRO_STATUS_SUCCESS) {
+ cairo_region_destroy (region);
+ region = NULL;
+ break;
+ }
+ }
+
+ cairo_rectangle_list_destroy (list);
+ return region;
+}
+
/* Expose handler for the canvas */
-static gint
-eel_canvas_expose (GtkWidget *widget, GdkEventExpose *event)
+static gboolean
+eel_canvas_draw (GtkWidget *widget, cairo_t *cr)
{
- EelCanvas *canvas;
+ EelCanvas *canvas = EEL_CANVAS (widget);
+ GdkWindow *bin_window;
+ cairo_region_t *region;
- canvas = EEL_CANVAS (widget);
+ if (!gdk_cairo_get_clip_rectangle (cr, NULL))
+ return FALSE;
+
+ bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (widget));
+ gtk_cairo_transform_to_window (cr, widget, bin_window);
- if (!gtk_widget_is_drawable (widget) || (event->window != gtk_layout_get_bin_window (&canvas->layout))) return FALSE;
+ region = eel_cairo_get_clip_region (cr);
+ if (region == NULL)
+ return FALSE;
#ifdef VERBOSE
- g_print ("Expose\n");
+ g_print ("Draw\n");
#endif
/* If there are any outstanding items that need updating, do them now */
if (canvas->idle_id) {
@@ -2893,38 +2942,35 @@ eel_canvas_expose (GtkWidget *widget, GdkEventExpose *event)
/* Hmmm. Would like to queue antiexposes if the update marked
anything that is gonna get redrawn as invalid */
-
- g_signal_emit (G_OBJECT (canvas), canvas_signals[DRAW_BACKGROUND], 0,
- event->area.x, event->area.y,
- event->area.width, event->area.height);
+ g_signal_emit (G_OBJECT (canvas), canvas_signals[DRAW_BACKGROUND], 0,
+ cr);
if (canvas->root->flags & EEL_CANVAS_ITEM_MAPPED)
- (* EEL_CANVAS_ITEM_GET_CLASS (canvas->root)->draw) (canvas->root,
- gtk_layout_get_bin_window (&canvas->layout),
- event);
-
-
+ EEL_CANVAS_ITEM_GET_CLASS (canvas->root)->draw (canvas->root, cr, region);
/* Chain up to get exposes on child widgets */
- GTK_WIDGET_CLASS (canvas_parent_class)->expose_event (widget, event);
+ if (GTK_WIDGET_CLASS (canvas_parent_class)->draw)
+ GTK_WIDGET_CLASS (canvas_parent_class)->draw (widget, cr);
+ cairo_region_destroy (region);
return FALSE;
}
static void
eel_canvas_draw_background (EelCanvas *canvas,
- int x, int y, int width, int height)
+ cairo_t *cr)
{
- cairo_t *cr;
+ cairo_rectangle_int_t rect;
- cr = gdk_cairo_create (gtk_layout_get_bin_window (&canvas->layout));
+ if (!gdk_cairo_get_clip_rectangle (cr, &rect))
+ return;
+ cairo_save (cr);
/* By default, we use the style background. */
gdk_cairo_set_source_color (cr, >k_widget_get_style (GTK_WIDGET (canvas))->bg[GTK_STATE_NORMAL]);
- cairo_rectangle (cr, x, y, width, height);
+ gdk_cairo_rectangle (cr, &rect);
cairo_fill (cr);
-
- cairo_destroy (cr);
+ cairo_restore (cr);
}
static void
@@ -3180,14 +3226,15 @@ eel_canvas_set_pixels_per_unit (EelCanvas *canvas, double n)
attributes.height = allocation.height;
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.visual = gtk_widget_get_visual (widget);
- attributes.colormap = gtk_widget_get_colormap (widget);
attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK;
- attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+ attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
window = gdk_window_new (gtk_widget_get_parent_window (widget),
&attributes, attributes_mask);
+#if 0
gdk_window_set_back_pixmap (window, NULL, FALSE);
+#endif
gdk_window_set_user_data (window, widget);
gdk_window_show (window);
diff --git a/eel/eel-canvas.h b/eel/eel-canvas.h
index e66e440..e4ee745 100644
--- a/eel/eel-canvas.h
+++ b/eel/eel-canvas.h
@@ -151,7 +151,7 @@ struct _EelCanvasItemClass {
* coordinates of the drawable, a temporary pixmap, where things get
* drawn. (width, height) are the dimensions of the drawable.
*/
- void (* draw) (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose);
+ void (* draw) (EelCanvasItem *item, cairo_t *cr, cairo_region_t *region);
/* Calculate the distance from an item to the specified point. It also
* returns a canvas item which is the item itself in the case of the
@@ -420,7 +420,7 @@ struct _EelCanvasClass {
/* Draw the background for the area given.
*/
void (* draw_background) (EelCanvas *canvas,
- int x, int y, int width, int height);
+ cairo_t *cr);
/* Private Virtual methods for groping the canvas inside bonobo */
void (* request_update) (EelCanvas *canvas);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]