mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Don't load all font faces sources
We stop at the first one we manage to load.
This commit is contained in:
parent
04b682195d
commit
b97c7a8c4d
4 changed files with 131 additions and 117 deletions
|
@ -21,7 +21,7 @@ use std::ops::Deref;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::u32;
|
use std::u32;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
use style::font_face::Source;
|
use style::font_face::{EffectiveSources, Source};
|
||||||
use style::properties::longhands::font_family::computed_value::FontFamily;
|
use style::properties::longhands::font_family::computed_value::FontFamily;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use util::prefs;
|
use util::prefs;
|
||||||
|
@ -105,8 +105,8 @@ impl FontTemplates {
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
GetFontTemplate(FontFamily, FontTemplateDescriptor, IpcSender<Reply>),
|
GetFontTemplate(FontFamily, FontTemplateDescriptor, IpcSender<Reply>),
|
||||||
GetLastResortFontTemplate(FontTemplateDescriptor, IpcSender<Reply>),
|
GetLastResortFontTemplate(FontTemplateDescriptor, IpcSender<Reply>),
|
||||||
AddWebFont(FontFamily, Source, IpcSender<()>),
|
AddWebFont(LowercaseString, EffectiveSources, IpcSender<()>),
|
||||||
AddDownloadedWebFont(FontFamily, Url, Vec<u8>, IpcSender<()>),
|
AddDownloadedWebFont(LowercaseString, Url, Vec<u8>, IpcSender<()>),
|
||||||
Exit(IpcSender<()>),
|
Exit(IpcSender<()>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,8 +171,33 @@ impl FontCache {
|
||||||
let font_template = self.last_resort_font_template(&descriptor);
|
let font_template = self.last_resort_font_template(&descriptor);
|
||||||
result.send(Reply::GetFontTemplateReply(Some(font_template))).unwrap();
|
result.send(Reply::GetFontTemplateReply(Some(font_template))).unwrap();
|
||||||
}
|
}
|
||||||
Command::AddWebFont(family, src, result) => {
|
Command::AddWebFont(family_name, sources, result) => {
|
||||||
let family_name = LowercaseString::new(family.name());
|
self.handle_add_web_font(family_name, sources, result);
|
||||||
|
}
|
||||||
|
Command::AddDownloadedWebFont(family_name, url, bytes, result) => {
|
||||||
|
let templates = &mut self.web_families.get_mut(&family_name).unwrap();
|
||||||
|
templates.add_template(Atom::from(url.to_string()), Some(bytes));
|
||||||
|
drop(result.send(()));
|
||||||
|
}
|
||||||
|
Command::Exit(result) => {
|
||||||
|
result.send(()).unwrap();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_add_web_font(&mut self,
|
||||||
|
family_name: LowercaseString,
|
||||||
|
mut sources: EffectiveSources,
|
||||||
|
sender: IpcSender<()>) {
|
||||||
|
let src = if let Some(src) = sources.next() {
|
||||||
|
src
|
||||||
|
} else {
|
||||||
|
sender.send(()).unwrap();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
if !self.web_families.contains_key(&family_name) {
|
if !self.web_families.contains_key(&family_name) {
|
||||||
let templates = FontTemplates::new();
|
let templates = FontTemplates::new();
|
||||||
self.web_families.insert(family_name.clone(), templates);
|
self.web_families.insert(family_name.clone(), templates);
|
||||||
|
@ -224,16 +249,17 @@ impl FontCache {
|
||||||
}
|
}
|
||||||
ResponseAction::ResponseComplete(response) => {
|
ResponseAction::ResponseComplete(response) => {
|
||||||
if response.is_err() || !*response_valid.lock().unwrap() {
|
if response.is_err() || !*response_valid.lock().unwrap() {
|
||||||
drop(result.send(()));
|
let msg = Command::AddWebFont(family_name.clone(), sources.clone(), sender.clone());
|
||||||
|
channel_to_self.send(msg).unwrap();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut bytes = bytes.lock().unwrap();
|
let mut bytes = bytes.lock().unwrap();
|
||||||
let bytes = mem::replace(&mut *bytes, Vec::new());
|
let bytes = mem::replace(&mut *bytes, Vec::new());
|
||||||
let command =
|
let command =
|
||||||
Command::AddDownloadedWebFont(family.clone(),
|
Command::AddDownloadedWebFont(family_name.clone(),
|
||||||
url.clone(),
|
url.clone(),
|
||||||
bytes,
|
bytes,
|
||||||
result.clone());
|
sender.clone());
|
||||||
channel_to_self.send(command).unwrap();
|
channel_to_self.send(command).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,21 +271,7 @@ impl FontCache {
|
||||||
for_each_variation(&font_face_name, |path| {
|
for_each_variation(&font_face_name, |path| {
|
||||||
templates.add_template(Atom::from(&*path), None);
|
templates.add_template(Atom::from(&*path), None);
|
||||||
});
|
});
|
||||||
result.send(()).unwrap();
|
sender.send(()).unwrap();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Command::AddDownloadedWebFont(family, url, bytes, result) => {
|
|
||||||
let family_name = LowercaseString::new(family.name());
|
|
||||||
|
|
||||||
let templates = &mut self.web_families.get_mut(&family_name).unwrap();
|
|
||||||
templates.add_template(Atom::from(url.to_string()), Some(bytes));
|
|
||||||
drop(result.send(()));
|
|
||||||
}
|
|
||||||
Command::Exit(result) => {
|
|
||||||
result.send(()).unwrap();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -431,8 +443,8 @@ impl FontCacheThread {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_web_font(&self, family: FontFamily, src: Source, sender: IpcSender<()>) {
|
pub fn add_web_font(&self, family: FontFamily, sources: EffectiveSources, sender: IpcSender<()>) {
|
||||||
self.chan.send(Command::AddWebFont(family, src, sender)).unwrap();
|
self.chan.send(Command::AddWebFont(LowercaseString::new(family.name()), sources, sender)).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exit(&self) {
|
pub fn exit(&self) {
|
||||||
|
|
|
@ -358,24 +358,22 @@ fn add_font_face_rules(stylesheet: &Stylesheet,
|
||||||
if opts::get().load_webfonts_synchronously {
|
if opts::get().load_webfonts_synchronously {
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
for font_face in stylesheet.effective_rules(&device).font_face() {
|
for font_face in stylesheet.effective_rules(&device).font_face() {
|
||||||
for source in font_face.effective_sources() {
|
let effective_sources = font_face.effective_sources();
|
||||||
font_cache_thread.add_web_font(font_face.family.clone(),
|
font_cache_thread.add_web_font(font_face.family.clone(),
|
||||||
(*source).clone(),
|
effective_sources,
|
||||||
sender.clone());
|
sender.clone());
|
||||||
receiver.recv().unwrap();
|
receiver.recv().unwrap();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for font_face in stylesheet.effective_rules(&device).font_face() {
|
for font_face in stylesheet.effective_rules(&device).font_face() {
|
||||||
for source in font_face.effective_sources() {
|
let effective_sources = font_face.effective_sources();
|
||||||
outstanding_web_fonts_counter.fetch_add(1, Ordering::SeqCst);
|
outstanding_web_fonts_counter.fetch_add(1, Ordering::SeqCst);
|
||||||
font_cache_thread.add_web_font(font_face.family.clone(),
|
font_cache_thread.add_web_font(font_face.family.clone(),
|
||||||
(*source).clone(),
|
effective_sources,
|
||||||
(*font_cache_sender).clone());
|
(*font_cache_sender).clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl LayoutThread {
|
impl LayoutThread {
|
||||||
/// Creates a new `LayoutThread` structure.
|
/// Creates a new `LayoutThread` structure.
|
||||||
|
|
|
@ -7,7 +7,6 @@ use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
|
||||||
use parser::{ParserContext, log_css_error};
|
use parser::{ParserContext, log_css_error};
|
||||||
use properties::longhands::font_family::parse_one_family;
|
use properties::longhands::font_family::parse_one_family;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::slice;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[derive(Clone, Debug, HeapSizeOf, PartialEq, Eq, Deserialize, Serialize)]
|
#[derive(Clone, Debug, HeapSizeOf, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
|
@ -60,21 +59,15 @@ pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EffectiveSourcesIter<'a>(slice::Iter<'a, Source>);
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct EffectiveSources(Vec<Source>);
|
||||||
|
|
||||||
impl FontFaceRule {
|
impl FontFaceRule {
|
||||||
/// Returns the list of effective sources for that font-face, that is the
|
/// Returns the list of effective sources for that font-face, that is the
|
||||||
/// sources which don't list any format hint, or the ones which list at
|
/// sources which don't list any format hint, or the ones which list at
|
||||||
/// least "truetype" or "opentype".
|
/// least "truetype" or "opentype".
|
||||||
pub fn effective_sources(&self) -> EffectiveSourcesIter {
|
pub fn effective_sources(&self) -> EffectiveSources {
|
||||||
EffectiveSourcesIter(self.sources.iter())
|
EffectiveSources(self.sources.iter().rev().filter(|source| {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> iter::Iterator for EffectiveSourcesIter<'a> {
|
|
||||||
type Item = &'a Source;
|
|
||||||
fn next(&mut self) -> Option<&'a Source> {
|
|
||||||
self.0.find(|source| {
|
|
||||||
if let Source::Url(ref url_source) = **source {
|
if let Source::Url(ref url_source) = **source {
|
||||||
let hints = &url_source.format_hints;
|
let hints = &url_source.format_hints;
|
||||||
// We support only opentype fonts and truetype is an alias for
|
// We support only opentype fonts and truetype is an alias for
|
||||||
|
@ -86,7 +79,14 @@ impl<'a> iter::Iterator for EffectiveSourcesIter<'a> {
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
})
|
}).cloned().collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl iter::Iterator for EffectiveSources {
|
||||||
|
type Item = Source;
|
||||||
|
fn next(&mut self) -> Option<Source> {
|
||||||
|
self.0.pop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use gfx::font_cache_thread::FontCacheThread;
|
use gfx::font_cache_thread::FontCacheThread;
|
||||||
use ipc_channel::ipc;
|
use ipc_channel::ipc;
|
||||||
use style::computed_values::font_family::FontFamily;
|
use style::computed_values::font_family::FontFamily;
|
||||||
use style::font_face::Source;
|
use style::font_face::{FontFaceRule, Source};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_local_web_font() {
|
fn test_local_web_font() {
|
||||||
|
@ -14,8 +14,12 @@ fn test_local_web_font() {
|
||||||
let font_cache_thread = FontCacheThread::new(inp_chan, None);
|
let font_cache_thread = FontCacheThread::new(inp_chan, None);
|
||||||
let family_name = FontFamily::FamilyName(From::from("test family"));
|
let family_name = FontFamily::FamilyName(From::from("test family"));
|
||||||
let variant_name = FontFamily::FamilyName(From::from("test font face"));
|
let variant_name = FontFamily::FamilyName(From::from("test font face"));
|
||||||
|
let font_face_rule = FontFaceRule {
|
||||||
|
family: family_name.clone(),
|
||||||
|
sources: vec![Source::Local(variant_name)],
|
||||||
|
};
|
||||||
|
|
||||||
font_cache_thread.add_web_font(family_name, Source::Local(variant_name), out_chan);
|
font_cache_thread.add_web_font(family_name, font_face_rule.effective_sources(), out_chan);
|
||||||
|
|
||||||
assert_eq!(out_receiver.recv().unwrap(), ());
|
assert_eq!(out_receiver.recv().unwrap(), ());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue