servo: Merge #11565 - Introduce FontFaceRules::effective_sources() (from nox:fonts); r=metajack
authorAnthony Ramine <n.oxyde@gmail.com>
Tue, 07 Jun 2016 03:50:18 -0500
changeset 339032 bdc56e5660c3e58e4d22a5a44a412b0376419e38
parent 339031 b266d21164c0b2541216f526b81dd6ebc87b2805
child 339033 4438903005b47beae9280d2f5db896487f6a1627
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmetajack
servo: Merge #11565 - Introduce FontFaceRules::effective_sources() (from nox:fonts); r=metajack Source-Repo: https://github.com/servo/servo Source-Revision: b64b21ace0e9b3639906c9dc988c66ea596f3d88
servo/components/layout/layout_thread.rs
servo/components/style/font_face.rs
--- a/servo/components/layout/layout_thread.rs
+++ b/servo/components/layout/layout_thread.rs
@@ -350,29 +350,33 @@ impl<'a, 'b: 'a> RwData<'a, 'b> {
     }
 }
 
 fn add_font_face_rules(stylesheet: &Stylesheet,
                        device: &Device,
                        font_cache_thread: &FontCacheThread,
                        font_cache_sender: &IpcSender<()>,
                        outstanding_web_fonts_counter: &Arc<AtomicUsize>) {
-    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.effective_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.effective_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());
             }
         }
     }
 }
 
 impl LayoutThread {
     /// Creates a new `LayoutThread` structure.
     fn new(id: PipelineId,
--- a/servo/components/style/font_face.rs
+++ b/servo/components/style/font_face.rs
@@ -1,16 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 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)]
 pub enum Source {
     Url(UrlSource),
     Local(FontFamily),
 }
 
@@ -53,16 +55,46 @@ pub fn parse_font_face_block(context: &P
                 family: family,
                 sources: src,
             })
         }
         _ => Err(())
     }
 }
 
+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<Source>),
 }
 
 
 struct FontFaceRuleParser<'a, 'b: 'a> {
     context: &'a ParserContext<'b>,