[dia] [cairo] Prepare pixmap free version of interactive renderer



commit ec5569018b14a93365b12f018e431d767bbe3d6d
Author: Hans Breuer <hans breuer org>
Date:   Sat Jun 23 15:21:58 2012 +0200

    [cairo] Prepare pixmap free version of interactive renderer
    
    With GTK+3.0 there wont be GdkPixmap anymore. The pixmap free version
    does work with gtk-2-2x, but it seems to be slightly slower.

 plug-ins/cairo/diacairo-interactive.c |   86 +++++++++++++++++++++++++++-----
 1 files changed, 72 insertions(+), 14 deletions(-)
---
diff --git a/plug-ins/cairo/diacairo-interactive.c b/plug-ins/cairo/diacairo-interactive.c
index 907aba1..132fd61 100644
--- a/plug-ins/cairo/diacairo-interactive.c
+++ b/plug-ins/cairo/diacairo-interactive.c
@@ -31,6 +31,15 @@
 #include "object.h"
 #include "textline.h"
 
+/* There is a variant prepared for GTK+3 
+ * but it seems to be sligly slower than the original version.
+ */
+#if GTK_CHECK_VERSION(3,0,0)
+#define DIA_CAIRO_WITH_PIXMAP 0
+#else
+#define DIA_CAIRO_WITH_PIXMAP 1
+#endif
+
 #define DIA_TYPE_CAIRO_INTERACTIVE_RENDERER           (dia_cairo_interactive_renderer_get_type ())
 #define DIA_CAIRO_INTERACTIVE_RENDERER(obj)           (G_TYPE_CHECK_INSTANCE_CAST ((obj), DIA_TYPE_CAIRO_INTERACTIVE_RENDERER, DiaCairoInteractiveRenderer))
 #define DIA_CAIRO_INTERACTIVE_RENDERER_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST ((klass), DIA_TYPE_CAIRO_INTERACTIVE_RENDERER, DiaCairoInteractiveRendererClass))
@@ -50,10 +59,14 @@ struct _DiaCairoInteractiveRenderer
   Rectangle *visible;
   real *zoom_factor;
 
+#if DIA_CAIRO_WITH_PIXMAP
   GdkPixmap *pixmap;              /* The pixmap shown in this display  */
+  GdkGC *gc;
+#else
+  cairo_surface_t *pixmap;        /* The pixmap shown in this display  */
+#endif
   guint32 width;                  /* The width of the pixmap in pixels */
   guint32 height;                 /* The height of the pixmap in pixels */
-  GdkGC *gc;
   GdkRegion *clip_region;
 
   /** If non-NULL, this rendering is a highlighting with the given color. */
@@ -140,11 +153,16 @@ cairo_interactive_renderer_init (DiaCairoInteractiveRenderer *object, void *p)
 static void
 cairo_interactive_renderer_finalize (GObject *object)
 {
-  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (object);
-
-  if (renderer->cr)
-    cairo_destroy (renderer->cr);
+  DiaCairoInteractiveRenderer *renderer = DIA_CAIRO_INTERACTIVE_RENDERER (object);
+  DiaCairoRenderer *base_renderer = DIA_CAIRO_RENDERER (object);
 
+  if (base_renderer->cr)
+    cairo_destroy (base_renderer->cr);
+  base_renderer->cr = NULL;
+#if !DIA_CAIRO_WITH_PIXMAP
+  if (renderer->pixmap)
+    cairo_surface_destroy (renderer->pixmap);
+#endif
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -316,13 +334,17 @@ dia_cairo_interactive_renderer_get_type (void)
 }
 
 static void
