1 // Copyright 2015 The Servo Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution.
3 //
4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7 // option. This file may not be copied, modified, or distributed
8 // except according to those terms.
9 
10 use base::CGFloat;
11 use color_space::CGColorSpace;
12 use core_foundation::base::{ToVoid, CFRelease, CFRetain, CFTypeID};
13 use font::{CGFont, CGGlyph};
14 use geometry::CGPoint;
15 use color::CGColor;
16 use path::CGPathRef;
17 use libc::{c_int, size_t};
18 use std::os::raw::c_void;
19 
20 use std::cmp;
21 use std::ptr;
22 use std::slice;
23 use geometry::{CGAffineTransform, CGRect};
24 use image::CGImage;
25 use foreign_types::{ForeignType, ForeignTypeRef};
26 
27 #[repr(C)]
28 #[derive(Clone, Copy, Debug)]
29 pub 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     // 10.5 and up:
47     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)]
62 pub enum CGTextDrawingMode {
63     CGTextFill,
64     CGTextStroke,
65     CGTextFillStroke,
66     CGTextInvisible,
67     CGTextFillClip,
68     CGTextStrokeClip,
69     CGTextClip
70 }
71 
72 #[repr(C)]
73 #[derive(Clone, Copy, Debug)]
74 pub enum CGLineCap {
75     CGLineCapButt,
76     CGLineCapRound,
77     CGLineCapSquare,
78 }
79 
80 #[repr(C)]
81 #[derive(Clone, Copy, Debug)]
82 pub enum CGLineJoin {
83     CGLineJoinMiter,
84     CGLineJoinRound,
85     CGLineJoinBevel,
86 }
87 
88 #[repr(C)]
89 #[derive(Clone, Copy, Debug)]
90 pub enum CGPathDrawingMode {
91     CGPathFill,
92     CGPathEOFill,
93     CGPathStroke,
94     CGPathFillStroke,
95     CGPathEOFillStroke,
96 }
97 
98 foreign_type! {
99     #[doc(hidden)]
100     type CType = ::sys::CGContext;
101     fn drop = |cs| CFRelease(cs as *mut _);
102     fn clone = |p| CFRetain(p as *const _) as *mut _;
103     pub struct CGContext;
104     pub struct CGContextRef;
105 }
106 
107 impl CGContext {
type_id() -> CFTypeID108     pub fn type_id() -> CFTypeID {
109         unsafe {
110             CGContextGetTypeID()
111         }
112     }
113 
create_bitmap_context(data: Option<*mut c_void>, width: size_t, height: size_t, bits_per_component: size_t, bytes_per_row: size_t, space: &CGColorSpace, bitmap_info: u32) -> CGContext114     pub fn create_bitmap_context(data: Option<*mut c_void>,
115                                  width: size_t,
116                                  height: size_t,
117                                  bits_per_component: size_t,
118                                  bytes_per_row: size_t,
119                                  space: &CGColorSpace,
120                                  bitmap_info: u32)
121                                  -> CGContext {
122         unsafe {
123             let result = CGBitmapContextCreate(data.unwrap_or(ptr::null_mut()),
124                                                width,
125                                                height,
126                                                bits_per_component,
127                                                bytes_per_row,
128                                                space.as_ptr(),
129                                                bitmap_info);
130             assert!(!result.is_null());
131             Self::from_ptr(result)
132         }
133     }
134 
data(&mut self) -> &mut [u8]135     pub fn data(&mut self) -> &mut [u8] {
136         unsafe {
137             slice::from_raw_parts_mut(
138                     CGBitmapContextGetData(self.as_ptr()) as *mut u8,
139                     (self.height() * self.bytes_per_row()) as usize)
140         }
141     }
142 }
143 
144 impl CGContextRef {
flush(&self)145     pub fn flush(&self) {
146         unsafe {
147             CGContextFlush(self.as_ptr())
148         }
149     }
150 
width(&self) -> size_t151     pub fn width(&self) -> size_t {
152         unsafe {
153             CGBitmapContextGetWidth(self.as_ptr())
154         }
155     }
156 
height(&self) -> size_t157     pub fn height(&self) -> size_t {
158         unsafe {
159             CGBitmapContextGetHeight(self.as_ptr())
160         }
161     }
162 
bytes_per_row(&self) -> size_t163     pub fn bytes_per_row(&self) -> size_t {
164         unsafe {
165             CGBitmapContextGetBytesPerRow(self.as_ptr())
166         }
167     }
168 
clip_bounding_box(&self) -> CGRect169     pub fn clip_bounding_box(&self) -> CGRect {
170         unsafe {
171             CGContextGetClipBoundingBox(self.as_ptr())
172         }
173     }
174 
set_fill_color(&self, color: &CGColor)175     pub fn set_fill_color(&self, color: &CGColor) {
176         unsafe {
177             CGContextSetFillColorWithColor(self.as_ptr(), color.to_void());
178         }
179     }
180 
set_rgb_fill_color(&self, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)181     pub fn set_rgb_fill_color(&self, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
182         unsafe {
183             CGContextSetRGBFillColor(self.as_ptr(), red, green, blue, alpha)
184         }
185     }
186 
set_rgb_stroke_color(&self, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)187     pub fn set_rgb_stroke_color(&self, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
188         unsafe {
189             CGContextSetRGBStrokeColor(self.as_ptr(), red, green, blue, alpha)
190         }
191     }
192 
set_gray_fill_color(&self, gray: CGFloat, alpha: CGFloat)193     pub fn set_gray_fill_color(&self, gray: CGFloat, alpha: CGFloat) {
194         unsafe {
195             CGContextSetGrayFillColor(self.as_ptr(), gray, alpha)
196         }
197     }
198 
set_blend_mode(&self, blend_mode: CGBlendMode)199     pub fn set_blend_mode(&self, blend_mode: CGBlendMode) {
200         unsafe {
201             CGContextSetBlendMode(self.as_ptr(), blend_mode)
202         }
203     }
204 
set_allows_font_smoothing(&self, allows_font_smoothing: bool)205     pub fn set_allows_font_smoothing(&self, allows_font_smoothing: bool) {
206         unsafe {
207             CGContextSetAllowsFontSmoothing(self.as_ptr(), allows_font_smoothing)
208         }
209     }
210 
set_font_smoothing_style(&self, style: i32)211     pub fn set_font_smoothing_style(&self, style: i32) {
212         unsafe {
213             CGContextSetFontSmoothingStyle(self.as_ptr(), style as _);
214         }
215     }
216 
set_should_smooth_fonts(&self, should_smooth_fonts: bool)217     pub fn set_should_smooth_fonts(&self, should_smooth_fonts: bool) {
218         unsafe {
219             CGContextSetShouldSmoothFonts(self.as_ptr(), should_smooth_fonts)
220         }
221     }
222 
set_allows_antialiasing(&self, allows_antialiasing: bool)223     pub fn set_allows_antialiasing(&self, allows_antialiasing: bool) {
224         unsafe {
225             CGContextSetAllowsAntialiasing(self.as_ptr(), allows_antialiasing)
226         }
227     }
228 
set_should_antialias(&self, should_antialias: bool)229     pub fn set_should_antialias(&self, should_antialias: bool) {
230         unsafe {
231             CGContextSetShouldAntialias(self.as_ptr(), should_antialias)
232         }
233     }
234 
set_allows_font_subpixel_quantization(&self, allows_font_subpixel_quantization: bool)235     pub fn set_allows_font_subpixel_quantization(&self, allows_font_subpixel_quantization: bool) {
236         unsafe {
237             CGContextSetAllowsFontSubpixelQuantization(self.as_ptr(), allows_font_subpixel_quantization)
238         }
239     }
240 
set_should_subpixel_quantize_fonts(&self, should_subpixel_quantize_fonts: bool)241     pub fn set_should_subpixel_quantize_fonts(&self, should_subpixel_quantize_fonts: bool) {
242         unsafe {
243             CGContextSetShouldSubpixelQuantizeFonts(self.as_ptr(), should_subpixel_quantize_fonts)
244         }
245     }
246 
set_allows_font_subpixel_positioning(&self, allows_font_subpixel_positioning: bool)247     pub fn set_allows_font_subpixel_positioning(&self, allows_font_subpixel_positioning: bool) {
248         unsafe {
249             CGContextSetAllowsFontSubpixelPositioning(self.as_ptr(), allows_font_subpixel_positioning)
250         }
251     }
252 
set_should_subpixel_position_fonts(&self, should_subpixel_position_fonts: bool)253     pub fn set_should_subpixel_position_fonts(&self, should_subpixel_position_fonts: bool) {
254         unsafe {
255             CGContextSetShouldSubpixelPositionFonts(self.as_ptr(), should_subpixel_position_fonts)
256         }
257     }
258 
set_text_drawing_mode(&self, mode: CGTextDrawingMode)259     pub fn set_text_drawing_mode(&self, mode: CGTextDrawingMode) {
260         unsafe {
261             CGContextSetTextDrawingMode(self.as_ptr(), mode)
262         }
263     }
264 
set_line_cap(&self, cap: CGLineCap)265     pub fn set_line_cap(&self, cap: CGLineCap) {
266         unsafe {
267             CGContextSetLineCap(self.as_ptr(), cap)
268         }
269     }
270 
set_line_dash(&self, phase: CGFloat, lengths: &[CGFloat])271     pub fn set_line_dash(&self, phase: CGFloat, lengths: &[CGFloat]) {
272         unsafe {
273             CGContextSetLineDash(self.as_ptr(), phase, lengths.as_ptr(), lengths.len())
274         }
275     }
276 
set_line_join(&self, join: CGLineJoin)277     pub fn set_line_join(&self, join: CGLineJoin) {
278         unsafe {
279             CGContextSetLineJoin(self.as_ptr(), join)
280         }
281     }
282 
set_line_width(&self, width: CGFloat)283     pub fn set_line_width(&self, width: CGFloat) {
284         unsafe {
285             CGContextSetLineWidth(self.as_ptr(), width)
286         }
287     }
288 
set_miter_limit(&self, limit: CGFloat)289     pub fn set_miter_limit(&self, limit: CGFloat) {
290         unsafe {
291             CGContextSetMiterLimit(self.as_ptr(), limit)
292         }
293     }
294 
add_path(&self, path: &CGPathRef)295     pub fn add_path(&self, path: &CGPathRef) {
296         unsafe {
297             CGContextAddPath(self.as_ptr(), path.as_ptr());
298         }
299     }
300 
add_curve_to_point(&self, cp1x: CGFloat, cp1y: CGFloat, cp2x: CGFloat, cp2y: CGFloat, x: CGFloat, y: CGFloat)301     pub fn add_curve_to_point(&self,
302                               cp1x: CGFloat,
303                               cp1y: CGFloat,
304                               cp2x: CGFloat,
305                               cp2y: CGFloat,
306                               x: CGFloat,
307                               y: CGFloat) {
308         unsafe {
309             CGContextAddCurveToPoint(self.as_ptr(),
310                                      cp1x, cp1y,
311                                      cp2x, cp2y,
312                                      x, y);
313         }
314     }
315 
add_quad_curve_to_point(&self, cpx: CGFloat, cpy: CGFloat, x: CGFloat, y: CGFloat)316     pub fn add_quad_curve_to_point(&self,
317                                    cpx: CGFloat,
318                                    cpy: CGFloat,
319                                    x: CGFloat,
320                                    y: CGFloat) {
321         unsafe {
322             CGContextAddQuadCurveToPoint(self.as_ptr(),
323                                          cpx, cpy,
324                                          x, y);
325         }
326     }
327 
add_line_to_point(&self, x: CGFloat, y: CGFloat)328     pub fn add_line_to_point(&self, x: CGFloat, y: CGFloat) {
329         unsafe {
330             CGContextAddLineToPoint(self.as_ptr(), x, y);
331         }
332     }
333 
begin_path(&self)334     pub fn begin_path(&self) {
335          unsafe {
336             CGContextBeginPath(self.as_ptr());
337         }
338     }
339 
close_path(&self)340     pub fn close_path(&self) {
341         unsafe {
342             CGContextClosePath(self.as_ptr());
343         }
344     }
345 
move_to_point(&self, x: CGFloat, y: CGFloat)346     pub fn move_to_point(&self, x: CGFloat, y: CGFloat) {
347         unsafe {
348             CGContextMoveToPoint(self.as_ptr(), x, y);
349         }
350     }
351 
clip(&self)352     pub fn clip(&self) {
353         unsafe {
354             CGContextClip(self.as_ptr());
355         }
356     }
357 
eo_clip(&self)358     pub fn eo_clip(&self) {
359         unsafe {
360             CGContextEOClip(self.as_ptr());
361         }
362     }
363 
draw_path(&self, mode: CGPathDrawingMode)364     pub fn draw_path(&self, mode: CGPathDrawingMode) {
365         unsafe {
366             CGContextDrawPath(self.as_ptr(), mode);
367         }
368     }
369 
fill_path(&self)370     pub fn fill_path(&self) {
371         unsafe {
372             CGContextFillPath(self.as_ptr());
373         }
374     }
375 
eo_fill_path(&self)376     pub fn eo_fill_path(&self) {
377         unsafe {
378             CGContextEOFillPath(self.as_ptr());
379         }
380     }
381 
stroke_path(&self)382     pub fn stroke_path(&self) {
383         unsafe {
384             CGContextStrokePath(self.as_ptr());
385         }
386     }
387 
fill_rect(&self, rect: CGRect)388     pub fn fill_rect(&self, rect: CGRect) {
389         unsafe {
390             CGContextFillRect(self.as_ptr(), rect)
391         }
392     }
393 
fill_rects(&self, rects: &[CGRect])394     pub fn fill_rects(&self, rects: &[CGRect]) {
395         unsafe {
396             CGContextFillRects(self.as_ptr(), rects.as_ptr(), rects.len())
397         }
398     }
399 
clear_rect(&self, rect: CGRect)400     pub fn clear_rect(&self, rect: CGRect) {
401         unsafe {
402             CGContextClearRect(self.as_ptr(), rect)
403         }
404     }
405 
stroke_rect(&self, rect: CGRect)406     pub fn stroke_rect(&self, rect: CGRect) {
407         unsafe {
408             CGContextStrokeRect(self.as_ptr(), rect)
409         }
410     }
411 
stroke_rect_with_width(&self, rect: CGRect, width: CGFloat)412     pub fn stroke_rect_with_width(&self, rect: CGRect, width: CGFloat) {
413         unsafe {
414             CGContextStrokeRectWithWidth(self.as_ptr(), rect, width)
415         }
416     }
417 
clip_to_rect(&self, rect: CGRect)418     pub fn clip_to_rect(&self, rect: CGRect) {
419         unsafe {
420             CGContextClipToRect(self.as_ptr(), rect)
421         }
422     }
423 
clip_to_rects(&self, rects: &[CGRect])424     pub fn clip_to_rects(&self, rects: &[CGRect]) {
425         unsafe {
426             CGContextClipToRects(self.as_ptr(), rects.as_ptr(), rects.len())
427         }
428     }
429 
replace_path_with_stroked_path(&self)430     pub fn replace_path_with_stroked_path(&self) {
431         unsafe {
432             CGContextReplacePathWithStrokedPath(self.as_ptr())
433         }
434     }
435 
fill_ellipse_in_rect(&self, rect: CGRect)436     pub fn fill_ellipse_in_rect(&self, rect: CGRect) {
437         unsafe {
438             CGContextFillEllipseInRect(self.as_ptr(), rect)
439         }
440     }
441 
stroke_ellipse_in_rect(&self, rect: CGRect)442     pub fn stroke_ellipse_in_rect(&self, rect: CGRect) {
443         unsafe {
444             CGContextStrokeEllipseInRect(self.as_ptr(), rect)
445         }
446     }
447 
stroke_line_segments(&self, points: &[CGPoint])448     pub fn stroke_line_segments(&self, points: &[CGPoint]) {
449         unsafe {
450             CGContextStrokeLineSegments(self.as_ptr(), points.as_ptr(), points.len())
451         }
452     }
453 
draw_image(&self, rect: CGRect, image: &CGImage)454     pub fn draw_image(&self, rect: CGRect, image: &CGImage) {
455         unsafe {
456             CGContextDrawImage(self.as_ptr(), rect, image.as_ptr());
457         }
458     }
459 
create_image(&self) -> Option<CGImage>460     pub fn create_image(&self) -> Option<CGImage> {
461         let image = unsafe { CGBitmapContextCreateImage(self.as_ptr()) };
462         if !image.is_null() {
463             Some(unsafe { CGImage::from_ptr(image) })
464         } else {
465             None
466         }
467     }
468 
set_font(&self, font: &CGFont)469     pub fn set_font(&self, font: &CGFont) {
470         unsafe {
471             CGContextSetFont(self.as_ptr(), font.as_ptr())
472         }
473     }
474 
set_font_size(&self, size: CGFloat)475     pub fn set_font_size(&self, size: CGFloat) {
476         unsafe {
477             CGContextSetFontSize(self.as_ptr(), size)
478         }
479     }
480 
set_text_matrix(&self, t: &CGAffineTransform)481     pub fn set_text_matrix(&self, t: &CGAffineTransform) {
482         unsafe {
483             CGContextSetTextMatrix(self.as_ptr(), *t)
484         }
485     }
486 
show_glyphs_at_positions(&self, glyphs: &[CGGlyph], positions: &[CGPoint])487     pub fn show_glyphs_at_positions(&self, glyphs: &[CGGlyph], positions: &[CGPoint]) {
488         unsafe {
489             let count = cmp::min(glyphs.len(), positions.len());
490             CGContextShowGlyphsAtPositions(self.as_ptr(),
491                                            glyphs.as_ptr(),
492                                            positions.as_ptr(),
493                                            count)
494         }
495     }
496 
save(&self)497     pub fn save(&self) {
498         unsafe {
499             CGContextSaveGState(self.as_ptr());
500         }
501     }
502 
restore(&self)503     pub fn restore(&self) {
504         unsafe {
505             CGContextRestoreGState(self.as_ptr());
506         }
507     }
508 
translate(&self, tx: CGFloat, ty: CGFloat)509     pub fn translate(&self, tx: CGFloat, ty: CGFloat) {
510         unsafe {
511             CGContextTranslateCTM(self.as_ptr(), tx, ty);
512         }
513     }
514 
scale(&self, sx: CGFloat, sy: CGFloat)515     pub fn scale(&self, sx: CGFloat, sy: CGFloat) {
516         unsafe {
517             CGContextScaleCTM(self.as_ptr(), sx, sy);
518         }
519     }
520 
rotate(&self, angle: CGFloat)521     pub fn rotate(&self, angle: CGFloat) {
522         unsafe {
523             CGContextRotateCTM(self.as_ptr(), angle);
524         }
525     }
526 
get_ctm(&self) -> CGAffineTransform527     pub fn get_ctm(&self) -> CGAffineTransform {
528         unsafe {
529             CGContextGetCTM(self.as_ptr())
530         }
531     }
532 
concat_ctm(&self, transform: CGAffineTransform)533     pub fn concat_ctm(&self, transform: CGAffineTransform) {
534         unsafe {
535             CGContextConcatCTM(self.as_ptr(), transform)
536         }
537     }
538 }
539 
540 #[test]
create_bitmap_context_test()541 fn create_bitmap_context_test() {
542     use geometry::*;
543 
544     let cs = CGColorSpace::create_device_rgb();
545     let ctx = CGContext::create_bitmap_context(None,
546                                 16, 8,
547                                 8, 0,
548                                 &cs,
549                                 ::base::kCGImageAlphaPremultipliedLast);
550     ctx.set_rgb_fill_color(1.,0.,1.,1.);
551     ctx.set_miter_limit(4.);
552     ctx.fill_rect(CGRect::new(&CGPoint::new(0.,0.), &CGSize::new(8.,8.)));
553     let img = ctx.create_image().unwrap();
554     assert_eq!(16, img.width());
555     assert_eq!(8, img.height());
556     assert_eq!(8, img.bits_per_component());
557     assert_eq!(32, img.bits_per_pixel());
558     let data = img.data();
559     assert_eq!(255, data.bytes()[0]);
560     assert_eq!(0, data.bytes()[1]);
561     assert_eq!(255, data.bytes()[2]);
562     assert_eq!(255, data.bytes()[3]);
563 }
564 
565 #[link(name = "CoreGraphics", kind = "framework")]
566 extern {
CGBitmapContextCreate(data: *mut c_void, width: size_t, height: size_t, bitsPerComponent: size_t, bytesPerRow: size_t, space: ::sys::CGColorSpaceRef, bitmapInfo: u32) -> ::sys::CGContextRef567     fn CGBitmapContextCreate(data: *mut c_void,
568                              width: size_t,
569                              height: size_t,
570                              bitsPerComponent: size_t,
571                              bytesPerRow: size_t,
572                              space: ::sys::CGColorSpaceRef,
573                              bitmapInfo: u32)
574                              -> ::sys::CGContextRef;
CGBitmapContextGetData(context: ::sys::CGContextRef) -> *mut c_void575     fn CGBitmapContextGetData(context: ::sys::CGContextRef) -> *mut c_void;
CGBitmapContextGetWidth(context: ::sys::CGContextRef) -> size_t576     fn CGBitmapContextGetWidth(context: ::sys::CGContextRef) -> size_t;
CGBitmapContextGetHeight(context: ::sys::CGContextRef) -> size_t577     fn CGBitmapContextGetHeight(context: ::sys::CGContextRef) -> size_t;
CGBitmapContextGetBytesPerRow(context: ::sys::CGContextRef) -> size_t578     fn CGBitmapContextGetBytesPerRow(context: ::sys::CGContextRef) -> size_t;
CGBitmapContextCreateImage(context: ::sys::CGContextRef) -> ::sys::CGImageRef579     fn CGBitmapContextCreateImage(context: ::sys::CGContextRef) -> ::sys::CGImageRef;
CGContextGetTypeID() -> CFTypeID580     fn CGContextGetTypeID() -> CFTypeID;
CGContextGetClipBoundingBox(c: ::sys::CGContextRef) -> CGRect581     fn CGContextGetClipBoundingBox(c: ::sys::CGContextRef) -> CGRect;
CGContextFlush(c: ::sys::CGContextRef)582     fn CGContextFlush(c: ::sys::CGContextRef);
CGContextSetBlendMode(c: ::sys::CGContextRef, blendMode: CGBlendMode)583     fn CGContextSetBlendMode(c: ::sys::CGContextRef, blendMode: CGBlendMode);
CGContextSetAllowsFontSmoothing(c: ::sys::CGContextRef, allowsFontSmoothing: bool)584     fn CGContextSetAllowsFontSmoothing(c: ::sys::CGContextRef, allowsFontSmoothing: bool);
CGContextSetShouldSmoothFonts(c: ::sys::CGContextRef, shouldSmoothFonts: bool)585     fn CGContextSetShouldSmoothFonts(c: ::sys::CGContextRef, shouldSmoothFonts: bool);
CGContextSetFontSmoothingStyle(c: ::sys::CGContextRef, style: c_int)586     fn CGContextSetFontSmoothingStyle(c: ::sys::CGContextRef, style: c_int);
CGContextSetAllowsAntialiasing(c: ::sys::CGContextRef, allowsAntialiasing: bool)587     fn CGContextSetAllowsAntialiasing(c: ::sys::CGContextRef, allowsAntialiasing: bool);
CGContextSetShouldAntialias(c: ::sys::CGContextRef, shouldAntialias: bool)588     fn CGContextSetShouldAntialias(c: ::sys::CGContextRef, shouldAntialias: bool);
CGContextSetAllowsFontSubpixelQuantization(c: ::sys::CGContextRef, allowsFontSubpixelQuantization: bool)589     fn CGContextSetAllowsFontSubpixelQuantization(c: ::sys::CGContextRef,
590                                                   allowsFontSubpixelQuantization: bool);
CGContextSetShouldSubpixelQuantizeFonts(c: ::sys::CGContextRef, shouldSubpixelQuantizeFonts: bool)591     fn CGContextSetShouldSubpixelQuantizeFonts(c: ::sys::CGContextRef,
592                                                shouldSubpixelQuantizeFonts: bool);
CGContextSetAllowsFontSubpixelPositioning(c: ::sys::CGContextRef, allowsFontSubpixelPositioning: bool)593     fn CGContextSetAllowsFontSubpixelPositioning(c: ::sys::CGContextRef,
594                                                  allowsFontSubpixelPositioning: bool);
CGContextSetShouldSubpixelPositionFonts(c: ::sys::CGContextRef, shouldSubpixelPositionFonts: bool)595     fn CGContextSetShouldSubpixelPositionFonts(c: ::sys::CGContextRef,
596                                                shouldSubpixelPositionFonts: bool);
CGContextSetTextDrawingMode(c: ::sys::CGContextRef, mode: CGTextDrawingMode)597     fn CGContextSetTextDrawingMode(c: ::sys::CGContextRef, mode: CGTextDrawingMode);
CGContextSetFillColorWithColor(c: ::sys::CGContextRef, color: *const c_void)598     fn CGContextSetFillColorWithColor(c: ::sys::CGContextRef, color: *const c_void);
CGContextSetLineCap(c: ::sys::CGContextRef, cap: CGLineCap)599     fn CGContextSetLineCap(c: ::sys::CGContextRef, cap: CGLineCap);
CGContextSetLineDash(c: ::sys::CGContextRef, phase: CGFloat, lengths: *const CGFloat, count: size_t)600     fn CGContextSetLineDash(c: ::sys::CGContextRef, phase: CGFloat, lengths: *const CGFloat, count: size_t);
CGContextSetLineJoin(c: ::sys::CGContextRef, join: CGLineJoin)601     fn CGContextSetLineJoin(c: ::sys::CGContextRef, join: CGLineJoin);
CGContextSetLineWidth(c: ::sys::CGContextRef, width: CGFloat)602     fn CGContextSetLineWidth(c: ::sys::CGContextRef, width: CGFloat);
CGContextSetMiterLimit(c: ::sys::CGContextRef, limit: CGFloat)603     fn CGContextSetMiterLimit(c: ::sys::CGContextRef, limit: CGFloat);
604 
CGContextAddPath(c: ::sys::CGContextRef, path: ::sys::CGPathRef)605     fn CGContextAddPath(c: ::sys::CGContextRef, path: ::sys::CGPathRef);
CGContextAddCurveToPoint(c: ::sys::CGContextRef, cp1x: CGFloat, cp1y: CGFloat, cp2x: CGFloat, cp2y: CGFloat, x: CGFloat, y: CGFloat)606     fn CGContextAddCurveToPoint(c: ::sys::CGContextRef,
607                                 cp1x: CGFloat,
608                                 cp1y: CGFloat,
609                                 cp2x: CGFloat,
610                                 cp2y: CGFloat,
611                                 x: CGFloat,
612                                 y: CGFloat);
CGContextAddQuadCurveToPoint(c: ::sys::CGContextRef, cpx: CGFloat, cpy: CGFloat, x: CGFloat, y: CGFloat)613     fn CGContextAddQuadCurveToPoint(c: ::sys::CGContextRef,
614                                     cpx: CGFloat,
615                                     cpy: CGFloat,
616                                     x: CGFloat,
617                                     y: CGFloat);
CGContextAddLineToPoint(c: ::sys::CGContextRef, x: CGFloat, y: CGFloat)618     fn CGContextAddLineToPoint(c: ::sys::CGContextRef,
619                                x: CGFloat,
620                                y: CGFloat);
CGContextBeginPath(c: ::sys::CGContextRef)621     fn CGContextBeginPath(c: ::sys::CGContextRef);
CGContextClosePath(c: ::sys::CGContextRef)622     fn CGContextClosePath(c: ::sys::CGContextRef);
CGContextMoveToPoint(c: ::sys::CGContextRef, x: CGFloat, y: CGFloat)623     fn CGContextMoveToPoint(c: ::sys::CGContextRef,
624                             x: CGFloat,
625                             y: CGFloat);
CGContextDrawPath(c: ::sys::CGContextRef, mode: CGPathDrawingMode)626     fn CGContextDrawPath(c: ::sys::CGContextRef, mode: CGPathDrawingMode);
CGContextFillPath(c: ::sys::CGContextRef)627     fn CGContextFillPath(c: ::sys::CGContextRef);
CGContextEOFillPath(c: ::sys::CGContextRef)628     fn CGContextEOFillPath(c: ::sys::CGContextRef);
CGContextClip(c: ::sys::CGContextRef)629     fn CGContextClip(c: ::sys::CGContextRef);
CGContextEOClip(c: ::sys::CGContextRef)630     fn CGContextEOClip(c: ::sys::CGContextRef);
CGContextStrokePath(c: ::sys::CGContextRef)631     fn CGContextStrokePath(c: ::sys::CGContextRef);
CGContextSetRGBFillColor(context: ::sys::CGContextRef, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)632     fn CGContextSetRGBFillColor(context: ::sys::CGContextRef,
633                                 red: CGFloat,
634                                 green: CGFloat,
635                                 blue: CGFloat,
636                                 alpha: CGFloat);
CGContextSetRGBStrokeColor(context: ::sys::CGContextRef, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)637     fn CGContextSetRGBStrokeColor(context: ::sys::CGContextRef,
638                                   red: CGFloat,
639                                   green: CGFloat,
640                                   blue: CGFloat,
641                                   alpha: CGFloat);
CGContextSetGrayFillColor(context: ::sys::CGContextRef, gray: CGFloat, alpha: CGFloat)642     fn CGContextSetGrayFillColor(context: ::sys::CGContextRef, gray: CGFloat, alpha: CGFloat);
CGContextClearRect(context: ::sys::CGContextRef, rect: CGRect)643     fn CGContextClearRect(context: ::sys::CGContextRef,
644                           rect: CGRect);
CGContextFillRect(context: ::sys::CGContextRef, rect: CGRect)645     fn CGContextFillRect(context: ::sys::CGContextRef,
646                          rect: CGRect);
CGContextFillRects(context: ::sys::CGContextRef, rects: *const CGRect, count: size_t)647     fn CGContextFillRects(context: ::sys::CGContextRef,
648                           rects: *const CGRect,
649                           count: size_t);
CGContextStrokeRect(context: ::sys::CGContextRef, rect: CGRect)650     fn CGContextStrokeRect(context: ::sys::CGContextRef,
651                            rect: CGRect);
CGContextStrokeRectWithWidth(context: ::sys::CGContextRef, rect: CGRect, width: CGFloat)652     fn CGContextStrokeRectWithWidth(context: ::sys::CGContextRef,
653                                     rect: CGRect,
654                                     width: CGFloat);
CGContextClipToRect(context: ::sys::CGContextRef, rect: CGRect)655     fn CGContextClipToRect(context: ::sys::CGContextRef,
656                            rect: CGRect);
CGContextClipToRects(context: ::sys::CGContextRef, rects: *const CGRect, count: size_t)657     fn CGContextClipToRects(context: ::sys::CGContextRef,
658                             rects: *const CGRect,
659                             count: size_t);
CGContextReplacePathWithStrokedPath(context: ::sys::CGContextRef)660     fn CGContextReplacePathWithStrokedPath(context: ::sys::CGContextRef);
CGContextFillEllipseInRect(context: ::sys::CGContextRef, rect: CGRect)661     fn CGContextFillEllipseInRect(context: ::sys::CGContextRef,
662                                   rect: CGRect);
CGContextStrokeEllipseInRect(context: ::sys::CGContextRef, rect: CGRect)663     fn CGContextStrokeEllipseInRect(context: ::sys::CGContextRef,
664                                     rect: CGRect);
CGContextStrokeLineSegments(context: ::sys::CGContextRef, points: *const CGPoint, count: size_t)665     fn CGContextStrokeLineSegments(context: ::sys::CGContextRef,
666                                     points: *const CGPoint,
667                                     count: size_t);
CGContextDrawImage(c: ::sys::CGContextRef, rect: CGRect, image: ::sys::CGImageRef)668     fn CGContextDrawImage(c: ::sys::CGContextRef, rect: CGRect, image: ::sys::CGImageRef);
CGContextSetFont(c: ::sys::CGContextRef, font: ::sys::CGFontRef)669     fn CGContextSetFont(c: ::sys::CGContextRef, font: ::sys::CGFontRef);
CGContextSetFontSize(c: ::sys::CGContextRef, size: CGFloat)670     fn CGContextSetFontSize(c: ::sys::CGContextRef, size: CGFloat);
CGContextSetTextMatrix(c: ::sys::CGContextRef, t: CGAffineTransform)671     fn CGContextSetTextMatrix(c: ::sys::CGContextRef, t: CGAffineTransform);
CGContextShowGlyphsAtPositions(c: ::sys::CGContextRef, glyphs: *const CGGlyph, positions: *const CGPoint, count: size_t)672     fn CGContextShowGlyphsAtPositions(c: ::sys::CGContextRef,
673                                       glyphs: *const CGGlyph,
674                                       positions: *const CGPoint,
675                                       count: size_t);
676 
CGContextSaveGState(c: ::sys::CGContextRef)677     fn CGContextSaveGState(c: ::sys::CGContextRef);
CGContextRestoreGState(c: ::sys::CGContextRef)678     fn CGContextRestoreGState(c: ::sys::CGContextRef);
CGContextTranslateCTM(c: ::sys::CGContextRef, tx: CGFloat, ty: CGFloat)679     fn CGContextTranslateCTM(c: ::sys::CGContextRef, tx: CGFloat, ty: CGFloat);
CGContextScaleCTM(c: ::sys::CGContextRef, sx: CGFloat, sy: CGFloat)680     fn CGContextScaleCTM(c: ::sys::CGContextRef, sx: CGFloat, sy: CGFloat);
CGContextRotateCTM(c: ::sys::CGContextRef, angle: CGFloat)681     fn CGContextRotateCTM(c: ::sys::CGContextRef, angle: CGFloat);
CGContextGetCTM(c: ::sys::CGContextRef) -> CGAffineTransform682     fn CGContextGetCTM(c: ::sys::CGContextRef) -> CGAffineTransform;
CGContextConcatCTM(c: ::sys::CGContextRef, transform: CGAffineTransform)683     fn CGContextConcatCTM(c: ::sys::CGContextRef, transform: CGAffineTransform);
684 }
685 
686