Bug 1333685 - Eliminate CircleShapeInfo, and use EllipseShapeInfo for circle(). r=dbaron
authorTing-Yu Lin <tlin@mozilla.com>
Wed, 25 Jan 2017 16:01:51 +0800
changeset 466679 a79202aaab99375695d6f58f2334713659f6ee4f
parent 466678 f07c28aa3e0a5ad4a773e1305db4f7a9fe41fc5b
child 466680 4f08b43226f0c43ae3054c8684d64641850b642a
child 466696 cad81866837b63a6266d1706fc870ca060f5f416
child 466698 12f516dc244881284ba66e9b99d51cc5762fb9a2
child 466730 a338e596b1d9f37186aaeddcfaa572ae043e578d
child 466857 6b8e2061312f7f48eea1ddfd6cddf298aea910c5
child 466999 6dee89eae3b2b77f2b2f05c4d979f825147198df
push id42948
push userbmo:gasolin@mozilla.com
push dateThu, 26 Jan 2017 07:49:21 +0000
reviewersdbaron
bugs1333685
milestone54.0a1
Bug 1333685 - Eliminate CircleShapeInfo, and use EllipseShapeInfo for circle(). r=dbaron The difference between CircleShapeInfo's constructor and EllipseShapeInfo's is the computation of the radii. Therefore, this patch creates a factory function to distinguish that, so shape-outside: circle() could be implemented by using EllipseShapeInfo. MozReview-Commit-ID: 9ZBQu8zCSrM
layout/generic/nsFloatManager.cpp
layout/generic/nsFloatManager.h
--- a/layout/generic/nsFloatManager.cpp
+++ b/layout/generic/nsFloatManager.cpp
@@ -609,61 +609,17 @@ nsFloatManager::BoxShapeInfo::LineRight(
       mShapeBoxRect.y, mShapeBoxRect.YMost(),
       blockStartCornerRadiusL, blockStartCornerRadiusB,
       blockEndCornerRadiusL, blockEndCornerRadiusB,
       aBStart, aBEnd);
   return mShapeBoxRect.XMost() - lineRightDiff;
 }
 
 /////////////////////////////////////////////////////////////////////////////
-// CircleShapeInfo
-
-nsFloatManager::CircleShapeInfo::CircleShapeInfo(
-  StyleBasicShape* const aBasicShape,
-  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 =
-    aShapeBoxRect.GetPhysicalRect(aWM, aContainerSize);
-  nsPoint physicalCenter =
-    ShapeUtils::ComputeCircleOrEllipseCenter(aBasicShape, physicalShapeBoxRect);
-  nscoord radius = ShapeUtils::ComputeCircleRadius(aBasicShape, physicalCenter,
-                                                   physicalShapeBoxRect);
-  mRadii = nsSize(radius, radius);
-  mCenter = ConvertPhysicalToLogical(aWM, physicalCenter, aContainerSize);
-}
-
-/////////////////////////////////////////////////////////////////////////////
 // EllipseShapeInfo
