forked from mirrors/gecko-dev
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:
parent
6022986b97
commit
4b8f8f4639
14 changed files with 174 additions and 649 deletions
|
|
@ -68,9 +68,9 @@ nsFont::MaxDifference nsFont::CalcDifference(const nsFont& aOther) const {
|
|||
// mapping from bitflag to font feature tag/value pair
|
||||
//
|
||||
// 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[] = {
|
||||
{TRUETYPE_TAG('j', 'p', '7', '8'), 1},
|
||||
{TRUETYPE_TAG('j', 'p', '8', '3'), 1},
|
||||
|
|
@ -83,10 +83,10 @@ const gfxFontFeature eastAsianDefaults[] = {
|
|||
{TRUETYPE_TAG('r', 'u', 'b', 'y'), 1}};
|
||||
|
||||
static_assert(MOZ_ARRAY_LENGTH(eastAsianDefaults) ==
|
||||
NS_FONT_VARIANT_EAST_ASIAN_COUNT,
|
||||
StyleFontVariantEastAsian::COUNT,
|
||||
"eastAsianDefaults[] should be correct");
|
||||
|
||||
// NS_FONT_VARIANT_LIGATURES_xxx values
|
||||
// StyleFontVariantLigatures::xxx values
|
||||
const gfxFontFeature ligDefaults[] = {
|
||||
{TRUETYPE_TAG('l', 'i', 'g', 'a'), 0}, // none value means all off
|
||||
{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'), 0}};
|
||||
|
||||
static_assert(MOZ_ARRAY_LENGTH(ligDefaults) == NS_FONT_VARIANT_LIGATURES_COUNT,
|
||||
static_assert(MOZ_ARRAY_LENGTH(ligDefaults) == StyleFontVariantLigatures::COUNT,
|
||||
"ligDefaults[] should be correct");
|
||||
|
||||
// NS_FONT_VARIANT_NUMERIC_xxx values
|
||||
// StyleFontVariantNumeric::xxx values
|
||||
const gfxFontFeature numericDefaults[] = {
|
||||
{TRUETYPE_TAG('l', '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}};
|
||||
|
||||
static_assert(MOZ_ARRAY_LENGTH(numericDefaults) ==
|
||||
NS_FONT_VARIANT_NUMERIC_COUNT,
|
||||
StyleFontVariantNumeric::COUNT,
|
||||
"numericDefaults[] should be correct");
|
||||
|
||||
static void AddFontFeaturesBitmask(uint32_t aValue, uint32_t aMin,
|
||||
uint32_t aMax,
|
||||
const gfxFontFeature aFeatureDefaults[],
|
||||
template <typename T>
|
||||
static void AddFontFeaturesBitmask(T aValue, T aMin, T aMax,
|
||||
Span<const gfxFontFeature> aFeatureDefaults,
|
||||
nsTArray<gfxFontFeature>& aFeaturesOut)
|
||||
|
||||
{
|
||||
uint32_t i, m;
|
||||
|
||||
for (i = 0, m = aMin; m <= aMax; i++, m <<= 1) {
|
||||
if (m & aValue) {
|
||||
for (uint32_t i = 0, m = aMin._0; m <= aMax._0; i++, m <<= 1) {
|
||||
if (m & aValue._0) {
|
||||
const gfxFontFeature& feature = aFeatureDefaults[i];
|
||||
aFeaturesOut.AppendElement(feature);
|
||||
}
|
||||
|
|
@ -192,28 +190,29 @@ void nsFont::AddFontFeaturesToStyle(gfxFontStyle* aStyle,
|
|||
|
||||
// -- east-asian
|
||||
if (variantEastAsian) {
|
||||
AddFontFeaturesBitmask(variantEastAsian, NS_FONT_VARIANT_EAST_ASIAN_JIS78,
|
||||
NS_FONT_VARIANT_EAST_ASIAN_RUBY, eastAsianDefaults,
|
||||
AddFontFeaturesBitmask(variantEastAsian, StyleFontVariantEastAsian::JIS78,
|
||||
StyleFontVariantEastAsian::RUBY, eastAsianDefaults,
|
||||
aStyle->featureSettings);
|
||||
}
|
||||
|
||||
// -- ligatures
|
||||
if (variantLigatures) {
|
||||
AddFontFeaturesBitmask(variantLigatures, NS_FONT_VARIANT_LIGATURES_NONE,
|
||||
NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL, ligDefaults,
|
||||
aStyle->featureSettings);
|
||||
AddFontFeaturesBitmask(variantLigatures, StyleFontVariantLigatures::NONE,
|
||||
StyleFontVariantLigatures::NO_CONTEXTUAL,
|
||||
ligDefaults, aStyle->featureSettings);
|
||||
|
||||
if (variantLigatures & NS_FONT_VARIANT_LIGATURES_COMMON) {
|
||||
if (variantLigatures & StyleFontVariantLigatures::COMMON_LIGATURES) {
|
||||
// liga already enabled, need to enable clig also
|
||||
setting.mTag = TRUETYPE_TAG('c', 'l', 'i', 'g');
|
||||
setting.mValue = 1;
|
||||
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
|
||||
setting.mTag = TRUETYPE_TAG('c', 'l', 'i', 'g');
|
||||
setting.mValue = 0;
|
||||
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
|
||||
setting.mValue = 0;
|
||||
setting.mTag = TRUETYPE_TAG('d', 'l', 'i', 'g');
|
||||
|
|
@ -229,8 +228,8 @@ void nsFont::AddFontFeaturesToStyle(gfxFontStyle* aStyle,
|
|||
|
||||
// -- numeric
|
||||
if (variantNumeric) {
|
||||
AddFontFeaturesBitmask(variantNumeric, NS_FONT_VARIANT_NUMERIC_LINING,
|
||||
NS_FONT_VARIANT_NUMERIC_ORDINAL, numericDefaults,
|
||||
AddFontFeaturesBitmask(variantNumeric, StyleFontVariantNumeric::LINING_NUMS,
|
||||
StyleFontVariantNumeric::ORDINAL, numericDefaults,
|
||||
aStyle->featureSettings);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ struct nsFont final {
|
|||
// Language system tag, to override document language;
|
||||
// this is an OpenType "language system" tag represented as a 32-bit integer
|
||||
// (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-weight, font-stretch. These are all 16-bit types.
|
||||
|
|
@ -58,11 +58,14 @@ struct nsFont final {
|
|||
mozilla::StyleFontVariantAlternates variantAlternates;
|
||||
|
||||
// Variant subproperties
|
||||
uint16_t variantLigatures = NS_FONT_VARIANT_LIGATURES_NORMAL;
|
||||
uint16_t variantEastAsian = NS_FONT_VARIANT_EAST_ASIAN_NORMAL;
|
||||
mozilla::StyleFontVariantLigatures variantLigatures =
|
||||
mozilla::StyleFontVariantLigatures::NORMAL;
|
||||
mozilla::StyleFontVariantEastAsian variantEastAsian =
|
||||
mozilla::StyleFontVariantEastAsian::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 variantWidth = NS_FONT_VARIANT_WIDTH_NORMAL;
|
||||
StyleFontVariantEmoji variantEmoji = StyleFontVariantEmoji::Normal;
|
||||
|
|
|
|||
|
|
@ -4700,7 +4700,7 @@ gfxFontStyle::gfxFontStyle()
|
|||
: size(DEFAULT_PIXEL_FONT_SIZE),
|
||||
sizeAdjust(0.0f),
|
||||
baselineOffset(0.0f),
|
||||
languageOverride(NO_FONT_LANGUAGE_OVERRIDE),
|
||||
languageOverride{0},
|
||||
weight(FontWeight::NORMAL),
|
||||
stretch(FontStretch::NORMAL),
|
||||
style(FontSlantStyle::NORMAL),
|
||||
|
|
@ -4723,7 +4723,7 @@ gfxFontStyle::gfxFontStyle(FontSlantStyle aStyle, FontWeight aWeight,
|
|||
bool aAllowStyleSynthesis,
|
||||
bool aAllowSmallCapsSynthesis,
|
||||
bool aUsePositionSynthesis,
|
||||
uint32_t aLanguageOverride)
|
||||
StyleFontLanguageOverride aLanguageOverride)
|
||||
: size(aSize),
|
||||
baselineOffset(0.0f),
|
||||
languageOverride(aLanguageOverride),
|
||||
|
|
|
|||
|
|
@ -100,7 +100,8 @@ struct gfxFontStyle {
|
|||
gfxFloat aSize, const FontSizeAdjust& aSizeAdjust,
|
||||
bool aSystemFont, bool aPrinterFont, bool aWeightSynthesis,
|
||||
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
|
||||
// from feature settings rules and (3) family-specific features. (1) and
|
||||
// (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
|
||||
// use font-language-override to request the Serbian option in the font
|
||||
// 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.
|
||||
|
||||
|
|
|
|||
|
|
@ -72,75 +72,6 @@
|
|||
#define NS_FONT_VARIANT_CAPS_TITLING 5
|
||||
#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_SUPER 1
|
||||
#define NS_FONT_VARIANT_POSITION_SUB 2
|
||||
|
|
|
|||
|
|
@ -188,8 +188,8 @@ bool gfxGraphiteShaper::ShapeText(DrawTarget* aDrawTarget,
|
|||
|
||||
gfxFontEntry* entry = mFont->GetFontEntry();
|
||||
uint32_t grLang = 0;
|
||||
if (style->languageOverride) {
|
||||
grLang = MakeGraphiteLangTag(style->languageOverride);
|
||||
if (style->languageOverride._0) {
|
||||
grLang = MakeGraphiteLangTag(style->languageOverride._0);
|
||||
} else if (entry->mLanguageOverride) {
|
||||
grLang = MakeGraphiteLangTag(entry->mLanguageOverride);
|
||||
} else if (aLanguage) {
|
||||
|
|
|
|||
|
|
@ -1538,8 +1538,8 @@ bool gfxHarfBuzzShaper::ShapeText(DrawTarget* aDrawTarget,
|
|||
hb_buffer_set_script(mBuffer, scriptTag);
|
||||
|
||||
hb_language_t language;
|
||||
if (style->languageOverride) {
|
||||
language = hb_ot_tag_to_language(style->languageOverride);
|
||||
if (style->languageOverride._0) {
|
||||
language = hb_ot_tag_to_language(style->languageOverride._0);
|
||||
} else if (entry->mLanguageOverride) {
|
||||
language = hb_ot_tag_to_language(entry->mLanguageOverride);
|
||||
} else if (aLanguage) {
|
||||
|
|
|
|||
|
|
@ -624,6 +624,9 @@ cbindgen-types = [
|
|||
{ gecko = "StyleAnchorScope", servo = "crate::values::computed::position::AnchorScope" },
|
||||
{ gecko = "StylePositionAnchor", servo = "crate::values::computed::position::PositionAnchor" },
|
||||
{ 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 = [
|
||||
|
|
|
|||
|
|
@ -4,33 +4,6 @@
|
|||
|
||||
//! 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 {
|
||||
($name:ty) => {
|
||||
impl $crate::values::computed::ToComputedValue for $name {
|
||||
|
|
|
|||
|
|
@ -564,20 +564,6 @@ impl Clone for ${style_struct.gecko_struct_name} {
|
|||
}
|
||||
</%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)">
|
||||
<% 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) %>
|
||||
<%self:impl_trait style_struct_name="Position"
|
||||
skip_longhands="${skip_position_longhands}
|
||||
masonry-auto-flow">
|
||||
skip_longhands="${skip_position_longhands}">
|
||||
% for side in SIDES:
|
||||
<% impl_split_style_coord(side.ident, "mOffset", side.index) %>
|
||||
% endfor
|
||||
|
|
@ -818,8 +803,6 @@ fn static_assert() {
|
|||
debug_assert_ne!(v.0, crate::values::specified::align::AlignFlags::LEGACY);
|
||||
self.mJustifyItems.computed = v;
|
||||
}
|
||||
|
||||
${impl_simple_type_with_conversion("masonry_auto_flow", "mMasonryAutoFlow")}
|
||||
</%self:impl_trait>
|
||||
|
||||
<%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_type_with_conversion("font_variant_ligatures", "mFont.variantLigatures")}
|
||||
${impl_simple_type_with_conversion("font_variant_east_asian", "mFont.variantEastAsian")}
|
||||
${impl_simple_type_with_conversion("font_variant_numeric", "mFont.variantNumeric")}
|
||||
${impl_simple("font_language_override", "mFont.languageOverride")}
|
||||
${impl_simple("font_variant_ligatures", "mFont.variantLigatures")}
|
||||
${impl_simple("font_variant_east_asian", "mFont.variantEastAsian")}
|
||||
${impl_simple("font_variant_numeric", "mFont.variantNumeric")}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn clone__moz_min_font_size_ratio(
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
type ComputedValue = MozScriptMinSize;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ use cssparser::{Parser, Token};
|
|||
#[cfg(feature = "gecko")]
|
||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps, MallocUnconditionalSizeOf};
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::values::SequenceWriter;
|
||||
use style_traits::{CssWriter, KeywordsCollectFn, ParseError};
|
||||
use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss};
|
||||
|
||||
|
|
@ -1249,453 +1248,148 @@ impl Parse for FontVariantAlternates {
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_variant_east_asian {
|
||||
{
|
||||
$(
|
||||
$(#[$($meta:tt)+])*
|
||||
$ident:ident / $css:expr => $gecko:ident = $value:expr,
|
||||
)+
|
||||
} => {
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||
/// Variants for east asian variant
|
||||
pub struct FontVariantEastAsian(u16);
|
||||
bitflags! {
|
||||
impl FontVariantEastAsian: u16 {
|
||||
/// None of the features
|
||||
const NORMAL = 0;
|
||||
$(
|
||||
$(#[$($meta)+])*
|
||||
const $ident = $value;
|
||||
)+
|
||||
}
|
||||
}
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Parse, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
|
||||
#[css(bitflags(
|
||||
single = "normal",
|
||||
mixed="jis78,jis83,jis90,jis04,simplified,traditional,full-width,proportional-width,ruby",
|
||||
validate_mixed = "Self::validate_mixed_flags",
|
||||
))]
|
||||
#[repr(C)]
|
||||
/// Variants for east asian variant
|
||||
pub struct FontVariantEastAsian(u16);
|
||||
bitflags! {
|
||||
impl FontVariantEastAsian: u16 {
|
||||
/// None of the features
|
||||
const NORMAL = 0;
|
||||
/// Enables rendering of JIS78 forms (OpenType feature: jp78)
|
||||
const JIS78 = 1 << 0;
|
||||
/// Enables rendering of JIS83 forms (OpenType feature: jp83).
|
||||
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 {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
if self.is_empty() {
|
||||
return dest.write_str("normal");
|
||||
}
|
||||
/// These values are exclusive with each other.
|
||||
const JIS_GROUP = Self::JIS78.0 | Self::JIS83.0 | Self::JIS90.0 | Self::JIS04.0 | Self::SIMPLIFIED.0 | Self::TRADITIONAL.0;
|
||||
|
||||
let mut writer = SequenceWriter::new(dest, " ");
|
||||
$(
|
||||
if self.intersects(Self::$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_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,)+]);
|
||||
}
|
||||
}
|
||||
/// Enables rendering of full-width variants (OpenType feature: fwid).
|
||||
const FULL_WIDTH = 1 << 6;
|
||||
/// Enables rendering of proportionally-spaced variants (OpenType feature: pwid).
|
||||
const PROPORTIONAL_WIDTH = 1 << 7;
|
||||
/// Enables display of ruby variant glyphs (OpenType feature: ruby).
|
||||
const RUBY = 1 << 8;
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
/// Obtain a specified value from a Gecko keyword value
|
||||
///
|
||||
/// Intended for use with presentation attributes, not style structs
|
||||
pub fn from_gecko_keyword(kw: u16) -> Self {
|
||||
Self::from_bits_truncate(kw)
|
||||
}
|
||||
/// The number of variants.
|
||||
pub const COUNT: usize = 9;
|
||||
|
||||
/// Transform into gecko keyword
|
||||
pub fn to_gecko_keyword(self) -> u16 {
|
||||
self.bits()
|
||||
fn validate_mixed_flags(&self) -> bool {
|
||||
if self.contains(Self::FULL_WIDTH | Self::PROPORTIONAL_WIDTH) {
|
||||
// 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")]
|
||||
impl_gecko_keyword_conversions!(FontVariantEastAsian, u16);
|
||||
|
||||
impl Parse for FontVariantEastAsian {
|
||||
/// normal | [ <east-asian-variant-values> || <east-asian-width-values> || ruby ]
|
||||
/// <east-asian-variant-values> = [ jis78 | jis83 | jis90 | jis04 | simplified | traditional ]
|
||||
/// <east-asian-width-values> = [ full-width | proportional-width ]
|
||||
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);
|
||||
}
|
||||
|
||||
while let Ok(flag) = input.try_parse(|input| {
|
||||
Ok(
|
||||
match_ignore_ascii_case! { &input.expect_ident().map_err(|_| ())?,
|
||||
"jis78" =>
|
||||
exclusive_value!((result, Self::JIS78 | Self::JIS83 |
|
||||
Self::JIS90 | Self::JIS04 |
|
||||
Self::SIMPLIFIED | Self::TRADITIONAL
|
||||
) => Self::JIS78),
|
||||
"jis83" =>
|
||||
exclusive_value!((result, Self::JIS78 | Self::JIS83 |
|
||||
Self::JIS90 | Self::JIS04 |
|
||||
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))
|
||||
}
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Parse, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
|
||||
#[css(bitflags(
|
||||
single = "normal,none",
|
||||
mixed="common-ligatures,no-common-ligatures,discretionary-ligatures,no-discretionary-ligatures,historical-ligatures,no-historical-ligatures,contextual,no-contextual",
|
||||
validate_mixed = "Self::validate_mixed_flags",
|
||||
))]
|
||||
#[repr(C)]
|
||||
/// Variants of ligatures
|
||||
pub struct FontVariantLigatures(u16);
|
||||
bitflags! {
|
||||
impl FontVariantLigatures: u16 {
|
||||
/// Specifies that common default features are enabled
|
||||
const NORMAL = 0;
|
||||
/// Specifies that no features are enabled;
|
||||
const NONE = 1;
|
||||
/// Enables display of common ligatures
|
||||
const COMMON_LIGATURES = 1 << 1;
|
||||
/// Disables display of common ligatures
|
||||
const NO_COMMON_LIGATURES = 1 << 2;
|
||||
/// Enables display of discretionary ligatures
|
||||
const DISCRETIONARY_LIGATURES = 1 << 3;
|
||||
/// Disables display of discretionary ligatures
|
||||
const NO_DISCRETIONARY_LIGATURES = 1 << 4;
|
||||
/// Enables display of historical ligatures
|
||||
const HISTORICAL_LIGATURES = 1 << 5;
|
||||
/// Disables display of historical ligatures
|
||||
const NO_HISTORICAL_LIGATURES = 1 << 6;
|
||||
/// Enables display of contextual alternates
|
||||
const CONTEXTUAL = 1 << 7;
|
||||
/// Disables display of contextual alternates
|
||||
const NO_CONTEXTUAL = 1 << 8;
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
/// Obtain a specified value from a Gecko keyword value
|
||||
///
|
||||
/// Intended for use with presentation attributes, not style structs
|
||||
pub fn from_gecko_keyword(kw: u16) -> Self {
|
||||
Self::from_bits_truncate(kw)
|
||||
}
|
||||
/// The number of variants.
|
||||
pub const COUNT: usize = 9;
|
||||
|
||||
/// Transform into gecko keyword
|
||||
pub fn to_gecko_keyword(self) -> u16 {
|
||||
self.bits()
|
||||
}
|
||||
}
|
||||
|
||||
#[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()
|
||||
fn validate_mixed_flags(&self) -> bool {
|
||||
// Mixing a value and its disabling value is forbidden.
|
||||
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)
|
||||
{
|
||||
return Ok(result);
|
||||
}
|
||||
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))
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_variant_numeric {
|
||||
{
|
||||
$(
|
||||
$(#[$($meta:tt)+])*
|
||||
$ident:ident / $css:expr => $gecko:ident = $value:expr,
|
||||
)+
|
||||
} => {
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
|
||||
/// Variants of numeric values
|
||||
pub struct FontVariantNumeric(u8);
|
||||
bitflags! {
|
||||
impl FontVariantNumeric: u8 {
|
||||
/// None of other variants are enabled.
|
||||
const NORMAL = 0;
|
||||
$(
|
||||
$(#[$($meta)+])*
|
||||
const $ident = $value;
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for FontVariantNumeric {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
if self.is_empty() {
|
||||
return dest.write_str("normal");
|
||||
}
|
||||
|
||||
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,)+]);
|
||||
}
|
||||
}
|
||||
/// Variants of numeric values
|
||||
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Parse, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
|
||||
#[css(bitflags(
|
||||
single = "normal",
|
||||
mixed="lining-nums,oldstyle-nums,proportional-nums,tabular-nums,diagonal-fractions,stacked-fractions,ordinal,slashed-zero",
|
||||
validate_mixed = "Self::validate_mixed_flags",
|
||||
))]
|
||||
#[repr(C)]
|
||||
pub struct FontVariantNumeric(u8);
|
||||
bitflags! {
|
||||
impl FontVariantNumeric : u8 {
|
||||
/// Specifies that common default features are enabled
|
||||
const NORMAL = 0;
|
||||
/// Enables display of lining numerals.
|
||||
const LINING_NUMS = 1 << 0;
|
||||
/// Enables display of old-style numerals.
|
||||
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;
|
||||
/// Enables display of lining diagonal fractions.
|
||||
const DIAGONAL_FRACTIONS = 1 << 4;
|
||||
/// Enables display of lining stacked fractions.
|
||||
const STACKED_FRACTIONS = 1 << 5;
|
||||
/// Enables display of slashed zeros.
|
||||
const SLASHED_ZERO = 1 << 6;
|
||||
/// Enables display of letter forms used with ordinal numbers.
|
||||
const ORDINAL = 1 << 7;
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
/// Obtain a specified value from a Gecko keyword value
|
||||
///
|
||||
/// Intended for use with presentation attributes, not style structs
|
||||
pub fn from_gecko_keyword(kw: u8) -> Self {
|
||||
Self::from_bits_truncate(kw)
|
||||
}
|
||||
/// The number of variants.
|
||||
pub const COUNT: usize = 8;
|
||||
|
||||
/// 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 |
|
||||
/// [ <numeric-figure-values> ||
|
||||
/// <numeric-spacing-values> ||
|
||||
|
|
@ -1705,62 +1399,14 @@ impl Parse for FontVariantNumeric {
|
|||
/// <numeric-figure-values> = [ lining-nums | oldstyle-nums ]
|
||||
/// <numeric-spacing-values> = [ proportional-nums | tabular-nums ]
|
||||
/// <numeric-fraction-values> = [ diagonal-fractions | stacked-fractions ]
|
||||
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()
|
||||
fn validate_mixed_flags(&self) -> bool {
|
||||
if self.contains(Self::LINING_NUMS | Self::OLDSTYLE_NUMS) ||
|
||||
self.contains(Self::PROPORTIONAL_NUMS | Self::TABULAR_NUMS) ||
|
||||
self.contains(Self::DIAGONAL_FRACTIONS | Self::STACKED_FRACTIONS)
|
||||
{
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
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))
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,10 @@ include = [
|
|||
"CaptionSide",
|
||||
"FontSizeAdjust",
|
||||
"FontPalette",
|
||||
"FontLanguageOverride",
|
||||
"FontVariantEastAsian",
|
||||
"FontVariantLigatures",
|
||||
"FontVariantNumeric",
|
||||
"ComputedFontStretchRange",
|
||||
"ComputedFontStyleDescriptor",
|
||||
"ComputedFontWeightRange",
|
||||
|
|
|
|||
|
|
@ -208,8 +208,6 @@ pub unsafe extern "C" fn Servo_Initialize(
|
|||
// Perform some debug-only runtime assertions.
|
||||
origin_flags::assert_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_CHROME_URL_DATA = dummy_chrome_url_data;
|
||||
|
|
|
|||
Loading…
Reference in a new issue