Rework color translation to support gray scale and bitmaps

This commit is contained in:
Kristian Rietveld 2010-06-26 17:08:15 +02:00
parent 42d07ad6ce
commit 49f72c1fb4
4 changed files with 115 additions and 59 deletions

View File

@ -196,22 +196,48 @@ gdk_colormap_get_screen (GdkColormap *cmap)
return gdk_screen_get_default (); return gdk_screen_get_default ();
} }
void CGColorRef
_gdk_quartz_colormap_get_rgba_from_pixel (GdkColormap *colormap, _gdk_quartz_colormap_get_cgcolor_from_pixel (GdkDrawable *drawable,
guint32 pixel, guint32 pixel)
CGFloat *red,
CGFloat *green,
CGFloat *blue,
CGFloat *alpha)
{ {
*red = (pixel >> 16 & 0xff) / 255.0; CGFloat r, g, b, a;
*green = (pixel >> 8 & 0xff) / 255.0; CGColorRef color;
*blue = (pixel & 0xff) / 255.0; const GdkVisual *visual;
GdkColormap *colormap;
if (colormap && gdk_colormap_get_visual (colormap)->depth == 32) colormap = gdk_drawable_get_colormap (drawable);
*alpha = (pixel >> 24 & 0xff) / 255.0; if (colormap)
visual = gdk_colormap_get_visual (colormap);
else 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;
} }
gboolean gboolean

View File

