aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/gfx/font_cache_task.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/gfx/font_cache_task.rs')
-rw-r--r--src/components/gfx/font_cache_task.rs70
1 files changed, 62 insertions, 8 deletions
diff --git a/src/components/gfx/font_cache_task.rs b/src/components/gfx/font_cache_task.rs
index 55e2dad003e..1dd71f9f1f8 100644
--- a/src/components/gfx/font_cache_task.rs
+++ b/src/components/gfx/font_cache_task.rs
@@ -11,6 +11,8 @@ 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 url::Url;
/// A list of font templates that make up a given font family.
struct FontFamily {
@@ -42,11 +44,23 @@ impl FontFamily {
None
}
+
+ fn add_template(&mut self, identifier: &str, maybe_data: Option<Vec<u8>>) {
+ for template in self.templates.iter() {
+ if template.identifier() == identifier {
+ return;
+ }
+ }
+
+ let template = FontTemplate::new(identifier, maybe_data);
+ self.templates.push(template);
+ }
}
/// Commands that the FontContext sends to the font cache task.
pub enum Command {
GetFontTemplate(String, FontTemplateDescriptor, Sender<Reply>),
+ AddWebFont(Url, String, Sender<()>),
Exit(Sender<()>),
}
@@ -61,7 +75,9 @@ struct FontCache {
port: Receiver<Command>,
generic_fonts: HashMap<String, String>,
local_families: HashMap<String, FontFamily>,
+ web_families: HashMap<String, FontFamily>,
font_context: FontContextHandle,
+ resource_task: ResourceTask,
}
impl FontCache {
@@ -80,6 +96,23 @@ impl FontCache {
result.send(GetFontTemplateReply(font_template));
}
+ AddWebFont(url, family_name, 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);
+ }
+ let family = self.web_families.get_mut(&family_name);
+ family.add_template(format!("{}", url).as_slice(), Some(bytes));
+ },
+ Err(msg) => {
+ fail!(msg);
+ }
+ }
+ result.send(());
+ }
Exit(result) => {
result.send(());
break;
@@ -105,9 +138,8 @@ impl FontCache {
}
}
- fn find_font_in_family<'a>(&'a mut self,
- family_name: &String,
- desc: &FontTemplateDescriptor) -> Option<Arc<FontTemplateData>> {
+ fn find_font_in_local_family<'a>(&'a mut self, family_name: &String, desc: &FontTemplateDescriptor)
+ -> Option<Arc<FontTemplateData>> {
// TODO(Issue #188): look up localized font family names if canonical name not found
// look up canonical name
if self.local_families.contains_key(family_name) {
@@ -116,8 +148,7 @@ impl FontCache {
if s.templates.len() == 0 {
get_variations_for_family(family_name.as_slice(), |path| {
- let template = FontTemplate::new(path.as_slice());
- s.templates.push(template);
+ s.add_template(path.as_slice(), None);
});
}
@@ -135,16 +166,31 @@ impl FontCache {
}
}
+ fn find_font_in_web_family<'a>(&'a mut self, family_name: &String, desc: &FontTemplateDescriptor)
+ -> Option<Arc<FontTemplateData>> {
+ if self.web_families.contains_key(family_name) {
+ let family = self.web_families.get_mut(family_name);
+ let maybe_font = family.find_font_for_style(desc, &self.font_context);
+ maybe_font
+ } else {
+ None
+ }
+ }
+
fn get_font_template(&mut self, family: &String, desc: &FontTemplateDescriptor) -> Option<Arc<FontTemplateData>> {
let transformed_family_name = self.transform_family(family);
- self.find_font_in_family(&transformed_family_name, desc)
+ let mut maybe_template = self.find_font_in_web_family(&transformed_family_name, desc);
+ if maybe_template.is_none() {
+ maybe_template = self.find_font_in_local_family(&transformed_family_name, desc);
+ }
+ maybe_template
}
fn get_last_resort_template(&mut self, desc: &FontTemplateDescriptor) -> Arc<FontTemplateData> {
let last_resort = get_last_resort_font_families();
for family in last_resort.iter() {
- let maybe_font_in_family = self.find_font_in_family(family, desc);
+ 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();
}
@@ -162,7 +208,7 @@ pub struct FontCacheTask {
}
impl FontCacheTask {
- pub fn new() -> FontCacheTask {
+ pub fn new(resource_task: ResourceTask) -> FontCacheTask {
let (chan, port) = channel();
spawn(proc() {
@@ -178,7 +224,9 @@ impl FontCacheTask {
port: port,
generic_fonts: generic_fonts,
local_families: HashMap::new(),
+ web_families: HashMap::new(),
font_context: FontContextHandle::new(),
+ resource_task: resource_task,
};
cache.refresh_local_families();
@@ -205,6 +253,12 @@ impl FontCacheTask {
}
}
+ pub fn add_web_font(&mut self, url: Url, family: &str) {
+ let (response_chan, response_port) = channel();
+ self.chan.send(AddWebFont(url, family.to_string(), response_chan));
+ response_port.recv();
+ }
+
pub fn exit(&self) {
let (response_chan, response_port) = channel();
self.chan.send(Exit(response_chan));