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::array::{CFArray, CFArrayRef}; 12 use core_foundation::data::{CFData, CFDataRef}; 13 use core_foundation::number::CFNumber; 14 use core_foundation::string::{CFString, CFStringRef}; 15 use core_foundation::dictionary::{CFDictionary, CFDictionaryRef}; 16 use data_provider::CGDataProvider; 17 use geometry::CGRect; 18 19 use foreign_types::ForeignType; 20 21 use libc::{c_int, size_t}; 22 23 pub use core_graphics_types::base::CGGlyph; 24 25 foreign_type! { 26 #[doc(hidden)] 27 type CType = ::sys::CGFont; 28 fn drop = |p| CFRelease(p as *mut _); 29 fn clone = |p| CFRetain(p as *const _) as *mut _; 30 pub struct CGFont; 31 pub struct CGFontRef; 32 } 33 34 unsafe impl Send for CGFont {} 35 unsafe impl Sync for CGFont {} 36 37 impl CGFont { type_id() -> CFTypeID38 pub fn type_id() -> CFTypeID { 39 unsafe { 40 CGFontGetTypeID() 41 } 42 } 43 from_data_provider(provider: CGDataProvider) -> Result<CGFont, ()>44 pub fn from_data_provider(provider: CGDataProvider) -> Result<CGFont, ()> { 45 unsafe { 46 let font_ref = CGFontCreateWithDataProvider(provider.as_ptr()); 47 if !font_ref.is_null() { 48 Ok(CGFont::from_ptr(font_ref)) 49 } else { 50 Err(()) 51 } 52 } 53 } 54 from_name(name: &CFString) -> Result<CGFont, ()>55 pub fn from_name(name: &CFString) -> Result<CGFont, ()> { 56 unsafe { 57 let font_ref = CGFontCreateWithFontName(name.as_concrete_TypeRef()); 58 if !font_ref.is_null() { 59 Ok(CGFont::from_ptr(font_ref)) 60 } else { 61 Err(()) 62 } 63 } 64 } 65 create_copy_from_variations(&self, vars: &CFDictionary<CFString, CFNumber>) -> Result<CGFont, ()>66 pub fn create_copy_from_variations(&self, vars: &CFDictionary<CFString, CFNumber>) -> Result<CGFont, ()> { 67 unsafe { 68 let font_ref = CGFontCreateCopyWithVariations(self.as_ptr(), 69 vars.as_concrete_TypeRef()); 70 if !font_ref.is_null() { 71 Ok(CGFont::from_ptr(font_ref)) 72 } else { 73 Err(()) 74 } 75 } 76 } 77 postscript_name(&self) -> CFString78 pub fn postscript_name(&self) -> CFString { 79 unsafe { 80 let string_ref = CGFontCopyPostScriptName(self.as_ptr()); 81 TCFType::wrap_under_create_rule(string_ref) 82 } 83 } 84 get_glyph_b_boxes(&self, glyphs: &[CGGlyph], bboxes: &mut [CGRect]) -> bool85 pub fn get_glyph_b_boxes(&self, glyphs: &[CGGlyph], bboxes: &mut [CGRect]) -> bool { 86 unsafe { 87 assert!(bboxes.len() >= glyphs.len()); 88 CGFontGetGlyphBBoxes(self.as_ptr(), 89 glyphs.as_ptr(), 90 glyphs.len(), 91 bboxes.as_mut_ptr()) 92 } 93 } 94 get_glyph_advances(&self, glyphs: &[CGGlyph], advances: &mut [c_int]) -> bool95 pub fn get_glyph_advances(&self, glyphs: &[CGGlyph], advances: &mut [c_int]) -> bool { 96 unsafe { 97 assert!(advances.len() >= glyphs.len()); 98 CGFontGetGlyphAdvances(self.as_ptr(), 99 glyphs.as_ptr(), 100 glyphs.len(), 101 advances.as_mut_ptr()) 102 } 103 } 104 get_units_per_em(&self) -> c_int105 pub fn get_units_per_em(&self) -> c_int { 106 unsafe { 107 CGFontGetUnitsPerEm(self.as_ptr()) 108 } 109 } 110 copy_table_tags(&self) -> CFArray<u32>111 pub fn copy_table_tags(&self) -> CFArray<u32> { 112 unsafe { 113 TCFType::wrap_under_create_rule(CGFontCopyTableTags(self.as_ptr())) 114 } 115 } 116 copy_table_for_tag(&self, tag: u32) -> Option<CFData>117 pub fn copy_table_for_tag(&self, tag: u32) -> Option<CFData> { 118 let data_ref = unsafe { CGFontCopyTableForTag(self.as_ptr(), tag) }; 119 if !data_ref.is_null() { 120 Some(unsafe { TCFType::wrap_under_create_rule(data_ref) }) 121 } else { 122 None 123 } 124 } 125 } 126 127 #[link(name = "CoreGraphics", kind = "framework")] 128 extern { 129 // TODO: basically nothing has bindings (even commented-out) besides what we use. CGFontCreateWithDataProvider(provider: ::sys::CGDataProviderRef) -> ::sys::CGFontRef130 fn CGFontCreateWithDataProvider(provider: ::sys::CGDataProviderRef) -> ::sys::CGFontRef; CGFontCreateWithFontName(name: CFStringRef) -> ::sys::CGFontRef131 fn CGFontCreateWithFontName(name: CFStringRef) -> ::sys::CGFontRef; CGFontCreateCopyWithVariations(font: ::sys::CGFontRef, vars: CFDictionaryRef) -> ::sys::CGFontRef132 fn CGFontCreateCopyWithVariations(font: ::sys::CGFontRef, vars: CFDictionaryRef) -> ::sys::CGFontRef; CGFontGetTypeID() -> CFTypeID133 fn CGFontGetTypeID() -> CFTypeID; 134 CGFontCopyPostScriptName(font: ::sys::CGFontRef) -> CFStringRef135 fn CGFontCopyPostScriptName(font: ::sys::CGFontRef) -> CFStringRef; 136 137 // These do the same thing as CFRetain/CFRelease, except 138 // gracefully handle a NULL argument. We don't use them. 139 //fn CGFontRetain(font: ::sys::CGFontRef); 140 //fn CGFontRelease(font: ::sys::CGFontRef); 141 CGFontGetGlyphBBoxes(font: ::sys::CGFontRef, glyphs: *const CGGlyph, count: size_t, bboxes: *mut CGRect) -> bool142 fn CGFontGetGlyphBBoxes(font: ::sys::CGFontRef, 143 glyphs: *const CGGlyph, 144 count: size_t, 145 bboxes: *mut CGRect) 146 -> bool; CGFontGetGlyphAdvances(font: ::sys::CGFontRef, glyphs: *const CGGlyph, count: size_t, advances: *mut c_int) -> bool147 fn CGFontGetGlyphAdvances(font: ::sys::CGFontRef, 148 glyphs: *const CGGlyph, 149 count: size_t, 150 advances: *mut c_int) 151 -> bool; CGFontGetUnitsPerEm(font: ::sys::CGFontRef) -> c_int152 fn CGFontGetUnitsPerEm(font: ::sys::CGFontRef) -> c_int; 153 CGFontCopyTableTags(font: ::sys::CGFontRef) -> CFArrayRef154 fn CGFontCopyTableTags(font: ::sys::CGFontRef) -> CFArrayRef; CGFontCopyTableForTag(font: ::sys::CGFontRef, tag: u32) -> CFDataRef155 fn CGFontCopyTableForTag(font: ::sys::CGFontRef, tag: u32) -> CFDataRef; 156 } 157