mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Add support for local font faces. Improves fonts on rust lang and guide.
This commit is contained in:
parent
d04733cf59
commit
1827852810
5 changed files with 39 additions and 40 deletions
|
@ -13,7 +13,7 @@ use sync::Arc;
|
||||||
use font_template::{FontTemplate, FontTemplateDescriptor};
|
use font_template::{FontTemplate, FontTemplateDescriptor};
|
||||||
use platform::font_template::FontTemplateData;
|
use platform::font_template::FontTemplateData;
|
||||||
use servo_net::resource_task::{ResourceTask, load_whole_resource};
|
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.
|
/// A list of font templates that make up a given font family.
|
||||||
struct FontFamily {
|
struct FontFamily {
|
||||||
|
@ -72,7 +72,7 @@ impl FontFamily {
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
GetFontTemplate(String, FontTemplateDescriptor, Sender<Reply>),
|
GetFontTemplate(String, FontTemplateDescriptor, Sender<Reply>),
|
||||||
GetLastResortFontTemplate(FontTemplateDescriptor, Sender<Reply>),
|
GetLastResortFontTemplate(FontTemplateDescriptor, Sender<Reply>),
|
||||||
AddWebFont(String, Url, Sender<()>),
|
AddWebFont(String, Source, Sender<()>),
|
||||||
Exit(Sender<()>),
|
Exit(Sender<()>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,19 +116,31 @@ impl FontCache {
|
||||||
let font_template = self.get_last_resort_font_template(&descriptor);
|
let font_template = self.get_last_resort_font_template(&descriptor);
|
||||||
result.send(GetFontTemplateReply(Some(font_template)));
|
result.send(GetFontTemplateReply(Some(font_template)));
|
||||||
}
|
}
|
||||||
AddWebFont(family_name, url, result) => {
|
AddWebFont(family_name, src, result) => {
|
||||||
let maybe_resource = load_whole_resource(&self.resource_task, url.clone());
|
if !self.web_families.contains_key(&family_name) {
|
||||||
match maybe_resource {
|
let family = FontFamily::new();
|
||||||
Ok((_, bytes)) => {
|
self.web_families.insert(family_name.clone(), family);
|
||||||
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);
|
let family = self.web_families.get_mut(&family_name);
|
||||||
family.add_template(format!("{}", url).as_slice(), Some(bytes));
|
get_variations_for_family(local_family_name.as_slice(), |path| {
|
||||||
},
|
family.add_template(path.as_slice(), None);
|
||||||
Err(_) => {
|
});
|
||||||
debug!("Failed to load web font: family={} url={}", family_name, url);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.send(());
|
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();
|
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();
|
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>>) {
|
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.
|
// 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!)
|
||||||
iter_font_face_rules(&sheet, |family, url| {
|
iter_font_face_rules(&sheet, |family, src| {
|
||||||
self.font_cache_task.add_web_font(family.to_string(), url.clone());
|
self.font_cache_task.add_web_font(family.to_string(), (*src).clone());
|
||||||
});
|
});
|
||||||
let mut rw_data = self.lock_rw_data(possibly_locked_rw_data);
|
let mut rw_data = self.lock_rw_data(possibly_locked_rw_data);
|
||||||
rw_data.stylist.add_stylesheet(sheet, AuthorOrigin);
|
rw_data.stylist.add_stylesheet(sheet, AuthorOrigin);
|
||||||
|
|
|
@ -14,10 +14,7 @@ use media_queries::{Device, Screen};
|
||||||
use url::{Url, UrlParser};
|
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: &Source|) {
|
||||||
|
|
||||||
|
|
||||||
pub fn iter_font_face_rules_inner(rules: &[CSSRule], callback: |family: &str, source: &Url|) {
|
|
||||||
let device = &Device { media_type: Screen }; // TODO, use Print when printing
|
let device = &Device { media_type: Screen }; // TODO, use Print when printing
|
||||||
for rule in rules.iter() {
|
for rule in rules.iter() {
|
||||||
match *rule {
|
match *rule {
|
||||||
|
@ -27,22 +24,20 @@ pub fn iter_font_face_rules_inner(rules: &[CSSRule], callback: |family: &str, so
|
||||||
},
|
},
|
||||||
CSSFontFaceRule(ref rule) => {
|
CSSFontFaceRule(ref rule) => {
|
||||||
for source in rule.sources.iter() {
|
for source in rule.sources.iter() {
|
||||||
if source.format_hints.is_empty() || source.format_hints.iter().any(
|
callback(rule.family.as_slice(), source)
|
||||||
|f| SUPPORTED_FORMATS.iter().any(
|
|
||||||
|s| f.as_slice().eq_ignore_ascii_case(*s))) {
|
|
||||||
callback(rule.family.as_slice(), &source.url)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Source {
|
#[deriving(Clone)]
|
||||||
|
pub enum Source {
|
||||||
UrlSource_(UrlSource),
|
UrlSource_(UrlSource),
|
||||||
LocalSource(String),
|
LocalSource(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deriving(Clone)]
|
||||||
pub struct UrlSource {
|
pub struct UrlSource {
|
||||||
pub url: Url,
|
pub url: Url,
|
||||||
pub format_hints: Vec<String>,
|
pub format_hints: Vec<String>,
|
||||||
|
@ -50,7 +45,7 @@ pub struct UrlSource {
|
||||||
|
|
||||||
pub struct FontFaceRule {
|
pub struct FontFaceRule {
|
||||||
pub family: String,
|
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) {
|
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" => {
|
"src" => {
|
||||||
match parse_slice_comma_separated(
|
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),
|
Ok(sources) => maybe_sources = Some(sources),
|
||||||
Err(()) => log_css_error(location, "Invalid src in @font-face"),
|
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, ()> {
|
fn parse_one_src(iter: ParserIter, base_url: &Url) -> Result<Source, ()> {
|
||||||
let url = match iter.next() {
|
let url = match iter.next() {
|
||||||
// Parsing url()
|
// 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::{AttrSelector, NamespaceConstraint, SpecificNamespace, AnyNamespace};
|
||||||
pub use selectors::{SimpleSelector,LocalNameSelector};
|
pub use selectors::{SimpleSelector,LocalNameSelector};
|
||||||
pub use cssparser::{Color, RGBA};
|
pub use cssparser::{Color, RGBA};
|
||||||
|
pub use font_face::{Source, LocalSource, UrlSource_};
|
||||||
|
|
||||||
mod stylesheets;
|
mod stylesheets;
|
||||||
mod errors;
|
mod errors;
|
||||||
|
|
|
@ -16,7 +16,7 @@ use errors::{ErrorLoggerIterator, log_css_error};
|
||||||
use namespaces::{NamespaceMap, parse_namespace_rule};
|
use namespaces::{NamespaceMap, parse_namespace_rule};
|
||||||
use media_queries::{MediaRule, parse_media_rule};
|
use media_queries::{MediaRule, parse_media_rule};
|
||||||
use media_queries;
|
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 {
|
pub struct Stylesheet {
|
||||||
|
@ -173,6 +173,6 @@ pub fn iter_stylesheet_style_rules(stylesheet: &Stylesheet, device: &media_queri
|
||||||
|
|
||||||
|
|
||||||
#[inline]
|
#[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)
|
iter_font_face_rules_inner(stylesheet.rules.as_slice(), callback)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue