gfx: Instantiate the CTFont corresponding to a Mac font on demand.

This avoids panics in multiprocess mode.
This commit is contained in:
Patrick Walton 2015-07-27 14:18:50 -07:00
parent 1ff7a51f0a
commit e9ec9289d6
3 changed files with 18 additions and 8 deletions

View file

@ -42,7 +42,7 @@ fn create_scaled_font(template: &Arc<FontTemplateData>, pt_size: Au) -> ScaledFo
#[cfg(target_os="macos")]
fn create_scaled_font(template: &Arc<FontTemplateData>, pt_size: Au) -> ScaledFont {
let cgfont = template.ctfont.as_ref().unwrap().copy_to_CGFont();
let cgfont = template.ctfont().as_ref().unwrap().copy_to_CGFont();
ScaledFont::new(BackendType::Skia, &cgfont, pt_size.to_f32_px())
}

View file

@ -64,7 +64,7 @@ impl FontHandleMethods for FontHandle {
Some(s) => s.to_f64_px(),
None => 0.0
};
match *template.ctfont {
match template.ctfont() {
Some(ref ctfont) => {
Ok(FontHandle {
font_data: template.clone(),

View file

@ -11,6 +11,7 @@ use serde::de::{Error, Visitor};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::borrow::ToOwned;
use std::ops::Deref;
use std::sync::Mutex;
use string_cache::Atom;
/// Platform specific font representation for mac.
@ -26,7 +27,7 @@ pub struct FontTemplateData {
/// When sending a `FontTemplateData` instance across processes, this will be set to `None` on
/// the other side, because `CTFont` instances cannot be sent across processes. This is
/// harmless, however, because it can always be recreated.
pub ctfont: CachedCTFont,
ctfont: CachedCTFont,
pub identifier: Atom,
pub font_data: Option<Vec<u8>>
@ -52,18 +53,27 @@ impl FontTemplateData {
};
FontTemplateData {
ctfont: CachedCTFont(ctfont),
ctfont: CachedCTFont(Mutex::new(ctfont)),
identifier: identifier.to_owned(),
font_data: font_data
}
}
/// Retrieves the Core Text font instance, instantiating it if necessary.
pub fn ctfont(&self) -> Option<CTFont> {
let mut ctfont = self.ctfont.lock().unwrap();
if ctfont.is_none() {
*ctfont = core_text::font::new_from_name(self.identifier.as_slice(), 0.0).ok()
}
ctfont.as_ref().map(|ctfont| (*ctfont).clone())
}
}
pub struct CachedCTFont(Option<CTFont>);
pub struct CachedCTFont(Mutex<Option<CTFont>>);
impl Deref for CachedCTFont {
type Target = Option<CTFont>;
fn deref(&self) -> &Option<CTFont> {
type Target = Mutex<Option<CTFont>>;
fn deref(&self) -> &Mutex<Option<CTFont>> {
&self.0
}
}
@ -84,7 +94,7 @@ impl Deserialize for CachedCTFont {
#[inline]
fn visit_none<E>(&mut self) -> Result<CachedCTFont,E> where E: Error {
Ok(CachedCTFont(None))
Ok(CachedCTFont(Mutex::new(None)))
}
}