Bug 1175492 - unpref transform-origin percentage handling for SVG elements r=jwatt
authorRobert Longson <longsonr@gmail.com>
Tue, 15 Sep 2015 22:10:48 +0100
changeset 295293 c8ca0ad7ecc45ecefebd9f90525ddf87764f9069
parent 295292 c32abb6c9e65860e4f12e5dbc4668b36779ee8fd
child 295294 a31775ecf4e27d31e7345943a992499c6c1d23fa
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt
bugs1175492
milestone43.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 1175492 - unpref transform-origin percentage handling for SVG elements r=jwatt
layout/base/nsDisplayList.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/reftests/transform/reftest.list
layout/style/nsCSSPropList.h
layout/style/nsStyleTransformMatrix.cpp
layout/style/test/property_database.js
layout/style/test/test_computed_style_prefs.html
modules/libpref/init/all.js
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -547,17 +547,17 @@ nsDisplayListBuilder::AddAnimationsAndTr
     return;
   }
 
   AnimationData data;
   if (aProperty == eCSSProperty_transform) {
     // XXX Performance here isn't ideal for SVG. We'd prefer to avoid resolving
     // the dimensions of refBox. That said, we only get here if there are CSS
     // animations or transitions on this element, and that is likely to be a
-    // lot rarer that transforms on SVG (the frequency of which drives the need
+    // lot rarer than transforms on SVG (the frequency of which drives the need
     // for TransformReferenceBox).
     TransformReferenceBox refBox(aFrame);
     nsRect bounds(0, 0, refBox.Width(), refBox.Height());
     // all data passed directly to the compositor should be in dev pixels
     int32_t devPixelsToAppUnits = aFrame->PresContext()->AppUnitsPerDevPixel();
     float scale = devPixelsToAppUnits;
     Point3D offsetToTransformOrigin =
       nsDisplayTransform::GetDeltaToTransformOrigin(aFrame, scale, &bounds);
@@ -4721,17 +4721,17 @@ nsDisplayTransform::nsDisplayTransform(n
   , mIndex(aIndex)
 {
   MOZ_COUNT_CTOR(nsDisplayTransform);
   MOZ_ASSERT(aFrame, "Must have a frame!");
   SetReferenceFrameToAncestor(aBuilder);
   Init(aBuilder);
 }
 
-/* Returns the delta specified by the -moz-transform-origin property.
+/* Returns the delta specified by the -transform-origin property.
  * This is a positive delta, meaning that it indicates the direction to move
  * to get from (0, 0) of the frame to the transform origin.  This function is
  * called off the main thread.
  */
 /* static */ Point3D
 nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame,
                                               float aAppUnitsPerPixel,
                                               const nsRect* aBoundsOverride)
@@ -4739,17 +4739,17 @@ nsDisplayTransform::GetDeltaToTransformO
   NS_PRECONDITION(aFrame, "Can't get delta for a null frame!");
   NS_PRECONDITION(aFrame->IsTransformed() || aFrame->StyleDisplay()->BackfaceIsHidden(),
                   "Shouldn't get a delta for an untransformed frame!");
 
   if (!aFrame->IsTransformed()) {
     return Point3D();
   }
 
-  /* For both of the coordinates, if the value of -moz-transform is a
+  /* For both of the coordinates, if the value of -transform is a
    * percentage, it's relative to the size of the frame.  Otherwise, if it's
    * a distance, it's already computed for us!
    */
   const nsStyleDisplay* display = aFrame->StyleDisplay();
   // We don't use aBoundsOverride for SVG since we need to account for
   // refBox.X/Y(). This happens to work because ReflowSVG sets the frame's
   // mRect before calling FinishAndStoreOverflow so we don't need the override.
   TransformReferenceBox refBox;
@@ -4763,17 +4763,17 @@ nsDisplayTransform::GetDeltaToTransformO
   /* Allows us to access dimension getters by index. */
   float coords[2];
   TransformReferenceBox::DimensionGetter dimensionGetter[] =
     { &TransformReferenceBox::Width, &TransformReferenceBox::Height };
   TransformReferenceBox::DimensionGetter offsetGetter[] =
     { &TransformReferenceBox::X, &TransformReferenceBox::Y };
 
   for (uint8_t index = 0; index < 2; ++index) {
-    /* If the -moz-transform-origin specifies a percentage, take the percentage
+    /* If the -transform-origin specifies a percentage, take the percentage
      * of the size of the box.
      */
     const nsStyleCoord &coord = display->mTransformOrigin[index];
     if (coord.GetUnit() == eStyleUnit_Calc) {
       const nsStyleCoord::Calc *calc = coord.GetCalcValue();
       coords[index] =
         NSAppUnitsToFloatPixels((refBox.*dimensionGetter[index])(), aAppUnitsPerPixel) *
           calc->mPercent +
@@ -4836,17 +4836,17 @@ nsDisplayTransform::GetDeltaToPerspectiv
   /* Allows us to access named variables by index. */
   Point3D result;
   result.z = 0.0f;
   gfx::Float* coords[2] = {&result.x, &result.y};
   TransformReferenceBox::DimensionGetter dimensionGetter[] =
     { &TransformReferenceBox::Width, &TransformReferenceBox::Height };
 
   for (uint8_t index = 0; index < 2; ++index) {
-    /* If the -moz-transform-origin specifies a percentage, take the percentage
+    /* If the -transform-origin specifies a percentage, take the percentage
      * of the size of the box.
      */
     const nsStyleCoord &coord = display->mPerspectiveOrigin[index];
     if (coord.GetUnit() == eStyleUnit_Calc) {
       const nsStyleCoord::Calc *calc = coord.GetCalcValue();
       *coords[index] =
         NSAppUnitsToFloatPixels((refBox.*dimensionGetter[index])(), aAppUnitsPerPixel) *
           calc->mPercent +
@@ -4888,17 +4888,17 @@ nsDisplayTransform::FrameTransformProper
       // calling it unnecessarily.
       if (mChildPerspective > 0.0) {
         mToPerspectiveOrigin = GetDeltaToPerspectiveOrigin(aFrame, aAppUnitsPerPixel);
       }
     }
   }
 }
 
-/* Wraps up the -moz-transform matrix in a change-of-basis matrix pair that
+/* Wraps up the -transform matrix in a change-of-basis matrix pair that
  * translates from local coordinate space to transform coordinate space, then
  * hands it back.
  */
 Matrix4x4
 nsDisplayTransform::GetResultingTransformMatrix(const FrameTransformProperties& aProperties,
                                                 const nsPoint& aOrigin,
                                                 float aAppUnitsPerPixel,
                                                 const nsRect* aBoundsOverride,
@@ -4983,17 +4983,17 @@ nsDisplayTransform::GetResultingTransfor
       -1.0 / NSAppUnitsToFloatPixels(aProperties.mChildPerspective, aAppUnitsPerPixel);
     /* At the point when perspective is applied, we have been translated to the transform origin.
      * The translation to the perspective origin is the difference between these values.
      */
     perspective.ChangeBasis(aProperties.GetToPerspectiveOrigin() - aProperties.mToTransformOrigin);
     result = result * perspective;
   }
 
-  /* Account for the -moz-transform-origin property by translating the
+  /* Account for the -transform-origin property by translating the
    * coordinate space to the new origin.
    */
   Point3D newOrigin =
     Point3D(NSAppUnitsToFloatPixels(aOrigin.x, aAppUnitsPerPixel),
             NSAppUnitsToFloatPixels(aOrigin.y, aAppUnitsPerPixel),
             0.0f);
   Point3D roundedOrigin(hasSVGTransforms ? newOrigin.x : NS_round(newOrigin.x),
                         hasSVGTransforms ? newOrigin.y : NS_round(newOrigin.y),
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -138,17 +138,17 @@ typedef nsStyleTransformMatrix::Transfor
 /* static */ uint32_t nsLayoutUtils::sFontSizeInflationLineThreshold;
 /* static */ int32_t  nsLayoutUtils::sFontSizeInflationMappingIntercept;
 /* static */ uint32_t nsLayoutUtils::sFontSizeInflationMaxRatio;
 /* static */ bool nsLayoutUtils::sFontSizeInflationForceEnabled;
 /* static */ bool nsLayoutUtils::sFontSizeInflationDisabledInMasterProcess;
 /* static */ bool nsLayoutUtils::sInvalidationDebuggingIsEnabled;
 /* static */ bool nsLayoutUtils::sCSSVariablesEnabled;
 /* static */ bool nsLayoutUtils::sInterruptibleReflowEnabled;
-/* static */ bool nsLayoutUtils::sSVGTransformOriginEnabled;
+/* static */ bool nsLayoutUtils::sSVGTransformBoxEnabled;
 
 static ViewID sScrollIdCounter = FrameMetrics::START_SCROLL_ID;
 
 typedef nsDataHashtable<nsUint64HashKey, nsIContent*> ContentMap;
 static ContentMap* sContentMap = nullptr;
 static ContentMap& GetContentMap() {
   if (!sContentMap) {
     sContentMap = new ContentMap();
@@ -7251,18 +7251,18 @@ nsLayoutUtils::Initialize()
   Preferences::AddBoolVarCache(&sFontSizeInflationDisabledInMasterProcess,
                                "font.size.inflation.disabledInMasterProcess");
   Preferences::AddBoolVarCache(&sInvalidationDebuggingIsEnabled,
                                "nglayout.debug.invalidation");
   Preferences::AddBoolVarCache(&sCSSVariablesEnabled,
                                "layout.css.variables.enabled");
   Preferences::AddBoolVarCache(&sInterruptibleReflowEnabled,
                                "layout.interruptible-reflow.enabled");
-  Preferences::AddBoolVarCache(&sSVGTransformOriginEnabled,
-                               "svg.transform-origin.enabled");
+  Preferences::AddBoolVarCache(&sSVGTransformBoxEnabled,
+                               "svg.transform-box.enabled");
 
   Preferences::RegisterCallback(GridEnabledPrefChangeCallback,
                                 GRID_ENABLED_PREF_NAME);
   GridEnabledPrefChangeCallback(GRID_ENABLED_PREF_NAME, nullptr);
   Preferences::RegisterCallback(RubyEnabledPrefChangeCallback,
                                 RUBY_ENABLED_PREF_NAME);
   RubyEnabledPrefChangeCallback(RUBY_ENABLED_PREF_NAME, nullptr);
   Preferences::RegisterCallback(StickyEnabledPrefChangeCallback,
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -2381,18 +2381,18 @@ public:
   static bool FontSizeInflationForceEnabled() {
     return sFontSizeInflationForceEnabled;
   }
 
   static bool FontSizeInflationDisabledInMasterProcess() {
     return sFontSizeInflationDisabledInMasterProcess;
   }
 
-  static bool SVGTransformOriginEnabled() {
-    return sSVGTransformOriginEnabled;
+  static bool SVGTransformBoxEnabled() {
+    return sSVGTransformBoxEnabled;
   }
 
   /**
    * See comment above "font.size.inflation.mappingIntercept" in
    * modules/libpref/src/init/all.js .
    */
   static int32_t FontSizeInflationMappingIntercept() {
     return sFontSizeInflationMappingIntercept;
@@ -2777,17 +2777,17 @@ private:
   static uint32_t sFontSizeInflationLineThreshold;
   static int32_t  sFontSizeInflationMappingIntercept;
   static uint32_t sFontSizeInflationMaxRatio;
   static bool sFontSizeInflationForceEnabled;
   static bool sFontSizeInflationDisabledInMasterProcess;
   static bool sInvalidationDebuggingIsEnabled;
   static bool sCSSVariablesEnabled;
   static bool sInterruptibleReflowEnabled;
-  static bool sSVGTransformOriginEnabled;
+  static bool sSVGTransformBoxEnabled;
 
   /**
    * Helper function for LogTestDataForPaint().
    */
   static void DoLogTestDataForPaint(mozilla::layers::LayerManager* aManager,
                                     ViewID aScrollId,
                                     const std::string& aKey,
                                     const std::string& aValue);
--- a/layout/reftests/transform/reftest.list
+++ b/layout/reftests/transform/reftest.list
@@ -40,22 +40,22 @@ random == rotate-1b.html rotate-1-ref.ht
 random == rotate-1c.html rotate-1-ref.html
 random == rotate-1d.html rotate-1-ref.html
 random == rotate-1e.html rotate-1-ref.html
 random == rotate-1f.html rotate-1-ref.html
 # rotate: 90deg rotations should be indistinguishable from objects constructed
 # to look the same.
 == rotate-2a.html rotate-2-ref.html
 == rotate-2b.html rotate-2-ref.html
-# -moz-transform-origin: We should NOT get the same images when using different
-# -moz-transform-origins.
+# -transform-origin: We should NOT get the same images when using different
+# -transform-origins.
 != origin-1a.html origin-1-ref.html
 != origin-1b.html origin-1-ref.html
-# -moz-transform-origin: We should get the same images when using equivalent
-# -moz-transform-origins.
+# -transform-origin: We should get the same images when using equivalent
+# -transform-origins.
 == origin-2a.html origin-2-ref.html
 == origin-2b.html origin-2-ref.html
 == origin-2c.html origin-2-ref.html
 # "Translate" with percentages should be indistinguishable from translate with
 # equivalent values.
 == percent-1a.html percent-1-ref.html
 == percent-1b.html percent-1-ref.html
 == percent-1c.html percent-1-ref.html
@@ -119,20 +119,20 @@ skip-if(B2G||Mulet) == stresstest-1.html
 # Bug 722777
 == table-1a.html table-1-ref.html
 == table-1b.html table-1-ref.html
 == table-1c.html table-1-ref.html
 == table-2a.html table-2-ref.html
 == table-2b.html table-2-ref.html
 # Bug 722463
 == inline-1a.html inline-1-ref.html
-pref(svg.transform-origin.enabled,true) == transform-box-svg-1a.svg transform-box-svg-1-ref.svg
-pref(svg.transform-origin.enabled,true) == transform-box-svg-1b.svg transform-box-svg-1-ref.svg
-pref(svg.transform-origin.enabled,true) == transform-box-svg-2a.svg transform-box-svg-2-ref.svg
-pref(svg.transform-origin.enabled,true) == transform-box-svg-2b.svg transform-box-svg-2-ref.svg
-pref(svg.transform-origin.enabled,true) == transform-origin-svg-1a.svg transform-origin-svg-1-ref.svg
-pref(svg.transform-origin.enabled,true) == transform-origin-svg-1b.svg transform-origin-svg-1-ref.svg
-pref(svg.transform-origin.enabled,true) == transform-origin-svg-2a.svg transform-origin-svg-2-ref.svg
-pref(svg.transform-origin.enabled,true) == transform-origin-svg-2b.svg transform-origin-svg-2-ref.svg
+pref(svg.transform-box.enabled,true) == transform-box-svg-1a.svg transform-box-svg-1-ref.svg
+pref(svg.transform-box.enabled,true) == transform-box-svg-1b.svg transform-box-svg-1-ref.svg
+pref(svg.transform-box.enabled,true) == transform-box-svg-2a.svg transform-box-svg-2-ref.svg
+pref(svg.transform-box.enabled,true) == transform-box-svg-2b.svg transform-box-svg-2-ref.svg
+== transform-origin-svg-1a.svg transform-origin-svg-1-ref.svg
+== transform-origin-svg-1b.svg transform-origin-svg-1-ref.svg
+== transform-origin-svg-2a.svg transform-origin-svg-2-ref.svg
+== transform-origin-svg-2b.svg transform-origin-svg-2-ref.svg
 # Bug 1122526
 == animate-layer-scale-inherit-1.html animate-layer-scale-inherit-1-ref.html
 == animate-layer-scale-inherit-2.html animate-layer-scale-inherit-2-ref.html
 == animate-layer-scale-inherit-3.html animate-layer-scale-inherit-1-ref.html
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -3331,17 +3331,17 @@ CSS_PROP_DISPLAY(
     nullptr,
     offsetof(nsStyleDisplay, mSpecifiedTransform),
     eStyleAnimType_Custom)
 CSS_PROP_DISPLAY(
     transform-box,
     transform_box,
     TransformBox,
     CSS_PROPERTY_PARSE_VALUE,
-    "svg.transform-origin.enabled",
+    "svg.transform-box.enabled",
     VARIANT_HK,
     kTransformBoxKTable,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_None)
 CSS_PROP_DISPLAY(
     transform-origin,
     transform_origin,
     TransformOrigin,
--- a/layout/style/nsStyleTransformMatrix.cpp
+++ b/layout/style/nsStyleTransformMatrix.cpp
@@ -45,21 +45,22 @@ TransformReferenceBox::EnsureDimensionsA
     return;
   }
 
   MOZ_ASSERT(mFrame);
 
   mIsCached = true;
 
   if (mFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) {
-    if (!nsLayoutUtils::SVGTransformOriginEnabled()) {
+    if (!nsLayoutUtils::SVGTransformBoxEnabled()) {
       mX = -mFrame->GetPosition().x;
       mY = -mFrame->GetPosition().y;
-      mWidth = 0;
-      mHeight = 0;
+      Size contextSize = nsSVGUtils::GetContextSize(mFrame);
+      mWidth = nsPresContext::CSSPixelsToAppUnits(contextSize.width);
+      mHeight = nsPresContext::CSSPixelsToAppUnits(contextSize.height);
     } else
     if (mFrame->StyleDisplay()->mTransformBox ==
           NS_STYLE_TRANSFORM_BOX_FILL_BOX) {
       // Percentages in transforms resolve against the SVG bbox, and the
       // transform is relative to the top-left of the SVG bbox.
       gfxRect bbox = nsSVGUtils::GetBBox(const_cast<nsIFrame*>(mFrame));
       nsRect bboxInAppUnits =
         nsLayoutUtils::RoundGfxRectToAppRect(bbox,
@@ -75,17 +76,17 @@ TransformReferenceBox::EnsureDimensionsA
     } else {
       // The value 'border-box' is treated as 'view-box' for SVG content.
       MOZ_ASSERT(mFrame->StyleDisplay()->mTransformBox ==
                    NS_STYLE_TRANSFORM_BOX_VIEW_BOX ||
                  mFrame->StyleDisplay()->mTransformBox ==
                    NS_STYLE_TRANSFORM_BOX_BORDER_BOX,
                  "Unexpected value for 'transform-box'");
       // Percentages in transforms resolve against the width/height of the
-      // nearest viewport (or it's viewBox if one is applied), and the
+      // nearest viewport (or its viewBox if one is applied), and the
       // transform is relative to {0,0} in current user space.
       mX = -mFrame->GetPosition().x;
       mY = -mFrame->GetPosition().y;
       Size contextSize = nsSVGUtils::GetContextSize(mFrame);
       mWidth = nsPresContext::CSSPixelsToAppUnits(contextSize.width);
       mHeight = nsPresContext::CSSPixelsToAppUnits(contextSize.height);
     }
     return;
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -5332,17 +5332,17 @@ if (SpecialPowers.getBoolPref("svg.paint
     inherited: true,
     type: CSS_TYPE_LONGHAND,
     initial_values: [ "normal" ],
     other_values: [ "fill", "fill stroke", "fill stroke markers", "stroke markers fill" ],
     invalid_values: [ "fill stroke markers fill", "fill normal" ]
   };
 }
 
-if (SpecialPowers.getBoolPref("svg.transform-origin.enabled")) {
+if (SpecialPowers.getBoolPref("svg.transform-box.enabled")) {
   gCSSProperties["transform-box"] = {
     domProp: "transformBox",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     initial_values: [ "border-box" ],
     other_values: [ "fill-box", "view-box" ],
     invalid_values: []
   };
--- a/layout/style/test/test_computed_style_prefs.html
+++ b/layout/style/test/test_computed_style_prefs.html
@@ -70,17 +70,17 @@ function step() {
 var gProps = {
   "layout.css.vertical-text.enabled": ["text-orientation", "writing-mode"],
   "layout.css.text-combine-upright.enabled": ["text-combine-upright"],
   "layout.css.image-orientation.enabled": ["image-orientation"],
   "layout.css.mix-blend-mode.enabled": ["mix-blend-mode"],
   "layout.css.isolation.enabled": [ "isolation"],
   "layout.css.masking.enabled": ["mask-type"],
   "layout.css.touch_action.enabled": ["touch-action"],
-  "svg.transform-origin.enabled": ["transform-box"]
+  "svg.transform-box.enabled": ["transform-box"]
 };
 
 var gCS = getComputedStyle(document.body, "");
 var gLengthWithAllPrefsDisabled;
 
 var gTestIndex = 0;
 var gPrefsPushed = false;
 var gTests = [
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -2566,19 +2566,19 @@ pref("svg.paint-order.enabled", true);
 // Is support for the <marker orient="auto-start-reverse"> feature enabled?
 pref("svg.marker-improvements.enabled", true);
 
 // Is support for the new getBBox method from SVG 2 enabled?
 // See https://svgwg.org/svg2-draft/single-page.html#types-SVGBoundingBoxOptions
 pref("svg.new-getBBox.enabled", false);
 
 #ifdef RELEASE_BUILD
-pref("svg.transform-origin.enabled", false);
+pref("svg.transform-box.enabled", false);
 #else
-pref("svg.transform-origin.enabled", true);
+pref("svg.transform-box.enabled", true);
 #endif // RELEASE_BUILD
 
 // Default font types and sizes by locale
 pref("font.default.ar", "sans-serif");
 pref("font.minimum-size.ar", 0);
 pref("font.size.variable.ar", 16);
 pref("font.size.fixed.ar", 13);