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
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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 = [
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,10 @@ include = [
|
||||||
"CaptionSide",
|
"CaptionSide",
|
||||||
"FontSizeAdjust",
|
"FontSizeAdjust",
|
||||||
"FontPalette",
|
"FontPalette",
|
||||||
|
"FontLanguageOverride",
|
||||||
|
"FontVariantEastAsian",
|
||||||
|
"FontVariantLigatures",
|
||||||
|
"FontVariantNumeric",
|
||||||
"ComputedFontStretchRange",
|
"ComputedFontStretchRange",
|
||||||
"ComputedFontStyleDescriptor",
|
"ComputedFontStyleDescriptor",
|
||||||
"ComputedFontWeightRange",
|
"ComputedFontWeightRange",
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue