Bug 1463745 Part 1: Add methods to FloatInfo and ShapeInfo to report whether or not they could narrow in the block direction. draft
authorBrad Werth <bwerth@mozilla.com>
Wed, 30 May 2018 10:03:45 -0700
changeset 806317 ece8a37a04528866a87d07ab6876e9f00ae87bb0
parent 805786 e0595117ff5bda3a63a72ad7b3b8754fec4fb4f0
child 806318 9a0311b08b2a57c8c5255aaa4e57e69ec8920351
push id112855
push userbwerth@mozilla.com
push dateFri, 08 Jun 2018 23:06:18 +0000
bugs1463745
milestone62.0a1
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
layout/generic/nsFloatManager.cpp
layout/generic/nsFloatManager.h
--- 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