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
This commit is contained in:
Glenn Watson 2014-10-14 11:33:34 -06:00
Родитель 747e39cf7d
Коммит ee7c17eaa4
5 изменённых файлов: 39 добавлений и 40 удалений

Просмотреть файл

@ -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<Reply>),
GetLastResortFontTemplate(FontTemplateDescriptor, Sender<Reply>),
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();
}

Просмотреть файл

@ -469,8 +469,8 @@ impl LayoutTask {
fn handle_add_stylesheet<'a>(&'a self, sheet: Stylesheet, possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) {
// 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);

Просмотреть файл

@ -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<String>,
@ -50,7 +45,7 @@ pub struct UrlSource {
pub struct FontFaceRule {
pub family: String,
pub sources: Vec<UrlSource>, // local() is not supported yet
pub sources: Vec<Source>,
}
pub fn parse_font_face_rule(rule: AtRule, parent_rules: &mut Vec<CSSRule>, base_url: &Url) {
@ -93,7 +88,7 @@ pub fn parse_font_face_rule(rule: AtRule, parent_rules: &mut Vec<CSSRule>, 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<CSSRule>, base_
}
/// local() is not supported yet
fn parse_one_url_src(iter: ParserIter, base_url: &Url) -> Result<UrlSource, ()> {
match parse_one_src(iter, base_url) {
Ok(UrlSource_(source)) => Ok(source),
_ => Err(())
}
}
fn parse_one_src(iter: ParserIter, base_url: &Url) -> Result<Source, ()> {
let url = match iter.next() {
// Parsing url()

Просмотреть файл

@ -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;

Просмотреть файл

@ -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)
}