mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Address review comments.
This commit is contained in:
parent
6465bf6a85
commit
40559d148a
4 changed files with 126 additions and 41 deletions
|
@ -105,7 +105,7 @@ impl FontCache {
|
||||||
self.web_families.insert(family_name.clone(), family);
|
self.web_families.insert(family_name.clone(), family);
|
||||||
}
|
}
|
||||||
let family = self.web_families.get_mut(&family_name);
|
let family = self.web_families.get_mut(&family_name);
|
||||||
family.add_template(format!("{}", url).as_slice(), Some(bytes));
|
family.add_template(format!("{}", url).as_slice(), Some(bytes));
|
||||||
},
|
},
|
||||||
Err(msg) => {
|
Err(msg) => {
|
||||||
fail!(msg);
|
fail!(msg);
|
||||||
|
|
|
@ -455,20 +455,23 @@ impl LayoutTask {
|
||||||
// Find all font-face rules and notify the font cache of them.
|
// Find all font-face rules and notify the font cache of them.
|
||||||
// GWTODO: Need to handle unloading web fonts (when we handle unloading stylesheets!)
|
// GWTODO: Need to handle unloading web fonts (when we handle unloading stylesheets!)
|
||||||
// GWTODO: Need to handle font-face nested within media rules.
|
// GWTODO: Need to handle font-face nested within media rules.
|
||||||
|
// GWTODO: Don't rely on format hint here. Should determine file format from data.
|
||||||
for rule in sheet.rules.iter() {
|
for rule in sheet.rules.iter() {
|
||||||
match rule {
|
match rule {
|
||||||
&CSSFontFaceRule(ref font_face_rule) => {
|
&CSSFontFaceRule(ref font_face_rule) => {
|
||||||
for source in font_face_rule.sources.iter() {
|
for source_line in font_face_rule.source_lines.iter() {
|
||||||
match source.format {
|
for source in source_line.sources.iter() {
|
||||||
TtfFormat => {
|
match source.format_hint {
|
||||||
self.font_cache_task.add_web_font(source.url.clone(), font_face_rule.family.as_slice());
|
TtfFormat => {
|
||||||
},
|
self.font_cache_task.add_web_font(source.url.clone(), font_face_rule.family.as_slice());
|
||||||
_ => {}
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.stylist.add_stylesheet(sheet, AuthorOrigin);
|
self.stylist.add_stylesheet(sheet, AuthorOrigin);
|
||||||
|
|
|
@ -22,19 +22,27 @@ pub enum FontFaceFormat {
|
||||||
|
|
||||||
pub struct FontFaceSource {
|
pub struct FontFaceSource {
|
||||||
pub url: Url,
|
pub url: Url,
|
||||||
pub format: FontFaceFormat,
|
pub format_hint: FontFaceFormat,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FontFaceSourceLine {
|
||||||
|
pub sources: Vec<FontFaceSource>
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FontFaceRule {
|
pub struct FontFaceRule {
|
||||||
pub family: String,
|
pub family: String,
|
||||||
pub sources: Vec<FontFaceSource>,
|
pub source_lines: Vec<FontFaceSourceLine>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_font_face_rule(rule: AtRule, parent_rules: &mut Vec<CSSRule>, base_url: &Url) {
|
pub fn parse_font_face_rule(rule: AtRule, parent_rules: &mut Vec<CSSRule>, base_url: &Url) {
|
||||||
let mut font_face_rule = FontFaceRule {
|
|
||||||
family: "".to_string(),
|
let mut maybe_family = None;
|
||||||
sources: vec!()
|
let mut source_lines = vec!();
|
||||||
};
|
|
||||||
|
if rule.prelude.as_slice().skip_whitespace().next().is_some() {
|
||||||
|
log_css_error(rule.location, "@font-face prelude contains unexpected characters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let block = match rule.block {
|
let block = match rule.block {
|
||||||
Some(block) => block,
|
Some(block) => block,
|
||||||
|
@ -53,9 +61,10 @@ pub fn parse_font_face_rule(rule: AtRule, parent_rules: &mut Vec<CSSRule>, base_
|
||||||
let name_lower = name.as_slice().to_ascii_lower();
|
let name_lower = name.as_slice().to_ascii_lower();
|
||||||
match name_lower.as_slice() {
|
match name_lower.as_slice() {
|
||||||
"font-family" => {
|
"font-family" => {
|
||||||
|
// FIXME(#2802): Share code with the font-family parser.
|
||||||
match one_component_value(value.as_slice()) {
|
match one_component_value(value.as_slice()) {
|
||||||
Some(&String(ref string_value)) => {
|
Some(&String(ref string_value)) => {
|
||||||
font_face_rule.family = string_value.clone();
|
maybe_family = Some(string_value.clone());
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
log_css_error(location, format!("Unsupported font-family string {:s}", name).as_slice());
|
log_css_error(location, format!("Unsupported font-family string {:s}", name).as_slice());
|
||||||
|
@ -63,45 +72,112 @@ pub fn parse_font_face_rule(rule: AtRule, parent_rules: &mut Vec<CSSRule>, base_
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"src" => {
|
"src" => {
|
||||||
for component_value in value.as_slice().skip_whitespace() {
|
let mut iter = value.as_slice().skip_whitespace();
|
||||||
match component_value {
|
let mut sources = vec!();
|
||||||
&URL(ref string_value) => {
|
let mut syntax_error = false;
|
||||||
let font_url = parse_url(string_value.as_slice(), Some(base_url.clone()));
|
|
||||||
let src = FontFaceSource { url: font_url, format: UnknownFormat };
|
'outer: loop {
|
||||||
font_face_rule.sources.push(src);
|
|
||||||
|
// url() or local() should be next
|
||||||
|
let url = match iter.next() {
|
||||||
|
Some(&URL(ref string_value)) => {
|
||||||
|
parse_url(string_value.as_slice(), Some(base_url.clone()))
|
||||||
},
|
},
|
||||||
&Function(ref string_value, ref values) => {
|
_ => {
|
||||||
|
log_css_error(location, "Unsupported declaration (local font face is not supported yet)");
|
||||||
|
syntax_error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// optional format, or comma to start loop again
|
||||||
|
let mut next_token = iter.next();
|
||||||
|
match next_token {
|
||||||
|
Some(&Function(ref string_value, ref values)) => {
|
||||||
match string_value.as_slice() {
|
match string_value.as_slice() {
|
||||||
"format" => {
|
"format" => {
|
||||||
let format = one_component_value(values.as_slice()).and_then(|c| {
|
let maybe_format_hint_string = one_component_value(
|
||||||
|
values.as_slice()).and_then(|c| {
|
||||||
match c {
|
match c {
|
||||||
&String(ref format_string) => Some(format_string.as_slice().to_ascii_lower()),
|
&String(ref s) => Some(s.as_slice().to_ascii_lower()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
match font_face_rule.sources.mut_last() {
|
|
||||||
Some(source) => {
|
match maybe_format_hint_string {
|
||||||
source.format = match format.unwrap_or("".to_string()).as_slice() {
|
Some(ref format_hint_string) => {
|
||||||
"embedded-opentype" => EotFormat,
|
let format_hints: Vec<&str> = format_hint_string.as_slice().split(',').collect();
|
||||||
"woff" => WoffFormat,
|
|
||||||
"truetype" | "opentype" => TtfFormat,
|
for format_hint in format_hints.iter() {
|
||||||
"svg" => SvgFormat,
|
let format_hint = format_hint.trim();
|
||||||
_ => UnknownFormat,
|
|
||||||
|
let hint = match format_hint.as_slice() {
|
||||||
|
"embedded-opentype" => EotFormat,
|
||||||
|
"woff" => WoffFormat,
|
||||||
|
"truetype" | "opentype" => TtfFormat,
|
||||||
|
"svg" => SvgFormat,
|
||||||
|
_ => UnknownFormat,
|
||||||
|
};
|
||||||
|
|
||||||
|
if hint == UnknownFormat {
|
||||||
|
log_css_error(location,
|
||||||
|
format!("Unknown font format {}", format_hint).as_slice());
|
||||||
|
syntax_error = true;
|
||||||
|
break 'outer;
|
||||||
|
}
|
||||||
|
|
||||||
|
let source = FontFaceSource {
|
||||||
|
url: url.clone(),
|
||||||
|
format_hint: hint,
|
||||||
|
};
|
||||||
|
sources.push(source);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
log_css_error(location,
|
||||||
|
format!("Unsupported token {}", string_value).as_slice());
|
||||||
|
syntax_error = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
None => {}
|
}
|
||||||
};
|
|
||||||
},
|
|
||||||
"local" => {
|
|
||||||
log_css_error(location, "local font face not supported yet!");
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
log_css_error(location, format!("Unsupported declaration {}", string_value).as_slice());
|
log_css_error(location,
|
||||||
|
format!("Unsupported token {}", string_value).as_slice());
|
||||||
|
syntax_error = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
next_token = iter.next();
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {
|
||||||
|
let source = FontFaceSource {
|
||||||
|
url: url,
|
||||||
|
format_hint: UnknownFormat,
|
||||||
|
};
|
||||||
|
sources.push(source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// after url or optional format, comes comma or end
|
||||||
|
match next_token {
|
||||||
|
Some(&Comma) => {},
|
||||||
|
None => break,
|
||||||
|
_ => {
|
||||||
|
log_css_error(location, "Unexpected token type");
|
||||||
|
syntax_error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !syntax_error {
|
||||||
|
assert!(sources.len() > 0);
|
||||||
|
|
||||||
|
let source_line = FontFaceSourceLine {
|
||||||
|
sources: sources
|
||||||
|
};
|
||||||
|
source_lines.push(source_line);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -112,5 +188,11 @@ pub fn parse_font_face_rule(rule: AtRule, parent_rules: &mut Vec<CSSRule>, base_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parent_rules.push(CSSFontFaceRule(font_face_rule));
|
if maybe_family.is_some() && source_lines.len() > 0 {
|
||||||
|
let font_face_rule = FontFaceRule {
|
||||||
|
family: maybe_family.unwrap(),
|
||||||
|
source_lines: source_lines,
|
||||||
|
};
|
||||||
|
parent_rules.push(CSSFontFaceRule(font_face_rule));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -47,7 +47,7 @@ pub use selectors::{NamespaceConstraint, Selector, CompoundSelector, SimpleSelec
|
||||||
pub use selectors::{parse_selector_list};
|
pub use selectors::{parse_selector_list};
|
||||||
pub use namespaces::NamespaceMap;
|
pub use namespaces::NamespaceMap;
|
||||||
pub use media_queries::{MediaRule, MediaQueryList, MediaQuery, Device, MediaType, MediaQueryType};
|
pub use media_queries::{MediaRule, MediaQueryList, MediaQuery, Device, MediaType, MediaQueryType};
|
||||||
pub use font_face::{FontFaceFormat, FontFaceRule, FontFaceSource, TtfFormat};
|
pub use font_face::{FontFaceFormat, FontFaceRule, FontFaceSource,FontFaceSourceLine, TtfFormat};
|
||||||
|
|
||||||
mod stylesheets;
|
mod stylesheets;
|
||||||
mod errors;
|
mod errors;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue