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, #[doc(alias = "kCGBlendModeCopy")]
130 Copy = 17, #[doc(alias = "kCGBlendModeSourceIn")]
132 SourceIn = 18, #[doc(alias = "kCGBlendModeSourceOut")]
134 SourceOut = 19, #[doc(alias = "kCGBlendModeSourceAtop")]
136 SourceAtop = 20, #[doc(alias = "kCGBlendModeDestinationOver")]
138 DestinationOver = 21, #[doc(alias = "kCGBlendModeDestinationIn")]
140 DestinationIn = 22, #[doc(alias = "kCGBlendModeDestinationOut")]
142 DestinationOut = 23, #[doc(alias = "kCGBlendModeDestinationAtop")]
144 DestinationAtop = 24, #[doc(alias = "kCGBlendModeXOR")]
146 XOR = 25, #[doc(alias = "kCGBlendModePlusDarker")]
148 PlusDarker = 26, #[doc(alias = "kCGBlendModePlusLighter")]
150 PlusLighter = 27, }
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}