Bug 1435692 - patch 2 - Implement the font-optical-sizing property in the Gecko style system, to control whether optical size is automatically applied. r=jwatt
authorJonathan Kew <jkew@mozilla.com>
Sat, 03 Mar 2018 18:53:11 +0100
changeset 406467 93cd740dde9663639513652018c72a4172c7cefe
parent 406466 65a8e5654ef56bb7a2cf81267a78d7151643765b
child 406468 5116edeac259905a7153f21c2e935df6487fdd71
push id60564
push userecoal95@gmail.com
push dateSat, 03 Mar 2018 21:12:39 +0000
treeherderautoland@eb917fd39e66 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt
bugs1435692
milestone60.0a1
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
Bug 1435692 - patch 2 - Implement the font-optical-sizing property in the Gecko style system, to control whether optical size is automatically applied. r=jwatt MozReview-Commit-ID: ClcWeX6Hsvm
layout/style/Declaration.cpp
layout/style/nsCSSParser.cpp
layout/style/nsCSSPropList.h
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsComputedDOMStylePropertyList.h
layout/style/nsRuleNode.cpp
layout/style/test/property_database.js
layout/style/test/test_bug377947.html
layout/style/test/test_system_font_serialization.html
--- a/layout/style/Declaration.cpp
+++ b/layout/style/Declaration.cpp
@@ -819,16 +819,18 @@ Declaration::GetPropertyValueInternal(
       const nsCSSValue *stretch =
         data->ValueFor(eCSSProperty_font_stretch);
       const nsCSSValue *sizeAdjust =
         data->ValueFor(eCSSProperty_font_size_adjust);
       const nsCSSValue *featureSettings =
         data->ValueFor(eCSSProperty_font_feature_settings);
       const nsCSSValue *languageOverride =
         data->ValueFor(eCSSProperty_font_language_override);
+      const nsCSSValue *opticalSizing =
+        data->ValueFor(eCSSProperty_font_optical_sizing); // may be missing!
       const nsCSSValue *fontKerning =
         data->ValueFor(eCSSProperty_font_kerning);
       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);
@@ -846,16 +848,17 @@ Declaration::GetPropertyValueInternal(
             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 ||
             featureSettings->GetUnit() != eCSSUnit_System_Font ||
             languageOverride->GetUnit() != eCSSUnit_System_Font ||
+            (opticalSizing && opticalSizing->GetUnit() != eCSSUnit_System_Font) ||
             fontKerning->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.
@@ -863,16 +866,17 @@ Declaration::GetPropertyValueInternal(
         }
         systemFont->AppendToString(eCSSProperty__x_system_font, aValue);
       } else {
         // properties reset by this shorthand property to their
         // initial values but not represented in its syntax
         if (sizeAdjust->GetUnit() != eCSSUnit_None ||
             featureSettings->GetUnit() != eCSSUnit_Normal ||
             languageOverride->GetUnit() != eCSSUnit_Normal ||
+            (opticalSizing && opticalSizing->GetIntValue() != NS_FONT_OPTICAL_SIZING_AUTO) ||
             fontKerning->GetIntValue() != NS_FONT_KERNING_AUTO ||
             fontVariantAlternates->GetUnit() != eCSSUnit_Normal ||
             fontVariantEastAsian->GetUnit() != eCSSUnit_Normal ||
             fontVariantLigatures->GetUnit() != eCSSUnit_Normal ||
             fontVariantNumeric->GetUnit() != eCSSUnit_Normal ||
             fontVariantPosition->GetUnit() != eCSSUnit_Normal) {
           return;
         }
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -14051,16 +14051,19 @@ CSSParserImpl::ParseFont()
       AppendValue(eCSSProperty_font_language_override, family);
       AppendValue(eCSSProperty_font_kerning, 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);
+      if (StylePrefs::sFontVariationsEnabled) {
+        AppendValue(eCSSProperty_font_optical_sizing, 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_weight, systemFont);
       AppendValue(eCSSProperty_font_size, systemFont);
@@ -14071,16 +14074,19 @@ CSSParserImpl::ParseFont()
       AppendValue(eCSSProperty_font_language_override, systemFont);
       AppendValue(eCSSProperty_font_kerning, 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);
+      if (StylePrefs::sFontVariationsEnabled) {
+        AppendValue(eCSSProperty_font_optical_sizing, systemFont);
+      }
     }
     return true;
   }
 
   // Get optional font-style, font-variant, font-weight, font-stretch
   // (in any order)
 
   // Indexes into fontIDs[] and values[] arrays.
