mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 549861 - reland font-variant subproperties with DOM-peer review. r=khuey
This commit is contained in:
parent
3d9c02c05e
commit
0eae803e8f
@ -897,6 +897,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(LockedFile, nsEventTargetSH,
|
||||
EVENTTARGET_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(CSSFontFeatureValuesRule, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
#ifdef MOZ_TIME_MANAGER
|
||||
NS_DEFINE_CLASSINFO_DATA(MozTimeManager, nsDOMGenericSH,
|
||||
@ -2266,6 +2268,10 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMLockedFile)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(CSSFontFeatureValuesRule, nsIDOMCSSFontFeatureValuesRule)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSFontFeatureValuesRule)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
#ifdef MOZ_TIME_MANAGER
|
||||
DOM_CLASSINFO_MAP_BEGIN(MozTimeManager, nsIDOMMozTimeManager)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozTimeManager)
|
||||
|
@ -232,6 +232,8 @@ DOMCI_CLASS(AsyncScrollEventDetail)
|
||||
|
||||
DOMCI_CLASS(LockedFile)
|
||||
|
||||
DOMCI_CLASS(CSSFontFeatureValuesRule)
|
||||
|
||||
#ifdef MOZ_TIME_MANAGER
|
||||
DOMCI_CLASS(MozTimeManager)
|
||||
#endif
|
||||
|
@ -69,6 +69,7 @@ interface nsIDOMCSSPrimitiveValue;
|
||||
interface nsIDOMCSSRule;
|
||||
interface nsIDOMCSSRuleList;
|
||||
interface nsIDOMMozCSSKeyframeRule;
|
||||
interface nsIDOMCSSFontFeatureValuesRule;
|
||||
interface nsIDOMCSSStyleSheet;
|
||||
interface nsIDOMCSSStyleDeclaration;
|
||||
interface nsIDOMCounter;
|
||||
|
@ -8,6 +8,7 @@ XPIDL_SOURCES += [
|
||||
'nsIDOMCSSCharsetRule.idl',
|
||||
'nsIDOMCSSConditionRule.idl',
|
||||
'nsIDOMCSSFontFaceRule.idl',
|
||||
'nsIDOMCSSFontFeatureValuesRule.idl',
|
||||
'nsIDOMCSSGroupingRule.idl',
|
||||
'nsIDOMCSSImportRule.idl',
|
||||
'nsIDOMCSSMediaRule.idl',
|
||||
|
@ -32,6 +32,7 @@ interface nsIDOMCSSRule : nsISupports
|
||||
const unsigned short MOZ_KEYFRAME_RULE = 8;
|
||||
const unsigned short NAMESPACE_RULE = 10;
|
||||
const unsigned short SUPPORTS_RULE = 12;
|
||||
const unsigned short FONT_FEATURE_VALUES_RULE = 14;
|
||||
|
||||
readonly attribute unsigned short type;
|
||||
attribute DOMString cssText;
|
||||
|
@ -115,6 +115,17 @@ PEMQExpectedFeatureValue=Found invalid value for media feature.
|
||||
PEBadFontBlockStart=Expected '{' to begin @font-face rule but found '%1$S'.
|
||||
PEBadFontBlockEnd=Expected '}' to end @font-face rule but found '%1$S'.
|
||||
PEAnonBoxNotAlone=Did not expect anonymous box.
|
||||
PEFFVUnexpectedEOF=Unexpected end of @font-feature-values rule.
|
||||
PEFFVBlockStart=Expected opening { of @font-feature-values rule but found '%1$S'.
|
||||
PEFFVValueSetStart=Expected opening { of feature value set but found '%1$S'.
|
||||
PEFFVNoFamily=Expected font family list for @font-feature-values rule but found '%1$S'.
|
||||
PEFFVUnexpectedBlockEnd=Expected '}' to end @font-feature-values rule but found '%1$S'.
|
||||
PEFFVUnknownFontVariantPropValue=Unknown font-variant property value '%1$S'.
|
||||
PEFFVExpectedIdent=Expected identifier but found '%1$S'.
|
||||
PEFFVExpectedValue=Expected non-negative integer value but found '%1$S'.
|
||||
PEFFVTooManyValues=Too many values for feature type '%1$S'.
|
||||
PEFFVGenericInFamilyList=Family list cannot contain generic font family name.
|
||||
PEFFVValueDefinitionTrailing=Expected end of value definition but found '%1$S'.
|
||||
PEBadDirValue=Expected 'ltr' or 'rtl' in direction selector but found '%1$S'.
|
||||
PESupportsConditionStartEOF2='not', '(', or function
|
||||
PESupportsConditionInParensEOF=')'
|
||||
|
@ -492,6 +492,7 @@ var interfaceNamesInGlobalScope =
|
||||
"CloseEvent",
|
||||
"IDBCursorWithValue",
|
||||
"CSSFontFaceRule",
|
||||
"CSSFontFeatureValuesRule",
|
||||
"XMLHttpRequestEventTarget",
|
||||
"CompositionEvent",
|
||||
"HTMLOutputElement",
|
||||
|
@ -11,8 +11,7 @@
|
||||
|
||||
nsFont::nsFont(const char* aName, uint8_t aStyle, uint8_t aVariant,
|
||||
uint16_t aWeight, int16_t aStretch, uint8_t aDecoration,
|
||||
nscoord aSize, float aSizeAdjust,
|
||||
const nsString* aLanguageOverride)
|
||||
nscoord aSize)
|
||||
{
|
||||
NS_ASSERTION(aName && IsASCII(nsDependentCString(aName)),
|
||||
"Must only pass ASCII names here");
|
||||
@ -24,16 +23,21 @@ nsFont::nsFont(const char* aName, uint8_t aStyle, uint8_t aVariant,
|
||||
stretch = aStretch;
|
||||
decorations = aDecoration;
|
||||
size = aSize;
|
||||
sizeAdjust = aSizeAdjust;
|
||||
if (aLanguageOverride) {
|
||||
languageOverride = *aLanguageOverride;
|
||||
}
|
||||
sizeAdjust = 0.0;
|
||||
kerning = NS_FONT_KERNING_AUTO;
|
||||
synthesis = NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE;
|
||||
|
||||
variantAlternates = 0;
|
||||
variantCaps = NS_FONT_VARIANT_CAPS_NORMAL;
|
||||
variantEastAsian = 0;
|
||||
variantLigatures = 0;
|
||||
variantNumeric = 0;
|
||||
variantPosition = NS_FONT_VARIANT_POSITION_NORMAL;
|
||||
}
|
||||
|
||||
nsFont::nsFont(const nsString& aName, uint8_t aStyle, uint8_t aVariant,
|
||||
nsFont::nsFont(const nsSubstring& aName, uint8_t aStyle, uint8_t aVariant,
|
||||
uint16_t aWeight, int16_t aStretch, uint8_t aDecoration,
|
||||
nscoord aSize, float aSizeAdjust,
|
||||
const nsString* aLanguageOverride)
|
||||
nscoord aSize)
|
||||
: name(aName)
|
||||
{
|
||||
style = aStyle;
|
||||
@ -43,10 +47,16 @@ nsFont::nsFont(const nsString& aName, uint8_t aStyle, uint8_t aVariant,
|
||||
stretch = aStretch;
|
||||
decorations = aDecoration;
|
||||
size = aSize;
|
||||
sizeAdjust = aSizeAdjust;
|
||||
if (aLanguageOverride) {
|
||||
languageOverride = *aLanguageOverride;
|
||||
}
|
||||
sizeAdjust = 0.0;
|
||||
kerning = NS_FONT_KERNING_AUTO;
|
||||
synthesis = NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE;
|
||||
|
||||
variantAlternates = 0;
|
||||
variantCaps = NS_FONT_VARIANT_CAPS_NORMAL;
|
||||
variantEastAsian = 0;
|
||||
variantLigatures = 0;
|
||||
variantNumeric = 0;
|
||||
variantPosition = NS_FONT_VARIANT_POSITION_NORMAL;
|
||||
}
|
||||
|
||||
nsFont::nsFont(const nsFont& aOther)
|
||||
@ -60,8 +70,18 @@ nsFont::nsFont(const nsFont& aOther)
|
||||
decorations = aOther.decorations;
|
||||
size = aOther.size;
|
||||
sizeAdjust = aOther.sizeAdjust;
|
||||
languageOverride = aOther.languageOverride;
|
||||
kerning = aOther.kerning;
|
||||
synthesis = aOther.synthesis;
|
||||
fontFeatureSettings = aOther.fontFeatureSettings;
|
||||
languageOverride = aOther.languageOverride;
|
||||
variantAlternates = aOther.variantAlternates;
|
||||
variantCaps = aOther.variantCaps;
|
||||
variantEastAsian = aOther.variantEastAsian;
|
||||
variantLigatures = aOther.variantLigatures;
|
||||
variantNumeric = aOther.variantNumeric;
|
||||
variantPosition = aOther.variantPosition;
|
||||
alternateValues = aOther.alternateValues;
|
||||
featureValueLookup = aOther.featureValueLookup;
|
||||
}
|
||||
|
||||
nsFont::nsFont()
|
||||
@ -81,8 +101,18 @@ bool nsFont::BaseEquals(const nsFont& aOther) const
|
||||
(size == aOther.size) &&
|
||||
(sizeAdjust == aOther.sizeAdjust) &&
|
||||
name.Equals(aOther.name, nsCaseInsensitiveStringComparator()) &&
|
||||
(kerning == aOther.kerning) &&
|
||||
(synthesis == aOther.synthesis) &&
|
||||
(fontFeatureSettings == aOther.fontFeatureSettings) &&
|
||||
(languageOverride == aOther.languageOverride) &&
|
||||
(fontFeatureSettings == aOther.fontFeatureSettings)) {
|
||||
(variantAlternates == aOther.variantAlternates) &&
|
||||
(variantCaps == aOther.variantCaps) &&
|
||||
(variantEastAsian == aOther.variantEastAsian) &&
|
||||
(variantLigatures == aOther.variantLigatures) &&
|
||||
(variantNumeric == aOther.variantNumeric) &&
|
||||
(variantPosition == aOther.variantPosition) &&
|
||||
(alternateValues == aOther.alternateValues) &&
|
||||
(featureValueLookup == aOther.featureValueLookup)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -109,16 +139,27 @@ nsFont& nsFont::operator=(const nsFont& aOther)
|
||||
decorations = aOther.decorations;
|
||||
size = aOther.size;
|
||||
sizeAdjust = aOther.sizeAdjust;
|
||||
languageOverride = aOther.languageOverride;
|
||||
kerning = aOther.kerning;
|
||||
synthesis = aOther.synthesis;
|
||||
fontFeatureSettings = aOther.fontFeatureSettings;
|
||||
languageOverride = aOther.languageOverride;
|
||||
variantAlternates = aOther.variantAlternates;
|
||||
variantCaps = aOther.variantCaps;
|
||||
variantEastAsian = aOther.variantEastAsian;
|
||||
variantLigatures = aOther.variantLigatures;
|
||||
variantNumeric = aOther.variantNumeric;
|
||||
variantPosition = aOther.variantPosition;
|
||||
alternateValues = aOther.alternateValues;
|
||||
featureValueLookup = aOther.featureValueLookup;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
nsFont::AddFontFeaturesToStyle(gfxFontStyle *aStyle) const
|
||||
nsFont::CopyAlternates(const nsFont& aOther)
|
||||
{
|
||||
// simple copy for now, font-variant implementation will expand
|
||||
aStyle->featureSettings.AppendElements(fontFeatureSettings);
|
||||
variantAlternates = aOther.variantAlternates;
|
||||
alternateValues = aOther.alternateValues;
|
||||
featureValueLookup = aOther.featureValueLookup;
|
||||
}
|
||||
|
||||
static bool IsGenericFontFamily(const nsString& aFamily)
|
||||
@ -184,6 +225,199 @@ bool nsFont::EnumerateFamilies(nsFontFamilyEnumFunc aFunc, void* aData) const
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
// NS_FONT_VARIANT_EAST_ASIAN_xxx values
|
||||
const gfxFontFeature eastAsianDefaults[] = {
|
||||
{ TRUETYPE_TAG('j','p','7','8'), 1 },
|
||||
{ TRUETYPE_TAG('j','p','8','3'), 1 },
|
||||
{ TRUETYPE_TAG('j','p','9','0'), 1 },
|
||||
{ TRUETYPE_TAG('j','p','0','4'), 1 },
|
||||
{ TRUETYPE_TAG('s','m','p','l'), 1 },
|
||||
{ TRUETYPE_TAG('t','r','a','d'), 1 },
|
||||
{ TRUETYPE_TAG('f','w','i','d'), 1 },
|
||||
{ TRUETYPE_TAG('p','w','i','d'), 1 },
|
||||
{ TRUETYPE_TAG('r','u','b','y'), 1 }
|
||||
};
|
||||
|
||||
PR_STATIC_ASSERT(NS_ARRAY_LENGTH(eastAsianDefaults) ==
|
||||
eFeatureEastAsian_numFeatures);
|
||||
|
||||
// NS_FONT_VARIANT_LIGATURES_xxx values
|
||||
const gfxFontFeature ligDefaults[] = {
|
||||
{ TRUETYPE_TAG('l','i','g','a'), 1 },
|
||||
{ TRUETYPE_TAG('l','i','g','a'), 0 },
|
||||
{ TRUETYPE_TAG('d','l','i','g'), 1 },
|
||||
{ TRUETYPE_TAG('d','l','i','g'), 0 },
|
||||
{ TRUETYPE_TAG('h','l','i','g'), 1 },
|
||||
{ TRUETYPE_TAG('h','l','i','g'), 0 },
|
||||
{ TRUETYPE_TAG('c','a','l','t'), 1 },
|
||||
{ TRUETYPE_TAG('c','a','l','t'), 0 }
|
||||
};
|
||||
|
||||
PR_STATIC_ASSERT(NS_ARRAY_LENGTH(ligDefaults) ==
|
||||
eFeatureLigatures_numFeatures);
|
||||
|
||||
// NS_FONT_VARIANT_NUMERIC_xxx values
|
||||
const gfxFontFeature numericDefaults[] = {
|
||||
{ TRUETYPE_TAG('l','n','u','m'), 1 },
|
||||
{ TRUETYPE_TAG('o','n','u','m'), 1 },
|
||||
{ TRUETYPE_TAG('p','n','u','m'), 1 },
|
||||
{ TRUETYPE_TAG('t','n','u','m'), 1 },
|
||||
{ TRUETYPE_TAG('f','r','a','c'), 1 },
|
||||
{ TRUETYPE_TAG('a','f','r','c'), 1 },
|
||||
{ TRUETYPE_TAG('z','e','r','o'), 1 },
|
||||
{ TRUETYPE_TAG('o','r','d','n'), 1 }
|
||||
};
|
||||
|
||||
PR_STATIC_ASSERT(NS_ARRAY_LENGTH(numericDefaults) ==
|
||||
eFeatureNumeric_numFeatures);
|
||||
|
||||
static void
|
||||
AddFontFeaturesBitmask(uint32_t aValue, uint32_t aMin, uint32_t aMax,
|
||||
const gfxFontFeature aFeatureDefaults[],
|
||||
nsTArray<gfxFontFeature>& aFeaturesOut)
|
||||
|
||||
{
|
||||
uint32_t i, m;
|
||||
|
||||
for (i = 0, m = aMin; m <= aMax; i++, m <<= 1) {
|
||||
if (m & aValue) {
|
||||
const gfxFontFeature& feature = aFeatureDefaults[i];
|
||||
aFeaturesOut.AppendElement(feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nsFont::AddFontFeaturesToStyle(gfxFontStyle *aStyle) const
|
||||
{
|
||||
// add in font-variant features
|
||||
gfxFontFeature setting;
|
||||
|
||||
// -- kerning
|
||||
setting.mTag = TRUETYPE_TAG('k','e','r','n');
|
||||
switch (kerning) {
|
||||
case NS_FONT_KERNING_NONE:
|
||||
setting.mValue = 0;
|
||||
aStyle->featureSettings.AppendElement(setting);
|
||||
break;
|
||||
case NS_FONT_KERNING_NORMAL:
|
||||
setting.mValue = 1;
|
||||
aStyle->featureSettings.AppendElement(setting);
|
||||
break;
|
||||
default:
|
||||
// auto case implies use user agent default
|
||||
break;
|
||||
}
|
||||
|
||||
// -- alternates
|
||||
if (variantAlternates & NS_FONT_VARIANT_ALTERNATES_HISTORICAL) {
|
||||
setting.mValue = 1;
|
||||
setting.mTag = TRUETYPE_TAG('h','i','s','t');
|
||||
aStyle->featureSettings.AppendElement(setting);
|
||||
}
|
||||
|
||||
|
||||
// -- copy font-specific alternate info into style
|
||||
// (this will be resolved after font-matching occurs)
|
||||
aStyle->alternateValues.AppendElements(alternateValues);
|
||||
aStyle->featureValueLookup = featureValueLookup;
|
||||
|
||||
// -- caps
|
||||
setting.mValue = 1;
|
||||
switch (variantCaps) {
|
||||
case NS_FONT_VARIANT_CAPS_ALLSMALL:
|
||||
setting.mTag = TRUETYPE_TAG('c','2','s','c');
|
||||
aStyle->featureSettings.AppendElement(setting);
|
||||
// fall through to the small-caps case
|
||||
case NS_FONT_VARIANT_CAPS_SMALLCAPS:
|
||||
setting.mTag = TRUETYPE_TAG('s','m','c','p');
|
||||
aStyle->featureSettings.AppendElement(setting);
|
||||
break;
|
||||
|
||||
case NS_FONT_VARIANT_CAPS_ALLPETITE:
|
||||
setting.mTag = TRUETYPE_TAG('c','2','p','c');
|
||||
aStyle->featureSettings.AppendElement(setting);
|
||||
// fall through to the petite-caps case
|
||||
case NS_FONT_VARIANT_CAPS_PETITECAPS:
|
||||
setting.mTag = TRUETYPE_TAG('p','c','a','p');
|
||||
aStyle->featureSettings.AppendElement(setting);
|
||||
break;
|
||||
|
||||
case NS_FONT_VARIANT_CAPS_TITLING:
|
||||
setting.mTag = TRUETYPE_TAG('t','i','t','l');
|
||||
aStyle->featureSettings.AppendElement(setting);
|
||||
break;
|
||||
|
||||
case NS_FONT_VARIANT_CAPS_UNICASE:
|
||||
setting.mTag = TRUETYPE_TAG('u','n','i','c');
|
||||
aStyle->featureSettings.AppendElement(setting);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// -- east-asian
|
||||
if (variantEastAsian) {
|
||||
AddFontFeaturesBitmask(variantEastAsian,
|
||||
NS_FONT_VARIANT_EAST_ASIAN_JIS78,
|
||||
NS_FONT_VARIANT_EAST_ASIAN_RUBY,
|
||||
eastAsianDefaults, aStyle->featureSettings);
|
||||
}
|
||||
|
||||
// -- ligatures
|
||||
if (variantLigatures) {
|
||||
AddFontFeaturesBitmask(variantLigatures,
|
||||
NS_FONT_VARIANT_LIGATURES_COMMON,
|
||||
NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL,
|
||||
ligDefaults, aStyle->featureSettings);
|
||||
|
||||
// special case common ligs, which also enable/disable clig
|
||||
if (variantLigatures & NS_FONT_VARIANT_LIGATURES_COMMON) {
|
||||
setting.mTag = TRUETYPE_TAG('c','l','i','g');
|
||||
setting.mValue = 1;
|
||||
aStyle->featureSettings.AppendElement(setting);
|
||||
} else if (variantLigatures & NS_FONT_VARIANT_LIGATURES_NO_COMMON) {
|
||||
setting.mTag = TRUETYPE_TAG('c','l','i','g');
|
||||
setting.mValue = 0;
|
||||
aStyle->featureSettings.AppendElement(setting);
|
||||
}
|
||||
}
|
||||
|
||||
// -- numeric
|
||||
if (variantNumeric) {
|
||||
AddFontFeaturesBitmask(variantNumeric,
|
||||
NS_FONT_VARIANT_NUMERIC_LINING,
|
||||
NS_FONT_VARIANT_NUMERIC_ORDINAL,
|
||||
numericDefaults, aStyle->featureSettings);
|
||||
}
|
||||
|
||||
// -- position
|
||||
setting.mTag = 0;
|
||||
setting.mValue = 1;
|
||||
switch (variantPosition) {
|
||||
case NS_FONT_VARIANT_POSITION_SUPER:
|
||||
setting.mTag = TRUETYPE_TAG('s','u','p','s');
|
||||
aStyle->featureSettings.AppendElement(setting);
|
||||
break;
|
||||
|
||||
case NS_FONT_VARIANT_POSITION_SUB:
|
||||
setting.mTag = TRUETYPE_TAG('s','u','b','s');
|
||||
aStyle->featureSettings.AppendElement(setting);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// add in features from font-feature-settings
|
||||
aStyle->featureSettings.AppendElements(fontFeatureSettings);
|
||||
}
|
||||
|
||||
static bool FontEnumCallback(const nsString& aFamily, bool aGeneric, void *aData)
|
||||
{
|
||||
*((nsString*)aData) = aFamily;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "nsTArray.h"
|
||||
#include "gfxFontConstants.h"
|
||||
#include "gfxFontFeatures.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
// XXX we need a method to enumerate all of the possible fonts on the
|
||||
// system across family, weight, style, size, etc. But not here!
|
||||
@ -50,6 +51,22 @@ struct NS_GFX nsFont {
|
||||
// The variant of the font (normal, small-caps)
|
||||
uint8_t variant;
|
||||
|
||||
// Variant subproperties
|
||||
// (currently -moz- versions, will replace variant above eventually)
|
||||
uint8_t variantCaps;
|
||||
uint8_t variantLigatures;
|
||||
uint8_t variantNumeric;
|
||||
uint8_t variantPosition;
|
||||
|
||||
uint16_t variantEastAsian;
|
||||
|
||||
// Some font-variant-alternates property values require
|
||||
// font-specific settings defined via @font-feature-values rules.
|
||||
// These are resolved *after* font matching occurs.
|
||||
|
||||
// -- bitmask for both enumerated and functional propvals
|
||||
uint16_t variantAlternates;
|
||||
|
||||
// The decorations on the font (underline, overline,
|
||||
// line-through). The decorations can be binary or'd together.
|
||||
uint8_t decorations;
|
||||
@ -70,6 +87,12 @@ struct NS_GFX nsFont {
|
||||
// needs to be done.
|
||||
float sizeAdjust;
|
||||
|
||||
// -- list of value tags for font-specific alternate features
|
||||
nsTArray<gfxAlternateValue> alternateValues;
|
||||
|
||||
// -- object used to look these up once the font is matched
|
||||
nsRefPtr<gfxFontFeatureValueSet> featureValueLookup;
|
||||
|
||||
// Font features from CSS font-feature-settings
|
||||
nsTArray<gfxFontFeature> fontFeatureSettings;
|
||||
|
||||
@ -78,17 +101,21 @@ struct NS_GFX nsFont {
|
||||
// (see http://www.microsoft.com/typography/otspec/languagetags.htm).
|
||||
nsString languageOverride;
|
||||
|
||||
// Kerning
|
||||
uint8_t kerning;
|
||||
|
||||
// Synthesis setting, controls use of fake bolding/italics
|
||||
uint8_t synthesis;
|
||||
|
||||
// Initialize the font struct with an ASCII name
|
||||
nsFont(const char* aName, uint8_t aStyle, uint8_t aVariant,
|
||||
uint16_t aWeight, int16_t aStretch, uint8_t aDecoration,
|
||||
nscoord aSize, float aSizeAdjust=0.0f,
|
||||
const nsString* aLanguageOverride = nullptr);
|
||||
nscoord aSize);
|
||||
|
||||
// Initialize the font struct with a (potentially) unicode name
|
||||
nsFont(const nsString& aName, uint8_t aStyle, uint8_t aVariant,
|
||||
nsFont(const nsSubstring& aName, uint8_t aStyle, uint8_t aVariant,
|
||||
uint16_t aWeight, int16_t aStretch, uint8_t aDecoration,
|
||||
nscoord aSize, float aSizeAdjust=0.0f,
|
||||
const nsString* aLanguageOverride = nullptr);
|
||||
nscoord aSize);
|
||||
|
||||
// Make a copy of the given font
|
||||
nsFont(const nsFont& aFont);
|
||||
@ -106,6 +133,8 @@ struct NS_GFX nsFont {
|
||||
|
||||
nsFont& operator=(const nsFont& aOther);
|
||||
|
||||
void CopyAlternates(const nsFont& aOther);
|
||||
|
||||
// Add featureSettings into style
|
||||
void AddFontFeaturesToStyle(gfxFontStyle *aStyle) const;
|
||||
|
||||
|
@ -80,7 +80,6 @@ SetupTests()
|
||||
NS_NewPermanentAtom(NS_LITERAL_STRING("en")),
|
||||
0.0,
|
||||
false, false, false,
|
||||
NS_LITERAL_STRING(""),
|
||||
NS_LITERAL_STRING(""));
|
||||
|
||||
gfxFontStyle style_western_bold_16 (FONT_STYLE_NORMAL,
|
||||
@ -90,7 +89,6 @@ SetupTests()
|
||||
NS_NewPermanentAtom(NS_LITERAL_STRING("en")),
|
||||
0.0,
|
||||
false, false, false,
|
||||
NS_LITERAL_STRING(""),
|
||||
NS_LITERAL_STRING(""));
|
||||
|
||||
/* Test 0 */
|
||||
|
@ -66,7 +66,6 @@ RunTest (TestEntry *test, gfxContext *ctx) {
|
||||
NS_NewPermanentAtom(NS_LITERAL_STRING("en")),
|
||||
0.0,
|
||||
false, false, false,
|
||||
NS_LITERAL_STRING(""),
|
||||
NS_LITERAL_STRING(""));
|
||||
|
||||
fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(NS_ConvertUTF8toUTF16(test->mFamilies), &style_western_normal_16, nullptr);
|
||||
|
@ -124,7 +124,6 @@ main (int argc, char **argv) {
|
||||
NS_NewPermanentAtom(NS_LITERAL_STRING("en")),
|
||||
0.0,
|
||||
false, false, false,
|
||||
NS_LITERAL_STRING(""),
|
||||
NS_LITERAL_STRING(""));
|
||||
|
||||
nsRefPtr<gfxFontGroup> fontGroup =
|
||||
|
@ -34,6 +34,7 @@ CPPSRCS = \
|
||||
gfxDrawable.cpp \
|
||||
gfxImageSurface.cpp \
|
||||
gfxFont.cpp \
|
||||
gfxFontFeatures.cpp \
|
||||
gfxFontMissingGlyphs.cpp \
|
||||
gfxFontTest.cpp \
|
||||
gfxFontUtils.cpp \
|
||||
|
@ -1367,17 +1367,111 @@ gfxFontCache::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
SizeOfExcludingThis(aMallocSizeOf, aSizes);
|
||||
}
|
||||
|
||||
#define MAX_SSXX_VALUE 99
|
||||
#define MAX_CVXX_VALUE 99
|
||||
|
||||
static void
|
||||
LookupAlternateValues(gfxFontFeatureValueSet *featureLookup,
|
||||
const nsAString& aFamily,
|
||||
const nsTArray<gfxAlternateValue>& altValue,
|
||||
nsTArray<gfxFontFeature>& aFontFeatures)
|
||||
{
|
||||
uint32_t numAlternates = altValue.Length();
|
||||
for (uint32_t i = 0; i < numAlternates; i++) {
|
||||
const gfxAlternateValue& av = altValue.ElementAt(i);
|
||||
nsAutoTArray<uint32_t,4> values;
|
||||
|
||||
// map <family, name, feature> ==> <values>
|
||||
bool found =
|
||||
featureLookup->GetFontFeatureValuesFor(aFamily, av.alternate,
|
||||
av.value, values);
|
||||
uint32_t numValues = values.Length();
|
||||
|
||||
// nothing defined, skip
|
||||
if (!found || numValues == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gfxFontFeature feature;
|
||||
if (av.alternate == NS_FONT_VARIANT_ALTERNATES_CHARACTER_VARIANT) {
|
||||
NS_ASSERTION(numValues <= 2,
|
||||
"too many values allowed for character-variant");
|
||||
// character-variant(12 3) ==> 'cv12' = 3
|
||||
uint32_t nn = values.ElementAt(0);
|
||||
// ignore values greater than 99
|
||||
if (nn == 0 || nn > MAX_CVXX_VALUE) {
|
||||
continue;
|
||||
}
|
||||
feature.mValue = 1;
|
||||
if (numValues > 1) {
|
||||
feature.mValue = values.ElementAt(1);
|
||||
}
|
||||
feature.mTag = HB_TAG('c','v',('0' + nn / 10), ('0' + nn % 10));
|
||||
aFontFeatures.AppendElement(feature);
|
||||
|
||||
} else if (av.alternate == NS_FONT_VARIANT_ALTERNATES_STYLESET) {
|
||||
// styleset(1 2 7) ==> 'ss01' = 1, 'ss02' = 1, 'ss07' = 1
|
||||
feature.mValue = 1;
|
||||
for (uint32_t v = 0; v < numValues; v++) {
|
||||
uint32_t nn = values.ElementAt(v);
|
||||
if (nn == 0 || nn > MAX_SSXX_VALUE) {
|
||||
continue;
|
||||
}
|
||||
feature.mTag = HB_TAG('s','s',('0' + nn / 10), ('0' + nn % 10));
|
||||
aFontFeatures.AppendElement(feature);
|
||||
}
|
||||
|
||||
} else {
|
||||
NS_ASSERTION(numValues == 1,
|
||||
"too many values for font-specific font-variant-alternates");
|
||||
feature.mValue = values.ElementAt(0);
|
||||
|
||||
switch (av.alternate) {
|
||||
case NS_FONT_VARIANT_ALTERNATES_STYLISTIC: // salt
|
||||
feature.mTag = HB_TAG('s','a','l','t');
|
||||
break;
|
||||
case NS_FONT_VARIANT_ALTERNATES_SWASH: // swsh, cswh
|
||||
feature.mTag = HB_TAG('s','w','s','h');
|
||||
aFontFeatures.AppendElement(feature);
|
||||
feature.mTag = HB_TAG('c','s','w','h');
|
||||
break;
|
||||
case NS_FONT_VARIANT_ALTERNATES_ORNAMENTS: // ornm
|
||||
feature.mTag = HB_TAG('o','r','n','m');
|
||||
break;
|
||||
case NS_FONT_VARIANT_ALTERNATES_ANNOTATION: // nalt
|
||||
feature.mTag = HB_TAG('n','a','l','t');
|
||||
break;
|
||||
default:
|
||||
feature.mTag = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
NS_ASSERTION(feature.mTag, "unsupported alternate type");
|
||||
if (!feature.mTag) {
|
||||
continue;
|
||||
}
|
||||
aFontFeatures.AppendElement(feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
gfxFontShaper::MergeFontFeatures(
|
||||
const nsTArray<gfxFontFeature>& aStyleRuleFeatures,
|
||||
const gfxFontStyle *aStyle,
|
||||
const nsTArray<gfxFontFeature>& aFontFeatures,
|
||||
bool aDisableLigatures,
|
||||
const nsAString& aFamilyName,
|
||||
nsDataHashtable<nsUint32HashKey,uint32_t>& aMergedFeatures)
|
||||
{
|
||||
uint32_t numAlts = aStyle->alternateValues.Length();
|
||||
const nsTArray<gfxFontFeature>& styleRuleFeatures =
|
||||
aStyle->featureSettings;
|
||||
|
||||
// bail immediately if nothing to do
|
||||
if (aStyleRuleFeatures.IsEmpty() &&
|
||||
if (styleRuleFeatures.IsEmpty() &&
|
||||
aFontFeatures.IsEmpty() &&
|
||||
!aDisableLigatures) {
|
||||
!aDisableLigatures &&
|
||||
numAlts == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1399,10 +1493,25 @@ gfxFontShaper::MergeFontFeatures(
|
||||
aMergedFeatures.Put(feature.mTag, feature.mValue);
|
||||
}
|
||||
|
||||
// add font-specific feature values from style rules
|
||||
if (aStyle->featureValueLookup && numAlts > 0) {
|
||||
nsAutoTArray<gfxFontFeature,4> featureList;
|
||||
|
||||
// insert list of alternate feature settings
|
||||
LookupAlternateValues(aStyle->featureValueLookup, aFamilyName,
|
||||
aStyle->alternateValues, featureList);
|
||||
|
||||
count = featureList.Length();
|
||||
for (i = 0; i < count; i++) {
|
||||
const gfxFontFeature& feature = featureList.ElementAt(i);
|
||||
aMergedFeatures.Put(feature.mTag, feature.mValue);
|
||||
}
|
||||
}
|
||||
|
||||
// add feature values from style rules
|
||||
count = aStyleRuleFeatures.Length();
|
||||
count = styleRuleFeatures.Length();
|
||||
for (i = 0; i < count; i++) {
|
||||
const gfxFontFeature& feature = aStyleRuleFeatures.ElementAt(i);
|
||||
const gfxFontFeature& feature = styleRuleFeatures.ElementAt(i);
|
||||
aMergedFeatures.Put(feature.mTag, feature.mValue);
|
||||
}
|
||||
|
||||
@ -4791,6 +4900,7 @@ gfxFontStyle::gfxFontStyle(uint8_t aStyle, uint16_t aWeight, int16_t aStretch,
|
||||
|
||||
gfxFontStyle::gfxFontStyle(const gfxFontStyle& aStyle) :
|
||||
language(aStyle.language),
|
||||
featureValueLookup(aStyle.featureValueLookup),
|
||||
size(aStyle.size), sizeAdjust(aStyle.sizeAdjust),
|
||||
languageOverride(aStyle.languageOverride),
|
||||
weight(aStyle.weight), stretch(aStyle.stretch),
|
||||
@ -4798,6 +4908,7 @@ gfxFontStyle::gfxFontStyle(const gfxFontStyle& aStyle) :
|
||||
style(aStyle.style)
|
||||
{
|
||||
featureSettings.AppendElements(aStyle.featureSettings);
|
||||
alternateValues.AppendElements(aStyle.alternateValues);
|
||||
}
|
||||
|
||||
int8_t
|
||||
|
@ -73,9 +73,23 @@ struct THEBES_API gfxFontStyle {
|
||||
// or inferred from the charset
|
||||
nsRefPtr<nsIAtom> language;
|
||||
|
||||
// Features are composed of (1) features from style rules (2) features
|
||||
// from feature setttings rules and (3) family-specific features. (1) and
|
||||
// (3) are guaranteed to be mutually exclusive
|
||||
|
||||
// custom opentype feature settings
|
||||
nsTArray<gfxFontFeature> featureSettings;
|
||||
|
||||
// Some font-variant property values require font-specific settings
|
||||
// defined via @font-feature-values rules. These are resolved after
|
||||
// font matching occurs.
|
||||
|
||||
// -- list of value tags for specific alternate features
|
||||
nsTArray<gfxAlternateValue> alternateValues;
|
||||
|
||||
// -- object used to look these up once the font is matched
|
||||
nsRefPtr<gfxFontFeatureValueSet> featureValueLookup;
|
||||
|
||||
// The logical size of the font, in pixels
|
||||
gfxFloat size;
|
||||
|
||||
@ -144,7 +158,9 @@ struct THEBES_API gfxFontStyle {
|
||||
(*reinterpret_cast<const uint32_t*>(&sizeAdjust) ==
|
||||
*reinterpret_cast<const uint32_t*>(&other.sizeAdjust)) &&
|
||||
(featureSettings == other.featureSettings) &&
|
||||
(languageOverride == other.languageOverride);
|
||||
(languageOverride == other.languageOverride) &&
|
||||
(alternateValues == other.alternateValues) &&
|
||||
(featureValueLookup == other.featureValueLookup);
|
||||
}
|
||||
|
||||
static void ParseFontFeatureSettings(const nsString& aFeatureString,
|
||||
@ -1147,9 +1163,10 @@ public:
|
||||
|
||||
// returns true if features exist in output, false otherwise
|
||||
static bool
|
||||
MergeFontFeatures(const nsTArray<gfxFontFeature>& aStyleRuleFeatures,
|
||||
MergeFontFeatures(const gfxFontStyle *aStyle,
|
||||
const nsTArray<gfxFontFeature>& aFontFeatures,
|
||||
bool aDisableLigatures,
|
||||
const nsAString& aFamilyName,
|
||||
nsDataHashtable<nsUint32HashKey,uint32_t>& aMergedFeatures);
|
||||
|
||||
protected:
|
||||
@ -1580,6 +1597,10 @@ public:
|
||||
virtual mozilla::TemporaryRef<mozilla::gfx::ScaledFont> GetScaledFont(mozilla::gfx::DrawTarget *aTarget)
|
||||
{ return gfxPlatform::GetPlatform()->GetScaledFontForFont(aTarget, this); }
|
||||
|
||||
bool KerningDisabled() {
|
||||
return mKerningSet && !mKerningEnabled;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
bool HasSubstitutionRulesWithSpaceLookups(int32_t aRunScript) {
|
||||
|
@ -30,4 +30,165 @@
|
||||
#define NS_FONT_STRETCH_EXTRA_EXPANDED 3
|
||||
#define NS_FONT_STRETCH_ULTRA_EXPANDED 4
|
||||
|
||||
#define NS_FONT_KERNING_AUTO 0
|
||||
#define NS_FONT_KERNING_NONE 1
|
||||
#define NS_FONT_KERNING_NORMAL 2
|
||||
|
||||
#define NS_FONT_SYNTHESIS_WEIGHT 0x1
|
||||
#define NS_FONT_SYNTHESIS_STYLE 0x2
|
||||
|
||||
enum {
|
||||
eFeatureAlternates_historical,
|
||||
eFeatureAlternates_stylistic,
|
||||
eFeatureAlternates_styleset,
|
||||
eFeatureAlternates_character_variant,
|
||||
eFeatureAlternates_swash,
|
||||
eFeatureAlternates_ornaments,
|
||||
eFeatureAlternates_annotation,
|
||||
|
||||
eFeatureAlternates_numFeatures
|
||||
};
|
||||
|
||||
// alternates - simple enumerated values
|
||||
#define NS_FONT_VARIANT_ALTERNATES_HISTORICAL (1 << eFeatureAlternates_historical)
|
||||
|
||||
// alternates - values that use functional syntax
|
||||
#define NS_FONT_VARIANT_ALTERNATES_STYLISTIC (1 << eFeatureAlternates_stylistic)
|
||||
#define NS_FONT_VARIANT_ALTERNATES_STYLESET (1 << eFeatureAlternates_styleset)
|
||||
#define NS_FONT_VARIANT_ALTERNATES_CHARACTER_VARIANT (1 << eFeatureAlternates_character_variant)
|
||||
#define NS_FONT_VARIANT_ALTERNATES_SWASH (1 << eFeatureAlternates_swash)
|
||||
#define NS_FONT_VARIANT_ALTERNATES_ORNAMENTS (1 << eFeatureAlternates_ornaments)
|
||||
#define NS_FONT_VARIANT_ALTERNATES_ANNOTATION (1 << eFeatureAlternates_annotation)
|
||||
|
||||
#define NS_FONT_VARIANT_ALTERNATES_ENUMERATED_MASK \
|
||||
NS_FONT_VARIANT_ALTERNATES_HISTORICAL
|
||||
|
||||
#define NS_FONT_VARIANT_ALTERNATES_FUNCTIONAL_MASK ( \
|
||||
NS_FONT_VARIANT_ALTERNATES_STYLISTIC | \
|
||||
NS_FONT_VARIANT_ALTERNATES_STYLESET | \
|
||||
NS_FONT_VARIANT_ALTERNATES_CHARACTER_VARIANT | \
|
||||
NS_FONT_VARIANT_ALTERNATES_SWASH | \
|
||||
NS_FONT_VARIANT_ALTERNATES_ORNAMENTS | \
|
||||
NS_FONT_VARIANT_ALTERNATES_ANNOTATION )
|
||||
|
||||
#define NS_FONT_VARIANT_CAPS_NORMAL 0
|
||||
#define NS_FONT_VARIANT_CAPS_SMALLCAPS 1
|
||||
#define NS_FONT_VARIANT_CAPS_ALLSMALL 2
|
||||
#define NS_FONT_VARIANT_CAPS_PETITECAPS 3
|
||||
#define NS_FONT_VARIANT_CAPS_ALLPETITE 4
|
||||
#define NS_FONT_VARIANT_CAPS_TITLING 5
|
||||
#define NS_FONT_VARIANT_CAPS_UNICASE 6
|
||||
|
||||
enum {
|
||||
eFeatureEastAsian_jis78,
|
||||
eFeatureEastAsian_jis83,
|
||||
eFeatureEastAsian_jis90,
|
||||
eFeatureEastAsian_jis04,
|
||||
eFeatureEastAsian_simplified,
|
||||
eFeatureEastAsian_traditional,
|
||||
eFeatureEastAsian_full_width,
|
||||
eFeatureEastAsian_prop_width,
|
||||
eFeatureEastAsian_ruby,
|
||||
|
||||
eFeatureEastAsian_numFeatures
|
||||
};
|
||||
|
||||
#define NS_FONT_VARIANT_EAST_ASIAN_JIS78 (1 << eFeatureEastAsian_jis78)
|
||||
#define NS_FONT_VARIANT_EAST_ASIAN_JIS83 (1 << eFeatureEastAsian_jis83)
|
||||
#define NS_FONT_VARIANT_EAST_ASIAN_JIS90 (1 << eFeatureEastAsian_jis90)
|
||||
#define NS_FONT_VARIANT_EAST_ASIAN_JIS04 (1 << eFeatureEastAsian_jis04)
|
||||
#define NS_FONT_VARIANT_EAST_ASIAN_SIMPLIFIED (1 << eFeatureEastAsian_simplified)
|
||||
#define NS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL (1 << eFeatureEastAsian_traditional)
|
||||
#define NS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH (1 << eFeatureEastAsian_full_width)
|
||||
#define NS_FONT_VARIANT_EAST_ASIAN_PROP_WIDTH (1 << eFeatureEastAsian_prop_width)
|
||||
#define NS_FONT_VARIANT_EAST_ASIAN_RUBY (1 << eFeatureEastAsian_ruby)
|
||||
|
||||
#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 )
|
||||
|
||||
enum {
|
||||
eFeatureLigatures_common,
|
||||
eFeatureLigatures_no_common,
|
||||
eFeatureLigatures_discretionary,
|
||||
eFeatureLigatures_no_discretionary,
|
||||
eFeatureLigatures_historical,
|
||||
eFeatureLigatures_no_historical,
|
||||
eFeatureLigatures_contextual,
|
||||
eFeatureLigatures_no_contextual,
|
||||
|
||||
eFeatureLigatures_numFeatures
|
||||
};
|
||||
|
||||
#define NS_FONT_VARIANT_LIGATURES_COMMON (1 << eFeatureLigatures_common)
|
||||
#define NS_FONT_VARIANT_LIGATURES_NO_COMMON (1 << eFeatureLigatures_no_common)
|
||||
#define NS_FONT_VARIANT_LIGATURES_DISCRETIONARY (1 << eFeatureLigatures_discretionary)
|
||||
#define NS_FONT_VARIANT_LIGATURES_NO_DISCRETIONARY (1 << eFeatureLigatures_no_discretionary)
|
||||
#define NS_FONT_VARIANT_LIGATURES_HISTORICAL (1 << eFeatureLigatures_historical)
|
||||
#define NS_FONT_VARIANT_LIGATURES_NO_HISTORICAL (1 << eFeatureLigatures_no_historical)
|
||||
#define NS_FONT_VARIANT_LIGATURES_CONTEXTUAL (1 << eFeatureLigatures_contextual)
|
||||
#define NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL (1 << eFeatureLigatures_no_contextual)
|
||||
|
||||
#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
|
||||
|
||||
enum {
|
||||
eFeatureNumeric_lining,
|
||||
eFeatureNumeric_oldstyle,
|
||||
eFeatureNumeric_proportional,
|
||||
eFeatureNumeric_tabular,
|
||||
eFeatureNumeric_diagonal_fractions,
|
||||
eFeatureNumeric_stacked_fractions,
|
||||
eFeatureNumeric_slashedzero,
|
||||
eFeatureNumeric_ordinal,
|
||||
|
||||
eFeatureNumeric_numFeatures
|
||||
};
|
||||
|
||||
#define NS_FONT_VARIANT_NUMERIC_LINING (1 << eFeatureNumeric_lining)
|
||||
#define NS_FONT_VARIANT_NUMERIC_OLDSTYLE (1 << eFeatureNumeric_oldstyle)
|
||||
#define NS_FONT_VARIANT_NUMERIC_PROPORTIONAL (1 << eFeatureNumeric_proportional)
|
||||
#define NS_FONT_VARIANT_NUMERIC_TABULAR (1 << eFeatureNumeric_tabular)
|
||||
#define NS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS (1 << eFeatureNumeric_diagonal_fractions)
|
||||
#define NS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS (1 << eFeatureNumeric_stacked_fractions)
|
||||
#define NS_FONT_VARIANT_NUMERIC_SLASHZERO (1 << eFeatureNumeric_slashedzero)
|
||||
#define NS_FONT_VARIANT_NUMERIC_ORDINAL (1 << eFeatureNumeric_ordinal)
|
||||
|
||||
#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
|
||||
|
||||
#endif
|
||||
|
@ -7,6 +7,11 @@
|
||||
#ifndef GFX_FONT_FEATURES_H
|
||||
#define GFX_FONT_FEATURES_H
|
||||
|
||||
#include "gfxTypes.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsString.h"
|
||||
|
||||
// An OpenType feature tag and value pair
|
||||
struct gfxFontFeature {
|
||||
uint32_t mTag; // see http://www.microsoft.com/typography/otspec/featuretags.htm
|
||||
@ -26,4 +31,95 @@ operator==(const gfxFontFeature& a, const gfxFontFeature& b)
|
||||
return (a.mTag == b.mTag) && (a.mValue == b.mValue);
|
||||
}
|
||||
|
||||
struct gfxAlternateValue {
|
||||
uint32_t alternate; // constants in gfxFontConstants.h
|
||||
nsString value; // string value to be looked up
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator<(const gfxAlternateValue& a, const gfxAlternateValue& b)
|
||||
{
|
||||
return (a.alternate < b.alternate) ||
|
||||
((a.alternate == b.alternate) && (a.value < b.value));
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator==(const gfxAlternateValue& a, const gfxAlternateValue& b)
|
||||
{
|
||||
return (a.alternate == b.alternate) && (a.value == b.value);
|
||||
}
|
||||
|
||||
class THEBES_API gfxFontFeatureValueSet {
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(gfxFontFeatureValueSet)
|
||||
|
||||
gfxFontFeatureValueSet();
|
||||
virtual ~gfxFontFeatureValueSet() {}
|
||||
|
||||
struct ValueList {
|
||||
ValueList(const nsAString& aName, const nsTArray<uint32_t>& aSelectors)
|
||||
: name(aName), featureSelectors(aSelectors)
|
||||
{}
|
||||
nsString name;
|
||||
nsTArray<uint32_t> featureSelectors;
|
||||
};
|
||||
|
||||
struct FeatureValues {
|
||||
uint32_t alternate;
|
||||
nsTArray<ValueList> valuelist;
|
||||
};
|
||||
|
||||
// returns true if found, false otherwise
|
||||
bool
|
||||
GetFontFeatureValuesFor(const nsAString& aFamily,
|
||||
uint32_t aVariantProperty,
|
||||
const nsAString& aName,
|
||||
nsTArray<uint32_t>& aValues);
|
||||
void
|
||||
AddFontFeatureValues(const nsAString& aFamily,
|
||||
const nsTArray<gfxFontFeatureValueSet::FeatureValues>& aValues);
|
||||
|
||||
protected:
|
||||
struct FeatureValueHashKey {
|
||||
nsString mFamily;
|
||||
uint32_t mPropVal;
|
||||
nsString mName;
|
||||
|
||||
FeatureValueHashKey()
|
||||
: mPropVal(0)
|
||||
{ }
|
||||
FeatureValueHashKey(const nsAString& aFamily,
|
||||
uint32_t aPropVal,
|
||||
const nsAString& aName)
|
||||
: mFamily(aFamily), mPropVal(aPropVal), mName(aName)
|
||||
{ }
|
||||
FeatureValueHashKey(const FeatureValueHashKey& aKey)
|
||||
: mFamily(aKey.mFamily), mPropVal(aKey.mPropVal), mName(aKey.mName)
|
||||
{ }
|
||||
};
|
||||
|
||||
class FeatureValueHashEntry : public PLDHashEntryHdr {
|
||||
public:
|
||||
typedef const FeatureValueHashKey &KeyType;
|
||||
typedef const FeatureValueHashKey *KeyTypePointer;
|
||||
|
||||
FeatureValueHashEntry(KeyTypePointer aKey) { }
|
||||
FeatureValueHashEntry(const FeatureValueHashEntry& toCopy)
|
||||
{
|
||||
NS_ERROR("Should not be called");
|
||||
}
|
||||
~FeatureValueHashEntry() { }
|
||||
|
||||
bool KeyEquals(const KeyTypePointer aKey) const;
|
||||
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
|
||||
static PLDHashNumber HashKey(const KeyTypePointer aKey);
|
||||
enum { ALLOW_MEMMOVE = true };
|
||||
|
||||
FeatureValueHashKey mKey;
|
||||
nsTArray<uint32_t> mValues;
|
||||
};
|
||||
|
||||
nsTHashtable<FeatureValueHashEntry> mFontFeatureValues;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -192,8 +192,13 @@ gfxGraphiteShaper::ShapeText(gfxContext *aContext,
|
||||
|
||||
nsDataHashtable<nsUint32HashKey,uint32_t> mergedFeatures;
|
||||
|
||||
if (MergeFontFeatures(style->featureSettings, entry->mFeatureSettings,
|
||||
aShapedText->DisableLigatures(), mergedFeatures)) {
|
||||
// if style contains font-specific features
|
||||
if (MergeFontFeatures(style,
|
||||
mFont->GetFontEntry()->mFeatureSettings,
|
||||
aShapedText->DisableLigatures(),
|
||||
mFont->GetFontEntry()->FamilyName(),
|
||||
mergedFeatures))
|
||||
{
|
||||
// enumerate result and insert into Graphite feature list
|
||||
GrFontFeatures f = {mGrFace, grFeatures};
|
||||
mergedFeatures.Enumerate(AddFeature, &f);
|
||||
|
@ -99,12 +99,14 @@ HBGetTable(hb_face_t *face, hb_tag_t aTag, void *aUserData)
|
||||
*/
|
||||
|
||||
struct FontCallbackData {
|
||||
FontCallbackData(gfxHarfBuzzShaper *aShaper, gfxContext *aContext)
|
||||
: mShaper(aShaper), mContext(aContext)
|
||||
FontCallbackData(gfxHarfBuzzShaper *aShaper, gfxContext *aContext,
|
||||
bool aKerning)
|
||||
: mShaper(aShaper), mContext(aContext), mKerning(aKerning)
|
||||
{ }
|
||||
|
||||
gfxHarfBuzzShaper *mShaper;
|
||||
gfxContext *mContext;
|
||||
bool mKerning;
|
||||
};
|
||||
|
||||
#define UNICODE_BMP_LIMIT 0x10000
|
||||
@ -644,7 +646,13 @@ HBGetHKerning(hb_font_t *font, void *font_data,
|
||||
{
|
||||
const FontCallbackData *fcd =
|
||||
static_cast<const FontCallbackData*>(font_data);
|
||||
return fcd->mShaper->GetHKerning(first_glyph, second_glyph);
|
||||
|
||||
// return 0 if kerning is explicitly disabled
|
||||
if (fcd->mKerning) {
|
||||
return fcd->mShaper->GetHKerning(first_glyph, second_glyph);
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -956,7 +964,9 @@ gfxHarfBuzzShaper::ShapeText(gfxContext *aContext,
|
||||
return false;
|
||||
}
|
||||
|
||||
FontCallbackData fcd(this, aContext);
|
||||
const gfxFontStyle *style = mFont->GetStyle();
|
||||
// kerning is enabled *except* when explicitly disabled (font-kerning: none)
|
||||
FontCallbackData fcd(this, aContext, !mFont->KerningDisabled());
|
||||
hb_font_t *font = hb_font_create(mHBFace);
|
||||
hb_font_set_funcs(font, sHBFontFuncs, &fcd, nullptr);
|
||||
hb_font_set_ppem(font, mFont->GetAdjustedSize(), mFont->GetAdjustedSize());
|
||||
@ -966,13 +976,15 @@ gfxHarfBuzzShaper::ShapeText(gfxContext *aContext,
|
||||
nsAutoTArray<hb_feature_t,20> features;
|
||||
|
||||
gfxFontEntry *entry = mFont->GetFontEntry();
|
||||
const gfxFontStyle *style = mFont->GetStyle();
|
||||
|
||||
nsDataHashtable<nsUint32HashKey,uint32_t> mergedFeatures;
|
||||
|
||||
if (MergeFontFeatures(style->featureSettings,
|
||||
mFont->GetFontEntry()->mFeatureSettings,
|
||||
aShapedText->DisableLigatures(), mergedFeatures)) {
|
||||
if (MergeFontFeatures(style,
|
||||
mFont->GetFontEntry()->mFeatureSettings,
|
||||
aShapedText->DisableLigatures(),
|
||||
mFont->GetFontEntry()->FamilyName(),
|
||||
mergedFeatures))
|
||||
{
|
||||
// enumerate result and insert into hb_feature array
|
||||
mergedFeatures.Enumerate(AddFeature, &features);
|
||||
}
|
||||
|
@ -51,6 +51,38 @@ skip-if(B2G) HTTP(..) == font-features-turkish-override-5.html font-features-tur
|
||||
HTTP(..) == font-features-order-1.html font-features-ref.html
|
||||
HTTP(..) == font-features-order-2.html font-features-noliga.html
|
||||
|
||||
# check priority of feature settings vs. font-variant subproperty
|
||||
HTTP(..) == font-features-order-3.html font-features-noliga.html
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) == font-features-order-4.html font-features-noliga.html
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) == font-features-order-5.html font-features-hlig.html
|
||||
|
||||
# check priority involving feature settings and font-variant-alternates
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) == alternates-order.html alternates-order-ref.html
|
||||
|
||||
# check that font-specific values line up with @font-face feature settings
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) == annotations.html annotations-ref.html
|
||||
|
||||
# font-variant subproperties
|
||||
# test for specific features being on and others off, based on prop values
|
||||
# (debug problems with font-variant-debug.html which displays all props)
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) == font-variant-alternates.html font-variant-alternates-ref.html
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) == font-variant-caps.html font-variant-caps-ref.html
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) == font-variant-east-asian.html font-variant-east-asian-ref.html
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) == font-variant-ligatures.html font-variant-ligatures-ref.html
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) == font-variant-numeric.html font-variant-numeric-ref.html
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) == font-variant-position.html font-variant-position-ref.html
|
||||
|
||||
# font-kerning
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) != font-kerning-normal.html font-kerning-none.html
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) != font-kerning-auto.html font-kerning-none.html
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) == font-kerning-auto.html font-kerning-normal.html
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) == font-kerning-normal.html font-kerning-kern.html
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) == font-kerning-none.html font-kerning-nokern.html
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) == font-kerning-1.html font-kerning-none.html
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) == font-kerning-2.html font-kerning-normal.html
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) == font-kerning-3.html font-kerning-none.html
|
||||
pref(layout.css.font-features.enabled,true) HTTP(..) != font-kerning-table-none.html font-kerning-table-normal.html
|
||||
|
||||
# sanity check for kerning - with no spaces, kerning should occur
|
||||
HTTP(..) == kerning-sanity-check-kern.html kerning-sanity-check-default.html
|
||||
HTTP(..) != kerning-sanity-check-nokern.html kerning-sanity-check-default.html
|
||||
|
@ -537,6 +537,22 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const
|
||||
*data->ValueFor(eCSSProperty_font_feature_settings);
|
||||
const nsCSSValue &languageOverride =
|
||||
*data->ValueFor(eCSSProperty_font_language_override);
|
||||
const nsCSSValue &fontKerning =
|
||||
*data->ValueFor(eCSSProperty_font_kerning);
|
||||
const nsCSSValue &fontSynthesis =
|
||||
*data->ValueFor(eCSSProperty_font_synthesis);
|
||||
const nsCSSValue &fontVariantAlternates =
|
||||
*data->ValueFor(eCSSProperty_font_variant_alternates);
|
||||
const nsCSSValue &fontVariantCaps =
|
||||
*data->ValueFor(eCSSProperty_font_variant_caps);
|
||||
const nsCSSValue &fontVariantEastAsian =
|
||||
*data->ValueFor(eCSSProperty_font_variant_east_asian);
|
||||
const nsCSSValue &fontVariantLigatures =
|
||||
*data->ValueFor(eCSSProperty_font_variant_ligatures);
|
||||
const nsCSSValue &fontVariantNumeric =
|
||||
*data->ValueFor(eCSSProperty_font_variant_numeric);
|
||||
const nsCSSValue &fontVariantPosition =
|
||||
*data->ValueFor(eCSSProperty_font_variant_position);
|
||||
|
||||
if (systemFont &&
|
||||
systemFont->GetUnit() != eCSSUnit_None &&
|
||||
@ -550,21 +566,39 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const
|
||||
stretch.GetUnit() != eCSSUnit_System_Font ||
|
||||
sizeAdjust.GetUnit() != eCSSUnit_System_Font ||
|
||||
featureSettings.GetUnit() != eCSSUnit_System_Font ||
|
||||
languageOverride.GetUnit() != eCSSUnit_System_Font) {
|
||||
languageOverride.GetUnit() != eCSSUnit_System_Font ||
|
||||
fontKerning.GetUnit() != eCSSUnit_System_Font ||
|
||||
fontSynthesis.GetUnit() != eCSSUnit_System_Font ||
|
||||
fontVariantAlternates.GetUnit() != eCSSUnit_System_Font ||
|
||||
fontVariantCaps.GetUnit() != eCSSUnit_System_Font ||
|
||||
fontVariantEastAsian.GetUnit() != eCSSUnit_System_Font ||
|
||||
fontVariantLigatures.GetUnit() != eCSSUnit_System_Font ||
|
||||
fontVariantNumeric.GetUnit() != eCSSUnit_System_Font ||
|
||||
fontVariantPosition.GetUnit() != eCSSUnit_System_Font) {
|
||||
// This can't be represented as a shorthand.
|
||||
return;
|
||||
}
|
||||
systemFont->AppendToString(eCSSProperty__x_system_font, aValue);
|
||||
} else {
|
||||
// The font-stretch, font-size-adjust,
|
||||
// -moz-font-feature-settings, and -moz-font-language-override
|
||||
// properties are reset by this shorthand property to their
|
||||
// -moz-font-feature-settings, -moz-font-language-override
|
||||
// along with kerning, synthesis and other font-variant
|
||||
// subproperties are reset by this shorthand property to their
|
||||
// initial values, but can't be represented in its syntax.
|
||||
if (stretch.GetUnit() != eCSSUnit_Enumerated ||
|
||||
stretch.GetIntValue() != NS_STYLE_FONT_STRETCH_NORMAL ||
|
||||
sizeAdjust.GetUnit() != eCSSUnit_None ||
|
||||
featureSettings.GetUnit() != eCSSUnit_Normal ||
|
||||
languageOverride.GetUnit() != eCSSUnit_Normal) {
|
||||
languageOverride.GetUnit() != eCSSUnit_Normal ||
|
||||
fontKerning.GetIntValue() != NS_FONT_KERNING_AUTO ||
|
||||
fontSynthesis.GetIntValue() !=
|
||||
(NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE) ||
|
||||
fontVariantAlternates.GetUnit() != eCSSUnit_Normal ||
|
||||
fontVariantCaps.GetUnit() != eCSSUnit_Normal ||
|
||||
fontVariantEastAsian.GetUnit() != eCSSUnit_Normal ||
|
||||
fontVariantLigatures.GetUnit() != eCSSUnit_Normal ||
|
||||
fontVariantNumeric.GetUnit() != eCSSUnit_Normal ||
|
||||
fontVariantPosition.GetUnit() != eCSSUnit_Normal) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,8 @@ public:
|
||||
KEYFRAME_RULE,
|
||||
KEYFRAMES_RULE,
|
||||
DOCUMENT_RULE,
|
||||
SUPPORTS_RULE
|
||||
SUPPORTS_RULE,
|
||||
FONT_FEATURE_VALUES_RULE
|
||||
};
|
||||
|
||||
virtual int32_t GetType() const = 0;
|
||||
|
@ -9,5 +9,8 @@ CSS_FONT_DESC(font-weight, Weight)
|
||||
CSS_FONT_DESC(font-stretch, Stretch)
|
||||
CSS_FONT_DESC(src, Src)
|
||||
CSS_FONT_DESC(unicode-range, UnicodeRange)
|
||||
|
||||
/* Note: the parsing code explicitly also accepts font-feature-settings
|
||||
and font-language-override. */
|
||||
CSS_FONT_DESC(-moz-font-feature-settings, FontFeatureSettings)
|
||||
CSS_FONT_DESC(-moz-font-language-override, FontLanguageOverride)
|
||||
|
@ -163,11 +163,14 @@ CSS_KEY(activeborder, activeborder)
|
||||
CSS_KEY(activecaption, activecaption)
|
||||
CSS_KEY(alias, alias)
|
||||
CSS_KEY(all, all)
|
||||
CSS_KEY(all-petite-caps, all_petite_caps)
|
||||
CSS_KEY(all-scroll, all_scroll)
|
||||
CSS_KEY(all-small-caps, all_small_caps)
|
||||
CSS_KEY(alpha, alpha)
|
||||
CSS_KEY(alternate, alternate)
|
||||
CSS_KEY(alternate-reverse, alternate_reverse)
|
||||
CSS_KEY(always, always)
|
||||
CSS_KEY(annotation, annotation)
|
||||
CSS_KEY(appworkspace, appworkspace)
|
||||
CSS_KEY(armenian, armenian)
|
||||
CSS_KEY(auto, auto)
|
||||
@ -200,6 +203,7 @@ CSS_KEY(captiontext, captiontext)
|
||||
CSS_KEY(cell, cell)
|
||||
CSS_KEY(center, center)
|
||||
CSS_KEY(ch, ch)
|
||||
CSS_KEY(character-variant, character_variant)
|
||||
CSS_KEY(circle, circle)
|
||||
CSS_KEY(cjk-ideographic, cjk_ideographic)
|
||||
CSS_KEY(clip, clip)
|
||||
@ -209,6 +213,7 @@ CSS_KEY(closest-side, closest_side)
|
||||
CSS_KEY(cm, cm)
|
||||
CSS_KEY(col-resize, col_resize)
|
||||
CSS_KEY(collapse, collapse)
|
||||
CSS_KEY(common-ligatures, common_ligatures)
|
||||
CSS_KEY(column, column)
|
||||
CSS_KEY(column-reverse, column_reverse)
|
||||
CSS_KEY(condensed, condensed)
|
||||
@ -217,6 +222,7 @@ CSS_KEY(content-box, content_box)
|
||||
CSS_KEY(context-menu, context_menu)
|
||||
CSS_KEY(continuous, continuous)
|
||||
CSS_KEY(copy, copy)
|
||||
CSS_KEY(contextual, contextual)
|
||||
CSS_KEY(cover, cover)
|
||||
CSS_KEY(crop, crop)
|
||||
CSS_KEY(cross, cross)
|
||||
@ -227,9 +233,11 @@ CSS_KEY(decimal, decimal)
|
||||
CSS_KEY(decimal-leading-zero, decimal_leading_zero)
|
||||
CSS_KEY(default, default)
|
||||
CSS_KEY(deg, deg)
|
||||
CSS_KEY(diagonal-fractions, diagonal_fractions)
|
||||
CSS_KEY(dialog, dialog)
|
||||
CSS_KEY(disabled, disabled)
|
||||
CSS_KEY(disc, disc)
|
||||
CSS_KEY(discretionary-ligatures, discretionary_ligatures)
|
||||
CSS_KEY(dotted, dotted)
|
||||
CSS_KEY(double, double)
|
||||
CSS_KEY(e-resize, e_resize)
|
||||
@ -273,6 +281,8 @@ CSS_KEY(highlight, highlight)
|
||||
CSS_KEY(highlighttext, highlighttext)
|
||||
CSS_KEY(hiragana, hiragana)
|
||||
CSS_KEY(hiragana-iroha, hiragana_iroha)
|
||||
CSS_KEY(historical-forms, historical_forms)
|
||||
CSS_KEY(historical-ligatures, historical_ligatures)
|
||||
CSS_KEY(horizontal, horizontal)
|
||||
CSS_KEY(hz, hz)
|
||||
CSS_KEY(icon, icon)
|
||||
@ -297,6 +307,10 @@ CSS_KEY(inset, inset)
|
||||
CSS_KEY(inside, inside)
|
||||
CSS_KEY(interpolatematrix, interpolatematrix)
|
||||
CSS_KEY(italic, italic)
|
||||
CSS_KEY(jis78, jis78)
|
||||
CSS_KEY(jis83, jis83)
|
||||
CSS_KEY(jis90, jis90)
|
||||
CSS_KEY(jis04, jis04)
|
||||
CSS_KEY(justify, justify)
|
||||
CSS_KEY(katakana, katakana)
|
||||
CSS_KEY(katakana-iroha, katakana_iroha)
|
||||
@ -309,6 +323,7 @@ CSS_KEY(left, left)
|
||||
CSS_KEY(lighter, lighter)
|
||||
CSS_KEY(line-through, line_through)
|
||||
CSS_KEY(linear, linear)
|
||||
CSS_KEY(lining-nums, lining_nums)
|
||||
CSS_KEY(list-item, list_item)
|
||||
CSS_KEY(logical, logical)
|
||||
CSS_KEY(lower-alpha, lower_alpha)
|
||||
@ -337,7 +352,11 @@ CSS_KEY(narrower, narrower)
|
||||
CSS_KEY(ne-resize, ne_resize)
|
||||
CSS_KEY(nesw-resize, nesw_resize)
|
||||
CSS_KEY(no-close-quote, no_close_quote)
|
||||
CSS_KEY(no-common-ligatures, no_common_ligatures)
|
||||
CSS_KEY(no-contextual, no_contextual)
|
||||
CSS_KEY(no-discretionary-ligatures, no_discretionary_ligatures)
|
||||
CSS_KEY(no-drop, no_drop)
|
||||
CSS_KEY(no-historical-ligatures, no_historical_ligatures)
|
||||
CSS_KEY(no-open-quote, no_open_quote)
|
||||
CSS_KEY(no-repeat, no_repeat)
|
||||
CSS_KEY(none, none)
|
||||
@ -348,7 +367,10 @@ CSS_KEY(ns-resize, ns_resize)
|
||||
CSS_KEY(nw-resize, nw_resize)
|
||||
CSS_KEY(nwse-resize, nwse_resize)
|
||||
CSS_KEY(oblique, oblique)
|
||||
CSS_KEY(oldstyle-nums, oldstyle_nums)
|
||||
CSS_KEY(open-quote, open_quote)
|
||||
CSS_KEY(ordinal, ordinal)
|
||||
CSS_KEY(ornaments, ornaments)
|
||||
CSS_KEY(outset, outset)
|
||||
CSS_KEY(outside, outside)
|
||||
CSS_KEY(overline, overline)
|
||||
@ -357,6 +379,7 @@ CSS_KEY(painted, painted)
|
||||
CSS_KEY(paused, paused)
|
||||
CSS_KEY(pc, pc)
|
||||
CSS_KEY(perspective, perspective)
|
||||
CSS_KEY(petite-caps, petite_caps)
|
||||
CSS_KEY(physical, physical)
|
||||
CSS_KEY(pointer, pointer)
|
||||
CSS_KEY(portrait, portrait)
|
||||
@ -366,6 +389,8 @@ CSS_KEY(pre-line, pre_line)
|
||||
CSS_KEY(preserve-3d, preserve_3d)
|
||||
CSS_KEY(progress, progress)
|
||||
CSS_KEY(progressive, progressive)
|
||||
CSS_KEY(proportional-nums, proportional_nums)
|
||||
CSS_KEY(proportional-width, proportional_width)
|
||||
CSS_KEY(pt, pt)
|
||||
CSS_KEY(px, px)
|
||||
CSS_KEY(rad, rad)
|
||||
@ -388,6 +413,7 @@ CSS_KEY(row, row)
|
||||
CSS_KEY(row-resize, row_resize)
|
||||
CSS_KEY(row-reverse, row_reverse)
|
||||
CSS_KEY(rtl, rtl)
|
||||
CSS_KEY(ruby, ruby)
|
||||
CSS_KEY(running, running)
|
||||
CSS_KEY(s, s)
|
||||
CSS_KEY(s-resize, s_resize)
|
||||
@ -409,9 +435,11 @@ CSS_KEY(semi-condensed, semi_condensed)
|
||||
CSS_KEY(semi-expanded, semi_expanded)
|
||||
CSS_KEY(separate, separate)
|
||||
CSS_KEY(show, show)
|
||||
CSS_KEY(simplified, simplified)
|
||||
CSS_KEY(skew, skew)
|
||||
CSS_KEY(skewx, skewx)
|
||||
CSS_KEY(skewy, skewy)
|
||||
CSS_KEY(slashed-zero, slashed_zero)
|
||||
CSS_KEY(small, small)
|
||||
CSS_KEY(small-caps, small_caps)
|
||||
CSS_KEY(small-caption, small_caption)
|
||||
@ -421,6 +449,7 @@ CSS_KEY(solid, solid)
|
||||
CSS_KEY(space-around, space_around)
|
||||
CSS_KEY(space-between, space_between)
|
||||
CSS_KEY(square, square)
|
||||
CSS_KEY(stacked-fractions, stacked_fractions)
|
||||
CSS_KEY(start, start)
|
||||
CSS_KEY(static, static)
|
||||
CSS_KEY(status-bar, status_bar)
|
||||
@ -429,9 +458,13 @@ CSS_KEY(step-start, step_start)
|
||||
CSS_KEY(stretch, stretch)
|
||||
CSS_KEY(stretch-to-fit, stretch_to_fit)
|
||||
CSS_KEY(stroke, stroke)
|
||||
CSS_KEY(style, style)
|
||||
CSS_KEY(styleset, styleset)
|
||||
CSS_KEY(stylistic, stylistic)
|
||||
CSS_KEY(sub, sub)
|
||||
CSS_KEY(super, super)
|
||||
CSS_KEY(sw-resize, sw_resize)
|
||||
CSS_KEY(swash, swash)
|
||||
CSS_KEY(table, table)
|
||||
CSS_KEY(table-caption, table_caption)
|
||||
CSS_KEY(table-cell, table_cell)
|
||||
@ -441,6 +474,7 @@ CSS_KEY(table-footer-group, table_footer_group)
|
||||
CSS_KEY(table-header-group, table_header_group)
|
||||
CSS_KEY(table-row, table_row)
|
||||
CSS_KEY(table-row-group, table_row_group)
|
||||
CSS_KEY(tabular-nums, tabular_nums)
|
||||
CSS_KEY(text, text)
|
||||
CSS_KEY(text-bottom, text_bottom)
|
||||
CSS_KEY(text-top, text_top)
|
||||
@ -451,9 +485,11 @@ CSS_KEY(threedface, threedface)
|
||||
CSS_KEY(threedhighlight, threedhighlight)
|
||||
CSS_KEY(threedlightshadow, threedlightshadow)
|
||||
CSS_KEY(threedshadow, threedshadow)
|
||||
CSS_KEY(titling-caps, titling_caps)
|
||||
CSS_KEY(toggle, toggle)
|
||||
CSS_KEY(top, top)
|
||||
CSS_KEY(top-outside, top_outside)
|
||||
CSS_KEY(traditional, traditional)
|
||||
CSS_KEY(translate, translate)
|
||||
CSS_KEY(translate3d, translate3d)
|
||||
CSS_KEY(translatex, translatex)
|
||||
@ -464,6 +500,7 @@ CSS_KEY(tri-state, tri_state)
|
||||
CSS_KEY(ultra-condensed, ultra_condensed)
|
||||
CSS_KEY(ultra-expanded, ultra_expanded)
|
||||
CSS_KEY(underline, underline)
|
||||
CSS_KEY(unicase, unicase)
|
||||
CSS_KEY(upper-alpha, upper_alpha)
|
||||
CSS_KEY(upper-latin, upper_latin)
|
||||
CSS_KEY(upper-roman, upper_roman)
|
||||
@ -477,6 +514,7 @@ CSS_KEY(visiblestroke, visiblestroke)
|
||||
CSS_KEY(w-resize, w_resize)
|
||||
CSS_KEY(wait, wait)
|
||||
CSS_KEY(wavy, wavy)
|
||||
CSS_KEY(weight, weight)
|
||||
CSS_KEY(wider, wider)
|
||||
CSS_KEY(window, window)
|
||||
CSS_KEY(windowframe, windowframe)
|
||||
|
@ -375,6 +375,9 @@ protected:
|
||||
void* aProcessData);
|
||||
|
||||
bool ParseFontFaceRule(RuleAppendFunc aAppendFunc, void* aProcessData);
|
||||
bool ParseFontFeatureValuesRule(RuleAppendFunc aAppendFunc,
|
||||
void* aProcessData);
|
||||
bool ParseFontFeatureValueSet(nsCSSFontFeatureValuesRule *aRule);
|
||||
bool ParseFontDescriptor(nsCSSFontFaceRule* aRule);
|
||||
bool ParseFontDescriptorValue(nsCSSFontDesc aDescID,
|
||||
nsCSSValue& aValue);
|
||||
@ -562,6 +565,14 @@ protected:
|
||||
bool ParseCounterData(nsCSSProperty aPropID);
|
||||
bool ParseCursor();
|
||||
bool ParseFont();
|
||||
bool ParseFontSynthesis(nsCSSValue& aValue);
|
||||
bool ParseSingleAlternate(int32_t& aWhichFeature, nsCSSValue& aValue);
|
||||
bool ParseFontVariantAlternates(nsCSSValue& aValue);
|
||||
bool ParseBitmaskValues(nsCSSValue& aValue, const int32_t aKeywordTable[],
|
||||
const int32_t aMasks[]);
|
||||
bool ParseFontVariantEastAsian(nsCSSValue& aValue);
|
||||
bool ParseFontVariantLigatures(nsCSSValue& aValue);
|
||||
bool ParseFontVariantNumeric(nsCSSValue& aValue);
|
||||
bool ParseFontWeight(nsCSSValue& aValue);
|
||||
bool ParseOneFamily(nsAString& aFamily, bool& aOneKeyword);
|
||||
bool ParseFamily(nsCSSValue& aValue);
|
||||
@ -665,12 +676,13 @@ protected:
|
||||
/* Functions for transform Parsing */
|
||||
bool ParseSingleTransform(bool aIsPrefixed, nsCSSValue& aValue, bool& aIs3D);
|
||||
bool ParseFunction(const nsString &aFunction, const int32_t aAllowedTypes[],
|
||||
uint16_t aMinElems, uint16_t aMaxElems,
|
||||
nsCSSValue &aValue);
|
||||
int32_t aVariantMaskAll, uint16_t aMinElems,
|
||||
uint16_t aMaxElems, nsCSSValue &aValue);
|
||||
bool ParseFunctionInternals(const int32_t aVariantMask[],
|
||||
uint16_t aMinElems,
|
||||
uint16_t aMaxElems,
|
||||
InfallibleTArray<nsCSSValue>& aOutput);
|
||||
int32_t aVariantMaskAll,
|
||||
uint16_t aMinElems,
|
||||
uint16_t aMaxElems,
|
||||
InfallibleTArray<nsCSSValue>& aOutput);
|
||||
|
||||
/* Functions for transform-origin/perspective-origin Parsing */
|
||||
bool ParseTransformOrigin(bool aPerspective);
|
||||
@ -1626,6 +1638,11 @@ CSSParserImpl::ParseAtRule(RuleAppendFunc aAppendFunc,
|
||||
parseFunc = &CSSParserImpl::ParseFontFaceRule;
|
||||
newSection = eCSSSection_General;
|
||||
|
||||
} else if (mToken.mIdent.LowerCaseEqualsLiteral("font-feature-values") &&
|
||||
nsCSSFontFeatureValuesRule::PrefEnabled()) {
|
||||
parseFunc = &CSSParserImpl::ParseFontFeatureValuesRule;
|
||||
newSection = eCSSSection_General;
|
||||
|
||||
} else if (mToken.mIdent.LowerCaseEqualsLiteral("page")) {
|
||||
parseFunc = &CSSParserImpl::ParsePageRule;
|
||||
newSection = eCSSSection_General;
|
||||
@ -2351,6 +2368,233 @@ CSSParserImpl::ParseFontDescriptor(nsCSSFontFaceRule* aRule)
|
||||
return true;
|
||||
}
|
||||
|
||||
// @font-feature-values <font-family># {
|
||||
// @<feature-type> {
|
||||
// <feature-ident> : <feature-index>+;
|
||||
// <feature-ident> : <feature-index>+;
|
||||
// ...
|
||||
// }
|
||||
// ...
|
||||
// }
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseFontFeatureValuesRule(RuleAppendFunc aAppendFunc,
|
||||
void* aData)
|
||||
{
|
||||
nsRefPtr<nsCSSFontFeatureValuesRule>
|
||||
valuesRule(new nsCSSFontFeatureValuesRule());
|
||||
|
||||
// parse family list
|
||||
nsCSSValue familyValue;
|
||||
|
||||
if (!ParseFamily(familyValue) ||
|
||||
familyValue.GetUnit() != eCSSUnit_Families)
|
||||
{
|
||||
REPORT_UNEXPECTED_TOKEN(PEFFVNoFamily);
|
||||
return false;
|
||||
}
|
||||
|
||||
// add family to rule
|
||||
nsAutoString familyList;
|
||||
bool hasGeneric;
|
||||
familyValue.GetStringValue(familyList);
|
||||
valuesRule->SetFamilyList(familyList, hasGeneric);
|
||||
|
||||
// family list has generic ==> parse error
|
||||
if (hasGeneric) {
|
||||
REPORT_UNEXPECTED_TOKEN(PEFFVGenericInFamilyList);
|
||||
return false;
|
||||
}
|
||||
|
||||
// open brace
|
||||
if (!ExpectSymbol('{', true)) {
|
||||
REPORT_UNEXPECTED_TOKEN(PEFFVBlockStart);
|
||||
return false;
|
||||
}
|
||||
|
||||
// list of sets of feature values, each set bound to a specific
|
||||
// feature-type (e.g. swash, annotation)
|
||||
for (;;) {
|
||||
if (!GetToken(true)) {
|
||||
REPORT_UNEXPECTED_EOF(PEFFVUnexpectedEOF);
|
||||
break;
|
||||
}
|
||||
if (mToken.IsSymbol('}')) { // done!
|
||||
UngetToken();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ParseFontFeatureValueSet(valuesRule)) {
|
||||
if (!SkipAtRule(false)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ExpectSymbol('}', true)) {
|
||||
REPORT_UNEXPECTED_TOKEN(PEFFVUnexpectedBlockEnd);
|
||||
SkipUntil('}');
|
||||
return false;
|
||||
}
|
||||
|
||||
(*aAppendFunc)(valuesRule, aData);
|
||||
return true;
|
||||
}
|
||||
|
||||
#define NUMVALUES_NO_LIMIT 0xFFFF
|
||||
|
||||
// parse a single value set containing name-value pairs for a single feature type
|
||||
// @<feature-type> { [ <feature-ident> : <feature-index>+ ; ]* }
|
||||
// Ex: @swash { flowing: 1; delicate: 2; }
|
||||
bool
|
||||
CSSParserImpl::ParseFontFeatureValueSet(nsCSSFontFeatureValuesRule
|
||||
*aFeatureValuesRule)
|
||||
{
|
||||
// -- @keyword (e.g. swash, styleset)
|
||||
if (eCSSToken_AtKeyword != mToken.mType) {
|
||||
REPORT_UNEXPECTED_TOKEN(PEFontFeatureValuesNoAt);
|
||||
OUTPUT_ERROR();
|
||||
UngetToken();
|
||||
return false;
|
||||
}
|
||||
|
||||
// which font-specific variant of font-variant-alternates
|
||||
int32_t whichVariant;
|
||||
nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(mToken.mIdent);
|
||||
if (keyword == eCSSKeyword_UNKNOWN ||
|
||||
!nsCSSProps::FindKeyword(keyword,
|
||||
nsCSSProps::kFontVariantAlternatesFuncsKTable,
|
||||
whichVariant))
|
||||
{
|
||||
if (!NonMozillaVendorIdentifier(mToken.mIdent)) {
|
||||
REPORT_UNEXPECTED_TOKEN(PEFFVUnknownFontVariantPropValue);
|
||||
OUTPUT_ERROR();
|
||||
}
|
||||
UngetToken();
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoString featureType(mToken.mIdent);
|
||||
|
||||
// open brace
|
||||
if (!ExpectSymbol('{', true)) {
|
||||
REPORT_UNEXPECTED_TOKEN(PEFFVValueSetStart);
|
||||
return false;
|
||||
}
|
||||
|
||||
// styleset and character-variant can be multi-valued, otherwise single value
|
||||
int32_t limitNumValues;
|
||||
|
||||
switch (keyword) {
|
||||
case eCSSKeyword_styleset:
|
||||
limitNumValues = NUMVALUES_NO_LIMIT;
|
||||
break;
|
||||
case eCSSKeyword_character_variant:
|
||||
limitNumValues = 2;
|
||||
break;
|
||||
default:
|
||||
limitNumValues = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// -- ident integer+ [, ident integer+]
|
||||
nsAutoTArray<gfxFontFeatureValueSet::ValueList, 5> values;
|
||||
|
||||
// list of font-feature-values-declaration's
|
||||
for (;;) {
|
||||
nsAutoString valueId;
|
||||
|
||||
if (!GetToken(true)) {
|
||||
REPORT_UNEXPECTED_EOF(PEFFVUnexpectedEOF);
|
||||
break;
|
||||
}
|
||||
|
||||
// ignore extra semicolons
|
||||
if (mToken.IsSymbol(';')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// close brace ==> done
|
||||
if (mToken.IsSymbol('}')) {
|
||||
break;
|
||||
}
|
||||
|
||||
// ident
|
||||
if (eCSSToken_Ident != mToken.mType) {
|
||||
REPORT_UNEXPECTED_TOKEN(PEFFVExpectedIdent);
|
||||
if (!SkipDeclaration(true)) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
valueId.Assign(mToken.mIdent);
|
||||
|
||||
// colon
|
||||
if (!ExpectSymbol(':', true)) {
|
||||
REPORT_UNEXPECTED_TOKEN(PEParseDeclarationNoColon);
|
||||
OUTPUT_ERROR();
|
||||
if (!SkipDeclaration(true)) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// value list
|
||||
nsAutoTArray<uint32_t,4> featureSelectors;
|
||||
|
||||
nsCSSValue intValue;
|
||||
while (ParseNonNegativeVariant(intValue, VARIANT_INTEGER, nullptr)) {
|
||||
featureSelectors.AppendElement(uint32_t(intValue.GetIntValue()));
|
||||
}
|
||||
|
||||
int32_t numValues = featureSelectors.Length();
|
||||
|
||||
if (numValues == 0) {
|
||||
REPORT_UNEXPECTED_TOKEN(PEFFVExpectedValue);
|
||||
OUTPUT_ERROR();
|
||||
if (!SkipDeclaration(true)) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (numValues > limitNumValues) {
|
||||
REPORT_UNEXPECTED_P(PEFFVTooManyValues, featureType);
|
||||
OUTPUT_ERROR();
|
||||
if (!SkipDeclaration(true)) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!GetToken(true)) {
|
||||
REPORT_UNEXPECTED_EOF(PEFFVUnexpectedEOF);
|
||||
gfxFontFeatureValueSet::ValueList v(valueId, featureSelectors);
|
||||
values.AppendElement(v);
|
||||
break;
|
||||
}
|
||||
|
||||
// ';' or '}' to end definition
|
||||
if (!mToken.IsSymbol(';') && !mToken.IsSymbol('}')) {
|
||||
REPORT_UNEXPECTED_TOKEN(PEFFVValueDefinitionTrailing);
|
||||
OUTPUT_ERROR();
|
||||
if (!SkipDeclaration(true)) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
gfxFontFeatureValueSet::ValueList v(valueId, featureSelectors);
|
||||
values.AppendElement(v);
|
||||
|
||||
if (mToken.IsSymbol('}')) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
aFeatureValuesRule->AddValueList(whichVariant, values);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseKeyframesRule(RuleAppendFunc aAppendFunc, void* aData)
|
||||
@ -6370,6 +6614,16 @@ CSSParserImpl::ParseSingleValueProperty(nsCSSValue& aValue,
|
||||
switch (aPropID) {
|
||||
case eCSSProperty_font_family:
|
||||
return ParseFamily(aValue);
|
||||
case eCSSProperty_font_synthesis:
|
||||
return ParseFontSynthesis(aValue);
|
||||
case eCSSProperty_font_variant_alternates:
|
||||
return ParseFontVariantAlternates(aValue);
|
||||
case eCSSProperty_font_variant_east_asian:
|
||||
return ParseFontVariantEastAsian(aValue);
|
||||
case eCSSProperty_font_variant_ligatures:
|
||||
return ParseFontVariantLigatures(aValue);
|
||||
case eCSSProperty_font_variant_numeric:
|
||||
return ParseFontVariantNumeric(aValue);
|
||||
case eCSSProperty_font_feature_settings:
|
||||
return ParseFontFeatureSettings(aValue);
|
||||
case eCSSProperty_font_weight:
|
||||
@ -8303,6 +8557,14 @@ CSSParserImpl::ParseFont()
|
||||
AppendValue(eCSSProperty_font_size_adjust, family);
|
||||
AppendValue(eCSSProperty_font_feature_settings, family);
|
||||
AppendValue(eCSSProperty_font_language_override, family);
|
||||
AppendValue(eCSSProperty_font_kerning, family);
|
||||
AppendValue(eCSSProperty_font_synthesis, family);
|
||||
AppendValue(eCSSProperty_font_variant_alternates, family);
|
||||
AppendValue(eCSSProperty_font_variant_caps, family);
|
||||
AppendValue(eCSSProperty_font_variant_east_asian, family);
|
||||
AppendValue(eCSSProperty_font_variant_ligatures, family);
|
||||
AppendValue(eCSSProperty_font_variant_numeric, family);
|
||||
AppendValue(eCSSProperty_font_variant_position, family);
|
||||
}
|
||||
else {
|
||||
AppendValue(eCSSProperty__x_system_font, family);
|
||||
@ -8317,6 +8579,14 @@ CSSParserImpl::ParseFont()
|
||||
AppendValue(eCSSProperty_font_size_adjust, systemFont);
|
||||
AppendValue(eCSSProperty_font_feature_settings, systemFont);
|
||||
AppendValue(eCSSProperty_font_language_override, systemFont);
|
||||
AppendValue(eCSSProperty_font_kerning, systemFont);
|
||||
AppendValue(eCSSProperty_font_synthesis, systemFont);
|
||||
AppendValue(eCSSProperty_font_variant_alternates, systemFont);
|
||||
AppendValue(eCSSProperty_font_variant_caps, systemFont);
|
||||
AppendValue(eCSSProperty_font_variant_east_asian, systemFont);
|
||||
AppendValue(eCSSProperty_font_variant_ligatures, systemFont);
|
||||
AppendValue(eCSSProperty_font_variant_numeric, systemFont);
|
||||
AppendValue(eCSSProperty_font_variant_position, systemFont);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -8380,12 +8650,287 @@ CSSParserImpl::ParseFont()
|
||||
AppendValue(eCSSProperty_font_size_adjust, nsCSSValue(eCSSUnit_None));
|
||||
AppendValue(eCSSProperty_font_feature_settings, nsCSSValue(eCSSUnit_Normal));
|
||||
AppendValue(eCSSProperty_font_language_override, nsCSSValue(eCSSUnit_Normal));
|
||||
AppendValue(eCSSProperty_font_kerning,
|
||||
nsCSSValue(NS_FONT_KERNING_AUTO, eCSSUnit_Enumerated));
|
||||
AppendValue(eCSSProperty_font_synthesis,
|
||||
nsCSSValue(NS_FONT_SYNTHESIS_WEIGHT | NS_FONT_SYNTHESIS_STYLE,
|
||||
eCSSUnit_Enumerated));
|
||||
AppendValue(eCSSProperty_font_variant_alternates,
|
||||
nsCSSValue(eCSSUnit_Normal));
|
||||
AppendValue(eCSSProperty_font_variant_caps, nsCSSValue(eCSSUnit_Normal));
|
||||
AppendValue(eCSSProperty_font_variant_east_asian,
|
||||
nsCSSValue(eCSSUnit_Normal));
|
||||
AppendValue(eCSSProperty_font_variant_ligatures,
|
||||
nsCSSValue(eCSSUnit_Normal));
|
||||
AppendValue(eCSSProperty_font_variant_numeric,
|
||||
nsCSSValue(eCSSUnit_Normal));
|
||||
AppendValue(eCSSProperty_font_variant_position,
|
||||
nsCSSValue(eCSSUnit_Normal));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseFontSynthesis(nsCSSValue& aValue)
|
||||
{
|
||||
if (!ParseVariant(aValue, VARIANT_HK | VARIANT_NONE,
|
||||
nsCSSProps::kFontSynthesisKTable)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// first value 'none' ==> done
|
||||
if (eCSSUnit_None == aValue.GetUnit() ||
|
||||
eCSSUnit_Initial == aValue.GetUnit() ||
|
||||
eCSSUnit_Inherit == aValue.GetUnit())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// look for a second value
|
||||
int32_t intValue = aValue.GetIntValue();
|
||||
nsCSSValue nextValue;
|
||||
|
||||
if (ParseEnum(nextValue, nsCSSProps::kFontSynthesisKTable)) {
|
||||
int32_t nextIntValue = nextValue.GetIntValue();
|
||||
if (nextIntValue & intValue) {
|
||||
return false;
|
||||
}
|
||||
aValue.SetIntValue(nextIntValue | intValue, eCSSUnit_Enumerated);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// font-variant-alternates allows for a combination of multiple
|
||||
// simple enumerated values and functional values. Functional values have
|
||||
// parameter lists with one or more idents which are later resolved
|
||||
// based on values defined in @font-feature-value rules.
|
||||
//
|
||||
// font-variant-alternates: swash(flowing), historical-forms, styleset(alt-g, alt-m);
|
||||
//
|
||||
// So for this the nsCSSValue is set to a pair value, with one
|
||||
// value for a bitmask of both simple and functional property values
|
||||
// and another value containing a ValuePairList with lists of idents
|
||||
// for each functional property value.
|
||||
//
|
||||
// pairValue
|
||||
// o intValue
|
||||
// NS_FONT_VARIANT_ALTERNATES_SWASH |
|
||||
// NS_FONT_VARIANT_ALTERNATES_STYLESET
|
||||
// o valuePairList, each element with
|
||||
// - intValue - indicates which alternate
|
||||
// - string or valueList of strings
|
||||
//
|
||||
// Note: when only 'historical-forms' is specified, there are no
|
||||
// functional values to store, in which case the valuePairList is a
|
||||
// single element dummy list. In all other cases, the length of the
|
||||
// list will match the number of functional values.
|
||||
|
||||
#define MAX_ALLOWED_FEATURES 512
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseSingleAlternate(int32_t& aWhichFeature,
|
||||
nsCSSValue& aValue)
|
||||
{
|
||||
if (!GetToken(true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isIdent = (mToken.mType == eCSSToken_Ident);
|
||||
if (mToken.mType != eCSSToken_Function && !isIdent) {
|
||||
UngetToken();
|
||||
return false;
|
||||
}
|
||||
|
||||
// ident ==> simple enumerated prop val (e.g. historical-forms)
|
||||
// function ==> e.g. swash(flowing) styleset(alt-g, alt-m)
|
||||
|
||||
nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(mToken.mIdent);
|
||||
if (!(eCSSKeyword_UNKNOWN < keyword &&
|
||||
nsCSSProps::FindKeyword(keyword,
|
||||
(isIdent ?
|
||||
nsCSSProps::kFontVariantAlternatesKTable :
|
||||
nsCSSProps::kFontVariantAlternatesFuncsKTable),
|
||||
aWhichFeature)))
|
||||
{
|
||||
// failed, pop token
|
||||
UngetToken();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isIdent) {
|
||||
aValue.SetIntValue(aWhichFeature, eCSSUnit_Enumerated);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t maxElems = 1;
|
||||
if (keyword == eCSSKeyword_styleset ||
|
||||
keyword == eCSSKeyword_character_variant) {
|
||||
maxElems = MAX_ALLOWED_FEATURES;
|
||||
}
|
||||
return ParseFunction(mToken.mIdent, nullptr, VARIANT_IDENTIFIER,
|
||||
1, maxElems, aValue);
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseFontVariantAlternates(nsCSSValue& aValue)
|
||||
{
|
||||
if (ParseVariant(aValue, VARIANT_INHERIT | VARIANT_NORMAL, nullptr)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// iterate through parameters
|
||||
nsCSSValue listValue;
|
||||
int32_t feature, featureFlags = 0;
|
||||
|
||||
// if no functional values, this may be a list with a single, unused element
|
||||
listValue.SetListValue();
|
||||
|
||||
nsCSSValueList* list = nullptr;
|
||||
nsCSSValue value;
|
||||
while (ParseSingleAlternate(feature, value)) {
|
||||
|
||||
// check to make sure value not already set
|
||||
if (feature == 0 ||
|
||||
feature & featureFlags) {
|
||||
return false;
|
||||
}
|
||||
|
||||
featureFlags |= feature;
|
||||
|
||||
// if function, need to add to the list of functions
|
||||
if (value.GetUnit() == eCSSUnit_Function) {
|
||||
if (!list) {
|
||||
list = listValue.GetListValue();
|
||||
} else {
|
||||
list->mNext = new nsCSSValueList;
|
||||
list = list->mNext;
|
||||
}
|
||||
list->mValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
nsCSSValue featureValue;
|
||||
featureValue.SetIntValue(featureFlags, eCSSUnit_Enumerated);
|
||||
aValue.SetPairValue(featureValue, listValue);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define MASK_END_VALUE -1
|
||||
|
||||
// aMasks - array of masks for mutually-exclusive property values,
|
||||
// e.g. proportial-nums, tabular-nums
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseBitmaskValues(nsCSSValue& aValue,
|
||||
const int32_t aKeywordTable[],
|
||||
const int32_t aMasks[])
|
||||
{
|
||||
if (!ParseVariant(aValue, VARIANT_HMK, aKeywordTable)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// first value 'normal', 'inherit', 'initial' ==> done
|
||||
if (eCSSUnit_Normal == aValue.GetUnit() ||
|
||||
eCSSUnit_Initial == aValue.GetUnit() ||
|
||||
eCSSUnit_Inherit == aValue.GetUnit())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// look for more values
|
||||
nsCSSValue nextValue;
|
||||
int32_t mergedValue = aValue.GetIntValue();
|
||||
|
||||
while (ParseEnum(nextValue, aKeywordTable))
|
||||
{
|
||||
int32_t nextIntValue = nextValue.GetIntValue();
|
||||
|
||||
// check to make sure value not already set
|
||||
if (nextIntValue & mergedValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const int32_t *m = aMasks;
|
||||
int32_t c = 0;
|
||||
|
||||
while (*m != MASK_END_VALUE) {
|
||||
if (*m & nextIntValue) {
|
||||
c = mergedValue & *m;
|
||||
break;
|
||||
}
|
||||
m++;
|
||||
}
|
||||
|
||||
if (c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mergedValue |= nextIntValue;
|
||||
}
|
||||
|
||||
aValue.SetIntValue(mergedValue, eCSSUnit_Enumerated);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const int32_t maskEastAsian[] = {
|
||||
NS_FONT_VARIANT_EAST_ASIAN_VARIANT_MASK,
|
||||
NS_FONT_VARIANT_EAST_ASIAN_WIDTH_MASK,
|
||||
MASK_END_VALUE
|
||||
};
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseFontVariantEastAsian(nsCSSValue& aValue)
|
||||
{
|
||||
NS_ASSERTION(maskEastAsian[NS_ARRAY_LENGTH(maskEastAsian) - 1] ==
|
||||
MASK_END_VALUE,
|
||||
"incorrectly terminated array");
|
||||
|
||||
return ParseBitmaskValues(aValue, nsCSSProps::kFontVariantEastAsianKTable,
|
||||
maskEastAsian);
|
||||
}
|
||||
|
||||
static const int32_t maskLigatures[] = {
|
||||
NS_FONT_VARIANT_LIGATURES_COMMON_MASK,
|
||||
NS_FONT_VARIANT_LIGATURES_DISCRETIONARY_MASK,
|
||||
NS_FONT_VARIANT_LIGATURES_HISTORICAL_MASK,
|
||||
NS_FONT_VARIANT_LIGATURES_CONTEXTUAL_MASK,
|
||||
MASK_END_VALUE
|
||||
};
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseFontVariantLigatures(nsCSSValue& aValue)
|
||||
{
|
||||
NS_ASSERTION(maskLigatures[NS_ARRAY_LENGTH(maskLigatures) - 1] ==
|
||||
MASK_END_VALUE,
|
||||
"incorrectly terminated array");
|
||||
|
||||
return ParseBitmaskValues(aValue, nsCSSProps::kFontVariantLigaturesKTable,
|
||||
maskLigatures);
|
||||
}
|
||||
|
||||
static const int32_t maskNumeric[] = {
|
||||
NS_FONT_VARIANT_NUMERIC_FIGURE_MASK,
|
||||
NS_FONT_VARIANT_NUMERIC_SPACING_MASK,
|
||||
NS_FONT_VARIANT_NUMERIC_FRACTION_MASK,
|
||||
MASK_END_VALUE
|
||||
};
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseFontVariantNumeric(nsCSSValue& aValue)
|
||||
{
|
||||
NS_ASSERTION(maskNumeric[NS_ARRAY_LENGTH(maskNumeric) - 1] ==
|
||||
MASK_END_VALUE,
|
||||
"incorrectly terminated array");
|
||||
|
||||
return ParseBitmaskValues(aValue, nsCSSProps::kFontVariantNumericKTable,
|
||||
maskNumeric);
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseFontWeight(nsCSSValue& aValue)
|
||||
{
|
||||
@ -9157,14 +9702,21 @@ CSSParserImpl::ParseTextOverflow(nsCSSValue& aValue)
|
||||
*/
|
||||
bool
|
||||
CSSParserImpl::ParseFunctionInternals(const int32_t aVariantMask[],
|
||||
int32_t aVariantMaskAll,
|
||||
uint16_t aMinElems,
|
||||
uint16_t aMaxElems,
|
||||
InfallibleTArray<nsCSSValue> &aOutput)
|
||||
{
|
||||
NS_ASSERTION((aVariantMask && !aVariantMaskAll) ||
|
||||
(!aVariantMask && aVariantMaskAll),
|
||||
"only one of the two variant mask parameters can be set");
|
||||
|
||||
for (uint16_t index = 0; index < aMaxElems; ++index) {
|
||||
nsCSSValue newValue;
|
||||
if (!ParseVariant(newValue, aVariantMask[index], nullptr))
|
||||
int32_t m = aVariantMaskAll ? aVariantMaskAll : aVariantMask[index];
|
||||
if (!ParseVariant(newValue, m, nullptr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aOutput.AppendElement(newValue);
|
||||
|
||||
@ -9192,7 +9744,8 @@ CSSParserImpl::ParseFunctionInternals(const int32_t aVariantMask[],
|
||||
* types for each element in the function. The zeroth element in the
|
||||
* array corresponds to the first function parameter, etc. The length
|
||||
* of this array _must_ be greater than or equal to aMaxElems or the
|
||||
* behavior is undefined.
|
||||
* behavior is undefined. If not null, aAllowTypesAll must be 0.
|
||||
* @param aAllowedTypesAll If set, every element tested for these types
|
||||
* @param aMinElems Minimum number of elements to read. Reading fewer than
|
||||
* this many elements will result in the function failing.
|
||||
* @param aMaxElems Maximum number of elements to read. Reading more than
|
||||
@ -9202,9 +9755,13 @@ CSSParserImpl::ParseFunctionInternals(const int32_t aVariantMask[],
|
||||
bool
|
||||
CSSParserImpl::ParseFunction(const nsString &aFunction,
|
||||
const int32_t aAllowedTypes[],
|
||||
int32_t aAllowedTypesAll,
|
||||
uint16_t aMinElems, uint16_t aMaxElems,
|
||||
nsCSSValue &aValue)
|
||||
{
|
||||
NS_ASSERTION((aAllowedTypes && !aAllowedTypesAll) ||
|
||||
(!aAllowedTypes && aAllowedTypesAll),
|
||||
"only one of the two allowed type parameter can be set");
|
||||
typedef InfallibleTArray<nsCSSValue>::size_type arrlen_t;
|
||||
|
||||
/* 2^16 - 2, so that if we have 2^16 - 2 transforms, we have 2^16 - 1
|
||||
@ -9222,9 +9779,10 @@ CSSParserImpl::ParseFunction(const nsString &aFunction,
|
||||
* it's out of bounds.
|
||||
*/
|
||||
InfallibleTArray<nsCSSValue> foundValues;
|
||||
if (!ParseFunctionInternals(aAllowedTypes, aMinElems, aMaxElems,
|
||||
foundValues))
|
||||
if (!ParseFunctionInternals(aAllowedTypes, aAllowedTypesAll, aMinElems,
|
||||
aMaxElems, foundValues)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Now, convert this array into an nsCSSValue::Array object.
|
||||
* We'll need N + 1 spots, one for the function name and the rest for the
|
||||
@ -9499,7 +10057,8 @@ CSSParserImpl::ParseSingleTransform(bool aIsPrefixed,
|
||||
break;
|
||||
}
|
||||
|
||||
return ParseFunction(mToken.mIdent, variantMask, minElems, maxElems, aValue);
|
||||
return ParseFunction(mToken.mIdent, variantMask, 0, minElems,
|
||||
maxElems, aValue);
|
||||
}
|
||||
|
||||
/* Parses a transform property list by continuously reading in properties
|
||||
|
@ -55,3 +55,5 @@ CSS_PROP_ALIAS(-moz-animation-iteration-count, animation_iteration_count, MozAni
|
||||
CSS_PROP_ALIAS(-moz-animation-name, animation_name, MozAnimationName, "layout.css.prefixes.animations")
|
||||
CSS_PROP_ALIAS(-moz-animation-play-state, animation_play_state, MozAnimationPlayState, "layout.css.prefixes.animations")
|
||||
CSS_PROP_ALIAS(-moz-animation-timing-function, animation_timing_function, MozAnimationTimingFunction, "layout.css.prefixes.animations")
|
||||
CSS_PROP_ALIAS(font-feature-settings, font_feature_settings, FontFeatureSettings, "layout.css.font-features.enabled")
|
||||
CSS_PROP_ALIAS(font-language-override, font_language_override, FontLanguageOverride, "layout.css.font-features.enabled")
|
||||
|
@ -1709,6 +1709,18 @@ CSS_PROP_FONT(
|
||||
nullptr,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_FONT(
|
||||
font-kerning,
|
||||
font_kerning,
|
||||
FontKerning,
|
||||
CSS_PROPERTY_PARSE_VALUE |
|
||||
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
|
||||
CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
|
||||
"layout.css.font-features.enabled",
|
||||
VARIANT_HK,
|
||||
kFontKerningKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_FONT(
|
||||
-moz-font-language-override,
|
||||
font_language_override,
|
||||
@ -1774,6 +1786,19 @@ CSS_PROP_FONT(
|
||||
kFontStyleKTable,
|
||||
offsetof(nsStyleFont, mFont.style),
|
||||
eStyleAnimType_EnumU8)
|
||||
CSS_PROP_FONT(
|
||||
font-synthesis,
|
||||
font_synthesis,
|
||||
FontSynthesis,
|
||||
CSS_PROPERTY_PARSE_VALUE |
|
||||
CSS_PROPERTY_VALUE_PARSER_FUNCTION |
|
||||
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
|
||||
CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
|
||||
"layout.css.font-features.enabled",
|
||||
0,
|
||||
kFontSynthesisKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_FONT(
|
||||
font-variant,
|
||||
font_variant,
|
||||
@ -1786,6 +1811,82 @@ CSS_PROP_FONT(
|
||||
kFontVariantKTable,
|
||||
offsetof(nsStyleFont, mFont.variant),
|
||||
eStyleAnimType_EnumU8)
|
||||
CSS_PROP_FONT(
|
||||
font-variant-alternates,
|
||||
font_variant_alternates,
|
||||
FontVariantAlternates,
|
||||
CSS_PROPERTY_PARSE_VALUE |
|
||||
CSS_PROPERTY_VALUE_PARSER_FUNCTION |
|
||||
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
|
||||
CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
|
||||
"layout.css.font-features.enabled",
|
||||
VARIANT_HK,
|
||||
kFontVariantAlternatesKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_FONT(
|
||||
font-variant-caps,
|
||||
font_variant_caps,
|
||||
FontVariantCaps,
|
||||
CSS_PROPERTY_PARSE_VALUE |
|
||||
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
|
||||
CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
|
||||
"layout.css.font-features.enabled",
|
||||
VARIANT_HMK,
|
||||
kFontVariantCapsKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_FONT(
|
||||
font-variant-east-asian,
|
||||
font_variant_east_asian,
|
||||
FontVariantEastAsian,
|
||||
CSS_PROPERTY_PARSE_VALUE |
|
||||
CSS_PROPERTY_VALUE_PARSER_FUNCTION |
|
||||
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
|
||||
CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
|
||||
"layout.css.font-features.enabled",
|
||||
0,
|
||||
kFontVariantEastAsianKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_FONT(
|
||||
font-variant-ligatures,
|
||||
font_variant_ligatures,
|
||||
FontVariantLigatures,
|
||||
CSS_PROPERTY_PARSE_VALUE |
|
||||
CSS_PROPERTY_VALUE_PARSER_FUNCTION |
|
||||
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
|
||||
CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
|
||||
"layout.css.font-features.enabled",
|
||||
0,
|
||||
kFontVariantLigaturesKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_FONT(
|
||||
font-variant-numeric,
|
||||
font_variant_numeric,
|
||||
FontVariantNumeric,
|
||||
CSS_PROPERTY_PARSE_VALUE |
|
||||
CSS_PROPERTY_VALUE_PARSER_FUNCTION |
|
||||
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
|
||||
CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
|
||||
"layout.css.font-features.enabled",
|
||||
0,
|
||||
kFontVariantNumericKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_FONT(
|
||||
font-variant-position,
|
||||
font_variant_position,
|
||||
FontVariantPosition,
|
||||
CSS_PROPERTY_PARSE_VALUE |
|
||||
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
|
||||
CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
|
||||
"layout.css.font-features.enabled",
|
||||
VARIANT_HMK,
|
||||
kFontVariantPositionKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_FONT(
|
||||
font-weight,
|
||||
font_weight,
|
||||
|
@ -410,7 +410,17 @@ nsCSSFontDesc
|
||||
nsCSSProps::LookupFontDesc(const nsAString& aFontDesc)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(gFontDescTable, "no lookup table, needs addref");
|
||||
return nsCSSFontDesc(gFontDescTable->Lookup(aFontDesc));
|
||||
nsCSSFontDesc which = nsCSSFontDesc(gFontDescTable->Lookup(aFontDesc));
|
||||
|
||||
// check for unprefixed font-feature-settings/font-language-override
|
||||
if (which == eCSSFontDesc_UNKNOWN &&
|
||||
mozilla::Preferences::GetBool("layout.css.font-features.enabled")) {
|
||||
nsAutoString prefixedProp;
|
||||
prefixedProp.AppendLiteral("-moz-");
|
||||
prefixedProp.Append(aFontDesc);
|
||||
which = nsCSSFontDesc(gFontDescTable->Lookup(prefixedProp));
|
||||
}
|
||||
return which;
|
||||
}
|
||||
|
||||
const nsAFlatCString&
|
||||
@ -1013,6 +1023,13 @@ const int32_t nsCSSProps::kFontKTable[] = {
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const int32_t nsCSSProps::kFontKerningKTable[] = {
|
||||
eCSSKeyword_auto, NS_FONT_KERNING_AUTO,
|
||||
eCSSKeyword_none, NS_FONT_KERNING_NONE,
|
||||
eCSSKeyword_normal, NS_FONT_KERNING_NORMAL,
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const int32_t nsCSSProps::kFontSizeKTable[] = {
|
||||
eCSSKeyword_xx_small, NS_STYLE_FONT_SIZE_XXSMALL,
|
||||
eCSSKeyword_x_small, NS_STYLE_FONT_SIZE_XSMALL,
|
||||
@ -1046,12 +1063,87 @@ const int32_t nsCSSProps::kFontStyleKTable[] = {
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const int32_t nsCSSProps::kFontSynthesisKTable[] = {
|
||||
eCSSKeyword_weight, NS_FONT_SYNTHESIS_WEIGHT,
|
||||
eCSSKeyword_style, NS_FONT_SYNTHESIS_STYLE,
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
|
||||
const int32_t nsCSSProps::kFontVariantKTable[] = {
|
||||
eCSSKeyword_normal, NS_STYLE_FONT_VARIANT_NORMAL,
|
||||
eCSSKeyword_small_caps, NS_STYLE_FONT_VARIANT_SMALL_CAPS,
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const int32_t nsCSSProps::kFontVariantAlternatesKTable[] = {
|
||||
eCSSKeyword_historical_forms, NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const int32_t nsCSSProps::kFontVariantAlternatesFuncsKTable[] = {
|
||||
eCSSKeyword_stylistic, NS_FONT_VARIANT_ALTERNATES_STYLISTIC,
|
||||
eCSSKeyword_styleset, NS_FONT_VARIANT_ALTERNATES_STYLESET,
|
||||
eCSSKeyword_character_variant, NS_FONT_VARIANT_ALTERNATES_CHARACTER_VARIANT,
|
||||
eCSSKeyword_swash, NS_FONT_VARIANT_ALTERNATES_SWASH,
|
||||
eCSSKeyword_ornaments, NS_FONT_VARIANT_ALTERNATES_ORNAMENTS,
|
||||
eCSSKeyword_annotation, NS_FONT_VARIANT_ALTERNATES_ANNOTATION,
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const int32_t nsCSSProps::kFontVariantCapsKTable[] = {
|
||||
eCSSKeyword_small_caps, NS_FONT_VARIANT_CAPS_SMALLCAPS,
|
||||
eCSSKeyword_all_small_caps, NS_FONT_VARIANT_CAPS_ALLSMALL,
|
||||
eCSSKeyword_petite_caps, NS_FONT_VARIANT_CAPS_PETITECAPS,
|
||||
eCSSKeyword_all_petite_caps, NS_FONT_VARIANT_CAPS_ALLPETITE,
|
||||
eCSSKeyword_titling_caps, NS_FONT_VARIANT_CAPS_TITLING,
|
||||
eCSSKeyword_unicase, NS_FONT_VARIANT_CAPS_UNICASE,
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const int32_t nsCSSProps::kFontVariantEastAsianKTable[] = {
|
||||
eCSSKeyword_jis78, NS_FONT_VARIANT_EAST_ASIAN_JIS78,
|
||||
eCSSKeyword_jis83, NS_FONT_VARIANT_EAST_ASIAN_JIS83,
|
||||
eCSSKeyword_jis90, NS_FONT_VARIANT_EAST_ASIAN_JIS90,
|
||||
eCSSKeyword_jis04, NS_FONT_VARIANT_EAST_ASIAN_JIS04,
|
||||
eCSSKeyword_simplified, NS_FONT_VARIANT_EAST_ASIAN_SIMPLIFIED,
|
||||
eCSSKeyword_traditional, NS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL,
|
||||
eCSSKeyword_full_width, NS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH,
|
||||
eCSSKeyword_proportional_width, NS_FONT_VARIANT_EAST_ASIAN_PROP_WIDTH,
|
||||
eCSSKeyword_ruby, NS_FONT_VARIANT_EAST_ASIAN_RUBY,
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const int32_t nsCSSProps::kFontVariantLigaturesKTable[] = {
|
||||
eCSSKeyword_common_ligatures, NS_FONT_VARIANT_LIGATURES_COMMON,
|
||||
eCSSKeyword_no_common_ligatures, NS_FONT_VARIANT_LIGATURES_NO_COMMON,
|
||||
eCSSKeyword_discretionary_ligatures, NS_FONT_VARIANT_LIGATURES_DISCRETIONARY,
|
||||
eCSSKeyword_no_discretionary_ligatures, NS_FONT_VARIANT_LIGATURES_NO_DISCRETIONARY,
|
||||
eCSSKeyword_historical_ligatures, NS_FONT_VARIANT_LIGATURES_HISTORICAL,
|
||||
eCSSKeyword_no_historical_ligatures, NS_FONT_VARIANT_LIGATURES_NO_HISTORICAL,
|
||||
eCSSKeyword_contextual, NS_FONT_VARIANT_LIGATURES_CONTEXTUAL,
|
||||
eCSSKeyword_no_contextual, NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL,
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const int32_t nsCSSProps::kFontVariantNumericKTable[] = {
|
||||
eCSSKeyword_lining_nums, NS_FONT_VARIANT_NUMERIC_LINING,
|
||||
eCSSKeyword_oldstyle_nums, NS_FONT_VARIANT_NUMERIC_OLDSTYLE,
|
||||
eCSSKeyword_proportional_nums, NS_FONT_VARIANT_NUMERIC_PROPORTIONAL,
|
||||
eCSSKeyword_tabular_nums, NS_FONT_VARIANT_NUMERIC_TABULAR,
|
||||
eCSSKeyword_diagonal_fractions, NS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS,
|
||||
eCSSKeyword_stacked_fractions, NS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS,
|
||||
eCSSKeyword_slashed_zero, NS_FONT_VARIANT_NUMERIC_SLASHZERO,
|
||||
eCSSKeyword_ordinal, NS_FONT_VARIANT_NUMERIC_ORDINAL,
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const int32_t nsCSSProps::kFontVariantPositionKTable[] = {
|
||||
eCSSKeyword_super, NS_FONT_VARIANT_POSITION_SUPER,
|
||||
eCSSKeyword_sub, NS_FONT_VARIANT_POSITION_SUB,
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const int32_t nsCSSProps::kFontWeightKTable[] = {
|
||||
eCSSKeyword_normal, NS_STYLE_FONT_WEIGHT_NORMAL,
|
||||
eCSSKeyword_bold, NS_STYLE_FONT_WEIGHT_BOLD,
|
||||
@ -2072,11 +2164,19 @@ static const nsCSSProperty gFontSubpropTable[] = {
|
||||
eCSSProperty_font_weight,
|
||||
eCSSProperty_font_size,
|
||||
eCSSProperty_line_height,
|
||||
eCSSProperty_font_size_adjust, // XXX Added LDB.
|
||||
eCSSProperty_font_stretch, // XXX Added LDB.
|
||||
eCSSProperty_font_size_adjust,
|
||||
eCSSProperty_font_stretch,
|
||||
eCSSProperty__x_system_font,
|
||||
eCSSProperty_font_feature_settings,
|
||||
eCSSProperty_font_language_override,
|
||||
eCSSProperty_font_kerning,
|
||||
eCSSProperty_font_synthesis,
|
||||
eCSSProperty_font_variant_alternates,
|
||||
eCSSProperty_font_variant_caps,
|
||||
eCSSProperty_font_variant_east_asian,
|
||||
eCSSProperty_font_variant_ligatures,
|
||||
eCSSProperty_font_variant_numeric,
|
||||
eCSSProperty_font_variant_position,
|
||||
eCSSProperty_UNKNOWN
|
||||
};
|
||||
|
||||
|
@ -402,10 +402,19 @@ public:
|
||||
static const int32_t kFloatKTable[];
|
||||
static const int32_t kFloatEdgeKTable[];
|
||||
static const int32_t kFontKTable[];
|
||||
static const int32_t kFontKerningKTable[];
|
||||
static const int32_t kFontSizeKTable[];
|
||||
static const int32_t kFontStretchKTable[];
|
||||
static const int32_t kFontStyleKTable[];
|
||||
static const int32_t kFontSynthesisKTable[];
|
||||
static const int32_t kFontVariantKTable[];
|
||||
static const int32_t kFontVariantAlternatesKTable[];
|
||||
static const int32_t kFontVariantAlternatesFuncsKTable[];
|
||||
static const int32_t kFontVariantCapsKTable[];
|
||||
static const int32_t kFontVariantEastAsianKTable[];
|
||||
static const int32_t kFontVariantLigaturesKTable[];
|
||||
static const int32_t kFontVariantNumericKTable[];
|
||||
static const int32_t kFontVariantPositionKTable[];
|
||||
static const int32_t kFontWeightKTable[];
|
||||
static const int32_t kIMEModeKTable[];
|
||||
static const int32_t kLineHeightKTable[];
|
||||
|
@ -978,6 +978,7 @@ struct RuleCascadeData {
|
||||
|
||||
nsTArray<nsFontFaceRuleContainer> mFontFaceRules;
|
||||
nsTArray<nsCSSKeyframesRule*> mKeyframesRules;
|
||||
nsTArray<nsCSSFontFeatureValuesRule*> mFontFeatureValuesRules;
|
||||
nsTArray<nsCSSPageRule*> mPageRules;
|
||||
|
||||
// Looks up or creates the appropriate list in |mAttributeSelectors|.
|
||||
@ -1029,6 +1030,7 @@ RuleCascadeData::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
|
||||
|
||||
n += mFontFaceRules.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mKeyframesRules.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mFontFeatureValuesRules.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mPageRules.SizeOfExcludingThis(aMallocSizeOf);
|
||||
|
||||
return n;
|
||||
@ -2749,6 +2751,21 @@ nsCSSRuleProcessor::AppendPageRules(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsCSSRuleProcessor::AppendFontFeatureValuesRules(
|
||||
nsPresContext *aPresContext,
|
||||
nsTArray<nsCSSFontFeatureValuesRule*>& aArray)
|
||||
{
|
||||
RuleCascadeData* cascade = GetRuleCascade(aPresContext);
|
||||
|
||||
if (cascade) {
|
||||
if (!aArray.AppendElements(cascade->mFontFeatureValuesRules))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCSSRuleProcessor::ClearRuleCascades()
|
||||
{
|
||||
@ -3047,12 +3064,14 @@ struct CascadeEnumData {
|
||||
CascadeEnumData(nsPresContext* aPresContext,
|
||||
nsTArray<nsFontFaceRuleContainer>& aFontFaceRules,
|
||||
nsTArray<nsCSSKeyframesRule*>& aKeyframesRules,
|
||||
nsTArray<nsCSSFontFeatureValuesRule*>& aFontFeatureValuesRules,
|
||||
nsTArray<nsCSSPageRule*>& aPageRules,
|
||||
nsMediaQueryResultCacheKey& aKey,
|
||||
uint8_t aSheetType)
|
||||
: mPresContext(aPresContext),
|
||||
mFontFaceRules(aFontFaceRules),
|
||||
mKeyframesRules(aKeyframesRules),
|
||||
mFontFeatureValuesRules(aFontFeatureValuesRules),
|
||||
mPageRules(aPageRules),
|
||||
mCacheKey(aKey),
|
||||
mSheetType(aSheetType)
|
||||
@ -3076,6 +3095,7 @@ struct CascadeEnumData {
|
||||
nsPresContext* mPresContext;
|
||||
nsTArray<nsFontFaceRuleContainer>& mFontFaceRules;
|
||||
nsTArray<nsCSSKeyframesRule*>& mKeyframesRules;
|
||||
nsTArray<nsCSSFontFeatureValuesRule*>& mFontFeatureValuesRules;
|
||||
nsTArray<nsCSSPageRule*>& mPageRules;
|
||||
nsMediaQueryResultCacheKey& mCacheKey;
|
||||
PLArenaPool mArena;
|
||||
@ -3093,7 +3113,9 @@ struct CascadeEnumData {
|
||||
* but kept in order per-weight, and
|
||||
* (2) add any @font-face rules, in order, into data->mFontFaceRules.
|
||||
* (3) add any @keyframes rules, in order, into data->mKeyframesRules.
|
||||
* (4) add any @page rules, in order, into data->mPageRules.
|
||||
* (4) add any @font-feature-value rules, in order,
|
||||
* into data->mFontFeatureValuesRules.
|
||||
* (5) add any @page rules, in order, into data->mPageRules.
|
||||
*/
|
||||
static bool
|
||||
CascadeRuleEnumFunc(css::Rule* aRule, void* aData)
|
||||
@ -3146,6 +3168,13 @@ CascadeRuleEnumFunc(css::Rule* aRule, void* aData)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (css::Rule::FONT_FEATURE_VALUES_RULE == type) {
|
||||
nsCSSFontFeatureValuesRule *fontFeatureValuesRule =
|
||||
static_cast<nsCSSFontFeatureValuesRule*>(aRule);
|
||||
if (!data->mFontFeatureValuesRules.AppendElement(fontFeatureValuesRule)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (css::Rule::PAGE_RULE == type) {
|
||||
nsCSSPageRule* pageRule = static_cast<nsCSSPageRule*>(aRule);
|
||||
if (!data->mPageRules.AppendElement(pageRule)) {
|
||||
@ -3252,6 +3281,7 @@ nsCSSRuleProcessor::RefreshRuleCascade(nsPresContext* aPresContext)
|
||||
if (newCascade) {
|
||||
CascadeEnumData data(aPresContext, newCascade->mFontFaceRules,
|
||||
newCascade->mKeyframesRules,
|
||||
newCascade->mFontFeatureValuesRules,
|
||||
newCascade->mPageRules,
|
||||
newCascade->mCacheKey,
|
||||
mSheetType);
|
||||
|
@ -128,6 +128,9 @@ public:
|
||||
bool AppendPageRules(nsPresContext* aPresContext,
|
||||
nsTArray<nsCSSPageRule*>& aArray);
|
||||
|
||||
bool AppendFontFeatureValuesRules(nsPresContext* aPresContext,
|
||||
nsTArray<nsCSSFontFeatureValuesRule*>& aArray);
|
||||
|
||||
/**
|
||||
* Returns the scope element for the scoped style sheets this rule
|
||||
* processor is for. If this is not a rule processor for scoped style
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "mozilla/dom/CSSStyleDeclarationBinding.h"
|
||||
#include "StyleRule.h"
|
||||
#include "nsFont.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -1910,6 +1911,255 @@ nsCSSFontFaceRule::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------
|
||||
// nsCSSFontFeatureValuesRule
|
||||
//
|
||||
|
||||
/* virtual */ already_AddRefed<css::Rule>
|
||||
nsCSSFontFeatureValuesRule::Clone() const
|
||||
{
|
||||
nsRefPtr<css::Rule> clone = new nsCSSFontFeatureValuesRule(*this);
|
||||
return clone.forget();
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsCSSFontFeatureValuesRule)
|
||||
NS_IMPL_RELEASE(nsCSSFontFeatureValuesRule)
|
||||
|
||||
DOMCI_DATA(CSSFontFeatureValuesRule, nsCSSFontFeatureValuesRule)
|
||||
|
||||
// QueryInterface implementation for nsCSSFontFeatureValuesRule
|
||||
NS_INTERFACE_MAP_BEGIN(nsCSSFontFeatureValuesRule)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFeatureValuesRule)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSFontFeatureValuesRule)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
IMPL_STYLE_RULE_INHERIT(nsCSSFontFeatureValuesRule, Rule)
|
||||
|
||||
static void
|
||||
FamilyListToString(const nsTArray<nsString>& aFamilyList, nsAString& aOutStr)
|
||||
{
|
||||
uint32_t i, n = aFamilyList.Length();
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
nsStyleUtil::AppendEscapedCSSString(aFamilyList[i], aOutStr);
|
||||
if (i != n - 1) {
|
||||
aOutStr.AppendLiteral(", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
FeatureValuesToString(
|
||||
const nsTArray<gfxFontFeatureValueSet::FeatureValues>& aFeatureValues,
|
||||
nsAString& aOutStr)
|
||||
{
|
||||
uint32_t i, n;
|
||||
|
||||
// append values
|
||||
n = aFeatureValues.Length();
|
||||
for (i = 0; i < n; i++) {
|
||||
const gfxFontFeatureValueSet::FeatureValues& fv = aFeatureValues[i];
|
||||
|
||||
// @alternate
|
||||
aOutStr.AppendLiteral(" @");
|
||||
nsAutoString functAlt;
|
||||
nsStyleUtil::GetFunctionalAlternatesName(fv.alternate, functAlt);
|
||||
aOutStr.Append(functAlt);
|
||||
aOutStr.AppendLiteral(" {");
|
||||
|
||||
// for each ident-values tuple
|
||||
uint32_t j, numValues = fv.valuelist.Length();
|
||||
for (j = 0; j < numValues; j++) {
|
||||
aOutStr.AppendLiteral(" ");
|
||||
const gfxFontFeatureValueSet::ValueList& vlist = fv.valuelist[j];
|
||||
nsStyleUtil::AppendEscapedCSSIdent(vlist.name, aOutStr);
|
||||
aOutStr.AppendLiteral(":");
|
||||
|
||||
uint32_t k, numSelectors = vlist.featureSelectors.Length();
|
||||
for (k = 0; k < numSelectors; k++) {
|
||||
aOutStr.AppendLiteral(" ");
|
||||
aOutStr.AppendInt(vlist.featureSelectors[k]);
|
||||
}
|
||||
|
||||
aOutStr.AppendLiteral(";");
|
||||
}
|
||||
aOutStr.AppendLiteral(" }\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
FontFeatureValuesRuleToString(
|
||||
const nsTArray<nsString>& aFamilyList,
|
||||
const nsTArray<gfxFontFeatureValueSet::FeatureValues>& aFeatureValues,
|
||||
nsAString& aOutStr)
|
||||
{
|
||||
aOutStr.AssignLiteral("@font-feature-values ");
|
||||
nsAutoString familyListStr, valueTextStr;
|
||||
FamilyListToString(aFamilyList, familyListStr);
|
||||
aOutStr.Append(familyListStr);
|
||||
aOutStr.AppendLiteral(" {\n");
|
||||
FeatureValuesToString(aFeatureValues, valueTextStr);
|
||||
aOutStr.Append(valueTextStr);
|
||||
aOutStr.AppendLiteral("}");
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
nsCSSFontFeatureValuesRule::List(FILE* out, int32_t aIndent) const
|
||||
{
|
||||
nsAutoString text;
|
||||
FontFeatureValuesRuleToString(mFamilyList, mFeatureValues, text);
|
||||
NS_ConvertUTF16toUTF8 utf8(text);
|
||||
|
||||
// replace newlines with newlines plus indent spaces
|
||||
char* indent = new char[(aIndent + 1) * 2];
|
||||
int32_t i;
|
||||
for (i = 1; i < (aIndent + 1) * 2 - 1; i++) {
|
||||
indent[i] = 0x20;
|
||||
}
|
||||
indent[0] = 0xa;
|
||||
indent[aIndent * 2 + 1] = 0;
|
||||
utf8.ReplaceSubstring("\n", indent);
|
||||
delete [] indent;
|
||||
|
||||
for (i = aIndent; --i >= 0; ) fputs(" ", out);
|
||||
fprintf(out, "%s\n", utf8.get());
|
||||
}
|
||||
#endif
|
||||
|
||||
/* virtual */ int32_t
|
||||
nsCSSFontFeatureValuesRule::GetType() const
|
||||
{
|
||||
return Rule::FONT_FEATURE_VALUES_RULE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSSFontFeatureValuesRule::GetType(uint16_t* aType)
|
||||
{
|
||||
*aType = nsIDOMCSSRule::FONT_FEATURE_VALUES_RULE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSSFontFeatureValuesRule::GetCssText(nsAString& aCssText)
|
||||
{
|
||||
FontFeatureValuesRuleToString(mFamilyList, mFeatureValues, aCssText);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSSFontFeatureValuesRule::SetCssText(const nsAString& aCssText)
|
||||
{
|
||||
// FIXME: implement???
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSSFontFeatureValuesRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
|
||||
{
|
||||
return Rule::GetParentStyleSheet(aSheet);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSSFontFeatureValuesRule::GetParentRule(nsIDOMCSSRule** aParentRule)
|
||||
{
|
||||
return Rule::GetParentRule(aParentRule);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSSFontFeatureValuesRule::GetFontFamily(nsAString& aFontFamily)
|
||||
{
|
||||
FamilyListToString(mFamilyList, aFontFamily);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSSFontFeatureValuesRule::SetFontFamily(const nsAString& aFontFamily)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSSFontFeatureValuesRule::GetValueText(nsAString& aValueText)
|
||||
{
|
||||
FeatureValuesToString(mFeatureValues, aValueText);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSSFontFeatureValuesRule::SetValueText(const nsAString& aValueText)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
struct MakeFamilyArray {
|
||||
MakeFamilyArray(nsTArray<nsString>& aFamilyArray)
|
||||
: familyArray(aFamilyArray), hasGeneric(false)
|
||||
{}
|
||||
|
||||
static bool
|
||||
AddFamily(const nsString& aFamily, bool aGeneric, void* aData)
|
||||
{
|
||||
MakeFamilyArray *familyArr = reinterpret_cast<MakeFamilyArray*> (aData);
|
||||
if (!aGeneric && !aFamily.IsEmpty()) {
|
||||
familyArr->familyArray.AppendElement(aFamily);
|
||||
}
|
||||
if (aGeneric) {
|
||||
familyArr->hasGeneric = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
nsTArray<nsString>& familyArray;
|
||||
bool hasGeneric;
|
||||
};
|
||||
|
||||
void
|
||||
nsCSSFontFeatureValuesRule::SetFamilyList(const nsAString& aFamilyList,
|
||||
bool& aContainsGeneric)
|
||||
{
|
||||
nsFont font(aFamilyList, 0, 0, 0, 0, 0, 0);
|
||||
MakeFamilyArray families(mFamilyList);
|
||||
font.EnumerateFamilies(MakeFamilyArray::AddFamily, (void*) &families);
|
||||
aContainsGeneric = families.hasGeneric;
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSFontFeatureValuesRule::AddValueList(int32_t aVariantAlternate,
|
||||
nsTArray<gfxFontFeatureValueSet::ValueList>& aValueList)
|
||||
{
|
||||
uint32_t i, len = mFeatureValues.Length();
|
||||
bool foundAlternate = false;
|
||||
|
||||
// add to an existing list for a given property value
|
||||
for (i = 0; i < len; i++) {
|
||||
gfxFontFeatureValueSet::FeatureValues& f = mFeatureValues.ElementAt(i);
|
||||
|
||||
if (f.alternate == uint32_t(aVariantAlternate)) {
|
||||
f.valuelist.AppendElements(aValueList);
|
||||
foundAlternate = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// create a new list for a given property value
|
||||
if (!foundAlternate) {
|
||||
gfxFontFeatureValueSet::FeatureValues &f = *mFeatureValues.AppendElement();
|
||||
f.alternate = aVariantAlternate;
|
||||
f.valuelist.AppendElements(aValueList);
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
nsCSSFontFeatureValuesRule::SizeOfIncludingThis(
|
||||
nsMallocSizeOfFun aMallocSizeOf) const
|
||||
{
|
||||
return aMallocSizeOf(this);
|
||||
}
|
||||
|
||||
// -------------------------------------------
|
||||
// nsCSSKeyframeStyleDeclaration
|
||||
//
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsIDOMCSSConditionRule.h"
|
||||
#include "nsIDOMCSSFontFaceRule.h"
|
||||
#include "nsIDOMCSSFontFeatureValuesRule.h"
|
||||
#include "nsIDOMCSSGroupingRule.h"
|
||||
#include "nsIDOMCSSMediaRule.h"
|
||||
#include "nsIDOMCSSMozDocumentRule.h"
|
||||
@ -31,6 +32,7 @@
|
||||
#include "Declaration.h"
|
||||
#include "nsIDOMCSSPageRule.h"
|
||||
#include "StyleRule.h"
|
||||
#include "gfxFontFeatures.h"
|
||||
|
||||
class nsMediaList;
|
||||
|
||||
@ -285,6 +287,61 @@ nsCSSFontFaceStyleDecl::ContainingRule() const
|
||||
(reinterpret_cast<const char*>(this) - offsetof(nsCSSFontFaceRule, mDecl));
|
||||
}
|
||||
|
||||
class nsCSSFontFeatureValuesRule MOZ_FINAL :
|
||||
public mozilla::css::Rule,
|
||||
public nsIDOMCSSFontFeatureValuesRule
|
||||
{
|
||||
public:
|
||||
nsCSSFontFeatureValuesRule() {}
|
||||
|
||||
nsCSSFontFeatureValuesRule(const nsCSSFontFeatureValuesRule& aCopy)
|
||||
// copy everything except our reference count
|
||||
: mozilla::css::Rule(aCopy),
|
||||
mFamilyList(aCopy.mFamilyList),
|
||||
mFeatureValues(aCopy.mFeatureValues) {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIStyleRule methods
|
||||
#ifdef DEBUG
|
||||
virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
|
||||
#endif
|
||||
|
||||
// Rule methods
|
||||
DECL_STYLE_RULE_INHERIT
|
||||
|
||||
virtual int32_t GetType() const MOZ_OVERRIDE;
|
||||
virtual already_AddRefed<mozilla::css::Rule> Clone() const MOZ_OVERRIDE;
|
||||
|
||||
// nsIDOMCSSRule interface
|
||||
NS_DECL_NSIDOMCSSRULE
|
||||
|
||||
// nsIDOMCSSFontFaceRule interface
|
||||
NS_DECL_NSIDOMCSSFONTFEATUREVALUESRULE
|
||||
|
||||
const nsTArray<nsString>& GetFamilyList() { return mFamilyList; }
|
||||
void SetFamilyList(const nsAString& aFamilyList, bool& aContainsGeneric);
|
||||
|
||||
void AddValueList(int32_t aVariantAlternate,
|
||||
nsTArray<gfxFontFeatureValueSet::ValueList>& aValueList);
|
||||
|
||||
const nsTArray<gfxFontFeatureValueSet::FeatureValues>& GetFeatureValues()
|
||||
{
|
||||
return mFeatureValues;
|
||||
}
|
||||
|
||||
virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
|
||||
|
||||
static bool PrefEnabled()
|
||||
{
|
||||
return mozilla::Preferences::GetBool("layout.css.font-features.enabled");
|
||||
}
|
||||
|
||||
protected:
|
||||
nsTArray<nsString> mFamilyList;
|
||||
nsTArray<gfxFontFeatureValueSet::FeatureValues> mFeatureValues;
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
|
||||
|
@ -806,8 +806,10 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
|
||||
aResult.AppendInt(GetIntValue(), 10);
|
||||
}
|
||||
else if (eCSSUnit_Enumerated == unit) {
|
||||
if (eCSSProperty_text_decoration_line == aProperty) {
|
||||
int32_t intValue = GetIntValue();
|
||||
int32_t intValue = GetIntValue();
|
||||
switch(aProperty) {
|
||||
|
||||
case eCSSProperty_text_decoration_line:
|
||||
if (NS_STYLE_TEXT_DECORATION_LINE_NONE == intValue) {
|
||||
AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
|
||||
aResult);
|
||||
@ -821,9 +823,9 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
|
||||
NS_STYLE_TEXT_DECORATION_LINE_PREF_ANCHORS,
|
||||
aResult);
|
||||
}
|
||||
}
|
||||
else if (eCSSProperty_marks == aProperty) {
|
||||
int32_t intValue = GetIntValue();
|
||||
break;
|
||||
|
||||
case eCSSProperty_marks:
|
||||
if (intValue == NS_STYLE_PAGE_MARKS_NONE) {
|
||||
AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
|
||||
aResult);
|
||||
@ -833,17 +835,48 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
|
||||
NS_STYLE_PAGE_MARKS_REGISTER,
|
||||
aResult);
|
||||
}
|
||||
}
|
||||
else if (eCSSProperty_paint_order == aProperty) {
|
||||
break;
|
||||
|
||||
case eCSSProperty_paint_order:
|
||||
MOZ_STATIC_ASSERT
|
||||
(NS_STYLE_PAINT_ORDER_BITWIDTH * NS_STYLE_PAINT_ORDER_LAST_VALUE <= 8,
|
||||
"SVGStyleStruct::mPaintOrder and the following cast not big enough");
|
||||
nsStyleUtil::AppendPaintOrderValue(static_cast<uint8_t>(GetIntValue()),
|
||||
aResult);
|
||||
}
|
||||
else {
|
||||
const nsAFlatCString& name = nsCSSProps::LookupPropertyValue(aProperty, GetIntValue());
|
||||
break;
|
||||
|
||||
case eCSSProperty_font_synthesis:
|
||||
nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
|
||||
NS_FONT_SYNTHESIS_WEIGHT,
|
||||
NS_FONT_SYNTHESIS_STYLE,
|
||||
aResult);
|
||||
break;
|
||||
|
||||
case eCSSProperty_font_variant_east_asian:
|
||||
nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
|
||||
NS_FONT_VARIANT_EAST_ASIAN_JIS78,
|
||||
NS_FONT_VARIANT_EAST_ASIAN_RUBY,
|
||||
aResult);
|
||||
break;
|
||||
|
||||
case eCSSProperty_font_variant_ligatures:
|
||||
nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
|
||||
NS_FONT_VARIANT_LIGATURES_COMMON,
|
||||
NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL,
|
||||
aResult);
|
||||
break;
|
||||
|
||||
case eCSSProperty_font_variant_numeric:
|
||||
nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
|
||||
NS_FONT_VARIANT_NUMERIC_LINING,
|
||||
NS_FONT_VARIANT_NUMERIC_ORDINAL,
|
||||
aResult);
|
||||
break;
|
||||
|
||||
default:
|
||||
const nsAFlatCString& name = nsCSSProps::LookupPropertyValue(aProperty, intValue);
|
||||
AppendASCIItoUTF16(name, aResult);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (eCSSUnit_EnumColor == unit) {
|
||||
@ -1057,7 +1090,27 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
|
||||
|
||||
aResult.AppendLiteral(")");
|
||||
} else if (eCSSUnit_Pair == unit) {
|
||||
GetPairValue().AppendToString(aProperty, aResult);
|
||||
if (eCSSProperty_font_variant_alternates == aProperty) {
|
||||
int32_t intValue = GetPairValue().mXValue.GetIntValue();
|
||||
nsAutoString out;
|
||||
|
||||
// simple, enumerated values
|
||||
nsStyleUtil::AppendBitmaskCSSValue(aProperty,
|
||||
intValue & NS_FONT_VARIANT_ALTERNATES_ENUMERATED_MASK,
|
||||
NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
|
||||
NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
|
||||
out);
|
||||
|
||||
// functional values
|
||||
const nsCSSValueList *list = GetPairValue().mYValue.GetListValue();
|
||||
nsAutoTArray<gfxAlternateValue,8> altValues;
|
||||
|
||||
nsStyleUtil::ComputeFunctionalAlternates(list, altValues);
|
||||
nsStyleUtil::SerializeFunctionalAlternates(altValues, out);
|
||||
aResult.Append(out);
|
||||
} else {
|
||||
GetPairValue().AppendToString(aProperty, aResult);
|
||||
}
|
||||
} else if (eCSSUnit_Triplet == unit) {
|
||||
GetTripletValue().AppendToString(aProperty, aResult);
|
||||
} else if (eCSSUnit_Rect == unit) {
|
||||
|
@ -1332,6 +1332,16 @@ nsComputedDOMStyle::DoGetFontFeatureSettings()
|
||||
return val;
|
||||
}
|
||||
|
||||
CSSValue*
|
||||
nsComputedDOMStyle::DoGetFontKerning()
|
||||
{
|
||||
nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
|
||||
val->SetIdent(
|
||||
nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.kerning,
|
||||
nsCSSProps::kFontKerningKTable));
|
||||
return val;
|
||||
}
|
||||
|
||||
CSSValue*
|
||||
nsComputedDOMStyle::DoGetFontLanguageOverride()
|
||||
{
|
||||
@ -1348,6 +1358,157 @@ nsComputedDOMStyle::DoGetFontLanguageOverride()
|
||||
return val;
|
||||
}
|
||||
|
||||
CSSValue*
|
||||
nsComputedDOMStyle::DoGetFontSynthesis()
|
||||
{
|
||||
nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
|
||||
|
||||
int32_t intValue = StyleFont()->mFont.synthesis;
|
||||
|
||||
if (0 == intValue) {
|
||||
val->SetIdent(eCSSKeyword_none);
|
||||
} else {
|
||||
nsAutoString valueStr;
|
||||
|
||||
nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_synthesis,
|
||||
intValue, NS_FONT_SYNTHESIS_WEIGHT,
|
||||
NS_FONT_SYNTHESIS_STYLE, valueStr);
|
||||
val->SetString(valueStr);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
CSSValue*
|
||||
nsComputedDOMStyle::DoGetFontVariantAlternates()
|
||||
{
|
||||
nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
|
||||
|
||||
int32_t intValue = StyleFont()->mFont.variantAlternates;
|
||||
|
||||
if (0 == intValue) {
|
||||
val->SetIdent(eCSSKeyword_normal);
|
||||
return val;
|
||||
}
|
||||
|
||||
// first, include enumerated values
|
||||
nsAutoString valueStr;
|
||||
|
||||
nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_alternates,
|
||||
intValue & NS_FONT_VARIANT_ALTERNATES_ENUMERATED_MASK,
|
||||
NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
|
||||
NS_FONT_VARIANT_ALTERNATES_HISTORICAL, valueStr);
|
||||
|
||||
// next, include functional values if present
|
||||
if (intValue & NS_FONT_VARIANT_ALTERNATES_FUNCTIONAL_MASK) {
|
||||
nsStyleUtil::SerializeFunctionalAlternates(StyleFont()->mFont.alternateValues,
|
||||
valueStr);
|
||||
}
|
||||
|
||||
val->SetString(valueStr);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
CSSValue*
|
||||
nsComputedDOMStyle::DoGetFontVariantCaps()
|
||||
{
|
||||
nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
|
||||
|
||||
int32_t intValue = StyleFont()->mFont.variantCaps;
|
||||
|
||||
if (0 == intValue) {
|
||||
val->SetIdent(eCSSKeyword_normal);
|
||||
} else {
|
||||
val->SetIdent(
|
||||
nsCSSProps::ValueToKeywordEnum(intValue,
|
||||
nsCSSProps::kFontVariantCapsKTable));
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
CSSValue*
|
||||
nsComputedDOMStyle::DoGetFontVariantEastAsian()
|
||||
{
|
||||
nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
|
||||
|
||||
int32_t intValue = StyleFont()->mFont.variantEastAsian;
|
||||
|
||||
if (0 == intValue) {
|
||||
val->SetIdent(eCSSKeyword_normal);
|
||||
} else {
|
||||
nsAutoString valueStr;
|
||||
|
||||
nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_east_asian,
|
||||
intValue, NS_FONT_VARIANT_EAST_ASIAN_JIS78,
|
||||
NS_FONT_VARIANT_EAST_ASIAN_RUBY, valueStr);
|
||||
val->SetString(valueStr);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
CSSValue*
|
||||
nsComputedDOMStyle::DoGetFontVariantLigatures()
|
||||
{
|
||||
nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
|
||||
|
||||
int32_t intValue = StyleFont()->mFont.variantLigatures;
|
||||
|
||||
if (0 == intValue) {
|
||||
val->SetIdent(eCSSKeyword_normal);
|
||||
} else {
|
||||
nsAutoString valueStr;
|
||||
|
||||
nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_ligatures,
|
||||
intValue, NS_FONT_VARIANT_LIGATURES_COMMON,
|
||||
NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL, valueStr);
|
||||
val->SetString(valueStr);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
CSSValue*
|
||||
nsComputedDOMStyle::DoGetFontVariantNumeric()
|
||||
{
|
||||
nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
|
||||
|
||||
int32_t intValue = StyleFont()->mFont.variantNumeric;
|
||||
|
||||
if (0 == intValue) {
|
||||
val->SetIdent(eCSSKeyword_normal);
|
||||
} else {
|
||||
nsAutoString valueStr;
|
||||
|
||||
nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_numeric,
|
||||
intValue, NS_FONT_VARIANT_NUMERIC_LINING,
|
||||
NS_FONT_VARIANT_NUMERIC_ORDINAL, valueStr);
|
||||
val->SetString(valueStr);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
CSSValue*
|
||||
nsComputedDOMStyle::DoGetFontVariantPosition()
|
||||
{
|
||||
nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
|
||||
|
||||
int32_t intValue = StyleFont()->mFont.variantPosition;
|
||||
|
||||
if (0 == intValue) {
|
||||
val->SetIdent(eCSSKeyword_normal);
|
||||
} else {
|
||||
val->SetIdent(
|
||||
nsCSSProps::ValueToKeywordEnum(intValue,
|
||||
nsCSSProps::kFontVariantPositionKTable));
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
CSSValue*
|
||||
nsComputedDOMStyle::GetBackgroundList(uint8_t nsStyleBackground::Layer::* aMember,
|
||||
uint32_t nsStyleBackground::* aCount,
|
||||
@ -4761,11 +4922,19 @@ nsComputedDOMStyle::GetQueryablePropertyMap(uint32_t* aLength)
|
||||
COMPUTED_STYLE_MAP_ENTRY(float, Float),
|
||||
//// COMPUTED_STYLE_MAP_ENTRY(font, Font),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_family, FontFamily),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_kerning, FontKerning),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_size, FontSize),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_size_adjust, FontSizeAdjust),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_stretch, FontStretch),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_style, FontStyle),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_synthesis, FontSynthesis),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_variant, FontVariant),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_variant_alternates, FontVariantAlternates),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_variant_caps, FontVariantCaps),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_variant_east_asian, FontVariantEastAsian),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_variant_ligatures, FontVariantLigatures),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_variant_numeric, FontVariantNumeric),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_variant_position, FontVariantPosition),
|
||||
COMPUTED_STYLE_MAP_ENTRY(font_weight, FontWeight),
|
||||
COMPUTED_STYLE_MAP_ENTRY_LAYOUT(height, Height),
|
||||
COMPUTED_STYLE_MAP_ENTRY(ime_mode, IMEMode),
|
||||
|
@ -188,13 +188,21 @@ private:
|
||||
mozilla::dom::CSSValue* DoGetColor();
|
||||
mozilla::dom::CSSValue* DoGetFontFamily();
|
||||
mozilla::dom::CSSValue* DoGetFontFeatureSettings();
|
||||
mozilla::dom::CSSValue* DoGetFontKerning();
|
||||
mozilla::dom::CSSValue* DoGetFontLanguageOverride();
|
||||
mozilla::dom::CSSValue* DoGetFontSize();
|
||||
mozilla::dom::CSSValue* DoGetFontSizeAdjust();
|
||||
mozilla::dom::CSSValue* DoGetFontStretch();
|
||||
mozilla::dom::CSSValue* DoGetFontStyle();
|
||||
mozilla::dom::CSSValue* DoGetFontWeight();
|
||||
mozilla::dom::CSSValue* DoGetFontSynthesis();
|
||||
mozilla::dom::CSSValue* DoGetFontVariant();
|
||||
mozilla::dom::CSSValue* DoGetFontVariantAlternates();
|
||||
mozilla::dom::CSSValue* DoGetFontVariantCaps();
|
||||
mozilla::dom::CSSValue* DoGetFontVariantEastAsian();
|
||||
mozilla::dom::CSSValue* DoGetFontVariantLigatures();
|
||||
mozilla::dom::CSSValue* DoGetFontVariantNumeric();
|
||||
mozilla::dom::CSSValue* DoGetFontVariantPosition();
|
||||
mozilla::dom::CSSValue* DoGetFontWeight();
|
||||
|
||||
/* Background properties */
|
||||
mozilla::dom::CSSValue* DoGetBackgroundAttachment();
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "CSSCalc.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsRenderingContext.h"
|
||||
#include "nsStyleUtil.h"
|
||||
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
|
||||
@ -3273,6 +3274,109 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
|
||||
aFont->mScriptLevel = 0;
|
||||
}
|
||||
|
||||
// font-kerning: none, enum, inherit, initial, -moz-system-font
|
||||
SetDiscrete(*aRuleData->ValueForFontKerning(),
|
||||
aFont->mFont.kerning, aCanStoreInRuleTree,
|
||||
SETDSC_ENUMERATED | SETDSC_SYSTEM_FONT,
|
||||
aParentFont->mFont.kerning,
|
||||
defaultVariableFont->kerning,
|
||||
0, 0, 0, systemFont.kerning);
|
||||
|
||||
// font-synthesis: none, enum (bit field), inherit, initial, -moz-system-font
|
||||
SetDiscrete(*aRuleData->ValueForFontSynthesis(),
|
||||
aFont->mFont.synthesis, aCanStoreInRuleTree,
|
||||
SETDSC_NONE | SETDSC_ENUMERATED | SETDSC_SYSTEM_FONT,
|
||||
aParentFont->mFont.synthesis,
|
||||
defaultVariableFont->synthesis,
|
||||
0, 0, 0, systemFont.synthesis);
|
||||
|
||||
// font-variant-alternates: normal, enum (bit field) + functions, inherit,
|
||||
// initial, -moz-system-font
|
||||
const nsCSSValue* variantAlternatesValue =
|
||||
aRuleData->ValueForFontVariantAlternates();
|
||||
int32_t variantAlternates = 0;
|
||||
|
||||
switch (variantAlternatesValue->GetUnit()) {
|
||||
case eCSSUnit_Inherit:
|
||||
aFont->mFont.CopyAlternates(aParentFont->mFont);
|
||||
aCanStoreInRuleTree = false;
|
||||
break;
|
||||
|
||||
case eCSSUnit_Initial:
|
||||
case eCSSUnit_Normal:
|
||||
aFont->mFont.variantAlternates = 0;
|
||||
aFont->mFont.alternateValues.Clear();
|
||||
aFont->mFont.featureValueLookup = nullptr;
|
||||
break;
|
||||
|
||||
case eCSSUnit_Pair:
|
||||
NS_ASSERTION(variantAlternatesValue->GetPairValue().mXValue.GetUnit() ==
|
||||
eCSSUnit_Enumerated, "strange unit for variantAlternates");
|
||||
variantAlternates =
|
||||
variantAlternatesValue->GetPairValue().mXValue.GetIntValue();
|
||||
aFont->mFont.variantAlternates = variantAlternates;
|
||||
|
||||
if (variantAlternates & NS_FONT_VARIANT_ALTERNATES_FUNCTIONAL_MASK) {
|
||||
// fetch the feature lookup object from the styleset
|
||||
aFont->mFont.featureValueLookup =
|
||||
aPresContext->StyleSet()->GetFontFeatureValuesLookup();
|
||||
|
||||
NS_ASSERTION(variantAlternatesValue->GetPairValue().mYValue.GetUnit() ==
|
||||
eCSSUnit_List, "function list not a list value");
|
||||
nsStyleUtil::ComputeFunctionalAlternates(
|
||||
variantAlternatesValue->GetPairValue().mYValue.GetListValue(),
|
||||
aFont->mFont.alternateValues);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// font-variant-caps: normal, enum, inherit, initial, -moz-system-font
|
||||
SetDiscrete(*aRuleData->ValueForFontVariantCaps(),
|
||||
aFont->mFont.variantCaps, aCanStoreInRuleTree,
|
||||
SETDSC_NORMAL | SETDSC_ENUMERATED | SETDSC_SYSTEM_FONT,
|
||||
aParentFont->mFont.variantCaps,
|
||||
defaultVariableFont->variantCaps,
|
||||
0, 0, 0, systemFont.variantCaps);
|
||||
|
||||
// font-variant-east-asian: normal, enum (bit field), inherit, initial,
|
||||
// -moz-system-font
|
||||
SetDiscrete(*aRuleData->ValueForFontVariantEastAsian(),
|
||||
aFont->mFont.variantEastAsian, aCanStoreInRuleTree,
|
||||
SETDSC_NORMAL | SETDSC_ENUMERATED | SETDSC_SYSTEM_FONT,
|
||||
aParentFont->mFont.variantEastAsian,
|
||||
defaultVariableFont->variantEastAsian,
|
||||
0, 0, 0, systemFont.variantEastAsian);
|
||||
|
||||
// font-variant-ligatures: normal, enum (bit field), inherit, initial,
|
||||
// -moz-system-font
|
||||
SetDiscrete(*aRuleData->ValueForFontVariantLigatures(),
|
||||
aFont->mFont.variantLigatures, aCanStoreInRuleTree,
|
||||
SETDSC_NORMAL | SETDSC_ENUMERATED | SETDSC_SYSTEM_FONT,
|
||||
aParentFont->mFont.variantLigatures,
|
||||
defaultVariableFont->variantLigatures,
|
||||
0, 0, 0, systemFont.variantLigatures);
|
||||
|
||||
// font-variant-numeric: normal, enum (bit field), inherit, initial,
|
||||
// -moz-system-font
|
||||
SetDiscrete(*aRuleData->ValueForFontVariantNumeric(),
|
||||
aFont->mFont.variantNumeric, aCanStoreInRuleTree,
|
||||
SETDSC_NORMAL | SETDSC_ENUMERATED | SETDSC_SYSTEM_FONT,
|
||||
aParentFont->mFont.variantNumeric,
|
||||
defaultVariableFont->variantNumeric,
|
||||
0, 0, 0, systemFont.variantNumeric);
|
||||
|
||||
// font-variant-position: normal, enum, inherit, initial,
|
||||
// -moz-system-font
|
||||
SetDiscrete(*aRuleData->ValueForFontVariantPosition(),
|
||||
aFont->mFont.variantPosition, aCanStoreInRuleTree,
|
||||
SETDSC_NORMAL | SETDSC_ENUMERATED | SETDSC_SYSTEM_FONT,
|
||||
aParentFont->mFont.variantPosition,
|
||||
defaultVariableFont->variantPosition,
|
||||
0, 0, 0, systemFont.variantPosition);
|
||||
|
||||
// font-feature-settings
|
||||
const nsCSSValue* featureSettingsValue =
|
||||
aRuleData->ValueForFontFeatureSettings();
|
||||
|
@ -110,6 +110,7 @@ nsStyleSet::nsStyleSet()
|
||||
mInShutdown(false),
|
||||
mAuthorStyleDisabled(false),
|
||||
mInReconstruct(false),
|
||||
mInitFontFeatureValuesLookup(true),
|
||||
mDirty(0),
|
||||
mUnusedRuleNodeCount(0)
|
||||
{
|
||||
@ -1540,6 +1541,59 @@ nsStyleSet::AppendKeyframesRules(nsPresContext* aPresContext,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsStyleSet::AppendFontFeatureValuesRules(nsPresContext* aPresContext,
|
||||
nsTArray<nsCSSFontFeatureValuesRule*>& aArray)
|
||||
{
|
||||
NS_ENSURE_FALSE(mInShutdown, false);
|
||||
|
||||
for (uint32_t i = 0; i < NS_ARRAY_LENGTH(gCSSSheetTypes); ++i) {
|
||||
nsCSSRuleProcessor *ruleProc = static_cast<nsCSSRuleProcessor*>
|
||||
(mRuleProcessors[gCSSSheetTypes[i]].get());
|
||||
if (ruleProc &&
|
||||
!ruleProc->AppendFontFeatureValuesRules(aPresContext, aArray))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<gfxFontFeatureValueSet>
|
||||
nsStyleSet::GetFontFeatureValuesLookup()
|
||||
{
|
||||
if (mInitFontFeatureValuesLookup) {
|
||||
mInitFontFeatureValuesLookup = false;
|
||||
|
||||
nsTArray<nsCSSFontFeatureValuesRule*> rules;
|
||||
AppendFontFeatureValuesRules(PresContext(), rules);
|
||||
|
||||
mFontFeatureValuesLookup = new gfxFontFeatureValueSet();
|
||||
|
||||
uint32_t i, numRules = rules.Length();
|
||||
for (i = 0; i < numRules; i++) {
|
||||
nsCSSFontFeatureValuesRule *rule = rules[i];
|
||||
|
||||
const nsTArray<nsString>& familyList = rule->GetFamilyList();
|
||||
const nsTArray<gfxFontFeatureValueSet::FeatureValues>&
|
||||
featureValues = rule->GetFeatureValues();
|
||||
|
||||
// for each family
|
||||
uint32_t f, numFam;
|
||||
|
||||
numFam = familyList.Length();
|
||||
for (f = 0; f < numFam; f++) {
|
||||
const nsString& family = familyList.ElementAt(f);
|
||||
nsAutoString silly(family);
|
||||
mFontFeatureValuesLookup->AddFontFeatureValues(silly, featureValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<gfxFontFeatureValueSet> lookup = mFontFeatureValuesLookup;
|
||||
return lookup.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
nsStyleSet::AppendPageRules(nsPresContext* aPresContext,
|
||||
nsTArray<nsCSSPageRule*>& aArray)
|
||||
|
@ -23,11 +23,12 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIStyleRule.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "gfxFontFeatures.h"
|
||||
|
||||
class nsIURI;
|
||||
class nsCSSFontFaceRule;
|
||||
class nsCSSKeyframesRule;
|
||||
class nsCSSFontFeatureValuesRule;
|
||||
class nsCSSPageRule;
|
||||
class nsRuleWalker;
|
||||
struct ElementDependentRuleProcessorData;
|
||||
@ -164,6 +165,14 @@ class nsStyleSet
|
||||
bool AppendKeyframesRules(nsPresContext* aPresContext,
|
||||
nsTArray<nsCSSKeyframesRule*>& aArray);
|
||||
|
||||
// Fetch object for looking up font feature values
|
||||
already_AddRefed<gfxFontFeatureValueSet> GetFontFeatureValuesLookup();
|
||||
|
||||
// Append all the currently-active font feature values rules to aArray.
|
||||
// Return true for success and false for failure.
|
||||
bool AppendFontFeatureValuesRules(nsPresContext* aPresContext,
|
||||
nsTArray<nsCSSFontFeatureValuesRule*>& aArray);
|
||||
|
||||
// Append all the currently-active page rules to aArray. Return
|
||||
// true for success and false for failure.
|
||||
bool AppendPageRules(nsPresContext* aPresContext,
|
||||
@ -406,6 +415,7 @@ class nsStyleSet
|
||||
unsigned mInShutdown : 1;
|
||||
unsigned mAuthorStyleDisabled: 1;
|
||||
unsigned mInReconstruct : 1;
|
||||
unsigned mInitFontFeatureValuesLookup : 1;
|
||||
unsigned mDirty : 9; // one dirty bit is used per sheet type
|
||||
|
||||
uint32_t mUnusedRuleNodeCount; // used to batch rule node GC
|
||||
@ -423,6 +433,9 @@ class nsStyleSet
|
||||
// BeginReconstruct and EndReconstruct, but in case of bugs that cause
|
||||
// style contexts to exist too long, may last longer.
|
||||
nsTArray<nsRuleNode*> mOldRuleTrees;
|
||||
|
||||
// whether font feature values lookup object needs initialization
|
||||
nsRefPtr<gfxFontFeatureValueSet> mFontFeatureValuesLookup;
|
||||
};
|
||||
|
||||
#ifdef _IMPL_NS_LAYOUT
|
||||
|
@ -192,6 +192,16 @@ nsChangeHint nsStyleFont::CalcFontDifference(const nsFont& aFont1, const nsFont&
|
||||
(aFont1.weight == aFont2.weight) &&
|
||||
(aFont1.stretch == aFont2.stretch) &&
|
||||
(aFont1.name == aFont2.name) &&
|
||||
(aFont1.kerning == aFont2.kerning) &&
|
||||
(aFont1.synthesis == aFont2.synthesis) &&
|
||||
(aFont1.variantAlternates == aFont2.variantAlternates) &&
|
||||
(aFont1.alternateValues == aFont2.alternateValues) &&
|
||||
(aFont1.featureValueLookup == aFont2.featureValueLookup) &&
|
||||
(aFont1.variantCaps == aFont2.variantCaps) &&
|
||||
(aFont1.variantEastAsian == aFont2.variantEastAsian) &&
|
||||
(aFont1.variantLigatures == aFont2.variantLigatures) &&
|
||||
(aFont1.variantNumeric == aFont2.variantNumeric) &&
|
||||
(aFont1.variantPosition == aFont2.variantPosition) &&
|
||||
(aFont1.fontFeatureSettings == aFont2.fontFeatureSettings) &&
|
||||
(aFont1.languageOverride == aFont2.languageOverride)) {
|
||||
if ((aFont1.decorations == aFont2.decorations)) {
|
||||
|
@ -270,6 +270,118 @@ nsStyleUtil::AppendFontFeatureSettings(const nsCSSValue& aSrc,
|
||||
AppendFontFeatureSettings(featureSettings, aResult);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsStyleUtil::GetFunctionalAlternatesName(int32_t aFeature,
|
||||
nsAString& aFeatureName)
|
||||
{
|
||||
aFeatureName.Truncate();
|
||||
nsCSSKeyword key =
|
||||
nsCSSProps::ValueToKeywordEnum(aFeature,
|
||||
nsCSSProps::kFontVariantAlternatesFuncsKTable);
|
||||
|
||||
NS_ASSERTION(key != eCSSKeyword_UNKNOWN, "bad alternate feature type");
|
||||
AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(key), aFeatureName);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsStyleUtil::SerializeFunctionalAlternates(
|
||||
const nsTArray<gfxAlternateValue>& aAlternates,
|
||||
nsAString& aResult)
|
||||
{
|
||||
nsAutoString funcName, funcParams;
|
||||
uint32_t numValues = aAlternates.Length();
|
||||
|
||||
uint32_t feature = 0;
|
||||
for (uint32_t i = 0; i < numValues; i++) {
|
||||
const gfxAlternateValue& v = aAlternates.ElementAt(i);
|
||||
if (feature != v.alternate) {
|
||||
feature = v.alternate;
|
||||
if (!funcName.IsEmpty() && !funcParams.IsEmpty()) {
|
||||
if (!aResult.IsEmpty()) {
|
||||
aResult.Append(PRUnichar(' '));
|
||||
}
|
||||
|
||||
// append the previous functional value
|
||||
aResult.Append(funcName);
|
||||
aResult.Append(PRUnichar('('));
|
||||
aResult.Append(funcParams);
|
||||
aResult.Append(PRUnichar(')'));
|
||||
}
|
||||
|
||||
// function name
|
||||
GetFunctionalAlternatesName(v.alternate, funcName);
|
||||
NS_ASSERTION(!funcName.IsEmpty(), "unknown property value name");
|
||||
|
||||
// function params
|
||||
AppendEscapedCSSIdent(v.value, funcParams);
|
||||
} else {
|
||||
if (!funcParams.IsEmpty()) {
|
||||
funcParams.Append(NS_LITERAL_STRING(", "));
|
||||
}
|
||||
AppendEscapedCSSIdent(v.value, funcParams);
|
||||
}
|
||||
}
|
||||
|
||||
// append the previous functional value
|
||||
if (!funcName.IsEmpty() && !funcParams.IsEmpty()) {
|
||||
if (!aResult.IsEmpty()) {
|
||||
aResult.Append(PRUnichar(' '));
|
||||
}
|
||||
|
||||
aResult.Append(funcName);
|
||||
aResult.Append(PRUnichar('('));
|
||||
aResult.Append(funcParams);
|
||||
aResult.Append(PRUnichar(')'));
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsStyleUtil::ComputeFunctionalAlternates(const nsCSSValueList* aList,
|
||||
nsTArray<gfxAlternateValue>& aAlternateValues)
|
||||
{
|
||||
gfxAlternateValue v;
|
||||
|
||||
aAlternateValues.Clear();
|
||||
for (const nsCSSValueList* curr = aList; curr != nullptr; curr = curr->mNext) {
|
||||
// list contains function units
|
||||
if (curr->mValue.GetUnit() != eCSSUnit_Function) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// element 0 is the propval in ident form
|
||||
const nsCSSValue::Array *func = curr->mValue.GetArrayValue();
|
||||
|
||||
// lookup propval
|
||||
nsAutoString keywordStr;
|
||||
func->Item(0).GetStringValue(keywordStr);
|
||||
nsCSSKeyword key = nsCSSKeywords::LookupKeyword(keywordStr);
|
||||
NS_ASSERTION(key != eCSSKeyword_UNKNOWN, "unknown alternate property value");
|
||||
|
||||
int32_t alternate;
|
||||
if (key == eCSSKeyword_UNKNOWN ||
|
||||
!nsCSSProps::FindKeyword(key,
|
||||
nsCSSProps::kFontVariantAlternatesFuncsKTable,
|
||||
alternate)) {
|
||||
NS_NOTREACHED("keyword not a font-variant-alternates value");
|
||||
}
|
||||
v.alternate = alternate;
|
||||
|
||||
// other elements are the idents associated with the propval
|
||||
// append one alternate value for each one
|
||||
uint32_t numElems = func->Count();
|
||||
for (uint32_t i = 1; i < numElems; i++) {
|
||||
const nsCSSValue& value = func->Item(i);
|
||||
NS_ASSERTION(value.GetUnit() == eCSSUnit_Ident,
|
||||
"weird unit found in variant alternate");
|
||||
if (value.GetUnit() != eCSSUnit_Ident) {
|
||||
continue;
|
||||
}
|
||||
value.GetStringValue(v.value);
|
||||
aAlternateValues.AppendElement(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ float
|
||||
nsStyleUtil::ColorComponentToFloat(uint8_t aAlpha)
|
||||
{
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "nsCoord.h"
|
||||
#include "nsCSSProperty.h"
|
||||
#include "gfxFontFeatures.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsSubstring.h"
|
||||
|
||||
@ -14,6 +15,7 @@ class nsCSSValue;
|
||||
class nsStringComparator;
|
||||
class nsIContent;
|
||||
struct gfxFontFeature;
|
||||
class nsCSSValueList;
|
||||
template <class E> class nsTArray;
|
||||
|
||||
// Style utility functions
|
||||
@ -51,6 +53,20 @@ public:
|
||||
static void AppendFontFeatureSettings(const nsCSSValue& src,
|
||||
nsAString& aResult);
|
||||
|
||||
// convert bitmask value to keyword name for a functional alternate
|
||||
static void GetFunctionalAlternatesName(int32_t aFeature,
|
||||
nsAString& aFeatureName);
|
||||
|
||||
// Append functional font-variant-alternates values to string
|
||||
static void
|
||||
SerializeFunctionalAlternates(const nsTArray<gfxAlternateValue>& aAlternates,
|
||||
nsAString& aResult);
|
||||
|
||||
// List of functional font-variant-alternates values to feature/value pairs
|
||||
static void
|
||||
ComputeFunctionalAlternates(const nsCSSValueList* aList,
|
||||
nsTArray<gfxAlternateValue>& aAlternateValues);
|
||||
|
||||
/*
|
||||
* Convert an author-provided floating point number to an integer (0
|
||||
* ... 255) appropriate for use in the alpha component of a color.
|
||||
|
@ -101,6 +101,7 @@ MOCHITEST_FILES = test_acid3_test46.html \
|
||||
test_dont_use_document_colors.html \
|
||||
test_font_face_parser.html \
|
||||
test_font_family_parsing.html \
|
||||
test_font_feature_values_parsing.html \
|
||||
test_garbage_at_end_of_declarations.html \
|
||||
test_group_insertRule.html \
|
||||
test_html_attribute_computed_values.html \
|
||||
|
@ -2491,7 +2491,7 @@ var gCSSProperties = {
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "normal" ],
|
||||
other_values: [ "small-caps" ],
|
||||
invalid_values: []
|
||||
invalid_values: [ "small-caps normal" ]
|
||||
},
|
||||
"font-weight": {
|
||||
domProp: "fontWeight",
|
||||
@ -4257,6 +4257,129 @@ if (SpecialPowers.getBoolPref("layout.css.flexbox.enabled")) {
|
||||
gCSSProperties["display"].other_values.push("inline-flex");
|
||||
}
|
||||
|
||||
if (SpecialPowers.getBoolPref("layout.css.font-features.enabled")) {
|
||||
var fontFeatureProperties = {
|
||||
"font-kerning": {
|
||||
domProp: "fontKerning",
|
||||
inherited: true,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "auto" ],
|
||||
other_values: [ "normal", "none" ],
|
||||
invalid_values: [ "on" ]
|
||||
},
|
||||
"font-variant-alternates": {
|
||||
domProp: "fontVariantAlternates",
|
||||
inherited: true,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "normal" ],
|
||||
other_values: [ "historical-forms",
|
||||
"styleset(alt-a, alt-b)", "character-variant(a, b, c)", "annotation(circled)",
|
||||
"swash(squishy)", "styleset(complex\\ blob, a)", "annotation(\\62 lah)" ],
|
||||
invalid_values: [ "historical-forms normal", "historical-forms historical-forms",
|
||||
"swash", "swash(3)", "annotation(a, b)", "ornaments(a,b)",
|
||||
"styleset(1234blah)", "annotation(a), annotation(b)", "annotation(a) normal" ]
|
||||
},
|
||||
"font-variant-caps": {
|
||||
domProp: "fontVariantCaps",
|
||||
inherited: true,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "normal" ],
|
||||
other_values: [ "small-caps", "all-small-caps", "petite-caps", "all-petite-caps", "titling-caps", "unicase" ],
|
||||
invalid_values: [ "normal small-caps", "petite-caps normal", "unicase unicase" ]
|
||||
},
|
||||
"font-variant-east-asian": {
|
||||
domProp: "fontVariantEastAsian",
|
||||
inherited: true,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "normal" ],
|
||||
other_values: [ "jis78", "jis83", "jis90", "jis04", "simplified", "traditional", "full-width", "proportional-width", "ruby",
|
||||
"jis78 full-width", "jis78 full-width ruby", "simplified proportional-width", "ruby simplified" ],
|
||||
invalid_values: [ "jis78 normal", "jis90 jis04", "simplified traditional", "full-width proportional-width",
|
||||
"ruby simplified ruby", "jis78 ruby simplified" ]
|
||||
},
|
||||
"font-variant-ligatures": {
|
||||
domProp: "fontVariantLigatures",
|
||||
inherited: true,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "normal" ],
|
||||
other_values: [ "common-ligatures", "no-common-ligatures", "discretionary-ligatures", "no-discretionary-ligatures",
|
||||
"historical-ligatures", "no-historical-ligatures", "contextual", "no-contextual",
|
||||
"common-ligatures no-discretionary-ligatures", "contextual no-discretionary-ligatures",
|
||||
"historical-ligatures no-common-ligatures", "no-historical-ligatures discretionary-ligatures",
|
||||
"common-ligatures no-discretionary-ligatures historical-ligatures no-contextual" ],
|
||||
invalid_values: [ "common-ligatures normal", "common-ligatures no-common-ligatures", "common-ligatures common-ligatures",
|
||||
"no-historical-ligatures historical-ligatures", "no-discretionary-ligatures discretionary-ligatures",
|
||||
"no-contextual contextual", "common-ligatures no-discretionary-ligatures no-common-ligatures" ]
|
||||
},
|
||||
"font-variant-numeric": {
|
||||
domProp: "fontVariantNumeric",
|
||||
inherited: true,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "normal" ],
|
||||
other_values: [ "lining-nums", "oldstyle-nums", "proportional-nums", "tabular-nums", "diagonal-fractions",
|
||||
"stacked-fractions", "slashed-zero", "ordinal", "lining-nums diagonal-fractions",
|
||||
"tabular-nums stacked-fractions", "tabular-nums slashed-zero stacked-fractions",
|
||||
"proportional-nums slashed-zero diagonal-fractions oldstyle-nums ordinal" ],
|
||||
invalid_values: [ "lining-nums normal", "lining-nums oldstyle-nums", "lining-nums normal slashed-zero ordinal",
|
||||
"proportional-nums tabular-nums", "diagonal-fractions stacked-fractions", "slashed-zero diagonal-fractions slashed-zero",
|
||||
"lining-nums slashed-zero diagonal-fractions oldstyle-nums", "diagonal-fractions diagonal-fractions" ]
|
||||
},
|
||||
"font-variant-position": {
|
||||
domProp: "fontVariantPosition",
|
||||
inherited: true,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "normal" ],
|
||||
other_values: [ "super", "sub" ],
|
||||
invalid_values: [ "normal sub", "super sub" ]
|
||||
},
|
||||
"font-synthesis": {
|
||||
domProp: "fontSynthesis",
|
||||
inherited: true,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "weight style" ],
|
||||
other_values: [ "none", "weight", "style" ],
|
||||
invalid_values: [ "weight none", "style none", "none style", "weight 10px", "weight weight", "style style" ]
|
||||
},
|
||||
// aliases for prefixed properties
|
||||
"font-feature-settings": {
|
||||
domProp: "fontFeatureSettings",
|
||||
inherited: true,
|
||||
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
|
||||
alias_for: "-moz-font-feature-settings",
|
||||
subproperties: [ "-moz-font-feature-settings" ],
|
||||
initial_values: [ "normal" ],
|
||||
other_values: [
|
||||
"'liga' on", "'liga'", "\"liga\" 1", "'liga', 'clig' 1",
|
||||
"\"liga\" off", "\"liga\" 0", '"cv01" 3, "cv02" 4',
|
||||
'"cswh", "smcp" off, "salt" 4', '"cswh" 1, "smcp" off, "salt" 4',
|
||||
'"cswh" 0, \'blah\', "liga", "smcp" off, "salt" 4',
|
||||
'"liga" ,"smcp" 0 , "blah"'
|
||||
],
|
||||
invalid_values: [
|
||||
'liga', 'liga 1', 'liga normal', '"liga" normal', 'normal liga',
|
||||
'normal "liga"', 'normal, "liga"', '"liga=1"', "'foobar' on",
|
||||
'"blahblah" 0', '"liga" 3.14', '"liga" 1 3.14', '"liga" 1 normal',
|
||||
'"liga" 1 off', '"liga" on off', '"liga" , 0 "smcp"', '"liga" "smcp"'
|
||||
]
|
||||
},
|
||||
"font-language-override": {
|
||||
domProp: "fontLanguageOverride",
|
||||
inherited: true,
|
||||
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
|
||||
alias_for: "-moz-font-language-override",
|
||||
subproperties: [ "-moz-font-language-override" ],
|
||||
initial_values: [ "normal" ],
|
||||
other_values: [ "'ENG'", "'TRK'", "\"TRK\"", "'N\\'Ko'" ],
|
||||
invalid_values: [ "TRK", "ja" ]
|
||||
}
|
||||
};
|
||||
for (var prop in fontFeatureProperties) {
|
||||
gCSSProperties[prop] = fontFeatureProperties[prop];
|
||||
}
|
||||
var fontAdditions = [ "font-kerning", "font-synthesis", "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position" ];
|
||||
gCSSProperties["font"].subproperties = gCSSProperties["font"].subproperties.concat(fontAdditions);
|
||||
}
|
||||
|
||||
if (SpecialPowers.getBoolPref("layout.css.masking.enabled")) {
|
||||
gCSSProperties["mask-type"] = {
|
||||
domProp: "maskType",
|
||||
|
@ -61,6 +61,21 @@ var all_but_one = {
|
||||
"-moz-font-feature-settings": "normal", // has to be default value
|
||||
"-moz-font-language-override": "normal" // has to be default value
|
||||
};
|
||||
if (SpecialPowers.getBoolPref("layout.css.font-features.enabled")) {
|
||||
var featureDefs = {
|
||||
"font-kerning": "auto", // has to be default value
|
||||
"font-synthesis": "weight style", // has to be default value
|
||||
"font-variant-alternates": "normal", // has to be default value
|
||||
"font-variant-caps": "normal", // has to be default value
|
||||
"font-variant-east-asian": "normal", // has to be default value
|
||||
"font-variant-ligatures": "normal", // has to be default value
|
||||
"font-variant-numeric": "normal", // has to be default value
|
||||
"font-variant-position": "normal" // has to be default value
|
||||
};
|
||||
for (var prop in featureDefs) {
|
||||
all_but_one[prop] = featureDefs[prop];
|
||||
}
|
||||
}
|
||||
for (var prop in all_but_one) {
|
||||
s.setProperty(prop, all_but_one[prop], "");
|
||||
}
|
||||
|
@ -47,7 +47,13 @@ is(e.style.cssText, "font: menu; font-weight: -moz-use-system-font ! important;"
|
||||
is(e.style.font, "", "font getter returns nothing");
|
||||
|
||||
e.setAttribute("style", "font: inherit; font-family: Helvetica;");
|
||||
is(e.style.cssText, "font-style: inherit; font-variant: inherit; font-weight: inherit; font-size: inherit; line-height: inherit; font-size-adjust: inherit; font-stretch: inherit; -moz-font-feature-settings: inherit; -moz-font-language-override: inherit; font-family: Helvetica;", "don't serialize system font for font:inherit");
|
||||
|
||||
var cssTextStr = "font-style: inherit; font-variant: inherit; font-weight: inherit; font-size: inherit; line-height: inherit; font-size-adjust: inherit; font-stretch: inherit; -moz-font-feature-settings: inherit; -moz-font-language-override: inherit;";
|
||||
if (SpecialPowers.getBoolPref("layout.css.font-features.enabled")) {
|
||||
cssTextStr += " font-kerning: inherit; font-synthesis: inherit; font-variant-alternates: inherit; font-variant-caps: inherit; font-variant-east-asian: inherit; font-variant-ligatures: inherit; font-variant-numeric: inherit; font-variant-position: inherit;"
|
||||
}
|
||||
|
||||
is(e.style.cssText, cssTextStr + " font-family: Helvetica;", "don't serialize system font for font:inherit");
|
||||
is(e.style.font, "", "font getter returns nothing");
|
||||
|
||||
</script>
|
||||
|
@ -1739,6 +1739,19 @@ pref("layout.css.supports-rule.enabled", true);
|
||||
// Is support for CSS Flexbox enabled?
|
||||
pref("layout.css.flexbox.enabled", true);
|
||||
|
||||
// Is support for CSS3 Fonts features enabled?
|
||||
// (includes font-variant-*, font-kerning, font-synthesis
|
||||
// and the @font-feature-values rule)
|
||||
// Note: with this enabled, font-feature-settings is aliased
|
||||
// to -moz-font-feature-settings. When unprefixing, this should
|
||||
// be reversed, -moz-font-feature-settings should alias to
|
||||
// font-feature-settings.
|
||||
#ifdef RELEASE_BUILD
|
||||
pref("layout.css.font-features.enabled", false);
|
||||
#else
|
||||
pref("layout.css.font-features.enabled", true);
|
||||
#endif
|
||||
|
||||
// Are sets of prefixed properties supported?
|
||||
pref("layout.css.prefixes.border-image", true);
|
||||
pref("layout.css.prefixes.transforms", true);
|
||||
|
Loading…
Reference in New Issue
Block a user