Bug 1098417 part 1.5: Ignore computed anchor-point if 'object-fit' and 'object-position' are at their initial values, for backwards compat. r=seth
authorDaniel Holbert <dholbert@cs.stanford.edu>
Tue, 25 Nov 2014 16:46:14 -0800
changeset 241852 aa382f6ee7ba6adac3390495038103d2e893a15f
parent 241851 8bc9f527fa128b338277fa62cf7655c50c8b1e8f
child 241853 ea1bc74871c0b205a9ccd741b8e0888baf1afcef
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersseth
bugs1098417
milestone36.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 1098417 part 1.5: Ignore computed anchor-point if 'object-fit' and 'object-position' are at their initial values, for backwards compat. r=seth
layout/base/nsLayoutUtils.cpp
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3619,16 +3619,39 @@ ComputeConcreteObjectSize(const nsSize& 
       return *constrainedSize;
 
     default:
       MOZ_ASSERT_UNREACHABLE("Unexpected enum value for 'object-fit'");
       return aConstraintSize; // fall back to (default) 'fill' behavior
   }
 }
 
+// (Helper for HasInitialObjectFitAndPosition, to check
+// each "object-position" coord.)
+typedef nsStyleBackground::Position::PositionCoord PositionCoord;
+static bool
+IsCoord50Pct(const PositionCoord& aCoord)
+{
+  return (aCoord.mLength == 0 &&
+          aCoord.mHasPercent &&
+          aCoord.mPercent == 0.5f);
+}
+
+// Indicates whether the given nsStylePosition has the initial values
+// for the "object-fit" and "object-position" properties.
+static bool
+HasInitialObjectFitAndPosition(const nsStylePosition* aStylePos)
+{
+  const nsStyleBackground::Position& objectPos = aStylePos->mObjectPosition;
+
+  return aStylePos->mObjectFit == NS_STYLE_OBJECT_FIT_FILL &&
+    IsCoord50Pct(objectPos.mXPosition) &&
+    IsCoord50Pct(objectPos.mYPosition);
+}
+
 /* static */ nsRect
 nsLayoutUtils::ComputeObjectDestRect(const nsRect& aConstraintRect,
                                      const IntrinsicSize& aIntrinsicSize,
                                      const nsSize& aIntrinsicRatio,
                                      const nsStylePosition* aStylePos,
                                      nsPoint* aAnchorPoint)
 {
   // Step 1: Figure out our "concrete object size"
@@ -3645,17 +3668,31 @@ nsLayoutUtils::ComputeObjectDestRect(con
                                             &imageTopLeftPt, &imageAnchorPt);
   // Right now, we're with respect to aConstraintRect's top-left point.  We add
   // that point here, to convert to the same broader coordinate space that
   // aConstraintRect is in.
   imageTopLeftPt += aConstraintRect.TopLeft();
   imageAnchorPt += aConstraintRect.TopLeft();
 
   if (aAnchorPoint) {
-    *aAnchorPoint = imageAnchorPt;
+    // Special-case: if our "object-fit" and "object-position" properties have
+    // their default values ("object-fit: fill; object-position:50% 50%"), then
+    // we'll override the calculated imageAnchorPt, and instead use the
+    // object's top-left corner.
+    //
+    // This special case is partly for backwards compatibility (since
+    // traditionally we've pixel-aligned the top-left corner of e.g. <img>
+    // elements), and partly because ComputeSnappedDrawingParameters produces
+    // less error if the anchor point is at the top-left corner. So, all other
+    // things being equal, we prefer that code path with less error.
+    if (HasInitialObjectFitAndPosition(aStylePos)) {
+      *aAnchorPoint = imageTopLeftPt;
+    } else {
+      *aAnchorPoint = imageAnchorPt;
+    }
   }
   return nsRect(imageTopLeftPt, concreteObjectSize);
 }
 
 nsresult
 nsLayoutUtils::GetFontMetricsForFrame(const nsIFrame* aFrame,
                                       nsFontMetrics** aFontMetrics,
                                       float aInflation)