@@ -14181,16 +14187,20 @@ CSSParserImpl::ParseFont()
       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));
+      if (StylePrefs::sFontVariationsEnabled) {
+        AppendValue(eCSSProperty_font_optical_sizing,
+                    nsCSSValue(NS_FONT_OPTICAL_SIZING_AUTO, eCSSUnit_Enumerated));
+      }
       return true;
     }
   }
   return false;
 }
 
 bool
 CSSParserImpl::ParseFontSynthesis(nsCSSValue& aValue)
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -1871,16 +1871,28 @@ CSS_PROP_FONT(
         CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
         CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
     "",
     VARIANT_NORMAL | VARIANT_INHERIT | VARIANT_STRING,
     nullptr,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_Discrete)
 CSS_PROP_FONT(
+    font-optical-sizing,
+    font_optical_sizing,
+    FontOpticalSizing,
+    CSS_PROPERTY_PARSE_VALUE |
+        CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
+        CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
+    "layout.css.font-variations.enabled",
+    VARIANT_HK,
+    kFontOpticalSizingKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+CSS_PROP_FONT(
     font-size,
     font_size,
     FontSize,
     CSS_PROPERTY_PARSE_VALUE |
         CSS_PROPERTY_VALUE_NONNEGATIVE |
         CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE |
         CSS_PROPERTY_APPLIES_TO_PLACEHOLDER |
         CSS_PROPERTY_UNITLESS_LENGTH_QUIRK,
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -1540,16 +1540,22 @@ const KTableEntry nsCSSProps::kFontKTabl
 
 const KTableEntry nsCSSProps::kFontKerningKTable[] = {
   { eCSSKeyword_auto, NS_FONT_KERNING_AUTO },
   { eCSSKeyword_none, NS_FONT_KERNING_NONE },
   { eCSSKeyword_normal, NS_FONT_KERNING_NORMAL },
   { eCSSKeyword_UNKNOWN, -1 }
 };
 
+const KTableEntry nsCSSProps::kFontOpticalSizingKTable[] = {
+  { eCSSKeyword_auto, NS_FONT_OPTICAL_SIZING_AUTO },
+  { eCSSKeyword_none, NS_FONT_OPTICAL_SIZING_NONE },
+  { eCSSKeyword_UNKNOWN, -1 }
+};
+
 const KTableEntry nsCSSProps::kFontSizeKTable[] = {
   { eCSSKeyword_xx_small, NS_STYLE_FONT_SIZE_XXSMALL },
   { eCSSKeyword_x_small, NS_STYLE_FONT_SIZE_XSMALL },
   { eCSSKeyword_small, NS_STYLE_FONT_SIZE_SMALL },
   { eCSSKeyword_medium, NS_STYLE_FONT_SIZE_MEDIUM },
   { eCSSKeyword_large, NS_STYLE_FONT_SIZE_LARGE },
   { eCSSKeyword_x_large, NS_STYLE_FONT_SIZE_XLARGE },
   { eCSSKeyword_xx_large, NS_STYLE_FONT_SIZE_XXLARGE },
@@ -2788,16 +2794,17 @@ static const nsCSSPropertyID gFontSubpro
   eCSSProperty_font_size,
   eCSSProperty_line_height,
   eCSSProperty_font_size_adjust,
   eCSSProperty_font_stretch,
   eCSSProperty__x_system_font,
   eCSSProperty_font_feature_settings,
   eCSSProperty_font_language_override,
   eCSSProperty_font_kerning,
+  eCSSProperty_font_optical_sizing,
   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
 };
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -793,16 +793,17 @@ public:
   static const KTableEntry kFlexWrapKTable[];
   // Not const because we modify its entries when the pref
   // "layout.css.float-logical-values.enabled" changes:
   static KTableEntry kFloatKTable[];
   static const KTableEntry kFloatEdgeKTable[];
   static const KTableEntry kFontDisplayKTable[];
   static const KTableEntry kFontKTable[];
   static const KTableEntry kFontKerningKTable[];
+  static const KTableEntry kFontOpticalSizingKTable[];
   static const KTableEntry kFontSizeKTable[];
   static const KTableEntry kFontSmoothingKTable[];
   static const KTableEntry kFontStretchKTable[];
   static const KTableEntry kFontStyleKTable[];
   static const KTableEntry kFontSynthesisKTable[];
   static const KTableEntry kFontVariantKTable[];
   static const KTableEntry kFontVariantAlternatesKTable[];
   static const KTableEntry kFontVariantAlternatesFuncsKTable[];
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -2273,16 +2273,26 @@ nsComputedDOMStyle::DoGetFontLanguageOve
     SerializeLanguageOverride(font->mFont.languageOverride, serializedStr);
     nsStyleUtil::AppendEscapedCSSString(serializedStr, escapedStr);
     val->SetString(escapedStr);
   }
   return val.forget();
 }
 
 already_AddRefed<CSSValue>