-
-nsFloatManager::EllipseShapeInfo::EllipseShapeInfo(
-  StyleBasicShape* const aBasicShape,
-  const LogicalRect& aShapeBoxRect,
-  WritingMode aWM,
-  const nsSize& aContainerSize)
-{
-  // Use physical coordinates to compute the center of the ellipse() since
-  // the <position> keywords such as 'left', 'top', etc. are physical.
-  // https://drafts.csswg.org/css-shapes-1/#funcdef-ellipse
-  nsRect physicalShapeBoxRect =
-    aShapeBoxRect.GetPhysicalRect(aWM, aContainerSize);
-  nsPoint physicalCenter =
-    ShapeUtils::ComputeCircleOrEllipseCenter(aBasicShape, physicalShapeBoxRect);
-  nsSize physicalRadii =
-    ShapeUtils::ComputeEllipseRadii(aBasicShape, physicalCenter,
-                                    physicalShapeBoxRect);
-  LogicalSize logicalRadii(aWM, physicalRadii);
-  mRadii = nsSize(logicalRadii.ISize(aWM), logicalRadii.BSize(aWM));
-  mCenter = ConvertPhysicalToLogical(aWM, physicalCenter, aContainerSize);
-}
-
 nscoord
 nsFloatManager::EllipseShapeInfo::LineLeft(WritingMode aWM,
                                            const nscoord aBStart,
                                            const nscoord aBEnd) const
 {
   nscoord lineLeftDiff =
     ComputeEllipseLineInterceptDiff(BStart(), BEnd(),
                                     mRadii.width, mRadii.height,
@@ -744,22 +700,19 @@ nsFloatManager::FloatInfo::FloatInfo(nsI
     StyleBasicShape* const basicShape = shapeOutside.GetBasicShape();
 
     switch (basicShape->GetShapeType()) {
       case StyleBasicShapeType::Polygon:
         // Bug 1326409 - Implement the rendering of basic shape polygon()
         // for CSS shape-outside.
         break;
       case StyleBasicShapeType::Circle:
-        mShapeInfo =
-          MakeUnique<CircleShapeInfo>(basicShape, rect, aWM, aContainerSize);
-        break;
       case StyleBasicShapeType::Ellipse:
         mShapeInfo =
-          MakeUnique<EllipseShapeInfo>(basicShape, rect, aWM, aContainerSize);
+          ShapeInfo::CreateCircleOrEllipse(basicShape, rect, aWM, aContainerSize);
         break;
       case StyleBasicShapeType::Inset:
         // Bug 1326407 - Implement the rendering of basic shape inset() for
         // CSS shape-outside.
         break;
     }
   } else {
     MOZ_ASSERT_UNREACHABLE("Unknown StyleShapeSourceType!");
@@ -867,16 +820,53 @@ nsFloatManager::FloatInfo::IsEmpty(Shape
     return IsEmpty();
   }
   return mShapeInfo->IsEmpty();
 }
 
 /////////////////////////////////////////////////////////////////////////////
 // ShapeInfo
 
+/* static */ UniquePtr<nsFloatManager::ShapeInfo>
+nsFloatManager::ShapeInfo::CreateCircleOrEllipse(
+  StyleBasicShape* const aBasicShape,
+  const LogicalRect& aShapeBoxRect,
+  WritingMode aWM,
+  const nsSize& aContainerSize)
+{
+  // Use physical coordinates to compute the center of circle() or ellipse()
+  // since the <position> keywords such as 'left', 'top', etc. are physical.
+  // https://drafts.csswg.org/css-shapes-1/#funcdef-ellipse
+  nsRect physicalShapeBoxRect =
+    aShapeBoxRect.GetPhysicalRect(aWM, aContainerSize);
+  nsPoint physicalCenter =
+    ShapeUtils::ComputeCircleOrEllipseCenter(aBasicShape, physicalShapeBoxRect);
+  nsPoint center =
+    ConvertPhysicalToLogical(aWM, physicalCenter, aContainerSize);
+
+  // Compute the circle or ellipse radii.
+  nsSize radii;
+  StyleBasicShapeType type = aBasicShape->GetShapeType();
+  if (type == StyleBasicShapeType::Circle) {
+    nscoord radius = ShapeUtils::ComputeCircleRadius(aBasicShape, physicalCenter,
+                                                     physicalShapeBoxRect);
+    radii = nsSize(radius, radius);
+  } else {
+    MOZ_ASSERT(type == StyleBasicShapeType::Ellipse);
+    nsSize physicalRadii =
+      ShapeUtils::ComputeEllipseRadii(aBasicShape, physicalCenter,
+                                      physicalShapeBoxRect);
+    LogicalSize logicalRadii(aWM, physicalRadii);
+    radii = nsSize(logicalRadii.ISize(aWM), logicalRadii.BSize(aWM));
+  }
+
+  return MakeUnique<EllipseShapeInfo>(center, radii);
+}
+
+
 /* static */ nscoord
 nsFloatManager::ShapeInfo::ComputeEllipseLineInterceptDiff(
   const nscoord aShapeBoxBStart, const nscoord aShapeBoxBEnd,
   const nscoord aBStartCornerRadiusL, const nscoord aBStartCornerRadiusB,
   const nscoord aBEndCornerRadiusL, const nscoord aBEndCornerRadiusB,
   const nscoord aBandBStart, const nscoord aBandBEnd)
 {
   // An example for the band intersecting with the top right corner of an
--- a/layout/generic/nsFloatManager.h
+++ b/layout/generic/nsFloatManager.h
@@ -356,16 +356,22 @@ private:
                               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;
 
+    static mozilla::UniquePtr<ShapeInfo> CreateCircleOrEllipse(
+      mozilla::StyleBasicShape* const aBasicShape,
+      const mozilla::LogicalRect& aShapeBoxRect,
+      mozilla::WritingMode aWM,
+      const nsSize& aContainerSize);
+
   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
@@ -415,24 +421,25 @@ 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.
     nsRect mShapeBoxRect;
     // The frame of the float.
     nsIFrame* const mFrame;
   };
 
-  // Implements shape-outside: ellipse().
+  // Implements shape-outside: circle() and shape-outside: ellipse().
   class EllipseShapeInfo : public ShapeInfo
   {
   public:
-    EllipseShapeInfo(mozilla::StyleBasicShape* const aBasicShape,
-                     const mozilla::LogicalRect& aShapeBoxRect,
-                     mozilla::WritingMode aWM,
-                     const nsSize& aContainerSize);
+    EllipseShapeInfo(const nsPoint& aCenter,
+                     const nsSize& aRadii)
+      : mCenter(aCenter)
+      , mRadii(aRadii)
+    {}
 
     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 - mRadii.height; }
@@ -440,36 +447,24 @@ private:
     bool IsEmpty() const override { return mRadii.IsEmpty(); };
 
     void Translate(nscoord aLineLeft, nscoord aBlockStart) override
     {
       mCenter.MoveBy(aLineLeft, aBlockStart);
     }
 
   protected:
-    EllipseShapeInfo() = default;
-
     // The position of the center of the ellipse. The coordinate space is the
     // same as FloatInfo::mRect.
     nsPoint mCenter;
     // The radii of the ellipse in app units. The width and height represent
     // the line-axis and block-axis radii of the ellipse.
     nsSize mRadii;
   };
 
-  // Implements shape-outside: circle().
-  class CircleShapeInfo final : public EllipseShapeInfo
-  {
-  public:
-    CircleShapeInfo(mozilla::StyleBasicShape* const aBasicShape,
-                    const mozilla::LogicalRect& aShapeBoxRect,
-                    mozilla::WritingMode aWM,
-                    const nsSize& aContainerSize);
-  };
-
   struct FloatInfo {
     nsIFrame *const mFrame;
     // The lowest block-ends of left/right floats up to and including
     // this one.
     nscoord mLeftBEnd, mRightBEnd;
 
     FloatInfo(nsIFrame* aFrame, nscoord aLineLeft, nscoord aBlockStart,
               const mozilla::LogicalRect& aMarginRect,