Handle font load errors in FontContext

Thread font load errors from platform font loading code to
FontContext::get_layout_font_group_for_style, and cache the failure
result, instead of panicing the thread when a font fails to load.

Before this patch, a failed font load would panic a LayoutTask,
causing a cascade of panics, eventually aborting the whole engine
during a panic within panic.
This commit is contained in:
Mikko Perttunen 2015-03-05 14:10:21 +02:00
parent 67548a6244
commit 92a4bba785

View file

@ -97,7 +97,7 @@ impl FontContext {
/// Create a font for use in layout calculations. /// Create a font for use in layout calculations.
fn create_layout_font(&self, template: Arc<FontTemplateData>, fn create_layout_font(&self, template: Arc<FontTemplateData>,
descriptor: FontTemplateDescriptor, pt_size: Au, descriptor: FontTemplateDescriptor, pt_size: Au,
variant: font_variant::T) -> Font { variant: font_variant::T) -> Result<Font, ()> {
// TODO: (Bug #3463): Currently we only support fake small-caps // TODO: (Bug #3463): Currently we only support fake small-caps
// painting. We should also support true small-caps (where the // painting. We should also support true small-caps (where the
// font supports it) in the future. // font supports it) in the future.
@ -106,8 +106,11 @@ impl FontContext {
font_variant::T::normal => pt_size, font_variant::T::normal => pt_size,
}; };
let handle: FontHandle = FontHandleMethods::new_from_template(&self.platform_handle, let handle: Result<FontHandle, _> =
template, Some(actual_pt_size)).unwrap(); FontHandleMethods::new_from_template(&self.platform_handle, template,
Some(actual_pt_size));
handle.map(|handle| {
let metrics = handle.get_metrics(); let metrics = handle.get_metrics();
Font { Font {
@ -121,6 +124,7 @@ impl FontContext {
shape_cache: HashCache::new(), shape_cache: HashCache::new(),
glyph_advance_cache: HashCache::new(), glyph_advance_cache: HashCache::new(),
} }
})
} }
/// Create a group of fonts for use in layout calculations. May return /// Create a group of fonts for use in layout calculations. May return
@ -179,12 +183,20 @@ impl FontContext {
desc.clone(), desc.clone(),
style.font_size, style.font_size,
style.font_variant); style.font_variant);
let font = match layout_font {
Ok(layout_font) => {
let layout_font = Rc::new(RefCell::new(layout_font)); let layout_font = Rc::new(RefCell::new(layout_font));
fonts.push(layout_font.clone());
Some(layout_font)
}
Err(_) => None
};
self.layout_font_cache.push(LayoutFontCacheEntry { self.layout_font_cache.push(LayoutFontCacheEntry {
family: family.name().to_owned(), family: family.name().to_owned(),
font: Some(layout_font.clone()), font: font
}); });
fonts.push(layout_font);
} }
None => { None => {
self.layout_font_cache.push(LayoutFontCacheEntry { self.layout_font_cache.push(LayoutFontCacheEntry {
@ -217,12 +229,17 @@ impl FontContext {
desc.clone(), desc.clone(),
style.font_size, style.font_size,
style.font_variant); style.font_variant);
match layout_font {
Ok(layout_font) => {
let layout_font = Rc::new(RefCell::new(layout_font)); let layout_font = Rc::new(RefCell::new(layout_font));
self.fallback_font_cache.push(FallbackFontCacheEntry { self.fallback_font_cache.push(FallbackFontCacheEntry {
font: layout_font.clone(), font: layout_font.clone(),
}); });
fonts.push(layout_font); fonts.push(layout_font);
} }
Err(_) => debug!("Failed to create fallback layout font!")
}
}
} }
let font_group = Rc::new(FontGroup::new(fonts)); let font_group = Rc::new(FontGroup::new(fonts));