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