diff --git a/ChangeLog b/ChangeLog index e9f896e223..77c6a51bcc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,42 @@ +2006-09-21 Michael Natterer + + Implement lots of value setters for GdkGC, based on a heavily + modified patch from Thomas Broyer (bug #328853): + + * gdk/quartz/gdkcolor-quartz.c: removed functions which set colors + on the CGContext. Instead, added gdk_quartz_get_rgba_from_pixel() + which simply returns RGBA values from a GdkColor's pixel value. + See gdk_quartz_update_context_from_gc() below. + + * gdk/quartz/gdkprivate-quartz.h (struct GdkGCQuartz): added lots + of members for the newly suppored GC values. Added enum + GdkQuartzContextValuesMask which is used for setting up the + CGContext for filling and/or stroking. + + * gdk/quartz/gdkgc-quartz.c (gdk_quartz_gc_get_values) + (gdk_quartz_gc_set_values) + (_gdk_windowing_gc_copy): support a lot more GC values. + + (gdk_quartz_update_context_from_gc): added + GdkQuartzContextValuesMask parameter and set filling/stroking + parameters accordingly. This function also gained full control + over the FG and BG colors (they can't be set separately any more). + + The stipple mask part of the patch doesn't work but seems to take + the right approach and doesn't make things worse, so i applied it. + + Did *not* apply the clipping part of the patch since I don't + understand it (I don't understand the version in CVS either, but + it at least works :-) + + * gdk/quartz/gdkdrawable-quartz.c: pass the right masks to + gdk_quartz_update_context_from_gc() and removed separate color + setting calls. Some minor fixes. + + * gdk/quartz/gdkwindow-quartz.c + (gdk_window_impl_quartz_begin_paint_region): set the CGContext's + fill color manually. We don't have/need a GC here. + 2006-09-21 Michael Natterer * gdk/quartz/gdkwindow-quartz.c diff --git a/gdk/quartz/gdkcolor-quartz.c b/gdk/quartz/gdkcolor-quartz.c index 07e726c4d0..40d40b208b 100644 --- a/gdk/quartz/gdkcolor-quartz.c +++ b/gdk/quartz/gdkcolor-quartz.c @@ -170,37 +170,21 @@ gdk_colormap_get_screen (GdkColormap *cmap) } void -gdk_quartz_set_context_fill_color_from_pixel (CGContextRef context, GdkColormap *colormap, guint32 pixel) +gdk_quartz_get_rgba_from_pixel (GdkColormap *colormap, + guint32 pixel, + float *red, + float *green, + float *blue, + float *alpha) { - float red, green, blue, alpha; - - red = (pixel >> 16 & 0xff) / 255.0; - green = (pixel >> 8 & 0xff) / 255.0; - blue = (pixel & 0xff) / 255.0; - + *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; + *alpha = (pixel >> 24 & 0xff) / 255.0; else - alpha = 1.0; - - CGContextSetRGBFillColor (context, red, green, blue, alpha); -} - -void -gdk_quartz_set_context_stroke_color_from_pixel (CGContextRef context, GdkColormap *colormap, guint32 pixel) -{ - float red, green, blue, alpha; - - 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; - else - alpha = 1.0; - - CGContextSetRGBStrokeColor (context, red, green, blue, 1.0); + *alpha = 1.0; } gboolean diff --git a/gdk/quartz/gdkdrawable-quartz.c b/gdk/quartz/gdkdrawable-quartz.c index 3142fa4c35..030f68362e 100644 --- a/gdk/quartz/gdkdrawable-quartz.c +++ b/gdk/quartz/gdkdrawable-quartz.c @@ -128,22 +128,21 @@ gdk_quartz_draw_rectangle (GdkDrawable *drawable, if (!context) return; - gdk_quartz_update_context_from_gc (context, gc); + gdk_quartz_update_context_from_gc (context, gc, + filled ? + GDK_QUARTZ_CONTEXT_FILL : + GDK_QUARTZ_CONTEXT_STROKE); if (filled) { CGRect rect = CGRectMake (x, y, width, height); - gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (drawable), - _gdk_gc_get_fg_pixel (gc)); CGContextFillRect (context, rect); } else { CGRect rect = CGRectMake (x + 0.5, y + 0.5, width, height); - gdk_quartz_set_context_stroke_color_from_pixel (context, gdk_drawable_get_colormap (drawable), - _gdk_gc_get_fg_pixel (gc)); CGContextStrokeRect (context, rect); } @@ -167,7 +166,10 @@ gdk_quartz_draw_arc (GdkDrawable *drawable, if (!context) return; - gdk_quartz_update_context_from_gc (context, gc); + gdk_quartz_update_context_from_gc (context, gc, + filled ? + GDK_QUARTZ_CONTEXT_FILL : + GDK_QUARTZ_CONTEXT_STROKE); CGContextSaveGState (context); @@ -176,9 +178,6 @@ gdk_quartz_draw_arc (GdkDrawable *drawable, if (filled) { - gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (drawable), - _gdk_gc_get_fg_pixel (gc)); - CGContextTranslateCTM (context, x + width / 2.0, y + height / 2.0); @@ -193,9 +192,6 @@ gdk_quartz_draw_arc (GdkDrawable *drawable, } else { - gdk_quartz_set_context_stroke_color_from_pixel (context, gdk_drawable_get_colormap (drawable), - _gdk_gc_get_fg_pixel (gc)); - CGContextTranslateCTM (context, x + width / 2.0 + 0.5, y + height / 2.0 + 0.5); @@ -225,13 +221,13 @@ gdk_quartz_draw_polygon (GdkDrawable *drawable, if (!context) return; - gdk_quartz_update_context_from_gc (context, gc); + gdk_quartz_update_context_from_gc (context, gc, + filled ? + GDK_QUARTZ_CONTEXT_FILL : + GDK_QUARTZ_CONTEXT_STROKE); if (filled) { - gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (drawable), - _gdk_gc_get_fg_pixel (gc)); - CGContextMoveToPoint (context, points[0].x, points[0].y); for (i = 1; i < npoints; i++) CGContextAddLineToPoint (context, points[i].x, points[i].y); @@ -241,9 +237,6 @@ gdk_quartz_draw_polygon (GdkDrawable *drawable, } else { - gdk_quartz_set_context_stroke_color_from_pixel (context, gdk_drawable_get_colormap (drawable), - _gdk_gc_get_fg_pixel (gc)); - CGContextMoveToPoint (context, points[0].x + 0.5, points[0].y + 0.5); for (i = 1; i < npoints; i++) CGContextAddLineToPoint (context, points[i].x + 0.5, points[i].y + 0.5); @@ -318,9 +311,8 @@ gdk_quartz_draw_drawable (GdkDrawable *drawable, if (!context) return; - gdk_quartz_update_context_from_gc (context, gc); - - CGContextSetBlendMode (context, kCGBlendModeNormal); + gdk_quartz_update_context_from_gc (context, gc, + GDK_QUARTZ_CONTEXT_STROKE); CGContextClipToRect (context, CGRectMake (xdest, ydest, width, height)); CGContextTranslateCTM (context, xdest - xsrc, ydest - ysrc); @@ -349,9 +341,9 @@ gdk_quartz_draw_points (GdkDrawable *drawable, if (!context) return; - gdk_quartz_update_context_from_gc (context, gc); - gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (drawable), - _gdk_gc_get_fg_pixel (gc)); + gdk_quartz_update_context_from_gc (context, gc, + GDK_QUARTZ_CONTEXT_STROKE | + GDK_QUARTZ_CONTEXT_FILL); /* Just draw 1x1 rectangles */ for (i = 0; i < npoints; i++) @@ -375,9 +367,8 @@ gdk_quartz_draw_segments (GdkDrawable *drawable, if (!context) return; - gdk_quartz_update_context_from_gc (context, gc); - gdk_quartz_set_context_stroke_color_from_pixel (context, gdk_drawable_get_colormap (drawable), - _gdk_gc_get_fg_pixel (gc)); + gdk_quartz_update_context_from_gc (context, gc, + GDK_QUARTZ_CONTEXT_STROKE); for (i = 0; i < nsegs; i++) { @@ -402,16 +393,14 @@ gdk_quartz_draw_lines (GdkDrawable *drawable, if (!context) return; - gdk_quartz_update_context_from_gc (context, gc); - gdk_quartz_set_context_stroke_color_from_pixel (context, gdk_drawable_get_colormap (drawable), - _gdk_gc_get_fg_pixel (gc)); - + gdk_quartz_update_context_from_gc (context, gc, + GDK_QUARTZ_CONTEXT_STROKE); + + CGContextMoveToPoint (context, points[0].x + 0.5, points[0].y + 0.5); + for (i = 1; i < npoints; i++) - { - CGContextMoveToPoint (context, points[i - 1].x + 0.5, points[i - 1].y + 0.5); - CGContextAddLineToPoint (context, points[i].x + 0.5, points[i].y + 0.5); - } - + CGContextAddLineToPoint (context, points[i].x + 0.5, points[i].y + 0.5); + CGContextStrokePath (context); gdk_quartz_drawable_release_context (drawable, context); @@ -462,9 +451,8 @@ gdk_quartz_draw_pixbuf (GdkDrawable *drawable, CGDataProviderRelease (data_provider); CGColorSpaceRelease (colorspace); - gdk_quartz_update_context_from_gc (context, gc); - - CGContextSetBlendMode (context, kCGBlendModeNormal); + gdk_quartz_update_context_from_gc (context, gc, + GDK_QUARTZ_CONTEXT_STROKE); CGContextClipToRect (context, CGRectMake (dest_x, dest_y, width, height)); CGContextTranslateCTM (context, dest_x - src_x, dest_y - src_y + pixbuf_height); @@ -509,9 +497,8 @@ gdk_quartz_draw_image (GdkDrawable *drawable, CGDataProviderRelease (data_provider); CGColorSpaceRelease (colorspace); - gdk_quartz_update_context_from_gc (context, gc); - - CGContextSetBlendMode (context, kCGBlendModeNormal); + gdk_quartz_update_context_from_gc (context, gc, + GDK_QUARTZ_CONTEXT_STROKE); CGContextClipToRect (context, CGRectMake (xdest, ydest, width, height)); CGContextTranslateCTM (context, xdest - xsrc, ydest - ysrc + image->height); diff --git a/gdk/quartz/gdkgc-quartz.c b/gdk/quartz/gdkgc-quartz.c index d18721568b..b1e140de6e 100644 --- a/gdk/quartz/gdkgc-quartz.c +++ b/gdk/quartz/gdkgc-quartz.c @@ -33,14 +33,12 @@ gdk_quartz_gc_get_values (GdkGC *gc, private = GDK_GC_QUARTZ (gc); - memset (values, 0, sizeof (GdkGCValues)); - - /* FIXME: Fill in more value as/if they are added. */ - values->foreground.pixel = _gdk_gc_get_fg_pixel (gc); values->background.pixel = _gdk_gc_get_bg_pixel (gc); - values->function = GDK_COPY; + values->font = private->font; + + values->function = private->function; values->fill = _gdk_gc_get_fill (gc); values->tile = _gdk_gc_get_tile (gc); @@ -53,6 +51,13 @@ gdk_quartz_gc_get_values (GdkGC *gc, values->ts_y_origin = gc->ts_y_origin; values->clip_x_origin = gc->clip_x_origin; values->clip_y_origin = gc->clip_y_origin; + + values->graphics_exposures = private->graphics_exposures; + + values->line_width = private->line_width; + values->line_style = private->line_style; + values->cap_style = private->cap_style; + values->join_style = private->join_style; } static void @@ -62,7 +67,19 @@ gdk_quartz_gc_set_values (GdkGC *gc, { GdkGCQuartz *private = GDK_GC_QUARTZ (gc); - private->values_mask |= mask; + if (mask & GDK_GC_FONT) + { + /* FIXME: implement font */ + } + + if (mask & GDK_GC_FUNCTION) + private->function = values->function; + + if (mask & GDK_GC_SUBWINDOW) + private->subwindow_mode = values->subwindow_mode; + + if (mask & GDK_GC_EXPOSURES) + private->graphics_exposures = values->graphics_exposures; if (mask & GDK_GC_CLIP_MASK) { @@ -76,15 +93,35 @@ gdk_quartz_gc_set_values (GdkGC *gc, else private->clip_mask = NULL; } + + if (mask & GDK_GC_LINE_WIDTH) + private->line_width = values->line_width; + + if (mask & GDK_GC_LINE_STYLE) + private->line_style = values->line_style; + + if (mask & GDK_GC_CAP_STYLE) + private->line_style = values->line_style; + + if (mask & GDK_GC_JOIN_STYLE) + private->join_style = values->join_style; } static void gdk_quartz_gc_set_dashes (GdkGC *gc, - gint dash_offset, - gint8 dash_list[], - gint n) + gint dash_offset, + gint8 dash_list[], + gint n) { - /* FIXME: Implement */ + GdkGCQuartz *private = GDK_GC_QUARTZ (gc); + gint i; + + private->dash_count = n; + g_free (private->dash_lengths); + private->dash_lengths = g_new (gfloat, n); + for (i = 0; i < n; i++) + private->dash_lengths[i] = (gfloat) dash_list[i]; + private->dash_phase = (gfloat) dash_offset; } static void @@ -186,20 +223,40 @@ _gdk_windowing_gc_copy (GdkGC *dst_gc, GdkGCQuartz *dst_quartz_gc = GDK_GC_QUARTZ (dst_gc); GdkGCQuartz *src_quartz_gc = GDK_GC_QUARTZ (src_gc); - dst_quartz_gc->values_mask = src_quartz_gc->values_mask; - + if (dst_quartz_gc->font) + gdk_font_unref (dst_quartz_gc->font); + dst_quartz_gc->font = src_quartz_gc->font; + if (dst_quartz_gc->font) + gdk_font_ref (dst_quartz_gc->font); + + dst_quartz_gc->function = src_quartz_gc->function; + dst_quartz_gc->subwindow_mode = src_quartz_gc->subwindow_mode; + dst_quartz_gc->graphics_exposures = src_quartz_gc->graphics_exposures; + dst_quartz_gc->have_clip_region = src_quartz_gc->have_clip_region; dst_quartz_gc->have_clip_mask = src_quartz_gc->have_clip_mask; - if (dst_quartz_gc->values_mask & GDK_GC_CLIP_MASK && dst_quartz_gc->clip_mask) + if (dst_quartz_gc->clip_mask) { CGImageRelease (dst_quartz_gc->clip_mask); dst_quartz_gc->clip_mask = NULL; } - if (src_quartz_gc->values_mask & GDK_GC_CLIP_MASK && src_quartz_gc->clip_mask) + if (src_quartz_gc->clip_mask) dst_quartz_gc->clip_mask = CGImageCreateCopy (GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (src_quartz_gc->clip_mask)->impl)->image); + + dst_quartz_gc->line_width = src_quartz_gc->line_width; + dst_quartz_gc->line_style = src_quartz_gc->line_style; + dst_quartz_gc->cap_style = src_quartz_gc->cap_style; + dst_quartz_gc->join_style = src_quartz_gc->join_style; + + if (dst_quartz_gc->dash_lengths) + g_free (dst_quartz_gc->dash_lengths); + dst_quartz_gc->dash_lengths = g_memdup (src_quartz_gc->dash_lengths, + sizeof (float) * src_quartz_gc->dash_count); + dst_quartz_gc->dash_count = src_quartz_gc->dash_count; + dst_quartz_gc->dash_phase = src_quartz_gc->dash_phase; } GdkScreen * @@ -208,12 +265,80 @@ gdk_gc_get_screen (GdkGC *gc) return _gdk_screen; } +static void +gdk_quartz_draw_tiled_pattern (void *info, + CGContextRef context) +{ + GdkGC *gc = GDK_GC (info); + CGImageRef pattern_image; + + pattern_image = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (_gdk_gc_get_tile (gc))->impl)->image; + + CGContextDrawImage (context, CGRectMake (0, 0, + CGImageGetWidth (pattern_image), + CGImageGetHeight (pattern_image)), + pattern_image); +} + +static void +gdk_quartz_draw_stippled_pattern (void *info, + CGContextRef context) +{ + GdkGC *gc = GDK_GC (info); + CGImageRef pattern_image; + CGRect rect; + gfloat r, g, b, a; + + 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)); + + CGContextClipToMask (context, rect, pattern_image); + gdk_quartz_get_rgba_from_pixel (gc->colormap, _gdk_gc_get_fg_pixel (gc), + &r, &g, &b, &a); + CGContextSetRGBFillColor (context, r, g, b, a); + CGContextFillRect (context, rect); +} + +static void +gdk_quartz_draw_opaque_stippled_pattern (void *info, + CGContextRef context) +{ + GdkGC *gc = GDK_GC (info); + CGImageRef pattern_image; + CGRect rect; + gfloat r, g, b, a; + + 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_get_rgba_from_pixel (gc->colormap, _gdk_gc_get_bg_pixel (gc), + &r, &g, &b, &a); + CGContextSetRGBFillColor (context, r, g, b, a); + CGContextFillRect (context, rect); + + CGContextClipToMask (context, rect, pattern_image); + gdk_quartz_get_rgba_from_pixel (gc->colormap, _gdk_gc_get_fg_pixel (gc), + &r, &g, &b, &a); + CGContextSetRGBFillColor (context, r, g, b, a); + CGContextFillRect (context, rect); +} + void -gdk_quartz_update_context_from_gc (CGContextRef context, GdkGC *gc) +gdk_quartz_update_context_from_gc (CGContextRef context, + GdkGC *gc, + GdkQuartzContextValuesMask mask) { GdkGCQuartz *private; + guint32 fg_pixel; + guint32 bg_pixel; - if (gc == NULL) + g_return_if_fail (gc == NULL || GDK_IS_GC (gc)); + + if (!gc) return; private = GDK_GC_QUARTZ (gc); @@ -258,4 +383,189 @@ gdk_quartz_update_context_from_gc (CGContextRef context, GdkGC *gc) CGImageGetHeight (private->clip_mask)), private->clip_mask); } + + fg_pixel = _gdk_gc_get_fg_pixel (gc); + bg_pixel = _gdk_gc_get_bg_pixel (gc); + + { + CGBlendMode blend_mode = kCGBlendModeNormal; + + switch (private->function) + { + case GDK_COPY: + blend_mode = kCGBlendModeNormal; + break; + + case GDK_INVERT: + blend_mode = kCGBlendModeExclusion; + fg_pixel = 0xffffffff; + bg_pixel = 0xffffffff; + break; + + case GDK_XOR: + blend_mode = kCGBlendModeExclusion; + break; + + case GDK_CLEAR: + case GDK_AND: + case GDK_AND_REVERSE: + case GDK_AND_INVERT: + case GDK_NOOP: + case GDK_OR: + case GDK_EQUIV: + case GDK_OR_REVERSE: + case GDK_COPY_INVERT: + case GDK_OR_INVERT: + case GDK_NAND: + case GDK_NOR: + case GDK_SET: + blend_mode = kCGBlendModeNormal; /* FIXME */ + break; + } + + CGContextSetBlendMode (context, blend_mode); + } + + /* FIXME: implement subwindow mode */ + + /* FIXME: implement graphics exposures */ + + if (mask & GDK_QUARTZ_CONTEXT_STROKE) + { + CGLineCap line_cap = kCGLineCapButt; + CGLineJoin line_join = kCGLineJoinMiter; + gfloat r, g, b, a; + + gdk_quartz_get_rgba_from_pixel (gc->colormap, fg_pixel, + &r, &g, &b, &a); + CGContextSetRGBStrokeColor (context, r, g, b, a); + + CGContextSetLineWidth (context, MAX (G_MINFLOAT, private->line_width)); + + switch (private->line_style) + { + case GDK_LINE_SOLID: + CGContextSetLineDash (context, 0.0, NULL, 0); + break; + + case GDK_LINE_DOUBLE_DASH: + /* FIXME: Implement; for now, fall back to GDK_LINE_ON_OFF_DASH */ + + case GDK_LINE_ON_OFF_DASH: + CGContextSetLineDash (context, private->dash_phase, + private->dash_lengths, private->dash_count); + break; + } + + switch (private->cap_style) + { + case GDK_CAP_NOT_LAST: + /* FIXME: Implement; for now, fall back to GDK_CAP_BUTT */ + case GDK_CAP_BUTT: + line_cap = kCGLineCapButt; + break; + case GDK_CAP_ROUND: + line_cap = kCGLineCapRound; + break; + case GDK_CAP_PROJECTING: + line_cap = kCGLineCapSquare; + break; + } + + CGContextSetLineCap (context, line_cap); + + switch (private->join_style) + { + case GDK_JOIN_MITER: + line_join = kCGLineJoinMiter; + break; + case GDK_JOIN_ROUND: + line_join = kCGLineJoinRound; + break; + case GDK_JOIN_BEVEL: + line_join = kCGLineJoinBevel; + break; + } + + CGContextSetLineJoin (context, line_join); + } + + if (mask & GDK_QUARTZ_CONTEXT_FILL) + { + GdkFill fill = _gdk_gc_get_fill (gc); + CGColorSpaceRef baseSpace; + CGColorSpaceRef patternSpace; + gfloat alpha = 1.0; + gfloat colors[4] = { 0.0, 0.0, 0.0, 0.0 }; + gfloat r, g, b, a; + + if (fill == GDK_SOLID) + { + gdk_quartz_get_rgba_from_pixel (gc->colormap, fg_pixel, + &r, &g, &b, &a); + CGContextSetRGBFillColor (context, r, g, b, a); + } + else + { + if (!private->ts_pattern) + { + CGImageRef pattern_image = NULL; + gfloat width, height; + gboolean is_colored = FALSE; + CGPatternCallbacks callbacks = { 0, NULL, NULL }; + + switch (fill) + { + case GDK_TILED: + pattern_image = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (_gdk_gc_get_tile (gc))->impl)->image; + is_colored = TRUE; + callbacks.drawPattern = gdk_quartz_draw_tiled_pattern; + break; + case GDK_STIPPLED: + pattern_image = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (_gdk_gc_get_stipple (gc))->impl)->image; + is_colored = FALSE; + callbacks.drawPattern = gdk_quartz_draw_stippled_pattern; + break; + case GDK_OPAQUE_STIPPLED: + pattern_image = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (_gdk_gc_get_stipple (gc))->impl)->image; + is_colored = TRUE; + callbacks.drawPattern = gdk_quartz_draw_opaque_stippled_pattern; + break; + default: + break; + } + + width = CGImageGetWidth (pattern_image); + height = CGImageGetHeight (pattern_image); + + private->ts_pattern = CGPatternCreate (private, + CGRectMake (0, 0, width, height), + CGAffineTransformIdentity, + width, height, + kCGPatternTilingConstantSpacing, + is_colored, + &callbacks); + } + + baseSpace = (fill == GDK_STIPPLED) ? CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB) : NULL; + patternSpace = CGColorSpaceCreatePattern (baseSpace); + + CGContextSetFillColorSpace (context, patternSpace); + CGColorSpaceRelease (patternSpace); + CGColorSpaceRelease (baseSpace); + + if (fill == GDK_STIPPLED) + gdk_quartz_get_rgba_from_pixel (gc->colormap, fg_pixel, + &colors[0], &colors[1], + &colors[2], &colors[3]); + + CGContextSetFillPattern (context, private->ts_pattern, + (fill == GDK_STIPPLED) ? colors : &alpha); + } + } + + if (mask & GDK_QUARTZ_CONTEXT_TEXT) + { + /* FIXME: implement text */ + } } diff --git a/gdk/quartz/gdkprivate-quartz.h b/gdk/quartz/gdkprivate-quartz.h index a1772ca71b..70a3303174 100644 --- a/gdk/quartz/gdkprivate-quartz.h +++ b/gdk/quartz/gdkprivate-quartz.h @@ -50,13 +50,27 @@ typedef struct _GdkDragContextPrivate GdkDragContextPrivate; struct _GdkGCQuartz { - GdkGC parent_instance; + GdkGC parent_instance; - GdkGCValuesMask values_mask; + GdkFont *font; + GdkFunction function; + GdkSubwindowMode subwindow_mode; + gboolean graphics_exposures; - gboolean have_clip_region; - gboolean have_clip_mask; - CGImageRef clip_mask; + gboolean have_clip_region; + gboolean have_clip_mask; + CGImageRef clip_mask; + + gint line_width; + GdkLineStyle line_style; + GdkCapStyle cap_style; + GdkJoinStyle join_style; + + gfloat *dash_lengths; + gint dash_count; + gfloat dash_phase; + + CGPatternRef ts_pattern; }; struct _GdkGCQuartzClass @@ -98,10 +112,22 @@ void _gdk_events_init (void); void _gdk_visual_init (void); void _gdk_input_init (void); -void gdk_quartz_set_context_fill_color_from_pixel (CGContextRef context, GdkColormap *colormap, guint32 pixel); -void gdk_quartz_set_context_stroke_color_from_pixel (CGContextRef context, GdkColormap *colormap, guint32 pixel); +typedef enum { + GDK_QUARTZ_CONTEXT_STROKE = 1 << 0, + GDK_QUARTZ_CONTEXT_FILL = 1 << 1, + GDK_QUARTZ_CONTEXT_TEXT = 1 << 2 +} GdkQuartzContextValuesMask; -void gdk_quartz_update_context_from_gc (CGContextRef context, GdkGC *gc); +void gdk_quartz_get_rgba_from_pixel (GdkColormap *colormap, + guint32 pixel, + gfloat *red, + gfloat *green, + gfloat *blue, + gfloat *alpha); + +void gdk_quartz_update_context_from_gc (CGContextRef context, + GdkGC *gc, + GdkQuartzContextValuesMask mask); gint _gdk_quartz_get_inverted_screen_y (gint y); diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c index e01e0046d6..23ad06361c 100644 --- a/gdk/quartz/gdkwindow-quartz.c +++ b/gdk/quartz/gdkwindow-quartz.c @@ -171,11 +171,16 @@ gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable, for (i = 0; i < n_rects; i++) { - gdk_quartz_set_context_fill_color_from_pixel - (context, gdk_drawable_get_colormap (GDK_DRAWABLE_IMPL_QUARTZ (impl)->wrapper), - GDK_WINDOW_OBJECT (GDK_DRAWABLE_IMPL_QUARTZ (impl)->wrapper)->bg_color.pixel); - - CGContextFillRect (context, CGRectMake (rects[i].x, rects[i].y, rects[i].width, rects[i].height)); + gfloat r, g, b, a; + + gdk_quartz_get_rgba_from_pixel (gdk_drawable_get_colormap (GDK_DRAWABLE_IMPL_QUARTZ (impl)->wrapper), + GDK_WINDOW_OBJECT (GDK_DRAWABLE_IMPL_QUARTZ (impl)->wrapper)->bg_color.pixel, + &r, &g, &b, &a); + + CGContextSetRGBFillColor (context, r, g, b, a); + CGContextFillRect (context, + CGRectMake (rects[i].x, rects[i].y, + rects[i].width, rects[i].height)); } gdk_quartz_drawable_release_context (GDK_DRAWABLE (impl), context);