Auto merge of #51 - pcwalton:surface-shape, r=metajack
Add bindings to the private `CGSNewRegionWithRectList` and `CGSSetSurfaceShape` APIs, and improve ergonomics of the geometry types. These changes allow us to set rounded corners on OpenGL views the same way Cocoa does, dramatically improving performance. r? @metajack cc @paulrouget <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/core-graphics-rs/51) <!-- Reviewable:end -->
This commit is contained in:
@@ -9,20 +9,76 @@
|
||||
|
||||
use base::CGFloat;
|
||||
|
||||
pub const CG_ZERO_POINT: CGPoint = CGPoint {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct CGSize {
|
||||
pub width: CGFloat,
|
||||
pub height: CGFloat,
|
||||
}
|
||||
|
||||
impl CGSize {
|
||||
#[inline]
|
||||
pub fn new(width: CGFloat, height: CGFloat) -> CGSize {
|
||||
CGSize {
|
||||
width: width,
|
||||
height: height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct CGPoint {
|
||||
pub x: CGFloat,
|
||||
pub y: CGFloat,
|
||||
}
|
||||
|
||||
impl CGPoint {
|
||||
#[inline]
|
||||
pub fn new(x: CGFloat, y: CGFloat) -> CGPoint {
|
||||
CGPoint {
|
||||
x: x,
|
||||
y: y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct CGRect {
|
||||
pub origin: CGPoint,
|
||||
pub size: CGSize
|
||||
}
|
||||
|
||||
impl CGRect {
|
||||
#[inline]
|
||||
pub fn new(origin: &CGPoint, size: &CGSize) -> CGRect {
|
||||
CGRect {
|
||||
origin: *origin,
|
||||
size: *size,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn inset(&self, size: &CGSize) -> CGRect {
|
||||
unsafe {
|
||||
ffi::CGRectInset(*self, size.width, size.height)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod ffi {
|
||||
use base::CGFloat;
|
||||
use geometry::CGRect;
|
||||
|
||||
#[link(name = "ApplicationServices", kind = "framework")]
|
||||
extern {
|
||||
pub fn CGRectInset(rect: CGRect, dx: CGFloat, dy: CGFloat) -> CGRect;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+63
-4
@@ -12,10 +12,11 @@
|
||||
//! These are liable to change at any time. Use with caution!
|
||||
|
||||
use geometry::CGRect;
|
||||
use libc::{c_int, c_uint};
|
||||
use std::ptr;
|
||||
|
||||
pub struct CGSRegion {
|
||||
region: ffi::CGSRegion,
|
||||
region: ffi::CGSRegionRef,
|
||||
}
|
||||
|
||||
impl Drop for CGSRegion {
|
||||
@@ -37,21 +38,79 @@ impl CGSRegion {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_rects(rects: &[CGRect]) -> CGSRegion {
|
||||
unsafe {
|
||||
let mut region = ptr::null_mut();
|
||||
assert!(ffi::CGSNewRegionWithRectList(rects.as_ptr(),
|
||||
rects.len() as c_uint,
|
||||
&mut region) == 0);
|
||||
CGSRegion {
|
||||
region: region,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This should always be memory-safe; the window server rejects any invalid surface IDs.
|
||||
pub struct CGSSurface {
|
||||
context_id: c_uint,
|
||||
window_number: c_int,
|
||||
surface_id: c_uint,
|
||||
}
|
||||
|
||||
impl CGSSurface {
|
||||
#[inline]
|
||||
pub fn from_ids(context_id: c_uint, window_number: c_int, surface_id: c_uint) -> CGSSurface {
|
||||
CGSSurface {
|
||||
context_id: context_id,
|
||||
window_number: window_number,
|
||||
surface_id: surface_id,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn id(&self) -> c_uint {
|
||||
self.surface_id
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_shape(&self, region: &CGSRegion) {
|
||||
unsafe {
|
||||
assert!(ffi::CGSSetSurfaceShape(self.context_id,
|
||||
self.window_number,
|
||||
self.surface_id,
|
||||
region.region) == 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod ffi {
|
||||
use geometry::CGRect;
|
||||
use libc::{c_int, c_uint};
|
||||
|
||||
// This is an enum so that we can't easily make instances of this opaque type.
|
||||
enum CGSRegionObject {}
|
||||
|
||||
pub type CGSRegion = *mut CGSRegionObject;
|
||||
pub type CGError = OSStatus;
|
||||
pub type CGSRegionRef = *mut CGSRegionObject;
|
||||
pub type OSStatus = i32;
|
||||
|
||||
#[link(name = "ApplicationServices", kind = "framework")]
|
||||
extern {
|
||||
pub fn CGSRegionRelease(region: CGSRegion);
|
||||
pub fn CGSNewRegionWithRect(rect: *const CGRect, region: *mut CGSRegion) -> OSStatus;
|
||||
pub fn CGSRegionRelease(region: CGSRegionRef);
|
||||
pub fn CGSNewRegionWithRect(rect: *const CGRect, outRegion: *mut CGSRegionRef) -> CGError;
|
||||
pub fn CGSNewRegionWithRectList(rects: *const CGRect,
|
||||
rectCount: c_uint,
|
||||
outRegion: *mut CGSRegionRef)
|
||||
-> CGError;
|
||||
|
||||
pub fn CGSSetSurfaceShape(contextID: c_uint,
|
||||
windowNumber: c_int,
|
||||
surfaceID: c_uint,
|
||||
region: CGSRegionRef)
|
||||
-> CGError;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user