From 1621e0679e92d69bae37da1a30c268ee717bb7ca Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sat, 21 May 2016 00:55:01 +0200 Subject: [PATCH 1/2] Do not create a channel for each source in add_font_face_rules --- components/layout/layout_thread.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/components/layout/layout_thread.rs b/components/layout/layout_thread.rs index 779a23fba82..2d98b96fdcb 100644 --- a/components/layout/layout_thread.rs +++ b/components/layout/layout_thread.rs @@ -357,19 +357,23 @@ fn add_font_face_rules(stylesheet: &Stylesheet, font_cache_thread: &FontCacheThread, font_cache_sender: &IpcSender<()>, outstanding_web_fonts_counter: &Arc) { - for font_face in stylesheet.effective_rules(&device).font_face() { - for source in &font_face.sources { - if opts::get().load_webfonts_synchronously { - let (sender, receiver) = ipc::channel().unwrap(); + if opts::get().load_webfonts_synchronously { + let (sender, receiver) = ipc::channel().unwrap(); + for font_face in stylesheet.effective_rules(&device).font_face() { + for source in &font_face.sources { font_cache_thread.add_web_font(font_face.family.clone(), - (*source).clone(), - sender); + (*source).clone(), + sender.clone()); receiver.recv().unwrap(); - } else { + } + } + } else { + for font_face in stylesheet.effective_rules(&device).font_face() { + for source in &font_face.sources { outstanding_web_fonts_counter.fetch_add(1, Ordering::SeqCst); font_cache_thread.add_web_font(font_face.family.clone(), - (*source).clone(), - (*font_cache_sender).clone()); + (*source).clone(), + (*font_cache_sender).clone()); } } } From 64b34d516215985827249529a4977522a0f6be8e Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Thu, 2 Jun 2016 22:27:55 +0200 Subject: [PATCH 2/2] Introduce FontFaceRules::effective_sources() This avoids downloading fonts in formats we don't support. --- components/layout/layout_thread.rs | 4 ++-- components/style/font_face.rs | 32 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/components/layout/layout_thread.rs b/components/layout/layout_thread.rs index 2d98b96fdcb..db0968775a5 100644 --- a/components/layout/layout_thread.rs +++ b/components/layout/layout_thread.rs @@ -360,7 +360,7 @@ fn add_font_face_rules(stylesheet: &Stylesheet, if opts::get().load_webfonts_synchronously { let (sender, receiver) = ipc::channel().unwrap(); for font_face in stylesheet.effective_rules(&device).font_face() { - for source in &font_face.sources { + for source in font_face.effective_sources() { font_cache_thread.add_web_font(font_face.family.clone(), (*source).clone(), sender.clone()); @@ -369,7 +369,7 @@ fn add_font_face_rules(stylesheet: &Stylesheet, } } else { for font_face in stylesheet.effective_rules(&device).font_face() { - for source in &font_face.sources { + for source in font_face.effective_sources() { outstanding_web_fonts_counter.fetch_add(1, Ordering::SeqCst); font_cache_thread.add_web_font(font_face.family.clone(), (*source).clone(), diff --git a/components/style/font_face.rs b/components/style/font_face.rs index d41daea2f50..6db70a86e25 100644 --- a/components/style/font_face.rs +++ b/components/style/font_face.rs @@ -6,6 +6,8 @@ use computed_values::font_family::FontFamily; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; use parser::{ParserContext, log_css_error}; use properties::longhands::font_family::parse_one_family; +use std::iter; +use std::slice; use url::Url; #[derive(Clone, Debug, HeapSizeOf, PartialEq, Eq, Deserialize, Serialize)] @@ -58,6 +60,36 @@ pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser) } } +pub struct EffectiveSourcesIter<'a>(slice::Iter<'a, Source>); + +impl FontFaceRule { + /// 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 + /// least "truetype" or "opentype". + pub fn effective_sources(&self) -> EffectiveSourcesIter { + EffectiveSourcesIter(self.sources.iter()) + } +} + +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 { + let hints = &url_source.format_hints; + // We support only opentype fonts and truetype is an alias for + // that format. Sources without format hints need to be + // downloaded in case we support them. + hints.is_empty() || hints.iter().any(|hint| { + hint == "truetype" || hint == "opentype" || hint == "woff" + }) + } else { + true + } + }) + } +} + enum FontFaceDescriptorDeclaration { Family(FontFamily), Src(Vec),