blob: fc7a9baed0d0003f6884ffe453c9e758b098c95e [file] [log] [blame]
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::ptr;
use core_foundation::base::{CFRelease, CFRetain, 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::{self, c_int, size_t};
pub type CGGlyph = libc::c_ushort;
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<CGFont, ()> {
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<CGFont, ()> {
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<CFString, CFNumber>) -> Result<CGFont, ()> {
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<u32> {
unsafe {
TCFType::wrap_under_create_rule(CGFontCopyTableTags(self.as_ptr()))
}
}
pub fn copy_table_for_tag(&self, tag: u32) -> Option<CFData> {
let data_ref = unsafe { CGFontCopyTableForTag(self.as_ptr(), tag) };
if data_ref != ptr::null() {
Some(unsafe { TCFType::wrap_under_create_rule(data_ref) })
} 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;
}