From ee7c17eaa4784e18d42b5dad573cdd3755c626c2 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Tue, 14 Oct 2014 11:33:34 -0600 Subject: [PATCH] servo: Merge #3675 - Add support for local font faces. Improves fonts on rust lang and guide (from glennw:local-fonts); r=pcwalton Source-Repo: https://github.com/servo/servo Source-Revision: 48ce107d7275c08273cea6dca3523d0eee23eea7 --- servo/components/gfx/font_cache_task.rs | 42 ++++++++++++++++--------- servo/components/layout/layout_task.rs | 4 +-- servo/components/style/font_face.rs | 28 +++++------------ servo/components/style/lib.rs | 1 + servo/components/style/stylesheets.rs | 4 +-- 5 files changed, 39 insertions(+), 40 deletions(-) diff --git a/servo/components/gfx/font_cache_task.rs b/servo/components/gfx/font_cache_task.rs index 1f1e6a110cc5..9c3b537e0f38 100644 --- a/servo/components/gfx/font_cache_task.rs +++ b/servo/components/gfx/font_cache_task.rs @@ -13,7 +13,7 @@ use sync::Arc; use font_template::{FontTemplate, FontTemplateDescriptor}; use platform::font_template::FontTemplateData; use servo_net::resource_task::{ResourceTask, load_whole_resource}; -use url::Url; +use style::{Source, LocalSource, UrlSource_}; /// A list of font templates that make up a given font family. struct FontFamily { @@ -72,7 +72,7 @@ impl FontFamily { pub enum Command { GetFontTemplate(String, FontTemplateDescriptor, Sender), GetLastResortFontTemplate(FontTemplateDescriptor, Sender), - AddWebFont(String, Url, Sender<()>), + AddWebFont(String, Source, Sender<()>), Exit(Sender<()>), } @@ -116,19 +116,31 @@ impl FontCache { let font_template = self.get_last_resort_font_template(&descriptor); result.send(GetFontTemplateReply(Some(font_template))); } - AddWebFont(family_name, url, result) => { - let maybe_resource = load_whole_resource(&self.resource_task, url.clone()); - match maybe_resource { - Ok((_, bytes)) => { - if !self.web_families.contains_key(&family_name) { - let family = FontFamily::new(); - self.web_families.insert(family_name.clone(), family); + AddWebFont(family_name, src, result) => { + if !self.web_families.contains_key(&family_name) { + let family = FontFamily::new(); + self.web_families.insert(family_name.clone(), family); + } + + match src { + UrlSource_(ref url_source) => { + let url = &url_source.url; + let maybe_resource = load_whole_resource(&self.resource_task, url.clone()); + match maybe_resource { + Ok((_, bytes)) => { + let family = self.web_families.get_mut(&family_name); + family.add_template(url.to_string().as_slice(), Some(bytes)); + }, + Err(_) => { + debug!("Failed to load web font: family={} url={}", family_name, url); + } } + } + LocalSource(ref local_family_name) => { let family = self.web_families.get_mut(&family_name); - family.add_template(format!("{}", url).as_slice(), Some(bytes)); - }, - Err(_) => { - debug!("Failed to load web font: family={} url={}", family_name, url); + get_variations_for_family(local_family_name.as_slice(), |path| { + family.add_template(path.as_slice(), None); + }); } } result.send(()); @@ -290,9 +302,9 @@ impl FontCacheTask { } } - pub fn add_web_font(&self, family: String, url: Url) { + pub fn add_web_font(&self, family: String, src: Source) { let (response_chan, response_port) = channel(); - self.chan.send(AddWebFont(family, url, response_chan)); + self.chan.send(AddWebFont(family, src, response_chan)); response_port.recv(); } diff --git a/servo/components/layout/layout_task.rs b/servo/components/layout/layout_task.rs index 03ea97d8583e..0eb0f739c698 100644 --- a/servo/components/layout/layout_task.rs +++ b/servo/components/layout/layout_task.rs @@ -469,8 +469,8 @@ impl LayoutTask { fn handle_add_stylesheet<'a>(&'a self, sheet: Stylesheet, possibly_locked_rw_data: &mut Option>) { // Find all font-face rules and notify the font cache of them. // GWTODO: Need to handle unloading web fonts (when we handle unloading stylesheets!) - iter_font_face_rules(&sheet, |family, url| { - self.font_cache_task.add_web_font(family.to_string(), url.clone()); + iter_font_face_rules(&sheet, |family, src| { + self.font_cache_task.add_web_font(family.to_string(), (*src).clone()); }); let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); rw_data.stylist.add_stylesheet(sheet, AuthorOrigin); diff --git a/servo/components/style/font_face.rs b/servo/components/style/font_face.rs index 12cbcd41a1da..62a65db96a53 100644 --- a/servo/components/style/font_face.rs +++ b/servo/components/style/font_face.rs @@ -14,10 +14,7 @@ use media_queries::{Device, Screen}; use url::{Url, UrlParser}; -static SUPPORTED_FORMATS: &'static [&'static str] = &["truetype", "opentype"]; - - -pub fn iter_font_face_rules_inner(rules: &[CSSRule], callback: |family: &str, source: &Url|) { +pub fn iter_font_face_rules_inner(rules: &[CSSRule], callback: |family: &str, source: &Source|) { let device = &Device { media_type: Screen }; // TODO, use Print when printing for rule in rules.iter() { match *rule { @@ -27,22 +24,20 @@ pub fn iter_font_face_rules_inner(rules: &[CSSRule], callback: |family: &str, so }, CSSFontFaceRule(ref rule) => { for source in rule.sources.iter() { - if source.format_hints.is_empty() || source.format_hints.iter().any( - |f| SUPPORTED_FORMATS.iter().any( - |s| f.as_slice().eq_ignore_ascii_case(*s))) { - callback(rule.family.as_slice(), &source.url) - } + callback(rule.family.as_slice(), source) } }, } } } -enum Source { +#[deriving(Clone)] +pub enum Source { UrlSource_(UrlSource), LocalSource(String), } +#[deriving(Clone)] pub struct UrlSource { pub url: Url, pub format_hints: Vec, @@ -50,7 +45,7 @@ pub struct UrlSource { pub struct FontFaceRule { pub family: String, - pub sources: Vec, // local() is not supported yet + pub sources: Vec, } pub fn parse_font_face_rule(rule: AtRule, parent_rules: &mut Vec, base_url: &Url) { @@ -93,7 +88,7 @@ pub fn parse_font_face_rule(rule: AtRule, parent_rules: &mut Vec, base_ }, "src" => { match parse_slice_comma_separated( - value.as_slice(), |iter| parse_one_url_src(iter, base_url)) { + value.as_slice(), |iter| parse_one_src(iter, base_url)) { Ok(sources) => maybe_sources = Some(sources), Err(()) => log_css_error(location, "Invalid src in @font-face"), }; @@ -117,15 +112,6 @@ pub fn parse_font_face_rule(rule: AtRule, parent_rules: &mut Vec, base_ } -/// local() is not supported yet -fn parse_one_url_src(iter: ParserIter, base_url: &Url) -> Result { - match parse_one_src(iter, base_url) { - Ok(UrlSource_(source)) => Ok(source), - _ => Err(()) - } -} - - fn parse_one_src(iter: ParserIter, base_url: &Url) -> Result { let url = match iter.next() { // Parsing url() diff --git a/servo/components/style/lib.rs b/servo/components/style/lib.rs index 997794596e04..e9e3ed27cee4 100644 --- a/servo/components/style/lib.rs +++ b/servo/components/style/lib.rs @@ -48,6 +48,7 @@ pub use selectors::{PseudoElement, Before, After, SelectorList, parse_selector_l pub use selectors::{AttrSelector, NamespaceConstraint, SpecificNamespace, AnyNamespace}; pub use selectors::{SimpleSelector,LocalNameSelector}; pub use cssparser::{Color, RGBA}; +pub use font_face::{Source, LocalSource, UrlSource_}; mod stylesheets; mod errors; diff --git a/servo/components/style/stylesheets.rs b/servo/components/style/stylesheets.rs index 657fc5fe83e8..cad9ea3b88d1 100644 --- a/servo/components/style/stylesheets.rs +++ b/servo/components/style/stylesheets.rs @@ -16,7 +16,7 @@ use errors::{ErrorLoggerIterator, log_css_error}; use namespaces::{NamespaceMap, parse_namespace_rule}; use media_queries::{MediaRule, parse_media_rule}; use media_queries; -use font_face::{FontFaceRule, parse_font_face_rule, iter_font_face_rules_inner}; +use font_face::{FontFaceRule, Source, parse_font_face_rule, iter_font_face_rules_inner}; pub struct Stylesheet { @@ -173,6 +173,6 @@ pub fn iter_stylesheet_style_rules(stylesheet: &Stylesheet, device: &media_queri #[inline] -pub fn iter_font_face_rules(stylesheet: &Stylesheet, callback: |family: &str, sources: &Url|) { +pub fn iter_font_face_rules(stylesheet: &Stylesheet, callback: |family: &str, source: &Source|) { iter_font_face_rules_inner(stylesheet.rules.as_slice(), callback) }