Introduce a FamilyName type, like FontFamily but not a generic family.

This commit is contained in:
Simon Sapin 2017-02-02 18:30:36 +01:00
parent 44f6c60d91
commit 52aa2431a9
3 changed files with 35 additions and 15 deletions

View file

@ -944,7 +944,7 @@ fn static_assert() {
for family in &v.0 { for family in &v.0 {
match *family { match *family {
FontFamily::FamilyName(ref name) => { FontFamily::FamilyName(ref name) => {
unsafe { Gecko_FontFamilyList_AppendNamed(list, name.as_ptr()); } unsafe { Gecko_FontFamilyList_AppendNamed(list, name.0.as_ptr()); }
} }
FontFamily::Generic(ref name) => { FontFamily::Generic(ref name) => {
let family_type = let family_type =

View file

@ -10,7 +10,7 @@
additional_methods=[Method("compute_font_hash", is_mut=True)]) %> additional_methods=[Method("compute_font_hash", is_mut=True)]) %>
<%helpers:longhand name="font-family" animatable="False" need_index="True" <%helpers:longhand name="font-family" animatable="False" need_index="True"
spec="https://drafts.csswg.org/css-fonts/#propdef-font-family"> spec="https://drafts.csswg.org/css-fonts/#propdef-font-family">
use self::computed_value::FontFamily; use self::computed_value::{FontFamily, FamilyName};
use values::NoViewportPercentage; use values::NoViewportPercentage;
use values::computed::ComputedValueAsSpecified; use values::computed::ComputedValueAsSpecified;
pub use self::computed_value::T as SpecifiedValue; pub use self::computed_value::T as SpecifiedValue;
@ -28,15 +28,19 @@
#[derive(Debug, PartialEq, Eq, Clone, Hash)] #[derive(Debug, PartialEq, Eq, Clone, Hash)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))] #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
pub enum FontFamily { pub enum FontFamily {
FamilyName(Atom), FamilyName(FamilyName),
Generic(Atom), Generic(Atom),
} }
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
pub struct FamilyName(pub Atom);
impl FontFamily { impl FontFamily {
#[inline] #[inline]
pub fn atom(&self) -> &Atom { pub fn atom(&self) -> &Atom {
match *self { match *self {
FontFamily::FamilyName(ref name) => name, FontFamily::FamilyName(ref name) => &name.0,
FontFamily::Generic(ref name) => name, FontFamily::Generic(ref name) => name,
} }
} }
@ -67,18 +71,22 @@
"monospace" => return FontFamily::Generic(atom!("monospace")), "monospace" => return FontFamily::Generic(atom!("monospace")),
_ => {} _ => {}
} }
FontFamily::FamilyName(input) FontFamily::FamilyName(FamilyName(input))
}
}
impl ToCss for FamilyName {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
dest.write_char('"')?;
write!(CssStringWriter::new(dest), "{}", self.0)?;
dest.write_char('"')
} }
} }
impl ToCss for FontFamily { impl ToCss for FontFamily {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self { match *self {
FontFamily::FamilyName(ref name) => { FontFamily::FamilyName(ref name) => name.to_css(dest),
dest.write_char('"')?;
write!(CssStringWriter::new(dest), "{}", name)?;
dest.write_char('"')
}
// All generic values accepted by the parser are known to not require escaping. // All generic values accepted by the parser are known to not require escaping.
FontFamily::Generic(ref name) => write!(dest, "{}", name), FontFamily::Generic(ref name) => write!(dest, "{}", name),
@ -121,10 +129,22 @@
} }
} }
/// `FamilyName::parse` is based on `FontFamily::parse` and not the other way around
/// because we want the former to exclude generic family keywords.
impl Parse for FamilyName {
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
match FontFamily::parse(context, input) {
Ok(FontFamily::FamilyName(name)) => Ok(name),
Ok(FontFamily::Generic(_)) |
Err(()) => Err(())
}
}
}
impl Parse for FontFamily { impl Parse for FontFamily {
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
if let Ok(value) = input.try(|input| input.expect_string()) { if let Ok(value) = input.try(|input| input.expect_string()) {
return Ok(FontFamily::FamilyName(Atom::from(&*value))) return Ok(FontFamily::FamilyName(FamilyName(Atom::from(&*value))))
} }
let first_ident = try!(input.expect_ident()); let first_ident = try!(input.expect_ident());
@ -165,7 +185,7 @@
value.push_str(" "); value.push_str(" ");
value.push_str(&ident); value.push_str(&ident);
} }
Ok(FontFamily::FamilyName(Atom::from(value))) Ok(FontFamily::FamilyName(FamilyName(Atom::from(value))))
} }
} }
</%helpers:longhand> </%helpers:longhand>

View file

@ -4,7 +4,7 @@
use gfx::font_cache_thread::FontCacheThread; use gfx::font_cache_thread::FontCacheThread;
use ipc_channel::ipc; use ipc_channel::ipc;
use style::computed_values::font_family::FontFamily; use style::computed_values::font_family::{FontFamily, FamilyName};
use style::font_face::{FontFaceRule, Source}; use style::font_face::{FontFaceRule, Source};
#[test] #[test]
@ -12,8 +12,8 @@ fn test_local_web_font() {
let (inp_chan, _) = ipc::channel().unwrap(); let (inp_chan, _) = ipc::channel().unwrap();
let (out_chan, out_receiver) = ipc::channel().unwrap(); let (out_chan, out_receiver) = ipc::channel().unwrap();
let font_cache_thread = FontCacheThread::new(inp_chan, None); let font_cache_thread = FontCacheThread::new(inp_chan, None);
let family_name = FontFamily::FamilyName(From::from("test family")); let family_name = FontFamily::FamilyName(FamilyName(From::from("test family")));
let variant_name = FontFamily::FamilyName(From::from("test font face")); let variant_name = FontFamily::FamilyName(FamilyName(From::from("test font face")));
let font_face_rule = FontFaceRule { let font_face_rule = FontFaceRule {
family: family_name.clone(), family: family_name.clone(),
sources: vec![Source::Local(variant_name)], sources: vec![Source::Local(variant_name)],