Backed out 11 changesets (bug 1404222) for static analysis failures on a CLOSED TREE.
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 02 Apr 2018 17:57:27 -0400
changeset 464924 98749dde9018b91a50b668cbd2ca729cc5bc7357
parent 464923 5559c98dc19a1713cd9279c0a2a833c6b62e08e8
child 464925 3a78edaef5e7d49c3032b1219415a76dfdded206
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1404222
milestone61.0a1
backs outa6a99136300c0453b38388f8ce669a6505d9ae62
7183b81043999bbcc3d95091d498f3bf930132b2
a1e4294c1c59556429fe9343b756afc5310d9cc5
b79d6e8318db9e2aed12bb01d4150cb167daa743
0450620fdabdf1c9032c31836434acc5188ee682
026c74a92d04faefebed778f381603fcb1db4a03
50ac4167f702141b4821e5e5e8f1f72d4d8f33d0
59038f2db68a14fbca498f408da8f9650c88efad
f6b9096da915f52a3b34e194beb9121e517bc823
4e0baffdd79bc8aa0f2708b4349115d3a3529fb8
57eeb849ab881f86485806bfff5d9952f50c268d
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 11 changesets (bug 1404222) for static analysis failures on a CLOSED TREE. Backed out changeset a6a99136300c (bug 1404222) Backed out changeset 7183b8104399 (bug 1404222) Backed out changeset a1e4294c1c59 (bug 1404222) Backed out changeset b79d6e8318db (bug 1404222) Backed out changeset 0450620fdabd (bug 1404222) Backed out changeset 026c74a92d04 (bug 1404222) Backed out changeset 50ac4167f702 (bug 1404222) Backed out changeset 59038f2db68a (bug 1404222) Backed out changeset f6b9096da915 (bug 1404222) Backed out changeset 4e0baffdd79b (bug 1404222) Backed out changeset 57eeb849ab88 (bug 1404222)
layout/generic/crashtests/1404222-empty-shape.html
layout/generic/crashtests/crashtests.list
layout/generic/nsFloatManager.cpp
layout/generic/nsFloatManager.h
layout/generic/nsFrame.cpp
layout/generic/nsIFrame.h
layout/painting/nsCSSRendering.cpp
layout/painting/nsCSSRenderingBorders.cpp
layout/painting/nsImageRenderer.cpp
layout/painting/nsImageRenderer.h
layout/style/ImageLoader.cpp
layout/style/ImageLoader.h
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/test/file_shape_outside_CORS.html
layout/svg/SVGObserverUtils.cpp
testing/web-platform/meta/MANIFEST.json
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-001.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-002.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-003.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-004.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-radial-gradient-001.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-000.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-001.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-002.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-003.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-004.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-005.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-012.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-013.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-014.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-015.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-016.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-017.html.ini
testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-025.html.ini
testing/web-platform/meta/css/css-shapes/spec-examples/shape-outside-010.html.ini
testing/web-platform/meta/css/css-shapes/spec-examples/shape-outside-011.html.ini
testing/web-platform/meta/css/css-shapes/spec-examples/shape-outside-012.html.ini
testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-005.html
testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-006.html
testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-007.html
testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-008.html
testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/shape-image-001.html
testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/shape-image-002.html
testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/shape-image-005.html
testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/support/animated.gif
deleted file mode 100644
--- a/layout/generic/crashtests/1404222-empty-shape.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<!DOCTYPE html>
-<div style="float: left; shape-outside: linear-gradient(to top, green 50%, transparent 50%);"></div>
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -669,15 +669,14 @@ load 1367413-1.html
 load 1368617-1.html
 load 1373586.html
 load 1375858.html
 load 1381134.html
 load 1381134-2.html
 load 1401420-1.html
 load 1401709.html
 load 1401807.html
-load 1404222-empty-shape.html
 load 1405443.html
 load 1415185.html
 load 1416544.html
 load 1427824.html
 load 1431781.html
 load 1431781-2.html
--- a/layout/generic/nsFloatManager.cpp
+++ b/layout/generic/nsFloatManager.cpp
@@ -6,22 +6,20 @@
 
 /* class that manages rules for positioning floats */
 
 #include "nsFloatManager.h"
 
 #include <algorithm>
 #include <initializer_list>
 
-#include "gfxContext.h"
 #include "mozilla/ReflowInput.h"
 #include "mozilla/ShapeUtils.h"
 #include "nsBlockFrame.h"
 #include "nsError.h"
-#include "nsImageRenderer.h"
 #include "nsIPresShell.h"
 #include "nsMemory.h"
 
 using namespace mozilla;
 
 int32_t nsFloatManager::sCachedFloatManagerCount = 0;
 void* nsFloatManager::sCachedFloatManagers[NS_FLOAT_MANAGER_CACHE_SIZE];
 
