mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
auto merge of #3663 : glennw/servo/font-fallback, r=pcwalton
Previously, any font template that could not be found would return an item from the last resort font family. Now, the last resort font family is only searched if the entire list of supplied font families is empty.
This commit is contained in:
commit
d04733cf59
2 changed files with 75 additions and 16 deletions
|
@ -71,13 +71,14 @@ impl FontFamily {
|
||||||
/// Commands that the FontContext sends to the font cache task.
|
/// Commands that the FontContext sends to the font cache task.
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
GetFontTemplate(String, FontTemplateDescriptor, Sender<Reply>),
|
GetFontTemplate(String, FontTemplateDescriptor, Sender<Reply>),
|
||||||
|
GetLastResortFontTemplate(FontTemplateDescriptor, Sender<Reply>),
|
||||||
AddWebFont(String, Url, Sender<()>),
|
AddWebFont(String, Url, Sender<()>),
|
||||||
Exit(Sender<()>),
|
Exit(Sender<()>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reply messages sent from the font cache task to the FontContext caller.
|
/// Reply messages sent from the font cache task to the FontContext caller.
|
||||||
pub enum Reply {
|
pub enum Reply {
|
||||||
GetFontTemplateReply(Arc<FontTemplateData>),
|
GetFontTemplateReply(Option<Arc<FontTemplateData>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The font cache task itself. It maintains a list of reference counted
|
/// The font cache task itself. It maintains a list of reference counted
|
||||||
|
@ -109,12 +110,11 @@ impl FontCache {
|
||||||
match msg {
|
match msg {
|
||||||
GetFontTemplate(family, descriptor, result) => {
|
GetFontTemplate(family, descriptor, result) => {
|
||||||
let maybe_font_template = self.get_font_template(&family, &descriptor);
|
let maybe_font_template = self.get_font_template(&family, &descriptor);
|
||||||
let font_template = match maybe_font_template {
|
result.send(GetFontTemplateReply(maybe_font_template));
|
||||||
Some(font_template) => font_template,
|
}
|
||||||
None => self.get_last_resort_template(&descriptor),
|
GetLastResortFontTemplate(descriptor, result) => {
|
||||||
};
|
let font_template = self.get_last_resort_font_template(&descriptor);
|
||||||
|
result.send(GetFontTemplateReply(Some(font_template)));
|
||||||
result.send(GetFontTemplateReply(font_template));
|
|
||||||
}
|
}
|
||||||
AddWebFont(family_name, url, result) => {
|
AddWebFont(family_name, url, result) => {
|
||||||
let maybe_resource = load_whole_resource(&self.resource_task, url.clone());
|
let maybe_resource = load_whole_resource(&self.resource_task, url.clone());
|
||||||
|
@ -197,7 +197,8 @@ impl FontCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_font_template(&mut self, family: &String, desc: &FontTemplateDescriptor) -> Option<Arc<FontTemplateData>> {
|
fn get_font_template(&mut self, family: &String, desc: &FontTemplateDescriptor)
|
||||||
|
-> Option<Arc<FontTemplateData>> {
|
||||||
let transformed_family_name = self.transform_family(family);
|
let transformed_family_name = self.transform_family(family);
|
||||||
let mut maybe_template = self.find_font_in_web_family(&transformed_family_name, desc);
|
let mut maybe_template = self.find_font_in_web_family(&transformed_family_name, desc);
|
||||||
if maybe_template.is_none() {
|
if maybe_template.is_none() {
|
||||||
|
@ -206,7 +207,8 @@ impl FontCache {
|
||||||
maybe_template
|
maybe_template
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_last_resort_template(&mut self, desc: &FontTemplateDescriptor) -> Arc<FontTemplateData> {
|
fn get_last_resort_font_template(&mut self, desc: &FontTemplateDescriptor)
|
||||||
|
-> Arc<FontTemplateData> {
|
||||||
let last_resort = get_last_resort_font_families();
|
let last_resort = get_last_resort_font_families();
|
||||||
|
|
||||||
for family in last_resort.iter() {
|
for family in last_resort.iter() {
|
||||||
|
@ -259,7 +261,7 @@ impl FontCacheTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_font_template(&self, family: String, desc: FontTemplateDescriptor)
|
pub fn get_font_template(&self, family: String, desc: FontTemplateDescriptor)
|
||||||
-> Arc<FontTemplateData> {
|
-> Option<Arc<FontTemplateData>> {
|
||||||
|
|
||||||
let (response_chan, response_port) = channel();
|
let (response_chan, response_port) = channel();
|
||||||
self.chan.send(GetFontTemplate(family, desc, response_chan));
|
self.chan.send(GetFontTemplate(family, desc, response_chan));
|
||||||
|
@ -273,6 +275,21 @@ impl FontCacheTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_last_resort_font_template(&self, desc: FontTemplateDescriptor)
|
||||||
|
-> Arc<FontTemplateData> {
|
||||||
|
|
||||||
|
let (response_chan, response_port) = channel();
|
||||||
|
self.chan.send(GetLastResortFontTemplate(desc, response_chan));
|
||||||
|
|
||||||
|
let reply = response_port.recv();
|
||||||
|
|
||||||
|
match reply {
|
||||||
|
GetFontTemplateReply(data) => {
|
||||||
|
data.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_web_font(&self, family: String, url: Url) {
|
pub fn add_web_font(&self, family: String, url: Url) {
|
||||||
let (response_chan, response_port) = channel();
|
let (response_chan, response_port) = channel();
|
||||||
self.chan.send(AddWebFont(family, url, response_chan));
|
self.chan.send(AddWebFont(family, url, response_chan));
|
||||||
|
|
|
@ -45,6 +45,10 @@ struct LayoutFontCacheEntry {
|
||||||
font: Rc<RefCell<Font>>,
|
font: Rc<RefCell<Font>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct FallbackFontCacheEntry {
|
||||||
|
font: Rc<RefCell<Font>>,
|
||||||
|
}
|
||||||
|
|
||||||
/// A cached azure font (per render task) that
|
/// A cached azure font (per render task) that
|
||||||
/// can be shared by multiple text runs.
|
/// can be shared by multiple text runs.
|
||||||
struct RenderFontCacheEntry {
|
struct RenderFontCacheEntry {
|
||||||
|
@ -63,6 +67,7 @@ pub struct FontContext {
|
||||||
|
|
||||||
/// TODO: See bug https://github.com/servo/servo/issues/3300.
|
/// TODO: See bug https://github.com/servo/servo/issues/3300.
|
||||||
layout_font_cache: Vec<LayoutFontCacheEntry>,
|
layout_font_cache: Vec<LayoutFontCacheEntry>,
|
||||||
|
fallback_font_cache: Vec<FallbackFontCacheEntry>,
|
||||||
|
|
||||||
/// Strong reference as the render FontContext is (for now) recycled
|
/// Strong reference as the render FontContext is (for now) recycled
|
||||||
/// per frame. TODO: Make this weak when incremental redraw is done.
|
/// per frame. TODO: Make this weak when incremental redraw is done.
|
||||||
|
@ -76,6 +81,7 @@ impl FontContext {
|
||||||
platform_handle: handle,
|
platform_handle: handle,
|
||||||
font_cache_task: font_cache_task,
|
font_cache_task: font_cache_task,
|
||||||
layout_font_cache: vec!(),
|
layout_font_cache: vec!(),
|
||||||
|
fallback_font_cache: vec!(),
|
||||||
render_font_cache: vec!(),
|
render_font_cache: vec!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,11 +122,10 @@ impl FontContext {
|
||||||
// TODO: The font context holds a strong ref to the cached fonts
|
// TODO: The font context holds a strong ref to the cached fonts
|
||||||
// so they will never be released. Find out a good time to drop them.
|
// so they will never be released. Find out a good time to drop them.
|
||||||
|
|
||||||
|
let desc = FontTemplateDescriptor::new(style.weight, style.style == font_style::italic);
|
||||||
let mut fonts: Vec<Rc<RefCell<Font>>> = vec!();
|
let mut fonts: Vec<Rc<RefCell<Font>>> = vec!();
|
||||||
|
|
||||||
for family in style.families.iter() {
|
for family in style.families.iter() {
|
||||||
let desc = FontTemplateDescriptor::new(style.weight, style.style == font_style::italic);
|
|
||||||
|
|
||||||
// GWTODO: Check on real pages if this is faster as Vec() or HashMap().
|
// GWTODO: Check on real pages if this is faster as Vec() or HashMap().
|
||||||
let mut cache_hit = false;
|
let mut cache_hit = false;
|
||||||
for cached_font_entry in self.layout_font_cache.iter() {
|
for cached_font_entry in self.layout_font_cache.iter() {
|
||||||
|
@ -138,10 +143,47 @@ impl FontContext {
|
||||||
|
|
||||||
if !cache_hit {
|
if !cache_hit {
|
||||||
let font_template = self.font_cache_task.get_font_template(family.clone(), desc.clone());
|
let font_template = self.font_cache_task.get_font_template(family.clone(), desc.clone());
|
||||||
let layout_font = Rc::new(RefCell::new(self.create_layout_font(font_template,
|
match font_template {
|
||||||
desc.clone(), style.pt_size, style.variant)));
|
Some(font_template) => {
|
||||||
self.layout_font_cache.push(LayoutFontCacheEntry {
|
let layout_font = self.create_layout_font(font_template,
|
||||||
family: family.clone(),
|
desc.clone(),
|
||||||
|
style.pt_size,
|
||||||
|
style.variant);
|
||||||
|
let layout_font = Rc::new(RefCell::new(layout_font));
|
||||||
|
self.layout_font_cache.push(LayoutFontCacheEntry {
|
||||||
|
family: family.clone(),
|
||||||
|
font: layout_font.clone(),
|
||||||
|
});
|
||||||
|
fonts.push(layout_font);
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If unable to create any of the specified fonts, create one from the
|
||||||
|
// list of last resort fonts for this platform.
|
||||||
|
if fonts.len() == 0 {
|
||||||
|
let mut cache_hit = false;
|
||||||
|
for cached_font_entry in self.fallback_font_cache.iter() {
|
||||||
|
let cached_font = cached_font_entry.font.borrow();
|
||||||
|
if cached_font.descriptor == desc &&
|
||||||
|
cached_font.requested_pt_size == style.pt_size &&
|
||||||
|
cached_font.variant == style.variant {
|
||||||
|
fonts.push(cached_font_entry.font.clone());
|
||||||
|
cache_hit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !cache_hit {
|
||||||
|
let font_template = self.font_cache_task.get_last_resort_font_template(desc.clone());
|
||||||
|
let layout_font = self.create_layout_font(font_template,
|
||||||
|
desc.clone(),
|
||||||
|
style.pt_size,
|
||||||
|
style.variant);
|
||||||
|
let layout_font = Rc::new(RefCell::new(layout_font));
|
||||||
|
self.fallback_font_cache.push(FallbackFontCacheEntry {
|
||||||
font: layout_font.clone(),
|
font: layout_font.clone(),
|
||||||
});
|
});
|
||||||
fonts.push(layout_font);
|
fonts.push(layout_font);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue