mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
style: [css-fonts] Implement 'font-synthesis: small-caps'
Differential Revision: https://phabricator.services.mozilla.com/D114313
This commit is contained in:
parent
fd3d12e214
commit
0cb64672f4
1 changed files with 68 additions and 32 deletions
|
@ -1990,23 +1990,24 @@ impl Parse for FontFeatureSettings {
|
|||
Debug,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToComputedValue,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
/// Whether user agents are allowed to synthesize bold or oblique font faces
|
||||
/// when a font family lacks bold or italic faces
|
||||
/// when a font family lacks those faces, or a small-caps variant when this is
|
||||
/// not supported by the face.
|
||||
pub struct FontSynthesis {
|
||||
/// If a `font-weight` is requested that the font family does not contain,
|
||||
/// the user agent may synthesize the requested weight from the weights
|
||||
/// that do exist in the font family.
|
||||
#[css(represents_keyword)]
|
||||
pub weight: bool,
|
||||
/// If a font-style is requested that the font family does not contain,
|
||||
/// the user agent may synthesize the requested style from the normal face in the font family.
|
||||
#[css(represents_keyword)]
|
||||
pub style: bool,
|
||||
/// This bit controls whether the user agent is allowed to synthesize small caps variant
|
||||
/// when a font face lacks it.
|
||||
pub small_caps: bool,
|
||||
}
|
||||
|
||||
impl FontSynthesis {
|
||||
|
@ -2016,6 +2017,7 @@ impl FontSynthesis {
|
|||
FontSynthesis {
|
||||
weight: true,
|
||||
style: true,
|
||||
small_caps: true,
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
|
@ -2024,8 +2026,14 @@ impl FontSynthesis {
|
|||
FontSynthesis {
|
||||
weight: false,
|
||||
style: false,
|
||||
small_caps: false,
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
/// Return true if this is the 'none' value
|
||||
pub fn is_none(&self) -> bool {
|
||||
*self == Self::none()
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for FontSynthesis {
|
||||
|
@ -2033,26 +2041,23 @@ impl Parse for FontSynthesis {
|
|||
_: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<FontSynthesis, ParseError<'i>> {
|
||||
let mut result = FontSynthesis {
|
||||
weight: false,
|
||||
style: false,
|
||||
};
|
||||
try_match_ident_ignore_ascii_case! { input,
|
||||
"none" => Ok(result),
|
||||
"weight" => {
|
||||
result.weight = true;
|
||||
if input.try_parse(|input| input.expect_ident_matching("style")).is_ok() {
|
||||
result.style = true;
|
||||
}
|
||||
Ok(result)
|
||||
},
|
||||
"style" => {
|
||||
result.style = true;
|
||||
if input.try_parse(|input| input.expect_ident_matching("weight")).is_ok() {
|
||||
result.weight = true;
|
||||
}
|
||||
Ok(result)
|
||||
},
|
||||
use crate::values::SelectorParseErrorKind;
|
||||
let mut result = Self::none();
|
||||
while let Ok(ident) = input.try_parse(|i| i.expect_ident_cloned()) {
|
||||
match_ignore_ascii_case! { &ident,
|
||||
"none" if result.is_none() => return Ok(result),
|
||||
"weight" if !result.weight => result.weight = true,
|
||||
"style" if !result.style => result.style = true,
|
||||
"small-caps" if !result.small_caps &&
|
||||
static_prefs::pref!("layout.css.font-synthesis-small-caps.enabled")
|
||||
=> result.small_caps = true,
|
||||
_ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident))),
|
||||
}
|
||||
}
|
||||
if !result.is_none() {
|
||||
Ok(result)
|
||||
} else {
|
||||
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2062,14 +2067,41 @@ impl ToCss for FontSynthesis {
|
|||
where
|
||||
W: Write,
|
||||
{
|
||||
if self.weight && self.style {
|
||||
dest.write_str("weight style")
|
||||
} else if self.style {
|
||||
dest.write_str("style")
|
||||
} else if self.weight {
|
||||
dest.write_str("weight")
|
||||
} else {
|
||||
dest.write_str("none")
|
||||
if self.is_none() {
|
||||
return dest.write_str("none");
|
||||
}
|
||||
|
||||
let mut need_space = false;
|
||||
if self.weight {
|
||||
dest.write_str("weight")?;
|
||||
need_space = true;
|
||||
}
|
||||
if self.style {
|
||||
if need_space {
|
||||
dest.write_str(" ")?;
|
||||
}
|
||||
dest.write_str("style")?;
|
||||
need_space = true;
|
||||
}
|
||||
if self.small_caps {
|
||||
if need_space {
|
||||
dest.write_str(" ")?;
|
||||
}
|
||||
dest.write_str("small-caps")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl SpecifiedValueInfo for FontSynthesis {
|
||||
fn collect_completion_keywords(f: KeywordsCollectFn) {
|
||||
f(&[
|
||||
"none",
|
||||
"weight",
|
||||
"style",
|
||||
]);
|
||||
if static_prefs::pref!("layout.css.font-synthesis-small-caps.enabled") {
|
||||
f(&["small-caps"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2082,6 +2114,7 @@ impl From<u8> for FontSynthesis {
|
|||
FontSynthesis {
|
||||
weight: bits & structs::NS_FONT_SYNTHESIS_WEIGHT as u8 != 0,
|
||||
style: bits & structs::NS_FONT_SYNTHESIS_STYLE as u8 != 0,
|
||||
small_caps: bits & structs::NS_FONT_SYNTHESIS_SMALL_CAPS as u8 != 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2098,6 +2131,9 @@ impl From<FontSynthesis> for u8 {
|
|||
if v.style {
|
||||
bits |= structs::NS_FONT_SYNTHESIS_STYLE as u8;
|
||||
}
|
||||
if v.small_caps {
|
||||
bits |= structs::NS_FONT_SYNTHESIS_SMALL_CAPS as u8;
|
||||
}
|
||||
bits
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue