Bug 1451499 Part 1: Uplift some interval methods from ImageShapeInfo to ShapeInfo. draft
authorBrad Werth <bwerth@mozilla.com>
Thu, 19 Apr 2018 12:17:44 -0700
changeset 791208 5ed13bd60371314a9a9c9e56abd32e4d75b2ce4d
parent 791136 35165f43d0b97f500dafb4f0f7b9ca8d91416812
child 791209 3948c7030820dc2cb0fa4c5c394736c6bf12a0cf
push id108734
push userbwerth@mozilla.com
push dateThu, 03 May 2018 19:09:16 +0000
bugs1451499
milestone61.0a1
Bug 1451499 Part 1: Uplift some interval methods from ImageShapeInfo to ShapeInfo. MozReview-Commit-ID: AMwujPuTeOm
layout/generic/nsFloatManager.cpp
--- a/layout/generic/nsFloatManager.cpp
+++ b/layout/generic/nsFloatManager.cpp
@@ -632,16 +632,23 @@ protected:
   // axis. The values are stored as block edges in the y coordinates,
   // and inline edges as the x coordinates. Interval arrays should be sorted
   // on increasing y values. This function uses a binary search to find the
   // first interval that contains aTargetY. If no such interval exists, this
   // function returns aIntervals.Length().
   static size_t MinIntervalIndexContainingY(const nsTArray<nsRect>& aIntervals,
                                             const nscoord aTargetY);
 
+  // This interval function is designed to handle the arguments to ::LineLeft()
+  // and LineRight() and interpret them for the supplied aIntervals.
+  static nscoord LineEdge(const nsTArray<nsRect>& aIntervals,
+                          const nscoord aBStart,
+                          const nscoord aBEnd,
+                          bool aIsLineLeft);
+
   // These types, constants, and functions are useful for ShapeInfos that
   // allocate a distance field. Efficient distance field calculations use
   // integer values that are 5X the Euclidean distance. MAX_MARGIN_5X is the
   // largest possible margin that we can calculate (in 5X integer dev pixels),
   // given these constraints.
   typedef uint16_t dfType;
   static const dfType MAX_CHAMFER_VALUE;
   static const dfType MAX_MARGIN;
@@ -1441,20 +1448,16 @@ public:
                     const nscoord aBEnd) const override;
   nscoord BStart() const override { return mBStart; }
   nscoord BEnd() const override { return mBEnd; }
   bool IsEmpty() const override { return mIntervals.IsEmpty(); }
 
   void Translate(nscoord aLineLeft, nscoord aBlockStart) override;
 
 private:
-  nscoord LineEdge(const nscoord aBStart,
-                   const nscoord aBEnd,
-                   bool aLeft) const;
-
   // 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.
 
   // The intervals are stored in ascending order on y.
   nsTArray<nsRect> mIntervals;
 
@@ -1864,67 +1867,27 @@ nsFloatManager::ImageShapeInfo::CreateIn
     // moves in a positive step in both inline and block directions.
     origin.MoveBy(aIMin * aAppUnitsPerDevPixel, aB * aAppUnitsPerDevPixel);
   }
 
   mIntervals.AppendElement(nsRect(origin, size));
 }
 
 nscoord
