Bug 1326406 Part 3 - Add ShapeInfo::Translate() for moving the origin of ShapeInfo. draft
authorTing-Yu Lin <tlin@mozilla.com>
Mon, 23 Jan 2017 17:17:37 +0800
changeset 466054 88d7ca10f1d303193a352cd385a61858dc584854
parent 466053 0e14d70df907ad85c6b2cc5b657ebba095487bfa
child 466055 24a44c6f264911e257e92fac4ee9029536fa5c4d
push id42771
push userbmo:tlin@mozilla.com
push dateWed, 25 Jan 2017 05:31:10 +0000
bugs1326406
milestone54.0a1
Bug 1326406 Part 3 - Add ShapeInfo::Translate() for moving the origin of ShapeInfo. Instead of manually adding (aLineLeft, aBlockStart) when creating a shape, add Translate() to let the shapes implement their only way to move their origin. FloatInfo could then move the shapes after they're created. MozReview-Commit-ID: ApZBHnkng74
layout/generic/nsFloatManager.cpp
layout/generic/nsFloatManager.h
--- a/layout/generic/nsFloatManager.cpp
+++ b/layout/generic/nsFloatManager.cpp
@@ -613,18 +613,16 @@ nsFloatManager::BoxShapeInfo::LineRight(
   return mShapeBoxRect.XMost() - lineRightDiff;
 }
 
 /////////////////////////////////////////////////////////////////////////////
 // CircleShapeInfo
 
 nsFloatManager::CircleShapeInfo::CircleShapeInfo(
   StyleBasicShape* const aBasicShape,
-  nscoord aLineLeft,
-  nscoord aBlockStart,
   const LogicalRect& aShapeBoxRect,
   WritingMode aWM,
   const nsSize& aContainerSize)
 {
   // Use physical coordinates to compute the center of the circle() since
   // the <position> keywords such as 'left', 'top', etc. are physical.
   // https://drafts.csswg.org/css-shapes-1/#funcdef-circle
   nsRect physicalShapeBoxRect =
@@ -634,18 +632,18 @@ nsFloatManager::CircleShapeInfo::CircleS
   mRadius =
     ShapeUtils::ComputeCircleRadius(aBasicShape, physicalCenter,
                                     physicalShapeBoxRect);
 
   // Convert the coordinate space back to the same as FloatInfo::mRect.
   // mCenter.x is in the line-axis of the frame manager and mCenter.y are in
   // the frame manager's real block-axis.
   LogicalPoint logicalCenter(aWM, physicalCenter, aContainerSize);
-  mCenter = nsPoint(logicalCenter.LineRelative(aWM, aContainerSize) + aLineLeft,
-                    logicalCenter.B(aWM) + aBlockStart);
+  mCenter = nsPoint(logicalCenter.LineRelative(aWM, aContainerSize),
+                    logicalCenter.B(aWM));
 }
 
 nscoord
 nsFloatManager::CircleShapeInfo::LineLeft(WritingMode aWM,
                                           const nscoord aBStart,
                                           const nscoord aBEnd) const
 {
   nscoord lineLeftDiff =
@@ -714,30 +712,32 @@ nsFloatManager::FloatInfo::FloatInfo(nsI
       break;
     case StyleShapeOutsideShapeBox::NoBox:
       MOZ_ASSERT(shapeOutside.GetType() != StyleShapeSourceType::Box,
                  "Box source type must have <shape-box> specified!");
       break;
   }
 
   if (shapeOutside.GetType() == StyleShapeSourceType::Box) {
-    nsRect shapeBoxRect(rect.LineLeft(aWM, aContainerSize) + aLineLeft,
-                        rect.BStart(aWM) + aBlockStart,
+    nsRect shapeBoxRect(rect.LineLeft(aWM, aContainerSize), rect.BStart(aWM),
                         rect.ISize(aWM), rect.BSize(aWM));
     mShapeInfo = MakeUnique<BoxShapeInfo>(shapeBoxRect, mFrame);
   } else if (shapeOutside.GetType() == StyleShapeSourceType::Shape) {
     StyleBasicShape* const basicShape = shapeOutside.GetBasicShape();
 
     if (basicShape->GetShapeType() == StyleBasicShapeType::Circle) {
-      mShapeInfo = MakeUnique<CircleShapeInfo>(basicShape, aLineLeft, aBlockStart,
-                                               rect, aWM, aContainerSize);
+      mShapeInfo =
+        MakeUnique<CircleShapeInfo>(basicShape, rect, aWM, aContainerSize);
     }
   } else {
     MOZ_ASSERT_UNREACHABLE("Unknown StyleShapeSourceType!");
   }
+
+  // Translate the shape to the same origin as nsFloatManager.
+  mShapeInfo->Translate(aLineLeft, aBlockStart);
 }
 
 #ifdef NS_BUILD_REFCNT_LOGGING
 nsFloatManager::FloatInfo::FloatInfo(FloatInfo&& aOther)
   : mFrame(Move(aOther.mFrame))
   , mLeftBEnd(Move(aOther.mLeftBEnd))
   , mRightBEnd(Move(aOther.mRightBEnd))
   , mRect(Move(aOther.mRect))
--- a/layout/generic/nsFloatManager.h
+++ b/layout/generic/nsFloatManager.h
@@ -347,16 +347,19 @@ private:
                              const nscoord aBEnd) const = 0;
     virtual nscoord LineRight(mozilla::WritingMode aWM,
                               const nscoord aBStart,
                               const nscoord aBEnd) const = 0;
     virtual nscoord BStart() const = 0;
     virtual nscoord BEnd() const = 0;
     virtual bool IsEmpty() const = 0;
 
