1use crate::base::CGFloat;
11use crate::color::CGColor;
12use crate::color_space::CGColorSpace;
13use crate::font::{CGFont, CGGlyph};
14use crate::geometry::{CGPoint, CGSize};
15use crate::gradient::{CGGradient, CGGradientDrawingOptions};
16use crate::path::CGPathRef;
17use core::ffi::c_void;
18use core_foundation::base::{CFTypeID, TCFType};
19
20use crate::geometry::{CGAffineTransform, CGRect};
21use crate::image::CGImage;
22use foreign_types::{foreign_type, ForeignType, ForeignTypeRef};
23use std::cmp;
24use std::ptr;
25use std::slice;
26
27#[repr(C)]
28#[derive(Clone, Copy, Debug)]
29pub enum CGBlendMode {
30 Normal = 0,
31 Multiply,
32 Screen,
33 Overlay,
34 Darken,
35 Lighten,
36 ColorDodge,
37 ColorBurn,
38 SoftLight,
39 HardLight,
40 Difference,
41 Exclusion,
42 Hue,
43 Saturation,
44 Color,
45 Luminosity,
46 Clear,
48 Copy,
49 SourceIn,
50 SourceOut,
51 SourceAtop,
52 DestinationOver,
53 DestinationIn,
54 DestinationOut,
55 DestinationAtop,
56 Xor,
57 PlusDarker,
58 PlusLighter,
59}
60
61#[repr(C)]
62pub enum CGTextDrawingMode {
63 CGTextFill,
64 CGTextStroke,
65 CGTextFillStroke,
66 CGTextInvisible,
67 CGTextFillClip,
68 CGTextStrokeClip,
69 CGTextFillStrokeClip,
70 CGTextClip,
71}
72
73#[repr(C)]
74#[derive(Clone, Copy, Debug)]
75pub enum CGLineCap {
76 CGLineCapButt,
77 CGLineCapRound,
78 CGLineCapSquare,
79}
80
81#[repr(C)]
82#[derive(Clone, Copy, Debug)]
83pub enum CGLineJoin {
84 CGLineJoinMiter,
85 CGLineJoinRound,
86 CGLineJoinBevel,
87}
88
89#[repr(C)]
90#[derive(Clone, Copy, Debug)]
91pub enum CGPathDrawingMode {
92 CGPathFill,
93 CGPathEOFill,
94 CGPathStroke,
95 CGPathFillStroke,
96 CGPathEOFillStroke,
97}
98
99#[repr(C)]
100#[derive(Clone, Copy, Debug)]
101pub enum CGInterpolationQuality {
102 CGInterpolationQualityDefault,
103 CGInterpolationQualityNone,
104 CGInterpolationQualityLow,
105 CGInterpolationQualityMedium,
106 CGInterpolationQualityHigh,
107}
108
109foreign_type! {
110 #[doc(hidden)]
111 pub unsafe type CGContext {
112 type CType = crate::sys::CGContext;
113 fn drop = |cs| CGContextRelease(cs);
114 fn clone = |p| CGContextRetain(p);
115 }
116}
117
118impl CGContext {
119 pub fn type_id() -> CFTypeID {
120 unsafe { CGContextGetTypeID() }
121 }
122
123 pub unsafe fn from_existing_context_ptr(ctx: *mut crate::sys::CGContext) -> CGContext {
135 CGContextRetain(ctx);
136 Self::from_ptr(ctx)
137 }
138
139 pub fn create_bitmap_context(
140 data: Option<*mut c_void>,
141 width: usize,
142 height: usize,
143 bits_per_component: usize,
144 bytes_per_row: usize,
145 space: &CGColorSpace,
146 bitmap_info: u32,
147 ) -> CGContext {
148 unsafe {
149 let result = CGBitmapContextCreate(
150 data.unwrap_or(ptr::null_mut()),
151 width,
152 height,
153 bits_per_component,
154 bytes_per_row,
155 space.as_ptr(),
156 bitmap_info,
157 );
158 assert!(!result.is_null());
159 Self::from_ptr(result)
160 }
161 }
162
163 pub fn data(&mut self) -> &mut [u8] {
164 unsafe {
165 slice::from_raw_parts_mut(
166 CGBitmapContextGetData(self.as_ptr()) as *mut u8,
167 self.height() * self.bytes_per_row(),
168 )
169 }
170 }
171}
172
173impl CGContextRef {
174 pub fn flush(&self) {
175 unsafe { CGContextFlush(self.as_ptr()) }
176 }
177
178 pub fn width(&self) -> usize {
179 unsafe { CGBitmapContextGetWidth(self.as_ptr()) }
180 }
181
182 pub fn height(&self) -> usize {
183 unsafe { CGBitmapContextGetHeight(self.as_ptr()) }
184 }
185
186 pub fn bytes_per_row(&self) -> usize {
187 unsafe { CGBitmapContextGetBytesPerRow(self.as_ptr()) }
188 }
189
190 pub fn clip_bounding_box(&self) -> CGRect {
191 unsafe { CGContextGetClipBoundingBox(self.as_ptr()) }
192 }
193
194 pub fn set_fill_color(&self, color: &CGColor) {
195 unsafe {
196 CGContextSetFillColorWithColor(self.as_ptr(), color.as_concrete_TypeRef());
197 }
198 }
199
200 pub fn set_rgb_fill_color(&self, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
201 unsafe { CGContextSetRGBFillColor(self.as_ptr(), red, green, blue, alpha) }
202 }
203
204 pub fn set_rgb_stroke_color(
205 &self,
206 red: CGFloat,
207 green: CGFloat,
208 blue: CGFloat,
209 alpha: CGFloat,
210 ) {
211 unsafe { CGContextSetRGBStrokeColor(self.as_ptr(), red, green, blue, alpha) }
212 }
213
214 pub fn set_gray_fill_color(&self, gray: CGFloat, alpha: CGFloat) {
215 unsafe { CGContextSetGrayFillColor(self.as_ptr(), gray, alpha) }
216 }
217
218 pub fn set_blend_mode(&self, blend_mode: CGBlendMode) {
219 unsafe { CGContextSetBlendMode(self.as_ptr(), blend_mode) }
220 }
221
222 pub fn set_allows_font_smoothing(&self, allows_font_smoothing: bool) {
223 unsafe { CGContextSetAllowsFontSmoothing(self.as_ptr(), allows_font_smoothing) }
224 }
225
226 pub fn set_should_smooth_fonts(&self, should_smooth_fonts: bool) {
227 unsafe { CGContextSetShouldSmoothFonts(self.as_ptr(), should_smooth_fonts) }
228 }
229
230 pub fn set_allows_antialiasing(&self, allows_antialiasing: bool) {
231 unsafe { CGContextSetAllowsAntialiasing(self.as_ptr(), allows_antialiasing) }
232 }
233
234 pub fn set_should_antialias(&self, should_antialias: bool) {
235 unsafe { CGContextSetShouldAntialias(self.as_ptr(), should_antialias) }
236 }
237
238 pub fn set_allows_font_subpixel_quantization(&self, allows_font_subpixel_quantization: bool) {
239 unsafe {
240 CGContextSetAllowsFontSubpixelQuantization(
241 self.as_ptr(),
242 allows_font_subpixel_quantization,
243 )
244 }
245 }
246
247 pub fn set_should_subpixel_quantize_fonts(&self, should_subpixel_quantize_fonts: bool) {
248 unsafe {
249 CGContextSetShouldSubpixelQuantizeFonts(self.as_ptr(), should_subpixel_quantize_fonts)
250 }
251 }
252
253 pub fn set_allows_font_subpixel_positioning(&self, allows_font_subpixel_positioning: bool) {
254 unsafe {
255 CGContextSetAllowsFontSubpixelPositioning(
256 self.as_ptr(),
257 allows_font_subpixel_positioning,
258 )
259 }
260 }
261
262 pub fn set_should_subpixel_position_fonts(&self, should_subpixel_position_fonts: bool) {
263 unsafe {
264 CGContextSetShouldSubpixelPositionFonts(self.as_ptr(), should_subpixel_position_fonts)
265 }
266 }
267
268 pub fn set_text_drawing_mode(&self, mode: CGTextDrawingMode) {
269 unsafe { CGContextSetTextDrawingMode(self.as_ptr(), mode) }
270 }
271
272 pub fn set_line_cap(&self, cap: CGLineCap) {
273 unsafe { CGContextSetLineCap(self.as_ptr(), cap) }
274 }
275
276 pub fn set_line_dash(&self, phase: CGFloat, lengths: &[CGFloat]) {
277 unsafe { CGContextSetLineDash(self.as_ptr(), phase, lengths.as_ptr(), lengths.len()) }
278 }
279
280 pub fn set_line_join(&self, join: CGLineJoin) {
281 unsafe { CGContextSetLineJoin(self.as_ptr(), join) }
282 }
283
284 pub fn set_line_width(&self, width: CGFloat) {
285 unsafe { CGContextSetLineWidth(self.as_ptr(), width) }
286 }
287
288 pub fn set_miter_limit(&self, limit: CGFloat) {
289 unsafe { CGContextSetMiterLimit(self.as_ptr(), limit) }
290 }
291
292 pub fn add_path(&self, path: &CGPathRef) {
293 unsafe {
294 CGContextAddPath(self.as_ptr(), path.as_ptr());
295 }
296 }
297
298 pub fn add_curve_to_point(
299 &self,
300 cp1x: CGFloat,
301 cp1y: CGFloat,
302 cp2x: CGFloat,
303 cp2y: CGFloat,
304 x: CGFloat,
305 y: CGFloat,
306 ) {
307 unsafe {
308 CGContextAddCurveToPoint(self.as_ptr(), cp1x, cp1y, cp2x, cp2y, x, y);
309 }
310 }
311
312 pub fn add_quad_curve_to_point(&self, cpx: CGFloat, cpy: CGFloat, x: CGFloat, y: CGFloat) {
313 unsafe {
314 CGContextAddQuadCurveToPoint(self.as_ptr(), cpx, cpy, x, y);
315 }
316 }
317
318 pub fn add_line_to_point(&self, x: CGFloat, y: CGFloat) {
319 unsafe {
320 CGContextAddLineToPoint(self.as_ptr(), x, y);
321 }
322 }
323
324 pub fn begin_path(&self) {
325 unsafe {
326 CGContextBeginPath(self.as_ptr());
327 }
328 }
329
330 pub fn close_path(&self) {
331 unsafe {
332 CGContextClosePath(self.as_ptr());
333 }
334 }
335
336 pub fn move_to_point(&self, x: CGFloat, y: CGFloat) {
337 unsafe {
338 CGContextMoveToPoint(self.as_ptr(), x, y);
339 }
340 }
341
342 pub fn clip(&self) {
343 unsafe {
344 CGContextClip(self.as_ptr());
345 }
346 }
347
348 pub fn eo_clip(&self) {
349 unsafe {
350 CGContextEOClip(self.as_ptr());
351 }
352 }
353
354 pub fn reset_clip(&self) {
355 unsafe {
356 CGContextResetClip(self.as_ptr());
357 }
358 }
359
360 pub fn draw_path(&self, mode: CGPathDrawingMode) {
361 unsafe {
362 CGContextDrawPath(self.as_ptr(), mode);
363 }
364 }
365
366 pub fn fill_path(&self) {
367 unsafe {
368 CGContextFillPath(self.as_ptr());
369 }
370 }
371
372 pub fn eo_fill_path(&self) {
373 unsafe {
374 CGContextEOFillPath(self.as_ptr());
375 }
376 }
377
378 pub fn stroke_path(&self) {
379 unsafe {
380 CGContextStrokePath(self.as_ptr());
381 }
382 }
383
384 pub fn fill_rect(&self, rect: CGRect) {
385 unsafe { CGContextFillRect(self.as_ptr(), rect) }
386 }
387
388 pub fn fill_rects(&self, rects: &[CGRect]) {
389 unsafe { CGContextFillRects(self.as_ptr(), rects.as_ptr(), rects.len()) }
390 }
391
392 pub fn clear_rect(&self, rect: CGRect) {
393 unsafe { CGContextClearRect(self.as_ptr(), rect) }
394 }
395
396 pub fn stroke_rect(&self, rect: CGRect) {
397 unsafe { CGContextStrokeRect(self.as_ptr(), rect) }
398 }
399
400 pub fn stroke_rect_with_width(&self, rect: CGRect, width: CGFloat) {
401 unsafe { CGContextStrokeRectWithWidth(self.as_ptr(), rect, width) }
402 }
403
404 pub fn clip_to_rect(&self, rect: CGRect) {
405 unsafe { CGContextClipToRect(self.as_ptr(), rect) }
406 }
407
408 pub fn clip_to_rects(&self, rects: &[CGRect]) {
409 unsafe { CGContextClipToRects(self.as_ptr(), rects.as_ptr(), rects.len()) }
410 }
411
412 pub fn clip_to_mask(&self, rect: CGRect, image: &CGImage) {
413 unsafe { CGContextClipToMask(self.as_ptr(), rect, image.as_ptr()) }
414 }
415
416 pub fn replace_path_with_stroked_path(&self) {
417 unsafe { CGContextReplacePathWithStrokedPath(self.as_ptr()) }
418 }
419
420 pub fn fill_ellipse_in_rect(&self, rect: CGRect) {
421 unsafe { CGContextFillEllipseInRect(self.as_ptr(), rect) }
422 }
423
424 pub fn stroke_ellipse_in_rect(&self, rect: CGRect) {
425 unsafe { CGContextStrokeEllipseInRect(self.as_ptr(), rect) }
426 }
427
428 pub fn stroke_line_segments(&self, points: &[CGPoint]) {
429 unsafe { CGContextStrokeLineSegments(self.as_ptr(), points.as_ptr(), points.len()) }
430 }
431
432 pub fn set_interpolation_quality(&self, quality: CGInterpolationQuality) {
433 unsafe {
434 CGContextSetInterpolationQuality(self.as_ptr(), quality);
435 }
436 }
437
438 pub fn get_interpolation_quality(&self) -> CGInterpolationQuality {
439 unsafe { CGContextGetInterpolationQuality(self.as_ptr()) }
440 }
441
442 pub fn draw_image(&self, rect: CGRect, image: &CGImage) {
443 unsafe {
444 CGContextDrawImage(self.as_ptr(), rect, image.as_ptr());
445 }
446 }
447
448 pub fn create_image(&self) -> Option<CGImage> {
449 let image = unsafe { CGBitmapContextCreateImage(self.as_ptr()) };
450 if !image.is_null() {
451 Some(unsafe { CGImage::from_ptr(image) })
452 } else {
453 None
454 }
455 }
456
457 pub fn set_font(&self, font: &CGFont) {
458 unsafe { CGContextSetFont(self.as_ptr(), font.as_ptr()) }
459 }
460
461 pub fn set_font_size(&self, size: CGFloat) {
462 unsafe { CGContextSetFontSize(self.as_ptr(), size) }
463 }
464
465 pub fn set_text_matrix(&self, t: &CGAffineTransform) {
466 unsafe { CGContextSetTextMatrix(self.as_ptr(), *t) }
467 }
468
469 pub fn set_text_position(&self, x: CGFloat, y: CGFloat) {
470 unsafe { CGContextSetTextPosition(self.as_ptr(), x, y) }
471 }
472
473 pub fn show_glyphs_at_positions(&self, glyphs: &[CGGlyph], positions: &[CGPoint]) {
474 unsafe {
475 let count = cmp::min(glyphs.len(), positions.len());
476 CGContextShowGlyphsAtPositions(
477 self.as_ptr(),
478 glyphs.as_ptr(),
479 positions.as_ptr(),
480 count,
481 )
482 }
483 }
484
485 pub fn save(&self) {
486 unsafe {
487 CGContextSaveGState(self.as_ptr());
488 }
489 }
490
491 pub fn restore(&self) {
492 unsafe {
493 CGContextRestoreGState(self.as_ptr());
494 }
495 }
496
497 pub fn translate(&self, tx: CGFloat, ty: CGFloat) {
498 unsafe {
499 CGContextTranslateCTM(self.as_ptr(), tx, ty);
500 }
501 }
502
503 pub fn scale(&self, sx: CGFloat, sy: CGFloat) {
504 unsafe {
505 CGContextScaleCTM(self.as_ptr(), sx, sy);
506 }
507 }
508
509 pub fn rotate(&self, angle: CGFloat) {
510 unsafe {
511 CGContextRotateCTM(self.as_ptr(), angle);
512 }
513 }
514
515 pub fn get_ctm(&self) -> CGAffineTransform {
516 unsafe { CGContextGetCTM(self.as_ptr()) }
517 }
518
519 pub fn concat_ctm(&self, transform: CGAffineTransform) {
520 unsafe { CGContextConcatCTM(self.as_ptr(), transform) }
521 }
522
523 pub fn draw_linear_gradient(
524 &self,
525 gradient: &CGGradient,
526 start_point: CGPoint,
527 end_point: CGPoint,
528 options: CGGradientDrawingOptions,
529 ) {
530 unsafe {
531 CGContextDrawLinearGradient(
532 self.as_ptr(),
533 gradient.as_ptr(),
534 start_point,
535 end_point,
536 options,
537 );
538 }
539 }
540
541 pub fn draw_radial_gradient(
542 &self,
543 gradient: &CGGradient,
544 start_center: CGPoint,
545 start_radius: CGFloat,
546 end_center: CGPoint,
547 end_radius: CGFloat,
548 options: CGGradientDrawingOptions,
549 ) {
550 unsafe {
551 CGContextDrawRadialGradient(
552 self.as_ptr(),
553 gradient.as_ptr(),
554 start_center,
555 start_radius,
556 end_center,
557 end_radius,
558 options,
559 );
560 }
561 }
562
563 pub fn set_shadow(&self, offset: CGSize, blur: CGFloat) {
564 unsafe {
565 CGContextSetShadow(self.as_ptr(), offset, blur);
566 }
567 }
568
569 pub fn set_shadow_with_color(&self, offset: CGSize, blur: CGFloat, color: &CGColor) {
570 unsafe {
571 CGContextSetShadowWithColor(self.as_ptr(), offset, blur, color.as_concrete_TypeRef());
572 }
573 }
574
575 pub fn set_alpha(&self, alpha: CGFloat) {
576 unsafe {
577 CGContextSetAlpha(self.as_ptr(), alpha);
578 }
579 }
580}
581
582#[test]
583fn create_bitmap_context_test() {
584 use crate::geometry::*;
585
586 let cs = CGColorSpace::create_device_rgb();
587 let ctx = CGContext::create_bitmap_context(
588 None,
589 16,
590 8,
591 8,
592 0,
593 &cs,
594 crate::base::kCGImageAlphaPremultipliedLast,
595 );
596 ctx.set_rgb_fill_color(1., 0., 1., 1.);
597 ctx.set_miter_limit(4.);
598 ctx.fill_rect(CGRect::new(&CGPoint::new(0., 0.), &CGSize::new(8., 8.)));
599 let img = ctx.create_image().unwrap();
600 assert_eq!(16, img.width());
601 assert_eq!(8, img.height());
602 assert_eq!(8, img.bits_per_component());
603 assert_eq!(32, img.bits_per_pixel());
604 let data = img.data();
605 assert_eq!(255, data.bytes()[0]);
606 assert_eq!(0, data.bytes()[1]);
607 assert_eq!(255, data.bytes()[2]);
608 assert_eq!(255, data.bytes()[3]);
609}
610
611#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
612extern "C" {
613 fn CGContextRetain(c: crate::sys::CGContextRef) -> crate::sys::CGContextRef;
614 fn CGContextRelease(c: crate::sys::CGContextRef);
615
616 fn CGBitmapContextCreate(
617 data: *mut c_void,
618 width: usize,
619 height: usize,
620 bitsPerComponent: usize,
621 bytesPerRow: usize,
622 space: crate::sys::CGColorSpaceRef,
623 bitmapInfo: u32,
624 ) -> crate::sys::CGContextRef;
625 fn CGBitmapContextGetData(context: crate::sys::CGContextRef) -> *mut c_void;
626 fn CGBitmapContextGetWidth(context: crate::sys::CGContextRef) -> usize;
627 fn CGBitmapContextGetHeight(context: crate::sys::CGContextRef) -> usize;
628 fn CGBitmapContextGetBytesPerRow(context: crate::sys::CGContextRef) -> usize;
629 fn CGBitmapContextCreateImage(context: crate::sys::CGContextRef) -> crate::sys::CGImageRef;
630 fn CGContextGetTypeID() -> CFTypeID;
631 fn CGContextGetClipBoundingBox(c: crate::sys::CGContextRef) -> CGRect;
632 fn CGContextFlush(c: crate::sys::CGContextRef);
633 fn CGContextSetBlendMode(c: crate::sys::CGContextRef, blendMode: CGBlendMode);
634 fn CGContextSetAllowsFontSmoothing(c: crate::sys::CGContextRef, allowsFontSmoothing: bool);
635 fn CGContextSetShouldSmoothFonts(c: crate::sys::CGContextRef, shouldSmoothFonts: bool);
636 fn CGContextSetAllowsAntialiasing(c: crate::sys::CGContextRef, allowsAntialiasing: bool);
637 fn CGContextSetShouldAntialias(c: crate::sys::CGContextRef, shouldAntialias: bool);
638 fn CGContextSetAllowsFontSubpixelQuantization(
639 c: crate::sys::CGContextRef,
640 allowsFontSubpixelQuantization: bool,
641 );
642 fn CGContextSetShouldSubpixelQuantizeFonts(
643 c: crate::sys::CGContextRef,
644 shouldSubpixelQuantizeFonts: bool,
645 );
646 fn CGContextSetAllowsFontSubpixelPositioning(
647 c: crate::sys::CGContextRef,
648 allowsFontSubpixelPositioning: bool,
649 );
650 fn CGContextSetShouldSubpixelPositionFonts(
651 c: crate::sys::CGContextRef,
652 shouldSubpixelPositionFonts: bool,
653 );
654 fn CGContextSetTextDrawingMode(c: crate::sys::CGContextRef, mode: CGTextDrawingMode);
655 fn CGContextSetFillColorWithColor(c: crate::sys::CGContextRef, color: crate::sys::CGColorRef);
656 fn CGContextSetLineCap(c: crate::sys::CGContextRef, cap: CGLineCap);
657 fn CGContextSetLineDash(
658 c: crate::sys::CGContextRef,
659 phase: CGFloat,
660 lengths: *const CGFloat,
661 count: usize,
662 );
663 fn CGContextSetLineJoin(c: crate::sys::CGContextRef, join: CGLineJoin);
664 fn CGContextSetLineWidth(c: crate::sys::CGContextRef, width: CGFloat);
665 fn CGContextSetMiterLimit(c: crate::sys::CGContextRef, limit: CGFloat);
666
667 fn CGContextAddPath(c: crate::sys::CGContextRef, path: crate::sys::CGPathRef);
668 fn CGContextAddCurveToPoint(
669 c: crate::sys::CGContextRef,
670 cp1x: CGFloat,
671 cp1y: CGFloat,
672 cp2x: CGFloat,
673 cp2y: CGFloat,
674 x: CGFloat,
675 y: CGFloat,
676 );
677 fn CGContextAddQuadCurveToPoint(
678 c: crate::sys::CGContextRef,
679 cpx: CGFloat,
680 cpy: CGFloat,
681 x: CGFloat,
682 y: CGFloat,
683 );
684 fn CGContextAddLineToPoint(c: crate::sys::CGContextRef, x: CGFloat, y: CGFloat);
685 fn CGContextBeginPath(c: crate::sys::CGContextRef);
686 fn CGContextClosePath(c: crate::sys::CGContextRef);
687 fn CGContextMoveToPoint(c: crate::sys::CGContextRef, x: CGFloat, y: CGFloat);
688 fn CGContextDrawPath(c: crate::sys::CGContextRef, mode: CGPathDrawingMode);
689 fn CGContextFillPath(c: crate::sys::CGContextRef);
690 fn CGContextEOFillPath(c: crate::sys::CGContextRef);
691 fn CGContextClip(c: crate::sys::CGContextRef);
692 fn CGContextEOClip(c: crate::sys::CGContextRef);
693 fn CGContextResetClip(c: crate::sys::CGContextRef);
694 fn CGContextStrokePath(c: crate::sys::CGContextRef);
695 fn CGContextSetRGBFillColor(
696 context: crate::sys::CGContextRef,
697 red: CGFloat,
698 green: CGFloat,
699 blue: CGFloat,
700 alpha: CGFloat,
701 );
702 fn CGContextSetRGBStrokeColor(
703 context: crate::sys::CGContextRef,
704 red: CGFloat,
705 green: CGFloat,
706 blue: CGFloat,
707 alpha: CGFloat,
708 );
709 fn CGContextSetGrayFillColor(context: crate::sys::CGContextRef, gray: CGFloat, alpha: CGFloat);
710 fn CGContextClearRect(context: crate::sys::CGContextRef, rect: CGRect);
711 fn CGContextFillRect(context: crate::sys::CGContextRef, rect: CGRect);
712 fn CGContextFillRects(context: crate::sys::CGContextRef, rects: *const CGRect, count: usize);
713 fn CGContextStrokeRect(context: crate::sys::CGContextRef, rect: CGRect);
714 fn CGContextStrokeRectWithWidth(
715 context: crate::sys::CGContextRef,
716 rect: CGRect,
717 width: CGFloat,
718 );
719 fn CGContextClipToRect(context: crate::sys::CGContextRef, rect: CGRect);
720 fn CGContextClipToRects(context: crate::sys::CGContextRef, rects: *const CGRect, count: usize);
721 fn CGContextClipToMask(
722 ctx: crate::sys::CGContextRef,
723 rect: CGRect,
724 mask: crate::sys::CGImageRef,
725 );
726 fn CGContextReplacePathWithStrokedPath(context: crate::sys::CGContextRef);
727 fn CGContextFillEllipseInRect(context: crate::sys::CGContextRef, rect: CGRect);
728 fn CGContextStrokeEllipseInRect(context: crate::sys::CGContextRef, rect: CGRect);
729 fn CGContextStrokeLineSegments(
730 context: crate::sys::CGContextRef,
731 points: *const CGPoint,
732 count: usize,
733 );
734 fn CGContextDrawImage(c: crate::sys::CGContextRef, rect: CGRect, image: crate::sys::CGImageRef);
735 fn CGContextSetInterpolationQuality(
736 c: crate::sys::CGContextRef,
737 quality: CGInterpolationQuality,
738 );
739 fn CGContextGetInterpolationQuality(c: crate::sys::CGContextRef) -> CGInterpolationQuality;
740 fn CGContextSetFont(c: crate::sys::CGContextRef, font: crate::sys::CGFontRef);
741 fn CGContextSetFontSize(c: crate::sys::CGContextRef, size: CGFloat);
742 fn CGContextSetTextMatrix(c: crate::sys::CGContextRef, t: CGAffineTransform);
743 fn CGContextSetTextPosition(c: crate::sys::CGContextRef, x: CGFloat, y: CGFloat);
744 fn CGContextShowGlyphsAtPositions(
745 c: crate::sys::CGContextRef,
746 glyphs: *const CGGlyph,
747 positions: *const CGPoint,
748 count: usize,
749 );
750
751 fn CGContextSaveGState(c: crate::sys::CGContextRef);
752 fn CGContextRestoreGState(c: crate::sys::CGContextRef);
753 fn CGContextTranslateCTM(c: crate::sys::CGContextRef, tx: CGFloat, ty: CGFloat);
754 fn CGContextScaleCTM(c: crate::sys::CGContextRef, sx: CGFloat, sy: CGFloat);
755 fn CGContextRotateCTM(c: crate::sys::CGContextRef, angle: CGFloat);
756 fn CGContextGetCTM(c: crate::sys::CGContextRef) -> CGAffineTransform;
757 fn CGContextConcatCTM(c: crate::sys::CGContextRef, transform: CGAffineTransform);
758
759 fn CGContextDrawLinearGradient(
760 c: crate::sys::CGContextRef,
761 gradient: crate::sys::CGGradientRef,
762 startPoint: CGPoint,
763 endPoint: CGPoint,
764 options: CGGradientDrawingOptions,
765 );
766 fn CGContextDrawRadialGradient(
767 c: crate::sys::CGContextRef,
768 gradient: crate::sys::CGGradientRef,
769 startCenter: CGPoint,
770 startRadius: CGFloat,
771 endCenter: CGPoint,
772 endRadius: CGFloat,
773 options: CGGradientDrawingOptions,
774 );
775
776 fn CGContextSetShadow(c: crate::sys::CGContextRef, offset: CGSize, blur: CGFloat);
777 fn CGContextSetShadowWithColor(
778 c: crate::sys::CGContextRef,
779 offset: CGSize,
780 blur: CGFloat,
781 color: crate::sys::CGColorRef,
782 );
783
784 fn CGContextSetAlpha(c: crate::sys::CGContextRef, alpha: CGFloat);
785}