21
21
#include <config.h>
23
22
#include <cairo-quartz.h>
24
23
#include "gdkprivate-quartz.h"
26
25
static gpointer parent_class;
27
static cairo_user_data_key_t gdk_quartz_cairo_key;
29
GdkDrawable *drawable;
33
static cairo_user_data_key_t surface_info_key;
30
GdkDrawable *drawable;
31
CGContextRef cg_context;
32
} GdkQuartzCairoSurfaceData;
36
surface_info_destroy (void *data)
35
gdk_quartz_cairo_surface_destroy (void *data)
38
SurfaceInfo *info = data;
40
gdk_quartz_drawable_release_context (info->drawable, info->context);
37
GdkQuartzCairoSurfaceData *surface_data = data;
38
GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (surface_data->drawable);
40
gdk_quartz_drawable_release_context (surface_data->drawable,
41
surface_data->cg_context);
43
impl->cairo_surface = NULL;
45
g_free (surface_data);
45
48
static cairo_surface_t *
46
49
gdk_quartz_ref_cairo_surface (GdkDrawable *drawable)
48
51
GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
51
cairo_surface_t *surface;
54
53
if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable) &&
55
54
GDK_WINDOW_DESTROYED (impl->wrapper))
58
context = gdk_quartz_drawable_get_context (drawable, TRUE);
62
gdk_drawable_get_size (drawable, &width, &height);
64
surface = cairo_quartz_surface_create (context, width, height, TRUE);
66
info = g_new (SurfaceInfo, 1);
67
info->drawable = drawable;
68
info->context = context;
70
cairo_surface_set_user_data (surface, &surface_info_key,
71
info, surface_info_destroy);
57
if (!impl->cairo_surface)
59
CGContextRef cg_context;
61
GdkQuartzCairoSurfaceData *surface_data;
63
cg_context = gdk_quartz_drawable_get_context (drawable, TRUE);
67
gdk_drawable_get_size (drawable, &width, &height);
69
impl->cairo_surface = cairo_quartz_surface_create_for_cg_context (cg_context, width, height);
71
surface_data = g_new (GdkQuartzCairoSurfaceData, 1);
72
surface_data->drawable = drawable;
73
surface_data->cg_context = cg_context;
75
cairo_surface_set_user_data (impl->cairo_surface, &gdk_quartz_cairo_key,
76
surface_data, gdk_quartz_cairo_surface_destroy);
79
cairo_surface_reference (impl->cairo_surface);
81
return impl->cairo_surface;
131
gdk_quartz_update_context_from_gc (context, gc);
140
_gdk_quartz_gc_update_cg_context (gc,
144
GDK_QUARTZ_CONTEXT_FILL :
145
GDK_QUARTZ_CONTEXT_STROKE);
135
149
CGRect rect = CGRectMake (x, y, width, height);
137
gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
138
_gdk_gc_get_fg_pixel (gc));
139
151
CGContextFillRect (context, rect);
143
155
CGRect rect = CGRectMake (x + 0.5, y + 0.5, width, height);
145
gdk_quartz_set_context_stroke_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
146
_gdk_gc_get_fg_pixel (gc));
147
157
CGContextStrokeRect (context, rect);
228
gdk_quartz_update_context_from_gc (context, gc);
235
_gdk_quartz_gc_update_cg_context (gc, drawable, context,
237
GDK_QUARTZ_CONTEXT_FILL :
238
GDK_QUARTZ_CONTEXT_STROKE);
232
gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
233
_gdk_gc_get_fg_pixel (gc));
235
242
CGContextMoveToPoint (context, points[0].x, points[0].y);
236
243
for (i = 1; i < npoints; i++)
237
244
CGContextAddLineToPoint (context, points[i].x, points[i].y);
321
gdk_quartz_update_context_from_gc (context, gc);
323
CGContextSetBlendMode (context, kCGBlendModeNormal);
325
_gdk_quartz_gc_update_cg_context (gc, drawable, context,
326
GDK_QUARTZ_CONTEXT_STROKE);
325
328
CGContextClipToRect (context, CGRectMake (xdest, ydest, width, height));
326
329
CGContextTranslateCTM (context, xdest - xsrc, ydest - ysrc);
352
gdk_quartz_update_context_from_gc (context, gc);
353
gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
354
_gdk_gc_get_fg_pixel (gc));
355
_gdk_quartz_gc_update_cg_context (gc, drawable, context,
356
GDK_QUARTZ_CONTEXT_STROKE |
357
GDK_QUARTZ_CONTEXT_FILL);
356
359
/* Just draw 1x1 rectangles */
357
360
for (i = 0; i < npoints; i++)
378
gdk_quartz_update_context_from_gc (context, gc);
379
gdk_quartz_set_context_stroke_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
380
_gdk_gc_get_fg_pixel (gc));
381
_gdk_quartz_gc_update_cg_context (gc, drawable, context,
382
GDK_QUARTZ_CONTEXT_STROKE);
382
384
for (i = 0; i < nsegs; i++)
405
gdk_quartz_update_context_from_gc (context, gc);
406
gdk_quartz_set_context_stroke_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
407
_gdk_gc_get_fg_pixel (gc));
407
_gdk_quartz_gc_update_cg_context (gc, drawable, context,
408
GDK_QUARTZ_CONTEXT_STROKE);
410
CGContextMoveToPoint (context, points[0].x + 0.5, points[0].y + 0.5);
409
412
for (i = 1; i < npoints; i++)
411
CGContextMoveToPoint (context, points[i - 1].x + 0.5, points[i - 1].y + 0.5);
412
CGContextAddLineToPoint (context, points[i].x + 0.5, points[i].y + 0.5);
413
CGContextAddLineToPoint (context, points[i].x + 0.5, points[i].y + 0.5);
415
415
CGContextStrokePath (context);
417
417
gdk_quartz_drawable_release_context (drawable, context);
462
462
CGDataProviderRelease (data_provider);
463
463
CGColorSpaceRelease (colorspace);
465
gdk_quartz_update_context_from_gc (context, gc);
467
CGContextSetBlendMode (context, kCGBlendModeNormal);
465
_gdk_quartz_gc_update_cg_context (gc, drawable, context,
466
GDK_QUARTZ_CONTEXT_STROKE);
469
468
CGContextClipToRect (context, CGRectMake (dest_x, dest_y, width, height));
470
469
CGContextTranslateCTM (context, dest_x - src_x, dest_y - src_y + pixbuf_height);
509
508
CGDataProviderRelease (data_provider);
510
509
CGColorSpaceRelease (colorspace);
512
gdk_quartz_update_context_from_gc (context, gc);
514
CGContextSetBlendMode (context, kCGBlendModeNormal);
511
_gdk_quartz_gc_update_cg_context (gc, drawable, context,
512
GDK_QUARTZ_CONTEXT_STROKE);
516
514
CGContextClipToRect (context, CGRectMake (xdest, ydest, width, height));
517
515
CGContextTranslateCTM (context, xdest - xsrc, ydest - ysrc + image->height);
601
599
gdk_quartz_drawable_get_context (GdkDrawable *drawable,
602
600
gboolean antialias)
602
GdkDrawableImplQuartz *drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
603
CGContextRef cg_context;
605
if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable) &&
606
GDK_WINDOW_DESTROYED (drawable_impl->wrapper))
604
609
if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable))
606
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
607
CGContextRef context;
609
impl->pool = [[NSAutoreleasePool alloc] init];
611
if (![impl->view lockFocusIfCanDraw])
611
GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
613
/* Lock focus when not called as part of a drawRect call. This
614
* is needed when called from outside "real" expose events, for
615
* example for synthesized expose events when realizing windows
616
* and for widgets that send fake expose events like the arrow
617
* buttons in spinbuttons.
619
if (window_impl->in_paint_rect_count == 0)
613
[impl->pool release];
621
window_impl->pool = [[NSAutoreleasePool alloc] init];
622
if (![window_impl->view lockFocusIfCanDraw])
624
[window_impl->pool release];
625
window_impl->pool = NULL;
617
context = [[NSGraphicsContext currentContext] graphicsPort];
619
CGContextSaveGState (context);
620
CGContextSetAllowsAntialiasing (context, antialias);
631
cg_context = [[NSGraphicsContext currentContext] graphicsPort];
632
CGContextSaveGState (cg_context);
633
CGContextSetAllowsAntialiasing (cg_context, antialias);
622
635
/* We'll emulate the clipping caused by double buffering here */
623
if (impl->begin_paint_count != 0)
636
if (window_impl->begin_paint_count != 0)
626
639
CGRect *cg_rects;
627
640
GdkRectangle *rects;
630
gdk_region_get_rectangles (impl->paint_clip_region,
643
gdk_region_get_rectangles (window_impl->paint_clip_region,
631
644
&rects, &n_rects);
633
646
if (n_rects == 1)
643
656
cg_rects[i].size.height = rects[i].height;
646
CGContextClipToRects (context, cg_rects, n_rects);
659
CGContextClipToRects (cg_context, cg_rects, n_rects);
649
662
if (cg_rects != &rect)
650
663
g_free (cg_rects);
655
666
else if (GDK_IS_PIXMAP_IMPL_QUARTZ (drawable))
657
668
GdkPixmapImplQuartz *impl = GDK_PIXMAP_IMPL_QUARTZ (drawable);
658
CGContextRef context;
660
context = CGBitmapContextCreate (impl->data,
661
CGImageGetWidth (impl->image),
662
CGImageGetHeight (impl->image),
663
CGImageGetBitsPerComponent (impl->image),
664
CGImageGetBytesPerRow (impl->image),
665
CGImageGetColorSpace (impl->image),
666
CGImageGetBitmapInfo (impl->image));
667
CGContextSetAllowsAntialiasing (context, antialias);
672
g_assert_not_reached ();
670
cg_context = CGBitmapContextCreate (impl->data,
671
CGImageGetWidth (impl->image),
672
CGImageGetHeight (impl->image),
673
CGImageGetBitsPerComponent (impl->image),
674
CGImageGetBytesPerRow (impl->image),
675
CGImageGetColorSpace (impl->image),
676
CGImageGetBitmapInfo (impl->image));
677
CGContextSetAllowsAntialiasing (cg_context, antialias);
681
g_warning ("Tried to create CGContext for something not a quartz window or pixmap");
678
gdk_quartz_drawable_release_context (GdkDrawable *drawable,
679
CGContextRef context)
689
gdk_quartz_drawable_release_context (GdkDrawable *drawable,
690
CGContextRef cg_context)
684
692
if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable))
686
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
688
CGContextRestoreGState (context);
689
CGContextSetAllowsAntialiasing (context, TRUE);
691
if (impl->in_paint_rect_count == 0 &&
692
impl->begin_paint_count == 0)
693
CGContextFlush (context);
695
[impl->view unlockFocus];
696
[impl->pool release];
694
GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
696
CGContextRestoreGState (cg_context);
697
CGContextSetAllowsAntialiasing (cg_context, TRUE);
699
/* See comment in gdk_quartz_drawable_get_context(). */
700
if (window_impl->in_paint_rect_count == 0)
702
[window_impl->view unlockFocus];
704
if (window_impl->pool)
706
[window_impl->pool release];
707
window_impl->pool = NULL;
698
711
else if (GDK_IS_PIXMAP_IMPL_QUARTZ (drawable))
712
CGContextRelease (cg_context);
716
_gdk_quartz_drawable_finish (GdkDrawable *drawable)
718
GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
720
if (impl->cairo_surface)
700
CGContextRelease (context);
722
cairo_surface_finish (impl->cairo_surface);
723
cairo_surface_set_user_data (impl->cairo_surface, &gdk_quartz_cairo_key,
725
impl->cairo_surface = NULL;