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 core_foundation::base::{CFRelease, CFRetain, CFTypeID, TCFType}; 11 use core_foundation::data::{CFData, CFDataRef}; 12 13 use libc::{size_t, off_t}; 14 use std::mem; 15 use std::ptr; 16 use std::sync::Arc; 17 use std::os::raw::c_void; 18 19 use foreign_types::{ForeignType, ForeignTypeRef}; 20 21 pub type CGDataProviderGetBytesCallback = Option<unsafe extern fn (*mut c_void, *mut c_void, size_t) -> size_t>; 22 pub type CGDataProviderReleaseInfoCallback = Option<unsafe extern fn (*mut c_void)>; 23 pub type CGDataProviderRewindCallback = Option<unsafe extern fn (*mut c_void)>; 24 pub type CGDataProviderSkipBytesCallback = Option<unsafe extern fn (*mut c_void, size_t)>; 25 pub type CGDataProviderSkipForwardCallback = Option<unsafe extern fn (*mut c_void, off_t) -> off_t>; 26 27 pub type CGDataProviderGetBytePointerCallback = Option<unsafe extern fn (*mut c_void) -> *mut c_void>; 28 pub type CGDataProviderGetBytesAtOffsetCallback = Option<unsafe extern fn (*mut c_void, *mut c_void, size_t, size_t)>; 29 pub type CGDataProviderReleaseBytePointerCallback = Option<unsafe extern fn (*mut c_void, *const c_void)>; 30 pub type CGDataProviderReleaseDataCallback = Option<unsafe extern fn (*mut c_void, *const c_void, size_t)>; 31 pub type CGDataProviderGetBytesAtPositionCallback = Option<unsafe extern fn (*mut c_void, *mut c_void, off_t, size_t)>; 32 33 foreign_type! { 34 #[doc(hidden)] 35 type CType = ::sys::CGDataProvider; 36 fn drop = |cs| CFRelease(cs as *mut _); 37 fn clone = |p| CFRetain(p as *const _) as *mut _; 38 pub struct CGDataProvider; 39 pub struct CGDataProviderRef; 40 } 41 42 impl CGDataProvider { type_id() -> CFTypeID43 pub fn type_id() -> CFTypeID { 44 unsafe { 45 CGDataProviderGetTypeID() 46 } 47 } 48 49 /// Creates a data provider from the given reference-counted buffer. 50 /// 51 /// The `CGDataProvider` object takes ownership of the reference. Once the data provider 52 /// is destroyed, the reference count of the buffer is automatically decremented. from_buffer(buffer: Arc<Vec<u8>>) -> Self53 pub fn from_buffer(buffer: Arc<Vec<u8>>) -> Self { 54 unsafe { 55 let ptr = (*buffer).as_ptr() as *const c_void; 56 let len = buffer.len() as size_t; 57 let info = mem::transmute::<Arc<Vec<u8>>, *mut c_void>(buffer); 58 let result = CGDataProviderCreateWithData(info, ptr, len, Some(release)); 59 return CGDataProvider::from_ptr(result); 60 } 61 62 unsafe extern "C" fn release(info: *mut c_void, _: *const c_void, _: size_t) { 63 drop(mem::transmute::<*mut c_void, Arc<Vec<u8>>>(info)) 64 } 65 } 66 67 /// Creates a data prvider from a given slice. The data provider does not own the slice in this 68 /// case, so it's up to the user to ensure the memory safety here. from_slice(buffer: &[u8]) -> Self69 pub unsafe fn from_slice(buffer: &[u8]) -> Self { 70 let ptr = buffer.as_ptr() as *const c_void; 71 let len = buffer.len() as size_t; 72 let result = CGDataProviderCreateWithData(ptr::null_mut(), ptr, len, None); 73 CGDataProvider::from_ptr(result) 74 } 75 76 /// Creates a data provider from the given raw pointer, length, and destructor function. 77 /// 78 /// This is double-boxed because the Core Text API requires that the userdata be a single 79 /// pointer. from_custom_data(custom_data: Box<Box<CustomData>>) -> Self80 pub unsafe fn from_custom_data(custom_data: Box<Box<CustomData>>) -> Self { 81 let (ptr, len) = (custom_data.ptr() as *const c_void, custom_data.len()); 82 let userdata = mem::transmute::<Box<Box<CustomData>>, &mut c_void>(custom_data); 83 let data_provider = CGDataProviderCreateWithData(userdata, ptr, len, Some(release)); 84 return CGDataProvider::from_ptr(data_provider); 85 86 unsafe extern "C" fn release(info: *mut c_void, _: *const c_void, _: size_t) { 87 drop(mem::transmute::<*mut c_void, Box<Box<CustomData>>>(info)) 88 } 89 } 90 } 91 92 impl CGDataProviderRef { 93 /// Creates a copy of the data from the underlying `CFDataProviderRef`. copy_data(&self) -> CFData94 pub fn copy_data(&self) -> CFData { 95 unsafe { CFData::wrap_under_create_rule(CGDataProviderCopyData(self.as_ptr())) } 96 } 97 } 98 99 /// Encapsulates custom data that can be wrapped. 100 pub trait CustomData { 101 /// Returns a pointer to the start of the custom data. This pointer *must not change* during 102 /// the lifespan of this CustomData. ptr(&self) -> *const u8103 unsafe fn ptr(&self) -> *const u8; 104 /// Returns the length of this custom data. This value must not change during the lifespan of 105 /// this CustomData. len(&self) -> usize106 unsafe fn len(&self) -> usize; 107 } 108 109 #[link(name = "CoreGraphics", kind = "framework")] 110 extern { CGDataProviderCopyData(provider: ::sys::CGDataProviderRef) -> CFDataRef111 fn CGDataProviderCopyData(provider: ::sys::CGDataProviderRef) -> CFDataRef; 112 //fn CGDataProviderCreateDirect 113 //fn CGDataProviderCreateSequential 114 //fn CGDataProviderCreateWithCFData CGDataProviderCreateWithData(info: *mut c_void, data: *const c_void, size: size_t, releaseData: CGDataProviderReleaseDataCallback ) -> ::sys::CGDataProviderRef115 fn CGDataProviderCreateWithData(info: *mut c_void, 116 data: *const c_void, 117 size: size_t, 118 releaseData: CGDataProviderReleaseDataCallback 119 ) -> ::sys::CGDataProviderRef; 120 //fn CGDataProviderCreateWithFilename(filename: *c_char) -> CGDataProviderRef; 121 //fn CGDataProviderCreateWithURL CGDataProviderGetTypeID() -> CFTypeID122 fn CGDataProviderGetTypeID() -> CFTypeID; 123 //fn CGDataProviderRelease(provider: CGDataProviderRef); 124 //fn CGDataProviderRetain(provider: CGDataProviderRef) -> CGDataProviderRef; 125 } 126