1 // Copyright 2013 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 core_foundation::base::TCFType;
12 use core_foundation::dictionary::CFDictionary;
13 
14 pub const CG_ZERO_POINT: CGPoint = CGPoint {
15     x: 0.0,
16     y: 0.0,
17 };
18 
19 pub const CG_ZERO_SIZE: CGSize = CGSize {
20     width: 0.0,
21     height: 0.0,
22 };
23 
24 pub const CG_ZERO_RECT: CGRect = CGRect {
25     origin: CG_ZERO_POINT,
26     size: CG_ZERO_SIZE,
27 };
28 
29 pub const CG_AFFINE_TRANSFORM_IDENTITY: CGAffineTransform = CGAffineTransform {
30     a: 1.0, b: 0.0,
31     c: 0.0, d: 1.0,
32     tx: 0.0, ty: 0.0,
33 };
34 
35 #[repr(C)]
36 #[derive(Clone, Copy, Debug, Default)]
37 pub struct CGSize {
38     pub width: CGFloat,
39     pub height: CGFloat,
40 }
41 
42 impl CGSize {
43     #[inline]
new(width: CGFloat, height: CGFloat) -> CGSize44     pub fn new(width: CGFloat, height: CGFloat) -> CGSize {
45         CGSize {
46             width: width,
47             height: height,
48         }
49     }
50 
51     #[inline]
apply_transform(&self, t: &CGAffineTransform) -> CGSize52     pub fn apply_transform(&self, t: &CGAffineTransform) -> CGSize {
53         unsafe {
54             ffi::CGSizeApplyAffineTransform(*self, *t)
55         }
56     }
57 }
58 
59 #[repr(C)]
60 #[derive(Clone, Copy, Debug, Default)]
61 pub struct CGPoint {
62     pub x: CGFloat,
63     pub y: CGFloat,
64 }
65 
66 impl CGPoint {
67     #[inline]
new(x: CGFloat, y: CGFloat) -> CGPoint68     pub fn new(x: CGFloat, y: CGFloat) -> CGPoint {
69         CGPoint {
70             x: x,
71             y: y,
72         }
73     }
74 
75     #[inline]
apply_transform(&self, t: &CGAffineTransform) -> CGPoint76     pub fn apply_transform(&self, t: &CGAffineTransform) -> CGPoint {
77         unsafe {
78             ffi::CGPointApplyAffineTransform(*self, *t)
79         }
80     }
81 }
82 
83 #[repr(C)]
84 #[derive(Clone, Copy, Debug, Default)]
85 pub struct CGRect {
86     pub origin: CGPoint,
87     pub size: CGSize
88 }
89 
90 impl CGRect {
91     #[inline]
new(origin: &CGPoint, size: &CGSize) -> CGRect92     pub fn new(origin: &CGPoint, size: &CGSize) -> CGRect {
93         CGRect {
94             origin: *origin,
95             size: *size,
96         }
97     }
98 
99     #[inline]
inset(&self, size: &CGSize) -> CGRect100     pub fn inset(&self, size: &CGSize) -> CGRect {
101         unsafe {
102             ffi::CGRectInset(*self, size.width, size.height)
103         }
104     }
105 
106     #[inline]
from_dict_representation(dict: &CFDictionary) -> Option<CGRect>107     pub fn from_dict_representation(dict: &CFDictionary) -> Option<CGRect> {
108         let mut rect = CGRect::new(&CGPoint::new(0., 0.), &CGSize::new(0., 0.));
109         let result = unsafe {
110             ffi::CGRectMakeWithDictionaryRepresentation(dict.as_concrete_TypeRef(), &mut rect)
111         };
112         if result == 0 {
113             None
114         } else {
115             Some(rect)
116         }
117     }
118 
119     #[inline]
is_empty(&self) -> bool120     pub fn is_empty(&self) -> bool {
121         unsafe {
122             // I use one, as it seems that `YES` is not available from this crate.
123             ffi::CGRectIsEmpty(*self) == 1
124         }
125     }
126 
127     #[inline]
is_intersects(&self, other: &CGRect) -> bool128     pub fn is_intersects(&self, other: &CGRect) -> bool {
129         unsafe {
130             // I use one, as it seems that `YES` is not available from this crate.
131             ffi::CGRectIntersectsRect(*self, *other) == 1
132         }
133     }
134 
135     #[inline]
apply_transform(&self, t: &CGAffineTransform) -> CGRect136     pub fn apply_transform(&self, t: &CGAffineTransform) -> CGRect {
137         unsafe {
138             ffi::CGRectApplyAffineTransform(*self, *t)
139         }
140     }
141 }
142 
143 impl PartialEq for CGRect {
144     #[inline]
eq(&self, other: &CGRect) -> bool145     fn eq(&self, other: &CGRect) -> bool {
146         unsafe {
147             ffi::CGRectEqualToRect(*self, *other) != 0
148         }
149     }
150 }
151 
152 #[repr(C)]
153 #[derive(Clone, Copy, Debug, Default)]
154 pub struct CGAffineTransform {
155     pub a: CGFloat,
156     pub b: CGFloat,
157     pub c: CGFloat,
158     pub d: CGFloat,
159     pub tx: CGFloat,
160     pub ty: CGFloat,
161 }
162 
163 impl CGAffineTransform {
164     #[inline]
new( a: CGFloat, b: CGFloat, c: CGFloat, d: CGFloat, tx: CGFloat, ty: CGFloat, ) -> CGAffineTransform165     pub fn new(
166         a: CGFloat,
167         b: CGFloat,
168         c: CGFloat,
169         d: CGFloat,
170         tx: CGFloat,
171         ty: CGFloat,
172     ) -> CGAffineTransform {
173         CGAffineTransform { a, b, c, d, tx, ty }
174     }
175 
176     #[inline]
invert(&self) -> CGAffineTransform177     pub fn invert(&self) -> CGAffineTransform {
178         unsafe {
179             ffi::CGAffineTransformInvert(*self)
180         }
181     }
182 }
183 
184 mod ffi {
185     use base::{CGFloat, boolean_t};
186     use geometry::{CGAffineTransform, CGPoint, CGRect, CGSize};
187     use core_foundation::dictionary::CFDictionaryRef;
188 
189     #[link(name = "CoreGraphics", kind = "framework")]
190     extern {
CGRectInset(rect: CGRect, dx: CGFloat, dy: CGFloat) -> CGRect191         pub fn CGRectInset(rect: CGRect, dx: CGFloat, dy: CGFloat) -> CGRect;
CGRectMakeWithDictionaryRepresentation(dict: CFDictionaryRef, rect: *mut CGRect) -> boolean_t192         pub fn CGRectMakeWithDictionaryRepresentation(dict: CFDictionaryRef,
193                                                       rect: *mut CGRect) -> boolean_t;
CGRectIsEmpty(rect: CGRect) -> boolean_t194         pub fn CGRectIsEmpty(rect: CGRect) -> boolean_t;
CGRectIntersectsRect(rect1: CGRect, rect2: CGRect) -> boolean_t195         pub fn CGRectIntersectsRect(rect1: CGRect, rect2: CGRect) -> boolean_t;
CGRectEqualToRect(rect1: CGRect, rect2: CGRect) -> boolean_t196         pub fn CGRectEqualToRect(rect1: CGRect, rect2: CGRect) -> boolean_t;
197 
CGAffineTransformInvert(t: CGAffineTransform) -> CGAffineTransform198         pub fn CGAffineTransformInvert(t: CGAffineTransform) -> CGAffineTransform;
199 
CGPointApplyAffineTransform(point: CGPoint, t: CGAffineTransform) -> CGPoint200         pub fn CGPointApplyAffineTransform(point: CGPoint, t: CGAffineTransform) -> CGPoint;
CGRectApplyAffineTransform(rect: CGRect, t: CGAffineTransform) -> CGRect201         pub fn CGRectApplyAffineTransform(rect: CGRect, t: CGAffineTransform) -> CGRect;
CGSizeApplyAffineTransform(size: CGSize, t: CGAffineTransform) -> CGSize202         pub fn CGSizeApplyAffineTransform(size: CGSize, t: CGAffineTransform) -> CGSize;
203     }
204 }
205 
206