author | Jonathan Kew <jfkthame@gmail.com> |
Tue, 13 Jul 2010 21:30:42 +0100 | |
changeset 47359 | 0f7bc3357bc3d24d1f325c945a8d7b929c0a9b53 |
parent 47358 | 2f5efa678ed82d97a911042ba94bbea91248a08a |
child 47360 | 1027e04ad4ee459b548b8c9afa86f8d13ec59d51 |
push id | 1 |
push user | root |
push date | Tue, 26 Apr 2011 22:38:44 +0000 |
treeherder | mozilla-beta@bfdb6e623a36 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | dbaron |
bugs | 511339 |
milestone | 2.0b2pre |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp +++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp @@ -2350,17 +2350,19 @@ nsCanvasRenderingContext2D::SetFont(cons gfxFontStyle style(fontStyle->mFont.style, fontStyle->mFont.weight, fontStyle->mFont.stretch, NSAppUnitsToFloatPixels(fontSize, float(aupcp)), language, fontStyle->mFont.sizeAdjust, fontStyle->mFont.systemFont, fontStyle->mFont.familyNameQuirks, - printerFont); + printerFont, + fontStyle->mFont.featureSettings, + fontStyle->mFont.languageOverride); CurrentState().fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(fontStyle->mFont.name, &style, presShell->GetPresContext()->GetUserFontSet()); NS_ASSERTION(CurrentState().fontGroup, "Could not get font group"); CurrentState().font = font; return NS_OK;
--- a/dom/interfaces/css/nsIDOMNSCSS2Properties.idl +++ b/dom/interfaces/css/nsIDOMNSCSS2Properties.idl @@ -35,17 +35,17 @@ * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "nsIDOMSVGCSS2Properties.idl" -[scriptable, uuid(29B6104D-933F-4DD0-8FC8-BDEC0514469D)] +[scriptable, uuid(C8FA5710-8E47-4E76-9EBD-87E2ACF4F46C)] interface nsIDOMNSCSS2Properties : nsIDOMSVGCSS2Properties { /* Non-DOM 2 extensions */ /* Mozilla extension CSS properties */ attribute DOMString MozAppearance; // raises(DOMException) on setting @@ -116,16 +116,22 @@ interface nsIDOMNSCSS2Properties : nsIDO // raises(DOMException) on setting attribute DOMString MozColumnGap; // raises(DOMException) on setting attribute DOMString MozFloatEdge; // raises(DOMException) on setting + attribute DOMString MozFontFeatureSettings; + // raises(DOMException) on setting + + attribute DOMString MozFontLanguageOverride; + // raises(DOMException) on setting + attribute DOMString MozForceBrokenImageIcon; // raises(DOMException) on setting attribute DOMString MozImageRegion; // raises(DOMException) on setting attribute DOMString MozMarginEnd; // raises(DOMException) on setting
--- a/gfx/src/nsFont.cpp +++ b/gfx/src/nsFont.cpp @@ -37,60 +37,78 @@ #include "nsFont.h" #include "nsString.h" #include "nsUnicharUtils.h" #include "nsCRT.h" nsFont::nsFont(const char* aName, PRUint8 aStyle, PRUint8 aVariant, PRUint16 aWeight, PRInt16 aStretch, PRUint8 aDecoration, - nscoord aSize, float aSizeAdjust) + nscoord aSize, float aSizeAdjust, + const nsString* aFeatureSettings, + const nsString* aLanguageOverride) { NS_ASSERTION(aName && IsASCII(nsDependentCString(aName)), "Must only pass ASCII names here"); name.AssignASCII(aName); style = aStyle; systemFont = PR_FALSE; variant = aVariant; familyNameQuirks = PR_FALSE; weight = aWeight; stretch = aStretch; decorations = aDecoration; size = aSize; sizeAdjust = aSizeAdjust; + if (aFeatureSettings) { + featureSettings = *aFeatureSettings; + } + if (aLanguageOverride) { + languageOverride = *aLanguageOverride; + } } nsFont::nsFont(const nsString& aName, PRUint8 aStyle, PRUint8 aVariant, PRUint16 aWeight, PRInt16 aStretch, PRUint8 aDecoration, - nscoord aSize, float aSizeAdjust) + nscoord aSize, float aSizeAdjust, + const nsString* aFeatureSettings, + const nsString* aLanguageOverride) : name(aName) { style = aStyle; systemFont = PR_FALSE; variant = aVariant; familyNameQuirks = PR_FALSE; weight = aWeight; stretch = aStretch; decorations = aDecoration; size = aSize; sizeAdjust = aSizeAdjust; + if (aFeatureSettings) { + featureSettings = *aFeatureSettings; + } + if (aLanguageOverride) { + languageOverride = *aLanguageOverride; + } } nsFont::nsFont(const nsFont& aOther) : name(aOther.name) { style = aOther.style; systemFont = aOther.systemFont; variant = aOther.variant; familyNameQuirks = aOther.familyNameQuirks; weight = aOther.weight; stretch = aOther.stretch; decorations = aOther.decorations; size = aOther.size; sizeAdjust = aOther.sizeAdjust; + featureSettings = aOther.featureSettings; + languageOverride = aOther.languageOverride; } nsFont::nsFont() { } nsFont::~nsFont() { @@ -100,17 +118,19 @@ PRBool nsFont::BaseEquals(const nsFont& { if ((style == aOther.style) && (systemFont == aOther.systemFont) && (familyNameQuirks == aOther.familyNameQuirks) && (weight == aOther.weight) && (stretch == aOther.stretch) && (size == aOther.size) && (sizeAdjust == aOther.sizeAdjust) && - name.Equals(aOther.name, nsCaseInsensitiveStringComparator())) { + name.Equals(aOther.name, nsCaseInsensitiveStringComparator()) && + (featureSettings == aOther.featureSettings) && + (languageOverride == aOther.languageOverride)) { return PR_TRUE; } return PR_FALSE; } PRBool nsFont::Equals(const nsFont& aOther) const { if (BaseEquals(aOther) && @@ -128,16 +148,18 @@ nsFont& nsFont::operator=(const nsFont& systemFont = aOther.systemFont; variant = aOther.variant; familyNameQuirks = aOther.familyNameQuirks; weight = aOther.weight; stretch = aOther.stretch; decorations = aOther.decorations; size = aOther.size; sizeAdjust = aOther.sizeAdjust; + featureSettings = aOther.featureSettings; + languageOverride = aOther.languageOverride; return *this; } static PRBool IsGenericFontFamily(const nsString& aFamily) { PRUint8 generic; nsFont::GetGenericID(aFamily, &generic); return generic != kGenericFont_NONE;
--- a/gfx/src/nsFont.h +++ b/gfx/src/nsFont.h @@ -97,25 +97,37 @@ struct NS_GFX nsFont { nscoord size; // The aspect-value (ie., the ratio actualsize:actualxheight) that any // actual physical font created from this font structure must have when // rendering or measuring a string. A value of 0 means no adjustment // needs to be done. float sizeAdjust; + // Font features from CSS font-feature-settings + nsString featureSettings; + + // Language system tag, to override document language; + // this is an OpenType "language system" tag represented as a 32-bit integer + // (see http://www.microsoft.com/typography/otspec/languagetags.htm). + nsString languageOverride; + // Initialize the font struct with an ASCII name nsFont(const char* aName, PRUint8 aStyle, PRUint8 aVariant, PRUint16 aWeight, PRInt16 aStretch, PRUint8 aDecoration, - nscoord aSize, float aSizeAdjust=0.0f); + nscoord aSize, float aSizeAdjust=0.0f, + const nsString* aFeatureSettings = nsnull, + const nsString* aLanguageOverride = nsnull); // Initialize the font struct with a (potentially) unicode name nsFont(const nsString& aName, PRUint8 aStyle, PRUint8 aVariant, PRUint16 aWeight, PRInt16 aStretch, PRUint8 aDecoration, - nscoord aSize, float aSizeAdjust=0.0f); + nscoord aSize, float aSizeAdjust=0.0f, + const nsString* aFeatureSettings = nsnull, + const nsString* aLanguageOverride = nsnull); // Make a copy of the given font nsFont(const nsFont& aFont); nsFont(); ~nsFont(); PRBool operator==(const nsFont& aOther) const {
--- a/gfx/src/thebes/nsThebesFontMetrics.cpp +++ b/gfx/src/thebes/nsThebesFontMetrics.cpp @@ -78,17 +78,19 @@ nsThebesFontMetrics::Init(const nsFont& gfxFloat size = gfxFloat(aFont.size) / mP2A; PRBool printerFont = mDeviceContext->IsPrinterSurface(); mFontStyle = new gfxFontStyle(aFont.style, aFont.weight, aFont.stretch, size, aLanguage, aFont.sizeAdjust, aFont.systemFont, aFont.familyNameQuirks, - printerFont); + printerFont, + aFont.featureSettings, + aFont.languageOverride); mFontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(aFont.name, mFontStyle, aUserFontSet); if (mFontGroup->FontListLength() < 1) return NS_ERROR_UNEXPECTED; return NS_OK;
--- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -1694,16 +1694,17 @@ InsertFontFaceRule(nsCSSFontFaceRule *aR nsAutoString fontfamily; nsCSSValue val; PRUint32 unit; PRUint32 weight = NS_STYLE_FONT_WEIGHT_NORMAL; PRUint32 stretch = NS_STYLE_FONT_STRETCH_NORMAL; PRUint32 italicStyle = FONT_STYLE_NORMAL; + nsString featureSettings, languageOverride; // set up family name aRule->GetDesc(eCSSFontDesc_Family, val); unit = val.GetUnit(); if (unit == eCSSUnit_String) { val.GetStringValue(fontfamily); } else { NS_ASSERTION(unit == eCSSUnit_Null, @@ -1744,16 +1745,40 @@ InsertFontFaceRule(nsCSSFontFaceRule *aR italicStyle = val.GetIntValue(); } else if (unit == eCSSUnit_Normal) { italicStyle = FONT_STYLE_NORMAL; } else { NS_ASSERTION(unit == eCSSUnit_Null, "@font-face style has unexpected unit"); } + // set up font features + aRule->GetDesc(eCSSFontDesc_FontFeatureSettings, val); + unit = val.GetUnit(); + if (unit == eCSSUnit_Normal) { + // empty feature string + } else if (unit == eCSSUnit_String) { + val.GetStringValue(featureSettings); + } else { + NS_ASSERTION(unit == eCSSUnit_Null, + "@font-face font-feature-settings has unexpected unit"); + } + + // set up font language override + aRule->GetDesc(eCSSFontDesc_FontLanguageOverride, val); + unit = val.GetUnit(); + if (unit == eCSSUnit_Normal) { + // empty feature string + } else if (unit == eCSSUnit_String) { + val.GetStringValue(languageOverride); + } else { + NS_ASSERTION(unit == eCSSUnit_Null, + "@font-face font-language-override has unexpected unit"); + } + // set up src array nsTArray<gfxFontFaceSrc> srcArray; aRule->GetDesc(eCSSFontDesc_Src, val); unit = val.GetUnit(); if (unit == eCSSUnit_Array) { nsCSSValue::Array *srcArr = val.GetArrayValue(); size_t numSrc = srcArr->Count(); @@ -1819,17 +1844,18 @@ InsertFontFaceRule(nsCSSFontFaceRule *aR break; } } } else { NS_ASSERTION(unit == eCSSUnit_Null, "@font-face src has unexpected unit"); } if (!fontfamily.IsEmpty() && srcArray.Length() > 0) { - aFontSet->AddFontFace(fontfamily, srcArray, weight, stretch, italicStyle); + aFontSet->AddFontFace(fontfamily, srcArray, weight, stretch, italicStyle, + featureSettings, languageOverride); } } gfxUserFontSet* nsPresContext::GetUserFontSetInternal() { // We want to initialize the user font set lazily the first time the // user asks for it, rather than building it too early and forcing
--- a/layout/style/nsCSSDeclaration.cpp +++ b/layout/style/nsCSSDeclaration.cpp @@ -1025,40 +1025,49 @@ nsCSSDeclaration::GetValue(nsCSSProperty const nsCSSValue &lh = *data->ValueStorageFor(eCSSProperty_line_height); const nsCSSValue &family = *data->ValueStorageFor(eCSSProperty_font_family); const nsCSSValue &stretch = *data->ValueStorageFor(eCSSProperty_font_stretch); const nsCSSValue &sizeAdjust = *data->ValueStorageFor(eCSSProperty_font_size_adjust); + const nsCSSValue &featureSettings = + *data->ValueStorageFor(eCSSProperty_font_feature_settings); + const nsCSSValue &languageOverride = + *data->ValueStorageFor(eCSSProperty_font_language_override); if (systemFont && systemFont->GetUnit() != eCSSUnit_None && systemFont->GetUnit() != eCSSUnit_Null) { if (style.GetUnit() != eCSSUnit_System_Font || variant.GetUnit() != eCSSUnit_System_Font || weight.GetUnit() != eCSSUnit_System_Font || size.GetUnit() != eCSSUnit_System_Font || lh.GetUnit() != eCSSUnit_System_Font || family.GetUnit() != eCSSUnit_System_Font || stretch.GetUnit() != eCSSUnit_System_Font || - sizeAdjust.GetUnit() != eCSSUnit_System_Font) { + sizeAdjust.GetUnit() != eCSSUnit_System_Font || + featureSettings.GetUnit() != eCSSUnit_System_Font || + languageOverride.GetUnit() != eCSSUnit_System_Font) { // This can't be represented as a shorthand. return NS_OK; } AppendCSSValueToString(eCSSProperty__x_system_font, *systemFont, aValue); } else { - // The font-stretch and font-size-adjust + // The font-stretch, font-size-adjust, + // -moz-font-feature-settings, and -moz-font-language-override // properties 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) { + sizeAdjust.GetUnit() != eCSSUnit_None || + featureSettings.GetUnit() != eCSSUnit_Normal || + languageOverride.GetUnit() != eCSSUnit_Normal) { return NS_OK; } if (style.GetUnit() != eCSSUnit_Enumerated || style.GetIntValue() != NS_FONT_STYLE_NORMAL) { AppendCSSValueToString(eCSSProperty_font_style, style, aValue); aValue.Append(PRUnichar(' ')); }
--- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -5958,16 +5958,20 @@ CSSParserImpl::ParseSingleValueProperty( case eCSSProperty_float: return ParseVariant(aValue, VARIANT_HK, nsCSSProps::kFloatKTable); case eCSSProperty_float_edge: return ParseVariant(aValue, VARIANT_HK, nsCSSProps::kFloatEdgeKTable); case eCSSProperty_font_family: return ParseFamily(aValue); + case eCSSProperty_font_feature_settings: + case eCSSProperty_font_language_override: + return ParseVariant(aValue, VARIANT_NORMAL | VARIANT_INHERIT | + VARIANT_STRING, nsnull); case eCSSProperty_font_size: return ParseNonNegativeVariant(aValue, VARIANT_HKLP | VARIANT_SYSFONT | VARIANT_CALC, nsCSSProps::kFontSizeKTable); case eCSSProperty_font_size_adjust: return ParseVariant(aValue, VARIANT_HON | VARIANT_SYSFONT, nsnull); @@ -6236,16 +6240,20 @@ CSSParserImpl::ParseFontDescriptorValue( // These two are unique to @font-face and have their own special grammar. case eCSSFontDesc_Src: return ParseFontSrc(aValue); case eCSSFontDesc_UnicodeRange: return ParseFontRanges(aValue); + case eCSSFontDesc_FontFeatureSettings: + case eCSSFontDesc_FontLanguageOverride: + return ParseVariant(aValue, VARIANT_NORMAL | VARIANT_STRING, nsnull); + case eCSSFontDesc_UNKNOWN: case eCSSFontDesc_COUNT: NS_NOTREACHED("bad nsCSSFontDesc code"); } // explicitly do NOT have a default case to let the compiler // help find missing descriptors return PR_FALSE; } @@ -7820,28 +7828,32 @@ CSSParserImpl::ParseFont() AppendValue(eCSSProperty_font_family, family); AppendValue(eCSSProperty_font_style, family); AppendValue(eCSSProperty_font_variant, family); AppendValue(eCSSProperty_font_weight, family); AppendValue(eCSSProperty_font_size, family); AppendValue(eCSSProperty_line_height, family); AppendValue(eCSSProperty_font_stretch, family); AppendValue(eCSSProperty_font_size_adjust, family); + AppendValue(eCSSProperty_font_feature_settings, family); + AppendValue(eCSSProperty_font_language_override, family); } else { AppendValue(eCSSProperty__x_system_font, family); nsCSSValue systemFont(eCSSUnit_System_Font); AppendValue(eCSSProperty_font_family, systemFont); AppendValue(eCSSProperty_font_style, systemFont); AppendValue(eCSSProperty_font_variant, systemFont); AppendValue(eCSSProperty_font_weight, systemFont); AppendValue(eCSSProperty_font_size, systemFont); AppendValue(eCSSProperty_line_height, systemFont); AppendValue(eCSSProperty_font_stretch, systemFont); AppendValue(eCSSProperty_font_size_adjust, systemFont); + AppendValue(eCSSProperty_font_feature_settings, systemFont); + AppendValue(eCSSProperty_font_language_override, systemFont); } return PR_TRUE; } return PR_FALSE; } // Get optional font-style, font-variant and font-weight (in any order) const PRInt32 numProps = 3; @@ -7893,16 +7905,18 @@ CSSParserImpl::ParseFont() AppendValue(eCSSProperty_font_style, values[0]); AppendValue(eCSSProperty_font_variant, values[1]); AppendValue(eCSSProperty_font_weight, values[2]); AppendValue(eCSSProperty_font_size, size); AppendValue(eCSSProperty_line_height, lineHeight); AppendValue(eCSSProperty_font_stretch, nsCSSValue(NS_FONT_STRETCH_NORMAL, eCSSUnit_Enumerated)); AppendValue(eCSSProperty_font_size_adjust, nsCSSValue(eCSSUnit_None)); + AppendValue(eCSSProperty_font_feature_settings, nsCSSValue(eCSSUnit_Normal)); + AppendValue(eCSSProperty_font_language_override, nsCSSValue(eCSSUnit_Normal)); return PR_TRUE; } } return PR_FALSE; } PRBool CSSParserImpl::ParseFontWeight(nsCSSValue& aValue)
--- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -1426,16 +1426,38 @@ CSS_PROP_FONT( CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, Font, mFamily, eCSSType_Value, nsnull, CSS_PROP_NO_OFFSET, eStyleAnimType_None) CSS_PROP_FONT( + -moz-font-feature-settings, + font_feature_settings, + MozFontFeatureSettings, + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, + Font, + mFontFeatureSettings, + eCSSType_Value, + nsnull, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +CSS_PROP_FONT( + -moz-font-language-override, + font_language_override, + MozFontLanguageOverride, + CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, + Font, + mFontLanguageOverride, + eCSSType_Value, + nsnull, + CSS_PROP_NO_OFFSET, + eStyleAnimType_None) +CSS_PROP_FONT( font-size, font_size, FontSize, CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE, Font, mSize, eCSSType_Value, kFontSizeKTable,
--- a/layout/style/nsCSSProperty.h +++ b/layout/style/nsCSSProperty.h @@ -96,12 +96,14 @@ enum nsCSSType { enum nsCSSFontDesc { eCSSFontDesc_UNKNOWN = -1, eCSSFontDesc_Family, eCSSFontDesc_Style, eCSSFontDesc_Weight, eCSSFontDesc_Stretch, eCSSFontDesc_Src, eCSSFontDesc_UnicodeRange, + eCSSFontDesc_FontFeatureSettings, + eCSSFontDesc_FontLanguageOverride, eCSSFontDesc_COUNT }; #endif /* nsCSSProperty_h___ */
--- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -81,17 +81,19 @@ static nsStaticCaseInsensitiveNameTable* // Keep in sync with enum nsCSSFontDesc in nsCSSProperty.h. static const char* const kCSSRawFontDescs[] = { "font-family", "font-style", "font-weight", "font-stretch", "src", - "unicode-range" + "unicode-range", + "-moz-font-feature-settings", + "-moz-font-language-override" }; struct PropertyAndCount { nsCSSProperty property; PRUint32 count; }; static int @@ -1854,16 +1856,18 @@ static const nsCSSProperty gFontSubpropT eCSSProperty_font_style, eCSSProperty_font_variant, eCSSProperty_font_weight, eCSSProperty_font_size, eCSSProperty_line_height, eCSSProperty_font_size_adjust, // XXX Added LDB. eCSSProperty_font_stretch, // XXX Added LDB. eCSSProperty__x_system_font, + eCSSProperty_font_feature_settings, + eCSSProperty_font_language_override, eCSSProperty_UNKNOWN }; static const nsCSSProperty gListStyleSubpropTable[] = { eCSSProperty_list_style_type, eCSSProperty_list_style_image, eCSSProperty_list_style_position, eCSSProperty_UNKNOWN
--- a/layout/style/nsCSSRules.cpp +++ b/layout/style/nsCSSRules.cpp @@ -1571,17 +1571,19 @@ AppendSerializedUnicodeRange(nsCSSValue // Keep this in sync with enum nsCSSFontDesc in nsCSSProperty.h. nsCSSValue nsCSSFontFaceStyleDecl::* const nsCSSFontFaceStyleDecl::Fields[] = { &nsCSSFontFaceStyleDecl::mFamily, &nsCSSFontFaceStyleDecl::mStyle, &nsCSSFontFaceStyleDecl::mWeight, &nsCSSFontFaceStyleDecl::mStretch, &nsCSSFontFaceStyleDecl::mSrc, - &nsCSSFontFaceStyleDecl::mUnicodeRange + &nsCSSFontFaceStyleDecl::mUnicodeRange, + &nsCSSFontFaceStyleDecl::mFontFeatureSettings, + &nsCSSFontFaceStyleDecl::mFontLanguageOverride }; DOMCI_DATA(CSSFontFaceStyleDecl, nsCSSFontFaceStyleDecl) // QueryInterface implementation for nsCSSFontFaceStyleDecl NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceStyleDecl) NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleDeclaration) NS_INTERFACE_MAP_ENTRY(nsISupports)
--- a/layout/style/nsCSSRules.h +++ b/layout/style/nsCSSRules.h @@ -229,16 +229,18 @@ public: protected: friend class nsCSSFontFaceRule; nsCSSValue mFamily; nsCSSValue mStyle; nsCSSValue mWeight; nsCSSValue mStretch; nsCSSValue mSrc; nsCSSValue mUnicodeRange; + nsCSSValue mFontFeatureSettings; + nsCSSValue mFontLanguageOverride; static nsCSSValue nsCSSFontFaceStyleDecl::* const Fields[]; inline nsCSSFontFaceRule* ContainingRule(); inline const nsCSSFontFaceRule* ContainingRule() const; private: // NOT TO BE IMPLEMENTED // This object cannot be allocated on its own, only as part of
--- a/layout/style/nsCSSStruct.h +++ b/layout/style/nsCSSStruct.h @@ -278,16 +278,18 @@ struct nsCSSFont : public nsCSSStruct { nsCSSValue mSystemFont; nsCSSValue mFamily; nsCSSValue mStyle; nsCSSValue mVariant; nsCSSValue mWeight; nsCSSValue mSize; nsCSSValue mSizeAdjust; // NEW nsCSSValue mStretch; // NEW + nsCSSValue mFontFeatureSettings; + nsCSSValue mFontLanguageOverride; #ifdef MOZ_MATHML nsCSSValue mScriptLevel; // Integer values mean "relative", Number values mean "absolute" nsCSSValue mScriptSizeMultiplier; nsCSSValue mScriptMinSize; #endif private:
--- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -1314,16 +1314,50 @@ nsComputedDOMStyle::GetFontVariant(nsIDO nsCSSProps::ValueToKeywordEnum(GetStyleFont()->mFont.variant, nsCSSProps::kFontVariantKTable)); NS_ADDREF(*aValue = val); return NS_OK; } nsresult +nsComputedDOMStyle::GetMozFontFeatureSettings(nsIDOMCSSValue** aValue) +{ + nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue(); + NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY); + + const nsStyleFont* font = GetStyleFont(); + if (font->mFont.featureSettings.IsEmpty()) { + val->SetIdent(eCSSKeyword_normal); + } else { + nsString str; + nsStyleUtil::AppendEscapedCSSString(font->mFont.featureSettings, str); + val->SetString(str); + } + return CallQueryInterface(val, aValue); +} + +nsresult +nsComputedDOMStyle::GetMozFontLanguageOverride(nsIDOMCSSValue** aValue) +{ + nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue(); + NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY); + + const nsStyleFont* font = GetStyleFont(); + if (font->mFont.languageOverride.IsEmpty()) { + val->SetIdent(eCSSKeyword_normal); + } else { + nsString str; + nsStyleUtil::AppendEscapedCSSString(font->mFont.languageOverride, str); + val->SetString(str); + } + return CallQueryInterface(val, aValue); +} + +nsresult nsComputedDOMStyle::GetBackgroundList(PRUint8 nsStyleBackground::Layer::* aMember, PRUint32 nsStyleBackground::* aCount, const PRInt32 aTable[], nsIDOMCSSValue** aResult) { const nsStyleBackground* bg = GetStyleBackground(); nsDOMCSSValueList *valueList = GetROCSSValueList(PR_TRUE); @@ -4759,16 +4793,18 @@ nsComputedDOMStyle::GetQueryableProperty COMPUTED_STYLE_MAP_ENTRY(_moz_column_count, ColumnCount), COMPUTED_STYLE_MAP_ENTRY(_moz_column_width, ColumnWidth), COMPUTED_STYLE_MAP_ENTRY(_moz_column_gap, ColumnGap), //// COMPUTED_STYLE_MAP_ENTRY(_moz_column_rule, ColumnRule), COMPUTED_STYLE_MAP_ENTRY(_moz_column_rule_color, ColumnRuleColor), COMPUTED_STYLE_MAP_ENTRY(_moz_column_rule_width, ColumnRuleWidth), COMPUTED_STYLE_MAP_ENTRY(_moz_column_rule_style, ColumnRuleStyle), COMPUTED_STYLE_MAP_ENTRY(float_edge, FloatEdge), + COMPUTED_STYLE_MAP_ENTRY(font_feature_settings, MozFontFeatureSettings), + COMPUTED_STYLE_MAP_ENTRY(font_language_override, MozFontLanguageOverride), COMPUTED_STYLE_MAP_ENTRY(force_broken_image_icon, ForceBrokenImageIcon), COMPUTED_STYLE_MAP_ENTRY(image_region, ImageRegion), COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_outline_radius_bottomLeft, OutlineRadiusBottomLeft), COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_outline_radius_bottomRight,OutlineRadiusBottomRight), COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_outline_radius_topLeft, OutlineRadiusTopLeft), COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_outline_radius_topRight, OutlineRadiusTopRight), COMPUTED_STYLE_MAP_ENTRY(resize, Resize), COMPUTED_STYLE_MAP_ENTRY(stack_sizing, StackSizing),
--- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -178,16 +178,18 @@ private: nsresult GetTop(nsIDOMCSSValue** aValue); nsresult GetRight(nsIDOMCSSValue** aValue); nsresult GetBottom(nsIDOMCSSValue** aValue); nsresult GetStackSizing(nsIDOMCSSValue** aValue); /* Font properties */ nsresult GetColor(nsIDOMCSSValue** aValue); nsresult GetFontFamily(nsIDOMCSSValue** aValue); + nsresult GetMozFontFeatureSettings(nsIDOMCSSValue** aValue); + nsresult GetMozFontLanguageOverride(nsIDOMCSSValue** aValue); nsresult GetFontSize(nsIDOMCSSValue** aValue); nsresult GetFontSizeAdjust(nsIDOMCSSValue** aValue); nsresult GetFontStretch(nsIDOMCSSValue** aValue); nsresult GetFontStyle(nsIDOMCSSValue** aValue); nsresult GetFontWeight(nsIDOMCSSValue** aValue); nsresult GetFontVariant(nsIDOMCSSValue** aValue); /* Background properties */
--- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -3270,16 +3270,42 @@ nsRuleNode::SetFont(nsPresContext* aPres aCanStoreInRuleTree = PR_FALSE; aFont->mScriptLevel = aParentFont->mScriptLevel; } else if (eCSSUnit_Initial == aFontData.mScriptSizeMultiplier.GetUnit()) { aFont->mScriptLevel = 0; } #endif + // font-feature-settings + if (eCSSUnit_Inherit == aFontData.mFontFeatureSettings.GetUnit()) { + aCanStoreInRuleTree = PR_FALSE; + aFont->mFont.featureSettings = aParentFont->mFont.featureSettings; + } else if (eCSSUnit_Normal == aFontData.mFontFeatureSettings.GetUnit() || + eCSSUnit_Initial == aFontData.mFontFeatureSettings.GetUnit()) { + aFont->mFont.featureSettings.Truncate(); + } else if (eCSSUnit_System_Font == aFontData.mFontFeatureSettings.GetUnit()) { + aFont->mFont.featureSettings = systemFont.featureSettings; + } else if (eCSSUnit_String == aFontData.mFontFeatureSettings.GetUnit()) { + aFontData.mFontFeatureSettings.GetStringValue(aFont->mFont.featureSettings); + } + + // font-language-override + if (eCSSUnit_Inherit == aFontData.mFontLanguageOverride.GetUnit()) { + aCanStoreInRuleTree = PR_FALSE; + aFont->mFont.languageOverride = aParentFont->mFont.languageOverride; + } else if (eCSSUnit_Normal == aFontData.mFontLanguageOverride.GetUnit() || + eCSSUnit_Initial == aFontData.mFontLanguageOverride.GetUnit()) { + aFont->mFont.languageOverride.Truncate(); + } else if (eCSSUnit_System_Font == aFontData.mFontLanguageOverride.GetUnit()) { + aFont->mFont.languageOverride = systemFont.languageOverride; + } else if (eCSSUnit_String == aFontData.mFontLanguageOverride.GetUnit()) { + aFontData.mFontLanguageOverride.GetStringValue(aFont->mFont.languageOverride); + } + // font-size: enum, length, percent, inherit nscoord scriptLevelAdjustedParentSize = aParentFont->mSize; #ifdef MOZ_MATHML nscoord scriptLevelAdjustedUnconstrainedParentSize; scriptLevelAdjustedParentSize = ComputeScriptLevelSize(aFont, aParentFont, aPresContext, &scriptLevelAdjustedUnconstrainedParentSize); NS_ASSERTION(!aUsedStartStruct || aFont->mScriptUnconstrainedSize == aFont->mSize,
--- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -205,17 +205,19 @@ nsChangeHint nsStyleFont::CalcFontDiffer { if ((aFont1.size == aFont2.size) && (aFont1.sizeAdjust == aFont2.sizeAdjust) && (aFont1.style == aFont2.style) && (aFont1.variant == aFont2.variant) && (aFont1.familyNameQuirks == aFont2.familyNameQuirks) && (aFont1.weight == aFont2.weight) && (aFont1.stretch == aFont2.stretch) && - (aFont1.name == aFont2.name)) { + (aFont1.name == aFont2.name) && + (aFont1.featureSettings == aFont2.featureSettings) && + (aFont1.languageOverride == aFont2.languageOverride)) { if ((aFont1.decorations == aFont2.decorations)) { return NS_STYLE_HINT_NONE; } return NS_STYLE_HINT_VISUAL; } return NS_STYLE_HINT_REFLOW; }
--- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -1466,30 +1466,46 @@ var gCSSProperties = { initial_values: [ "none" ], other_values: [ "left", "right" ], invalid_values: [] }, "font": { domProp: "font", inherited: true, type: CSS_TYPE_TRUE_SHORTHAND, - subproperties: [ "font-style", "font-variant", "font-weight", "font-size", "line-height", "font-family", "font-stretch", "font-size-adjust" ], + subproperties: [ "font-style", "font-variant", "font-weight", "font-size", "line-height", "font-family", "font-stretch", "font-size-adjust", "-moz-font-feature-settings", "-moz-font-language-override" ], /* XXX could be sans-serif */ initial_values: [ "medium serif" ], other_values: [ "large serif", "9px fantasy", "bold italic small-caps 24px/1.4 Times New Roman, serif", "caption", "icon", "menu", "message-box", "small-caption", "status-bar" ], invalid_values: [] }, "font-family": { domProp: "fontFamily", inherited: true, type: CSS_TYPE_LONGHAND, initial_values: [ "serif" ], other_values: [ "sans-serif", "Times New Roman, serif", "'Times New Roman', serif", "cursive", "fantasy", "\"Times New Roman", "Times, \"Times New Roman" ], invalid_values: [ "\"Times New\" Roman" ] }, + "-moz-font-feature-settings": { + domProp: "MozFontFeatureSettings", + inherited: true, + type: CSS_TYPE_LONGHAND, + initial_values: [ "normal" ], + other_values: [ "'liga=1'", "\"liga=1\"", "'foo,bar=\"hello\"'" ], + invalid_values: [ "liga=1", "foo,bar=\"hello\"" ] + }, + "-moz-font-language-override": { + domProp: "MozFontLanguageOverride", + inherited: true, + type: CSS_TYPE_LONGHAND, + initial_values: [ "normal" ], + other_values: [ "'TRK'", "\"TRK\"", "'N\\'Ko'" ], + invalid_values: [ "TRK" ] + }, "font-size": { domProp: "fontSize", inherited: true, type: CSS_TYPE_LONGHAND, initial_values: [ "medium", "1rem", "-moz-calc(1rem)", "-moz-calc(0.75rem + 200% - 125% + 0.25rem - 75%)"
--- a/layout/style/test/test_bug377947.html +++ b/layout/style/test/test_bug377947.html @@ -53,17 +53,19 @@ is(s.getPropertyValue("font"), "", "font shorthand should start off empty"); var all_but_one = { "font-family": "serif", "font-style": "normal", "font-variant": "normal", "font-weight": "bold", "font-size": "small", "font-size-adjust": "none", // has to be default value - "font-stretch": "normal" // has to be default value + "font-stretch": "normal", // has to be default value + "-moz-font-feature-settings": "normal", // has to be default value + "-moz-font-language-override": "normal" // has to be default value }; for (var prop in all_but_one) { s.setProperty(prop, all_but_one[prop], ""); } is(s.getPropertyValue("font"), "", "font shorthand should be empty when some subproperties specified"); s.setProperty("line-height", "1.5", ""); isnot(s.getPropertyValue("font"), "",
--- a/layout/style/test/test_system_font_serialization.html +++ b/layout/style/test/test_system_font_serialization.html @@ -43,15 +43,15 @@ e.setAttribute("style", "font: menu; fon is(e.style.cssText, "font: menu;", "serialize system font alone"); is(e.style.font, "menu", "font getter returns value"); e.setAttribute("style", "font: menu; font-weight: -moz-use-system-font ! important"); is(e.style.cssText, "font: menu; font-weight: -moz-use-system-font ! important;", "serialize system font and subproperty that is 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; font-family: Helvetica;", "don't serialize system font for font:inherit"); +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"); is(e.style.font, "", "font getter returns nothing"); </script> </pre> </body> </html>
--- a/layout/svg/base/src/nsSVGGlyphFrame.cpp +++ b/layout/svg/base/src/nsSVGGlyphFrame.cpp @@ -1496,17 +1496,19 @@ nsSVGGlyphFrame::EnsureTextRun(float *aD const nsFont& font = fontData->mFont; PRBool printerFont = (presContext->Type() == nsPresContext::eContext_PrintPreview || presContext->Type() == nsPresContext::eContext_Print); gfxFontStyle fontStyle(font.style, font.weight, font.stretch, textRunSize, mStyleContext->GetStyleVisibility()->mLanguage, font.sizeAdjust, font.systemFont, font.familyNameQuirks, - printerFont); + printerFont, + font.featureSettings, + font.languageOverride); nsRefPtr<gfxFontGroup> fontGroup = gfxPlatform::GetPlatform()->CreateFontGroup(font.name, &fontStyle, presContext->GetUserFontSet()); PRUint32 flags = gfxTextRunFactory::TEXT_NEED_BOUNDING_BOX | nsLayoutUtils::GetTextRunFlagsForStyle(GetStyleContext(), GetStyleText(), GetStyleFont()); // XXX We should use a better surface here! But then we'd have to