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, #[doc(alias = "kCGBlendModeCopy")]
129 Copy = 17, #[doc(alias = "kCGBlendModeSourceIn")]
131 SourceIn = 18, #[doc(alias = "kCGBlendModeSourceOut")]
133 SourceOut = 19, #[doc(alias = "kCGBlendModeSourceAtop")]
135 SourceAtop = 20, #[doc(alias = "kCGBlendModeDestinationOver")]
137 DestinationOver = 21, #[doc(alias = "kCGBlendModeDestinationIn")]
139 DestinationIn = 22, #[doc(alias = "kCGBlendModeDestinationOut")]
141 DestinationOut = 23, #[doc(alias = "kCGBlendModeDestinationAtop")]
143 DestinationAtop = 24, #[doc(alias = "kCGBlendModeXOR")]
145 XOR = 25, #[doc(alias = "kCGBlendModePlusDarker")]
147 PlusDarker = 26, #[doc(alias = "kCGBlendModePlusLighter")]
149 PlusLighter = 27, }
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}