From 9e98795acac472c973988342802868d6ef0fd5c4 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Wed, 25 Jan 2017 16:01:51 +0800 Subject: [PATCH] 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 | 86 ++++++++++++++----------------- layout/generic/nsFloatManager.h | 29 +++++------ 2 files changed, 50 insertions(+), 65 deletions(-) diff --git a/layout/generic/nsFloatManager.cpp b/layout/generic/nsFloatManager.cpp index c2f5d32c29e8..4a025bd2246c 100644 --- a/layout/generic/nsFloatManager.cpp +++ b/layout/generic/nsFloatManager.cpp @@ -613,52 +613,8 @@ nsFloatManager::BoxShapeInfo::LineRight(WritingMode aWM, 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 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 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, @@ -749,12 +705,9 @@ nsFloatManager::FloatInfo::FloatInfo(nsIFrame* aFrame, // for CSS shape-outside. break; case StyleBasicShapeType::Circle: - mShapeInfo = - MakeUnique(basicShape, rect, aWM, aContainerSize); - break; case StyleBasicShapeType::Ellipse: mShapeInfo = - MakeUnique(basicShape, rect, aWM, aContainerSize); + ShapeInfo::CreateCircleOrEllipse(basicShape, rect, aWM, aContainerSize); break; case StyleBasicShapeType::Inset: // Bug 1326407 - Implement the rendering of basic shape inset() for @@ -872,6 +825,43 @@ nsFloatManager::FloatInfo::IsEmpty(ShapeType aShapeType) const ///////////////////////////////////////////////////////////////////////////// // ShapeInfo +/* static */ UniquePtr +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 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(center, radii); +} + + /* static */ nscoord nsFloatManager::ShapeInfo::ComputeEllipseLineInterceptDiff( const nscoord aShapeBoxBStart, const nscoord aShapeBoxBEnd, diff --git a/layout/generic/nsFloatManager.h b/layout/generic/nsFloatManager.h index 1b0cb9a9e2f7..e7dea3a8ff6b 100644 --- a/layout/generic/nsFloatManager.h +++ b/layout/generic/nsFloatManager.h @@ -361,6 +361,12 @@ private: // Translate the current origin by the specified offsets. virtual void Translate(nscoord aLineLeft, nscoord aBlockStart) = 0; + static mozilla::UniquePtr 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). @@ -420,14 +426,15 @@ private: 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, @@ -445,8 +452,6 @@ private: } protected: - EllipseShapeInfo() = default; - // The position of the center of the ellipse. The coordinate space is the // same as FloatInfo::mRect. nsPoint mCenter; @@ -455,16 +460,6 @@ private: 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