Skip to main content

core_graphics2/
context.rs

1use std::ptr::null;
2
3use core_foundation::{
4    base::{CFType, CFTypeID, TCFType},
5    dictionary::{CFDictionary, CFDictionaryRef},
6    impl_CFTypeDescription, impl_TCFType,
7    string::CFString,
8};
9use libc::{c_int, c_void, size_t};
10#[cfg(feature = "objc")]
11use objc2::encode::{Encoding, RefEncode};
12
13use crate::{
14    affine_transform::CGAffineTransform,
15    base::CGFloat,
16    color::{CGColor, CGColorRef},
17    color_space::{CGColorRenderingIntent, CGColorSpace, CGColorSpaceRef},
18    font::{CGFont, CGFontRef, CGGlyph},
19    geometry::{CGPoint, CGRect, CGSize},
20    gradient::{CGGradient, CGGradientDrawingOptions, CGGradientRef},
21    image::{CGImage, CGImageRef},
22    path::{CGLineCap, CGLineJoin, CGPath, CGPathRef},
23    pattern::{CGPattern, CGPatternRef},
24    shading::{CGShading, CGShadingRef},
25};
26
27#[repr(C)]
28pub struct __CGContext(c_void);
29
30pub type CGContextRef = *mut __CGContext;
31
32#[repr(i32)]
33#[derive(Clone, Copy, Debug, Eq, PartialEq)]
34pub enum CGPathDrawingMode {
35    #[doc(alias = "kCGPathFill")]
36    Fill         = 0,
37    #[doc(alias = "kCGPathEOFill")]
38    EOFill       = 1,
39    #[doc(alias = "kCGPathStroke")]
40    Stroke       = 2,
41    #[doc(alias = "kCGPathFillStroke")]
42    FillStroke   = 3,
43    #[doc(alias = "kCGPathEOFillStroke")]
44    EOFillStroke = 4,
45}
46
47#[repr(i32)]
48#[derive(Clone, Copy, Debug, Eq, PartialEq)]
49pub enum CGTextDrawingMode {
50    #[doc(alias = "kCGTextFill")]
51    Fill           = 0,
52    #[doc(alias = "kCGTextStroke")]
53    Stroke         = 1,
54    #[doc(alias = "kCGTextFillStroke")]
55    FillStroke     = 2,
56    #[doc(alias = "kCGTextInvisible")]
57    Invisible      = 3,
58    #[doc(alias = "kCGTextFillClip")]
59    FillClip       = 4,
60    #[doc(alias = "kCGTextStrokeClip")]
61    StrokeClip     = 5,
62    #[doc(alias = "kCGTextFillStrokeClip")]
63    FillStrokeClip = 6,
64    #[doc(alias = "kCGTextClip")]
65    Clip           = 7,
66}
67
68#[repr(i32)]
69#[derive(Clone, Copy, Debug, Eq, PartialEq)]
70pub enum CGTextEncoding {
71    #[doc(alias = "kCGEncodingFontSpecific")]
72    FontSpecific = 0,
73    #[doc(alias = "kCGEncodingMacRoman")]
74    MacRoman     = 1,
75}
76
77#[repr(i32)]
78#[derive(Clone, Copy, Debug, Eq, PartialEq)]
79pub enum CGInterpolationQuality {
80    #[doc(alias = "kCGInterpolationDefault")]
81    Default = 0,
82    #[doc(alias = "kCGInterpolationNone")]
83    None    = 1,
84    #[doc(alias = "kCGInterpolationLow")]
85    Low     = 2,
86    #[doc(alias = "kCGInterpolationMedium")]
87    Medium  = 4,
88    #[doc(alias = "kCGInterpolationHigh")]
89    High    = 3,
90}
91
92#[repr(i32)]
93#[derive(Clone, Copy, Debug, Eq, PartialEq)]
94pub enum CGBlendMode {
95    #[doc(alias = "kCGBlendModeNormal")]
96    Normal          = 0,
97    #[doc(alias = "kCGBlendModeMultiply")]
98    Multiply        = 1,
99    #[doc(alias = "kCGBlendModeScreen")]
100    Screen          = 2,
101    #[doc(alias = "kCGBlendModeOverlay")]
102    Overlay         = 3,
103    #[doc(alias = "kCGBlendModeDarken")]
104    Darken          = 4,
105    #[doc(alias = "kCGBlendModeLighten")]
106    Lighten         = 5,
107    #[doc(alias = "kCGBlendModeColorDodge")]
108    ColorDodge      = 6,
109    #[doc(alias = "kCGBlendModeColorBurn")]
110    ColorBurn       = 7,
111    #[doc(alias = "kCGBlendModeSoftLight")]
112    SoftLight       = 8,
113    #[doc(alias = "kCGBlendModeHardLight")]
114    HardLight       = 9,
115    #[doc(alias = "kCGBlendModeDifference")]
116    Difference      = 10,
117    #[doc(alias = "kCGBlendModeExclusion")]
118    Exclusion       = 11,
119    #[doc(alias = "kCGBlendModeHue")]
120    Hue             = 12,
121    #[doc(alias = "kCGBlendModeSaturation")]
122    Saturation      = 13,
123    #[doc(alias = "kCGBlendModeColor")]
124    Color           = 14,
125    #[doc(alias = "kCGBlendModeLuminosity")]
126    Luminosity      = 15,
127    #[doc(alias = "kCGBlendModeClear")]
128    Clear           = 16, // R = 0
129    #[doc(alias = "kCGBlendModeCopy")]
130    Copy            = 17, // R = S
131    #[doc(alias = "kCGBlendModeSourceIn")]
132    SourceIn        = 18, // R = S*Da
133    #[doc(alias = "kCGBlendModeSourceOut")]
134    SourceOut       = 19, // R = S*(1 - Da)
135    #[doc(alias = "kCGBlendModeSourceAtop")]
136    SourceAtop      = 20, // R = S*Da + D*(1 - Sa)
137    #[doc(alias = "kCGBlendModeDestinationOver")]
138    DestinationOver = 21, // R = S*(1 - Da) + D
139    #[doc(alias = "kCGBlendModeDestinationIn")]
140    DestinationIn   = 22, // R = D*Sa
141    #[doc(alias = "kCGBlendModeDestinationOut")]
142    DestinationOut  = 23, // R = D*(1 - Sa)
143    #[doc(alias = "kCGBlendModeDestinationAtop")]
144    DestinationAtop = 24, // R = S*(1 - Da) + D*Sa
145    #[doc(alias = "kCGBlendModeXOR")]
146    XOR             = 25, // R = S*(1 - Da) + D*(1 - Sa)
147    #[doc(alias = "kCGBlendModePlusDarker")]
148    PlusDarker      = 26, // R = MAX(0, (1 - D) + (1 - S))
149    #[doc(alias = "kCGBlendModePlusLighter")]
150    PlusLighter     = 27, // R = MIN(1, S + D)
151}
152
153extern "C" {
154    pub fn CGContextGetTypeID() -> CFTypeID;
155    pub fn CGContextSaveGState(c: CGContextRef);
156    pub fn CGContextRestoreGState(c: CGContextRef);
157    pub fn CGContextScaleCTM(c: CGContextRef, sx: CGFloat, sy: CGFloat);
158    pub fn CGContextTranslateCTM(c: CGContextRef, tx: CGFloat, ty: CGFloat);
159    pub fn CGContextRotateCTM(c: CGContextRef, angle: CGFloat);
160    pub fn CGContextConcatCTM(c: CGContextRef, transform: CGAffineTransform);
161    pub fn CGContextGetCTM(c: CGContextRef) -> CGAffineTransform;
162    pub fn CGContextSetLineWidth(c: CGContextRef, width: CGFloat);
163    pub fn CGContextSetLineCap(c: CGContextRef, cap: CGLineCap);
164    pub fn CGContextSetLineJoin(c: CGContextRef, join: CGLineJoin);
165    pub fn CGContextSetMiterLimit(c: CGContextRef, limit: CGFloat);
166    pub fn CGContextSetLineDash(c: CGContextRef, phase: CGFloat, lengths: *const CGFloat, count: size_t);
167    pub fn CGContextSetFlatness(c: CGContextRef, flatness: CGFloat);
168    pub fn CGContextSetAlpha(c: CGContextRef, alpha: CGFloat);
169    pub fn CGContextSetBlendMode(c: CGContextRef, mode: CGBlendMode);
170    pub fn CGContextBeginPath(c: CGContextRef);
171    pub fn CGContextMoveToPoint(c: CGContextRef, x: CGFloat, y: CGFloat);
172    pub fn CGContextAddLineToPoint(c: CGContextRef, x: CGFloat, y: CGFloat);
173    pub fn CGContextAddCurveToPoint(c: CGContextRef, cp1x: CGFloat, cp1y: CGFloat, cp2x: CGFloat, cp2y: CGFloat, x: CGFloat, y: CGFloat);
174    pub fn CGContextAddQuadCurveToPoint(c: CGContextRef, cpx: CGFloat, cpy: CGFloat, x: CGFloat, y: CGFloat);
175    pub fn CGContextClosePath(c: CGContextRef);
176    pub fn CGContextAddRect(c: CGContextRef, rect: CGRect);
177    pub fn CGContextAddRects(c: CGContextRef, rects: *const CGRect, count: size_t);
178    pub fn CGContextAddLines(c: CGContextRef, points: *const CGPoint, count: size_t);
179    pub fn CGContextAddEllipseInRect(c: CGContextRef, rect: CGRect);
180    pub fn CGContextAddArc(c: CGContextRef, x: CGFloat, y: CGFloat, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: bool);
181    pub fn CGContextAddArcToPoint(c: CGContextRef, x1: CGFloat, y1: CGFloat, x2: CGFloat, y2: CGFloat, radius: CGFloat);
182    pub fn CGContextAddPath(c: CGContextRef, path: CGPathRef);
183    pub fn CGContextReplacePathWithStrokedPath(c: CGContextRef);
184    pub fn CGContextIsPathEmpty(c: CGContextRef) -> bool;
185    pub fn CGContextGetPathCurrentPoint(c: CGContextRef) -> CGPoint;
186    pub fn CGContextGetPathBoundingBox(c: CGContextRef) -> CGRect;
187    pub fn CGContextCopyPath(c: CGContextRef) -> CGPathRef;
188    pub fn CGContextPathContainsPoint(c: CGContextRef, point: CGPoint, mode: CGPathDrawingMode) -> bool;
189    pub fn CGContextDrawPath(c: CGContextRef, mode: CGPathDrawingMode);
190    pub fn CGContextFillPath(c: CGContextRef);
191    pub fn CGContextEOFillPath(c: CGContextRef);
192    pub fn CGContextStrokePath(c: CGContextRef);
193    pub fn CGContextFillRect(c: CGContextRef, rect: CGRect);
194    pub fn CGContextFillRects(c: CGContextRef, rects: *const CGRect, count: size_t);
195    pub fn CGContextStrokeRect(c: CGContextRef, rect: CGRect);
196    pub fn CGContextStrokeRectWithWidth(c: CGContextRef, rect: CGRect, width: CGFloat);
197    pub fn CGContextClearRect(c: CGContextRef, rect: CGRect);
198    pub fn CGContextFillEllipseInRect(c: CGContextRef, rect: CGRect);
199    pub fn CGContextStrokeEllipseInRect(c: CGContextRef, rect: CGRect);
200    pub fn CGContextStrokeLineSegments(c: CGContextRef, points: *const CGPoint, count: size_t);
201    pub fn CGContextClip(c: CGContextRef);
202    pub fn CGContextEOClip(c: CGContextRef);
203    pub fn CGContextResetClip(c: CGContextRef);
204    pub fn CGContextClipToMask(c: CGContextRef, rect: CGRect, mask: CGImageRef);
205    pub fn CGContextGetClipBoundingBox(c: CGContextRef) -> CGRect;
206    pub fn CGContextClipToRect(c: CGContextRef, rect: CGRect);
207    pub fn CGContextClipToRects(c: CGContextRef, rects: *const CGRect, count: size_t);
208    pub fn CGContextSetFillColorWithColor(c: CGContextRef, color: CGColorRef);
209    pub fn CGContextSetStrokeColorWithColor(c: CGContextRef, color: CGColorRef);
210    pub fn CGContextSetFillColorSpace(c: CGContextRef, space: CGColorSpaceRef);
211    pub fn CGContextSetStrokeColorSpace(c: CGContextRef, space: CGColorSpaceRef);
212    pub fn CGContextSetFillColor(c: CGContextRef, components: *const CGFloat);
213    pub fn CGContextSetStrokeColor(c: CGContextRef, components: *const CGFloat);
214    pub fn CGContextSetFillPattern(c: CGContextRef, pattern: CGPatternRef, components: *const CGFloat);
215    pub fn CGContextSetStrokePattern(c: CGContextRef, pattern: CGPatternRef, components: *const CGFloat);
216    pub fn CGContextSetPatternPhase(c: CGContextRef, phase: CGSize);
217    pub fn CGContextSetGrayFillColor(c: CGContextRef, gray: CGFloat, alpha: CGFloat);
218    pub fn CGContextSetGrayStrokeColor(c: CGContextRef, gray: CGFloat, alpha: CGFloat);
219    pub fn CGContextSetRGBFillColor(c: CGContextRef, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat);
220    pub fn CGContextSetRGBStrokeColor(c: CGContextRef, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat);
221    pub fn CGContextSetCMYKFillColor(c: CGContextRef, cyan: CGFloat, magenta: CGFloat, yellow: CGFloat, black: CGFloat, alpha: CGFloat);
222    pub fn CGContextSetCMYKStrokeColor(c: CGContextRef, cyan: CGFloat, magenta: CGFloat, yellow: CGFloat, black: CGFloat, alpha: CGFloat);
223    pub fn CGContextSetRenderingIntent(c: CGContextRef, intent: CGColorRenderingIntent);
224    pub fn CGContextDrawImage(c: CGContextRef, rect: CGRect, image: CGImageRef);
225    pub fn CGContextDrawTiledImage(c: CGContextRef, rect: CGRect, image: CGImageRef);
226    pub fn CGContextGetInterpolationQuality(c: CGContextRef) -> CGInterpolationQuality;
227    pub fn CGContextSetInterpolationQuality(c: CGContextRef, quality: CGInterpolationQuality);
228    pub fn CGContextSetShadowWithColor(c: CGContextRef, offset: CGSize, blur: CGFloat, color: CGColorRef);
229    pub fn CGContextSetShadow(c: CGContextRef, offset: CGSize, blur: CGFloat);
230    pub fn CGContextDrawLinearGradient(
231        c: CGContextRef,
232        gradient: CGGradientRef,
233        startPoint: CGPoint,
234        endPoint: CGPoint,
235        options: CGGradientDrawingOptions,
236    );
237    pub fn CGContextDrawRadialGradient(
238        c: CGContextRef,
239        gradient: CGGradientRef,
240        startCenter: CGPoint,
241        startRadius: CGFloat,
242        endCenter: CGPoint,
243        endRadius: CGFloat,
244        options: CGGradientDrawingOptions,
245    );
246    pub fn CGContextDrawShading(c: CGContextRef, shading: CGShadingRef);
247    pub fn CGContextSetCharacterSpacing(c: CGContextRef, spacing: CGFloat);
248    pub fn CGContextSetTextPosition(c: CGContextRef, x: CGFloat, y: CGFloat);
249    pub fn CGContextGetTextPosition(c: CGContextRef) -> CGPoint;
250    pub fn CGContextSetTextMatrix(c: CGContextRef, t: CGAffineTransform);
251    pub fn CGContextGetTextMatrix(c: CGContextRef) -> CGAffineTransform;
252    pub fn CGContextSetTextDrawingMode(c: CGContextRef, mode: CGTextDrawingMode);
253    pub fn CGContextSetFont(c: CGContextRef, font: CGFontRef);
254    pub fn CGContextSetFontSize(c: CGContextRef, size: CGFloat);
255    pub fn CGContextShowGlyphsAtPositions(c: CGContextRef, glyphs: *const CGGlyph, positions: *const CGPoint, count: size_t);
256    pub fn CGContextBeginPage(c: CGContextRef, mediaBox: *const CGRect);
257    pub fn CGContextEndPage(c: CGContextRef);
258    pub fn CGContextRetain(c: CGContextRef) -> CGContextRef;
259    pub fn CGContextRelease(c: CGContextRef);
260    pub fn CGContextFlush(c: CGContextRef);
261    pub fn CGContextSynchronize(c: CGContextRef);
262    pub fn CGContextSetShouldAntialias(c: CGContextRef, shouldAntialias: bool);
263    pub fn CGContextSetAllowsAntialiasing(c: CGContextRef, allowsAntialiasing: bool);
264    pub fn CGContextSetShouldSmoothFonts(c: CGContextRef, shouldSmoothFonts: bool);
265    pub fn CGContextSetAllowsFontSmoothing(c: CGContextRef, allowsFontSmoothing: bool);
266    pub fn CGContextSetShouldSubpixelPositionFonts(c: CGContextRef, shouldSubpixelPositionFonts: bool);
267    pub fn CGContextSetAllowsFontSubpixelPositioning(c: CGContextRef, allowsFontSubpixelPositioning: bool);
268    pub fn CGContextSetShouldSubpixelQuantizeFonts(c: CGContextRef, shouldSubpixelQuantizeFonts: bool);
269    pub fn CGContextSetAllowsFontSubpixelQuantization(c: CGContextRef, allowsFontSubpixelQuantization: bool);
270    pub fn CGContextSetFontSmoothingStyle(c: CGContextRef, style: c_int);
271    pub fn CGContextBeginTransparencyLayer(c: CGContextRef, auxInfo: CFDictionaryRef);
272    pub fn CGContextBeginTransparencyLayerWithRect(c: CGContextRef, rect: CGRect, auxInfo: CFDictionaryRef);
273    pub fn CGContextEndTransparencyLayer(c: CGContextRef);
274    pub fn CGContextGetUserSpaceToDeviceSpaceTransform(c: CGContextRef) -> CGAffineTransform;
275    pub fn CGContextConvertPointToDeviceSpace(c: CGContextRef, point: CGPoint) -> CGPoint;
276    pub fn CGContextConvertPointToUserSpace(c: CGContextRef, point: CGPoint) -> CGPoint;
277    pub fn CGContextConvertSizeToDeviceSpace(c: CGContextRef, size: CGSize) -> CGSize;
278    pub fn CGContextConvertSizeToUserSpace(c: CGContextRef, size: CGSize) -> CGSize;
279    pub fn CGContextConvertRectToDeviceSpace(c: CGContextRef, rect: CGRect) -> CGRect;
280    pub fn CGContextConvertRectToUserSpace(c: CGContextRef, rect: CGRect) -> CGRect;
281}
282
283pub struct CGContext(CGContextRef);
284
285impl Drop for CGContext {
286    fn drop(&mut self) {
287        unsafe { CGContextRelease(self.as_concrete_TypeRef()) }
288    }
289}
290
291impl_TCFType!(CGContext, CGContextRef, CGContextGetTypeID);
292impl_CFTypeDescription!(CGContext);
293
294impl CGContext {
295    pub fn save_state(&self) {
296        unsafe { CGContextSaveGState(self.as_concrete_TypeRef()) }
297    }
298
299    pub fn restore_state(&self) {
300        unsafe { CGContextRestoreGState(self.as_concrete_TypeRef()) }
301    }
302
303    pub fn scale(&self, sx: CGFloat, sy: CGFloat) {
304        unsafe {
305            CGContextScaleCTM(self.as_concrete_TypeRef(), sx, sy);
306        }
307    }
308
309    pub fn translate(&self, tx: CGFloat, ty: CGFloat) {
310        unsafe {
311            CGContextTranslateCTM(self.as_concrete_TypeRef(), tx, ty);
312        }
313    }
314
315    pub fn rotate(&self, angle: CGFloat) {
316        unsafe {
317            CGContextRotateCTM(self.as_concrete_TypeRef(), angle);
318        }
319    }
320
321    pub fn concat_ctm(&self, transform: CGAffineTransform) {
322        unsafe { CGContextConcatCTM(self.as_concrete_TypeRef(), transform) }
323    }
324
325    pub fn get_ctm(&self) -> CGAffineTransform {
326        unsafe { CGContextGetCTM(self.as_concrete_TypeRef()) }
327    }
328
329    pub fn set_line_width(&self, width: CGFloat) {
330        unsafe { CGContextSetLineWidth(self.as_concrete_TypeRef(), width) }
331    }
332
333    pub fn set_line_cap(&self, cap: CGLineCap) {
334        unsafe { CGContextSetLineCap(self.as_concrete_TypeRef(), cap) }
335    }
336
337    pub fn set_line_join(&self, join: CGLineJoin) {
338        unsafe { CGContextSetLineJoin(self.as_concrete_TypeRef(), join) }
339    }
340
341    pub fn set_line_dash(&self, phase: CGFloat, lengths: &[CGFloat]) {
342        unsafe { CGContextSetLineDash(self.as_concrete_TypeRef(), phase, lengths.as_ptr(), lengths.len()) }
343    }
344
345    pub fn set_miter_limit(&self, limit: CGFloat) {
346        unsafe { CGContextSetMiterLimit(self.as_concrete_TypeRef(), limit) }
347    }
348
349    pub fn set_flatness(&self, flatness: CGFloat) {
350        unsafe { CGContextSetFlatness(self.as_concrete_TypeRef(), flatness) }
351    }
352
353    pub fn set_alpha(&self, alpha: CGFloat) {
354        unsafe {
355            CGContextSetAlpha(self.as_concrete_TypeRef(), alpha);
356        }
357    }
358
359    pub fn set_blend_mode(&self, mode: CGBlendMode) {
360        unsafe {
361            CGContextSetBlendMode(self.as_concrete_TypeRef(), mode);
362        }
363    }
364
365    pub fn begin_path(&self) {
366        unsafe {
367            CGContextBeginPath(self.as_concrete_TypeRef());
368        }
369    }
370
371    pub fn close_path(&self) {
372        unsafe {
373            CGContextClosePath(self.as_concrete_TypeRef());
374        }
375    }
376
377    pub fn move_to_point(&self, x: CGFloat, y: CGFloat) {
378        unsafe {
379            CGContextMoveToPoint(self.as_concrete_TypeRef(), x, y);
380        }
381    }
382
383    pub fn add_line_to_point(&self, x: CGFloat, y: CGFloat) {
384        unsafe {
385            CGContextAddLineToPoint(self.as_concrete_TypeRef(), x, y);
386        }
387    }
388
389    pub fn add_curve_to_point(&self, cp1x: CGFloat, cp1y: CGFloat, cp2x: CGFloat, cp2y: CGFloat, x: CGFloat, y: CGFloat) {
390        unsafe {
391            CGContextAddCurveToPoint(self.as_concrete_TypeRef(), cp1x, cp1y, cp2x, cp2y, x, y);
392        }
393    }
394
395    pub fn add_quad_curve_to_point(&self, cpx: CGFloat, cpy: CGFloat, x: CGFloat, y: CGFloat) {
396        unsafe {
397            CGContextAddQuadCurveToPoint(self.as_concrete_TypeRef(), cpx, cpy, x, y);
398        }
399    }
400
401    pub fn add_rect(&self, rect: CGRect) {
402        unsafe {
403            CGContextAddRect(self.as_concrete_TypeRef(), rect);
404        }
405    }
406
407    pub fn add_rects(&self, rects: &[CGRect]) {
408        unsafe {
409            CGContextAddRects(self.as_concrete_TypeRef(), rects.as_ptr(), rects.len());
410        }
411    }
412
413    pub fn add_lines(&self, points: &[CGPoint]) {
414        unsafe {
415            CGContextAddLines(self.as_concrete_TypeRef(), points.as_ptr(), points.len());
416        }
417    }
418
419    pub fn add_ellipse_in_rect(&self, rect: CGRect) {
420        unsafe {
421            CGContextAddEllipseInRect(self.as_concrete_TypeRef(), rect);
422        }
423    }
424
425    pub fn add_arc(&self, x: CGFloat, y: CGFloat, radius: CGFloat, start_angle: CGFloat, end_angle: CGFloat, clockwise: bool) {
426        unsafe {
427            CGContextAddArc(self.as_concrete_TypeRef(), x, y, radius, start_angle, end_angle, clockwise);
428        }
429    }
430
431    pub fn add_arc_to_point(&self, x1: CGFloat, y1: CGFloat, x2: CGFloat, y2: CGFloat, radius: CGFloat) {
432        unsafe {
433            CGContextAddArcToPoint(self.as_concrete_TypeRef(), x1, y1, x2, y2, radius);
434        }
435    }
436
437    pub fn add_path(&self, path: &CGPath) {
438        unsafe {
439            CGContextAddPath(self.as_concrete_TypeRef(), path.as_concrete_TypeRef());
440        }
441    }
442
443    pub fn replace_path_with_stroked_path(&self) {
444        unsafe { CGContextReplacePathWithStrokedPath(self.as_concrete_TypeRef()) }
445    }
446
447    pub fn is_path_empty(&self) -> bool {
448        unsafe { CGContextIsPathEmpty(self.as_concrete_TypeRef()) }
449    }
450
451    pub fn get_path_current_point(&self) -> CGPoint {
452        unsafe { CGContextGetPathCurrentPoint(self.as_concrete_TypeRef()) }
453    }
454
455    pub fn get_path_bounding_box(&self) -> CGRect {
456        unsafe { CGContextGetPathBoundingBox(self.as_concrete_TypeRef()) }
457    }
458
459    pub fn copy_path(&self) -> Option<CGPath> {
460        unsafe {
461            let path = CGContextCopyPath(self.as_concrete_TypeRef());
462            if path.is_null() {
463                None
464            } else {
465                Some(TCFType::wrap_under_create_rule(path))
466            }
467        }
468    }
469
470    pub fn path_contains_point(&self, point: CGPoint, mode: CGPathDrawingMode) -> bool {
471        unsafe { CGContextPathContainsPoint(self.as_concrete_TypeRef(), point, mode) }
472    }
473
474    pub fn draw_path(&self, mode: CGPathDrawingMode) {
475        unsafe {
476            CGContextDrawPath(self.as_concrete_TypeRef(), mode);
477        }
478    }
479
480    pub fn fill_path(&self) {
481        unsafe {
482            CGContextFillPath(self.as_concrete_TypeRef());
483        }
484    }
485
486    pub fn eo_fill_path(&self) {
487        unsafe {
488            CGContextEOFillPath(self.as_concrete_TypeRef());
489        }
490    }
491
492    pub fn stroke_path(&self) {
493        unsafe {
494            CGContextStrokePath(self.as_concrete_TypeRef());
495        }
496    }
497
498    pub fn fill_rect(&self, rect: CGRect) {
499        unsafe { CGContextFillRect(self.as_concrete_TypeRef(), rect) }
500    }
501
502    pub fn fill_rects(&self, rects: &[CGRect]) {
503        unsafe { CGContextFillRects(self.as_concrete_TypeRef(), rects.as_ptr(), rects.len()) }
504    }
505
506    pub fn stroke_rect(&self, rect: CGRect) {
507        unsafe { CGContextStrokeRect(self.as_concrete_TypeRef(), rect) }
508    }
509
510    pub fn stroke_rect_with_width(&self, rect: CGRect, width: CGFloat) {
511        unsafe { CGContextStrokeRectWithWidth(self.as_concrete_TypeRef(), rect, width) }
512    }
513
514    pub fn clear_rect(&self, rect: CGRect) {
515        unsafe { CGContextClearRect(self.as_concrete_TypeRef(), rect) }
516    }
517
518    pub fn fill_ellipse_in_rect(&self, rect: CGRect) {
519        unsafe { CGContextFillEllipseInRect(self.as_concrete_TypeRef(), rect) }
520    }
521
522    pub fn stroke_ellipse_in_rect(&self, rect: CGRect) {
523        unsafe { CGContextStrokeEllipseInRect(self.as_concrete_TypeRef(), rect) }
524    }
525
526    pub fn stroke_line_segments(&self, points: &[CGPoint]) {
527        unsafe { CGContextStrokeLineSegments(self.as_concrete_TypeRef(), points.as_ptr(), points.len()) }
528    }
529
530    pub fn clip(&self) {
531        unsafe {
532            CGContextClip(self.as_concrete_TypeRef());
533        }
534    }
535
536    pub fn eo_clip(&self) {
537        unsafe {
538            CGContextEOClip(self.as_concrete_TypeRef());
539        }
540    }
541
542    pub fn reset_clip(&self) {
543        unsafe {
544            CGContextResetClip(self.as_concrete_TypeRef());
545        }
546    }
547
548    pub fn clip_to_mask(&self, rect: CGRect, image: &CGImage) {
549        unsafe { CGContextClipToMask(self.as_concrete_TypeRef(), rect, image.as_concrete_TypeRef()) }
550    }
551
552    pub fn clip_bounding_box(&self) -> CGRect {
553        unsafe { CGContextGetClipBoundingBox(self.as_concrete_TypeRef()) }
554    }
555
556    pub fn clip_to_rect(&self, rect: CGRect) {
557        unsafe { CGContextClipToRect(self.as_concrete_TypeRef(), rect) }
558    }
559
560    pub fn clip_to_rects(&self, rects: &[CGRect]) {
561        unsafe { CGContextClipToRects(self.as_concrete_TypeRef(), rects.as_ptr(), rects.len()) }
562    }
563
564    pub fn set_fill_color(&self, color: &CGColor) {
565        unsafe {
566            CGContextSetFillColorWithColor(self.as_concrete_TypeRef(), color.as_concrete_TypeRef());
567        }
568    }
569
570    pub fn set_stroke_color(&self, color: &CGColor) {
571        unsafe {
572            CGContextSetStrokeColorWithColor(self.as_concrete_TypeRef(), color.as_concrete_TypeRef());
573        }
574    }
575
576    pub fn set_fill_color_space(&self, space: &CGColorSpace) {
577        unsafe {
578            CGContextSetFillColorSpace(self.as_concrete_TypeRef(), space.as_concrete_TypeRef());
579        }
580    }
581
582    pub fn set_stroke_color_space(&self, space: &CGColorSpace) {
583        unsafe {
584            CGContextSetStrokeColorSpace(self.as_concrete_TypeRef(), space.as_concrete_TypeRef());
585        }
586    }
587
588    pub unsafe fn set_fill_pattern(&self, pattern: &CGPattern, components: &[CGFloat]) {
589        unsafe {
590            CGContextSetFillPattern(self.as_concrete_TypeRef(), pattern.as_concrete_TypeRef(), components.as_ptr());
591        }
592    }
593
594    pub unsafe fn set_stroke_pattern(&self, pattern: &CGPattern, components: &[CGFloat]) {
595        unsafe {
596            CGContextSetStrokePattern(self.as_concrete_TypeRef(), pattern.as_concrete_TypeRef(), components.as_ptr());
597        }
598    }
599
600    pub fn set_pattern_phase(&self, phase: CGSize) {
601        unsafe {
602            CGContextSetPatternPhase(self.as_concrete_TypeRef(), phase);
603        }
604    }
605
606    pub fn set_gray_fill_color(&self, gray: CGFloat, alpha: CGFloat) {
607        unsafe {
608            CGContextSetGrayFillColor(self.as_concrete_TypeRef(), gray, alpha);
609        }
610    }
611
612    pub fn set_gray_stroke_color(&self, gray: CGFloat, alpha: CGFloat) {
613        unsafe {
614            CGContextSetGrayStrokeColor(self.as_concrete_TypeRef(), gray, alpha);
615        }
616    }
617
618    pub fn set_rgb_fill_color(&self, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
619        unsafe { CGContextSetRGBFillColor(self.as_concrete_TypeRef(), red, green, blue, alpha) }
620    }
621
622    pub fn set_rgb_stroke_color(&self, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
623        unsafe { CGContextSetRGBStrokeColor(self.as_concrete_TypeRef(), red, green, blue, alpha) }
624    }
625
626    pub fn set_cmyk_fill_color(&self, cyan: CGFloat, magenta: CGFloat, yellow: CGFloat, black: CGFloat, alpha: CGFloat) {
627        unsafe {
628            CGContextSetCMYKFillColor(self.as_concrete_TypeRef(), cyan, magenta, yellow, black, alpha);
629        }
630    }
631
632    pub fn set_cmyk_stroke_color(&self, cyan: CGFloat, magenta: CGFloat, yellow: CGFloat, black: CGFloat, alpha: CGFloat) {
633        unsafe {
634            CGContextSetCMYKStrokeColor(self.as_concrete_TypeRef(), cyan, magenta, yellow, black, alpha);
635        }
636    }
637
638    pub fn set_rendering_intent(&self, intent: CGColorRenderingIntent) {
639        unsafe {
640            CGContextSetRenderingIntent(self.as_concrete_TypeRef(), intent);
641        }
642    }
643
644    pub fn draw_image(&self, rect: CGRect, image: &CGImage) {
645        unsafe {
646            CGContextDrawImage(self.as_concrete_TypeRef(), rect, image.as_concrete_TypeRef());
647        }
648    }
649
650    pub fn draw_tiled_image(&self, rect: CGRect, image: &CGImage) {
651        unsafe {
652            CGContextDrawTiledImage(self.as_concrete_TypeRef(), rect, image.as_concrete_TypeRef());
653        }
654    }
655
656    pub fn get_interpolation_quality(&self) -> CGInterpolationQuality {
657        unsafe { CGContextGetInterpolationQuality(self.as_concrete_TypeRef()) }
658    }
659
660    pub fn set_interpolation_quality(&self, quality: CGInterpolationQuality) {
661        unsafe {
662            CGContextSetInterpolationQuality(self.as_concrete_TypeRef(), quality);
663        }
664    }
665
666    pub fn draw_linear_gradient(&self, gradient: &CGGradient, start_point: CGPoint, end_point: CGPoint, options: CGGradientDrawingOptions) {
667        unsafe {
668            CGContextDrawLinearGradient(self.as_concrete_TypeRef(), gradient.as_concrete_TypeRef(), start_point, end_point, options);
669        }
670    }
671
672    pub fn draw_radial_gradient(
673        &self,
674        gradient: &CGGradient,
675        start_center: CGPoint,
676        start_radius: CGFloat,
677        end_center: CGPoint,
678        end_radius: CGFloat,
679        options: CGGradientDrawingOptions,
680    ) {
681        unsafe {
682            CGContextDrawRadialGradient(
683                self.as_concrete_TypeRef(),
684                gradient.as_concrete_TypeRef(),
685                start_center,
686                start_radius,
687                end_center,
688                end_radius,
689                options,
690            );
691        }
692    }
693
694    pub fn set_shadow(&self, offset: CGSize, blur: CGFloat) {
695        unsafe {
696            CGContextSetShadow(self.as_concrete_TypeRef(), offset, blur);
697        }
698    }
699
700    pub fn set_shadow_with_color(&self, offset: CGSize, blur: CGFloat, color: &CGColor) {
701        unsafe {
702            CGContextSetShadowWithColor(self.as_concrete_TypeRef(), offset, blur, color.as_concrete_TypeRef());
703        }
704    }
705
706    pub fn draw_shading(&self, shading: &CGShading) {
707        unsafe {
708            CGContextDrawShading(self.as_concrete_TypeRef(), shading.as_concrete_TypeRef());
709        }
710    }
711
712    pub fn set_font(&self, font: &CGFont) {
713        unsafe { CGContextSetFont(self.as_concrete_TypeRef(), font.as_concrete_TypeRef()) }
714    }
715
716    pub fn set_font_size(&self, size: CGFloat) {
717        unsafe { CGContextSetFontSize(self.as_concrete_TypeRef(), size) }
718    }
719
720    pub fn set_text_matrix(&self, t: &CGAffineTransform) {
721        unsafe { CGContextSetTextMatrix(self.as_concrete_TypeRef(), *t) }
722    }
723
724    pub fn set_text_drawing_mode(&self, mode: CGTextDrawingMode) {
725        unsafe { CGContextSetTextDrawingMode(self.as_concrete_TypeRef(), mode) }
726    }
727
728    pub fn set_text_position(&self, x: CGFloat, y: CGFloat) {
729        unsafe { CGContextSetTextPosition(self.as_concrete_TypeRef(), x, y) }
730    }
731
732    pub fn set_allows_font_smoothing(&self, allows_font_smoothing: bool) {
733        unsafe { CGContextSetAllowsFontSmoothing(self.as_concrete_TypeRef(), allows_font_smoothing) }
734    }
735
736    pub fn set_should_smooth_fonts(&self, should_smooth_fonts: bool) {
737        unsafe { CGContextSetShouldSmoothFonts(self.as_concrete_TypeRef(), should_smooth_fonts) }
738    }
739
740    pub fn set_allows_antialiasing(&self, allows_antialiasing: bool) {
741        unsafe { CGContextSetAllowsAntialiasing(self.as_concrete_TypeRef(), allows_antialiasing) }
742    }
743
744    pub fn set_should_antialias(&self, should_antialias: bool) {
745        unsafe { CGContextSetShouldAntialias(self.as_concrete_TypeRef(), should_antialias) }
746    }
747
748    pub fn set_allows_font_subpixel_quantization(&self, allows_font_subpixel_quantization: bool) {
749        unsafe { CGContextSetAllowsFontSubpixelQuantization(self.as_concrete_TypeRef(), allows_font_subpixel_quantization) }
750    }
751
752    pub fn set_should_subpixel_quantize_fonts(&self, should_subpixel_quantize_fonts: bool) {
753        unsafe { CGContextSetShouldSubpixelQuantizeFonts(self.as_concrete_TypeRef(), should_subpixel_quantize_fonts) }
754    }
755
756    pub fn set_allows_font_subpixel_positioning(&self, allows_font_subpixel_positioning: bool) {
757        unsafe { CGContextSetAllowsFontSubpixelPositioning(self.as_concrete_TypeRef(), allows_font_subpixel_positioning) }
758    }
759
760    pub fn set_should_subpixel_position_fonts(&self, should_subpixel_position_fonts: bool) {
761        unsafe { CGContextSetShouldSubpixelPositionFonts(self.as_concrete_TypeRef(), should_subpixel_position_fonts) }
762    }
763
764    pub fn set_font_smoothing_style(&self, style: i32) {
765        unsafe {
766            CGContextSetFontSmoothingStyle(self.as_concrete_TypeRef(), style as _);
767        }
768    }
769
770    pub fn show_glyphs_at_positions(&self, glyphs: &[CGGlyph], positions: &[CGPoint]) {
771        unsafe {
772            let count = std::cmp::min(glyphs.len(), positions.len());
773            CGContextShowGlyphsAtPositions(self.as_concrete_TypeRef(), glyphs.as_ptr(), positions.as_ptr(), count)
774        }
775    }
776
777    pub fn begin_transparency_layer(&self, aux_info: Option<&CFDictionary<CFString, CFType>>) {
778        unsafe {
779            CGContextBeginTransparencyLayer(self.as_concrete_TypeRef(), aux_info.map_or(null(), |info| info.as_concrete_TypeRef()));
780        }
781    }
782
783    pub fn flush(&self) {
784        unsafe { CGContextFlush(self.as_concrete_TypeRef()) }
785    }
786
787    pub fn synchronize(&self) {
788        unsafe { CGContextSynchronize(self.as_concrete_TypeRef()) }
789    }
790
791    pub fn begin_page(&self, media_box: &CGRect) {
792        unsafe { CGContextBeginPage(self.as_concrete_TypeRef(), media_box) }
793    }
794
795    pub fn end_page(&self) {
796        unsafe { CGContextEndPage(self.as_concrete_TypeRef()) }
797    }
798
799    pub fn begin_transparency_layer_with_rect(&self, rect: CGRect, aux_info: Option<&CFDictionary<CFString, CFType>>) {
800        unsafe {
801            CGContextBeginTransparencyLayerWithRect(self.as_concrete_TypeRef(), rect, aux_info.map_or(null(), |info| info.as_concrete_TypeRef()));
802        }
803    }
804
805    pub fn end_transparency_layer(&self) {
806        unsafe {
807            CGContextEndTransparencyLayer(self.as_concrete_TypeRef());
808        }
809    }
810
811    pub fn get_user_space_to_device_space_transform(&self) -> CGAffineTransform {
812        unsafe { CGContextGetUserSpaceToDeviceSpaceTransform(self.as_concrete_TypeRef()) }
813    }
814
815    pub fn convert_point_to_device_space(&self, point: CGPoint) -> CGPoint {
816        unsafe { CGContextConvertPointToDeviceSpace(self.as_concrete_TypeRef(), point) }
817    }
818
819    pub fn convert_point_to_user_space(&self, point: CGPoint) -> CGPoint {
820        unsafe { CGContextConvertPointToUserSpace(self.as_concrete_TypeRef(), point) }
821    }
822
823    pub fn convert_size_to_device_space(&self, size: CGSize) -> CGSize {
824        unsafe { CGContextConvertSizeToDeviceSpace(self.as_concrete_TypeRef(), size) }
825    }
826
827    pub fn convert_size_to_user_space(&self, size: CGSize) -> CGSize {
828        unsafe { CGContextConvertSizeToUserSpace(self.as_concrete_TypeRef(), size) }
829    }
830
831    pub fn convert_rect_to_device_space(&self, rect: CGRect) -> CGRect {
832        unsafe { CGContextConvertRectToDeviceSpace(self.as_concrete_TypeRef(), rect) }
833    }
834
835    pub fn convert_rect_to_user_space(&self, rect: CGRect) -> CGRect {
836        unsafe { CGContextConvertRectToUserSpace(self.as_concrete_TypeRef(), rect) }
837    }
838}
839
840#[cfg(feature = "objc")]
841unsafe impl RefEncode for __CGContext {
842    const ENCODING_REF: Encoding = Encoding::Pointer(&Encoding::Struct("CGContext", &[]));
843}