Bug 1899126 - Simplify some font-variant code to take advantage of cbindgen and derived implementations. r=jfkthame,layout-reviewers

While at it do fontLanguageOverride to, in order to remove
impl_simple_type_with_conversion.

Differential Revision: https://phabricator.services.mozilla.com/D211761
This commit is contained in:
Emilio Cobos Álvarez 2024-05-28 09:37:21 +00:00
parent 6022986b97
commit 4b8f8f4639
14 changed files with 174 additions and 649 deletions

View file

@ -68,9 +68,9 @@ nsFont::MaxDifference nsFont::CalcDifference(const nsFont& aOther) const {
// mapping from bitflag to font feature tag/value pair // mapping from bitflag to font feature tag/value pair
// //
// these need to be kept in sync with the constants listed // these need to be kept in sync with the constants listed
// in gfxFontConstants.h (e.g. NS_FONT_VARIANT_EAST_ASIAN_JIS78) // in gfxFontConstants.h (e.g. StyleFontVariantEastAsian::JIS78)
// NS_FONT_VARIANT_EAST_ASIAN_xxx values // StyleFontVariantEastAsian::xxx values
const gfxFontFeature eastAsianDefaults[] = { const gfxFontFeature eastAsianDefaults[] = {
{TRUETYPE_TAG('j', 'p', '7', '8'), 1}, {TRUETYPE_TAG('j', 'p', '7', '8'), 1},
{TRUETYPE_TAG('j', 'p', '8', '3'), 1}, {TRUETYPE_TAG('j', 'p', '8', '3'), 1},
@ -83,10 +83,10 @@ const gfxFontFeature eastAsianDefaults[] = {
{TRUETYPE_TAG('r', 'u', 'b', 'y'), 1}}; {TRUETYPE_TAG('r', 'u', 'b', 'y'), 1}};
static_assert(MOZ_ARRAY_LENGTH(eastAsianDefaults) == static_assert(MOZ_ARRAY_LENGTH(eastAsianDefaults) ==
NS_FONT_VARIANT_EAST_ASIAN_COUNT, StyleFontVariantEastAsian::COUNT,
"eastAsianDefaults[] should be correct"); "eastAsianDefaults[] should be correct");
// NS_FONT_VARIANT_LIGATURES_xxx values // StyleFontVariantLigatures::xxx values
const gfxFontFeature ligDefaults[] = { const gfxFontFeature ligDefaults[] = {
{TRUETYPE_TAG('l', 'i', 'g', 'a'), 0}, // none value means all off {TRUETYPE_TAG('l', 'i', 'g', 'a'), 0}, // none value means all off
{TRUETYPE_TAG('l', 'i', 'g', 'a'), 1}, {TRUETYPE_TAG('l', 'i', 'g', 'a'), 1},
@ -98,10 +98,10 @@ const gfxFontFeature ligDefaults[] = {
{TRUETYPE_TAG('c', 'a', 'l', 't'), 1}, {TRUETYPE_TAG('c', 'a', 'l', 't'), 1},
{TRUETYPE_TAG('c', 'a', 'l', 't'), 0}}; {TRUETYPE_TAG('c', 'a', 'l', 't'), 0}};
static_assert(MOZ_ARRAY_LENGTH(ligDefaults) == NS_FONT_VARIANT_LIGATURES_COUNT, static_assert(MOZ_ARRAY_LENGTH(ligDefaults) == StyleFontVariantLigatures::COUNT,
"ligDefaults[] should be correct"); "ligDefaults[] should be correct");
// NS_FONT_VARIANT_NUMERIC_xxx values // StyleFontVariantNumeric::xxx values
const gfxFontFeature numericDefaults[] = { const gfxFontFeature numericDefaults[] = {
{TRUETYPE_TAG('l', 'n', 'u', 'm'), 1}, {TRUETYPE_TAG('l', 'n', 'u', 'm'), 1},
{TRUETYPE_TAG('o', 'n', 'u', 'm'), 1}, {TRUETYPE_TAG('o', 'n', 'u', 'm'), 1},
@ -113,19 +113,17 @@ const gfxFontFeature numericDefaults[] = {
{TRUETYPE_TAG('o', 'r', 'd', 'n'), 1}}; {TRUETYPE_TAG('o', 'r', 'd', 'n'), 1}};
static_assert(MOZ_ARRAY_LENGTH(numericDefaults) == static_assert(MOZ_ARRAY_LENGTH(numericDefaults) ==
NS_FONT_VARIANT_NUMERIC_COUNT, StyleFontVariantNumeric::COUNT,
"numericDefaults[] should be correct"); "numericDefaults[] should be correct");
static void AddFontFeaturesBitmask(uint32_t aValue, uint32_t aMin, template <typename T>
uint32_t aMax, static void AddFontFeaturesBitmask(T aValue, T aMin, T aMax,
const gfxFontFeature aFeatureDefaults[], Span<const gfxFontFeature> aFeatureDefaults,
nsTArray<gfxFontFeature>& aFeaturesOut) nsTArray<gfxFontFeature>& aFeaturesOut)
{ {
uint32_t i, m; for (uint32_t i = 0, m = aMin._0; m <= aMax._0; i++, m <<= 1) {
if (m & aValue._0) {
for (i = 0, m = aMin; m <= aMax; i++, m <<= 1) {
if (m & aValue) {
const gfxFontFeature& feature = aFeatureDefaults[i]; const gfxFontFeature& feature = aFeatureDefaults[i];
aFeaturesOut.AppendElement(feature); aFeaturesOut.AppendElement(feature);
} }
@ -192,28 +190,29 @@ void nsFont::AddFontFeaturesToStyle(gfxFontStyle* aStyle,
// -- east-asian // -- east-asian
if (variantEastAsian) { if (variantEastAsian) {
AddFontFeaturesBitmask(variantEastAsian, NS_FONT_VARIANT_EAST_ASIAN_JIS78, AddFontFeaturesBitmask(variantEastAsian, StyleFontVariantEastAsian::JIS78,
NS_FONT_VARIANT_EAST_ASIAN_RUBY, eastAsianDefaults, StyleFontVariantEastAsian::RUBY, eastAsianDefaults,
aStyle->featureSettings); aStyle->featureSettings);
} }
// -- ligatures // -- ligatures
if (variantLigatures) { if (variantLigatures) {
AddFontFeaturesBitmask(variantLigatures, NS_FONT_VARIANT_LIGATURES_NONE, AddFontFeaturesBitmask(variantLigatures, StyleFontVariantLigatures::NONE,
NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL, ligDefaults, StyleFontVariantLigatures::NO_CONTEXTUAL,
aStyle->featureSettings); ligDefaults, aStyle->featureSettings);
if (variantLigatures & NS_FONT_VARIANT_LIGATURES_COMMON) { if (variantLigatures & StyleFontVariantLigatures::COMMON_LIGATURES) {
// liga already enabled, need to enable clig also // liga already enabled, need to enable clig also
setting.mTag = TRUETYPE_TAG('c', 'l', 'i', 'g'); setting.mTag = TRUETYPE_TAG('c', 'l', 'i', 'g');
setting.mValue = 1; setting.mValue = 1;
aStyle->featureSettings.AppendElement(setting); aStyle->featureSettings.AppendElement(setting);
} else if (variantLigatures & NS_FONT_VARIANT_LIGATURES_NO_COMMON) { } else if (variantLigatures &
StyleFontVariantLigatures::NO_COMMON_LIGATURES) {
// liga already disabled, need to disable clig also // liga already disabled, need to disable clig also
setting.mTag = TRUETYPE_TAG('c', 'l', 'i', 'g'); setting.mTag = TRUETYPE_TAG('c', 'l', 'i', 'g');
setting.mValue = 0; setting.mValue = 0;
aStyle->featureSettings.AppendElement(setting); aStyle->featureSettings.AppendElement(setting);
} else if (variantLigatures & NS_FONT_VARIANT_LIGATURES_NONE) { } else if (variantLigatures & StyleFontVariantLigatures::NONE) {
// liga already disabled, need to disable dlig, hlig, calt, clig // liga already disabled, need to disable dlig, hlig, calt, clig
setting.mValue = 0; setting.mValue = 0;
setting.mTag = TRUETYPE_TAG('d', 'l', 'i', 'g'); setting.mTag = TRUETYPE_TAG('d', 'l', 'i', 'g');
@ -229,8 +228,8 @@ void nsFont::AddFontFeaturesToStyle(gfxFontStyle* aStyle,
// -- numeric // -- numeric
if (variantNumeric) { if (variantNumeric) {
AddFontFeaturesBitmask(variantNumeric, NS_FONT_VARIANT_NUMERIC_LINING, AddFontFeaturesBitmask(variantNumeric, StyleFontVariantNumeric::LINING_NUMS,
NS_FONT_VARIANT_NUMERIC_ORDINAL, numericDefaults, StyleFontVariantNumeric::ORDINAL, numericDefaults,
aStyle->featureSettings); aStyle->featureSettings);
} }

View file

@ -44,7 +44,7 @@ struct nsFont final {
// Language system tag, to override document language; // Language system tag, to override document language;
// this is an OpenType "language system" tag represented as a 32-bit integer // this is an OpenType "language system" tag represented as a 32-bit integer
// (see http://www.microsoft.com/typography/otspec/languagetags.htm). // (see http://www.microsoft.com/typography/otspec/languagetags.htm).
uint32_t languageOverride = 0; mozilla::StyleFontLanguageOverride languageOverride{0};
// Font-selection/rendering properties corresponding to CSS font-style, // Font-selection/rendering properties corresponding to CSS font-style,
// font-weight, font-stretch. These are all 16-bit types. // font-weight, font-stretch. These are all 16-bit types.
@ -58,11 +58,14 @@ struct nsFont final {
mozilla::StyleFontVariantAlternates variantAlternates; mozilla::StyleFontVariantAlternates variantAlternates;
// Variant subproperties // Variant subproperties
uint16_t variantLigatures = NS_FONT_VARIANT_LIGATURES_NORMAL; mozilla::StyleFontVariantLigatures variantLigatures =
uint16_t variantEastAsian = NS_FONT_VARIANT_EAST_ASIAN_NORMAL; mozilla::StyleFontVariantLigatures::NORMAL;
mozilla::StyleFontVariantEastAsian variantEastAsian =
mozilla::StyleFontVariantEastAsian::NORMAL;
uint8_t variantCaps = NS_FONT_VARIANT_CAPS_NORMAL; uint8_t variantCaps = NS_FONT_VARIANT_CAPS_NORMAL;
uint8_t variantNumeric = NS_FONT_VARIANT_NUMERIC_NORMAL; mozilla::StyleFontVariantNumeric variantNumeric =
mozilla::StyleFontVariantNumeric::NORMAL;
uint8_t variantPosition = NS_FONT_VARIANT_POSITION_NORMAL; uint8_t variantPosition = NS_FONT_VARIANT_POSITION_NORMAL;
uint8_t variantWidth = NS_FONT_VARIANT_WIDTH_NORMAL; uint8_t variantWidth = NS_FONT_VARIANT_WIDTH_NORMAL;
StyleFontVariantEmoji variantEmoji = StyleFontVariantEmoji::Normal; StyleFontVariantEmoji variantEmoji = StyleFontVariantEmoji::Normal;

View file

@ -4700,7 +4700,7 @@ gfxFontStyle::gfxFontStyle()
: size(DEFAULT_PIXEL_FONT_SIZE), : size(DEFAULT_PIXEL_FONT_SIZE),
sizeAdjust(0.0f), sizeAdjust(0.0f),
baselineOffset(0.0f), baselineOffset(0.0f),
languageOverride(NO_FONT_LANGUAGE_OVERRIDE), languageOverride{0},
weight(FontWeight::NORMAL), weight(FontWeight::NORMAL),
stretch(FontStretch::NORMAL), stretch(FontStretch::NORMAL),
style(FontSlantStyle::NORMAL), style(FontSlantStyle::NORMAL),
@ -4723,7 +4723,7 @@ gfxFontStyle::gfxFontStyle(FontSlantStyle aStyle, FontWeight aWeight,
bool aAllowStyleSynthesis, bool aAllowStyleSynthesis,
bool aAllowSmallCapsSynthesis, bool aAllowSmallCapsSynthesis,
bool aUsePositionSynthesis, bool aUsePositionSynthesis,
uint32_t aLanguageOverride) StyleFontLanguageOverride aLanguageOverride)
: size(aSize), : size(aSize),
baselineOffset(0.0f), baselineOffset(0.0f),
languageOverride(aLanguageOverride), languageOverride(aLanguageOverride),

View file

@ -100,7 +100,8 @@ struct gfxFontStyle {
gfxFloat aSize, const FontSizeAdjust& aSizeAdjust, gfxFloat aSize, const FontSizeAdjust& aSizeAdjust,
bool aSystemFont, bool aPrinterFont, bool aWeightSynthesis, bool aSystemFont, bool aPrinterFont, bool aWeightSynthesis,
bool aStyleSynthesis, bool aSmallCapsSynthesis, bool aStyleSynthesis, bool aSmallCapsSynthesis,
bool aPositionSynthesis, uint32_t aLanguageOverride); bool aPositionSynthesis,
mozilla::StyleFontLanguageOverride aLanguageOverride);
// Features are composed of (1) features from style rules (2) features // Features are composed of (1) features from style rules (2) features
// from feature settings rules and (3) family-specific features. (1) and // from feature settings rules and (3) family-specific features. (1) and
// (3) are guaranteed to be mutually exclusive // (3) are guaranteed to be mutually exclusive
@ -146,7 +147,7 @@ struct gfxFontStyle {
// but the font in use does not explicitly support this; the author can // but the font in use does not explicitly support this; the author can
// use font-language-override to request the Serbian option in the font // use font-language-override to request the Serbian option in the font
// in order to get correct glyph shapes.) // in order to get correct glyph shapes.)
uint32_t languageOverride; mozilla::StyleFontLanguageOverride languageOverride;
// The Font{Weight,Stretch,SlantStyle} fields are each a 16-bit type. // The Font{Weight,Stretch,SlantStyle} fields are each a 16-bit type.

View file

@ -72,75 +72,6 @@
#define NS_FONT_VARIANT_CAPS_TITLING 5 #define NS_FONT_VARIANT_CAPS_TITLING 5
#define NS_FONT_VARIANT_CAPS_UNICASE 6 #define NS_FONT_VARIANT_CAPS_UNICASE 6
#define NS_FONT_VARIANT_EAST_ASIAN_NORMAL 0
#define NS_FONT_VARIANT_EAST_ASIAN_JIS78 (1 << 0)
#define NS_FONT_VARIANT_EAST_ASIAN_JIS83 (1 << 1)
#define NS_FONT_VARIANT_EAST_ASIAN_JIS90 (1 << 2)
#define NS_FONT_VARIANT_EAST_ASIAN_JIS04 (1 << 3)
#define NS_FONT_VARIANT_EAST_ASIAN_SIMPLIFIED (1 << 4)
#define NS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL (1 << 5)
#define NS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH (1 << 6)
#define NS_FONT_VARIANT_EAST_ASIAN_PROP_WIDTH (1 << 7)
#define NS_FONT_VARIANT_EAST_ASIAN_RUBY (1 << 8)
#define NS_FONT_VARIANT_EAST_ASIAN_COUNT 9
#define NS_FONT_VARIANT_EAST_ASIAN_VARIANT_MASK \
(NS_FONT_VARIANT_EAST_ASIAN_JIS78 | NS_FONT_VARIANT_EAST_ASIAN_JIS83 | \
NS_FONT_VARIANT_EAST_ASIAN_JIS90 | NS_FONT_VARIANT_EAST_ASIAN_JIS04 | \
NS_FONT_VARIANT_EAST_ASIAN_SIMPLIFIED | \
NS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL)
#define NS_FONT_VARIANT_EAST_ASIAN_WIDTH_MASK \
(NS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH | \
NS_FONT_VARIANT_EAST_ASIAN_PROP_WIDTH)
#define NS_FONT_VARIANT_LIGATURES_NORMAL 0
#define NS_FONT_VARIANT_LIGATURES_NONE (1 << 0)
#define NS_FONT_VARIANT_LIGATURES_COMMON (1 << 1)
#define NS_FONT_VARIANT_LIGATURES_NO_COMMON (1 << 2)
#define NS_FONT_VARIANT_LIGATURES_DISCRETIONARY (1 << 3)
#define NS_FONT_VARIANT_LIGATURES_NO_DISCRETIONARY (1 << 4)
#define NS_FONT_VARIANT_LIGATURES_HISTORICAL (1 << 5)
#define NS_FONT_VARIANT_LIGATURES_NO_HISTORICAL (1 << 6)
#define NS_FONT_VARIANT_LIGATURES_CONTEXTUAL (1 << 7)
#define NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL (1 << 8)
#define NS_FONT_VARIANT_LIGATURES_COUNT 9
#define NS_FONT_VARIANT_LIGATURES_COMMON_MASK \
(NS_FONT_VARIANT_LIGATURES_COMMON | NS_FONT_VARIANT_LIGATURES_NO_COMMON)
#define NS_FONT_VARIANT_LIGATURES_DISCRETIONARY_MASK \
(NS_FONT_VARIANT_LIGATURES_DISCRETIONARY | \
NS_FONT_VARIANT_LIGATURES_NO_DISCRETIONARY)
#define NS_FONT_VARIANT_LIGATURES_HISTORICAL_MASK \
(NS_FONT_VARIANT_LIGATURES_HISTORICAL | \
NS_FONT_VARIANT_LIGATURES_NO_HISTORICAL)
#define NS_FONT_VARIANT_LIGATURES_CONTEXTUAL_MASK \
NS_FONT_VARIANT_LIGATURES_CONTEXTUAL | NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL
#define NS_FONT_VARIANT_NUMERIC_NORMAL 0
#define NS_FONT_VARIANT_NUMERIC_LINING (1 << 0)
#define NS_FONT_VARIANT_NUMERIC_OLDSTYLE (1 << 1)
#define NS_FONT_VARIANT_NUMERIC_PROPORTIONAL (1 << 2)
#define NS_FONT_VARIANT_NUMERIC_TABULAR (1 << 3)
#define NS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS (1 << 4)
#define NS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS (1 << 5)
#define NS_FONT_VARIANT_NUMERIC_SLASHZERO (1 << 6)
#define NS_FONT_VARIANT_NUMERIC_ORDINAL (1 << 7)
#define NS_FONT_VARIANT_NUMERIC_COUNT 8
#define NS_FONT_VARIANT_NUMERIC_FIGURE_MASK \
NS_FONT_VARIANT_NUMERIC_LINING | NS_FONT_VARIANT_NUMERIC_OLDSTYLE
#define NS_FONT_VARIANT_NUMERIC_SPACING_MASK \
NS_FONT_VARIANT_NUMERIC_PROPORTIONAL | NS_FONT_VARIANT_NUMERIC_TABULAR
#define NS_FONT_VARIANT_NUMERIC_FRACTION_MASK \
NS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS | \
NS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS
#define NS_FONT_VARIANT_POSITION_NORMAL 0 #define NS_FONT_VARIANT_POSITION_NORMAL 0
#define NS_FONT_VARIANT_POSITION_SUPER 1 #define NS_FONT_VARIANT_POSITION_SUPER 1
#define NS_FONT_VARIANT_POSITION_SUB 2 #define NS_FONT_VARIANT_POSITION_SUB 2

View file

@ -188,8 +188,8 @@ bool gfxGraphiteShaper::ShapeText(DrawTarget* aDrawTarget,
gfxFontEntry* entry = mFont->GetFontEntry(); gfxFontEntry* entry = mFont->GetFontEntry();
uint32_t grLang = 0; uint32_t grLang = 0;
if (style->languageOverride) { if (style->languageOverride._0) {
grLang = MakeGraphiteLangTag(style->languageOverride); grLang = MakeGraphiteLangTag(style->languageOverride._0);
} else if (entry->mLanguageOverride) { } else if (entry->mLanguageOverride) {
grLang = MakeGraphiteLangTag(entry->mLanguageOverride); grLang = MakeGraphiteLangTag(entry->mLanguageOverride);
} else if (aLanguage) { } else if (aLanguage) {

View file

@ -1538,8 +1538,8 @@ bool gfxHarfBuzzShaper::ShapeText(DrawTarget* aDrawTarget,
hb_buffer_set_script(mBuffer, scriptTag); hb_buffer_set_script(mBuffer, scriptTag);
hb_language_t language; hb_language_t language;
if (style->languageOverride) { if (style->languageOverride._0) {
language = hb_ot_tag_to_language(style->languageOverride); language = hb_ot_tag_to_language(style->languageOverride._0);
} else if (entry->mLanguageOverride) { } else if (entry->mLanguageOverride) {
language = hb_ot_tag_to_language(entry->mLanguageOverride); language = hb_ot_tag_to_language(entry->mLanguageOverride);
} else if (aLanguage) { } else if (aLanguage) {

View file

@ -624,6 +624,9 @@ cbindgen-types = [
{ gecko = "StyleAnchorScope", servo = "crate::values::computed::position::AnchorScope" }, { gecko = "StyleAnchorScope", servo = "crate::values::computed::position::AnchorScope" },
{ gecko = "StylePositionAnchor", servo = "crate::values::computed::position::PositionAnchor" }, { gecko = "StylePositionAnchor", servo = "crate::values::computed::position::PositionAnchor" },
{ gecko = "StylePositionVisibility", servo = "crate::values::computed::position::PositionVisibility" }, { gecko = "StylePositionVisibility", servo = "crate::values::computed::position::PositionVisibility" },
{ gecko = "StyleFontVariantEastAsian", servo = "crate::values::computed::font::FontVariantEastAsian" },
{ gecko = "StyleFontVariantLigatures", servo = "crate::values::computed::font::FontVariantLigatures" },
{ gecko = "StyleFontVariantNumeric", servo = "crate::values::computed::font::FontVariantNumeric" },
] ]
mapped-generic-types = [ mapped-generic-types = [

View file

@ -4,33 +4,6 @@
//! Various macro helpers. //! Various macro helpers.
macro_rules! exclusive_value {
(($value:ident, $set:expr) => $ident:path) => {
if $value.intersects($set) {
return Err(());
} else {
$ident
}
};
}
#[cfg(feature = "gecko")]
macro_rules! impl_gecko_keyword_conversions {
($name:ident, $utype:ty) => {
impl From<$utype> for $name {
fn from(bits: $utype) -> $name {
$name::from_gecko_keyword(bits)
}
}
impl From<$name> for $utype {
fn from(v: $name) -> $utype {
v.to_gecko_keyword()
}
}
};
}
macro_rules! trivial_to_computed_value { macro_rules! trivial_to_computed_value {
($name:ty) => { ($name:ty) => {
impl $crate::values::computed::ToComputedValue for $name { impl $crate::values::computed::ToComputedValue for $name {

View file

@ -564,20 +564,6 @@ impl Clone for ${style_struct.gecko_struct_name} {
} }
</%def> </%def>
<%def name="impl_simple_type_with_conversion(ident, gecko_ffi_name)">
#[allow(non_snake_case)]
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
self.${gecko_ffi_name} = From::from(v)
}
<% impl_simple_copy(ident, gecko_ffi_name) %>
#[allow(non_snake_case)]
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
From::from(self.${gecko_ffi_name})
}
</%def>
<%def name="impl_font_settings(ident, gecko_type, tag_type, value_type, gecko_value_type)"> <%def name="impl_font_settings(ident, gecko_type, tag_type, value_type, gecko_value_type)">
<% gecko_ffi_name = to_camel_case_lower(ident) %> <% gecko_ffi_name = to_camel_case_lower(ident) %>
@ -809,8 +795,7 @@ fn static_assert() {
<% skip_position_longhands = " ".join(x.ident for x in SIDES) %> <% skip_position_longhands = " ".join(x.ident for x in SIDES) %>
<%self:impl_trait style_struct_name="Position" <%self:impl_trait style_struct_name="Position"
skip_longhands="${skip_position_longhands} skip_longhands="${skip_position_longhands}">
masonry-auto-flow">
% for side in SIDES: % for side in SIDES:
<% impl_split_style_coord(side.ident, "mOffset", side.index) %> <% impl_split_style_coord(side.ident, "mOffset", side.index) %>
% endfor % endfor
@ -818,8 +803,6 @@ fn static_assert() {
debug_assert_ne!(v.0, crate::values::specified::align::AlignFlags::LEGACY); debug_assert_ne!(v.0, crate::values::specified::align::AlignFlags::LEGACY);
self.mJustifyItems.computed = v; self.mJustifyItems.computed = v;
} }
${impl_simple_type_with_conversion("masonry_auto_flow", "mMasonryAutoFlow")}
</%self:impl_trait> </%self:impl_trait>
<%self:impl_trait style_struct_name="Outline" <%self:impl_trait style_struct_name="Outline"
@ -959,10 +942,10 @@ fn static_assert() {
} }
${impl_simple_type_with_conversion("font_language_override", "mFont.languageOverride")} ${impl_simple("font_language_override", "mFont.languageOverride")}
${impl_simple_type_with_conversion("font_variant_ligatures", "mFont.variantLigatures")} ${impl_simple("font_variant_ligatures", "mFont.variantLigatures")}
${impl_simple_type_with_conversion("font_variant_east_asian", "mFont.variantEastAsian")} ${impl_simple("font_variant_east_asian", "mFont.variantEastAsian")}
${impl_simple_type_with_conversion("font_variant_numeric", "mFont.variantNumeric")} ${impl_simple("font_variant_numeric", "mFont.variantNumeric")}
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn clone__moz_min_font_size_ratio( pub fn clone__moz_min_font_size_ratio(

View file

@ -985,22 +985,6 @@ impl ToCss for FontLanguageOverride {
} }
} }
// FIXME(emilio): Make Gecko use the cbindgen'd fontLanguageOverride, then
// remove this.
#[cfg(feature = "gecko")]
impl From<u32> for FontLanguageOverride {
fn from(v: u32) -> Self {
unsafe { Self::from_u32(v) }
}
}
#[cfg(feature = "gecko")]
impl From<FontLanguageOverride> for u32 {
fn from(v: FontLanguageOverride) -> u32 {
v.0
}
}
impl ToComputedValue for specified::MozScriptMinSize { impl ToComputedValue for specified::MozScriptMinSize {
type ComputedValue = MozScriptMinSize; type ComputedValue = MozScriptMinSize;

View file

@ -26,7 +26,6 @@ use cssparser::{Parser, Token};
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps, MallocUnconditionalSizeOf}; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps, MallocUnconditionalSizeOf};
use std::fmt::{self, Write}; use std::fmt::{self, Write};
use style_traits::values::SequenceWriter;
use style_traits::{CssWriter, KeywordsCollectFn, ParseError}; use style_traits::{CssWriter, KeywordsCollectFn, ParseError};
use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss}; use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss};
@ -1249,453 +1248,148 @@ impl Parse for FontVariantAlternates {
} }
} }
macro_rules! impl_variant_east_asian { #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Parse, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
{ #[css(bitflags(
$( single = "normal",
$(#[$($meta:tt)+])* mixed="jis78,jis83,jis90,jis04,simplified,traditional,full-width,proportional-width,ruby",
$ident:ident / $css:expr => $gecko:ident = $value:expr, validate_mixed = "Self::validate_mixed_flags",
)+ ))]
} => { #[repr(C)]
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)] /// Variants for east asian variant
/// Variants for east asian variant pub struct FontVariantEastAsian(u16);
pub struct FontVariantEastAsian(u16); bitflags! {
bitflags! { impl FontVariantEastAsian: u16 {
impl FontVariantEastAsian: u16 { /// None of the features
/// None of the features const NORMAL = 0;
const NORMAL = 0; /// Enables rendering of JIS78 forms (OpenType feature: jp78)
$( const JIS78 = 1 << 0;
$(#[$($meta)+])* /// Enables rendering of JIS83 forms (OpenType feature: jp83).
const $ident = $value; const JIS83 = 1 << 1;
)+ /// Enables rendering of JIS90 forms (OpenType feature: jp90).
} const JIS90 = 1 << 2;
} /// Enables rendering of JIS2004 forms (OpenType feature: jp04).
const JIS04 = 1 << 3;
/// Enables rendering of simplified forms (OpenType feature: smpl).
const SIMPLIFIED = 1 << 4;
/// Enables rendering of traditional forms (OpenType feature: trad).
const TRADITIONAL = 1 << 5;
impl ToCss for FontVariantEastAsian { /// These values are exclusive with each other.
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result const JIS_GROUP = Self::JIS78.0 | Self::JIS83.0 | Self::JIS90.0 | Self::JIS04.0 | Self::SIMPLIFIED.0 | Self::TRADITIONAL.0;
where
W: Write,
{
if self.is_empty() {
return dest.write_str("normal");
}
let mut writer = SequenceWriter::new(dest, " "); /// Enables rendering of full-width variants (OpenType feature: fwid).
$( const FULL_WIDTH = 1 << 6;
if self.intersects(Self::$ident) { /// Enables rendering of proportionally-spaced variants (OpenType feature: pwid).
writer.raw_item($css)?; const PROPORTIONAL_WIDTH = 1 << 7;
} /// Enables display of ruby variant glyphs (OpenType feature: ruby).
)+ const RUBY = 1 << 8;
Ok(())
}
}
/// Asserts that all variant-east-asian matches its NS_FONT_VARIANT_EAST_ASIAN_* value.
#[cfg(feature = "gecko")]
#[inline]
pub fn assert_variant_east_asian_matches() {
use crate::gecko_bindings::structs;
$(
debug_assert_eq!(structs::$gecko as u16, FontVariantEastAsian::$ident.bits());
)+
}
impl SpecifiedValueInfo for FontVariantEastAsian {
fn collect_completion_keywords(f: KeywordsCollectFn) {
f(&["normal", $($css,)+]);
}
}
} }
} }
impl_variant_east_asian! {
/// Enables rendering of JIS78 forms (OpenType feature: jp78)
JIS78 / "jis78" => NS_FONT_VARIANT_EAST_ASIAN_JIS78 = 0x01,
/// Enables rendering of JIS83 forms (OpenType feature: jp83).
JIS83 / "jis83" => NS_FONT_VARIANT_EAST_ASIAN_JIS83 = 0x02,
/// Enables rendering of JIS90 forms (OpenType feature: jp90).
JIS90 / "jis90" => NS_FONT_VARIANT_EAST_ASIAN_JIS90 = 0x04,
/// Enables rendering of JIS2004 forms (OpenType feature: jp04).
JIS04 / "jis04" => NS_FONT_VARIANT_EAST_ASIAN_JIS04 = 0x08,
/// Enables rendering of simplified forms (OpenType feature: smpl).
SIMPLIFIED / "simplified" => NS_FONT_VARIANT_EAST_ASIAN_SIMPLIFIED = 0x10,
/// Enables rendering of traditional forms (OpenType feature: trad).
TRADITIONAL / "traditional" => NS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL = 0x20,
/// Enables rendering of full-width variants (OpenType feature: fwid).
FULL_WIDTH / "full-width" => NS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH = 0x40,
/// Enables rendering of proportionally-spaced variants (OpenType feature: pwid).
PROPORTIONAL_WIDTH / "proportional-width" => NS_FONT_VARIANT_EAST_ASIAN_PROP_WIDTH = 0x80,
/// Enables display of ruby variant glyphs (OpenType feature: ruby).
RUBY / "ruby" => NS_FONT_VARIANT_EAST_ASIAN_RUBY = 0x100,
}
#[cfg(feature = "gecko")]
impl FontVariantEastAsian { impl FontVariantEastAsian {
/// Obtain a specified value from a Gecko keyword value /// The number of variants.
/// pub const COUNT: usize = 9;
/// Intended for use with presentation attributes, not style structs
pub fn from_gecko_keyword(kw: u16) -> Self {
Self::from_bits_truncate(kw)
}
/// Transform into gecko keyword fn validate_mixed_flags(&self) -> bool {
pub fn to_gecko_keyword(self) -> u16 { if self.contains(Self::FULL_WIDTH | Self::PROPORTIONAL_WIDTH) {
self.bits() // full-width and proportional-width are exclusive with each other.
return false;
}
let jis = self.intersection(Self::JIS_GROUP);
if !jis.is_empty() && !jis.bits().is_power_of_two() {
return false;
}
true
} }
} }
#[cfg(feature = "gecko")] #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Parse, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
impl_gecko_keyword_conversions!(FontVariantEastAsian, u16); #[css(bitflags(
single = "normal,none",
impl Parse for FontVariantEastAsian { mixed="common-ligatures,no-common-ligatures,discretionary-ligatures,no-discretionary-ligatures,historical-ligatures,no-historical-ligatures,contextual,no-contextual",
/// normal | [ <east-asian-variant-values> || <east-asian-width-values> || ruby ] validate_mixed = "Self::validate_mixed_flags",
/// <east-asian-variant-values> = [ jis78 | jis83 | jis90 | jis04 | simplified | traditional ] ))]
/// <east-asian-width-values> = [ full-width | proportional-width ] #[repr(C)]
fn parse<'i, 't>( /// Variants of ligatures
_context: &ParserContext, pub struct FontVariantLigatures(u16);
input: &mut Parser<'i, 't>, bitflags! {
) -> Result<Self, ParseError<'i>> { impl FontVariantLigatures: u16 {
let mut result = Self::empty(); /// Specifies that common default features are enabled
const NORMAL = 0;
if input /// Specifies that no features are enabled;
.try_parse(|input| input.expect_ident_matching("normal")) const NONE = 1;
.is_ok() /// Enables display of common ligatures
{ const COMMON_LIGATURES = 1 << 1;
return Ok(result); /// Disables display of common ligatures
} const NO_COMMON_LIGATURES = 1 << 2;
/// Enables display of discretionary ligatures
while let Ok(flag) = input.try_parse(|input| { const DISCRETIONARY_LIGATURES = 1 << 3;
Ok( /// Disables display of discretionary ligatures
match_ignore_ascii_case! { &input.expect_ident().map_err(|_| ())?, const NO_DISCRETIONARY_LIGATURES = 1 << 4;
"jis78" => /// Enables display of historical ligatures
exclusive_value!((result, Self::JIS78 | Self::JIS83 | const HISTORICAL_LIGATURES = 1 << 5;
Self::JIS90 | Self::JIS04 | /// Disables display of historical ligatures
Self::SIMPLIFIED | Self::TRADITIONAL const NO_HISTORICAL_LIGATURES = 1 << 6;
) => Self::JIS78), /// Enables display of contextual alternates
"jis83" => const CONTEXTUAL = 1 << 7;
exclusive_value!((result, Self::JIS78 | Self::JIS83 | /// Disables display of contextual alternates
Self::JIS90 | Self::JIS04 | const NO_CONTEXTUAL = 1 << 8;
Self::SIMPLIFIED | Self::TRADITIONAL
) => Self::JIS83),
"jis90" =>
exclusive_value!((result, Self::JIS78 | Self::JIS83 |
Self::JIS90 | Self::JIS04 |
Self::SIMPLIFIED | Self::TRADITIONAL
) => Self::JIS90),
"jis04" =>
exclusive_value!((result, Self::JIS78 | Self::JIS83 |
Self::JIS90 | Self::JIS04 |
Self::SIMPLIFIED | Self::TRADITIONAL
) => Self::JIS04),
"simplified" =>
exclusive_value!((result, Self::JIS78 | Self::JIS83 |
Self::JIS90 | Self::JIS04 |
Self::SIMPLIFIED | Self::TRADITIONAL
) => Self::SIMPLIFIED),
"traditional" =>
exclusive_value!((result, Self::JIS78 | Self::JIS83 |
Self::JIS90 | Self::JIS04 |
Self::SIMPLIFIED | Self::TRADITIONAL
) => Self::TRADITIONAL),
"full-width" =>
exclusive_value!((result, Self::FULL_WIDTH |
Self::PROPORTIONAL_WIDTH
) => Self::FULL_WIDTH),
"proportional-width" =>
exclusive_value!((result, Self::FULL_WIDTH |
Self::PROPORTIONAL_WIDTH
) => Self::PROPORTIONAL_WIDTH),
"ruby" =>
exclusive_value!((result, Self::RUBY) => Self::RUBY),
_ => return Err(()),
},
)
}) {
result.insert(flag);
}
if !result.is_empty() {
Ok(result)
} else {
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
}
} }
} }
macro_rules! impl_variant_ligatures {
{
$(
$(#[$($meta:tt)+])*
$ident:ident / $css:expr => $gecko:ident = $value:expr,
)+
} => {
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
/// Variants of ligatures
pub struct FontVariantLigatures(u16);
bitflags! {
impl FontVariantLigatures: u16 {
/// Specifies that common default features are enabled
const NORMAL = 0;
$(
$(#[$($meta)+])*
const $ident = $value;
)+
}
}
impl ToCss for FontVariantLigatures {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
if self.is_empty() {
return dest.write_str("normal");
}
if self.contains(FontVariantLigatures::NONE) {
return dest.write_str("none");
}
let mut writer = SequenceWriter::new(dest, " ");
$(
if self.intersects(FontVariantLigatures::$ident) {
writer.raw_item($css)?;
}
)+
Ok(())
}
}
/// Asserts that all variant-east-asian matches its NS_FONT_VARIANT_EAST_ASIAN_* value.
#[cfg(feature = "gecko")]
#[inline]
pub fn assert_variant_ligatures_matches() {
use crate::gecko_bindings::structs;
$(
debug_assert_eq!(structs::$gecko as u16, FontVariantLigatures::$ident.bits());
)+
}
impl SpecifiedValueInfo for FontVariantLigatures {
fn collect_completion_keywords(f: KeywordsCollectFn) {
f(&["normal", $($css,)+]);
}
}
}
}
impl_variant_ligatures! {
/// Specifies that all types of ligatures and contextual forms
/// covered by this property are explicitly disabled
NONE / "none" => NS_FONT_VARIANT_LIGATURES_NONE = 0x01,
/// Enables display of common ligatures
COMMON_LIGATURES / "common-ligatures" => NS_FONT_VARIANT_LIGATURES_COMMON = 0x02,
/// Disables display of common ligatures
NO_COMMON_LIGATURES / "no-common-ligatures" => NS_FONT_VARIANT_LIGATURES_NO_COMMON = 0x04,
/// Enables display of discretionary ligatures
DISCRETIONARY_LIGATURES / "discretionary-ligatures" => NS_FONT_VARIANT_LIGATURES_DISCRETIONARY = 0x08,
/// Disables display of discretionary ligatures
NO_DISCRETIONARY_LIGATURES / "no-discretionary-ligatures" => NS_FONT_VARIANT_LIGATURES_NO_DISCRETIONARY = 0x10,
/// Enables display of historical ligatures
HISTORICAL_LIGATURES / "historical-ligatures" => NS_FONT_VARIANT_LIGATURES_HISTORICAL = 0x20,
/// Disables display of historical ligatures
NO_HISTORICAL_LIGATURES / "no-historical-ligatures" => NS_FONT_VARIANT_LIGATURES_NO_HISTORICAL = 0x40,
/// Enables display of contextual alternates
CONTEXTUAL / "contextual" => NS_FONT_VARIANT_LIGATURES_CONTEXTUAL = 0x80,
/// Disables display of contextual alternates
NO_CONTEXTUAL / "no-contextual" => NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL = 0x100,
}
#[cfg(feature = "gecko")]
impl FontVariantLigatures { impl FontVariantLigatures {
/// Obtain a specified value from a Gecko keyword value /// The number of variants.
/// pub const COUNT: usize = 9;
/// Intended for use with presentation attributes, not style structs
pub fn from_gecko_keyword(kw: u16) -> Self {
Self::from_bits_truncate(kw)
}
/// Transform into gecko keyword fn validate_mixed_flags(&self) -> bool {
pub fn to_gecko_keyword(self) -> u16 { // Mixing a value and its disabling value is forbidden.
self.bits() if self.contains(Self::COMMON_LIGATURES | Self::NO_COMMON_LIGATURES) ||
} self.contains(Self::DISCRETIONARY_LIGATURES | Self::NO_DISCRETIONARY_LIGATURES) ||
} self.contains(Self::HISTORICAL_LIGATURES | Self::NO_HISTORICAL_LIGATURES) ||
self.contains(Self::CONTEXTUAL | Self::NO_CONTEXTUAL)
#[cfg(feature = "gecko")]
impl_gecko_keyword_conversions!(FontVariantLigatures, u16);
impl Parse for FontVariantLigatures {
/// normal | none |
/// [ <common-lig-values> ||
/// <discretionary-lig-values> ||
/// <historical-lig-values> ||
/// <contextual-alt-values> ]
/// <common-lig-values> = [ common-ligatures | no-common-ligatures ]
/// <discretionary-lig-values> = [ discretionary-ligatures | no-discretionary-ligatures ]
/// <historical-lig-values> = [ historical-ligatures | no-historical-ligatures ]
/// <contextual-alt-values> = [ contextual | no-contextual ]
fn parse<'i, 't>(
_context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
let mut result = Self::empty();
if input
.try_parse(|input| input.expect_ident_matching("normal"))
.is_ok()
{ {
return Ok(result); return false;
}
if input
.try_parse(|input| input.expect_ident_matching("none"))
.is_ok()
{
return Ok(Self::NONE);
}
while let Ok(flag) = input.try_parse(|input| {
Ok(
match_ignore_ascii_case! { &input.expect_ident().map_err(|_| ())?,
"common-ligatures" =>
exclusive_value!((result, Self::COMMON_LIGATURES |
Self::NO_COMMON_LIGATURES
) => Self::COMMON_LIGATURES),
"no-common-ligatures" =>
exclusive_value!((result, Self::COMMON_LIGATURES |
Self::NO_COMMON_LIGATURES
) => Self::NO_COMMON_LIGATURES),
"discretionary-ligatures" =>
exclusive_value!((result, Self::DISCRETIONARY_LIGATURES |
Self::NO_DISCRETIONARY_LIGATURES
) => Self::DISCRETIONARY_LIGATURES),
"no-discretionary-ligatures" =>
exclusive_value!((result, Self::DISCRETIONARY_LIGATURES |
Self::NO_DISCRETIONARY_LIGATURES
) => Self::NO_DISCRETIONARY_LIGATURES),
"historical-ligatures" =>
exclusive_value!((result, Self::HISTORICAL_LIGATURES |
Self::NO_HISTORICAL_LIGATURES
) => Self::HISTORICAL_LIGATURES),
"no-historical-ligatures" =>
exclusive_value!((result, Self::HISTORICAL_LIGATURES |
Self::NO_HISTORICAL_LIGATURES
) => Self::NO_HISTORICAL_LIGATURES),
"contextual" =>
exclusive_value!((result, Self::CONTEXTUAL |
Self::NO_CONTEXTUAL
) => Self::CONTEXTUAL),
"no-contextual" =>
exclusive_value!((result, Self::CONTEXTUAL |
Self::NO_CONTEXTUAL
) => Self::NO_CONTEXTUAL),
_ => return Err(()),
},
)
}) {
result.insert(flag);
}
if !result.is_empty() {
Ok(result)
} else {
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
} }
true
} }
} }
macro_rules! impl_variant_numeric { /// Variants of numeric values
{ #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Parse, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
$( #[css(bitflags(
$(#[$($meta:tt)+])* single = "normal",
$ident:ident / $css:expr => $gecko:ident = $value:expr, mixed="lining-nums,oldstyle-nums,proportional-nums,tabular-nums,diagonal-fractions,stacked-fractions,ordinal,slashed-zero",
)+ validate_mixed = "Self::validate_mixed_flags",
} => { ))]
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)] #[repr(C)]
/// Variants of numeric values pub struct FontVariantNumeric(u8);
pub struct FontVariantNumeric(u8); bitflags! {
bitflags! { impl FontVariantNumeric : u8 {
impl FontVariantNumeric: u8 { /// Specifies that common default features are enabled
/// None of other variants are enabled. const NORMAL = 0;
const NORMAL = 0; /// Enables display of lining numerals.
$( const LINING_NUMS = 1 << 0;
$(#[$($meta)+])* /// Enables display of old-style numerals.
const $ident = $value; const OLDSTYLE_NUMS = 1 << 1;
)+ /// Enables display of proportional numerals.
} const PROPORTIONAL_NUMS = 1 << 2;
} /// Enables display of tabular numerals.
const TABULAR_NUMS = 1 << 3;
impl ToCss for FontVariantNumeric { /// Enables display of lining diagonal fractions.
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result const DIAGONAL_FRACTIONS = 1 << 4;
where /// Enables display of lining stacked fractions.
W: Write, const STACKED_FRACTIONS = 1 << 5;
{ /// Enables display of slashed zeros.
if self.is_empty() { const SLASHED_ZERO = 1 << 6;
return dest.write_str("normal"); /// Enables display of letter forms used with ordinal numbers.
} const ORDINAL = 1 << 7;
let mut writer = SequenceWriter::new(dest, " ");
$(
if self.intersects(FontVariantNumeric::$ident) {
writer.raw_item($css)?;
}
)+
Ok(())
}
}
/// Asserts that all variant-east-asian matches its NS_FONT_VARIANT_EAST_ASIAN_* value.
#[cfg(feature = "gecko")]
#[inline]
pub fn assert_variant_numeric_matches() {
use crate::gecko_bindings::structs;
$(
debug_assert_eq!(structs::$gecko as u8, FontVariantNumeric::$ident.bits());
)+
}
impl SpecifiedValueInfo for FontVariantNumeric {
fn collect_completion_keywords(f: KeywordsCollectFn) {
f(&["normal", $($css,)+]);
}
}
} }
} }
impl_variant_numeric! {
/// Enables display of lining numerals.
LINING_NUMS / "lining-nums" => NS_FONT_VARIANT_NUMERIC_LINING = 0x01,
/// Enables display of old-style numerals.
OLDSTYLE_NUMS / "oldstyle-nums" => NS_FONT_VARIANT_NUMERIC_OLDSTYLE = 0x02,
/// Enables display of proportional numerals.
PROPORTIONAL_NUMS / "proportional-nums" => NS_FONT_VARIANT_NUMERIC_PROPORTIONAL = 0x04,
/// Enables display of tabular numerals.
TABULAR_NUMS / "tabular-nums" => NS_FONT_VARIANT_NUMERIC_TABULAR = 0x08,
/// Enables display of lining diagonal fractions.
DIAGONAL_FRACTIONS / "diagonal-fractions" => NS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS = 0x10,
/// Enables display of lining stacked fractions.
STACKED_FRACTIONS / "stacked-fractions" => NS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS = 0x20,
/// Enables display of letter forms used with ordinal numbers.
ORDINAL / "ordinal" => NS_FONT_VARIANT_NUMERIC_ORDINAL = 0x80,
/// Enables display of slashed zeros.
SLASHED_ZERO / "slashed-zero" => NS_FONT_VARIANT_NUMERIC_SLASHZERO = 0x40,
}
#[cfg(feature = "gecko")]
impl FontVariantNumeric { impl FontVariantNumeric {
/// Obtain a specified value from a Gecko keyword value /// The number of variants.
/// pub const COUNT: usize = 8;
/// Intended for use with presentation attributes, not style structs
pub fn from_gecko_keyword(kw: u8) -> Self {
Self::from_bits_truncate(kw)
}
/// Transform into gecko keyword
pub fn to_gecko_keyword(self) -> u8 {
self.bits()
}
}
#[cfg(feature = "gecko")]
impl_gecko_keyword_conversions!(FontVariantNumeric, u8);
impl Parse for FontVariantNumeric {
/// normal | /// normal |
/// [ <numeric-figure-values> || /// [ <numeric-figure-values> ||
/// <numeric-spacing-values> || /// <numeric-spacing-values> ||
@ -1705,62 +1399,14 @@ impl Parse for FontVariantNumeric {
/// <numeric-figure-values> = [ lining-nums | oldstyle-nums ] /// <numeric-figure-values> = [ lining-nums | oldstyle-nums ]
/// <numeric-spacing-values> = [ proportional-nums | tabular-nums ] /// <numeric-spacing-values> = [ proportional-nums | tabular-nums ]
/// <numeric-fraction-values> = [ diagonal-fractions | stacked-fractions ] /// <numeric-fraction-values> = [ diagonal-fractions | stacked-fractions ]
fn parse<'i, 't>( fn validate_mixed_flags(&self) -> bool {
_context: &ParserContext, if self.contains(Self::LINING_NUMS | Self::OLDSTYLE_NUMS) ||
input: &mut Parser<'i, 't>, self.contains(Self::PROPORTIONAL_NUMS | Self::TABULAR_NUMS) ||
) -> Result<Self, ParseError<'i>> { self.contains(Self::DIAGONAL_FRACTIONS | Self::STACKED_FRACTIONS)
let mut result = Self::empty();
if input
.try_parse(|input| input.expect_ident_matching("normal"))
.is_ok()
{ {
return Ok(result); return false;
}
while let Ok(flag) = input.try_parse(|input| {
Ok(
match_ignore_ascii_case! { &input.expect_ident().map_err(|_| ())?,
"ordinal" =>
exclusive_value!((result, Self::ORDINAL) => Self::ORDINAL),
"slashed-zero" =>
exclusive_value!((result, Self::SLASHED_ZERO) => Self::SLASHED_ZERO),
"lining-nums" =>
exclusive_value!((result, Self::LINING_NUMS |
Self::OLDSTYLE_NUMS
) => Self::LINING_NUMS),
"oldstyle-nums" =>
exclusive_value!((result, Self::LINING_NUMS |
Self::OLDSTYLE_NUMS
) => Self::OLDSTYLE_NUMS),
"proportional-nums" =>
exclusive_value!((result, Self::PROPORTIONAL_NUMS |
Self::TABULAR_NUMS
) => Self::PROPORTIONAL_NUMS),
"tabular-nums" =>
exclusive_value!((result, Self::PROPORTIONAL_NUMS |
Self::TABULAR_NUMS
) => Self::TABULAR_NUMS),
"diagonal-fractions" =>
exclusive_value!((result, Self::DIAGONAL_FRACTIONS |
Self::STACKED_FRACTIONS
) => Self::DIAGONAL_FRACTIONS),
"stacked-fractions" =>
exclusive_value!((result, Self::DIAGONAL_FRACTIONS |
Self::STACKED_FRACTIONS
) => Self::STACKED_FRACTIONS),
_ => return Err(()),
},
)
}) {
result.insert(flag);
}
if !result.is_empty() {
Ok(result)
} else {
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
} }
true
} }
} }

View file

@ -100,6 +100,10 @@ include = [
"CaptionSide", "CaptionSide",
"FontSizeAdjust", "FontSizeAdjust",
"FontPalette", "FontPalette",
"FontLanguageOverride",
"FontVariantEastAsian",
"FontVariantLigatures",
"FontVariantNumeric",
"ComputedFontStretchRange", "ComputedFontStretchRange",
"ComputedFontStyleDescriptor", "ComputedFontStyleDescriptor",
"ComputedFontWeightRange", "ComputedFontWeightRange",

View file

@ -208,8 +208,6 @@ pub unsafe extern "C" fn Servo_Initialize(
// Perform some debug-only runtime assertions. // Perform some debug-only runtime assertions.
origin_flags::assert_flags_match(); origin_flags::assert_flags_match();
traversal_flags::assert_traversal_flags_match(); traversal_flags::assert_traversal_flags_match();
specified::font::assert_variant_east_asian_matches();
specified::font::assert_variant_ligatures_matches();
DUMMY_URL_DATA = dummy_url_data; DUMMY_URL_DATA = dummy_url_data;
DUMMY_CHROME_URL_DATA = dummy_chrome_url_data; DUMMY_CHROME_URL_DATA = dummy_chrome_url_data;