Bug 787947. Avoid scaling by 0 when snapping gradient tiles. r=jrmuizel

This commit is contained in:
Robert O'Callahan
2012-09-25 15:25:48 +12:00
parent 8e9785466d
commit b4af1d44d6
4 changed files with 32 additions and 19 deletions

View File

@@ -2290,6 +2290,7 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
gfxRect areaToFill = gfxRect areaToFill =
nsLayoutUtils::RectToGfxRect(aFillArea, appUnitsPerPixel); nsLayoutUtils::RectToGfxRect(aFillArea, appUnitsPerPixel);
gfxMatrix ctm = ctx->CurrentMatrix(); gfxMatrix ctm = ctx->CurrentMatrix();
bool isCTMPreservingAxisAlignedRectangles = ctm.PreservesAxisAlignedRectangles();
// xStart/yStart are the top-left corner of the top-left tile. // xStart/yStart are the top-left corner of the top-left tile.
nscoord xStart = FindTileStart(dirty.x, aOneCellArea.x, aOneCellArea.width); nscoord xStart = FindTileStart(dirty.x, aOneCellArea.x, aOneCellArea.width);
@@ -2309,27 +2310,30 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
gfxRect fillRect = gfxRect fillRect =
pattern->mCoversTile ? areaToFill : tileRect.Intersect(areaToFill); pattern->mCoversTile ? areaToFill : tileRect.Intersect(areaToFill);
ctx->NewPath(); ctx->NewPath();
// If we can snap the gradient tile and fill rects, do so, but make sure // Try snapping the fill rect. Snap its top-left and bottom-right
// that the gradient is scaled precisely to the tile rect. // independently to preserve the orientation.
gfxRect fillRectSnapped = fillRect; gfxPoint snappedFillRectTopLeft = fillRect.TopLeft();
// Don't snap the tileRect directly since that would lose information gfxPoint snappedFillRectBottomRight = fillRect.BottomRight();
// about the orientation of the current transform (i.e. vertical or if (isCTMPreservingAxisAlignedRectangles &&
// horizontal flipping). Instead snap the corners independently so if ctx->UserToDevicePixelSnapped(snappedFillRectTopLeft, true) &&
// the CTM has a flip, our Scale() below preserves the flip. ctx->UserToDevicePixelSnapped(snappedFillRectBottomRight, true)) {
gfxPoint tileRectSnappedTopLeft = tileRect.TopLeft(); if (snappedFillRectTopLeft.x == snappedFillRectBottomRight.x ||
gfxPoint tileRectSnappedBottomRight = tileRect.BottomRight(); snappedFillRectTopLeft.y == snappedFillRectBottomRight.y) {
if (ctx->UserToDevicePixelSnapped(fillRectSnapped, true) && // Nothing to draw; avoid scaling by zero and other weirdness that
ctx->UserToDevicePixelSnapped(tileRectSnappedTopLeft, true) && // could put the context in an error state.
ctx->UserToDevicePixelSnapped(tileRectSnappedBottomRight, true)) { continue;
}
// Set the context's transform to the transform that maps fillRect to
// snappedFillRect. The part of the gradient that was going to
// exactly fill fillRect will fill snappedFillRect instead.
ctx->IdentityMatrix(); ctx->IdentityMatrix();
ctx->Rectangle(fillRectSnapped); ctx->Translate(snappedFillRectTopLeft);
ctx->Translate(tileRectSnappedTopLeft); ctx->Scale((snappedFillRectBottomRight.x - snappedFillRectTopLeft.x)/fillRect.width,
ctx->Scale((tileRectSnappedBottomRight.x - tileRectSnappedTopLeft.x)/tileRect.width, (snappedFillRectBottomRight.y - snappedFillRectTopLeft.y)/fillRect.height);
(tileRectSnappedBottomRight.y - tileRectSnappedTopLeft.y)/tileRect.height); ctx->Translate(-fillRect.TopLeft());
} else { }
ctx->Rectangle(fillRect); ctx->Rectangle(fillRect);
ctx->Translate(tileRect.TopLeft()); ctx->Translate(tileRect.TopLeft());
}
ctx->SetPattern(pattern->mPattern); ctx->SetPattern(pattern->mPattern);
ctx->Fill(); ctx->Fill();
ctx->SetMatrix(ctm); ctx->SetMatrix(ctm);

View File

@@ -0,0 +1,4 @@
<!DOCTYPE HTML>
<body style="background:white;">
<div style="position:absolute; left:10px; top:10px; width:100px; height:100px; border:1px solid black;"></div>
<p style="position:absolute; left:10px; z-index:2">Hello

View File

@@ -0,0 +1,4 @@
<!DOCTYPE HTML>
<body style="background:white;">
<div style="position:absolute; left:10px; top:10px; width:100px; height:100px; border:1px solid black; background-image:linear-gradient(30deg, white, rgba(255,255,255,0)); background-size:0.3px 100px;"></div>
<p style="position:absolute; left:10px; z-index:2">Hello

View File

@@ -1719,3 +1719,4 @@ fuzzy-if(true,17,5859) == 759036-2.html 759036-2-ref.html
== 776265-2b.html 776265-2-ref.html == 776265-2b.html 776265-2-ref.html
== 776265-2c.html 776265-2-ref.html == 776265-2c.html 776265-2-ref.html
== 776265-2d.html 776265-2-ref.html == 776265-2d.html 776265-2-ref.html
== 787947-1.html 787947-1-ref.html