+nsComputedDOMStyle::DoGetFontOpticalSizing()
+{
+  RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
+  val->SetIdent(
+    nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.opticalSizing,
+                                   nsCSSProps::kFontOpticalSizingKTable));
+  return val.forget();
+}
+
+already_AddRefed<CSSValue>
 nsComputedDOMStyle::DoGetFontSynthesis()
 {
   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
 
   int32_t intValue = StyleFont()->mFont.synthesis;
 
   if (0 == intValue) {
     val->SetIdent(eCSSKeyword_none);
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -288,16 +288,17 @@ private:
 
   /* Font properties */
   already_AddRefed<CSSValue> DoGetColor();
   already_AddRefed<CSSValue> DoGetFontFamily();
   already_AddRefed<CSSValue> DoGetFontFeatureSettings();
   already_AddRefed<CSSValue> DoGetFontVariationSettings();
   already_AddRefed<CSSValue> DoGetFontKerning();
   already_AddRefed<CSSValue> DoGetFontLanguageOverride();
+  already_AddRefed<CSSValue> DoGetFontOpticalSizing();
   already_AddRefed<CSSValue> DoGetFontSize();
   already_AddRefed<CSSValue> DoGetFontSizeAdjust();
   already_AddRefed<CSSValue> DoGetOsxFontSmoothing();
   already_AddRefed<CSSValue> DoGetFontSmoothingBackgroundColor();
   already_AddRefed<CSSValue> DoGetFontStretch();
   already_AddRefed<CSSValue> DoGetFontStyle();
   already_AddRefed<CSSValue> DoGetFontSynthesis();
   already_AddRefed<CSSValue> DoGetFontVariant();
--- a/layout/style/nsComputedDOMStylePropertyList.h
+++ b/layout/style/nsComputedDOMStylePropertyList.h
@@ -130,16 +130,17 @@ COMPUTED_STYLE_PROP(flex_grow,          
 COMPUTED_STYLE_PROP(flex_shrink,                   FlexShrink)
 COMPUTED_STYLE_PROP(flex_wrap,                     FlexWrap)
 COMPUTED_STYLE_PROP(float_,                        Float)
 //// COMPUTED_STYLE_PROP(font,                     Font)
 COMPUTED_STYLE_PROP(font_family,                   FontFamily)
 COMPUTED_STYLE_PROP(font_feature_settings,         FontFeatureSettings)
 COMPUTED_STYLE_PROP(font_kerning,                  FontKerning)
 COMPUTED_STYLE_PROP(font_language_override,        FontLanguageOverride)
+COMPUTED_STYLE_PROP(font_optical_sizing,           FontOpticalSizing)
 COMPUTED_STYLE_PROP(font_size,                     FontSize)
 COMPUTED_STYLE_PROP(font_size_adjust,              FontSizeAdjust)
 COMPUTED_STYLE_PROP(font_stretch,                  FontStretch)
 COMPUTED_STYLE_PROP(font_style,                    FontStyle)
 COMPUTED_STYLE_PROP(font_synthesis,                FontSynthesis)
 COMPUTED_STYLE_PROP(font_variant,                  FontVariant)
 COMPUTED_STYLE_PROP(font_variant_alternates,       FontVariantAlternates)
 COMPUTED_STYLE_PROP(font_variant_caps,             FontVariantCaps)
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -3746,16 +3746,24 @@ nsRuleNode::SetFont(nsPresContext* aPres
   // font-synthesis: none, enum (bit field), inherit, initial
   SetValue(*aRuleData->ValueForFontSynthesis(),
            aFont->mFont.synthesis, aConditions,
            SETVAL_ENUMERATED | SETVAL_UNSET_INHERIT,
            aParentFont->mFont.synthesis,
            defaultVariableFont->synthesis,
            Unused, /* none */ 0, Unused, Unused);
 
+  // font-optical-sizing: none, enum, inherit, initial, -moz-system-font
+  SetValue(*aRuleData->ValueForFontOpticalSizing(),
+           aFont->mFont.opticalSizing, aConditions,
+           SETVAL_ENUMERATED | SETVAL_UNSET_INHERIT,
+           aParentFont->mFont.opticalSizing,
+           defaultVariableFont->opticalSizing,
+           Unused, Unused, Unused, systemFont.opticalSizing);
+
   // 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:
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -6354,17 +6354,29 @@ if (IsCSSPropertyPrefEnabled("layout.css
       "'wdth' 1 'wght' 2", // missing comma between pairs
       "'wdth' 1,", // trailing comma
       "'wdth' 1 , , 'wght' 2", // extra comma
       "'wdth', 1" // comma within pair
     ],
     unbalanced_values: [
       "'wdth\" 1", "\"wdth' 1" // mismatched quotes
     ]
-  }
+  };
+  gCSSProperties["font-optical-sizing"] = {
+    domProp: "fontOpticalSizing",
+    inherited: true,
+    type: CSS_TYPE_LONGHAND,
+    applies_to_first_letter: true,
+    applies_to_first_line: true,
+    applies_to_placeholder: true,
+    initial_values: [ "auto" ],
+    other_values: [ "none" ],
+    invalid_values: [ "on" ]
+  };
+  gCSSProperties["font"].subproperties.push("font-optical-sizing");
 }
 
 if (IsCSSPropertyPrefEnabled("layout.css.frames-timing.enabled")) {
   gCSSProperties["animation-timing-function"].other_values.push(
     "frames(2)", "frames(1000)", "frames( 2 )");
   gCSSProperties["animation-timing-function"].invalid_values.push(
     "frames(1)", "frames(-2)", "frames", "frames()", "frames(,)",
     "frames(a)", "frames(2.0)", "frames(2.5)", "frames(2 3)");
--- a/layout/style/test/test_bug377947.html
+++ b/layout/style/test/test_bug377947.html
@@ -56,16 +56,17 @@ var all_but_one = {
   "font-variant": "normal",
   "font-weight": "bold",
   "font-size": "small",
   "font-stretch": "normal",
   "font-size-adjust": "none", // has to be default value
   "font-feature-settings": "normal", // has to be default value
   "font-language-override": "normal", // has to be default value
   "font-kerning": "auto", // has to be default value
+  "font-optical-sizing": "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
 };
--- a/layout/style/test/test_system_font_serialization.html
+++ b/layout/style/test/test_system_font_serialization.html
@@ -12,16 +12,31 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=475214">Mozilla Bug 475214</a>
 <p id="display"></p>
 <div id="content">
   
 </div>
 <pre id="test">
 <script type="application/javascript">
 
+/* Helper copied from property_database.js */
+function IsCSSPropertyPrefEnabled(prefName)
+{
+  try {
+    if (SpecialPowers.getBoolPref(prefName)) {
+      return true;
+    }
+  } catch (ex) {
+    ok(false, "Failed to look up property-controlling pref '" +
+       prefName + "' (" + ex + ")");
+  }
+
+  return false;
+}
+
 /** Test for Bug 475214 **/
 
 var e = document.getElementById("content");
 var s = e.style;
 
 e.style.font = "menu";
 is(e.style.cssText, "font: menu;", "serialize system font alone");
 is(e.style.font, "menu", "font getter returns value");
@@ -45,29 +60,33 @@ is(e.style.font, "menu", "font getter re
 // Servo doesn't support parsing -moz-use-system-font
 if (!SpecialPowers.DOMWindowUtils.isStyledByServo) {
   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;");
-const EXPECTED_DECLS = [
+EXPECTED_DECLS = [
   "font-family: Helvetica;",
   "font-feature-settings: inherit;",
   "font-kerning: inherit;",
   "font-language-override: inherit;",
   "font-size-adjust: inherit;",
   "font-size: inherit;",
   "font-stretch: inherit;",
   "font-style: inherit;",
   "font-variant: inherit;",
   "font-weight: inherit;",
   "line-height: inherit;",
-].join(" ");
+];
+if (IsCSSPropertyPrefEnabled("layout.css.font-variations.enabled")) {
+  EXPECTED_DECLS.push("font-optical-sizing: inherit;");
+}
+EXPECTED_DECLS = EXPECTED_DECLS.sort().join(" ");
 let sortedDecls = e.style.cssText.split(/ (?=font-|line-)/).sort().join(" ");
 is(sortedDecls, EXPECTED_DECLS, "don't serialize system font for font:inherit");
 is(e.style.font, "", "font getter returns nothing");
 
 </script>
 </pre>
 </body>
 </html>