@ -280,11 +280,24 @@ gdk_gc_get_screen (GdkGC *gc)
return _gdk_screen; return _gdk_screen;
} }
struct PatternCallbackInfo
{
GdkGCQuartz *private_gc;
GdkDrawable *drawable;
};
static void
pattern_callback_info_release (void *info)
{
g_free (info);
}
static void static void
gdk_quartz_draw_tiled_pattern (void *info, gdk_quartz_draw_tiled_pattern (void *info,
CGContextRef context) CGContextRef context)
{ {
GdkGC *gc = GDK_GC (info); struct PatternCallbackInfo *pinfo = info;
GdkGC *gc = GDK_GC (pinfo->private_gc);
CGImageRef pattern_image; CGImageRef pattern_image;
size_t width, height; size_t width, height;
@ -302,10 +315,11 @@ static void
gdk_quartz_draw_stippled_pattern (void *info, gdk_quartz_draw_stippled_pattern (void *info,
CGContextRef context) CGContextRef context)
{ {
GdkGC *gc = GDK_GC (info); struct PatternCallbackInfo *pinfo = info;
GdkGC *gc = GDK_GC (pinfo->private_gc);
CGImageRef pattern_image; CGImageRef pattern_image;
CGRect rect; 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; pattern_image = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (_gdk_gc_get_stipple (gc))->impl)->image;
rect = CGRectMake (0, 0, rect = CGRectMake (0, 0,
@ -313,10 +327,11 @@ gdk_quartz_draw_stippled_pattern (void *info,
CGImageGetHeight (pattern_image)); CGImageGetHeight (pattern_image));
CGContextClipToMask (context, rect, pattern_image); CGContextClipToMask (context, rect, pattern_image);
_gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, color = _gdk_quartz_colormap_get_cgcolor_from_pixel (pinfo->drawable,
_gdk_gc_get_fg_pixel (gc), _gdk_gc_get_fg_pixel (gc));
&r, &g, &b, &a); CGContextSetFillColorWithColor (context, color);
CGContextSetRGBFillColor (context, r, g, b, a); CGColorRelease (color);
CGContextFillRect (context, rect); CGContextFillRect (context, rect);
} }
@ -324,27 +339,30 @@ static void
gdk_quartz_draw_opaque_stippled_pattern (void *info, gdk_quartz_draw_opaque_stippled_pattern (void *info,
CGContextRef context) CGContextRef context)
{ {
GdkGC *gc = GDK_GC (info); struct PatternCallbackInfo *pinfo = info;
GdkGC *gc = GDK_GC (pinfo->private_gc);
CGImageRef pattern_image; CGImageRef pattern_image;
CGRect rect; 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; pattern_image = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (_gdk_gc_get_stipple (gc))->impl)->image;
rect = CGRectMake (0, 0, rect = CGRectMake (0, 0,
CGImageGetWidth (pattern_image), CGImageGetWidth (pattern_image),
CGImageGetHeight (pattern_image)); CGImageGetHeight (pattern_image));
_gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, color = _gdk_quartz_colormap_get_cgcolor_from_pixel (pinfo->drawable,
_gdk_gc_get_bg_pixel (gc), _gdk_gc_get_bg_pixel (gc));
&r, &g, &b, &a); CGContextSetFillColorWithColor (context, color);
CGContextSetRGBFillColor (context, r, g, b, a); CGColorRelease (color);
CGContextFillRect (context, rect); CGContextFillRect (context, rect);
CGContextClipToMask (context, rect, pattern_image); CGContextClipToMask (context, rect, pattern_image);
_gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, color = _gdk_quartz_colormap_get_cgcolor_from_pixel (info,
_gdk_gc_get_fg_pixel (gc), _gdk_gc_get_fg_pixel (gc));
&r, &g, &b, &a); CGContextSetFillColorWithColor (context, color);
CGContextSetRGBFillColor (context, r, g, b, a); CGColorRelease (color);
CGContextFillRect (context, rect); CGContextFillRect (context, rect);
} }
@ -453,12 +471,12 @@ _gdk_quartz_gc_update_cg_context (GdkGC *gc,
{ {
CGLineCap line_cap = kCGLineCapButt; CGLineCap line_cap = kCGLineCapButt;
CGLineJoin line_join = kCGLineJoinMiter; CGLineJoin line_join = kCGLineJoinMiter;
CGFloat r, g, b, a; CGColorRef color;
_gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, color = _gdk_quartz_colormap_get_cgcolor_from_pixel (drawable,
fg_pixel, fg_pixel);
&r, &g, &b, &a); CGContextSetStrokeColorWithColor (context, color);
CGContextSetRGBStrokeColor (context, r, g, b, a); CGColorRelease (color);
CGContextSetLineWidth (context, MAX (G_MINFLOAT, private->line_width)); CGContextSetLineWidth (context, MAX (G_MINFLOAT, private->line_width));
@ -516,15 +534,15 @@ _gdk_quartz_gc_update_cg_context (GdkGC *gc,
CGColorSpaceRef baseSpace; CGColorSpaceRef baseSpace;
CGColorSpaceRef patternSpace; CGColorSpaceRef patternSpace;
CGFloat alpha = 1.0; CGFloat alpha = 1.0;
CGFloat colors[4] = { 0.0, 0.0, 0.0, 0.0 };
CGFloat r, g, b, a;
if (fill == GDK_SOLID) if (fill == GDK_SOLID)
{ {
_gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, CGColorRef color;
fg_pixel,
&r, &g, &b, &a); color = _gdk_quartz_colormap_get_cgcolor_from_pixel (drawable,
CGContextSetRGBFillColor (context, r, g, b, a); fg_pixel);
CGContextSetFillColorWithColor (context, color);
CGColorRelease (color);
} }
else else
{ {
@ -534,8 +552,16 @@ _gdk_quartz_gc_update_cg_context (GdkGC *gc,
gfloat width, height; gfloat width, height;
gboolean is_colored = FALSE; gboolean is_colored = FALSE;
CGPatternCallbacks callbacks = { 0, NULL, NULL }; CGPatternCallbacks callbacks = { 0, NULL, NULL };
struct PatternCallbackInfo *info;
CGPoint phase; 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) switch (fill)
{ {
case GDK_TILED: 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)); phase = CGPointApplyAffineTransform (CGPointMake (gc->ts_x_origin, gc->ts_y_origin), CGContextGetCTM (context));
CGContextSetPatternPhase (context, CGSizeMake (phase.x, phase.y)); CGContextSetPatternPhase (context, CGSizeMake (phase.x, phase.y));
private->ts_pattern = CGPatternCreate (private, private->ts_pattern = CGPatternCreate (info,
CGRectMake (0, 0, width, height), CGRectMake (0, 0, width, height),
CGAffineTransformIdentity, CGAffineTransformIdentity,
width, height, width, height,
@ -580,12 +606,20 @@ _gdk_quartz_gc_update_cg_context (GdkGC *gc,
CGColorSpaceRelease (baseSpace); CGColorSpaceRelease (baseSpace);
if (fill == GDK_STIPPLED) if (fill == GDK_STIPPLED)
_gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, fg_pixel, {
&colors[0], &colors[1], CGColorRef color;
&colors[2], &colors[3]); const CGFloat *components;
color = _gdk_quartz_colormap_get_cgcolor_from_pixel (drawable,
fg_pixel);
components = CGColorGetComponents (color);
CGContextSetFillPattern (context, private->ts_pattern, CGContextSetFillPattern (context, private->ts_pattern,
(fill == GDK_STIPPLED) ? colors : &alpha); components);
CGColorRelease (color);
}
else
CGContextSetFillPattern (context, private->ts_pattern, &alpha);
} }
} }

View File

@ -129,12 +129,8 @@ void _gdk_quartz_gc_update_cg_context (GdkGC *gc,
GdkQuartzContextValuesMask mask); GdkQuartzContextValuesMask mask);
/* Colormap */ /* Colormap */
void _gdk_quartz_colormap_get_rgba_from_pixel (GdkColormap *colormap, CGColorRef _gdk_quartz_colormap_get_cgcolor_from_pixel (GdkDrawable *drawable,
guint32 pixel, guint32 pixel);
CGFloat *red,
CGFloat *green,
CGFloat *blue,
CGFloat *alpha);
/* Window */ /* Window */
gboolean _gdk_quartz_window_is_ancestor (GdkWindow *ancestor, gboolean _gdk_quartz_window_is_ancestor (GdkWindow *ancestor,

View File

@ -255,14 +255,14 @@ gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable,
if (bg_pixmap == NULL) if (bg_pixmap == NULL)
{ {
CGContextRef cg_context; CGContextRef cg_context;
CGFloat r, g, b, a; CGColorRef color;
gint i; gint i;
cg_context = gdk_quartz_drawable_get_context (GDK_DRAWABLE (impl), FALSE); cg_context = gdk_quartz_drawable_get_context (GDK_DRAWABLE (impl), FALSE);
_gdk_quartz_colormap_get_rgba_from_pixel (gdk_drawable_get_colormap (window), color = _gdk_quartz_colormap_get_cgcolor_from_pixel (window,
private->bg_color.pixel, private->bg_color.pixel);
&r, &g, &b, &a); CGContextSetFillColorWithColor (cg_context, color);
CGContextSetRGBFillColor (cg_context, r, g, b, a); CGColorRelease (color);
for (i = 0; i < n_rects; i++) for (i = 0; i < n_rects; i++)
{ {