@@ -172,18 +170,19 @@ nsFloatManager::GetFlowArea(WritingMode 
   bool haveFloats = false;
   for (uint32_t i = floatCount; i > 0; --i) {
     const FloatInfo &fi = mFloats[i-1];
     if (fi.mLeftBEnd <= blockStart && fi.mRightBEnd <= blockStart) {
       // There aren't any more floats that could intersect this band.
       break;
     }
     if (fi.IsEmpty(aShapeType)) {
-      // Ignore empty float areas.
-      // https://drafts.csswg.org/css-shapes/#relation-to-box-model-and-float-behavior
+      // For compatibility, ignore floats with empty rects, even though it
+      // disagrees with the spec.  (We might want to fix this in the
+      // future, though.)
       continue;
     }
 
     nscoord floatBStart = fi.BStart(aShapeType);
     nscoord floatBEnd = fi.BEnd(aShapeType);
     if (blockStart < floatBStart && aBandInfoType == BandInfoType::BandFromPoint) {
       // This float is below our band.  Shrink our band's height if needed.
       if (floatBStart < blockEnd) {
@@ -576,23 +575,16 @@ public:
     const nsSize& aContainerSize);
 
   static UniquePtr<ShapeInfo> CreatePolygon(
     const UniquePtr<StyleBasicShape>& aBasicShape,
     const LogicalRect& aShapeBoxRect,
     WritingMode aWM,
     const nsSize& aContainerSize);
 
-  static UniquePtr<ShapeInfo> CreateImageShape(
-    const UniquePtr<nsStyleImage>& aShapeImage,
-    float aShapeImageThreshold,
-    nsIFrame* const aFrame,
-    WritingMode aWM,
-    const nsSize& aContainerSize);
-
 protected:
   // Compute the minimum line-axis difference between the bounding shape
   // box and its rounded corner within the given band (block-axis region).
   // This is used as a helper function to compute the LineRight() and
   // LineLeft(). See the picture in the implementation for an example.
   // RadiusL and RadiusB stand for radius on the line-axis and block-axis.
   //
   // Returns radius-x diff on the line-axis, or 0 if there's no rounded
@@ -618,17 +610,16 @@ protected:
     const nscoord aRadii[8],
     WritingMode aWM);
 };
 
 /////////////////////////////////////////////////////////////////////////////
 // RoundedBoxShapeInfo
 //
 // Implements shape-outside: <shape-box> and shape-outside: inset().
-//
 class nsFloatManager::RoundedBoxShapeInfo final : public nsFloatManager::ShapeInfo
 {
 public:
   RoundedBoxShapeInfo(const nsRect& aRect,
                       UniquePtr<nscoord[]> aRadii)
     : mRect(aRect)
     , mRadii(Move(aRadii))
   {}
@@ -957,304 +948,44 @@ nsFloatManager::PolygonShapeInfo::XInter
 
   MOZ_ASSERT(aP1.y != aP2.y,
              "A horizontal line segment results in dividing by zero error!");
 
   return aP1.x + (aY - aP1.y) * (aP2.x - aP1.x) / (aP2.y - aP1.y);
 }
 
 /////////////////////////////////////////////////////////////////////////////
-// ImageShapeInfo
-//
-// Implements shape-outside: <image>
-//
-class nsFloatManager::ImageShapeInfo final : public nsFloatManager::ShapeInfo
-{
-public:
-  ImageShapeInfo(uint8_t* aAlphaPixels,
-                 int32_t aStride,
-                 const LayoutDeviceIntSize& aImageSize,
-                 int32_t aAppUnitsPerDevPixel,
-                 float aShapeImageThreshold,
-                 const nsRect& aContentRect,
-                 WritingMode aWM,
-                 const nsSize& aContainerSize);
-
-  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(); }
-
-  void Translate(nscoord aLineLeft, nscoord aBlockStart) override;
-
-private:
-  size_t MinIntervalIndexContainingY(const nscoord aTargetY) const;
-  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;
-
-  nscoord mBStart = nscoord_MAX;
-  nscoord mBEnd = nscoord_MIN;
-};
-
-nsFloatManager::ImageShapeInfo::ImageShapeInfo(
-  uint8_t* aAlphaPixels,
-  int32_t aStride,
-  const LayoutDeviceIntSize& aImageSize,
-  int32_t aAppUnitsPerDevPixel,
-  float aShapeImageThreshold,
-  const nsRect& aContentRect,
-  WritingMode aWM,
-  const nsSize& aContainerSize)
-{
-  MOZ_ASSERT(aShapeImageThreshold >=0.0 && aShapeImageThreshold <=1.0,
-             "The computed value of shape-image-threshold is wrong!");
-
-  const uint8_t threshold = NSToIntFloor(aShapeImageThreshold * 255);
-  const int32_t w = aImageSize.width;
-  const int32_t h = aImageSize.height;
-
-  // Scan the pixels in a double loop. For horizontal writing modes, we do
-  // this row by row, from top to bottom. For vertical writing modes, we do
-  // column by column, from left to right. We define the two loops
-  // generically, then figure out the rows and cols within the i loop.
-  const int32_t bSize = aWM.IsVertical() ? w : h;
-  const int32_t iSize = aWM.IsVertical() ? h : w;
-  for (int32_t b = 0; b < bSize; ++b) {
-    // iMin and iMax store the start and end of the float area for the row
-    // or column represented by this iteration of the b loop.
-    int32_t iMin = -1;
-    int32_t iMax = -1;
-
-    for (int32_t i = 0; i < iSize; ++i) {
-      const int32_t col = aWM.IsVertical() ? b : i;
-      const int32_t row = aWM.IsVertical() ? i : b;
-
-      // Determine if the alpha pixel at this row and column has a value
-      // greater than the threshold. If it does, update our iMin and iMax values
-      // to track the edges of the float area for this row or column.
-      // https://drafts.csswg.org/css-shapes-1/#valdef-shape-image-threshold-number
-      const uint8_t alpha = aAlphaPixels[col + row * aStride];
-      if (alpha > threshold) {
-        if (iMin == -1) {
-          iMin = i;
-        }
-        MOZ_ASSERT(iMax < i);
-        iMax = i;
-      }
-    }
-
-    // At the end of a row or column; did we find something?
-    if (iMin != -1) {
-      // Store an interval as an nsRect with our inline axis values stored in x
-      // and our block axis values stored in y. The position is dependent on
-      // the writing mode, but the size is the same for all writing modes.
-
-      // Size is the difference in inline axis edges stored as x, and one
-      // block axis pixel stored as y. For the inline axis, we add 1 to iMax
-      // because we want to capture the far edge of the last pixel.
-      nsSize size(((iMax + 1) - iMin) * aAppUnitsPerDevPixel,
-                  aAppUnitsPerDevPixel);
-
-      // Since we started our scanning of the image pixels from the top left,
-      // the interval position starts from the origin of the content rect,
-      // converted to logical coordinates.
-      nsPoint origin = ConvertToFloatLogical(aContentRect.TopLeft(), aWM,
-                                             aContainerSize);
-
-      // Depending on the writing mode, we now move the origin.
-      if (aWM.IsVerticalRL()) {
-        // vertical-rl or sideways-rl.
-        // These writing modes proceed from the top right, and each interval
-        // moves in a positive inline direction and negative block direction.
-        // That means that the intervals will be reversed after all have been
-        // constructed. We add 1 to b to capture the end of the block axis pixel.
-        origin.MoveBy(iMin * aAppUnitsPerDevPixel, (b + 1) * -aAppUnitsPerDevPixel);
-      } else if (aWM.IsVerticalLR() && aWM.IsSideways()) {
-        // sideways-lr.
-        // These writing modes proceed from the bottom left, and each interval
-        // moves in a negative inline direction and a positive block direction.
-        // We add 1 to iMax to capture the end of the inline axis pixel.
-        origin.MoveBy((iMax + 1) * -aAppUnitsPerDevPixel, b * aAppUnitsPerDevPixel);
-      } else {
-        // horizontal-tb or vertical-lr.
-        // These writing modes proceed from the top left and each interval
-        // moves in a positive step in both inline and block directions.
-        origin.MoveBy(iMin * aAppUnitsPerDevPixel, b * aAppUnitsPerDevPixel);
-      }
-
-      mIntervals.AppendElement(nsRect(origin, size));
-    }
-  }
-
-  if (aWM.IsVerticalRL()) {
-    // vertical-rl or sideways-rl.
-    // 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].Y();
-    mBEnd = mIntervals.LastElement().YMost();
-  }
-}
-
-size_t
-nsFloatManager::ImageShapeInfo::MinIntervalIndexContainingY(
-  const nscoord aTargetY) const
-{
-  // 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 = mIntervals.Length();
-  while (startIdx < endIdx) {
-    size_t midIdx = startIdx + (endIdx - startIdx) / 2;
-    if (mIntervals[midIdx].ContainsY(aTargetY)) {
-      return midIdx;
-    }
-    nscoord midY = mIntervals[midIdx].Y();
-    if (midY < aTargetY) {
-      startIdx = midIdx + 1;
-    } else {
-      endIdx = midIdx;
-    }
-  }
-
-  return endIdx;
-}
-
-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(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);
-}
-
-nscoord
-nsFloatManager::ImageShapeInfo::LineRight(const nscoord aBStart,
-                                          const nscoord aBEnd) const
-{
-  return LineEdge(aBStart, aBEnd, false);
-}
-
-void
-nsFloatManager::ImageShapeInfo::Translate(nscoord aLineLeft,
-                                          nscoord aBlockStart)
-{
-  for (nsRect& interval : mIntervals) {
-    interval.MoveBy(aLineLeft, aBlockStart);
-  }
-
-  mBStart += aBlockStart;
-  mBEnd += aBlockStart;
-}
-
-/////////////////////////////////////////////////////////////////////////////
 // FloatInfo
 
 nsFloatManager::FloatInfo::FloatInfo(nsIFrame* aFrame,
                                      nscoord aLineLeft, nscoord aBlockStart,
                                      const LogicalRect& aMarginRect,
                                      WritingMode aWM,
                                      const nsSize& aContainerSize)
   : mFrame(aFrame)
   , mRect(ShapeInfo::ConvertToFloatLogical(aMarginRect, aWM, aContainerSize) +
           nsPoint(aLineLeft, aBlockStart))
 {
   MOZ_COUNT_CTOR(nsFloatManager::FloatInfo);
 
-  if (IsEmpty()) {
-    // Per spec, a float area defined by a shape is clipped to the float’s
-    // margin box. Therefore, no need to create a shape info if the float's
-    // margin box is empty, since a float area can only be smaller than the
-    // margin box.
-
-    // https://drafts.csswg.org/css-shapes/#relation-to-box-model-and-float-behavior
-    return;
-  }
-
   const StyleShapeSource& shapeOutside = mFrame->StyleDisplay()->mShapeOutside;
 
   switch (shapeOutside.GetType()) {
     case StyleShapeSourceType::None:
       // No need to create shape info.
       return;
 
     case StyleShapeSourceType::URL:
       MOZ_ASSERT_UNREACHABLE("shape-outside doesn't have URL source type!");
       return;
 
-    case StyleShapeSourceType::Image: {
-      float shapeImageThreshold = mFrame->StyleDisplay()->mShapeImageThreshold;
-      mShapeInfo = ShapeInfo::CreateImageShape(shapeOutside.GetShapeImage(),
-                                               shapeImageThreshold,
-                                               mFrame,
-                                               aWM,
-                                               aContainerSize);
-      if (!mShapeInfo) {
-        // Image is not ready, or fails to load, etc.
-        return;
-      }
-
-      break;
-    }
+    case StyleShapeSourceType::Image:
+      // Bug 1265343: Implement 'shape-image-threshold'
+      // Bug 1404222: Support shape-outside: <image>
+      return;
 
     case StyleShapeSourceType::Box: {
       // Initialize <shape-box>'s reference rect.
       LogicalRect shapeBoxRect =
         ShapeInfo::ComputeShapeBoxRect(shapeOutside, mFrame, aMarginRect, aWM);
       mShapeInfo = ShapeInfo::CreateShapeBox(mFrame, shapeBoxRect, aWM,
                                              aContainerSize);
       break;
@@ -1541,94 +1272,16 @@ nsFloatManager::ShapeInfo::CreatePolygon
   // Convert all the physical vertices to logical.
   for (nsPoint& vertex : vertices) {
     vertex = ConvertToFloatLogical(vertex, aWM, aContainerSize);
   }
 
   return MakeUnique<PolygonShapeInfo>(Move(vertices));
 }
 
-/* static */ UniquePtr<nsFloatManager::ShapeInfo>
-nsFloatManager::ShapeInfo::CreateImageShape(
-  const UniquePtr<nsStyleImage>& aShapeImage,
-  float aShapeImageThreshold,
-  nsIFrame* const aFrame,
-  WritingMode aWM,
-  const nsSize& aContainerSize)
-{
-  MOZ_ASSERT(aShapeImage ==
-             aFrame->StyleDisplay()->mShapeOutside.GetShapeImage(),
-             "aFrame should be the frame that we got aShapeImage from");
-
-  nsImageRenderer imageRenderer(aFrame, aShapeImage.get(),
-                                nsImageRenderer::FLAG_SYNC_DECODE_IMAGES);
-
-  if (!imageRenderer.PrepareImage()) {
-    // The image is not ready yet.
-    return nullptr;
-  }
-
-  nsRect contentRect = aFrame->GetContentRect();
-
-  // Create a draw target and draw shape image on it.
-  nsDeviceContext* dc = aFrame->PresContext()->DeviceContext();
-  int32_t appUnitsPerDevPixel = dc->AppUnitsPerDevPixel();
-  LayoutDeviceIntSize contentSizeInDevPixels =
-    LayoutDeviceIntSize::FromAppUnitsRounded(contentRect.Size(),
-                                             appUnitsPerDevPixel);
-
-  // Use empty CSSSizeOrRatio to force set the preferred size as the frame's
-  // content box size.
-  imageRenderer.SetPreferredSize(CSSSizeOrRatio(), contentRect.Size());
-
-  RefPtr<gfx::DrawTarget> drawTarget =
-    gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(
-      contentSizeInDevPixels.ToUnknownSize(),
-      gfx::SurfaceFormat::A8);
-  if (!drawTarget) {
-    return nullptr;
-  }
-
-  RefPtr<gfxContext> context = gfxContext::CreateOrNull(drawTarget);
-  MOZ_ASSERT(context); // already checked the target above
-
-  ImgDrawResult result =
-    imageRenderer.DrawShapeImage(aFrame->PresContext(), *context);
-
-  if (result != ImgDrawResult::SUCCESS) {
-    return nullptr;
-  }
-
-  // Retrieve the pixel image buffer to create the image shape info.
-  RefPtr<SourceSurface> sourceSurface = drawTarget->Snapshot();
-  RefPtr<DataSourceSurface> dataSourceSurface = sourceSurface->GetDataSurface();
-  DataSourceSurface::ScopedMap map(dataSourceSurface, DataSourceSurface::READ);
-
-  if (!map.IsMapped()) {
-    return nullptr;
-  }
-
-  MOZ_ASSERT(sourceSurface->GetSize() == contentSizeInDevPixels.ToUnknownSize(),
-             "Who changes the size?");
-
-  uint8_t* alphaPixels = map.GetData();
-  int32_t stride = map.GetStride();
-
-  // NOTE: ImageShapeInfo constructor does not keep a persistent copy of
-  // alphaPixels; it's only used during the constructor to compute pixel ranges.
-  return MakeUnique<ImageShapeInfo>(alphaPixels,
-                                    stride,
-                                    contentSizeInDevPixels,
-                                    appUnitsPerDevPixel,
-                                    aShapeImageThreshold,
-                                    contentRect,
-                                    aWM,
-                                    aContainerSize);
-}
-
 /* static */ nscoord
 nsFloatManager::ShapeInfo::ComputeEllipseLineInterceptDiff(
   const nscoord aShapeBoxBStart, const nscoord aShapeBoxBEnd,
   const nscoord aBStartCornerRadiusL, const nscoord aBStartCornerRadiusB,
   const nscoord aBEndCornerRadiusL, const nscoord aBEndCornerRadiusB,
   const nscoord aBandBStart, const nscoord aBandBEnd)
 {
   // An example for the band intersecting with the top right corner of an
--- a/layout/generic/nsFloatManager.h
+++ b/layout/generic/nsFloatManager.h
@@ -339,17 +339,16 @@ public:
 #endif
 
 private:
 
   class ShapeInfo;
   class RoundedBoxShapeInfo;
   class EllipseShapeInfo;
   class PolygonShapeInfo;
-  class ImageShapeInfo;
 
   struct FloatInfo {
     nsIFrame *const mFrame;
     // The lowest block-ends of left/right floats up to and including
     // this one.
     nscoord mLeftBEnd, mRightBEnd;
 
     FloatInfo(nsIFrame* aFrame, nscoord aLineLeft, nscoord aBlockStart,
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -101,25 +101,24 @@
 #include "mozilla/EffectSet.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/ServoStyleSet.h"
+#include "mozilla/css/ImageLoader.h"
 #include "mozilla/gfx/Tools.h"
 #include "nsPrintfCString.h"
 #include "ActiveLayerTracker.h"
 
 #include "nsITheme.h"
 #include "nsThemeConstants.h"
 
-#include "ImageLoader.h"
-
 using namespace mozilla;
 using namespace mozilla::css;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
 typedef nsAbsoluteContainingBlock::AbsPosReflowFlags AbsPosReflowFlags;
 
@@ -903,17 +902,17 @@ AddAndRemoveImageAssociations(nsFrame* a
     CompareLayers(aOldLayers, aNewLayers,
       [&imageLoader, aFrame](imgRequestProxy* aReq)
       { imageLoader->DisassociateRequestFromFrame(aReq, aFrame); }
     );
   }
 
   CompareLayers(aNewLayers, aOldLayers,
     [&imageLoader, aFrame](imgRequestProxy* aReq)
-    { imageLoader->AssociateRequestToFrame(aReq, aFrame, 0); }
+    { imageLoader->AssociateRequestToFrame(aReq, aFrame); }
   );
 }
 
 void
 nsIFrame::AddDisplayItem(nsDisplayItem* aItem)
 {
   DisplayItemArray* items = GetProperty(DisplayItems());
   if (!items) {
@@ -1171,34 +1170,17 @@ nsFrame::DidSetComputedStyle(ComputedSty
   // to paint borders with a different style, because they won't have the
   // correct size for the border either.
   if (oldBorderImage != newBorderImage) {
     // stop and restart the image loading/notification
     if (oldBorderImage && HasImageRequest()) {
       imageLoader->DisassociateRequestFromFrame(oldBorderImage, this);
     }
     if (newBorderImage) {
-      imageLoader->AssociateRequestToFrame(newBorderImage, this, 0);
-    }
-  }
-
-  imgIRequest* oldShapeImage =
-      aOldComputedStyle
-    ? aOldComputedStyle->StyleDisplay()->mShapeOutside.GetShapeImageData()
-    : nullptr;
-  imgIRequest* newShapeImage =
-    StyleDisplay()->mShapeOutside.GetShapeImageData();
-
-  if (oldShapeImage != newShapeImage) {
-    if (oldShapeImage && HasImageRequest()) {
-      imageLoader->DisassociateRequestFromFrame(oldShapeImage, this);
-    }
-    if (newShapeImage) {
-      imageLoader->AssociateRequestToFrame(newShapeImage, this,
-        ImageLoader::REQUEST_REQUIRES_REFLOW);
+      imageLoader->AssociateRequestToFrame(newBorderImage, this);
     }
   }
 
   // If the page contains markup that overrides text direction, and
   // does not contain any characters that would activate the Unicode
   // bidi algorithm, we need to call |SetBidiEnabled| on the pres
   // context before reflow starts.  See bug 115921.
   if (StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
@@ -5233,32 +5215,32 @@ nsIFrame::ContentOffsets nsIFrame::GetCo
 }
 
 nsIFrame::ContentOffsets nsFrame::CalcContentOffsetsFromFramePoint(const nsPoint& aPoint)
 {
   return OffsetsForSingleFrame(this, aPoint);
 }
 
 void
-nsIFrame::AssociateImage(const nsStyleImage& aImage, nsPresContext* aPresContext,
-                         uint32_t aImageLoaderFlags)
+nsIFrame::AssociateImage(const nsStyleImage& aImage, nsPresContext* aPresContext)
 {
   if (aImage.GetType() != eStyleImageType_Image) {
     return;
   }
 
   imgRequestProxy* req = aImage.GetImageData();
   if (!req) {
     return;
   }
+
   mozilla::css::ImageLoader* loader =
     aPresContext->Document()->StyleImageLoader();
 
   // If this fails there's not much we can do ...
-  loader->AssociateRequestToFrame(req, this, aImageLoaderFlags);
+  loader->AssociateRequestToFrame(req, this);
 }
 
 nsresult
 nsFrame::GetCursor(const nsPoint& aPoint,
                    nsIFrame::Cursor& aCursor)
 {
   FillCursorInformationFromStyle(StyleUserInterface(), aCursor);
   if (NS_STYLE_CURSOR_AUTO == aCursor.mCursor) {
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -1950,18 +1950,17 @@ public:
   virtual ContentOffsets GetContentOffsetsFromPointExternal(const nsPoint& aPoint,
                                                             uint32_t aFlags = 0)
   { return GetContentOffsetsFromPoint(aPoint, aFlags); }
 
   /**
    * Ensure that aImage gets notifed when the underlying image request loads
    * or animates.
    */
-  void AssociateImage(const nsStyleImage& aImage, nsPresContext* aPresContext,
-                      uint32_t aImageLoaderFlags);
+  void AssociateImage(const nsStyleImage& aImage, nsPresContext* aPresContext);
 
   /**
    * This structure holds information about a cursor. mContainer represents a
    * loaded image that should be preferred. If it is not possible to use it, or
    * if it is null, mCursor should be used.
    */
   struct MOZ_STACK_CLASS Cursor {
     nsCOMPtr<imgIContainer> mContainer;
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -2740,17 +2740,17 @@ nsCSSRendering::PaintStyleImageLayerWith
   // association of the style data with the frame.
   if (aBackgroundSC != aParams.frame->Style()) {
     uint32_t startLayer = drawAllLayers ? layers.mImageCount - 1
                                         : aParams.layer;
     uint32_t count = drawAllLayers ? layers.mImageCount : 1;
     NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT_WITH_RANGE(i, layers, startLayer,
                                                          count) {
       aParams.frame->AssociateImage(layers.mLayers[i].mImage,
-                                    &aParams.presCtx, 0);
+                                    &aParams.presCtx);
     }
   }
 
   // The background color is rendered over the entire dirty area,
   // even if the image isn't.
   if (drawBackgroundColor && !isCanvasFrame) {
     DrawBackgroundColor(clipState, &aRenderingCtx, appUnitsPerPixel);
   }
--- a/layout/painting/nsCSSRenderingBorders.cpp
+++ b/layout/painting/nsCSSRenderingBorders.cpp
@@ -3481,17 +3481,17 @@ nsCSSBorderImageRenderer::CreateBorderIm
   }
 
   // Ensure we get invalidated for loads and animations of the image.
   // We need to do this here because this might be the only code that
   // knows about the association of the style data with the frame.
   // XXX We shouldn't really... since if anybody is passing in a
   // different style, they'll potentially have the wrong size for the
   // border too.
-  aForFrame->AssociateImage(aStyleBorder.mBorderImageSource, aPresContext, 0);
+  aForFrame->AssociateImage(aStyleBorder.mBorderImageSource, aPresContext);
 
   nsCSSBorderImageRenderer renderer(aForFrame, aBorderArea,
                                     aStyleBorder, aSkipSides, imgRenderer);
   *aDrawResult = ImgDrawResult::SUCCESS;
   return Some(renderer);
 }
 
 ImgDrawResult
--- a/layout/painting/nsImageRenderer.cpp
+++ b/layout/painting/nsImageRenderer.cpp
@@ -1,30 +1,28 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* utility code for drawing images as CSS borders, backgrounds, and shapes. */
+/* utility functions for drawing borders and backgrounds */
 
 #include "nsImageRenderer.h"
 
 #include "mozilla/webrender/WebRenderAPI.h"
 
 #include "gfxContext.h"
 #include "gfxDrawable.h"
 #include "ImageOps.h"
-#include "ImageRegion.h"
 #include "mozilla/layers/StackingContextHelper.h"
 #include "mozilla/layers/WebRenderLayerManager.h"
 #include "nsContentUtils.h"
 #include "nsCSSRendering.h"
 #include "nsCSSRenderingGradients.h"
-#include "nsDeviceContext.h"
 #include "nsIFrame.h"
 #include "nsStyleStructInlines.h"
 #include "nsSVGDisplayableFrame.h"
 #include "SVGObserverUtils.h"
 #include "nsSVGIntegrationUtils.h"
 #include "mozilla/layers/WebRenderLayerManager.h"
 
 using namespace mozilla;
@@ -943,82 +941,20 @@ nsImageRenderer::DrawBorderImageComponen
                                               ExtendMode::CLAMP, 1.0);
   }
 
   nsSize repeatSize(aFill.Size());
   nsRect fillRect(aFill);
   nsRect destTile = RequiresScaling(fillRect, aHFill, aVFill, aUnitSize)
                   ? ComputeTile(fillRect, aHFill, aVFill, aUnitSize, repeatSize)
                   : fillRect;
-
   return Draw(aPresContext, aRenderingContext, aDirtyRect, destTile,
               fillRect, destTile.TopLeft(), repeatSize, aSrc);
 }
 
-ImgDrawResult
-nsImageRenderer::DrawShapeImage(nsPresContext* aPresContext,
-                                gfxContext& aRenderingContext)
-{
-  if (!IsReady()) {
-    NS_NOTREACHED("Ensure PrepareImage() has returned true before calling me");
-    return ImgDrawResult::NOT_READY;
-  }
-
-  if (mSize.width <= 0 || mSize.height <= 0) {
-    return ImgDrawResult::SUCCESS;
-  }
-
-  ImgDrawResult result = ImgDrawResult::SUCCESS;
-
-  switch (mType) {
-    case eStyleImageType_Image: {
-      uint32_t drawFlags = ConvertImageRendererToDrawFlags(mFlags) |
-                           imgIContainer::FRAME_FIRST;
-      nsRect dest(nsPoint(0, 0), mSize);
-      // We have a tricky situation in our choice of SamplingFilter. Shape images
-      // define a float area based on the alpha values in the rendered pixels.
-      // When multiple device pixels are used for one css pixel, the sampling
-      // can change crisp edges into aliased edges. For visual pixels, that's
-      // usually the right choice. For defining a float area, it can cause problems.
-      // If a style is using a shape-image-threshold value that is less than the
-      // alpha of the edge pixels, any filtering may smear the alpha into adjacent
-      // pixels and expand the float area in a confusing way. Since the alpha
-      // threshold can be set precisely in CSS, and since a web author may be
-      // counting on that threshold to define a precise float area from an image,
-      // it is least confusing to have the rendered pixels have unfiltered alpha.
-      // We use SamplingFilter::POINT to ensure that each rendered pixel has an
-      // alpha that precisely matches the alpha of the closest pixel in the image.
-      nsLayoutUtils::DrawSingleImage(aRenderingContext, aPresContext,
-                                     mImageContainer, SamplingFilter::POINT,
-                                     dest, dest, Nothing(),
-                                     drawFlags,
-                                     nullptr, nullptr);
-      break;
-    }
-
-    case eStyleImageType_Gradient: {
-      nsCSSGradientRenderer renderer =
-        nsCSSGradientRenderer::Create(aPresContext, mGradientData, mSize);
-      nsRect dest(nsPoint(0, 0), mSize);
-
-      renderer.Paint(aRenderingContext, dest, dest, mSize,
-                     CSSIntRect::FromAppUnitsRounded(dest),
-                     dest, 1.0);
-      break;
-    }
-
-    default:
-      // Unsupported image type.
-      result = ImgDrawResult::BAD_IMAGE;
-      break;
-  }
-
-  return result;
-}
-
 bool
 nsImageRenderer::IsRasterImage()
 {
   if (mType != eStyleImageType_Image || !mImageContainer)
     return false;
   return mImageContainer->GetType() == imgIContainer::TYPE_RASTER;
 }
 
--- a/layout/painting/nsImageRenderer.h
+++ b/layout/painting/nsImageRenderer.h
@@ -249,24 +249,16 @@ public:
                            const mozilla::CSSIntRect& aSrc,
                            mozilla::StyleBorderImageRepeat aHFill,
                            mozilla::StyleBorderImageRepeat aVFill,
                            const nsSize&        aUnitSize,
                            uint8_t              aIndex,
                            const mozilla::Maybe<nsSize>& aSVGViewportSize,
                            const bool           aHasIntrinsicRatio);
 
-  /**
-   * Draw the image to aRenderingContext which can be used to define the
-   * float area in the presence of "shape-outside: <image>".
-   */
-  ImgDrawResult
-  DrawShapeImage(nsPresContext* aPresContext,
-                 gfxContext& aRenderingContext);
-
   bool IsRasterImage();
   bool IsAnimatedImage();
 
   /// Retrieves the image associated with this nsImageRenderer, if there is one.
   already_AddRefed<imgIContainer> GetImage();
 
   bool IsImageContainerAvailable(layers::LayerManager* aManager, uint32_t aFlags);
   bool IsReady() const { return mPrepareResult == ImgDrawResult::SUCCESS; }
--- a/layout/style/ImageLoader.cpp
+++ b/layout/style/ImageLoader.cpp
@@ -9,17 +9,16 @@
  */
 
 #include "mozilla/css/ImageLoader.h"
 #include "nsAutoPtr.h"
 #include "nsContentUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsError.h"
 #include "nsDisplayList.h"
-#include "nsIFrameInlines.h"
 #include "FrameLayerBuilder.h"
 #include "SVGObserverUtils.h"
 #include "imgIContainer.h"
 #include "Image.h"
 #include "GeckoProfiler.h"
 #include "mozilla/layers/WebRenderUserData.h"
 
 namespace mozilla {
@@ -43,18 +42,17 @@ ImageLoader::DropDocumentReference()
   }
   mImages.Clear();
 
   mDocument = nullptr;
 }
 
 void
 ImageLoader::AssociateRequestToFrame(imgIRequest* aRequest,
-                                     nsIFrame* aFrame,
-                                     FrameFlags aFlags)
+                                     nsIFrame* aFrame)
 {
   nsCOMPtr<imgINotificationObserver> observer;
   aRequest->GetNotificationObserver(getter_AddRefs(observer));
   if (!observer) {
     // The request has already been canceled, so ignore it.  This is ok because
     // we're not going to get any more notifications from a canceled request.
     return;
   }
@@ -73,73 +71,25 @@ ImageLoader::AssociateRequestToFrame(img
     });
 
   RequestSet* requestSet =
     mFrameToRequestMap.LookupForAdd(aFrame).OrInsert([=]() {
       aFrame->SetHasImageRequest(true);
       return new RequestSet();
     });
 
-  // Add frame to the frameSet, and handle any special processing the
-  // frame might require.
-  FrameWithFlags fwf(aFrame);
-  FrameWithFlags* fwfToModify(&fwf);
-
-  // See if the frameSet already has this frame.
-  uint32_t i = frameSet->IndexOfFirstElementGt(fwf, FrameOnlyComparator());
-  if (i > 0 && aFrame == frameSet->ElementAt(i-1).mFrame) {
-    // We're already tracking this frame, so prepare to modify the
-    // existing FrameWithFlags object.
-    fwfToModify = &frameSet->ElementAt(i-1);
+  // Add these to the sets, but only if they're not already there.
+  uint32_t i = frameSet->IndexOfFirstElementGt(aFrame);
+  if (i == 0 || aFrame != frameSet->ElementAt(i-1)) {
+    frameSet->InsertElementAt(i, aFrame);
   }
-
-  // Check if the frame requires special processing.
-  if (aFlags & REQUEST_REQUIRES_REFLOW) {
-    fwfToModify->mFlags |= REQUEST_REQUIRES_REFLOW;
-
-    // If we weren't already blocking onload, do that now.
-    if ((fwfToModify->mFlags & REQUEST_HAS_BLOCKED_ONLOAD) == 0) {
-      fwfToModify->mFlags |= REQUEST_HAS_BLOCKED_ONLOAD;
-
-      // Block document onload until we either remove the frame in
-      // RemoveRequestToFrameMapping or complete a reflow.
-      mDocument->BlockOnload();
-
-      // We need to stay blocked until we get a reflow. If the first frame
-      // is not yet decoded, we'll trigger that reflow from onFrameComplete.
-      // But if the first frame is already decoded, we need to trigger that
-      // reflow now, because we'll never get a call to onFrameComplete.
-      uint32_t status = 0;
-      if(NS_SUCCEEDED(aRequest->GetImageStatus(&status)) &&
-         status & imgIRequest::STATUS_FRAME_COMPLETE) {
-        RequestReflowOnFrame(aFrame, aRequest);
-      }
-    }
-  }
-
-  // Do some sanity checking to ensure that we only add to one mapping
-  // iff we also add to the other mapping.
-  DebugOnly<bool> didAddToFrameSet(false);
-  DebugOnly<bool> didAddToRequestSet(false);
-
-  // If we weren't already tracking this frame, add it to the frameSet.
-  if (i == 0 || aFrame != frameSet->ElementAt(i-1).mFrame) {
-    frameSet->InsertElementAt(i, fwf);
-    didAddToFrameSet = true;
-  }
-
-  // Add request to the request set if it wasn't already there.
   i = requestSet->IndexOfFirstElementGt(aRequest);
   if (i == 0 || aRequest != requestSet->ElementAt(i-1)) {
     requestSet->InsertElementAt(i, aRequest);
-    didAddToRequestSet = true;
   }
-
-  MOZ_ASSERT(didAddToFrameSet == didAddToRequestSet,
-             "We should only add to one map iff we also add to the other map.");
 }
 
 void
 ImageLoader::MaybeRegisterCSSImage(ImageLoader::Image* aImage)
 {
   NS_ASSERTION(aImage, "This should never be null!");
 
   bool found = false;
@@ -184,31 +134,17 @@ ImageLoader::RemoveRequestToFrameMapping
     aRequest->GetNotificationObserver(getter_AddRefs(observer));
     MOZ_ASSERT(!observer || observer == this);
   }
 #endif
 
   if (auto entry = mRequestToFrameMap.Lookup(aRequest)) {
     FrameSet* frameSet = entry.Data();
     MOZ_ASSERT(frameSet, "This should never be null");
-
-    // Before we remove aFrame from the frameSet, unblock onload if needed.
-    uint32_t i = frameSet->IndexOfFirstElementGt(FrameWithFlags(aFrame),
-                                                 FrameOnlyComparator());
-
-    if (i > 0 && aFrame == frameSet->ElementAt(i-1).mFrame) {
-      FrameWithFlags& fwf = frameSet->ElementAt(i-1);
-      if (fwf.mFlags & REQUEST_HAS_BLOCKED_ONLOAD) {
-        mDocument->UnblockOnload(false);
-        // We're about to remove fwf from the frameSet, so we don't bother
-        // updating the flag.
-      }
-      frameSet->RemoveElementAt(i-1);
-    }
-
+    frameSet->RemoveElementSorted(aFrame);
     if (frameSet->IsEmpty()) {
       nsPresContext* presContext = GetPresContext();
       if (presContext) {
         nsLayoutUtils::DeregisterImageRequest(presContext, aRequest, nullptr);
       }
       entry.Remove();
     }
   }
@@ -421,18 +357,17 @@ InvalidateImages(nsIFrame* aFrame)
 }
 
 void
 ImageLoader::DoRedraw(FrameSet* aFrameSet, bool aForcePaint)
 {
   NS_ASSERTION(aFrameSet, "Must have a frame set");
   NS_ASSERTION(mDocument, "Should have returned earlier!");
 
-  for (FrameWithFlags& fwf : *aFrameSet) {
-    nsIFrame* frame = fwf.mFrame;
+  for (nsIFrame* frame : *aFrameSet) {
     if (frame->StyleVisibility()->IsVisible()) {
       if (frame->IsFrameOfType(nsIFrame::eTablePart)) {
         // Tables don't necessarily build border/background display items
         // for the individual table part frames, so IterateRetainedDataFor
         // might not find the right display item.
         frame->InvalidateFrame();
       } else {
         InvalidateImages(frame);
@@ -447,69 +382,16 @@ ImageLoader::DoRedraw(FrameSet* aFrameSe
         if (aForcePaint) {
           frame->SchedulePaint();
         }
       }
     }
   }
 }
 
-void
-ImageLoader::UnblockOnloadIfNeeded(nsIFrame* aFrame, imgIRequest* aRequest)
-{
-  MOZ_ASSERT(aFrame);
-  MOZ_ASSERT(aRequest);
-
-  FrameSet* frameSet = mRequestToFrameMap.Get(aRequest);
-  if (!frameSet) {
-    return;
-  }
-
-  size_t i = frameSet->BinaryIndexOf(FrameWithFlags(aFrame),
-                                     FrameOnlyComparator());
-  if (i != FrameSet::NoIndex) {
-    FrameWithFlags& fwf = frameSet->ElementAt(i);
-    if (fwf.mFlags & REQUEST_HAS_BLOCKED_ONLOAD) {
-      mDocument->UnblockOnload(false);
-      fwf.mFlags &= ~REQUEST_HAS_BLOCKED_ONLOAD;
-    }
-  }
-}
-
-void
-ImageLoader::RequestReflowIfNeeded(FrameSet* aFrameSet, imgIRequest* aRequest)
-{
-  MOZ_ASSERT(aFrameSet);
-
-  for (FrameWithFlags& fwf : *aFrameSet) {
-    nsIFrame* frame = fwf.mFrame;
-    if (fwf.mFlags & REQUEST_REQUIRES_REFLOW) {
-      // Tell the container of the float to reflow because the
-      // shape-outside: <image> has finished decoding its first frame.
-      RequestReflowOnFrame(frame, aRequest);
-    }
-  }
-}
-
-void
-ImageLoader::RequestReflowOnFrame(nsIFrame* aFrame, imgIRequest* aRequest)
-{
-  // Actually request the reflow.
-  nsIFrame* floatContainer = aFrame->GetInFlowParent();
-  floatContainer->PresShell()->FrameNeedsReflow(
-    floatContainer, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
-
-  // We'll respond to the reflow events by unblocking onload, regardless
-  // of whether the reflow was completed or cancelled. The callback will
-  // also delete itself when it is called.
-  ImageReflowCallback* unblocker = new ImageReflowCallback(this, aFrame,
-                                                           aRequest);
-  floatContainer->PresShell()->PostReflowCallback(unblocker);
-}
-
 NS_IMPL_ADDREF(ImageLoader)
 NS_IMPL_RELEASE(ImageLoader)
 
 NS_INTERFACE_MAP_BEGIN(ImageLoader)
   NS_INTERFACE_MAP_ENTRY(imgINotificationObserver)
 NS_INTERFACE_MAP_END
 
 NS_IMETHODIMP
@@ -567,18 +449,17 @@ ImageLoader::OnSizeAvailable(imgIRequest
 
   aImage->SetAnimationMode(presContext->ImageAnimationMode());
 
   FrameSet* frameSet = mRequestToFrameMap.Get(aRequest);
   if (!frameSet) {
     return NS_OK;
   }
 
-  for (FrameWithFlags& fwf : *frameSet) {
-    nsIFrame* frame = fwf.mFrame;
+  for (nsIFrame* frame : *frameSet) {
     if (frame->StyleVisibility()->IsVisible()) {
       frame->MarkNeedsDisplayItemRebuild();
     }
   }
 
   return NS_OK;
 }
 
@@ -613,19 +494,16 @@ ImageLoader::OnFrameComplete(imgIRequest
     return NS_OK;
   }
 
   FrameSet* frameSet = mRequestToFrameMap.Get(aRequest);
   if (!frameSet) {
     return NS_OK;
   }
 
-  // We may need reflow (for example if the image is from shape-outside).
-  RequestReflowIfNeeded(frameSet, aRequest);
-
   // Since we just finished decoding a frame, we always want to paint, in case
   // we're now able to paint an image that we couldn't paint before (and hence
   // that we don't have retained data for).
   DoRedraw(frameSet, /* aForcePaint = */ true);
 
   return NS_OK;
 }
 
@@ -658,41 +536,10 @@ ImageLoader::FlushUseCounters()
     nsCOMPtr<imgIContainer> container;
     request->GetImage(getter_AddRefs(container));
     if (container) {
       static_cast<image::Image*>(container.get())->ReportUseCounters();
     }
   }
 }
 
-bool
-ImageLoader::ImageReflowCallback::ReflowFinished()
-{
-  // Check that the frame is still valid. If it isn't, then onload was
-  // unblocked when the frame was removed from the FrameSet in
-  // RemoveRequestToFrameMapping.
-  if (mFrame.IsAlive()) {
-    mLoader->UnblockOnloadIfNeeded(mFrame, mRequest);
-  }
-
-  // Get rid of this callback object.
-  delete this;
-
-  // We don't need to trigger layout.
-  return false;
-}
-
-void
-ImageLoader::ImageReflowCallback::ReflowCallbackCanceled()
-{
-  // Check that the frame is still valid. If it isn't, then onload was
-  // unblocked when the frame was removed from the FrameSet in
-  // RemoveRequestToFrameMapping.
-  if (mFrame.IsAlive()) {
-    mLoader->UnblockOnloadIfNeeded(mFrame, mRequest);
-  }
-
-  // Get rid of this callback object.
-  delete this;
-}
-
 } // namespace css
 } // namespace mozilla
