From 88cae1769b335dd844034e3929734f27bcad546f Mon Sep 17 00:00:00 2001 From: Kristian Rietveld Date: Sat, 26 Jun 2010 17:08:15 +0200 Subject: [PATCH] Rework color translation to support gray scale and bitmaps (cherry picked from commit 49f72c1fb4bf90fde0ba9c4b40794672b775d2a8) --- gdk/quartz/gdkcolor-quartz.c | 54 ++++++++++++----- gdk/quartz/gdkgc-quartz.c | 102 ++++++++++++++++++++++----------- gdk/quartz/gdkprivate-quartz.h | 8 +-- gdk/quartz/gdkwindow-quartz.c | 10 ++-- 4 files changed, 115 insertions(+), 59 deletions(-) diff --git a/gdk/quartz/gdkcolor-quartz.c b/gdk/quartz/gdkcolor-quartz.c index b722185792..7afcf2cce5 100644 --- a/gdk/quartz/gdkcolor-quartz.c +++ b/gdk/quartz/gdkcolor-quartz.c @@ -163,20 +163,46 @@ gdk_colormap_get_screen (GdkColormap *cmap) return gdk_screen_get_default (); } -void -_gdk_quartz_colormap_get_rgba_from_pixel (GdkColormap *colormap, - guint32 pixel, - CGFloat *red, - CGFloat *green, - CGFloat *blue, - CGFloat *alpha) +CGColorRef +_gdk_quartz_colormap_get_cgcolor_from_pixel (GdkDrawable *drawable, + guint32 pixel) { - *red = (pixel >> 16 & 0xff) / 255.0; - *green = (pixel >> 8 & 0xff) / 255.0; - *blue = (pixel & 0xff) / 255.0; - - if (colormap && gdk_colormap_get_visual (colormap)->depth == 32) - *alpha = (pixel >> 24 & 0xff) / 255.0; + CGFloat r, g, b, a; + CGColorRef color; + const GdkVisual *visual; + GdkColormap *colormap; + + colormap = gdk_drawable_get_colormap (drawable); + if (colormap) + visual = gdk_colormap_get_visual (colormap); else - *alpha = 1.0; + visual = gdk_visual_get_best_with_depth (gdk_drawable_get_depth (drawable)); + + switch (visual->type) + { + case GDK_VISUAL_STATIC_GRAY: + case GDK_VISUAL_GRAYSCALE: + g = (pixel & 0xff) / 255.0f; + + if (visual->depth == 1) + g = g == 0.0f ? 0.0f : 1.0f; + + color = CGColorCreateGenericGray (g, 1.0f); + break; + + default: + r = (pixel >> 16 & 0xff) / 255.0; + g = (pixel >> 8 & 0xff) / 255.0; + b = (pixel & 0xff) / 255.0; + + if (visual->depth == 32) + a = (pixel >> 24 & 0xff) / 255.0; + else + a = 1.0; + + color = CGColorCreateGenericRGB (r, g, b, a); + break; + } + + return color; } diff --git a/gdk/quartz/gdkgc-quartz.c b/gdk/quartz/gdkgc-quartz.c index d0a23668fc..780732be0e 100644 --- a/gdk/quartz/gdkgc-quartz.c +++ b/gdk/quartz/gdkgc-quartz.c @@ -280,11 +280,24 @@ gdk_gc_get_screen (GdkGC *gc) return _gdk_screen; } +struct PatternCallbackInfo +{ + GdkGCQuartz *private_gc; + GdkDrawable *drawable; +}; + +static void +pattern_callback_info_release (void *info) +{ + g_free (info); +} + static void gdk_quartz_draw_tiled_pattern (void *info, CGContextRef context) { - GdkGC *gc = GDK_GC (info); + struct PatternCallbackInfo *pinfo = info; + GdkGC *gc = GDK_GC (pinfo->private_gc); CGImageRef pattern_image; size_t width, height; @@ -302,10 +315,11 @@ static void gdk_quartz_draw_stippled_pattern (void *info, CGContextRef context) { - GdkGC *gc = GDK_GC (info); + struct PatternCallbackInfo *pinfo = info; + GdkGC *gc = GDK_GC (pinfo->private_gc); CGImageRef pattern_image; CGRect rect; - CGFloat r, g, b, a; + CGColorRef color; pattern_image = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (_gdk_gc_get_stipple (gc))->impl)->image; rect = CGRectMake (0, 0, @@ -313,10 +327,11 @@ gdk_quartz_draw_stippled_pattern (void *info, CGImageGetHeight (pattern_image)); CGContextClipToMask (context, rect, pattern_image); - _gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, - _gdk_gc_get_fg_pixel (gc), - &r, &g, &b, &a); - CGContextSetRGBFillColor (context, r, g, b, a); + color = _gdk_quartz_colormap_get_cgcolor_from_pixel (pinfo->drawable, + _gdk_gc_get_fg_pixel (gc)); + CGContextSetFillColorWithColor (context, color); + CGColorRelease (color); + CGContextFillRect (context, rect); } @@ -324,27 +339,30 @@ static void gdk_quartz_draw_opaque_stippled_pattern (void *info, CGContextRef context) { - GdkGC *gc = GDK_GC (info); + struct PatternCallbackInfo *pinfo = info; + GdkGC *gc = GDK_GC (pinfo->private_gc); CGImageRef pattern_image; CGRect rect; - CGFloat r, g, b, a; + CGColorRef color; pattern_image = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (_gdk_gc_get_stipple (gc))->impl)->image; rect = CGRectMake (0, 0, CGImageGetWidth (pattern_image), CGImageGetHeight (pattern_image)); - _gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, - _gdk_gc_get_bg_pixel (gc), - &r, &g, &b, &a); - CGContextSetRGBFillColor (context, r, g, b, a); + color = _gdk_quartz_colormap_get_cgcolor_from_pixel (pinfo->drawable, + _gdk_gc_get_bg_pixel (gc)); + CGContextSetFillColorWithColor (context, color); + CGColorRelease (color); + CGContextFillRect (context, rect); CGContextClipToMask (context, rect, pattern_image); - _gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, - _gdk_gc_get_fg_pixel (gc), - &r, &g, &b, &a); - CGContextSetRGBFillColor (context, r, g, b, a); + color = _gdk_quartz_colormap_get_cgcolor_from_pixel (info, + _gdk_gc_get_fg_pixel (gc)); + CGContextSetFillColorWithColor (context, color); + CGColorRelease (color); + CGContextFillRect (context, rect); } @@ -453,12 +471,12 @@ _gdk_quartz_gc_update_cg_context (GdkGC *gc, { CGLineCap line_cap = kCGLineCapButt; CGLineJoin line_join = kCGLineJoinMiter; - CGFloat r, g, b, a; + CGColorRef color; - _gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, - fg_pixel, - &r, &g, &b, &a); - CGContextSetRGBStrokeColor (context, r, g, b, a); + color = _gdk_quartz_colormap_get_cgcolor_from_pixel (drawable, + fg_pixel); + CGContextSetStrokeColorWithColor (context, color); + CGColorRelease (color); CGContextSetLineWidth (context, MAX (G_MINFLOAT, private->line_width)); @@ -516,15 +534,15 @@ _gdk_quartz_gc_update_cg_context (GdkGC *gc, CGColorSpaceRef baseSpace; CGColorSpaceRef patternSpace; CGFloat alpha = 1.0; - CGFloat colors[4] = { 0.0, 0.0, 0.0, 0.0 }; - CGFloat r, g, b, a; if (fill == GDK_SOLID) { - _gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, - fg_pixel, - &r, &g, &b, &a); - CGContextSetRGBFillColor (context, r, g, b, a); + CGColorRef color; + + color = _gdk_quartz_colormap_get_cgcolor_from_pixel (drawable, + fg_pixel); + CGContextSetFillColorWithColor (context, color); + CGColorRelease (color); } else { @@ -534,8 +552,16 @@ _gdk_quartz_gc_update_cg_context (GdkGC *gc, gfloat width, height; gboolean is_colored = FALSE; CGPatternCallbacks callbacks = { 0, NULL, NULL }; + struct PatternCallbackInfo *info; CGPoint phase; + info = g_new (struct PatternCallbackInfo, 1); + /* Won't ref to avoid circular dependencies */ + info->drawable = drawable; + info->private_gc = private; + + callbacks.releaseInfo = pattern_callback_info_release; + switch (fill) { case GDK_TILED: @@ -563,7 +589,7 @@ _gdk_quartz_gc_update_cg_context (GdkGC *gc, phase = CGPointApplyAffineTransform (CGPointMake (gc->ts_x_origin, gc->ts_y_origin), CGContextGetCTM (context)); CGContextSetPatternPhase (context, CGSizeMake (phase.x, phase.y)); - private->ts_pattern = CGPatternCreate (private, + private->ts_pattern = CGPatternCreate (info, CGRectMake (0, 0, width, height), CGAffineTransformIdentity, width, height, @@ -580,12 +606,20 @@ _gdk_quartz_gc_update_cg_context (GdkGC *gc, CGColorSpaceRelease (baseSpace); if (fill == GDK_STIPPLED) - _gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, fg_pixel, - &colors[0], &colors[1], - &colors[2], &colors[3]); + { + CGColorRef color; + const CGFloat *components; - CGContextSetFillPattern (context, private->ts_pattern, - (fill == GDK_STIPPLED) ? colors : &alpha); + color = _gdk_quartz_colormap_get_cgcolor_from_pixel (drawable, + fg_pixel); + components = CGColorGetComponents (color); + + CGContextSetFillPattern (context, private->ts_pattern, + components); + CGColorRelease (color); + } + else + CGContextSetFillPattern (context, private->ts_pattern, &alpha); } } diff --git a/gdk/quartz/gdkprivate-quartz.h b/gdk/quartz/gdkprivate-quartz.h index 0809dcf82b..8e9708f3c4 100644 --- a/gdk/quartz/gdkprivate-quartz.h +++ b/gdk/quartz/gdkprivate-quartz.h @@ -129,12 +129,8 @@ void _gdk_quartz_gc_update_cg_context (GdkGC *gc, GdkQuartzContextValuesMask mask); /* Colormap */ -void _gdk_quartz_colormap_get_rgba_from_pixel (GdkColormap *colormap, - guint32 pixel, - CGFloat *red, - CGFloat *green, - CGFloat *blue, - CGFloat *alpha); +CGColorRef _gdk_quartz_colormap_get_cgcolor_from_pixel (GdkDrawable *drawable, + guint32 pixel); /* Window */ gboolean _gdk_quartz_window_is_ancestor (GdkWindow *ancestor, diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c index efc0672e7c..8de986c52d 100644 --- a/gdk/quartz/gdkwindow-quartz.c +++ b/gdk/quartz/gdkwindow-quartz.c @@ -262,14 +262,14 @@ gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable, if (bg_pixmap == NULL) { CGContextRef cg_context; - CGFloat r, g, b, a; + CGColorRef color; gint i; cg_context = gdk_quartz_drawable_get_context (GDK_DRAWABLE (impl), FALSE); - _gdk_quartz_colormap_get_rgba_from_pixel (gdk_drawable_get_colormap (window), - private->bg_color.pixel, - &r, &g, &b, &a); - CGContextSetRGBFillColor (cg_context, r, g, b, a); + color = _gdk_quartz_colormap_get_cgcolor_from_pixel (window, + private->bg_color.pixel); + CGContextSetFillColorWithColor (cg_context, color); + CGColorRelease (color); for (i = 0; i < n_rects; i++) {