--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -104,26 +104,24 @@ public:
PRBool PrepareImage();
/**
* @return the image size in appunits. CSS gradient images don't have an
* intrinsic size so we have to pass in a default that they will use.
*/
nsSize ComputeSize(const nsSize& aDefault);
/**
* Draws the image to the target rendering context.
- * @param aRepeat indicates whether the image is to be repeated (tiled)
* @see nsLayoutUtils::DrawImage() for other parameters
*/
void Draw(nsPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDest,
const nsRect& aFill,
const nsPoint& aAnchor,
- const nsRect& aDirty,
- PRBool aRepeat);
+ const nsRect& aDirty);
private:
nsIFrame* mForFrame;
nsStyleImage mImage;
nsStyleImageType mType;
nsCOMPtr<imgIContainer> mImageContainer;
nsRefPtr<nsStyleGradient> mGradientData;
PRBool mIsReady;
@@ -1597,92 +1595,466 @@ nsCSSRendering::DetermineBackgroundColor
aBackground,
aFrame,
drawBackgroundImage,
drawBackgroundColor);
}
static gfxFloat
ConvertGradientValueToPixels(const nsStyleCoord& aCoord,
- nscoord aFillLength,
- nscoord aAppUnitsPerPixel)
+ gfxFloat aFillLength,
+ PRInt32 aAppUnitsPerPixel)
{
switch (aCoord.GetUnit()) {
case eStyleUnit_Percent:
- return aCoord.GetPercentValue() * aFillLength / aAppUnitsPerPixel;
+ return aCoord.GetPercentValue() * aFillLength;
case eStyleUnit_Coord:
- return aCoord.GetCoordValue() / aAppUnitsPerPixel;
+ return NSAppUnitsToFloatPixels(aCoord.GetCoordValue(), aAppUnitsPerPixel);
default:
NS_WARNING("Unexpected coord unit");
return 0;
}
}
+// Given a box with size aBoxSize and origin (0,0), and an angle aAngle,
+// and a starting point for the gradient line aStart, find the endpoint of
+// the gradient line --- the intersection of the gradient line with a line
+// perpendicular to aAngle that passes through the farthest corner in the
+// direction aAngle.
+static gfxPoint
+ComputeGradientLineEndFromAngle(const gfxPoint& aStart,
+ double aAngle,
+ const gfxSize& aBoxSize)
+{
+ double dx = cos(-aAngle);
+ double dy = sin(-aAngle);
+ gfxPoint farthestCorner(dx > 0 ? aBoxSize.width : 0,
+ dy > 0 ? aBoxSize.height : 0);
+ gfxPoint delta = farthestCorner - aStart;
+ double u = delta.x*dy - delta.y*dx;
+ return farthestCorner + gfxPoint(-u*dy, u*dx);
+}
+
+// Compute the start and end points of the gradient line for a linear gradient.
+static void
+ComputeLinearGradientLine(nsPresContext* aPresContext,
+ nsStyleGradient* aGradient,
+ const gfxSize& aBoxSize,
+ gfxPoint* aLineStart,
+ gfxPoint* aLineEnd)
+{
+ if (aGradient->mBgPosX.GetUnit() == eStyleUnit_None) {
+ double angle;
+ if (aGradient->mAngle.IsAngleValue()) {
+ angle = aGradient->mAngle.GetAngleValueInRadians();
+ } else {
+ angle = -M_PI_2; // defaults to vertical gradient starting from top
+ }
+ gfxPoint center(aBoxSize.width/2, aBoxSize.height/2);
+ *aLineEnd = ComputeGradientLineEndFromAngle(center, angle, aBoxSize);
+ *aLineStart = gfxPoint(aBoxSize.width, aBoxSize.height) - *aLineEnd;
+ } else {
+ PRInt32 appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
+ *aLineStart = gfxPoint(
+ ConvertGradientValueToPixels(aGradient->mBgPosX, aBoxSize.width,
+ appUnitsPerPixel),
+ ConvertGradientValueToPixels(aGradient->mBgPosY, aBoxSize.height,
+ appUnitsPerPixel));
+ if (aGradient->mAngle.IsAngleValue()) {
+ double angle = aGradient->mAngle.GetAngleValueInRadians();
+ *aLineEnd = ComputeGradientLineEndFromAngle(*aLineStart, angle, aBoxSize);
+ } else {
+ // No angle, the line end is just the reflection of the start point
+ // through the center of the box
+ *aLineEnd = gfxPoint(aBoxSize.width, aBoxSize.height) - *aLineStart;
+ }
+ }
+}
+
+// Compute the start and end points of the gradient line for a radial gradient.
+// Also returns the horizontal and vertical radii defining the circle or
+// ellipse to use.
+static void
+ComputeRadialGradientLine(nsPresContext* aPresContext,
+ nsStyleGradient* aGradient,
+ const gfxSize& aBoxSize,
+ gfxPoint* aLineStart,
+ gfxPoint* aLineEnd,
+ double* aRadiusX,
+ double* aRadiusY)
+{
+ if (aGradient->mBgPosX.GetUnit() == eStyleUnit_None) {
+ // Default line start point is the center of the box
+ *aLineStart = gfxPoint(aBoxSize.width/2, aBoxSize.height/2);
+ } else {
+ PRInt32 appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
+ *aLineStart = gfxPoint(
+ ConvertGradientValueToPixels(aGradient->mBgPosX, aBoxSize.width,
+ appUnitsPerPixel),
+ ConvertGradientValueToPixels(aGradient->mBgPosY, aBoxSize.height,
+ appUnitsPerPixel));
+ }
+
+ // Compute gradient shape: the x and y radii of an ellipse.
+ double radiusX, radiusY;
+ double leftDistance = PR_ABS(aLineStart->x);
+ double rightDistance = PR_ABS(aBoxSize.width - aLineStart->x);
+ double topDistance = PR_ABS(aLineStart->y);
+ double bottomDistance = PR_ABS(aBoxSize.height - aLineStart->y);
+ switch (aGradient->mSize) {
+ case NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE:
+ radiusX = NS_MIN(leftDistance, rightDistance);
+ radiusY = NS_MIN(topDistance, bottomDistance);
+ if (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_CIRCULAR) {
+ radiusX = radiusY = NS_MIN(radiusX, radiusY);
+ }
+ break;
+ case NS_STYLE_GRADIENT_SIZE_CLOSEST_CORNER: {
+ // Compute x and y distances to nearest corner
+ double offsetX = NS_MIN(leftDistance, rightDistance);
+ double offsetY = NS_MIN(topDistance, bottomDistance);
+ if (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_CIRCULAR) {
+ radiusX = radiusY = NS_hypot(offsetX, offsetY);
+ } else {
+ // maintain aspect ratio
+ radiusX = offsetX*M_SQRT2;
+ radiusY = offsetY*M_SQRT2;
+ }
+ break;
+ }
+ case NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE:
+ radiusX = NS_MAX(leftDistance, rightDistance);
+ radiusY = NS_MAX(topDistance, bottomDistance);
+ if (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_CIRCULAR) {
+ radiusX = radiusY = NS_MAX(radiusX, radiusY);
+ }
+ break;
+ case NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER: {
+ // Compute x and y distances to nearest corner
+ double offsetX = NS_MAX(leftDistance, rightDistance);
+ double offsetY = NS_MAX(topDistance, bottomDistance);
+ if (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_CIRCULAR) {
+ radiusX = radiusY = NS_hypot(offsetX, offsetY);
+ } else {
+ // maintain aspect ratio
+ radiusX = offsetX*M_SQRT2;
+ radiusY = offsetY*M_SQRT2;
+ }
+ break;
+ }
+ default:
+ NS_ABORT_IF_FALSE(PR_FALSE, "unknown radial gradient sizing method");
+ }
+ *aRadiusX = radiusX;
+ *aRadiusY = radiusY;
+
+ double angle;
+ if (aGradient->mAngle.IsAngleValue()) {
+ angle = aGradient->mAngle.GetAngleValueInRadians();
+ } else {
+ // Default angle is 0deg
+ angle = 0.0;
+ }
+
+ // The gradient line end point is where the gradient line intersects
+ // the ellipse.
+ *aLineEnd = *aLineStart + gfxPoint(radiusX*cos(-angle), radiusY*sin(-angle));
+}
+
+// A resolved color stop --- with a specific position along the gradient line,
+// and a Thebes color
+struct ColorStop {
+ ColorStop(double aPosition, nscolor aColor) :
+ mPosition(aPosition), mColor(aColor) {}
+ double mPosition; // along the gradient line; 0=start, 1=end
+ gfxRGBA mColor;
+};
+
+// Returns aFrac*aC2 + (1 - aFrac)*C1. The interpolation is done
+// in unpremultiplied space, which is what SVG gradients and cairo
+// gradients expect.
+static gfxRGBA
+InterpolateColor(const gfxRGBA& aC1, const gfxRGBA& aC2, double aFrac)
+{
+ double other = 1 - aFrac;
+ return gfxRGBA(aC2.r*aFrac + aC1.r*other,
+ aC2.g*aFrac + aC1.g*other,
+ aC2.b*aFrac + aC1.b*other,
+ aC2.a*aFrac + aC1.a*other);
+}
+
void
nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsStyleGradient* aGradient,
const nsRect& aDirtyRect,
const nsRect& aOneCellArea,
- const nsRect& aFillArea,
- PRBool aRepeat)
+ const nsRect& aFillArea)
{
-#if 0
+ if (aOneCellArea.IsEmpty())
+ return;
+
gfxContext *ctx = aRenderingContext.ThebesContext();
nscoord appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
-
- gfxRect dirtyRect = RectToGfxRect(aDirtyRect, appUnitsPerPixel);
- gfxRect areaToFill = RectToGfxRect(aFillArea, appUnitsPerPixel);
gfxRect oneCellArea = RectToGfxRect(aOneCellArea, appUnitsPerPixel);
- gfxPoint fillOrigin = oneCellArea.TopLeft();
-
- areaToFill = areaToFill.Intersect(dirtyRect);
- if (areaToFill.IsEmpty())
- return;
-
- gfxFloat gradX0 = ConvertGradientValueToPixels(aGradient->mStartX,
- aOneCellArea.width, appUnitsPerPixel);
- gfxFloat gradY0 = ConvertGradientValueToPixels(aGradient->mStartY,
- aOneCellArea.height, appUnitsPerPixel);
- gfxFloat gradX1 = ConvertGradientValueToPixels(aGradient->mEndX,
- aOneCellArea.width, appUnitsPerPixel);
- gfxFloat gradY1 = ConvertGradientValueToPixels(aGradient->mEndY,
- aOneCellArea.height, appUnitsPerPixel);
-
+
+ // Compute "gradient line" start and end relative to oneCellArea
+ gfxPoint lineStart, lineEnd;
+ double radiusX = 0, radiusY = 0; // for radial gradients only
+ if (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_LINEAR) {
+ ComputeLinearGradientLine(aPresContext, aGradient, oneCellArea.size,
+ &lineStart, &lineEnd);
+ } else {
+ ComputeRadialGradientLine(aPresContext, aGradient, oneCellArea.size,
+ &lineStart, &lineEnd, &radiusX, &radiusY);
+ }
+ gfxFloat lineLength = NS_hypot(lineEnd.x - lineStart.x,
+ lineEnd.y - lineStart.y);
+
+ NS_ABORT_IF_FALSE(aGradient->mStops.Length() >= 2,
+ "The parser should reject gradients with less than two stops");
+
+ // Build color stop array and compute stop positions
+ nsTArray<ColorStop> stops;
+ // If there is a run of stops before stop i that did not have specified
+ // positions, then this is the index of the first stop in that run, otherwise
+ // it's -1.
+ PRInt32 firstUnsetPosition = -1;
+ for (PRUint32 i = 0; i < aGradient->mStops.Length(); ++i) {
+ const nsStyleGradientStop& stop = aGradient->mStops[i];
+ double position;
+ switch (stop.mLocation.GetUnit()) {
+ case eStyleUnit_None:
+ if (i == 0) {
+ // First stop defaults to position 0.0
+ position = 0.0;
+ } else if (i == aGradient->mStops.Length() - 1) {
+ // Last stop defaults to position 1.0
+ position = 1.0;
+ } else {
+ // Other stops with no specified position get their position assigned
+ // later by interpolation, see below.
+ // Remeber where the run of stops with no specified position starts,
+ // if it starts here.
+ if (firstUnsetPosition < 0) {
+ firstUnsetPosition = i;
+ }
+ stops.AppendElement(ColorStop(0, stop.mColor));
+ continue;
+ }
+ break;
+ case eStyleUnit_Percent:
+ position = stop.mLocation.GetPercentValue();
+ break;
+ case eStyleUnit_Coord:
+ position = lineLength < 1e-6 ? 0.0 :
+ stop.mLocation.GetCoordValue() / appUnitsPerPixel / lineLength;
+ break;
+ default:
+ NS_ABORT_IF_FALSE(PR_FALSE, "Unknown stop position type");
+ }
+
+ if (i > 0) {
+ // Prevent decreasing stop positions by advancing this position
+ // to the previous stop position, if necessary
+ position = NS_MAX(position, stops[i - 1].mPosition);
+ }
+ stops.AppendElement(ColorStop(position, stop.mColor));
+ if (firstUnsetPosition > 0) {
+ // Interpolate positions for all stops that didn't have a specified position
+ double p = stops[firstUnsetPosition - 1].mPosition;
+ double d = (stops[i].mPosition - p)/(i - firstUnsetPosition + 1);
+ for (PRUint32 j = firstUnsetPosition; j < i; ++j) {
+ p += d;
+ stops[j].mPosition = p;
+ }
+ firstUnsetPosition = -1;
+ }
+ }
+
+ // Eliminate negative-position stops if the gradient is radial.
+ double firstStop = stops[0].mPosition;
+ if (aGradient->mShape != NS_STYLE_GRADIENT_SHAPE_LINEAR && firstStop < 0.0) {
+ if (aGradient->mRepeating) {
+ // Choose an instance of the repeated pattern that gives us all positive
+ // stop-offsets.
+ double lastStop = stops[stops.Length() - 1].mPosition;
+ double stopDelta = lastStop - firstStop;
+ // If all the stops are in approximately the same place then logic below
+ // will kick in that makes us draw just the last stop color, so don't
+ // try to do anything in that case. We certainly need to avoid
+ // dividing by zero.
+ if (stopDelta >= 1e-6) {
+ double instanceCount = NS_ceil(-firstStop/stopDelta);
+ // Advance stops by instanceCount multiples of the period of the
+ // repeating gradient.
+ double offset = instanceCount*stopDelta;
+ for (PRUint32 i = 0; i < stops.Length(); i++) {
+ stops[i].mPosition += offset;
+ }
+ }
+ } else {
+ // Move negative-position stops to position 0.0. We may also need
+ // to set the color of the stop to the color the gradient should have
+ // at the center of the ellipse.
+ for (PRUint32 i = 0; i < stops.Length(); i++) {
+ double pos = stops[i].mPosition;
+ if (pos < 0.0) {
+ stops[i].mPosition = 0.0;
+ // If this is the last stop, we don't need to adjust the color,
+ // it will fill the entire area.
+ if (i < stops.Length() - 1) {
+ double nextPos = stops[i + 1].mPosition;
+ // If nextPos is approximately equal to pos, then we don't
+ // need to adjust the color of this stop because it's
+ // not going to be displayed.
+ // If nextPos is negative, we don't need to adjust the color of
+ // this stop since it's not going to be displayed because
+ // nextPos will also be moved to 0.0.
+ if (nextPos >= 0.0 && nextPos - pos >= 1e-6) {
+ // Compute how far the new position 0.0 is along the interval
+ // between pos and nextPos.
+ // XXX Color interpolation (in cairo, too) should use the
+ // CSS 'color-interpolation' property!
+ double frac = (0.0 - pos)/(nextPos - pos);
+ stops[i].mColor =
+ InterpolateColor(stops[i].mColor, stops[i + 1].mColor, frac);
+ }
+ }
+ }
+ }
+ }
+ firstStop = stops[0].mPosition;
+ NS_ABORT_IF_FALSE(firstStop >= 0.0, "Failed to fix stop offsets");
+ }
+
+ double lastStop = stops[stops.Length() - 1].mPosition;
+ // Cairo gradients must have stop positions in the range [0, 1]. So,
+ // stop positions will be normalized below by subtracting firstStop and then
+ // multiplying by stopScale.
+ double stopScale;
+ double stopDelta = lastStop - firstStop;
+ if (stopDelta < 1e-6 || lineLength < 1e-6 ||
+ (aGradient->mShape != NS_STYLE_GRADIENT_SHAPE_LINEAR &&
+ (radiusX < 1e-6 || radiusY < 1e-6))) {
+ // Stops are all at the same place. Map all stops to 0.0.
+ // For radial gradients we need to fill with the last stop color,
+ // so just set both radii to 0.
+ stopScale = 0.0;
+ radiusX = radiusY = 0.0;
+ lastStop = firstStop;
+ } else {
+ stopScale = 1.0/stopDelta;
+ }
+
+ // Create the gradient pattern.
nsRefPtr<gfxPattern> gradientPattern;
- if (aGradient->mIsRadial) {
- gfxFloat gradRadius0 = double(aGradient->mStartRadius) / appUnitsPerPixel;
- gfxFloat gradRadius1 = double(aGradient->mEndRadius) / appUnitsPerPixel;
- gradientPattern = new gfxPattern(gradX0, gradY0, gradRadius0,
- gradX1, gradY1, gradRadius1);
+ if (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_LINEAR) {
+ // Compute the actual gradient line ends we need to pass to cairo after
+ // stops have been normalized.
+ gfxPoint gradientStart = lineStart + (lineEnd - lineStart)*firstStop;
+ gfxPoint gradientEnd = lineStart + (lineEnd - lineStart)*lastStop;
+
+ if (stopScale == 0.0) {
+ // Stops are all at the same place. For repeating gradients, this will
+ // just paint the last stop color. We don't need to do anything.
+ // For non-repeating gradients, this should render as two colors, one
+ // on each "side" of the gradient line segment, which is a point. All
+ // our stops will be at 0.0; we just need to set the direction vector
+ // correctly.
+ gradientEnd = gradientStart + (lineEnd - lineStart);
+ }
+
+ gradientPattern = new gfxPattern(gradientStart.x, gradientStart.y,
+ gradientEnd.x, gradientEnd.y);
} else {
- gradientPattern = new gfxPattern(gradX0, gradY0, gradX1, gradY1);
+ NS_ASSERTION(firstStop >= 0.0,
+ "Negative stops not allowed for radial gradients");
+
+ // To form an ellipse, we'll stretch a circle vertically, if necessary.
+ // So our radii are based on radiusX.
+ double innerRadius = radiusX*firstStop;
+ double outerRadius = radiusX*lastStop;
+ gradientPattern = new gfxPattern(lineStart.x, lineStart.y, innerRadius,
+ lineStart.x, lineStart.y, outerRadius);
+ if (gradientPattern && radiusX != radiusY) {
+ // Stretch the circles into ellipses vertically by setting a transform
+ // in the pattern.
+ // Recall that this is the transform from user space to pattern space.
+ // So to stretch the ellipse by factor of P vertically, we scale
+ // user coordinates by 1/P.
+ gfxMatrix matrix;
+ matrix.Translate(lineStart);
+ matrix.Scale(1.0, radiusX/radiusY);
+ matrix.Translate(-lineStart);
+ gradientPattern->SetMatrix(matrix);
+ }
}
-
if (!gradientPattern || gradientPattern->CairoStatus())
return;
- for (PRUint32 i = 0; i < aGradient->mStops.Length(); i++) {
- gradientPattern->AddColorStop(aGradient->mStops[i].mPosition,
- gfxRGBA(aGradient->mStops[i].mColor));
+ // Now set normalized color stops in pattern.
+ if (stopScale == 0.0) {
+ // Non-repeating linear gradient with all stops in same place -> just add
+ // first stop and last stop, both at position 0.
+ // Repeating or radial gradient with all stops in the same place -> just
+ // paint the last stop color.
+ if (!aGradient->mRepeating &&
+ aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_LINEAR) {
+ gradientPattern->AddColorStop(0.0, stops[0].mColor);
+ }
+ gradientPattern->AddColorStop(0.0, stops[stops.Length() - 1].mColor);
+ } else {
+ // Use all stops
+ for (PRUint32 i = 0; i < stops.Length(); i++) {
+ double pos = stopScale*(stops[i].mPosition - firstStop);
+ gradientPattern->AddColorStop(pos, stops[i].mColor);
+ }
}
- if (aRepeat)
+ // Set repeat mode. Default cairo extend mode is PAD.
+ if (aGradient->mRepeating) {
gradientPattern->SetExtend(gfxPattern::EXTEND_REPEAT);
-
- ctx->Save();
- ctx->NewPath();
- // The fill origin is part of the translate call so the pattern starts at
- // the desired point, rather than (0,0).
- ctx->Translate(fillOrigin);
- ctx->SetPattern(gradientPattern);
- ctx->Rectangle(areaToFill - fillOrigin, PR_TRUE);
- ctx->Fill();
- ctx->Restore();
-#endif
+ }
+
+ // Paint gradient tiles. This isn't terribly efficient, but doing it this
+ // way is simple and sure to get pixel-snapping right. We could speed things
+ // up by drawing tiles into temporary surfaces and copying those to the
+ // destination, but after pixel-snapping tiles may not all be the same size.
+ nsRect dirty;
+ dirty.IntersectRect(aDirtyRect, aFillArea);
+ gfxRect areaToFill = RectToGfxRect(aFillArea, appUnitsPerPixel);
+ gfxMatrix ctm = ctx->CurrentMatrix();
+
+ // Compute which tile is the top-left tile to be drawn.
+ PRInt32 firstTileX = (dirty.x - aOneCellArea.x)/aOneCellArea.width;
+ PRInt32 firstTileY = (dirty.y - aOneCellArea.y)/aOneCellArea.height;
+ // xStart/yStart are the top-left corner of the top-left tile.
+ nscoord xStart = firstTileX*aOneCellArea.width + aOneCellArea.x;
+ nscoord yStart = firstTileY*aOneCellArea.height + aOneCellArea.y;
+ nscoord xEnd = dirty.XMost();
+ nscoord yEnd = dirty.YMost();
+ // x and y are the top-left corner of the tile to draw
+ for (nscoord y = yStart; y < yEnd; y += aOneCellArea.height) {
+ for (nscoord x = xStart; x < xEnd; x += aOneCellArea.width) {
+ // The coordinates of the tile
+ gfxRect tileRect =
+ RectToGfxRect(nsRect(x, y, aOneCellArea.width, aOneCellArea.height),
+ appUnitsPerPixel);
+ // 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 = tileRect.Intersect(areaToFill);
+ ctx->NewPath();
+ ctx->Translate(tileRect.pos);
+ ctx->SetPattern(gradientPattern);
+ ctx->Rectangle(fillRect - tileRect.pos, PR_TRUE);
+ ctx->Fill();
+ ctx->SetMatrix(ctm);
+ }
+ }
}
void
nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
const nsRect& aDirtyRect,
const nsRect& aBorderArea,
@@ -2099,18 +2471,17 @@ PaintBackgroundLayer(nsPresContext* aPre
}
if (repeat & NS_STYLE_BG_REPEAT_Y) {
fillArea.y = aBGClipRect.y;
fillArea.height = aBGClipRect.height;
}
fillArea.IntersectRect(fillArea, aBGClipRect);
imageRenderer.Draw(aPresContext, aRenderingContext, destArea, fillArea,
- anchor + aBorderArea.TopLeft(), aDirtyRect,
- (repeat != NS_STYLE_BG_REPEAT_OFF));
+ anchor + aBorderArea.TopLeft(), aDirtyRect);
}
static void
DrawBorderImage(nsPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsIFrame* aForFrame,
const nsRect& aBorderArea,
const nsStyleBorder& aBorderStyle,
@@ -3220,18 +3591,17 @@ ImageRenderer::ComputeSize(const nsSize&
}
void
ImageRenderer::Draw(nsPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDest,
const nsRect& aFill,
const nsPoint& aAnchor,
- const nsRect& aDirty,
- PRBool aRepeat)
+ const nsRect& aDirty)
{
if (!mIsReady) {
NS_NOTREACHED("Ensure PrepareImage() has returned true before calling me");
return;
}
if (aDest.IsEmpty() || aFill.IsEmpty())
return;
@@ -3244,17 +3614,17 @@ ImageRenderer::Draw(nsPresContext*
: (PRUint32) imgIContainer::FLAG_NONE;
nsLayoutUtils::DrawImage(&aRenderingContext, mImageContainer,
nsLayoutUtils::GetGraphicsFilterForFrame(mForFrame),
aDest, aFill, aAnchor, aDirty, drawFlags);
break;
}
case eStyleImageType_Gradient:
nsCSSRendering::PaintGradient(aPresContext, aRenderingContext,
- mGradientData, aDirty, aDest, aFill, aRepeat);
+ mGradientData, aDirty, aDest, aFill);
break;
case eStyleImageType_Null:
default:
break;
}
}
// -----
--- a/layout/base/nsCSSRendering.h
+++ b/layout/base/nsCSSRendering.h
@@ -130,18 +130,17 @@ struct nsCSSRendering {
/**
* Render a gradient for an element.
*/
static void PaintGradient(nsPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsStyleGradient* aGradient,
const nsRect& aDirtyRect,
const nsRect& aOneCellArea,
- const nsRect& aFillArea,
- PRBool aRepeat);
+ const nsRect& aFillArea);
/**
* Gets the root frame for the frame
*/
static nsIFrame* FindRootFrame(nsIFrame* aForFrame);
/**
* @return PR_TRUE if |aFrame| is a canvas frame, in the CSS sense.
--- a/layout/base/tests/scrolling_helper.html
+++ b/layout/base/tests/scrolling_helper.html
@@ -20,22 +20,22 @@ body > div {
tests which expect to observe scrolling happening. -->
<!-- Each of the DIV children of the BODY is one test. We scroll that DIV's
scrollTop (or scrollLeft, if the DIV's class is 'horizontal')
from 0 to 20 and then call the function given by the DIV's id,
passing the blit region and the paint region as a parameters. -->
<div id="testSimpleScroll">
- <div style="height:300px; background:-moz-linear-gradient(top, bottom, from(red), to(black));"></div>
+ <div style="height:300px; background:-moz-linear-gradient(top, red, black);"></div>
</div>
<div id="testFixedBackground">
- <div style="height:300px; margin-bottom:-300px; background:-moz-linear-gradient(left, right, from(red), to(black)) fixed;"></div>
- <div style="height:300px; background:-moz-linear-gradient(top, bottom, from(rgba(0,0,0,0.7)), to(rgba(255,0,0,0.7)));"></div>
+ <div style="height:300px; margin-bottom:-300px; background:-moz-linear-gradient(left, red, black) fixed;"></div>
+ <div style="height:300px; background:-moz-linear-gradient(top, rgba(0,0,0,0.7), rgba(255,0,0,0.7));"></div>
</div>
<div id="testFixedPosOverlay">
<div style="position:fixed; left:0; top:50px; width:100px; height:45px; background:yellow;"></div>
<p>Hello
<p>Hello
<p>Hello
<p>Hello
@@ -55,41 +55,41 @@ body > div {
<p>Hello
<p>Hello
<p>Hello
<p>Hello
<p>Hello
</div>
<div style="border:1px solid black;" id="testBorder">
- <div style="height:300px; background:-moz-linear-gradient(top, bottom, from(red), to(black));"></div>
+ <div style="height:300px; background:-moz-linear-gradient(top, red, black);"></div>
</div>
<div id="testScrollOutOfView">
- <div style="height:10px; margin-bottom:210px; background:-moz-linear-gradient(top, bottom, from(rgba(0,0,0,0.7)), to(rgba(255,0,0,0.7)));"></div>
+ <div style="height:10px; margin-bottom:210px; background:-moz-linear-gradient(top, rgba(0,0,0,0.7), rgba(255,0,0,0.7));"></div>
</div>
<div id="testScrollIntoView">
- <div style="height:10px; margin-top:210px; background:-moz-linear-gradient(top, bottom, from(rgba(0,0,0,0.7)), to(rgba(255,0,0,0.7)));"></div>
+ <div style="height:10px; margin-top:210px; background:-moz-linear-gradient(top, rgba(0,0,0,0.7), rgba(255,0,0,0.7));"></div>
</div>
<div id="testSimpleScrollWithSubpixelOffset1" style="top:0.2px">
- <div style="height:300px; background:-moz-linear-gradient(top, bottom, from(red), to(black));"></div>
+ <div style="height:300px; background:-moz-linear-gradient(top, red, black);"></div>
</div>
<div id="testSimpleScrollWithSubpixelOffset2" style="top:0.8px">
- <div style="height:300px; background:-moz-linear-gradient(top, bottom, from(red), to(black));"></div>
+ <div style="height:300px; background:-moz-linear-gradient(top, red, black);"></div>
</div>
<div id="testSimpleScrollWithSubpixelOffset3" style="left:0.2px" class="horizontal">
- <div style="width:300px; height:200px; background:-moz-linear-gradient(left, right, from(red), to(black));"></div>
+ <div style="width:300px; height:200px; background:-moz-linear-gradient(left, red, black);"></div>
</div>
<div id="testSimpleScrollWithSubpixelOffset4" style="left:0.8px" class="horizontal">
- <div style="width:300px; height:200px; background:-moz-linear-gradient(left, right, from(red), to(black));"></div>
+ <div style="width:300px; height:200px; background:-moz-linear-gradient(left, red, black);"></div>
</div>
<div id="testMovingClipArea">
<div style="margin-top:20px; height:20px; margin-bottom:300px; background-color:blue; overflow:hidden;"></div>
</div>
<script>
var tests = document.querySelectorAll("body>div");
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-1-ref.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(top left, white, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-1a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(top left -45deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-1b.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(-45deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-2-ref.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(top right, white, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-2a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(top right -135deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-2b.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(-135deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-3-ref.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(bottom right, white, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-3a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(bottom right 135deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-3b.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(135deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-4-ref.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(bottom left, white, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-4a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(bottom left 45deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-4b.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(45deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-5-ref.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(bottom right 135deg, white 75%, black); width: 400px; height: 400px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-5a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(100px 100px 135deg, white, black); width: 400px; height: 400px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-6-ref.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(bottom left 45deg, white 75%, black); width: 400px; height: 400px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-6a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(300px 100px 45deg, white, black); width: 400px; height: 400px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-7-ref.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(top left -45deg, white 75%, black); width: 400px; height: 400px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-7a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(300px 300px -45deg, white, black); width: 400px; height: 400px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-8-ref.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(top right -135deg, white 75%, black); width: 400px; height: 400px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-8a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(100px 300px -135deg, white, black); width: 400px; height: 400px;"></div>
--- a/layout/reftests/css-gradients/linear-keywords-ref.html
+++ b/layout/reftests/css-gradients/linear-keywords-ref.html
@@ -1,16 +1,16 @@
<html xmlns="http://www.w3.org/1999/xhtml"
class="reftest-wait">
<head>
<script>
function doDraw() {
var ctx = document.getElementById('canvas').getContext('2d');
- var grad = ctx.createLinearGradient(0,0,150,300);
+ var grad = ctx.createLinearGradient(0,0,300,300);
grad.addColorStop(0, '#0000ff');
grad.addColorStop(1, '#000000');
ctx.fillStyle = grad;
ctx.fillRect(0,0,300,300);
document.documentElement.removeAttribute('class');
}
--- a/layout/reftests/css-gradients/linear-keywords.html
+++ b/layout/reftests/css-gradients/linear-keywords.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(left top, center bottom, from(#0000ff), to(#000000)) no-repeat; width: 300px; height: 300px;"><br></div>
+<div style="background: -moz-linear-gradient(left top, #0000ff, #000000) no-repeat; width: 300px; height: 300px;"><br></div>
--- a/layout/reftests/css-gradients/linear-mix-ref.html
+++ b/layout/reftests/css-gradients/linear-mix-ref.html
@@ -1,25 +1,25 @@
<html xmlns="http://www.w3.org/1999/xhtml"
class="reftest-wait">
<head>
<script>
function doDraw() {
var ctx = document.getElementById('canvas').getContext('2d');
- var grad = ctx.createLinearGradient(150,20,270,130);
+ var grad = ctx.createLinearGradient(120,20,300,20);
grad.addColorStop(0, '#0000ff');
grad.addColorStop(1, '#000000');
ctx.fillStyle = grad;
ctx.fillRect(0,0,300,300);
ctx = document.getElementById('canvas2').getContext('2d');
- grad = ctx.createLinearGradient(30,300,300,50);
+ grad = ctx.createLinearGradient(30,300,30,0);
grad.addColorStop(0, '#00ff00');
grad.addColorStop(1, '#000000');
ctx.fillStyle = grad;
ctx.fillRect(0,0,300,300);
document.documentElement.removeAttribute('class');
}
--- a/layout/reftests/css-gradients/linear-mix.html
+++ b/layout/reftests/css-gradients/linear-mix.html
@@ -1,3 +1,3 @@
-<div style="background: -moz-linear-gradient(center 20px, 90% 130px, from(#0000ff), to(#000000)) no-repeat; width: 300px; height: 300px; position: absolute; top: 30px; left: 30px;"><br></div>
+<div style="background: -moz-linear-gradient(40% 20px 0deg, #0000ff, #000000) no-repeat; width: 300px; height: 300px; position: absolute; top: 30px; left: 30px;"><br></div>
-<div style="background: -moz-linear-gradient(10% bottom, right 50px, from(#00ff00), to(#000000)) no-repeat; width: 300px; height: 300px; position: absolute; top: 360px; left: 30px;"><br></div>
+<div style="background: -moz-linear-gradient(10% bottom 90deg, #00ff00, #000000) no-repeat; width: 300px; height: 300px; position: absolute; top: 360px; left: 30px;"><br></div>
--- a/layout/reftests/css-gradients/linear-percent-ref.html
+++ b/layout/reftests/css-gradients/linear-percent-ref.html
@@ -1,16 +1,16 @@
<html xmlns="http://www.w3.org/1999/xhtml"
class="reftest-wait">
<head>
<script>
function doDraw() {
var ctx = document.getElementById('canvas').getContext('2d');
- var grad = ctx.createLinearGradient(30,60,240,270);
+ var grad = ctx.createLinearGradient(30,60,300,60);
grad.addColorStop(0, '#0000ff');
grad.addColorStop(1, '#000000');
ctx.fillStyle = grad;
ctx.fillRect(0,0,300,300);
document.documentElement.removeAttribute('class');
}
--- a/layout/reftests/css-gradients/linear-percent.html
+++ b/layout/reftests/css-gradients/linear-percent.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(10% 20%, 80% 90%, from(#0000ff), to(#000000)) no-repeat; width: 300px; height: 300px;"><br></div>
+<div style="background: -moz-linear-gradient(10% 20% 0deg, #0000ff, #000000) no-repeat; width: 300px; height: 300px;"><br></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-position-1-ref.html
@@ -0,0 +1,2 @@
+<body style="margin:0;">
+<div style="background: -moz-linear-gradient(left, white, black) no-repeat; position:relative; left:-200px; width: 300px; height: 300px;"><br></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-position-1a.html
@@ -0,0 +1,2 @@
+<body style="margin:0;">
+<div style="background: -moz-linear-gradient(left, white, black) no-repeat; background-position:-200px 0; width: 300px; height: 300px;"><br></div>
--- a/layout/reftests/css-gradients/linear-ref.html
+++ b/layout/reftests/css-gradients/linear-ref.html
@@ -1,16 +1,16 @@
<html xmlns="http://www.w3.org/1999/xhtml"
class="reftest-wait">
<head>
<script>
function doDraw() {
var ctx = document.getElementById('canvas').getContext('2d');
- var grad = ctx.createLinearGradient(10,20,50,100);
+ var grad = ctx.createLinearGradient(0,150,300,150);
grad.addColorStop(0, 'red');
grad.addColorStop(1, 'rgb(100, 200, 0)');
grad.addColorStop(0.5, '#7777FF');
ctx.fillStyle = grad;
ctx.fillRect(0,0,300,300);
document.documentElement.removeAttribute('class');
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-repeat-1-ref.html
@@ -0,0 +1,6 @@
+<div style="background: black; width: 300px; height: 50px;"></div>
+<div style="background: white; width: 300px; height: 50px;"></div>
+<div style="background: black; width: 300px; height: 50px;"></div>
+<div style="background: white; width: 300px; height: 50px;"></div>
+<div style="background: black; width: 300px; height: 50px;"></div>
+<div style="background: white; width: 300px; height: 50px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-repeat-1a.html
@@ -0,0 +1,2 @@
+<div style="background: -moz-linear-gradient(black, black 50%, white 50%, white);
+ -moz-background-size: 100px 100px; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-repeat-1b.html
@@ -0,0 +1,2 @@
+<div style="background: -moz-linear-gradient(black, black 50px, white 50px, white 100px, black 100px, black 150px, white 150px, white 200px);
+ -moz-background-size: 100px 200px; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-repeat-1c.html
@@ -0,0 +1,4 @@
+<div style="background: -moz-linear-gradient(white, white 50%, black 50%, black);
+ -moz-background-size: 100px 100px;
+ background-position: 0 -50px;
+ width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-repeat-1d.html
@@ -0,0 +1,3 @@
+<div style="background: -moz-linear-gradient(white, white 50px, black 50px, black 100px, white 100px, white 150px, black 150px, black 200px);
+ -moz-background-size: 100px 200px; background-position: 0 -50px;
+ width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-repeat-1e.html
@@ -0,0 +1,3 @@
+<div style="background: -moz-linear-gradient(black, black 50%, white 50%, white);
+ -moz-background-size: 300px 100px; background-repeat: repeat-y;
+ width: 500px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-repeat-1f.html
@@ -0,0 +1,10 @@
+<div style="background: -moz-linear-gradient(black, black 50px, white 50px, white 100px, black 100px, black 150px, white 150px, white 200px);
+ -moz-background-size: 100px 200px; background-repeat: repeat-x;
+ width: 300px; height: 800px;
+ margin-bottom: -600px;"></div>
+<!-- making the gradient actually be 300px high isn't reliable since
+ the stop positions cannot be exactly represented and rounding errors
+ creep in. So just let the gradient be 200px high and pad out to match
+ the reference. -->
+<div style="background: black; width: 300px; height: 50px;"></div>
+<div style="background: white; width: 300px; height: 50px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-repeat-1g.html
@@ -0,0 +1,10 @@
+<div style="background: -moz-linear-gradient(black, black 50px, white 50px, white 100px, black 100px, black 150px, white 150px, white 200px);
+ -moz-background-size: 300px 200px; background-repeat: no-repeat;
+ width: 800px; height: 800px;
+ margin-bottom: -600px;"></div>
+<!-- making the gradient actually be 300px high isn't reliable since
+ the stop positions cannot be exactly represented and rounding errors
+ creep in. So just let the gradient be 200px high and pad out to match
+ the reference. -->
+<div style="background: black; width: 300px; height: 50px;"></div>
+<div style="background: white; width: 300px; height: 50px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-size-1-ref.html
@@ -0,0 +1,3 @@
+<div style="background: -moz-linear-gradient(white, black) no-repeat; width: 300px; height: 100px;"></div>
+<div style="background: -moz-linear-gradient(white, black) no-repeat; width: 300px; height: 100px;"></div>
+<div style="background: -moz-linear-gradient(white, black) no-repeat; width: 300px; height: 100px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-size-1a.html
@@ -0,0 +1,2 @@
+<div style="background: -moz-linear-gradient(white, black);
+ -moz-background-size: 300px 100px; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-stops-1-ref.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(white 0%, red 20%, green 40%, blue 60%, yellow 80%, black 100%) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-stops-1a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(white, red, green, blue, yellow, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-stops-1b.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(white 0, red 60px, green 120px, blue 180px, yellow 240px, black 300px) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-stops-1c.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(white, red 20%, green, blue 60%, yellow, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-stops-1d.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(white, red, green 40%, red 40%, green 40%, blue, yellow, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-stops-1e.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(white, red, green 40%, red 20%, green 40%, blue, yellow, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-stops-1f.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(white, red, green 40%, red 40%, green 20%, blue, yellow, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-vertical-1-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<canvas id="canvas" width="300" height="300"/>
+<script>
+var ctx = document.getElementById('canvas').getContext('2d');
+
+var grad = ctx.createLinearGradient(150,0,150,300);
+grad.addColorStop(0, 'white');
+grad.addColorStop(1, 'black');
+
+ctx.fillStyle = grad;
+ctx.fillRect(0,0,300,300);
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-vertical-1a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(white, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-vertical-1b.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(top left -90deg, white, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-vertical-1c.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(white 0%, white 0%, black) no-repeat; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-vertical-1d.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(white 0%, white -20%, black) no-repeat; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear-viewport-ref.html
+++ b/layout/reftests/css-gradients/linear-viewport-ref.html
@@ -1,1 +1,1 @@
-<body style="border: 0; margin: 0; padding: 0;"><div style="background: -moz-linear-gradient(top, bottom, from(blue), to(aqua)) no-repeat; width: 100%; height: 100%;"> </div></body>
+<body style="border: 0; margin: 0; padding: 0;"><div style="background: -moz-linear-gradient(blue, aqua) no-repeat; width: 100%; height: 100%;"> </div></body>
--- a/layout/reftests/css-gradients/linear-viewport.html
+++ b/layout/reftests/css-gradients/linear-viewport.html
@@ -1,2 +1,2 @@
<!-- bug 509681 -->
-<body style="background: -moz-linear-gradient(top, bottom, from(blue), to(aqua)) fixed no-repeat;">
+<body style="background: -moz-linear-gradient(blue, aqua) fixed no-repeat;">
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-zero-length-1-ref.html
@@ -0,0 +1,2 @@
+<div style="background: black; width: 300px; height: 300px;"></div>
+<div style="background: black; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-zero-length-1a.html
@@ -0,0 +1,2 @@
+<div style="background: -moz-linear-gradient(150px 150px, white, black); width: 300px; height: 300px;"></div>
+<div style="background: -moz-repeating-linear-gradient(150px 150px, white, black); width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-zero-length-1b.html
@@ -0,0 +1,2 @@
+<div style="background: -moz-linear-gradient(150px 150px, white, white 100px, black); width: 300px; height: 300px;"></div>
+<div style="background: -moz-repeating-linear-gradient(150px 150px, white, white 100px, black); width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-zero-length-1c.html
@@ -0,0 +1,2 @@
+<div style="background: -moz-linear-gradient(center, white, black 50%); width: 300px; height: 300px;"></div>
+<div style="background: -moz-repeating-linear-gradient(center, white, black 50%); width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/linear.html
+++ b/layout/reftests/css-gradients/linear.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(10px 20px, 50px 100px, from(red), to(rgb(100, 200, 0)), color-stop(0.5, #7777FF)) no-repeat; width: 300px; height: 300px;"><br></div>
+<div style="background: -moz-linear-gradient(left, red 0%, #7777FF 50%, rgb(100, 200, 0) 100%) no-repeat; width: 300px; height: 300px;"><br></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/nostops-ref.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml"
- class="reftest-wait">
-<head>
-<script>
-function doDraw() {
- var ctx = document.getElementById('canvas').getContext('2d');
-
- var grad = ctx.createLinearGradient(0,0,150,300);
-
- ctx.fillStyle = grad;
- ctx.fillRect(0,0,300,300);
-
- document.documentElement.removeAttribute('class');
-}
-</script>
-</head>
-<body onload="doDraw();">
-<canvas id="canvas" width="300" height="300"/>
-</body>
-</html>
-
--- a/layout/reftests/css-gradients/nostops.html
+++ b/layout/reftests/css-gradients/nostops.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(left top, center bottom) no-repeat; width: 300px; height: 300px;"><br></div>
+<div style="background: -moz-linear-gradient(left top) no-repeat; width: 300px; height: 300px;"><br></div>
deleted file mode 100644
--- a/layout/reftests/css-gradients/onestop-ref.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml"
- class="reftest-wait">
-<head>
-<script>
-function doDraw() {
- var ctx = document.getElementById('canvas').getContext('2d');
-
- var grad = ctx.createLinearGradient(0,0,150,300);
- grad.addColorStop(0.5, '#0000ff');
-
- ctx.fillStyle = grad;
- ctx.fillRect(0,0,300,300);
-
- document.documentElement.removeAttribute('class');
-}
-</script>
-</head>
-<body onload="doDraw();">
-<canvas id="canvas" width="300" height="300"/>
-</body>
-</html>
-
--- a/layout/reftests/css-gradients/onestop.html
+++ b/layout/reftests/css-gradients/onestop.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(left top, center bottom, color-stop(0.5, #0000ff)) no-repeat; width: 300px; height: 300px;"><br></div>
+<div style="background: -moz-linear-gradient(left top, #0000ff 50%) no-repeat; width: 300px; height: 300px;"><br></div>
rename from layout/reftests/css-gradients/radial-ref.html
rename to layout/reftests/css-gradients/radial-1-ref.html
--- a/layout/reftests/css-gradients/radial-ref.html
+++ b/layout/reftests/css-gradients/radial-1-ref.html
@@ -1,23 +1,22 @@
-<html xmlns="http://www.w3.org/1999/xhtml"
+<html xmlns="http://www.w3.org/1999/xhtml"
class="reftest-wait">
<head>
<script>
function doDraw() {
var ctx = document.getElementById('canvas').getContext('2d');
- var radgrad = ctx.createRadialGradient(45,45,10,45,45,30);
+ var radgrad = ctx.createRadialGradient(100,100,25,100,100,50);
radgrad.addColorStop(0, '#FF0000');
radgrad.addColorStop(1, '#0000FF');
ctx.fillStyle = radgrad;
ctx.fillRect(0,0,300,300);
document.documentElement.removeAttribute('class');
}
</script>
</head>
<body onload="doDraw();">
<canvas id="canvas" width="300" height="300"/>
</body>
</html>
-
rename from layout/reftests/css-gradients/radial.html
rename to layout/reftests/css-gradients/radial-1a.html
--- a/layout/reftests/css-gradients/radial.html
+++ b/layout/reftests/css-gradients/radial-1a.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-radial-gradient(45px 45px, 10px, 45px 45px, 30px, from(#ff0000), to(#0000ff)) no-repeat; width: 300px; height: 300px;"><br></div>
+<div style="background: -moz-radial-gradient(100px 100px, closest-side, #ff0000 25px, #0000ff 50px) no-repeat; width: 300px; height: 300px;"><br></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-2-ref.html
@@ -0,0 +1,22 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+ class="reftest-wait">
+<head>
+<script>
+function doDraw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ var radgrad = ctx.createRadialGradient(100,100,0,100,100,50);
+ radgrad.addColorStop(0, '#FF0000');
+ radgrad.addColorStop(1, '#0000FF');
+
+ ctx.fillStyle = radgrad;
+ ctx.fillRect(0,0,300,300);
+
+ document.documentElement.removeAttribute('class');
+}
+</script>
+</head>
+<body onload="doDraw();">
+<canvas id="canvas" width="300" height="300"/>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-2a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-radial-gradient(100px 100px, closest-side, yellow -10px, #ff0000 0, #0000ff 50px); width: 300px; height: 300px;"><br></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-2b.html
@@ -0,0 +1,3 @@
+<!-- This test checks that adjustment of stop positions to be non-negative
+ happens after the calculation of implied stop positions -->
+<div style="background: -moz-radial-gradient(100px 100px, closest-side, #ff0000 -50px, #ff0000, #0000ff 50px); width: 300px; height: 300px;"><br></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-position-1-ref.html
@@ -0,0 +1,2 @@
+<body style="margin:0;">
+<div style="background: -moz-radial-gradient(white, black) no-repeat; position:relative; left:-200px; width: 300px; height: 300px;"><br></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-position-1a.html
@@ -0,0 +1,2 @@
+<body style="margin:0;">
+<div style="background: -moz-radial-gradient(white, black) no-repeat; background-position:-200px 0; width: 300px; height: 300px;"><br></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-shape-closest-corner-1-ref.html
@@ -0,0 +1,9 @@
+<style>div { position:absolute; width:200px; height:200px; }</style>
+<div style="background: -moz-radial-gradient(60px 80px, circle closest-side, white, black 100px); top:10px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(140px 80px, circle closest-side, white, black 100px); top:10px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(80px 60px, circle closest-side, white, black 100px); top:220px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(80px 140px, circle closest-side, white, black 100px); top:220px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(60px 80px 90deg, closest-corner, white, black 80px); top:430px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(140px 80px 90deg, closest-corner, white, black 80px); top:430px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(80px 60px 90deg, ellipse closest-corner, white, black 60px); top:640px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(80px 140px 90deg, ellipse closest-corner, white, black 60px); top:640px; left:220px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-shape-closest-corner-1a.html
@@ -0,0 +1,9 @@
+<style>div { position:absolute; width:200px; height:200px; }</style>
+<div style="background: -moz-radial-gradient(60px 80px, circle closest-corner, white, black); top:10px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(140px 80px, circle closest-corner, white, black); top:10px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(80px 60px, circle closest-corner, white, black); top:220px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(80px 140px, circle closest-corner, white, black); top:220px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(60px 80px, ellipse closest-corner, white, black 60px); top:430px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(140px 80px, ellipse closest-corner, white, black 60px); top:430px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(80px 60px, closest-corner, white, black 80px); top:640px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(80px 140px, closest-corner, white, black 80px); top:640px; left:220px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-shape-closest-side-1-ref.html
@@ -0,0 +1,9 @@
+<style>div { position:absolute; width:200px; height:200px; }</style>
+<div style="background: -moz-radial-gradient(50px 80px, circle closest-side, white, black 50px); top:10px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(150px 80px, circle closest-side, white, black 50px); top:10px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(80px 50px, circle closest-side, white, black 50px); top:220px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(80px 150px, circle closest-side, white, black 50px); top:220px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(20px 20px, circle closest-side, white, black 20px); height:100px; -moz-transform-origin:0 0; -moz-transform:scale(1.0, 2.0); top:430px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(180px 20px, circle closest-side, white, black 20px); height:100px; -moz-transform-origin:0 0; -moz-transform:scale(1.0, 2.0); top:430px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(20px 20px, circle closest-side, white, black 20px); width:100px; -moz-transform-origin:0 0; -moz-transform:scale(2.0, 1.0); top:640px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(20px 180px, circle closest-side, white, black 20px); width:100px; -moz-transform-origin:0 0; -moz-transform:scale(2.0, 1.0); top:640px; left:220px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-shape-closest-side-1a.html
@@ -0,0 +1,9 @@
+<style>div { position:absolute; width:200px; height:200px; }</style>
+<div style="background: -moz-radial-gradient(50px 80px, circle closest-side, white, black); top:10px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(150px 80px, circle closest-side, white, black); top:10px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(80px 50px, circle closest-side, white, black); top:220px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(80px 150px, circle closest-side, white, black); top:220px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(20px 40px, ellipse closest-side, white, black); top:430px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(180px 40px, ellipse closest-side, white, black); top:430px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(40px 20px, closest-side, white, black); top:640px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(40px 180px, closest-side, white, black); top:640px; left:220px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-shape-farthest-corner-1-ref.html
@@ -0,0 +1,9 @@
+<style>div { position:absolute; width:200px; height:200px; }</style>
+<div style="background: -moz-radial-gradient(40px 80px, circle farthest-side, white, black 200px); top:10px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(160px 80px, circle farthest-side, white, black 200px); top:10px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(80px 40px, circle farthest-side, white, black 200px); top:220px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(80px 160px, circle farthest-side, white, black 200px); top:220px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(60px 80px 90deg, farthest-corner, white, black 120px); top:430px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(140px 80px 90deg, farthest-corner, white, black 120px); top:430px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(80px 60px 90deg, ellipse farthest-corner, white, black 140px); top:640px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(80px 140px 90deg, ellipse farthest-corner, white, black 140px); top:640px; left:220px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-shape-farthest-corner-1a.html
@@ -0,0 +1,9 @@
+<style>div { position:absolute; width:200px; height:200px; }</style>
+<div style="background: -moz-radial-gradient(40px 80px, circle farthest-corner, white, black); top:10px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(160px 80px, circle farthest-corner, white, black); top:10px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(80px 40px, circle farthest-corner, white, black); top:220px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(80px 160px, circle farthest-corner, white, black); top:220px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(60px 80px, ellipse farthest-corner, white, black 140px); top:430px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(140px 80px, ellipse farthest-corner, white, black 140px); top:430px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(80px 60px, farthest-corner, white, black 120px); top:640px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(80px 140px, farthest-corner, white, black 120px); top:640px; left:220px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-shape-farthest-side-1-ref.html
@@ -0,0 +1,9 @@
+<style>div { position:absolute; width:200px; height:200px; }</style>
+<div style="background: -moz-radial-gradient(50px 80px, circle farthest-side, white, black 150px); top:10px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(150px 80px, circle farthest-side, white, black 150px); top:10px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(80px 50px, circle farthest-side, white, black 150px); top:220px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(80px 150px, circle farthest-side, white, black 150px); top:220px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(80px 80px, circle farthest-side, white, black 120px); -moz-transform-origin:0 0; -moz-transform:scale(1.0, 0.5); top:430px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(120px 120px, circle farthest-side, white, black 120px); -moz-transform-origin:0 0; -moz-transform:scale(1.0, 0.5); top:430px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(80px 80px, circle farthest-side, white, black 120px); -moz-transform-origin:0 0; -moz-transform:scale(0.5, 1.0); top:640px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(120px 120px, circle farthest-side, white, black 120px); -moz-transform-origin:0 0; -moz-transform:scale(0.5, 1.0); top:640px; left:220px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-shape-farthest-side-1a.html
@@ -0,0 +1,9 @@
+<style>div { position:absolute; width:200px; height:200px; }</style>
+<div style="background: -moz-radial-gradient(50px 80px, circle farthest-side, white, black); top:10px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(150px 80px, circle farthest-side, white, black); top:10px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(80px 50px, circle farthest-side, white, black); top:220px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(80px 150px, circle farthest-side, white, black); top:220px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(80px 40px, farthest-side, white, black); height:100px; top:430px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(120px 60px, farthest-side, white, black); height:100px; top:430px; left:220px;"></div>
+<div style="background: -moz-radial-gradient(40px 80px, ellipse farthest-side, white, black); width:100px; top:640px; left:10px;"></div>
+<div style="background: -moz-radial-gradient(60px 120px, ellipse farthest-side, white, black); width:100px; top:640px; left:220px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-size-1-ref.html
@@ -0,0 +1,3 @@
+<div style="background: -moz-radial-gradient(white, black) no-repeat; width: 300px; height: 100px;"></div>
+<div style="background: -moz-radial-gradient(white, black) no-repeat; width: 300px; height: 100px;"></div>
+<div style="background: -moz-radial-gradient(white, black) no-repeat; width: 300px; height: 100px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-size-1a.html
@@ -0,0 +1,2 @@
+<div style="background: -moz-radial-gradient(white, black);
+ -moz-background-size: 300px 100px; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-zero-length-1-ref.html
@@ -0,0 +1,2 @@
+<div style="background: black; width: 300px; height: 300px;"></div>
+<div style="background: black; width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-zero-length-1a.html
@@ -0,0 +1,2 @@
+<div style="background: -moz-radial-gradient(left, circle closest-side, white, black); width: 300px; height: 300px;"></div>
+<div style="background: -moz-repeating-radial-gradient(left, circle closest-side, white, black); width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-zero-length-1b.html
@@ -0,0 +1,2 @@
+<div style="background: -moz-radial-gradient(left, circle closest-side, red, white 100px, black); width: 300px; height: 300px;"></div>
+<div style="background: -moz-repeating-radial-gradient(left, circle closest-side, red, white 100px, black); width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-zero-length-1c.html
@@ -0,0 +1,2 @@
+<div style="background: -moz-radial-gradient(left, circle closest-side, red, white 100px, black); width: 300px; height: 300px;"></div>
+<div style="background: -moz-repeating-radial-gradient(left, circle closest-side, red, white 100px, black); width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-zero-length-1d.html
@@ -0,0 +1,2 @@
+<div style="background: -moz-radial-gradient(left, ellipse closest-side, red, white 100px, black); width: 300px; height: 300px;"></div>
+<div style="background: -moz-repeating-radial-gradient(left, ellipse closest-side, red, white 100px, black); width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-zero-length-1e.html
@@ -0,0 +1,2 @@
+<div style="background: -moz-radial-gradient(left, ellipse closest-side, red, white 100px, black); width: 300px; height: 300px;"></div>
+<div style="background: -moz-repeating-radial-gradient(left, ellipse closest-side, red, white 100px, black); width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/radial-zero-length-1f.html
@@ -0,0 +1,2 @@
+<div style="background: -moz-radial-gradient(top, ellipse closest-side, red, white 100px, black); width: 300px; height: 300px;"></div>
+<div style="background: -moz-repeating-radial-gradient(top, ellipse closest-side, red, white 100px, black); width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/reftest.list
+++ b/layout/reftests/css-gradients/reftest.list
@@ -1,9 +1,67 @@
== linear.html linear-ref.html
-== radial.html radial-ref.html
== linear-keywords.html linear-keywords-ref.html
== linear-percent.html linear-percent-ref.html
== linear-mix.html linear-mix-ref.html
-== nostops.html nostops-ref.html
-== onestop.html onestop-ref.html
-== twostops.html twostops-ref.html
+== linear-diagonal-1a.html linear-diagonal-1-ref.html
+== linear-diagonal-1b.html linear-diagonal-1-ref.html
+== linear-diagonal-2a.html linear-diagonal-2-ref.html
+== linear-diagonal-2b.html linear-diagonal-2-ref.html
+== linear-diagonal-3a.html linear-diagonal-3-ref.html
+== linear-diagonal-3b.html linear-diagonal-3-ref.html
+== linear-diagonal-4a.html linear-diagonal-4-ref.html
+== linear-diagonal-4b.html linear-diagonal-4-ref.html
+== linear-diagonal-5a.html linear-diagonal-5-ref.html
+== linear-diagonal-6a.html linear-diagonal-6-ref.html
+== linear-diagonal-7a.html linear-diagonal-7-ref.html
+== linear-diagonal-8a.html linear-diagonal-8-ref.html
+== linear-position-1a.html linear-position-1-ref.html
+== linear-repeat-1a.html linear-repeat-1-ref.html
+== linear-repeat-1b.html linear-repeat-1-ref.html
+== linear-repeat-1c.html linear-repeat-1-ref.html
+== linear-repeat-1d.html linear-repeat-1-ref.html
+== linear-repeat-1e.html linear-repeat-1-ref.html
+== linear-repeat-1f.html linear-repeat-1-ref.html
+== linear-repeat-1g.html linear-repeat-1-ref.html
+== linear-size-1a.html linear-size-1-ref.html
+== linear-stops-1a.html linear-stops-1-ref.html
+== linear-stops-1b.html linear-stops-1-ref.html
+== linear-stops-1c.html linear-stops-1-ref.html
+== linear-stops-1d.html linear-stops-1-ref.html
+== linear-stops-1e.html linear-stops-1-ref.html
+== linear-stops-1f.html linear-stops-1-ref.html
+== linear-vertical-1a.html linear-vertical-1-ref.html
+== linear-vertical-1b.html linear-vertical-1-ref.html
+== linear-vertical-1c.html linear-vertical-1-ref.html
+== linear-vertical-1d.html linear-vertical-1-ref.html
== linear-viewport.html linear-viewport-ref.html
+== linear-zero-length-1a.html linear-zero-length-1-ref.html
+== linear-zero-length-1b.html linear-zero-length-1-ref.html
+== linear-zero-length-1c.html linear-zero-length-1-ref.html
+== nostops.html about:blank
+== onestop.html about:blank
+== radial-1a.html radial-1-ref.html
+== radial-2a.html radial-2-ref.html
+== radial-2b.html radial-2-ref.html
+== radial-position-1a.html radial-position-1-ref.html
+== radial-shape-closest-corner-1a.html radial-shape-closest-corner-1-ref.html
+== radial-shape-closest-side-1a.html radial-shape-closest-side-1-ref.html
+== radial-shape-farthest-corner-1a.html radial-shape-farthest-corner-1-ref.html
+== radial-shape-farthest-side-1a.html radial-shape-farthest-side-1-ref.html
+== radial-size-1a.html radial-size-1-ref.html
+== radial-zero-length-1a.html radial-zero-length-1-ref.html
+== radial-zero-length-1b.html radial-zero-length-1-ref.html
+== radial-zero-length-1c.html radial-zero-length-1-ref.html
+== radial-zero-length-1d.html radial-zero-length-1-ref.html
+== radial-zero-length-1e.html radial-zero-length-1-ref.html
+== radial-zero-length-1f.html radial-zero-length-1-ref.html
+== repeating-linear-1a.html repeating-linear-1-ref.html
+== repeating-linear-1b.html repeating-linear-1-ref.html
+== repeating-linear-2a.html repeating-linear-2-ref.html
+== repeating-radial-1a.html repeating-radial-1-ref.html
+== repeating-radial-1b.html repeating-radial-1-ref.html
+== repeating-radial-2a.html repeating-radial-2-ref.html
+== twostops-1a.html twostops-1-ref.html
+== twostops-1b.html twostops-1-ref.html
+fails == twostops-1c.html twostops-1-ref.html # bug 524173
+== twostops-1d.html twostops-1-ref.html
+fails-if(MOZ_WIDGET_TOOLKIT!="cocoa") == twostops-1e.html twostops-1-ref.html # bug 524173
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/repeating-linear-1-ref.html
@@ -0,0 +1,8 @@
+<div style="background: black; width: 400px; height: 50px;"></div>
+<div style="background: white; width: 400px; height: 50px;"></div>
+<div style="background: black; width: 400px; height: 50px;"></div>
+<div style="background: white; width: 400px; height: 50px;"></div>
+<div style="background: black; width: 400px; height: 50px;"></div>
+<div style="background: white; width: 400px; height: 50px;"></div>
+<div style="background: black; width: 400px; height: 50px;"></div>
+<div style="background: white; width: 400px; height: 50px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/repeating-linear-1a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-repeating-linear-gradient(black 0, black 50px, white 50px, white 100px); width: 400px; height: 400px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/repeating-linear-1b.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-repeating-linear-gradient(black 100px, black 150px, white 150px, white 200px); width: 400px; height: 400px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/repeating-linear-2-ref.html
@@ -0,0 +1,1 @@
+<div style="width:300px; height:300px; background:blue;"></div>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/repeating-linear-2a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-repeating-linear-gradient(red 20px, blue 20px); width: 300px; height: 300px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/repeating-radial-1-ref.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-repeating-radial-gradient(closest-side, black 0, black 50px, white 50px, white 100px); width: 400px; height: 400px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/repeating-radial-1a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-repeating-radial-gradient(closest-side, black 100px, black 150px, white 150px, white 200px); width: 400px; height: 400px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/repeating-radial-1b.html
@@ -0,0 +1,4 @@
+<!-- Test adjustment of negative stop positions in a repeating radial gradient.
+ We should still get a repeating pattern, i.e., the stops cannot
+ naively be mapped to 0. -->
+<div style="background: -moz-repeating-radial-gradient(closest-side, black -100px, black -50px, white -50px, white 0); width: 400px; height: 400px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/repeating-radial-2-ref.html
@@ -0,0 +1,1 @@
+<div style="width:300px; height:300px; background:blue;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/repeating-radial-2a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-repeating-radial-gradient(red 20px, blue 20px); width: 300px; height: 300px;"></div>
rename from layout/reftests/css-gradients/twostops-ref.html
rename to layout/reftests/css-gradients/twostops-1-ref.html
--- a/layout/reftests/css-gradients/twostops-ref.html
+++ b/layout/reftests/css-gradients/twostops-1-ref.html
@@ -1,23 +1,7 @@
-<html xmlns="http://www.w3.org/1999/xhtml"
- class="reftest-wait">
-<head>
-<script>
-function doDraw() {
- var ctx = document.getElementById('canvas').getContext('2d');
-
- var grad = ctx.createLinearGradient(0,0,150,300);
- grad.addColorStop(0.5, '#0000ff');
- grad.addColorStop(0.5, '#ff0000');
-
- ctx.fillStyle = grad;
- ctx.fillRect(0,0,300,300);
-
- document.documentElement.removeAttribute('class');
-}
-</script>
-</head>
-<body onload="doDraw();">
-<canvas id="canvas" width="300" height="300"/>
+<!DOCTYPE HTML>
+<html>
+<body>
+<div style="background:#0000ff; width:300px; height:150px;"></div>
+<div style="background:#ff0000; width:300px; height:150px;"></div>
</body>
</html>
-
rename from layout/reftests/css-gradients/twostops.html
rename to layout/reftests/css-gradients/twostops-1a.html
--- a/layout/reftests/css-gradients/twostops.html
+++ b/layout/reftests/css-gradients/twostops-1a.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(left top, center bottom, color-stop(0.5, #0000ff), color-stop(0.5, #ff0000)) no-repeat; width: 300px; height: 300px;"><br></div>
+<div style="background: -moz-linear-gradient(top, #0000ff 50%, #ff0000 50%) no-repeat; width: 300px; height: 300px;"><br></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/twostops-1b.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(bottom, #ff0000 50%, #0000ff 50%) no-repeat; width: 300px; height: 300px;"><br></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/twostops-1c.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(yellow -50%, #0000ff 0, #0000ff 50%, #ff0000 50%) no-repeat; width: 300px; height: 300px;"><br></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/twostops-1d.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(#0000ff 50%, #ff0000 50%, #ff0000 100%, yellow 150%) no-repeat; width: 300px; height: 300px;"><br></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/twostops-1e.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(yellow -50%, #0000ff 0, #0000ff 50%, #ff0000 50%, #ff0000 100%, yellow 150%) no-repeat; width: 300px; height: 300px;"><br></div>
--- a/layout/style/nsStyleCoord.h
+++ b/layout/style/nsStyleCoord.h
@@ -49,17 +49,17 @@ class nsString;
enum nsStyleUnit {
eStyleUnit_Null = 0, // (no value) value is not specified
eStyleUnit_Normal = 1, // (no value)
eStyleUnit_Auto = 2, // (no value)
eStyleUnit_None = 3, // (no value)
eStyleUnit_Percent = 10, // (float) 1.0 == 100%
eStyleUnit_Factor = 11, // (float) a multiplier
eStyleUnit_Degree = 12, // (float) angle in degrees
- eStyleUnit_Grad = 13, // (float) angle in radians
+ eStyleUnit_Grad = 13, // (float) angle in grads
eStyleUnit_Radian = 14, // (float) angle in radians
eStyleUnit_Coord = 20, // (nscoord) value is twips
eStyleUnit_Integer = 30, // (int) value is simple integer
eStyleUnit_Enumerated = 32 // (int) value has enumerated meaning
};
typedef union {
PRInt32 mInt; // nscoord is a PRInt32 for now
@@ -88,16 +88,20 @@ public:
PRBool operator==(const nsStyleCoord& aOther) const;
PRBool operator!=(const nsStyleCoord& aOther) const;
nsStyleUnit GetUnit(void) const {
NS_ASSERTION(mUnit != eStyleUnit_Null, "reading uninitialized value");
return mUnit;
}
+ PRBool IsAngleValue(void) const {
+ return eStyleUnit_Degree <= mUnit && mUnit <= eStyleUnit_Radian;
+ }
+
nscoord GetCoordValue(void) const;
PRInt32 GetIntValue(void) const;
float GetPercentValue(void) const;
float GetFactorValue(void) const;
float GetAngleValue(void) const;
double GetAngleValueInRadians(void) const;
void GetUnionValue(nsStyleUnion& aValue) const;
--- a/toolkit/themes/pinstripe/global/shared.inc
+++ b/toolkit/themes/pinstripe/global/shared.inc
@@ -1,34 +1,34 @@
%filter substitution
%define loweredShadow 0 1px rgba(255, 255, 255, .4)
%define focusRingShadow 0 0 1px -moz-mac-focusring inset, 0 0 4px 1px -moz-mac-focusring, 0 0 2px 1px -moz-mac-focusring
%define roundButtonBorder 1px solid rgba(0, 0, 0, .4)
-%define roundButtonBackground -moz-linear-gradient(top, bottom, from(#FFF), to(#CACACA)) repeat-x
+%define roundButtonBackground -moz-linear-gradient(top, bottom, #FFF, #CACACA) repeat-x
%define roundButtonShadow 0 1px rgba(255, 255, 255, .4)
%define roundButtonPressedBackground #CCC
%define roundButtonPressedShadow inset 0 1px 4px rgba(0, 0, 0, .2), 0 1px rgba(255, 255, 255, .4)
-%define scopeBarBackground -moz-linear-gradient(top, bottom, from(#E8E8E8), to(#D0D0D0)) repeat-x
+%define scopeBarBackground -moz-linear-gradient(top, bottom, #E8E8E8, #D0D0D0) repeat-x
%define scopeBarSeparatorBorder 1px solid #888
%define scopeBarTitleColor #6D6D6D
%define sidebarItemBorderTop 1px solid #94A1C0
-%define sidebarItemBackground -moz-linear-gradient(top, bottom, from(#A0B0CF), to(#7386AB)) repeat-x
+%define sidebarItemBackground -moz-linear-gradient(top, bottom, #A0B0CF, #7386AB) repeat-x
%define sidebarItemFocusedBorderTop 1px solid #5382C5
-%define sidebarItemFocusedBackground -moz-linear-gradient(top, bottom, from(#6494D4), to(#2559AC)) repeat-x
+%define sidebarItemFocusedBackground -moz-linear-gradient(top, bottom, #6494D4, #2559AC) repeat-x
%define sidebarItemGraphiteBorderTop 1px solid #97A4B1
-%define sidebarItemGraphiteBackground -moz-linear-gradient(top, bottom, from(#AAB7C4), to(#8393A4)) repeat-x
+%define sidebarItemGraphiteBackground -moz-linear-gradient(top, bottom, #AAB7C4, #8393A4) repeat-x
%define sidebarItemGraphiteFocusedBorderTop 1px solid #6B798D
-%define sidebarItemGraphiteFocusedBackground -moz-linear-gradient(top, bottom, from(#8293A6), to(#425972)) repeat-x
+%define sidebarItemGraphiteFocusedBackground -moz-linear-gradient(top, bottom, #8293A6, #425972) repeat-x
%define sidebarItemInactiveBorderTop 1px solid #979797
-%define sidebarItemInactiveBackground -moz-linear-gradient(top, bottom, from(#B4B4B4), to(#8A8A8A)) repeat-x
+%define sidebarItemInactiveBackground -moz-linear-gradient(top, bottom, #B4B4B4, #8A8A8A) repeat-x
%define toolbarbuttonBorderColor rgba(59, 59, 59, 0.9)
%define toolbarbuttonCornerRadius 3px
-%define toolbarbuttonBackground -moz-linear-gradient(top, bottom, from(#FFF), to(#ADADAD)) repeat-x
+%define toolbarbuttonBackground -moz-linear-gradient(top, bottom, #FFF, #ADADAD) repeat-x
%define toolbarbuttonPressedInnerShadow inset rgba(0, 0, 0, 0.3) 0 -6px 14px, inset #000 0 1px 4px, inset rgba(0, 0, 0, 0.2) 0 1px 4px
%define toolbarbuttonPressedBackgroundColor #B5B5B5
%define toolbarbuttonInactiveBorderColor rgba(146, 146, 146, 0.84)
%define toolbarbuttonInactiveFontColor #7C7C7C
-%define toolbarbuttonInactiveBackgroundImage -moz-linear-gradient(top, bottom, from(#FFF), to(#CCC))
+%define toolbarbuttonInactiveBackgroundImage -moz-linear-gradient(top, bottom, #FFF, #CCC)