зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
747e39cf7d
Коммит
ee7c17eaa4
|
@ -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)
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче