Auto merge of #46 - pcwalton:postscript-names, r=glennw

Support serialization of `CGFont` objects.

Due to API limitations, this will only serialize native fonts, not Web
fonts. Specifically, there is no way I know of to fetch the
`CGDataProvider` associated with a `CGFont`. This isn't a problem for
Servo, however, because Servo knows which fonts are Web fonts and stores
their byte data separately.

r? @glennw or @larsbergstrom

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/core-graphics-rs/46)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo
2015-12-01 06:13:48 +05:30
3 changed files with 44 additions and 2 deletions
+2
View File
@@ -10,3 +10,5 @@ license = "MIT / Apache-2.0"
[dependencies]
libc = "0.2"
core-foundation = "0.2"
serde = "0.6"
+41 -2
View File
@@ -8,9 +8,12 @@
// except according to those terms.
use core_foundation::base::{CFRelease, CFRetain, CFTypeID, CFTypeRef, TCFType};
use core_foundation::string::{CFString, CFStringRef};
use data_provider::{CGDataProvider, CGDataProviderRef};
use libc;
use serde::de::{self, Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};
use std::mem;
use std::ptr;
@@ -28,6 +31,22 @@ pub struct CGFont {
unsafe impl Send for CGFont {}
unsafe impl Sync for CGFont {}
impl Serialize for CGFont {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
let postscript_name = self.postscript_name().to_string();
postscript_name.serialize(serializer)
}
}
impl Deserialize for CGFont {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where D: Deserializer {
let postscript_name: String = try!(Deserialize::deserialize(deserializer));
CGFont::from_name(&CFString::new(&*postscript_name)).map_err(|err| {
de::Error::syntax("Couldn't find a font with that PostScript name!")
})
}
}
impl Clone for CGFont {
#[inline]
fn clone(&self) -> CGFont {
@@ -92,15 +111,35 @@ impl CGFont {
}
}
}
pub fn from_name(name: &CFString) -> Result<CGFont, ()> {
unsafe {
let font_ref = CGFontCreateWithFontName(name.as_concrete_TypeRef());
if font_ref != ptr::null() {
Ok(TCFType::wrap_under_create_rule(font_ref))
} else {
Err(())
}
}
}
pub fn postscript_name(&self) -> CFString {
unsafe {
let string_ref = CGFontCopyPostScriptName(self.obj);
TCFType::wrap_under_create_rule(string_ref)
}
}
}
#[link(name = "ApplicationServices", kind = "framework")]
extern {
// TODO: basically nothing has bindings (even commented-out) besides what we use.
// TODO: basically nothing has bindings (even commented-out) besides what we use.
fn CGFontCreateWithDataProvider(provider: CGDataProviderRef) -> CGFontRef;
fn CGFontCreateWithFontName(name: CFStringRef) -> CGFontRef;
fn CGFontGetTypeID() -> CFTypeID;
fn CGFontCopyPostScriptName(font: CGFontRef) -> CFStringRef;
// These do the same thing as CFRetain/CFRelease, except
// gracefully handle a NULL argument. We don't use them.
//fn CGFontRetain(font: CGFontRef);
+1
View File
@@ -9,6 +9,7 @@
extern crate libc;
extern crate core_foundation;
extern crate serde;
pub mod base;
pub mod color_space;