-nsFloatManager::ImageShapeInfo::LineEdge(const nscoord aBStart,
-                                         const nscoord aBEnd,
-                                         bool aLeft) const
-{
-  MOZ_ASSERT(aBStart <= aBEnd,
-             "The band's block start is greater than its block end?");
-
-  // Find all the intervals whose rects overlap the aBStart to
-  // aBEnd range, and find the most constraining inline edge
-  // depending on the value of aLeft.
-
-  // Since the intervals are stored in block-axis order, we need
-  // to find the first interval that overlaps aBStart and check
-  // succeeding intervals until we get past aBEnd.
-
-  nscoord lineEdge = aLeft ? nscoord_MAX : nscoord_MIN;
-
-  size_t intervalCount = mIntervals.Length();
-  for (size_t i = MinIntervalIndexContainingY(mIntervals, aBStart);
-	   i < intervalCount; ++i) {
-    // We can always get the bCoord from the intervals' mLineLeft,
-    // since the y() coordinate is duplicated in both points in the
-    // interval.
-    auto& interval = mIntervals[i];
-    nscoord bCoord = interval.Y();
-    if (bCoord > aBEnd) {
-      break;
-    }
-    // Get the edge from the interval point indicated by aLeft.
-    if (aLeft) {
-      lineEdge = std::min(lineEdge, interval.X());
-    } else {
-      lineEdge = std::max(lineEdge, interval.XMost());
-    }
-  }
-
-  return lineEdge;
-}
-
-nscoord
 nsFloatManager::ImageShapeInfo::LineLeft(const nscoord aBStart,
                                          const nscoord aBEnd) const
 {
-  return LineEdge(aBStart, aBEnd, true);
+  return LineEdge(mIntervals, aBStart, aBEnd, true);
 }
 
 nscoord
 nsFloatManager::ImageShapeInfo::LineRight(const nscoord aBStart,
                                           const nscoord aBEnd) const
 {
-  return LineEdge(aBStart, aBEnd, false);
+  return LineEdge(mIntervals, aBStart, aBEnd, false);
 }
 
 void
 nsFloatManager::ImageShapeInfo::Translate(nscoord aLineLeft,
                                           nscoord aBlockStart)
 {
   for (nsRect& interval : mIntervals) {
     interval.MoveBy(aLineLeft, aBlockStart);
@@ -2531,42 +2494,16 @@ nsFloatManager::ShapeInfo::ConvertToFloa
   WritingMode aWM,
   const nsSize& aContainerSize)
 {
   LogicalPoint logicalPoint(aWM, aPoint, aContainerSize);
   return nsPoint(logicalPoint.LineRelative(aWM, aContainerSize),
                  logicalPoint.B(aWM));
 }
 
-/* static */ size_t
-nsFloatManager::ShapeInfo::MinIntervalIndexContainingY(
-  const nsTArray<nsRect>& aIntervals,
-  const nscoord aTargetY)
-{
-  // Perform a binary search to find the minimum index of an interval
-  // that contains aTargetY. If no such interval exists, return a value
-  // equal to the number of intervals.
-  size_t startIdx = 0;
-  size_t endIdx = aIntervals.Length();
-  while (startIdx < endIdx) {
-    size_t midIdx = startIdx + (endIdx - startIdx) / 2;
-    if (aIntervals[midIdx].ContainsY(aTargetY)) {
-      return midIdx;
-    }
-    nscoord midY = aIntervals[midIdx].Y();
-    if (midY < aTargetY) {
-      startIdx = midIdx + 1;
-    } else {
-      endIdx = midIdx;
-    }
-  }
-
-  return endIdx;
-}
-
 /* static */ nsFloatManager::ShapeInfo::dfType
 nsFloatManager::ShapeInfo::CalcUsedShapeMargin5X(
   nscoord aShapeMargin,
   int32_t aAppUnitsPerDevPixel)
 {
   // Our distance field has to be able to hold values equal to the
   // maximum shape-margin value that we care about faithfully rendering,
   // times 5. A 16-bit unsigned int can represent up to ~ 65K which means
@@ -2630,16 +2567,83 @@ nsFloatManager::ShapeInfo::ConvertToFloa
     std::swap(logicalRadii[eCornerTopLeftY], logicalRadii[eCornerBottomLeftY]);
     std::swap(logicalRadii[eCornerTopRightX], logicalRadii[eCornerBottomRightX]);
     std::swap(logicalRadii[eCornerTopRightY], logicalRadii[eCornerBottomRightY]);
   }
 
   return logicalRadii;
 }
 
+/* static */ size_t
+nsFloatManager::ShapeInfo::MinIntervalIndexContainingY(
+  const nsTArray<nsRect>& aIntervals,
+  const nscoord aTargetY)
+{
+  // Perform a binary search to find the minimum index of an interval
+  // that contains aTargetY. If no such interval exists, return a value
+  // equal to the number of intervals.
+  size_t startIdx = 0;
+  size_t endIdx = aIntervals.Length();
+  while (startIdx < endIdx) {
+    size_t midIdx = startIdx + (endIdx - startIdx) / 2;
+    if (aIntervals[midIdx].ContainsY(aTargetY)) {
+      return midIdx;
+    }
+    nscoord midY = aIntervals[midIdx].Y();
+    if (midY < aTargetY) {
+      startIdx = midIdx + 1;
+    } else {
+      endIdx = midIdx;
+    }
+  }
+
+  return endIdx;
+}
+
+/* static */ nscoord
+nsFloatManager::ShapeInfo::LineEdge(const nsTArray<nsRect>& aIntervals,
+                                    const nscoord aBStart,
+                                    const nscoord aBEnd,
+                                    bool aIsLineLeft)
+{
+  MOZ_ASSERT(aBStart <= aBEnd,
+             "The band's block start is greater than its block end?");
+
+  // Find all the intervals whose rects overlap the aBStart to
+  // aBEnd range, and find the most constraining inline edge
+  // depending on the value of aLeft.
+
+  // Since the intervals are stored in block-axis order, we need
+  // to find the first interval that overlaps aBStart and check
+  // succeeding intervals until we get past aBEnd.
+
+  nscoord lineEdge = aIsLineLeft ? nscoord_MAX : nscoord_MIN;
+
+  size_t intervalCount = aIntervals.Length();
+  for (size_t i = MinIntervalIndexContainingY(aIntervals, aBStart);
+       i < intervalCount; ++i) {
+    // We can always get the bCoord from the intervals' mLineLeft,
+    // since the y() coordinate is duplicated in both points in the
+    // interval.
+    auto& interval = aIntervals[i];
+    nscoord bCoord = interval.Y();
+    if (bCoord > aBEnd) {
+      break;
+    }
+    // Get the edge from the interval point indicated by aLeft.
+    if (aIsLineLeft) {
+      lineEdge = std::min(lineEdge, interval.X());
+    } else {
+      lineEdge = std::max(lineEdge, interval.XMost());
+    }
+  }
+
+  return lineEdge;
+}
+
 //----------------------------------------------------------------------
 
 nsAutoFloatManager::~nsAutoFloatManager()
 {
   // Restore the old float manager in the reflow input if necessary.
   if (mNew) {
 #ifdef DEBUG
     if (nsBlockFrame::gNoisyFloatManager) {