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
--- 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;
};