--- a/layout/style/ImageLoader.h
+++ b/layout/style/ImageLoader.h
@@ -5,21 +5,19 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // A class that handles style system image loads (other image loads are handled
 // by the nodes in the content tree).
 
 #ifndef mozilla_css_ImageLoader_h___
 #define mozilla_css_ImageLoader_h___
 
-#include "mozilla/CORSMode.h"
+#include "CORSMode.h"
 #include "nsClassHashtable.h"
 #include "nsHashKeys.h"
-#include "nsIFrame.h"
-#include "nsIReflowCallback.h"
 #include "nsTArray.h"
 #include "imgIRequest.h"
 #include "imgINotificationObserver.h"
 #include "mozilla/Attributes.h"
 
 class imgIContainer;
 class nsIFrame;
 class nsIDocument;
@@ -30,24 +28,16 @@ class nsIPrincipal;
 namespace mozilla {
 namespace css {
 
 struct ImageValue;
 
 class ImageLoader final : public imgINotificationObserver
 {
 public:
-  // We also associate flags alongside frames in the request-to-frames hashmap.
-  // These are used for special handling of events for requests.
-  typedef uint32_t FrameFlags;
-  enum {
-    REQUEST_REQUIRES_REFLOW    = 1u << 0,
-    REQUEST_HAS_BLOCKED_ONLOAD = 1u << 1
-  };
-
   typedef mozilla::css::ImageValue Image;
 
   explicit ImageLoader(nsIDocument* aDocument)
   : mDocument(aDocument),
     mInClone(false)
   {
     MOZ_ASSERT(mDocument);
   }
@@ -56,18 +46,17 @@ public:
   NS_DECL_IMGINOTIFICATIONOBSERVER
 
   void DropDocumentReference();
 
   void MaybeRegisterCSSImage(Image* aImage);
   void DeregisterCSSImage(Image* aImage);
 
   void AssociateRequestToFrame(imgIRequest* aRequest,
-                               nsIFrame* aFrame,
-                               FrameFlags aFlags);
+                               nsIFrame* aFrame);
 
   void DisassociateRequestFromFrame(imgIRequest* aRequest,
                                     nsIFrame* aFrame);
 
   void DropRequestsForFrame(nsIFrame* aFrame);
 
   void SetAnimationMode(uint16_t aMode);
 
@@ -79,84 +68,37 @@ public:
   void LoadImage(nsIURI* aURI, nsIPrincipal* aPrincipal, nsIURI* aReferrer,
                  Image* aCSSValue, CORSMode aCorsMode);
 
   void DestroyRequest(imgIRequest* aRequest);
 
   void FlushUseCounters();
 
 private:
-  // This callback is used to unblock document onload after a reflow
-  // triggered from an image load.
-  struct ImageReflowCallback final : public nsIReflowCallback
-  {
-    RefPtr<ImageLoader> mLoader;
-    WeakFrame mFrame;
-    nsCOMPtr<imgIRequest> const mRequest;
-
-    ImageReflowCallback(ImageLoader* aLoader,
-                        nsIFrame* aFrame,
-                        imgIRequest* aRequest)
-    : mLoader(aLoader)
-    , mFrame(aFrame)
-    , mRequest(aRequest)
-    {}
-
-    bool ReflowFinished() override;
-    void ReflowCallbackCanceled() override;
-  };
-
   ~ImageLoader() {}
 
   // We need to be able to look up the frames associated with a request (for
   // delivering notifications) and the requests associated with a frame (when
   // the frame goes away). Thus we maintain hashtables going both ways.  These
   // should always be in sync.
 
-  struct FrameWithFlags {
-    explicit FrameWithFlags(nsIFrame* aFrame)
-    : mFrame(aFrame),
-      mFlags(0)
-    {
-      MOZ_ASSERT(mFrame);
-    }
-    nsIFrame* const mFrame;
-    FrameFlags mFlags;
-  };
-
-  // A helper class to compare FrameWithFlags by comparing mFrame and
-  // ignoring mFlags.
-  class FrameOnlyComparator {
-    public:
-      bool Equals(const FrameWithFlags& aElem1,
-                  const FrameWithFlags& aElem2) const
-      { return aElem1.mFrame == aElem2.mFrame; }
-
-      bool LessThan(const FrameWithFlags& aElem1,
-                    const FrameWithFlags& aElem2) const
-      { return aElem1.mFrame < aElem2.mFrame; }
-  };
-
-  typedef nsTArray<FrameWithFlags> FrameSet;
+  typedef nsTArray<nsIFrame*> FrameSet;
   typedef nsTArray<nsCOMPtr<imgIRequest> > RequestSet;
   typedef nsTHashtable<nsPtrHashKey<Image> > ImageHashSet;
   typedef nsClassHashtable<nsISupportsHashKey,
                            FrameSet> RequestToFrameMap;
   typedef nsClassHashtable<nsPtrHashKey<nsIFrame>,
                            RequestSet> FrameToRequestMap;
 
   void AddImage(Image* aCSSImage);
   void RemoveImage(Image* aCSSImage);
 
   nsPresContext* GetPresContext();
 
   void DoRedraw(FrameSet* aFrameSet, bool aForcePaint);
-  void UnblockOnloadIfNeeded(nsIFrame* aFrame, imgIRequest* aRequest);
-  void RequestReflowIfNeeded(FrameSet* aFrameSet, imgIRequest* aRequest);
-  void RequestReflowOnFrame(nsIFrame* aFrame, imgIRequest* aRequest);
 
   nsresult OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage);
   nsresult OnFrameComplete(imgIRequest* aRequest);
   nsresult OnImageIsAnimated(imgIRequest* aRequest);
   nsresult OnFrameUpdate(imgIRequest* aRequest);
 
   // Helpers for DropRequestsForFrame / DisassociateRequestFromFrame above.
   void RemoveRequestToFrameMapping(imgIRequest* aRequest, nsIFrame* aFrame);
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1064,28 +1064,16 @@ StyleShapeSource::SetURL(css::URLValue* 
 void
 StyleShapeSource::SetShapeImage(UniquePtr<nsStyleImage> aShapeImage)
 {
   MOZ_ASSERT(aShapeImage);
   mShapeImage = Move(aShapeImage);
   mType = StyleShapeSourceType::Image;
 }
 
-imgIRequest*
-StyleShapeSource::GetShapeImageData() const
-{
-  if (mType != StyleShapeSourceType::Image) {
-    return nullptr;
-  }
-  if (mShapeImage->GetType() != eStyleImageType_Image) {
-    return nullptr;
-  }
-  return mShapeImage->GetImageData();
-}
-
 void
 StyleShapeSource::SetBasicShape(UniquePtr<StyleBasicShape> aBasicShape,
                                 StyleGeometryBox aReferenceBox)
 {
   MOZ_ASSERT(aBasicShape);
   mBasicShape = Move(aBasicShape);
   mReferenceBox = aReferenceBox;
   mType = StyleShapeSourceType::Shape;
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2140,21 +2140,16 @@ struct StyleShapeSource final
   void SetURL(css::URLValue* aValue);
 
   const UniquePtr<nsStyleImage>& GetShapeImage() const
   {
     MOZ_ASSERT(mType == StyleShapeSourceType::Image, "Wrong shape source type!");
     return mShapeImage;
   }
 
-  // Iff we have "shape-outside:<image>" with an image URI (not a gradient),
-  // this method returns the corresponding imgIRequest*. Else, returns
-  // null.
-  imgIRequest* GetShapeImageData() const;
-
   void SetShapeImage(UniquePtr<nsStyleImage> aShapeImage);
 
   const UniquePtr<StyleBasicShape>& GetBasicShape() const
   {
     MOZ_ASSERT(mType == StyleShapeSourceType::Shape, "Wrong shape source type!");
     return mBasicShape;
   }
 
--- a/layout/style/test/file_shape_outside_CORS.html
+++ b/layout/style/test/file_shape_outside_CORS.html
@@ -28,16 +28,17 @@
 const DOMAIN = "http://mochi.test:8888";
 
 function sendResults() {
   let divAllow = document.getElementById("allow");
   let divAllowSib = divAllow.nextElementSibling;
   window.parent.postMessage({
     "result": (divAllowSib.getBoundingClientRect().left == divAllow.getBoundingClientRect().left),
     "message": "Test 1: Sibling is at same left offset as div (shape-outside was allowed).",
+    "todo": true,
     },
     DOMAIN);
 
   let divRefuse = document.getElementById("refuse");
   let divRefuseSib = divRefuse.nextElementSibling;
   window.parent.postMessage({
     "result": (divRefuseSib.getBoundingClientRect().left != divRefuse.getBoundingClientRect().left),
     "message": "Test 2: Sibling is at different left offset from div (shape-outside was refused).",
--- a/layout/svg/SVGObserverUtils.cpp
+++ b/layout/svg/SVGObserverUtils.cpp
@@ -418,17 +418,17 @@ nsSVGMaskProperty::ResolveImage(uint32_t
 
   if (!image.IsResolved()) {
     MOZ_ASSERT(image.GetType() == nsStyleImageType::eStyleImageType_Image);
     image.ResolveImage(mFrame->PresContext(), nullptr);
 
     mozilla::css::ImageLoader* imageLoader =
       mFrame->PresContext()->Document()->StyleImageLoader();
     if (imgRequestProxy* req = image.GetImageData()) {
-      imageLoader->AssociateRequestToFrame(req, mFrame, 0);
+      imageLoader->AssociateRequestToFrame(req, mFrame);
     }
   }
 }
 
 bool
 nsSVGTextPathProperty::TargetIsValid()
 {
   Element* target = GetTarget();
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -125722,64 +125722,16 @@
       [
        "/css/css-shapes/shape-outside/shape-image/gradients/reference/shape-outside-linear-gradient-004-ref.html",
        "=="
       ]
      ],
      {}
     ]
    ],
-   "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-005.html": [
-    [
-     "/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-005.html",
-     [
-      [
-       "/css/css-shapes/shape-outside/shape-image/gradients/reference/shape-outside-linear-gradient-001-ref.html",
-       "=="
-      ]
-     ],
-     {}
-    ]
-   ],
-   "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-006.html": [
-    [
-     "/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-006.html",
-     [
-      [
-       "/css/css-shapes/shape-outside/shape-image/gradients/reference/shape-outside-linear-gradient-001-ref.html",
-       "=="
-      ]
-     ],
-     {}
-    ]
-   ],
-   "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-007.html": [
-    [
-     "/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-007.html",
-     [
-      [
-       "/css/css-shapes/shape-outside/shape-image/gradients/reference/shape-outside-linear-gradient-001-ref.html",
-       "=="
-      ]
-     ],
-     {}
-    ]
-   ],
-   "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-008.html": [
-    [
-     "/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-008.html",
-     [
-      [
-       "/css/css-shapes/shape-outside/shape-image/gradients/reference/shape-outside-linear-gradient-001-ref.html",
-       "=="
-      ]
-     ],
-     {}
-    ]
-   ],
    "css/css-shapes/shape-outside/shape-image/shape-image-000.html": [
     [
      "/css/css-shapes/shape-outside/shape-image/shape-image-000.html",
      [
       [
        "/css/css-shapes/shape-outside/shape-image/reference/shape-image-000-ref.html",
        "=="
       ]
@@ -506905,46 +506857,30 @@
   "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-003.html": [
    "7338abdd6edb1027dc2e12b001773ce5ad114286",
    "reftest"
   ],
   "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-004.html": [
    "1e5377c120916557dc1525b38c9cf7eb86ae0151",
    "reftest"
   ],
-  "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-005.html": [
-   "dfbf4ad61f18ad05e243e58a2458b5b776ecf3fb",
-   "reftest"
-  ],
-  "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-006.html": [
-   "da35426f9ffc53101a053a61512c6928d140adff",
-   "reftest"
-  ],
-  "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-007.html": [
-   "03752707f61fbf16290b9733c280b79e00440b96",
-   "reftest"
-  ],
-  "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-008.html": [
-   "2ce6445aed0987c0ab7b83f614e9ceb8186fff7b",
-   "reftest"
-  ],
   "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-radial-gradient-001.html": [
    "b13df2df3be12ac74a7933794d91558c416b412c",
    "testharness"
   ],
   "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-radial-gradient-002.html": [
    "dbe8bd280e7f65fc5a1b43f4a211ca8e08a20d5e",
    "testharness"
   ],
   "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-radial-gradient-003.html": [
    "80fd9390054506c5e7bd8a6e60c1e6156dd604ec",
    "testharness"
   ],
   "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-radial-gradient-004.html": [
-   "fc47f277737dce4f7c6b08d0181355a810107c7b",
+   "67c3b8ea983da6b7d9b6b7e252b6415ebc7d1f9d",
    "testharness"
   ],
   "css/css-shapes/shape-outside/shape-image/reference/shape-image-000-ref.html": [
    "535d72bd77ac04e8e1accaa36edc6077baed17f3",
    "support"
   ],
   "css/css-shapes/shape-outside/shape-image/reference/shape-image-001-ref.html": [
    "5f5ed24372bdb45721dcb3befac0e5a0d3bb4091",
@@ -507006,33 +506942,33 @@
    "a58a3cc2988c71698edf5b36172b93fcae12b1ef",
    "support"
   ],
   "css/css-shapes/shape-outside/shape-image/shape-image-000.html": [
    "a650a83a5c0510138a0a26cd721c89e2fb2e5619",
    "reftest"
   ],
   "css/css-shapes/shape-outside/shape-image/shape-image-001.html": [
-   "f69cd2483ed81b496fb5d1c0024b6a16df7375b1",
+   "d97482f9149c68fff971e383ffb72f1371e898ef",
    "reftest"
   ],
   "css/css-shapes/shape-outside/shape-image/shape-image-002.html": [
-   "299635765004bd1cf9cff8a0888678a2331d7b19",
+   "1f3ace2827629f37439108e43f6528d8d728e5a2",
    "reftest"
   ],
   "css/css-shapes/shape-outside/shape-image/shape-image-003.html": [
    "f4ca43f0badb8cefa375cfcfdaa7a0098b2c0a2e",
    "reftest"
   ],
   "css/css-shapes/shape-outside/shape-image/shape-image-004.html": [
    "ed7ccc693f4f69921cc3b9b780adb55e1a10748c",
    "reftest"
   ],
   "css/css-shapes/shape-outside/shape-image/shape-image-005.html": [
-   "38883b770a73cc4eac3170a356b272edb6a5c483",
+   "274932a778268e3fda90b289e7f5ca22ee0f9adc",
    "reftest"
   ],
   "css/css-shapes/shape-outside/shape-image/shape-image-006.html": [
    "9185f8f5f09c24246aabc9f15aa24be96cdfcedd",
    "reftest"
   ],
   "css/css-shapes/shape-outside/shape-image/shape-image-007.html": [
    "c34f191a3c72a570e24f3fb95f679af70dc2ec69",
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-001.html.ini
@@ -0,0 +1,2 @@
+[shape-outside-linear-gradient-001.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-002.html.ini
@@ -0,0 +1,2 @@
+[shape-outside-linear-gradient-002.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-003.html.ini
@@ -0,0 +1,2 @@
+[shape-outside-linear-gradient-003.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-004.html.ini
@@ -0,0 +1,2 @@
+[shape-outside-linear-gradient-004.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-radial-gradient-001.html.ini
@@ -0,0 +1,4 @@
+[shape-outside-radial-gradient-001.html]
+  [CSS Test: Left float with radial gradient]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-000.html.ini
@@ -0,0 +1,2 @@
+[shape-image-000.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-001.html.ini
@@ -0,0 +1,2 @@
+[shape-image-001.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-002.html.ini
@@ -0,0 +1,2 @@
+[shape-image-002.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-003.html.ini
@@ -0,0 +1,2 @@
+[shape-image-003.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-004.html.ini
@@ -0,0 +1,2 @@
+[shape-image-004.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-005.html.ini
@@ -0,0 +1,2 @@
+[shape-image-005.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-012.html.ini
@@ -0,0 +1,2 @@
+[shape-image-012.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-013.html.ini
@@ -0,0 +1,2 @@
+[shape-image-013.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-014.html.ini
@@ -0,0 +1,2 @@
+[shape-image-014.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-015.html.ini
@@ -0,0 +1,2 @@
+[shape-image-015.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-016.html.ini
@@ -0,0 +1,2 @@
+[shape-image-016.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-017.html.ini
@@ -0,0 +1,2 @@
+[shape-image-017.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/shape-outside/shape-image/shape-image-025.html.ini
@@ -0,0 +1,2 @@
+[shape-image-025.html]
+  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/spec-examples/shape-outside-010.html.ini
@@ -0,0 +1,4 @@
+[shape-outside-010.html]
+  [CSS Test: Shape from image - url(), alpha channel, opacity 0]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/spec-examples/shape-outside-011.html.ini
@@ -0,0 +1,4 @@
+[shape-outside-011.html]
+  [CSS Test: Shape from image - url(), alpha channel, opacity > 0]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/css/css-shapes/spec-examples/shape-outside-012.html.ini
@@ -0,0 +1,4 @@
+[shape-outside-012.html]
+  [CSS Test: Shape from image - shape-image-threshold - 0.9]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-005.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <title>CSS Test: Test float with linear gradient under writing-mode: vertical-rl</title>
-    <link rel="author" title="Ting-Yu Lin" href="mailto:aethanyc@gmail.com"/>
-    <link rel="author" title="Mozilla" href="http://www.mozilla.org/">
-    <link rel="help" href="http://www.w3.org/TR/css-shapes-1/#shapes-from-image"/>
-    <link rel="help" href="http://www.w3.org/TR/css-shapes-1/#shape-outside-property"/>
-    <link rel="match" href="reference/shape-outside-linear-gradient-001-ref.html"/>
-    <meta name="flags" content="ahem"/>
-    <meta name="assert" content="This test verifies that shape-outside respects a simple linear gradient under vertical-rl."/>
-    <style type="text/css">
-    .container {
-      writing-mode: vertical-rl;
-      inline-size: 100px;
-      block-size: 200px;
-      background-color: red;
-      font-family: Ahem;
-      font-size: 50px;
-      line-height: 1;
-    }
-    #test {
-      color: green;
-    }
-    #float-left {
-      /* Note: In .container's writing-mode, "float: left" actually floats
-         us towards the top. */
-      float: left;
-      inline-size: 100px;
-      block-size: 200px;
-      background: linear-gradient(to bottom, green 50%, transparent 50%);
-      shape-outside: linear-gradient(to bottom, green 50%, transparent 50%);
-    }
-    #float-right {
-      /* Note: In .container's writing-mode, "float: right" actually floats
-         us towards the bottom. */
-      float: right;
-      inline-size: 100px;
-      block-size: 200px;
-      background: linear-gradient(to top, green 50%, transparent 50%);
-      shape-outside: linear-gradient(to top, green 50%, transparent 50%);
-    }
-    </style>
-  </head>
-  <body>
-    <p>
-      The test passes if you see a green square. There should be no red.
-    </p>
-    <div id="test" class="container">
-      <div id="float-left"></div>
-      x x x x
-    </div>
-    <div id="test" class="container" style="direction: rtl;">
-      <div id="float-right"></div>
-      x x x x
-    </div>
-  </body>
-</html>
deleted file mode 100644
--- a/testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-006.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <title>CSS Test: Test float with linear gradient under writing-mode: vertical-lr</title>
-    <link rel="author" title="Ting-Yu Lin" href="mailto:aethanyc@gmail.com"/>
-    <link rel="author" title="Mozilla" href="http://www.mozilla.org/">
-    <link rel="help" href="http://www.w3.org/TR/css-shapes-1/#shapes-from-image"/>
-    <link rel="help" href="http://www.w3.org/TR/css-shapes-1/#shape-outside-property"/>
-    <link rel="match" href="reference/shape-outside-linear-gradient-001-ref.html"/>
-    <meta name="flags" content="ahem"/>
-    <meta name="assert" content="This test verifies that shape-outside respects a simple linear gradient under vertical-lr."/>
-    <style type="text/css">
-    .container {
-      writing-mode: vertical-lr;
-      inline-size: 100px;
-      block-size: 200px;
-      background-color: red;
-      font-family: Ahem;
-      font-size: 50px;
-      line-height: 1;
-    }
-    #test {
-      color: green;
-    }
-    #float-left {
-      /* Note: In .container's writing-mode, "float: left" actually floats
-         us towards the top. */
-      float: left;
-      inline-size: 100px;
-      block-size: 200px;
-      background: linear-gradient(to bottom, green 50%, transparent 50%);
-      shape-outside: linear-gradient(to bottom, green 50%, transparent 50%);
-    }
-    #float-right {
-      /* Note: In .container's writing-mode, "float: right" actually floats
-         us towards the bottom. */
-      float: right;
-      inline-size: 100px;
-      block-size: 200px;
-      background: linear-gradient(to top, green 50%, transparent 50%);
-      shape-outside: linear-gradient(to top, green 50%, transparent 50%);
-    }
-    </style>
-  </head>
-  <body>
-    <p>
-      The test passes if you see a green square. There should be no red.
-    </p>
-    <div id="test" class="container">
-      <div id="float-left"></div>
-      x x x x
-    </div>
-    <div id="test" class="container" style="direction: rtl;">
-      <div id="float-right"></div>
-      x x x x
-    </div>
-  </body>
-</html>
deleted file mode 100644
--- a/testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-007.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <title>CSS Test: Test float with linear gradient under writing-mode: sideways-rl</title>
-    <link rel="author" title="Ting-Yu Lin" href="mailto:aethanyc@gmail.com"/>
-    <link rel="author" title="Mozilla" href="http://www.mozilla.org/">
-    <link rel="help" href="http://www.w3.org/TR/css-shapes-1/#shapes-from-image"/>
-    <link rel="help" href="http://www.w3.org/TR/css-shapes-1/#shape-outside-property"/>
-    <link rel="match" href="reference/shape-outside-linear-gradient-001-ref.html"/>
-    <meta name="flags" content="ahem"/>
-    <meta name="assert" content="This test verifies that shape-outside respects a simple linear gradient under sideways-rl."/>
-    <style type="text/css">
-    .container {
-      writing-mode: sideways-rl;
-      inline-size: 100px;
-      block-size: 200px;
-      background-color: red;
-      font-family: Ahem;
-      font-size: 50px;
-      line-height: 1;
-    }
-    #test {
-      color: green;
-    }
-    #float-left {
-      /* Note: In .container's writing-mode, "float: left" actually floats
-         us towards the top. */
-      float: left;
-      inline-size: 100px;
-      block-size: 200px;
-      background: linear-gradient(to bottom, green 50%, transparent 50%);
-      shape-outside: linear-gradient(to bottom, green 50%, transparent 50%);
-    }
-    #float-right {
-      /* Note: In .container's writing-mode, "float: right" actually floats
-         us towards the bottom. */
-      float: right;
-      inline-size: 100px;
-      block-size: 200px;
-      background: linear-gradient(to top, green 50%, transparent 50%);
-      shape-outside: linear-gradient(to top, green 50%, transparent 50%);
-    }
-    </style>
-  </head>
-  <body>
-    <p>
-      The test passes if you see a green square. There should be no red.
-    </p>
-    <div id="test" class="container">
-      <div id="float-left"></div>
-      x x x x
-    </div>
-    <div id="test" class="container" style="direction: rtl;">
-      <div id="float-right"></div>
-      x x x x
-    </div>
-  </body>
-</html>
deleted file mode 100644
--- a/testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-008.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <title>CSS Test: Test float with linear gradient under writing-mode: sideways-lr</title>
-    <link rel="author" title="Ting-Yu Lin" href="mailto:aethanyc@gmail.com"/>
-    <link rel="author" title="Mozilla" href="http://www.mozilla.org/">
-    <link rel="help" href="http://www.w3.org/TR/css-shapes-1/#shapes-from-image"/>
-    <link rel="help" href="http://www.w3.org/TR/css-shapes-1/#shape-outside-property"/>
-    <link rel="match" href="reference/shape-outside-linear-gradient-001-ref.html"/>
-    <meta name="flags" content="ahem"/>
-    <meta name="assert" content="This test verifies that shape-outside respects a simple linear gradient under sideways-lr."/>
-    <style type="text/css">
-    .container {
-      writing-mode: sideways-lr;
-      inline-size: 100px;
-      block-size: 200px;
-      background-color: red;
-      font-family: Ahem;
-      font-size: 50px;
-      line-height: 1;
-    }
-    #test {
-      color: green;
-    }
-    #float-left {
-      /* Note: In .container's writing-mode, "float: left" actually floats
-         us towards the bottom. */
-      float: left;
-      inline-size: 100px;
-      block-size: 200px;
-      background: linear-gradient(to top, green 50%, transparent 50%);
-      shape-outside: linear-gradient(to top, green 50%, transparent 50%);
-    }
-    #float-right {
-      /* Note: In .container's writing-mode, "float: right" actually floats
-         us towards the top. */
-      float: right;
-      inline-size: 100px;
-      block-size: 200px;
-      background: linear-gradient(to bottom, green 50%, transparent 50%);
-      shape-outside: linear-gradient(to bottom, green 50%, transparent 50%);
-    }
-    </style>
-  </head>
-  <body>
-    <p>
-      The test passes if you see a green square. There should be no red.
-    </p>
-    <div id="test" class="container">
-      <div id="float-left"></div>
-      x x x x
-    </div>
-    <div id="test" class="container" style="direction: rtl;">
-      <div id="float-right"></div>
-      x x x x
-    </div>
-  </body>
-</html>
--- a/testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/shape-image-001.html
+++ b/testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/shape-image-001.html
@@ -17,17 +17,17 @@
         }
         #test {
             width: 150px;
             color: rgb(0, 100, 0);
             background-color: black;
         }
         #image {
             float: left;
-            width: 100px;
+            width: 150px;
             height: 100px;
             shape-outside: url("support/left-half-rectangle-70.png");
         }
         #failure {
             width: 50px;
             height: 100px;
             background-color: red;
             position: absolute;
--- a/testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/shape-image-002.html
+++ b/testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/shape-image-002.html
@@ -17,23 +17,23 @@
         }
         #test {
             width: 100px;
             color: rgb(0, 100, 0);
             background-color: red;
         }
         #image {
             float: left;
-            shape-outside: url('data:image/svg+xml;utf8,<svg width="100px" height="100px" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="%23006400" d=" M 0.00 0.00 L 50.00 0.00 C 50.00 33.33 50.00 66.67 50.00 100.00 L 0.00 100.00 L 0.00 0.00 Z" /></svg>');
+            shape-outside: url('data:image/svg+xml;utf8,<svg width="100px" height="100px" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#006400" d=" M 0.00 0.00 L 50.00 0.00 C 50.00 33.33 50.00 66.67 50.00 100.00 L 0.00 100.00 L 0.00 0.00 Z" /></svg>');
         }
     </style>
 </head>
 <body>
     <p>
         The test passes if you see a solid green square. There should be no red.
     </p>
     <div id="test" class="container">
-        <img id="image" src='data:image/svg+xml;utf8,<svg width="100px" height="100px" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="%23006400" d=" M 0.00 0.00 L 50.00 0.00 C 50.00 33.33 50.00 66.67 50.00 100.00 L 0.00 100.00 L 0.00 0.00 Z" /></svg>'/>
+        <img id="image" src='data:image/svg+xml;utf8,<svg width="100px" height="100px" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#006400" d=" M 0.00 0.00 L 50.00 0.00 C 50.00 33.33 50.00 66.67 50.00 100.00 L 0.00 100.00 L 0.00 0.00 Z" /></svg>'/>
         X
         X
     </div>
 </body>
 </html>
--- a/testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/shape-image-005.html
+++ b/testing/web-platform/tests/css/css-shapes/shape-outside/shape-image/shape-image-005.html
@@ -17,24 +17,24 @@
         }
         #test {
             width: 100px;
             color: rgb(0, 100, 0);
             background-color: red;
         }
         #image {
             float: left;
-            shape-outside: url('data:image/svg+xml;utf8,<svg width="100px" height="100px" style="background-color: rgba(0,0,0,0.7)" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="%23006400" d=" M 0.00 0.00 L 50.00 0.00 C 50.00 33.33 50.00 66.67 50.00 100.00 L 0.00 100.00 L 0.00 0.00 Z" /></svg>');
+            shape-outside: url('data:image/svg+xml;utf8,<svg width="100px" height="100px" style="background-color: rgba(0,0,0,0.7)" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#006400" d=" M 0.00 0.00 L 50.00 0.00 C 50.00 33.33 50.00 66.67 50.00 100.00 L 0.00 100.00 L 0.00 0.00 Z" /></svg>');
             shape-image-threshold: 0.8;
         }
     </style>
 </head>
 <body>
     <p>
         The test passes if you see a solid green square. There should be no red.
     </p>
     <div id="test" class="container">
-        <img id="image" src='data:image/svg+xml;utf8,<svg width="100px" height="100px" style="background-color: rgba(0,0,0,0.7)" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="%23006400" d=" M 0.00 0.00 L 50.00 0.00 C 50.00 33.33 50.00 66.67 50.00 100.00 L 0.00 100.00 L 0.00 0.00 Z" /></svg>'/>
+        <img id="image" src='data:image/svg+xml;utf8,<svg width="100px" height="100px" style="background-color: rgba(0,0,0,0.7)" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#006400" d=" M 0.00 0.00 L 50.00 0.00 C 50.00 33.33 50.00 66.67 50.00 100.00 L 0.00 100.00 L 0.00 0.00 Z" /></svg>'/>
         X
         X
     </div>
 </body>
 </html>
index 9e424df7cdfb6b228b18297334fba7cabdb270cd..083c9a0a23df0815fe593540ea487ef36119ef4f
GIT binary patch
literal 1816
zc${<hbhEHbOkqf2n8?KN|Nnm=14J?~DE{Y;@C{IKNi0bO(l+)L1&PVosU-?Ysp*+{
zwo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&Psj#ZZEyztRNmQuF
z&B-gas<2f`Ovz75wF0t1!um=IU?nBlwn~m52?day&iO^D3Z{C-y2%EHh6-k8dWI&Z
zW@d&u3PuKoM*0RoWTtCqVr6P(Wn``Z1xi5Mic-?7f?V97b^&>|N*N_31y=g{<>lpi
z<;HsXMd|v6mX?+vGmMOMfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZ_=!pRr6smX
zN-!_v7Ql_oE7k*hM=v=)SHB{$K;KZ$Kp#n=uP=V3xw&xF#U(+hY4}wahg24%>IbD3
z=a&{GrvjBLgESXdITxiSmgE<O<mczWLNOpCza+mnBfmhwIoM1=!#6QGGY=%73D)83
zYvq|&T#}fVoa*Ufs{|C$%gju%ax%6wbTcqEakg-=G&FQIb}}+DbF*+YGPkfWbvCxJ
zgz0t3PcF?(%`1WFO+n~2#i<vR7$CY+i!#enQ{0O3a}~gzw#vlq79-qlf#^-a?G|I4
zdi8;h(MOAFm=G}ifSB-v3*^9)erg^ty%zx!Hsk+)fB*dc_4CK~Z(qNB{`B#~`*&~O
zyngla#q(!RpFDo_@WK6ickkT3b@RscYgeyazI5@z`EzH_oIZ8(#PMTCj~qU9@WB3k
zd-v?#wR6YzZCkf&-n4PU`gLp9tX{Qp#qwoKmn>eiaKZd}bLY&SHFL)FX;Y_6o-}bn
ze_wA;cUNaeds}Nub5mnOeO+x$bya0Wd0A;maZzDGeqL@)c2;IadRl5qa#CVKd|Yfy
zbW~(Scvxsia8O`?zn`y<x0k1fyPK<vvy-EPy`8O%wUwoXxtXbnv5}#HzMig*ww9)b
zx|*trvXY{Lyqv6zw3MWTxR|Jju#lhtKOZj-Hy0-dI~ywtGZQ1Qboj}_DagRYpaU!^
z7(k^51JnPW{*|ZaGA*97<(Bo_domCC+k)Ju^>-{=e6s9S_qI)J*YEe}e~Wwi?;y8Z
zo&CZIFO1nHTB`PU7Qb6yys}qo^R*4Sx;>{q?K_~hu`9-C`305Ip0kDB4+<?i_HDfX
zk?(Ks{Ri!g5*itfClV?;RxG%2xZ=?cCQcPgPsxNz&y|)fnHM-ea!OgvinNl_N?3KO
z>(|X$zq%y3txs2SM|#gby`%f~ODP@eoai&vJZm)f_}t0)(<8Gs=VZ*=8s53Odwq2?
z|MtqRvppC4?k&eWy?uW7^8WR$TVZ!T?tLBqeEocn`}zO*;~i?5e{y~*7f5hw<mNOp
zdBL9O(kd(&R#G9jNUl>{TC;4+55Z)Q-ZG16Un+!Bye4XUp3;Pbl|E`%t(yW2tGE21
zu<G7?Z_jW3wnrY*o^>vJb!yu??&F_)u7B%&{_EWLfBZaL?MD`U?C{Z=erDNc&R(zO
zS5|%PI-9lq&bsg1eBH;NZ2FnQyyE(sZNGW@Pe1>%>u=xr*Wdr_`_C_-Vc`*xQPDAD
z#f}p<Ui{#Y)U@=B%&hF3xpL>pn=gNIN@-bnMP*fW&04kV)U8*)xTLkMy`!_MyJxT7
zefsw6-`p}fHa;;qH9d3I>{$~D_5!O2su%81(F@#AFKoa3Y1iL<%N~FKQ?r(T$8vEG
z4)chP7w(f!tgyIzqk=<H!}4Z$rsj|7o*gGMpa0Yp*UH)vxoT&}tY162++V%Y5UytT
z&X(?ey=wQV?pM)VI$D1`&t%T&%vou3lINvNrI$4O*@(Fny)$BW+|{)Gd(HPJubq3G
co^*5Gs$F^a-p%6^{(sMFy&7LeFav`%03QwP^8f$<