Bug 1275957 - Part 1. Apply space property to gradient. r=mstange
authorEthan Lin <ethlin@mozilla.com>
Thu, 02 Jun 2016 02:09:00 +0200
changeset 339160 f795d90a2debcabf78d6cce0d446990e08bd0ba6
parent 339159 d048e177ab2685617f4cadad190314c2452d324e
child 339161 f4fd6197c80aecef9e38887f4407956c7c667383
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1275957
milestone49.0a1
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
Bug 1275957 - Part 1. Apply space property to gradient. r=mstange
layout/base/nsCSSRendering.cpp
layout/base/nsCSSRendering.h
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -2489,16 +2489,17 @@ ResolvePremultipliedAlpha(nsTArray<Color
 
 void
 nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
                               nsRenderingContext& aRenderingContext,
                               nsStyleGradient* aGradient,
                               const nsRect& aDirtyRect,
                               const nsRect& aDest,
                               const nsRect& aFillArea,
+                              const nsSize& aRepeatSize,
                               const CSSIntRect& aSrc,
                               const nsSize& aIntrinsicSize)
 {
   PROFILER_LABEL("nsCSSRendering", "PaintGradient",
     js::ProfileEntry::Category::GRAPHICS);
 
   Telemetry::AutoTimer<Telemetry::GRADIENT_DURATION, Telemetry::Microsecond> gradientTimer;
   if (aDest.IsEmpty() || aFillArea.IsEmpty()) {
@@ -2824,24 +2825,24 @@ nsCSSRendering::PaintGradient(nsPresCont
     nsLayoutUtils::RectToGfxRect(aFillArea, appUnitsPerDevPixel);
   gfxRect dirtyAreaToFill = nsLayoutUtils::RectToGfxRect(dirty, appUnitsPerDevPixel);
   dirtyAreaToFill.RoundOut();
 
   gfxMatrix ctm = ctx->CurrentMatrix();
   bool isCTMPreservingAxisAlignedRectangles = ctm.PreservesAxisAlignedRectangles();
 
   // xStart/yStart are the top-left corner of the top-left tile.
-  nscoord xStart = FindTileStart(dirty.x, aDest.x, aDest.width);
-  nscoord yStart = FindTileStart(dirty.y, aDest.y, aDest.height);
+  nscoord xStart = FindTileStart(dirty.x, aDest.x, aRepeatSize.width);
+  nscoord yStart = FindTileStart(dirty.y, aDest.y, aRepeatSize.height);
   nscoord xEnd = forceRepeatToCoverTiles ? xStart + aDest.width : dirty.XMost();
   nscoord yEnd = forceRepeatToCoverTiles ? yStart + aDest.height : dirty.YMost();
 
   // x and y are the top-left corner of the tile to draw
-  for (nscoord y = yStart; y < yEnd; y += aDest.height) {
-    for (nscoord x = xStart; x < xEnd; x += aDest.width) {
+  for (nscoord y = yStart; y < yEnd; y += aRepeatSize.height) {
+    for (nscoord x = xStart; x < xEnd; x += aRepeatSize.width) {
       // The coordinates of the tile
       gfxRect tileRect = nsLayoutUtils::RectToGfxRect(
                       nsRect(x, y, aDest.width, aDest.height),
                       appUnitsPerDevPixel);
       // The actual area to fill with this tile is the intersection of this
       // tile with the overall area we're supposed to be filling
       gfxRect fillRect =
         forceRepeatToCoverTiles ? areaToFill : tileRect.Intersect(areaToFill);
@@ -5280,17 +5281,17 @@ nsImageRenderer::Draw(nsPresContext*    
                                            ConvertImageRendererToDrawFlags(mFlags),
                                            mExtendMode);
       break;
     }
     case eStyleImageType_Gradient:
     {
       nsCSSRendering::PaintGradient(aPresContext, aRenderingContext,
                                     mGradientData, aDirtyRect,
-                                    aDest, aFill, aSrc, mSize);
+                                    aDest, aFill, aRepeatSize, aSrc, mSize);
       break;
     }
     case eStyleImageType_Element:
     {
       RefPtr<gfxDrawable> drawable = DrawableForElement(aDest,
                                                           aRenderingContext);
       if (!drawable) {
         NS_WARNING("Could not create drawable for element");
@@ -5545,17 +5546,17 @@ nsImageRenderer::DrawBorderImageComponen
                                     drawFlags);
   }
 
   nsRect destTile = RequiresScaling(aFill, aHFill, aVFill, aUnitSize)
                   ? ComputeTile(aFill, aHFill, aVFill, aUnitSize)
                   : aFill;
 
   return Draw(aPresContext, aRenderingContext, aDirtyRect, destTile,
-              aFill, destTile.TopLeft(), nsSize(0, 0), aSrc);
+              aFill, destTile.TopLeft(), destTile.Size(), aSrc);
 }
 
 bool
 nsImageRenderer::IsRasterImage()
 {
   if (mType != eStyleImageType_Image || !mImageContainer)
     return false;
   return mImageContainer->GetType() == imgIContainer::TYPE_RASTER;
--- a/layout/base/nsCSSRendering.h
+++ b/layout/base/nsCSSRendering.h
@@ -445,16 +445,17 @@ struct nsCSSRendering {
    * aIntrinsicSize is the size of the source gradient.
    */
   static void PaintGradient(nsPresContext* aPresContext,
                             nsRenderingContext& aRenderingContext,
                             nsStyleGradient* aGradient,
                             const nsRect& aDirtyRect,
                             const nsRect& aDest,
                             const nsRect& aFill,
+                            const nsSize& aRepeatSize,
                             const mozilla::CSSIntRect& aSrc,
                             const nsSize& aIntrinsiceSize);
 
   /**
    * Find the frame whose background style should be used to draw the
    * canvas background. aForFrame must be the frame for the root element
    * whose background style should be used. This function will return
    * aForFrame unless the <body> background should be propagated, in
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2529,17 +2529,18 @@ bool
 nsStyleImageLayers::Layer::RenderingMightDependOnPositioningAreaSizeChange() const
 {
   // Do we even have an image?
   if (mImage.IsEmpty()) {
     return false;
   }
 
   return mPosition.DependsOnPositioningAreaSize() ||
-      mSize.DependsOnPositioningAreaSize(mImage);
+      mSize.DependsOnPositioningAreaSize(mImage) ||
+      mRepeat.DependsOnPositioningAreaSize();
 }
 
 bool
 nsStyleImageLayers::Layer::operator==(const Layer& aOther) const
 {
   return mAttachment == aOther.mAttachment &&
          mClip == aOther.mClip &&
          mOrigin == aOther.mOrigin &&
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -598,16 +598,21 @@ struct nsStyleImageLayers {
     // Initialize nothing
     Repeat() {}
 
     bool IsInitialValue() const {
       return mXRepeat == NS_STYLE_IMAGELAYER_REPEAT_REPEAT &&
              mYRepeat == NS_STYLE_IMAGELAYER_REPEAT_REPEAT;
     }
 
+    bool DependsOnPositioningAreaSize() const {
+      return mXRepeat == NS_STYLE_IMAGELAYER_REPEAT_SPACE ||
+             mYRepeat == NS_STYLE_IMAGELAYER_REPEAT_SPACE;
+    }
+
     // Initialize to initial values
     void SetInitialValues();
 
     bool operator==(const Repeat& aOther) const {
       return mXRepeat == aOther.mXRepeat &&
              mYRepeat == aOther.mYRepeat;
     }
     bool operator!=(const Repeat& aOther) const {