mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
style: Implement the font-synthesis-{weight,style,small-caps} longhand properties, and make font-synthesis into a shorthand
Differential Revision: https://phabricator.services.mozilla.com/D167480
This commit is contained in:
parent
dbd3eab9cd
commit
05fb1b62b7
9 changed files with 169 additions and 208 deletions
|
@ -809,33 +809,26 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
||||||
builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_BORDER_BACKGROUND);
|
builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_BORDER_BACKGROUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self
|
if self.author_specified.contains(LonghandId::FontFamily) {
|
||||||
.author_specified
|
|
||||||
.contains(LonghandId::FontFamily)
|
|
||||||
{
|
|
||||||
builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_FONT_FAMILY);
|
builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_FONT_FAMILY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self
|
if self.author_specified.contains(LonghandId::LetterSpacing) {
|
||||||
.author_specified
|
|
||||||
.contains(LonghandId::LetterSpacing)
|
|
||||||
{
|
|
||||||
builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_LETTER_SPACING);
|
builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_LETTER_SPACING);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self
|
if self.author_specified.contains(LonghandId::WordSpacing) {
|
||||||
.author_specified
|
|
||||||
.contains(LonghandId::WordSpacing)
|
|
||||||
{
|
|
||||||
builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_WORD_SPACING);
|
builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_WORD_SPACING);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
if self
|
if self.author_specified.contains(LonghandId::FontSynthesisWeight) {
|
||||||
.author_specified
|
builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_FONT_SYNTHESIS_WEIGHT);
|
||||||
.contains(LonghandId::FontSynthesis)
|
}
|
||||||
{
|
|
||||||
builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_FONT_SYNTHESIS);
|
#[cfg(feature = "gecko")]
|
||||||
|
if self.author_specified.contains(LonghandId::FontSynthesisStyle) {
|
||||||
|
builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_FONT_SYNTHESIS_STYLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
|
|
|
@ -90,28 +90,34 @@ bitflags! {
|
||||||
/// Whether there are author-specified rules for `font-family`.
|
/// Whether there are author-specified rules for `font-family`.
|
||||||
const HAS_AUTHOR_SPECIFIED_FONT_FAMILY = 1 << 16;
|
const HAS_AUTHOR_SPECIFIED_FONT_FAMILY = 1 << 16;
|
||||||
|
|
||||||
/// Whether there are author-specified rules for `font-synthesis`.
|
/// Whether there are author-specified rules for `font-synthesis-weight`.
|
||||||
const HAS_AUTHOR_SPECIFIED_FONT_SYNTHESIS = 1 << 17;
|
const HAS_AUTHOR_SPECIFIED_FONT_SYNTHESIS_WEIGHT = 1 << 17;
|
||||||
|
|
||||||
|
/// Whether there are author-specified rules for `font-synthesis-style`.
|
||||||
|
const HAS_AUTHOR_SPECIFIED_FONT_SYNTHESIS_STYLE = 1 << 18;
|
||||||
|
|
||||||
|
// (There's also font-synthesis-small-caps, but we don't currently need to
|
||||||
|
// keep track of that.)
|
||||||
|
|
||||||
/// Whether there are author-specified rules for `letter-spacing`.
|
/// Whether there are author-specified rules for `letter-spacing`.
|
||||||
const HAS_AUTHOR_SPECIFIED_LETTER_SPACING = 1 << 18;
|
const HAS_AUTHOR_SPECIFIED_LETTER_SPACING = 1 << 19;
|
||||||
|
|
||||||
/// Whether there are author-specified rules for `word-spacing`.
|
/// Whether there are author-specified rules for `word-spacing`.
|
||||||
const HAS_AUTHOR_SPECIFIED_WORD_SPACING = 1 << 19;
|
const HAS_AUTHOR_SPECIFIED_WORD_SPACING = 1 << 20;
|
||||||
|
|
||||||
/// Whether the style depends on viewport units.
|
/// Whether the style depends on viewport units.
|
||||||
const USES_VIEWPORT_UNITS = 1 << 20;
|
const USES_VIEWPORT_UNITS = 1 << 21;
|
||||||
|
|
||||||
/// Whether the style depends on viewport units on container queries.
|
/// Whether the style depends on viewport units on container queries.
|
||||||
///
|
///
|
||||||
/// This needs to be a separate flag from `USES_VIEWPORT_UNITS` because
|
/// This needs to be a separate flag from `USES_VIEWPORT_UNITS` because
|
||||||
/// it causes us to re-match the style (rather than re-cascascading it,
|
/// it causes us to re-match the style (rather than re-cascascading it,
|
||||||
/// which is enough for other uses of viewport units).
|
/// which is enough for other uses of viewport units).
|
||||||
const USES_VIEWPORT_UNITS_ON_CONTAINER_QUERIES = 1 << 21;
|
const USES_VIEWPORT_UNITS_ON_CONTAINER_QUERIES = 1 << 22;
|
||||||
|
|
||||||
/// A flag used to mark styles which have `container-type` of `size` or
|
/// A flag used to mark styles which have `container-type` of `size` or
|
||||||
/// `inline-size`, or under one.
|
/// `inline-size`, or under one.
|
||||||
const SELF_OR_ANCESTOR_HAS_SIZE_CONTAINER_TYPE = 1 << 22;
|
const SELF_OR_ANCESTOR_HAS_SIZE_CONTAINER_TYPE = 1 << 23;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -884,7 +884,6 @@ class PropertyRestrictions:
|
||||||
"text-combine-upright",
|
"text-combine-upright",
|
||||||
"ruby-position",
|
"ruby-position",
|
||||||
# XXX Should these really apply to cue?
|
# XXX Should these really apply to cue?
|
||||||
"font-synthesis",
|
|
||||||
"-moz-osx-font-smoothing",
|
"-moz-osx-font-smoothing",
|
||||||
# FIXME(emilio): background-blend-mode should be part of the
|
# FIXME(emilio): background-blend-mode should be part of the
|
||||||
# background shorthand, and get reset, per
|
# background shorthand, and get reset, per
|
||||||
|
@ -895,6 +894,7 @@ class PropertyRestrictions:
|
||||||
+ PropertyRestrictions.shorthand(data, "background")
|
+ PropertyRestrictions.shorthand(data, "background")
|
||||||
+ PropertyRestrictions.shorthand(data, "outline")
|
+ PropertyRestrictions.shorthand(data, "outline")
|
||||||
+ PropertyRestrictions.shorthand(data, "font")
|
+ PropertyRestrictions.shorthand(data, "font")
|
||||||
|
+ PropertyRestrictions.shorthand(data, "font-synthesis")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -837,7 +837,7 @@ fn static_assert() {
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<% skip_font_longhands = """font-family font-size font-size-adjust font-weight
|
<% skip_font_longhands = """font-family font-size font-size-adjust font-weight
|
||||||
font-style font-stretch font-synthesis -x-lang
|
font-style font-stretch -x-lang
|
||||||
font-variant-alternates font-variant-east-asian
|
font-variant-alternates font-variant-east-asian
|
||||||
font-variant-ligatures font-variant-numeric
|
font-variant-ligatures font-variant-numeric
|
||||||
font-language-override font-feature-settings
|
font-language-override font-feature-settings
|
||||||
|
@ -909,8 +909,6 @@ fn static_assert() {
|
||||||
${impl_simple('font_stretch', 'mFont.stretch')}
|
${impl_simple('font_stretch', 'mFont.stretch')}
|
||||||
${impl_simple('font_style', 'mFont.style')}
|
${impl_simple('font_style', 'mFont.style')}
|
||||||
|
|
||||||
${impl_simple_type_with_conversion("font_synthesis", "mFont.synthesis")}
|
|
||||||
|
|
||||||
${impl_simple("font_variant_alternates", "mFont.variantAlternates")}
|
${impl_simple("font_variant_alternates", "mFont.variantAlternates")}
|
||||||
|
|
||||||
${impl_simple("font_size_adjust", "mFont.sizeAdjust")}
|
${impl_simple("font_size_adjust", "mFont.sizeAdjust")}
|
||||||
|
|
|
@ -81,12 +81,36 @@ ${helpers.predefined_type(
|
||||||
)}
|
)}
|
||||||
|
|
||||||
${helpers.predefined_type(
|
${helpers.predefined_type(
|
||||||
"font-synthesis",
|
"font-synthesis-weight",
|
||||||
"FontSynthesis",
|
"FontSynthesis",
|
||||||
engines="gecko",
|
engines="gecko",
|
||||||
initial_value="specified::FontSynthesis::get_initial_value()",
|
initial_value="computed::FontSynthesis::Auto",
|
||||||
|
initial_specified_value="specified::FontSynthesis::Auto",
|
||||||
|
gecko_ffi_name="mFont.synthesisWeight",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
spec="https://drafts.csswg.org/css-fonts/#propdef-font-synthesis",
|
spec="https://drafts.csswg.org/css-fonts-4/#font-synthesis-weight",
|
||||||
|
)}
|
||||||
|
|
||||||
|
${helpers.predefined_type(
|
||||||
|
"font-synthesis-style",
|
||||||
|
"FontSynthesis",
|
||||||
|
engines="gecko",
|
||||||
|
initial_value="computed::FontSynthesis::Auto",
|
||||||
|
initial_specified_value="specified::FontSynthesis::Auto",
|
||||||
|
gecko_ffi_name="mFont.synthesisStyle",
|
||||||
|
animation_value_type="discrete",
|
||||||
|
spec="https://drafts.csswg.org/css-fonts-4/#font-synthesis-style",
|
||||||
|
)}
|
||||||
|
|
||||||
|
${helpers.predefined_type(
|
||||||
|
"font-synthesis-small-caps",
|
||||||
|
"FontSynthesis",
|
||||||
|
engines="gecko",
|
||||||
|
initial_value="computed::FontSynthesis::Auto",
|
||||||
|
initial_specified_value="specified::FontSynthesis::Auto",
|
||||||
|
gecko_ffi_name="mFont.synthesisSmallCaps",
|
||||||
|
animation_value_type="discrete",
|
||||||
|
spec="https://drafts.csswg.org/css-fonts-4/#font-synthesis-small-caps",
|
||||||
)}
|
)}
|
||||||
|
|
||||||
${helpers.predefined_type(
|
${helpers.predefined_type(
|
||||||
|
|
|
@ -456,3 +456,84 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%helpers:shorthand>
|
</%helpers:shorthand>
|
||||||
|
|
||||||
|
<%helpers:shorthand name="font-synthesis"
|
||||||
|
engines="gecko"
|
||||||
|
flags="SHORTHAND_IN_GETCS"
|
||||||
|
sub_properties="font-synthesis-weight font-synthesis-style font-synthesis-small-caps"
|
||||||
|
derive_value_info="False"
|
||||||
|
spec="https://drafts.csswg.org/css-fonts-3/#propdef-font-variant">
|
||||||
|
<% sub_properties = ["weight", "style", "small_caps"] %>
|
||||||
|
|
||||||
|
use crate::values::specified::FontSynthesis;
|
||||||
|
|
||||||
|
pub fn parse_value<'i, 't>(
|
||||||
|
_context: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
) -> Result<Longhands, ParseError<'i>> {
|
||||||
|
% for prop in sub_properties:
|
||||||
|
let mut ${prop} = FontSynthesis::None;
|
||||||
|
% endfor
|
||||||
|
|
||||||
|
if input.try_parse(|input| input.expect_ident_matching("none")).is_ok() {
|
||||||
|
// Leave all the individual values as None
|
||||||
|
} else {
|
||||||
|
let mut has_custom_value = false;
|
||||||
|
while !input.is_exhausted() {
|
||||||
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
|
% for prop in sub_properties:
|
||||||
|
"${prop.replace('_', '-')}" if ${prop} == FontSynthesis::None => {
|
||||||
|
has_custom_value = true;
|
||||||
|
${prop} = FontSynthesis::Auto;
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !has_custom_value {
|
||||||
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(expanded! {
|
||||||
|
% for prop in sub_properties:
|
||||||
|
font_synthesis_${prop}: ${prop},
|
||||||
|
% endfor
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ToCss for LonghandsToSerialize<'a> {
|
||||||
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write {
|
||||||
|
let mut has_any = false;
|
||||||
|
|
||||||
|
% for prop in sub_properties:
|
||||||
|
if self.font_synthesis_${prop} == &FontSynthesis::Auto {
|
||||||
|
if has_any {
|
||||||
|
dest.write_char(' ')?;
|
||||||
|
}
|
||||||
|
has_any = true;
|
||||||
|
dest.write_str("${prop.replace('_', '-')}")?;
|
||||||
|
}
|
||||||
|
% endfor
|
||||||
|
|
||||||
|
if !has_any {
|
||||||
|
dest.write_str("none")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The shorthand takes the sub-property names of the longhands, and not the
|
||||||
|
// 'auto' keyword like they do, so we can't automatically derive this.
|
||||||
|
impl SpecifiedValueInfo for Longhands {
|
||||||
|
fn collect_completion_keywords(f: KeywordsCollectFn) {
|
||||||
|
f(&[
|
||||||
|
"none",
|
||||||
|
% for prop in sub_properties:
|
||||||
|
"${prop.replace('_', '-')}",
|
||||||
|
% endfor
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</%helpers:shorthand>
|
||||||
|
|
|
@ -869,12 +869,8 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||||
if !is_legacy_marker {
|
if !is_legacy_marker {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if !self
|
let flags = self.style.flags.get();
|
||||||
.style
|
if !flags.contains(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_FONT_FAMILY) {
|
||||||
.flags
|
|
||||||
.get()
|
|
||||||
.contains(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_FONT_FAMILY)
|
|
||||||
{
|
|
||||||
self.style
|
self.style
|
||||||
.mutate_font()
|
.mutate_font()
|
||||||
.set_font_family(FontFamily::moz_bullet().clone());
|
.set_font_family(FontFamily::moz_bullet().clone());
|
||||||
|
@ -882,33 +878,23 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||||
// FIXME(mats): We can remove this if support for font-synthesis is added to @font-face rules.
|
// FIXME(mats): We can remove this if support for font-synthesis is added to @font-face rules.
|
||||||
// Then we can add it to the @font-face rule in html.css instead.
|
// Then we can add it to the @font-face rule in html.css instead.
|
||||||
// https://github.com/w3c/csswg-drafts/issues/6081
|
// https://github.com/w3c/csswg-drafts/issues/6081
|
||||||
if !self
|
if !flags.contains(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_FONT_SYNTHESIS_WEIGHT) {
|
||||||
.style
|
|
||||||
.flags
|
|
||||||
.get()
|
|
||||||
.contains(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_FONT_SYNTHESIS)
|
|
||||||
{
|
|
||||||
self.style
|
self.style
|
||||||
.mutate_font()
|
.mutate_font()
|
||||||
.set_font_synthesis(FontSynthesis::none());
|
.set_font_synthesis_weight(FontSynthesis::None);
|
||||||
|
}
|
||||||
|
if !flags.contains(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_FONT_SYNTHESIS_STYLE) {
|
||||||
|
self.style
|
||||||
|
.mutate_font()
|
||||||
|
.set_font_synthesis_style(FontSynthesis::None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !self
|
if !flags.contains(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_LETTER_SPACING) {
|
||||||
.style
|
|
||||||
.flags
|
|
||||||
.get()
|
|
||||||
.contains(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_LETTER_SPACING)
|
|
||||||
{
|
|
||||||
self.style
|
self.style
|
||||||
.mutate_inherited_text()
|
.mutate_inherited_text()
|
||||||
.set_letter_spacing(LetterSpacing::normal());
|
.set_letter_spacing(LetterSpacing::normal());
|
||||||
}
|
}
|
||||||
if !self
|
if !flags.contains(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_WORD_SPACING) {
|
||||||
.style
|
|
||||||
.flags
|
|
||||||
.get()
|
|
||||||
.contains(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_WORD_SPACING)
|
|
||||||
{
|
|
||||||
self.style
|
self.style
|
||||||
.mutate_inherited_text()
|
.mutate_inherited_text()
|
||||||
.set_word_spacing(WordSpacing::normal());
|
.set_word_spacing(WordSpacing::normal());
|
||||||
|
|
|
@ -26,8 +26,8 @@ use std::fmt::{self, Write};
|
||||||
use style_traits::{CssWriter, ParseError, ToCss};
|
use style_traits::{CssWriter, ParseError, ToCss};
|
||||||
|
|
||||||
pub use crate::values::computed::Length as MozScriptMinSize;
|
pub use crate::values::computed::Length as MozScriptMinSize;
|
||||||
pub use crate::values::specified::font::FontPalette;
|
pub use crate::values::specified::font::{FontPalette, FontSynthesis};
|
||||||
pub use crate::values::specified::font::{FontSynthesis, MozScriptSizeMultiplier};
|
pub use crate::values::specified::font::MozScriptSizeMultiplier;
|
||||||
pub use crate::values::specified::font::{
|
pub use crate::values::specified::font::{
|
||||||
FontVariantAlternates, FontVariantEastAsian, FontVariantLigatures, FontVariantNumeric, XLang,
|
FontVariantAlternates, FontVariantEastAsian, FontVariantLigatures, FontVariantNumeric, XLang,
|
||||||
XTextZoom,
|
XTextZoom,
|
||||||
|
|
|
@ -1717,155 +1717,6 @@ impl Parse for FontVariantNumeric {
|
||||||
/// This property provides low-level control over OpenType or TrueType font features.
|
/// This property provides low-level control over OpenType or TrueType font features.
|
||||||
pub type FontFeatureSettings = FontSettings<FeatureTagValue<Integer>>;
|
pub type FontFeatureSettings = FontSettings<FeatureTagValue<Integer>>;
|
||||||
|
|
||||||
#[derive(
|
|
||||||
Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem,
|
|
||||||
)]
|
|
||||||
/// Whether user agents are allowed to synthesize bold or oblique font 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.
|
|
||||||
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.
|
|
||||||
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 {
|
|
||||||
#[inline]
|
|
||||||
/// Get the default value of font-synthesis
|
|
||||||
pub fn get_initial_value() -> Self {
|
|
||||||
FontSynthesis {
|
|
||||||
weight: true,
|
|
||||||
style: true,
|
|
||||||
small_caps: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
/// Get the 'none' value of font-synthesis
|
|
||||||
pub fn none() -> Self {
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn allow_font_synthesis_small_caps() -> bool {
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
return static_prefs::pref!("layout.css.font-synthesis-small-caps.enabled");
|
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Parse for FontSynthesis {
|
|
||||||
fn parse<'i, 't>(
|
|
||||||
_: &ParserContext,
|
|
||||||
input: &mut Parser<'i, 't>,
|
|
||||||
) -> Result<FontSynthesis, ParseError<'i>> {
|
|
||||||
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 && allow_font_synthesis_small_caps()
|
|
||||||
=> 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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToCss for FontSynthesis {
|
|
||||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
|
||||||
where
|
|
||||||
W: Write,
|
|
||||||
{
|
|
||||||
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 allow_font_synthesis_small_caps() {
|
|
||||||
f(&["small-caps"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
impl From<u8> for FontSynthesis {
|
|
||||||
fn from(bits: u8) -> FontSynthesis {
|
|
||||||
use crate::gecko_bindings::structs;
|
|
||||||
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
impl From<FontSynthesis> for u8 {
|
|
||||||
fn from(v: FontSynthesis) -> u8 {
|
|
||||||
use crate::gecko_bindings::structs;
|
|
||||||
|
|
||||||
let mut bits: u8 = 0;
|
|
||||||
if v.weight {
|
|
||||||
bits |= structs::NS_FONT_SYNTHESIS_WEIGHT as 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)]
|
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)]
|
||||||
/// Allows authors to explicitly specify the language system of the font,
|
/// Allows authors to explicitly specify the language system of the font,
|
||||||
/// overriding the language system implied by the content language
|
/// overriding the language system implied by the content language
|
||||||
|
@ -1936,6 +1787,29 @@ impl Parse for FontLanguageOverride {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A value for any of the font-synthesis-{weight,style,small-caps} properties.
|
||||||
|
#[repr(u8)]
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Eq,
|
||||||
|
MallocSizeOf,
|
||||||
|
Parse,
|
||||||
|
PartialEq,
|
||||||
|
SpecifiedValueInfo,
|
||||||
|
ToComputedValue,
|
||||||
|
ToCss,
|
||||||
|
ToResolvedValue,
|
||||||
|
ToShmem,
|
||||||
|
)]
|
||||||
|
pub enum FontSynthesis {
|
||||||
|
/// This attribute may be synthesized if not supported by a face.
|
||||||
|
Auto,
|
||||||
|
/// Do not attempt to synthesis this style attribute.
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone,
|
Clone,
|
||||||
Debug,
|
Debug,
|
||||||
|
@ -1993,7 +1867,6 @@ impl ToCss for FontPalette {
|
||||||
/// variations.
|
/// variations.
|
||||||
pub type FontVariationSettings = FontSettings<VariationValue<Number>>;
|
pub type FontVariationSettings = FontSettings<VariationValue<Number>>;
|
||||||
|
|
||||||
|
|
||||||
fn parse_one_feature_value<'i, 't>(
|
fn parse_one_feature_value<'i, 't>(
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue