// Copyright 2013 The Servo Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use core_foundation::base::{CFRelease, CFRetain, CFType, CFTypeID, TCFType}; use core_foundation::array::{CFArray, CFArrayRef}; use core_foundation::data::{CFData, CFDataRef}; use core_foundation::number::CFNumber; use core_foundation::string::{CFString, CFStringRef}; use core_foundation::dictionary::{CFDictionary, CFDictionaryRef}; use data_provider::CGDataProvider; use geometry::CGRect; use foreign_types::ForeignType; use libc::{c_int, size_t}; pub use core_graphics_types::base::CGGlyph; foreign_type! { #[doc(hidden)] type CType = ::sys::CGFont; fn drop = |p| CFRelease(p as *mut _); fn clone = |p| CFRetain(p as *const _) as *mut _; pub struct CGFont; pub struct CGFontRef; } unsafe impl Send for CGFont {} unsafe impl Sync for CGFont {} impl CGFont { pub fn type_id() -> CFTypeID { unsafe { CGFontGetTypeID() } } pub fn from_data_provider(provider: CGDataProvider) -> Result { unsafe { let font_ref = CGFontCreateWithDataProvider(provider.as_ptr()); if !font_ref.is_null() { Ok(CGFont::from_ptr(font_ref)) } else { Err(()) } } } pub fn from_name(name: &CFString) -> Result { unsafe { let font_ref = CGFontCreateWithFontName(name.as_concrete_TypeRef()); if !font_ref.is_null() { Ok(CGFont::from_ptr(font_ref)) } else { Err(()) } } } pub fn create_copy_from_variations(&self, vars: &CFDictionary) -> Result { unsafe { let font_ref = CGFontCreateCopyWithVariations(self.as_ptr(), vars.as_concrete_TypeRef()); if !font_ref.is_null() { Ok(CGFont::from_ptr(font_ref)) } else { Err(()) } } } pub fn postscript_name(&self) -> CFString { unsafe { let string_ref = CGFontCopyPostScriptName(self.as_ptr()); TCFType::wrap_under_create_rule(string_ref) } } pub fn get_glyph_b_boxes(&self, glyphs: &[CGGlyph], bboxes: &mut [CGRect]) -> bool { unsafe { assert!(bboxes.len() >= glyphs.len()); CGFontGetGlyphBBoxes(self.as_ptr(), glyphs.as_ptr(), glyphs.len(), bboxes.as_mut_ptr()) } } pub fn get_glyph_advances(&self, glyphs: &[CGGlyph], advances: &mut [c_int]) -> bool { unsafe { assert!(advances.len() >= glyphs.len()); CGFontGetGlyphAdvances(self.as_ptr(), glyphs.as_ptr(), glyphs.len(), advances.as_mut_ptr()) } } pub fn get_units_per_em(&self) -> c_int { unsafe { CGFontGetUnitsPerEm(self.as_ptr()) } } pub fn copy_table_tags(&self) -> CFArray { unsafe { TCFType::wrap_under_create_rule(CGFontCopyTableTags(self.as_ptr())) } } pub fn copy_table_for_tag(&self, tag: u32) -> Option { let data_ref = unsafe { CGFontCopyTableForTag(self.as_ptr(), tag) }; if !data_ref.is_null() { Some(unsafe { TCFType::wrap_under_create_rule(data_ref) }) } else { None } } pub fn copy_variations(&self) -> Option> { let variations = unsafe { CGFontCopyVariations(self.as_ptr()) }; if !variations.is_null() { Some(unsafe { TCFType::wrap_under_create_rule(variations) }) } else { None } } pub fn copy_variation_axes(&self) -> Option>> { let axes = unsafe { CGFontCopyVariationAxes(self.as_ptr()) }; if !axes.is_null() { Some(unsafe { TCFType::wrap_under_create_rule(axes) }) } else { None } } } #[link(name = "CoreGraphics", kind = "framework")] extern { // TODO: basically nothing has bindings (even commented-out) besides what we use. fn CGFontCreateWithDataProvider(provider: ::sys::CGDataProviderRef) -> ::sys::CGFontRef; fn CGFontCreateWithFontName(name: CFStringRef) -> ::sys::CGFontRef; fn CGFontCreateCopyWithVariations(font: ::sys::CGFontRef, vars: CFDictionaryRef) -> ::sys::CGFontRef; fn CGFontGetTypeID() -> CFTypeID; fn CGFontCopyPostScriptName(font: ::sys::CGFontRef) -> CFStringRef; // These do the same thing as CFRetain/CFRelease, except // gracefully handle a NULL argument. We don't use them. //fn CGFontRetain(font: ::sys::CGFontRef); //fn CGFontRelease(font: ::sys::CGFontRef); fn CGFontGetGlyphBBoxes(font: ::sys::CGFontRef, glyphs: *const CGGlyph, count: size_t, bboxes: *mut CGRect) -> bool; fn CGFontGetGlyphAdvances(font: ::sys::CGFontRef, glyphs: *const CGGlyph, count: size_t, advances: *mut c_int) -> bool; fn CGFontGetUnitsPerEm(font: ::sys::CGFontRef) -> c_int; fn CGFontCopyTableTags(font: ::sys::CGFontRef) -> CFArrayRef; fn CGFontCopyTableForTag(font: ::sys::CGFontRef, tag: u32) -> CFDataRef; fn CGFontCopyVariations(font: ::sys::CGFontRef) -> CFDictionaryRef; fn CGFontCopyVariationAxes(font: ::sys::CGFontRef) -> CFArrayRef; }