Bug 1463745 Part 1: Add methods to FloatInfo and ShapeInfo to report whether or not they could narrow in the block direction.
MozReview-Commit-ID: 38TMjcoaeAe
--- a/layout/generic/nsFloatManager.cpp
+++ b/layout/generic/nsFloatManager.cpp
@@ -527,16 +527,24 @@ public:
virtual nscoord LineLeft(const nscoord aBStart,
const nscoord aBEnd) const = 0;
virtual nscoord LineRight(const nscoord aBStart,
const nscoord aBEnd) const = 0;
virtual nscoord BStart() const = 0;
virtual nscoord BEnd() const = 0;
virtual bool IsEmpty() const = 0;
+ // Does this shape possibly get inline narrower in the BStart() to BEnd()
+ // span when proceeding in the block direction? This is false for unrounded
+ // rectangles that span all the way to BEnd(), but could be true for other
+ // shapes. Note that we don't care if the BEnd() falls short of the margin
+ // rect -- the ShapeInfo can only affect float behavior in the span between
+ // BStart() and BEnd().
+ virtual bool MayNarrowInBlockDirection() const = 0;
+
// Translate the current origin by the specified offsets.
virtual void Translate(nscoord aLineLeft, nscoord aBlockStart) = 0;
static LogicalRect ComputeShapeBoxRect(
const StyleShapeSource& aShapeOutside,
nsIFrame* const aFrame,
const LogicalRect& aMarginRect,
WritingMode aWM);
@@ -730,16 +738,19 @@ public:
return mCenter.y + mRadii.height + mShapeMargin;
}
bool IsEmpty() const override {
// An EllipseShapeInfo is never empty, because an ellipse or circle with
// a zero radius acts like a point, and an ellipse with one zero radius
// acts like a line.
return false;
}
+ bool MayNarrowInBlockDirection() const override {
+ return true;
+ }
void Translate(nscoord aLineLeft, nscoord aBlockStart) override
{
mCenter.MoveBy(aLineLeft, aBlockStart);
for (nsRect& interval : mIntervals) {
interval.MoveBy(aLineLeft, aBlockStart);
}
@@ -1086,16 +1097,20 @@ public:
nscoord BEnd() const override { return mRect.YMost(); }
bool IsEmpty() const override {
// A RoundedBoxShapeInfo is never empty, because if it is collapsed to
// zero area, it acts like a point. If it is collapsed further, to become
// inside-out, it acts like a rect in the same shape as the inside-out
// rect.
return false;
}
+ bool MayNarrowInBlockDirection() const override {
+ // Only possible to narrow if there are non-null mRadii.
+ return !!mRadii;
+ }
void Translate(nscoord aLineLeft, nscoord aBlockStart) override
{
mRect.MoveBy(aLineLeft, aBlockStart);
if (mShapeMargin > 0) {
MOZ_ASSERT(mLogicalTopLeftCorner && mLogicalTopRightCorner &&
mLogicalBottomLeftCorner && mLogicalBottomRightCorner,
@@ -1279,16 +1294,17 @@ public:
nscoord BEnd() const override { return mBEnd; }
bool IsEmpty() const override {
// A PolygonShapeInfo is never empty, because the parser prevents us from
// creating a shape with no vertices. If we only have 1 vertex, the
// shape acts like a point. With 2 non-coincident vertices, the shape
// acts like a line.
return false;
}
+ bool MayNarrowInBlockDirection() const override { return true; }
void Translate(nscoord aLineLeft, nscoord aBlockStart) override;
private:
// Helper method for determining the mBStart and mBEnd based on the
// vertices' y extent.
void ComputeExtent();
@@ -1804,16 +1820,17 @@ public:
nscoord LineLeft(const nscoord aBStart,
const nscoord aBEnd) const override;
nscoord LineRight(const nscoord aBStart,
const nscoord aBEnd) const override;
nscoord BStart() const override { return mBStart; }
nscoord BEnd() const override { return mBEnd; }
bool IsEmpty() const override { return mIntervals.IsEmpty(); }
+ bool MayNarrowInBlockDirection() const override { return true; }
void Translate(nscoord aLineLeft, nscoord aBlockStart) override;
private:
// An interval is slice of the float area defined by this ImageShapeInfo.
// Each interval is a rectangle that is one pixel deep in the block
// axis. The values are stored as block edges in the y coordinates,
// and inline edges as the x coordinates.
@@ -2514,16 +2531,36 @@ nsFloatManager::FloatInfo::IsEmpty(Shape
MOZ_ASSERT(aShapeType == ShapeType::ShapeOutside);
if (!mShapeInfo) {
return IsEmpty();
}
return mShapeInfo->IsEmpty();
}
+bool
+nsFloatManager::FloatInfo::MayNarrowInBlockDirection(ShapeType aShapeType) const
+{
+ // This function mirrors the cases of the three argument versions of
+ // LineLeft() and LineRight(). This function returns true if and only if
+ // either of those functions could possibly return "narrower" values with
+ // increasing aBStart values. "Narrower" means closer to the far end of
+ // the float shape.
+ if (aShapeType == ShapeType::Margin) {
+ return false;
+ }
+
+ MOZ_ASSERT(aShapeType == ShapeType::ShapeOutside);
+ if (!mShapeInfo) {
+ return false;
+ }
+
+ return mShapeInfo->MayNarrowInBlockDirection();
+}
+
/////////////////////////////////////////////////////////////////////////////
// ShapeInfo
/* static */ LogicalRect
nsFloatManager::ShapeInfo::ComputeShapeBoxRect(
const StyleShapeSource& aShapeOutside,
nsIFrame* const aFrame,
const LogicalRect& aMarginRect,
--- a/layout/generic/nsFloatManager.h
+++ b/layout/generic/nsFloatManager.h
@@ -369,16 +369,17 @@ private:
// line-right extent within the given band, respectively.
nscoord LineLeft(ShapeType aShapeType,
const nscoord aBStart, const nscoord aBEnd) const;
nscoord LineRight(ShapeType aShapeType,
const nscoord aBStart, const nscoord aBEnd) const;
nscoord BStart(ShapeType aShapeType) const;
nscoord BEnd(ShapeType aShapeType) const;
bool IsEmpty(ShapeType aShapeType) const;
+ bool MayNarrowInBlockDirection(ShapeType aShapeType) const;
#ifdef NS_BUILD_REFCNT_LOGGING
FloatInfo(FloatInfo&& aOther);
~FloatInfo();
#endif
// NB! This is really a logical rect in a writing mode suitable for
// placing floats, which is not necessarily the actual writing mode