Bug 1265342 Part 2: Refactor interval creation in shape-outside:image. draft
authorBrad Werth <bwerth@mozilla.com>
Wed, 28 Feb 2018 10:43:43 -0800
changeset 762272 a953a115b7dd8244b66d4e235d5c91e4e1251195
parent 762271 b9fb6154933367c8232514f09f72903b399822a9
child 762273 cb1e6a9f04671da0f3c275479f213f975a5e6903
push id101114
push userbwerth@mozilla.com
push dateThu, 01 Mar 2018 23:33:31 +0000
bugs1265342
milestone60.0a1
Bug 1265342 Part 2: Refactor interval creation in shape-outside:image. MozReview-Commit-ID: LnzQPsSBVqY
layout/generic/nsFloatManager.cpp
--- a/layout/generic/nsFloatManager.cpp
+++ b/layout/generic/nsFloatManager.cpp
@@ -997,16 +997,29 @@ private:
     nsPoint mLineRight;
   };
 
   // The intervals should be sorted in ascending order on mLineLeft.Y().
   nsTArray<Interval> mIntervals;
 
   nscoord mBStart = nscoord_MAX;
   nscoord mBEnd = nscoord_MIN;
+
+  // CreateInterval transforms the supplied min and max, row and col
+  // values into an interval that respects the writing mode. An
+  // aOffsetFromMarginRect can be provided if the min, max, row and col
+  // values were generated relative to something other than the margin
+  // rect (such as the content rect).
+  void CreateInterval(int32_t aMin,
+                      int32_t aMax,
+                      int32_t aCol,
+                      int32_t aRow,
+                      const nsPoint& aOffsetFromMarginRect,
+                      WritingMode aWM,
+                      const nsSize& aContainerSize);
 };
 
 nsFloatManager::ImageShapeInfo::ImageShapeInfo(
   uint8_t* aAlphaPixels,
   int32_t aStride,
   const CSSIntSize& aImageSize,
   float aShapeImageThreshold,
   const nsRect& aContentRect,
@@ -1050,61 +1063,79 @@ nsFloatManager::ImageShapeInfo::ImageSha
       }
       if (max < curr) {
         max = curr;
       }
     }
 
     // At the end of a row (or column if vertical), and found something.
     if (curr == (aWM.IsVertical() ? h - 1 : w - 1) && (min != -1)) {
-      // Make the position be relative to the container.
-      nsPoint lineLeft(aContentRect.TopLeft());
-      nsPoint lineRight(aContentRect.TopLeft());
-
-      nscoord colAppUnits = CSSPixel::ToAppUnits(col);
-      nscoord rowAppUnits = CSSPixel::ToAppUnits(row);
-      nscoord minAppUnits = CSSPixel::ToAppUnits(min);
-      // Add one to max because we need the position of the pixels's right
-      // edge (or bottom edge if vertical).
-      nscoord maxAppUnits = CSSPixel::ToAppUnits(max + 1);
+      // We need to supply an offset of the content rect top left, since
+      // our col and row have been calculated from the content rect,
+      // instead of the margin rect (against which floats are applied).
+      CreateInterval(min, max, col, row, aContentRect.TopLeft(),
+                     aWM, aContainerSize);
 
-      if (aWM.IsVerticalLR() && aWM.IsSideways()) {
-        // sideways-lr: its physical directions of line-left and line-right
-        // are bottom and top, which are the opposite of other vertical
-        // writing modes.
-        lineLeft.MoveBy(colAppUnits, maxAppUnits);
-        lineRight.MoveBy(colAppUnits, minAppUnits);
-      } else if (aWM.IsVertical()) {
-        lineLeft.MoveBy(colAppUnits, minAppUnits);
-        lineRight.MoveBy(colAppUnits, maxAppUnits);
-      } else {
-        // horizontal-tb
-        lineLeft.MoveBy(minAppUnits, rowAppUnits);
-        lineRight.MoveBy(maxAppUnits, rowAppUnits);
-      }
-
-      mIntervals.AppendElement(
-        Interval{ ConvertToFloatLogical(lineLeft, aWM, aContainerSize),
-                  ConvertToFloatLogical(lineRight, aWM, aContainerSize) });
     }
   }
 
   if (aWM.IsVerticalRL()) {
     // Because we scan the columns from left to right, we need to reverse
     // the array so that it's sorted (in ascending order) on the block
     // direction.
     mIntervals.Reverse();
   }
 
   if (!mIntervals.IsEmpty()) {
     mBStart = mIntervals[0].mLineLeft.Y();
     mBEnd = mIntervals[mIntervals.Length() - 1].mLineLeft.Y();
   }
 }
 
+void
+nsFloatManager::ImageShapeInfo::CreateInterval(
+  int32_t aMin,
+  int32_t aMax,
+  int32_t aCol,
+  int32_t aRow,
+  const nsPoint& aOffsetFromMarginRect,
+  WritingMode aWM,
+  const nsSize& aContainerSize)
+{
+  // Make the position be relative to aOffsetFromMarginRect.
+  nsPoint lineLeft(aOffsetFromMarginRect);
+  nsPoint lineRight(aOffsetFromMarginRect);
+
+  nscoord minAppUnits = CSSPixel::ToAppUnits(aMin);
+  // Add one to max because we need the position of the pixels's right
+  // edge (or bottom edge if vertical).
+  nscoord maxAppUnits = CSSPixel::ToAppUnits(aMax + 1);
+  nscoord colAppUnits = CSSPixel::ToAppUnits(aCol);
+
+  if (aWM.IsVerticalLR() && aWM.IsSideways()) {
+    // sideways-lr: its physical directions of line-left and line-right
+    // are bottom and top, which are the opposite of other vertical
+    // writing modes.
+    lineLeft.MoveBy(colAppUnits, maxAppUnits);
+    lineRight.MoveBy(colAppUnits, minAppUnits);
+  } else if (aWM.IsVertical()) {
+    lineLeft.MoveBy(colAppUnits, minAppUnits);
+    lineRight.MoveBy(colAppUnits, maxAppUnits);
+  } else {
+    // horizontal-tb
+    nscoord rowAppUnits = CSSPixel::ToAppUnits(aRow);
+    lineLeft.MoveBy(minAppUnits, rowAppUnits);
+    lineRight.MoveBy(maxAppUnits, rowAppUnits);
+  }
+
+  mIntervals.AppendElement(
+    Interval{ ConvertToFloatLogical(lineLeft, aWM, aContainerSize),
+              ConvertToFloatLogical(lineRight, aWM, aContainerSize) });
+}
+
 nscoord
 nsFloatManager::ImageShapeInfo::LineLeft(const nscoord aBStart,
                                          const nscoord aBEnd) const
 {
   MOZ_ASSERT(aBStart <= aBEnd,
              "The band's block start is greater than its block end?");
 
   nscoord lineLeft = nscoord_MAX;