mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
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
This commit is contained in:
parent
39960f32e4
commit
d22a64884d
7 changed files with 44 additions and 14 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
1
tests/ref/case-insensitive-font-family-ref.html
Normal file
1
tests/ref/case-insensitive-font-family-ref.html
Normal file
|
@ -0,0 +1 @@
|
|||
<div style="font-family: Arial">Hello, world!</div>
|
1
tests/ref/case-insensitive-font-family.html
Normal file
1
tests/ref/case-insensitive-font-family.html
Normal file
|
@ -0,0 +1 @@
|
|||
<div style="font-family: arial">Hello, world!</div>
|
Loading…
Add table
Add a link
Reference in a new issue