core_graphics2/
context.rs

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