diff options
author | Clark Gaebel <cgaebel@mozilla.com> | 2014-11-03 16:46:21 -0800 |
---|---|---|
committer | Clark Gaebel <cgaebel@mozilla.com> | 2014-11-03 17:15:51 -0800 |
commit | d22a64884da5f83c9a34fb8841757053c2c1b36a (patch) | |
tree | d0cd310691f734e81ab282fc6491882b01b11a3c | |
parent | 39960f32e49c69977b185f91e587c9947b0b9a25 (diff) | |
download | servo-d22a64884da5f83c9a34fb8841757053c2c1b36a.tar.gz servo-d22a64884da5f83c9a34fb8841757053c2c1b36a.zip |
Implements case insensitive font family names.
One part (of 8!) of css font family disambiguation is that font families should
be matched case-insensitively.
This patch implements that. Once it lands, a bug needs to be filed to do lowercasing
properly (as a string, instead of char-by-char -- it's a unicode thing).
r? @gw
-rw-r--r-- | components/gfx/font_cache_task.rs | 32 | ||||
-rw-r--r-- | components/gfx/lib.rs | 2 | ||||
-rw-r--r-- | components/util/lib.rs | 1 | ||||
-rw-r--r-- | components/util/str.rs | 20 | ||||
-rw-r--r-- | tests/ref/basic.list | 1 | ||||
-rw-r--r-- | tests/ref/case-insensitive-font-family-ref.html | 1 | ||||
-rw-r--r-- | tests/ref/case-insensitive-font-family.html | 1 |
7 files changed, 44 insertions, 14 deletions
diff --git a/components/gfx/font_cache_task.rs b/components/gfx/font_cache_task.rs index 6c524289d65..3941f870f99 100644 --- a/components/gfx/font_cache_task.rs +++ b/components/gfx/font_cache_task.rs @@ -8,12 +8,14 @@ use platform::font_list::get_variations_for_family; use platform::font_list::get_last_resort_font_families; use platform::font_context::FontContextHandle; +use collections::str::Str; use std::collections::HashMap; use sync::Arc; use font_template::{FontTemplate, FontTemplateDescriptor}; use platform::font_template::FontTemplateData; use servo_net::resource_task::{ResourceTask, load_whole_resource}; use servo_util::task::spawn_named; +use servo_util::str::LowercaseString; use style::{Source, LocalSource, UrlSource_}; /// A list of font templates that make up a given font family. @@ -86,21 +88,21 @@ pub enum Reply { /// font templates that are currently in use. struct FontCache { port: Receiver<Command>, - generic_fonts: HashMap<String, String>, - local_families: HashMap<String, FontFamily>, - web_families: HashMap<String, FontFamily>, + generic_fonts: HashMap<LowercaseString, LowercaseString>, + local_families: HashMap<LowercaseString, FontFamily>, + web_families: HashMap<LowercaseString, FontFamily>, font_context: FontContextHandle, resource_task: ResourceTask, } -fn add_generic_font(generic_fonts: &mut HashMap<String, String>, +fn add_generic_font(generic_fonts: &mut HashMap<LowercaseString, LowercaseString>, generic_name: &str, mapped_name: &str) { let opt_system_default = get_system_default_family(generic_name); let family_name = match opt_system_default { - Some(system_default) => system_default, - None => mapped_name.to_string(), + Some(system_default) => LowercaseString::new(system_default.as_slice()), + None => LowercaseString::new(mapped_name), }; - generic_fonts.insert(generic_name.to_string(), family_name); + generic_fonts.insert(LowercaseString::new(generic_name), family_name); } impl FontCache { @@ -110,6 +112,7 @@ impl FontCache { match msg { GetFontTemplate(family, descriptor, result) => { + let family = LowercaseString::new(family.as_slice()); let maybe_font_template = self.get_font_template(&family, &descriptor); result.send(GetFontTemplateReply(maybe_font_template)); } @@ -118,6 +121,7 @@ impl FontCache { result.send(GetFontTemplateReply(Some(font_template))); } AddWebFont(family_name, src, result) => { + let family_name = LowercaseString::new(family_name.as_slice()); if !self.web_families.contains_key(&family_name) { let family = FontFamily::new(); self.web_families.insert(family_name.clone(), family); @@ -157,6 +161,7 @@ impl FontCache { fn refresh_local_families(&mut self) { self.local_families.clear(); get_available_families(|family_name| { + let family_name = LowercaseString::new(family_name.as_slice()); if !self.local_families.contains_key(&family_name) { let family = FontFamily::new(); self.local_families.insert(family_name, family); @@ -164,14 +169,14 @@ impl FontCache { }); } - fn transform_family(&self, family: &String) -> String { + fn transform_family(&self, family: &LowercaseString) -> LowercaseString { match self.generic_fonts.find(family) { - None => family.to_string(), + None => family.clone(), Some(mapped_family) => (*mapped_family).clone() } } - fn find_font_in_local_family<'a>(&'a mut self, family_name: &String, desc: &FontTemplateDescriptor) + fn find_font_in_local_family<'a>(&'a mut self, family_name: &LowercaseString, desc: &FontTemplateDescriptor) -> Option<Arc<FontTemplateData>> { // TODO(Issue #188): look up localized font family names if canonical name not found // look up canonical name @@ -199,7 +204,7 @@ impl FontCache { } } - fn find_font_in_web_family<'a>(&'a mut self, family_name: &String, desc: &FontTemplateDescriptor) + fn find_font_in_web_family<'a>(&'a mut self, family_name: &LowercaseString, desc: &FontTemplateDescriptor) -> Option<Arc<FontTemplateData>> { if self.web_families.contains_key(family_name) { let family = self.web_families.get_mut(family_name); @@ -210,7 +215,7 @@ impl FontCache { } } - fn get_font_template(&mut self, family: &String, desc: &FontTemplateDescriptor) + fn get_font_template(&mut self, family: &LowercaseString, desc: &FontTemplateDescriptor) -> Option<Arc<FontTemplateData>> { let transformed_family_name = self.transform_family(family); let mut maybe_template = self.find_font_in_web_family(&transformed_family_name, desc); @@ -225,7 +230,8 @@ impl FontCache { let last_resort = get_last_resort_font_families(); for family in last_resort.iter() { - let maybe_font_in_family = self.find_font_in_local_family(family, desc); + let family = LowercaseString::new(family.as_slice()); + let maybe_font_in_family = self.find_font_in_local_family(&family, desc); if maybe_font_in_family.is_some() { return maybe_font_in_family.unwrap(); } diff --git a/components/gfx/lib.rs b/components/gfx/lib.rs index 975ad1bd3a5..28312a09440 100644 --- a/components/gfx/lib.rs +++ b/components/gfx/lib.rs @@ -21,6 +21,7 @@ extern crate rustrt; extern crate stb_image; extern crate png; extern crate serialize; +extern crate unicode; #[phase(plugin)] extern crate "plugins" as servo_plugins; extern crate "net" as servo_net; @@ -71,4 +72,3 @@ pub mod platform; // Text #[path = "text/mod.rs"] pub mod text; - diff --git a/components/util/lib.rs b/components/util/lib.rs index 46e8b0b60df..3f4146eedfe 100644 --- a/components/util/lib.rs +++ b/components/util/lib.rs @@ -26,6 +26,7 @@ extern crate sync; extern crate task_info; extern crate "time" as std_time; extern crate string_cache; +extern crate unicode; extern crate url; #[phase(plugin)] diff --git a/components/util/str.rs b/components/util/str.rs index 6e88f0ba4f8..f08ae1178d9 100644 --- a/components/util/str.rs +++ b/components/util/str.rs @@ -7,6 +7,7 @@ use geometry::Au; use std::from_str::FromStr; use std::iter::Filter; use std::str::{CharEq, CharSplits}; +use unicode::char::to_lowercase; pub type DOMString = String; pub type StaticCharVec = &'static [char]; @@ -184,3 +185,22 @@ pub fn parse_length(mut value: &str) -> LengthOrPercentageOrAuto { } +#[deriving(Clone, Eq, PartialEq, Hash, Show)] +pub struct LowercaseString { + inner: String, +} + +impl LowercaseString { + pub fn new(s: &str) -> LowercaseString { + LowercaseString { + inner: s.chars().map(to_lowercase).collect(), + } + } +} + +impl Str for LowercaseString { + #[inline] + fn as_slice(&self) -> &str { + self.inner.as_slice() + } +} diff --git a/tests/ref/basic.list b/tests/ref/basic.list index befcd06d5ab..1147e58b203 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -1,3 +1,4 @@ +== case-insensitive-font-family.html case-insensitive-font-family-ref.html != img_simple.html img_simple_ref.html == basic_width_px.html basic_width_em.html == br.html br-ref.html diff --git a/tests/ref/case-insensitive-font-family-ref.html b/tests/ref/case-insensitive-font-family-ref.html new file mode 100644 index 00000000000..8d0e1adeba3 --- /dev/null +++ b/tests/ref/case-insensitive-font-family-ref.html @@ -0,0 +1 @@ +<div style="font-family: Arial">Hello, world!</div> diff --git a/tests/ref/case-insensitive-font-family.html b/tests/ref/case-insensitive-font-family.html new file mode 100644 index 00000000000..7cdec887b52 --- /dev/null +++ b/tests/ref/case-insensitive-font-family.html @@ -0,0 +1 @@ +<div style="font-family: arial">Hello, world!</div> |