From 61ca4f71a04c3b3ac1b70af125c51e286830b0cf Mon Sep 17 00:00:00 2001 From: Sven Herzberg Date: Sun, 20 Jul 2008 16:14:35 +0000 Subject: [PATCH] reviewed by: Richard Hult 2008-07-20 Sven Herzberg reviewed by: Richard Hult Extracted the CGContextRef creation into a virtual function of GdkDrawableImplQuartz; implement get_context() for GdkPixmap and GdkWindow * gdk/quartz/gdkdrawable-quartz.c (gdk_quartz_drawable_get_context): dropped the different implementations; forward to the virtual function now * gdk/quartz/gdkdrawable-quartz.h: added the virtual function * gdk/quartz/gdkpixmap-quartz.c (gdk_pixmap_impl_quartz_get_context), (gdk_pixmap_impl_quartz_class_init): implemented get_context() * gdk/quartz/gdkwindow-quartz.c (gdk_window_impl_quartz_get_context), (gdk_window_impl_quartz_class_init): implemented get_context() svn path=/trunk/; revision=20869 --- ChangeLog | 19 ++++++++ gdk/quartz/gdkdrawable-quartz.c | 82 +++------------------------------ gdk/quartz/gdkdrawable-quartz.h | 6 ++- gdk/quartz/gdkpixmap-quartz.c | 22 +++++++++ gdk/quartz/gdkwindow-quartz.c | 64 +++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 77 deletions(-) diff --git a/ChangeLog b/ChangeLog index 08952dfe3e..cf0a1f4c11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2008-07-20 Sven Herzberg + + reviewed by: Richard Hult + + Extracted the CGContextRef creation into a virtual function of + GdkDrawableImplQuartz; implement get_context() for GdkPixmap and + GdkWindow + + * gdk/quartz/gdkdrawable-quartz.c + (gdk_quartz_drawable_get_context): dropped the different + implementations; forward to the virtual function now + * gdk/quartz/gdkdrawable-quartz.h: added the virtual function + * gdk/quartz/gdkpixmap-quartz.c + (gdk_pixmap_impl_quartz_get_context), + (gdk_pixmap_impl_quartz_class_init): implemented get_context() + * gdk/quartz/gdkwindow-quartz.c + (gdk_window_impl_quartz_get_context), + (gdk_window_impl_quartz_class_init): implemented get_context() + 2007-08-19 Matthias Clasen * NEWS: Updates diff --git a/gdk/quartz/gdkdrawable-quartz.c b/gdk/quartz/gdkdrawable-quartz.c index b769773bd2..abf2916fc9 100644 --- a/gdk/quartz/gdkdrawable-quartz.c +++ b/gdk/quartz/gdkdrawable-quartz.c @@ -664,88 +664,18 @@ gdk_drawable_impl_quartz_get_type (void) return object_type; } -CGContextRef +CGContextRef gdk_quartz_drawable_get_context (GdkDrawable *drawable, gboolean antialias) { - GdkDrawableImplQuartz *drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable); - CGContextRef cg_context; - - if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable) && - GDK_WINDOW_DESTROYED (drawable_impl->wrapper)) - return NULL; - - if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable)) + if (!GDK_DRAWABLE_IMPL_QUARTZ_GET_CLASS (drawable)->get_context) { - GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (drawable); - - /* Lock focus when not called as part of a drawRect call. This - * is needed when called from outside "real" expose events, for - * example for synthesized expose events when realizing windows - * and for widgets that send fake expose events like the arrow - * buttons in spinbuttons. - */ - if (window_impl->in_paint_rect_count == 0) - { - if (![window_impl->view lockFocusIfCanDraw]) - return NULL; - } - - cg_context = [[NSGraphicsContext currentContext] graphicsPort]; - CGContextSaveGState (cg_context); - CGContextSetAllowsAntialiasing (cg_context, antialias); - - /* We'll emulate the clipping caused by double buffering here */ - if (window_impl->begin_paint_count != 0) - { - CGRect rect; - CGRect *cg_rects; - GdkRectangle *rects; - gint n_rects, i; - - gdk_region_get_rectangles (window_impl->paint_clip_region, - &rects, &n_rects); - - if (n_rects == 1) - cg_rects = ▭ - else - cg_rects = g_new (CGRect, n_rects); - - for (i = 0; i < n_rects; i++) - { - cg_rects[i].origin.x = rects[i].x; - cg_rects[i].origin.y = rects[i].y; - cg_rects[i].size.width = rects[i].width; - cg_rects[i].size.height = rects[i].height; - } - - CGContextClipToRects (cg_context, cg_rects, n_rects); - - g_free (rects); - if (cg_rects != &rect) - g_free (cg_rects); - } - } - else if (GDK_IS_PIXMAP_IMPL_QUARTZ (drawable)) - { - GdkPixmapImplQuartz *impl = GDK_PIXMAP_IMPL_QUARTZ (drawable); - - cg_context = CGBitmapContextCreate (impl->data, - CGImageGetWidth (impl->image), - CGImageGetHeight (impl->image), - CGImageGetBitsPerComponent (impl->image), - CGImageGetBytesPerRow (impl->image), - CGImageGetColorSpace (impl->image), - CGImageGetBitmapInfo (impl->image)); - CGContextSetAllowsAntialiasing (cg_context, antialias); - } - else - { - g_warning ("Tried to create CGContext for something not a quartz window or pixmap"); - cg_context = NULL; + g_warning ("%s doesn't implement GdkDrawableImplQuartzClass::get_context()", + G_OBJECT_TYPE_NAME (drawable)); + return NULL; } - return cg_context; + return GDK_DRAWABLE_IMPL_QUARTZ_GET_CLASS (drawable)->get_context (drawable, antialias); } void diff --git a/gdk/quartz/gdkdrawable-quartz.h b/gdk/quartz/gdkdrawable-quartz.h index f10441ff8e..1e5c8e8f4f 100644 --- a/gdk/quartz/gdkdrawable-quartz.h +++ b/gdk/quartz/gdkdrawable-quartz.h @@ -49,9 +49,13 @@ struct _GdkDrawableImplQuartz cairo_surface_t *cairo_surface; }; -struct _GdkDrawableImplQuartzClass +struct _GdkDrawableImplQuartzClass { GdkDrawableClass parent_class; + + /* vtable */ + CGContextRef (*get_context) (GdkDrawable* drawable, + gboolean antialias); }; GType gdk_drawable_impl_quartz_get_type (void); diff --git a/gdk/quartz/gdkpixmap-quartz.c b/gdk/quartz/gdkpixmap-quartz.c index 73b7ddef6a..62f0418461 100644 --- a/gdk/quartz/gdkpixmap-quartz.c +++ b/gdk/quartz/gdkpixmap-quartz.c @@ -41,6 +41,25 @@ gdk_pixmap_impl_quartz_get_size (GdkDrawable *drawable, *height = GDK_PIXMAP_IMPL_QUARTZ (drawable)->height; } +static CGContextRef +gdk_pixmap_impl_quartz_get_context (GdkDrawable *drawable, + gboolean antialias) +{ + GdkPixmapImplQuartz *impl = GDK_PIXMAP_IMPL_QUARTZ (drawable); + CGContextRef cg_context; + + cg_context = CGBitmapContextCreate (impl->data, + CGImageGetWidth (impl->image), + CGImageGetHeight (impl->image), + CGImageGetBitsPerComponent (impl->image), + CGImageGetBytesPerRow (impl->image), + CGImageGetColorSpace (impl->image), + CGImageGetBitmapInfo (impl->image)); + CGContextSetAllowsAntialiasing (cg_context, antialias); + + return cg_context; +} + static void gdk_pixmap_impl_quartz_finalize (GObject *object) { @@ -58,12 +77,15 @@ gdk_pixmap_impl_quartz_class_init (GdkPixmapImplQuartzClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass); + GdkDrawableImplQuartzClass *drawable_quartz_class = GDK_DRAWABLE_IMPL_QUARTZ_CLASS (klass); parent_class = g_type_class_peek_parent (klass); object_class->finalize = gdk_pixmap_impl_quartz_finalize; drawable_class->get_size = gdk_pixmap_impl_quartz_get_size; + + drawable_quartz_class->get_context = gdk_pixmap_impl_quartz_get_context; } GType diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c index f19c52e667..551212ebfe 100644 --- a/gdk/quartz/gdkwindow-quartz.c +++ b/gdk/quartz/gdkwindow-quartz.c @@ -89,6 +89,67 @@ gdk_window_impl_quartz_get_size (GdkDrawable *drawable, *height = GDK_WINDOW_IMPL_QUARTZ (drawable)->height; } +static CGContextRef +gdk_window_impl_quartz_get_context (GdkDrawable *drawable, + gboolean antialias) +{ + GdkDrawableImplQuartz *drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable); + GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (drawable); + CGContextRef cg_context; + + if (GDK_WINDOW_DESTROYED (drawable_impl->wrapper)) + return NULL; + + /* Lock focus when not called as part of a drawRect call. This + * is needed when called from outside "real" expose events, for + * example for synthesized expose events when realizing windows + * and for widgets that send fake expose events like the arrow + * buttons in spinbuttons. + */ + if (window_impl->in_paint_rect_count == 0) + { + if (![window_impl->view lockFocusIfCanDraw]) + return NULL; + } + + cg_context = [[NSGraphicsContext currentContext] graphicsPort]; + CGContextSaveGState (cg_context); + CGContextSetAllowsAntialiasing (cg_context, antialias); + + /* We'll emulate the clipping caused by double buffering here */ + if (window_impl->begin_paint_count != 0) + { + CGRect rect; + CGRect *cg_rects; + GdkRectangle *rects; + gint n_rects, i; + + gdk_region_get_rectangles (window_impl->paint_clip_region, + &rects, &n_rects); + + if (n_rects == 1) + cg_rects = ▭ + else + cg_rects = g_new (CGRect, n_rects); + + for (i = 0; i < n_rects; i++) + { + cg_rects[i].origin.x = rects[i].x; + cg_rects[i].origin.y = rects[i].y; + cg_rects[i].size.width = rects[i].width; + cg_rects[i].size.height = rects[i].height; + } + + CGContextClipToRects (cg_context, cg_rects, n_rects); + + g_free (rects); + if (cg_rects != &rect) + g_free (cg_rects); + } + + return cg_context; +} + static GdkRegion* gdk_window_impl_quartz_get_visible_region (GdkDrawable *drawable) { @@ -159,6 +220,7 @@ gdk_window_impl_quartz_finalize (GObject *object) static void gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass) { + GdkDrawableImplQuartzClass *drawable_quartz_class = GDK_DRAWABLE_IMPL_QUARTZ_CLASS (klass); GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); @@ -168,6 +230,8 @@ gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass) drawable_class->get_size = gdk_window_impl_quartz_get_size; + drawable_quartz_class->get_context = gdk_window_impl_quartz_get_context; + /* Visible and clip regions are the same */ drawable_class->get_clip_region = gdk_window_impl_quartz_get_visible_region; drawable_class->get_visible_region = gdk_window_impl_quartz_get_visible_region;