-begin_render(DiaRenderer *self)
+begin_render(DiaRenderer *self, const Rectangle *update)
 {
   DiaCairoInteractiveRenderer *renderer = DIA_CAIRO_INTERACTIVE_RENDERER (self);
   DiaCairoRenderer *base_renderer = DIA_CAIRO_RENDERER (self);
 
   g_return_if_fail (base_renderer->cr == NULL);
+#if DIA_CAIRO_WITH_PIXMAP
   base_renderer->cr = gdk_cairo_create(renderer->pixmap);
+#else
+  base_renderer->cr = cairo_create(renderer->pixmap);
+#endif
 
   /* Setup clipping for this sequence of render operations */
   /* Must be done before the scaling because the clip is in pixel coords */
@@ -332,13 +354,20 @@ begin_render(DiaRenderer *self)
   cairo_scale (base_renderer->cr, *renderer->zoom_factor, *renderer->zoom_factor);
   cairo_translate (base_renderer->cr, -renderer->visible->left, -renderer->visible->top);
 
+  /* second clipping */
+  if (update) {
+    real width = update->right - update->left;
+    real height = update->bottom - update->top;
+    cairo_rectangle (base_renderer->cr, update->left, update->top, width, height);
+    cairo_clip (base_renderer->cr);
+  }
 #ifdef HAVE_PANGOCAIRO_H
   base_renderer->layout = pango_cairo_create_layout (base_renderer->cr);
 #endif
 
   cairo_set_fill_rule (base_renderer->cr, CAIRO_FILL_RULE_EVEN_ODD);
 
-#if 0
+#if !DIA_CAIRO_WITH_PIXMAP
   /* should we set the background color? Or do nothing at all? */
   /* if this is drawn you can see 'clipping in action', outside of the clip it gets yellow ;) */
   cairo_set_source_rgba (base_renderer->cr, 1.0, 1.0, .8, 1.0);
@@ -445,21 +474,36 @@ set_size(DiaRenderer *object, gpointer window,
 {
   DiaCairoInteractiveRenderer *renderer = DIA_CAIRO_INTERACTIVE_RENDERER (object);
   DiaCairoRenderer *base_renderer = DIA_CAIRO_RENDERER (object);
+  cairo_rectangle_t extents;
 
   renderer->width = width;
   renderer->height = height;
+#if DIA_CAIRO_WITH_PIXMAP
   if (renderer->pixmap != NULL)
     g_object_unref(renderer->pixmap);
 
   /* TODO: we can probably get rid of this extra pixmap and just draw directly to what gdk_cairo_create() gives us for the window */
   renderer->pixmap = gdk_pixmap_new(GDK_WINDOW(window),  width, height, -1);
+#else
+# if GTK_CHECK_VERSION(2,22,0)
+  renderer->pixmap = gdk_window_create_similar_surface (GDK_WINDOW (window),
+							CAIRO_CONTENT_COLOR,
+							width, height);
+# else
+  extents.x = 0;
+  extents.y = 0;
+  extents.width = width;
+  extents.height = height;
+  renderer->pixmap = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA, &extents);
+# endif
+#endif
 
   if (base_renderer->surface != NULL)
     cairo_surface_destroy(base_renderer->surface);
-
-  if (renderer->gc == NULL) {
+#if DIA_CAIRO_WITH_PIXMAP
+  if (renderer->gc == NULL)
     renderer->gc = gdk_gc_new(renderer->pixmap);
-  }
+#endif
 }
 
 static void
@@ -467,6 +511,7 @@ copy_to_window (DiaRenderer *object, gpointer window,
                 int x, int y, int width, int height)
 {
   DiaCairoInteractiveRenderer *renderer = DIA_CAIRO_INTERACTIVE_RENDERER (object);
+#if DIA_CAIRO_WITH_PIXMAP
   static GdkGC *copy_gc = NULL;
   
   if (!copy_gc)
@@ -478,6 +523,16 @@ copy_to_window (DiaRenderer *object, gpointer window,
                      x, y,
                      x, y,
                      width > 0 ? width : -width, height > 0 ? height : -height);
+#else
+  cairo_t *cr;
+
+  cr = gdk_cairo_create (GDK_WINDOW(window));
+  cairo_set_source_surface (cr, renderer->pixmap, 0.0, 0.0);
+  cairo_rectangle (cr, x, y, width > 0 ? width : -width, height > 0 ? height : -height);
+  cairo_clip (cr);
+  cairo_paint (cr);
+  cairo_destroy (cr);
+#endif
 }
 
 static void
@@ -489,8 +544,9 @@ clip_region_clear(DiaRenderer *object)
     gdk_region_destroy(renderer->clip_region);
 
   renderer->clip_region =  gdk_region_new();
-
+#if DIA_CAIRO_WITH_PIXMAP
   gdk_gc_set_clip_region(renderer->gc, renderer->clip_region);
+#endif
 }
 
 static void
@@ -514,9 +570,10 @@ clip_region_add_rect(DiaRenderer *object,
   clip_rect.width = x2 - x1 + 1;
   clip_rect.height = y2 - y1 + 1;
 
-  gdk_region_union_with_rect( renderer->clip_region, &clip_rect );
-  
+  gdk_region_union_with_rect(renderer->clip_region, &clip_rect);
+#if DIA_CAIRO_WITH_PIXMAP
   gdk_gc_set_clip_region(renderer->gc, renderer->clip_region);
+#endif
 }
 
 static void
@@ -570,7 +627,8 @@ fill_pixel_rect(DiaRenderer *object,
 		int width, int height,
 		Color *color)
 {
-#if 1 /* if we do it with cairo there is something wrong with the clipping? */
+#if DIA_CAIRO_WITH_PIXMAP
+  /* if we do it with cairo there is something wrong with the clipping? */
   DiaCairoInteractiveRenderer *renderer = DIA_CAIRO_INTERACTIVE_RENDERER (object);
   GdkGC *gc = renderer->gc;
   GdkColor gdkcolor;



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