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
This commit is contained in:
Ting-Yu Lin 2017-01-25 16:01:51 +08:00
parent b0cf27878d
commit 9e98795aca
2 changed files with 50 additions and 65 deletions

View File

@ -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 <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,
@ -749,12 +705,9 @@ nsFloatManager::FloatInfo::FloatInfo(nsIFrame* aFrame,
// 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
@ -872,6 +825,43 @@ nsFloatManager::FloatInfo::IsEmpty(ShapeType aShapeType) const
/////////////////////////////////////////////////////////////////////////////
// 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,

View File

@ -361,6 +361,12 @@ private:
// 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).
@ -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