aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <metajack+bors@gmail.com>2014-11-03 18:30:35 -0700
committerbors-servo <metajack+bors@gmail.com>2014-11-03 18:30:35 -0700
commit2a88a3242cf85c807875883aeb14d113a1a27212 (patch)
treed0cd310691f734e81ab282fc6491882b01b11a3c
parent39960f32e49c69977b185f91e587c9947b0b9a25 (diff)
parentd22a64884da5f83c9a34fb8841757053c2c1b36a (diff)
downloadservo-2a88a3242cf85c807875883aeb14d113a1a27212.tar.gz
servo-2a88a3242cf85c807875883aeb14d113a1a27212.zip
auto merge of #3880 : cgaebel/servo/case-insensitive-font-family-matching, r=glennw,glennw
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? @glennw
-rw-r--r--components/gfx/font_cache_task.rs32
-rw-r--r--components/gfx/lib.rs2
-rw-r--r--components/util/lib.rs1
-rw-r--r--components/util/str.rs20
-rw-r--r--tests/ref/basic.list1
-rw-r--r--tests/ref/case-insensitive-font-family-ref.html1
-rw-r--r--tests/ref/case-insensitive-font-family.html1
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>