+    // Translate the current origin by the specified offsets.
+    virtual void Translate(nscoord aLineLeft, nscoord aBlockStart) = 0;
+
   protected:
     // Compute the minimum line-axis difference between the bounding shape
     // box and its rounded corner within the given band (block-axis region).
     // This is used as a helper function to compute the LineRight() and
     // LineLeft(). See the picture in the implementation for an example.
     // RadiusL and RadiusB stand for radius on the line-axis and block-axis.
     //
     // Returns radius-x diff on the line-axis, or 0 if there's no rounded
@@ -386,46 +389,54 @@ private:
                      const nscoord aBEnd) const override;
     nscoord LineRight(mozilla::WritingMode aWM,
                       const nscoord aBStart,
                       const nscoord aBEnd) const override;
     nscoord BStart() const override { return mShapeBoxRect.y; }
     nscoord BEnd() const override { return mShapeBoxRect.YMost(); }
     bool IsEmpty() const override { return mShapeBoxRect.IsEmpty(); };
 
+    void Translate(nscoord aLineLeft, nscoord aBlockStart) override
+    {
+      mShapeBoxRect.MoveBy(aLineLeft, aBlockStart);
+    }
+
   private:
     // This is the reference box of css shape-outside if specified, which
     // implements the <shape-box> value in the CSS Shapes Module Level 1.
     // The coordinate space is the same as FloatInfo::mRect.
-    const nsRect mShapeBoxRect;
+    nsRect mShapeBoxRect;
     // The frame of the float.
     nsIFrame* const mFrame;
   };
 
   // Implements shape-outside: circle().
   class CircleShapeInfo final : public ShapeInfo
   {
   public:
     CircleShapeInfo(mozilla::StyleBasicShape* const aBasicShape,
-                    nscoord aLineLeft,
-                    nscoord aBlockStart,
                     const mozilla::LogicalRect& aShapeBoxRect,
                     mozilla::WritingMode aWM,
                     const nsSize& aContainerSize);
 
     nscoord LineLeft(mozilla::WritingMode aWM,
                      const nscoord aBStart,
                      const nscoord aBEnd) const override;
     nscoord LineRight(mozilla::WritingMode aWM,
                       const nscoord aBStart,
                       const nscoord aBEnd) const override;
     nscoord BStart() const override { return mCenter.y - mRadius; }
     nscoord BEnd() const override { return mCenter.y + mRadius; }
     bool IsEmpty() const override { return mRadius == 0; };
 
+    void Translate(nscoord aLineLeft, nscoord aBlockStart) override
+    {
+      mCenter.MoveBy(aLineLeft, aBlockStart);
+    }
+
   private:
     // The position of the center of the circle. The coordinate space is the
     // same as FloatInfo::mRect.
     nsPoint mCenter;
     // The radius of the circle in app units.
     nscoord mRadius;
   };