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 767047 531999a7a46a758050ea8e4bc0d892c022c3d520
parent 767046 0d10e3ef9ffe258b349937ddd2531d0d9b2cc2ab
child 767048 e500d452953077e1e540bd1e2516382f7cbdbd8c
push id102494
push userbwerth@mozilla.com
push dateTue, 13 Mar 2018 20:51:39 +0000
bugs1265342
milestone61.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
@@ -1003,16 +1003,28 @@ 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 and outer
+  // values into an interval that respects the writing mode. An
+  // aOffsetFromMarginRect can be provided if the min, max, outer
+  // 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 aOuter,
+                      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,
@@ -1053,64 +1065,80 @@ nsFloatManager::ImageShapeInfo::ImageSha
         }
         MOZ_ASSERT(max < inner);
         max = inner;
       }
     }
 
     // At the end of a row or column; did we find something?
     if (min != -1) {
-      // Make the position be relative to the container.
-      nsPoint lineLeft(aContentRect.TopLeft());
-      nsPoint lineRight(aContentRect.TopLeft());
-
-      nscoord outerAppUnits = CSSPixel::ToAppUnits(outer);
-      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);
-
-      if (aWM.IsVertical()) {
-        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(outerAppUnits, maxAppUnits);
-          lineRight.MoveBy(outerAppUnits, minAppUnits);
-        } else {
-          // Other vertical writing modes vertical-lr, vertical-rl, and
-          // sideways-rl all map left to top, and right to bottom.
-          lineLeft.MoveBy(outerAppUnits, minAppUnits);
-          lineRight.MoveBy(outerAppUnits, maxAppUnits);
-        }
-      } else {
-        // horizontal-tb
-        lineLeft.MoveBy(minAppUnits, outerAppUnits);
-        lineRight.MoveBy(maxAppUnits, outerAppUnits);
-      }
-
-      mIntervals.AppendElement(
-        Interval{ ConvertToFloatLogical(lineLeft, aWM, aContainerSize),
-                  ConvertToFloatLogical(lineRight, aWM, aContainerSize) });
+      // 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, outer, aContentRect.TopLeft(),
+                     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 aOuter,
+  const nsPoint& aOffsetFromMarginRect,
+  WritingMode aWM,
+  const nsSize& aContainerSize)
+{
+  // Make the position be relative to aOffsetFromMarginRect.
+  nsPoint lineLeft(aOffsetFromMarginRect);
+  nsPoint lineRight(aOffsetFromMarginRect);
+
+  nscoord outerAppUnits = CSSPixel::ToAppUnits(aOuter);
+  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);
+
+  if (aWM.IsVertical()) {
+    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(outerAppUnits, maxAppUnits);
+      lineRight.MoveBy(outerAppUnits, minAppUnits);
+    } else {
+      // Other vertical writing modes vertical-lr, vertical-rl, and
+      // sideways-rl all map left to top, and right to bottom.
+      lineLeft.MoveBy(outerAppUnits, minAppUnits);
+      lineRight.MoveBy(outerAppUnits, maxAppUnits);
+    }
+  } else {
+    // horizontal-tb
+    lineLeft.MoveBy(minAppUnits, outerAppUnits);
+    lineRight.MoveBy(maxAppUnits, outerAppUnits);
+  }
+
+  mIntervals.AppendElement(
+    Interval{ ConvertToFloatLogical(lineLeft, aWM, aContainerSize),
+              ConvertToFloatLogical(lineRight, aWM, aContainerSize) });
+}
+
 size_t
 nsFloatManager::ImageShapeInfo::MinIntervalIndexWithYLargerThan(
   const nscoord aTargetY) const
 {
   // Perform a binary search to find the minimum index of an interval
   // with y() value greater than aTargetY. If no such interval exists,
   // return a value equal to the number of intervals.