mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-03 02:25:34 +00:00
Bug 809478. Handle 90-degree rotations when snapping transformed gradients. r=jrmuizel
--HG-- extra : rebase_source : 61e2873b334f89a0a8b6ae0a7df0dfa37e668d0b
This commit is contained in:
parent
4e9ee5bd7e
commit
b36f5b4ead
@ -2072,6 +2072,35 @@ FindTileStart(nscoord aDirtyCoord, nscoord aTilePos, nscoord aTileDim)
|
||||
return NSToCoordRound(multiples*aTileDim + aTilePos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the transform matrix that maps aFrom to the rectangle defined by
|
||||
* aToTopLeft/aToTopRight/aToBottomRight. The destination rectangle must be
|
||||
* nonempty and must be axis-aligned.
|
||||
*/
|
||||
static gfxMatrix
|
||||
TransformRectToRect(const gfxRect& aFrom, const gfxPoint& aToTopLeft,
|
||||
const gfxPoint& aToTopRight, const gfxPoint& aToBottomRight)
|
||||
{
|
||||
gfxMatrix m;
|
||||
if (aToTopRight.y == aToTopLeft.y && aToTopRight.x == aToBottomRight.x) {
|
||||
// Not a rotation, so xy and yx are zero
|
||||
m.xy = m.yx = 0.0;
|
||||
m.xx = (aToBottomRight.x - aToTopLeft.x)/aFrom.width;
|
||||
m.yy = (aToBottomRight.y - aToTopLeft.y)/aFrom.height;
|
||||
m.x0 = aToTopLeft.x - m.xx*aFrom.x;
|
||||
m.y0 = aToTopLeft.y - m.yy*aFrom.y;
|
||||
} else {
|
||||
NS_ASSERTION(aToTopRight.y == aToBottomRight.y && aToTopRight.x == aToTopLeft.x,
|
||||
"Destination rectangle not axis-aligned");
|
||||
m.xx = m.yy = 0.0;
|
||||
m.xy = (aToBottomRight.x - aToTopLeft.x)/aFrom.height;
|
||||
m.yx = (aToBottomRight.y - aToTopLeft.y)/aFrom.width;
|
||||
m.x0 = aToTopLeft.x - m.xy*aFrom.y;
|
||||
m.y0 = aToTopLeft.y - m.yx*aFrom.x;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
|
||||
nsRenderingContext& aRenderingContext,
|
||||
@ -2392,10 +2421,14 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
|
||||
// Try snapping the fill rect. Snap its top-left and bottom-right
|
||||
// independently to preserve the orientation.
|
||||
gfxPoint snappedFillRectTopLeft = fillRect.TopLeft();
|
||||
gfxPoint snappedFillRectTopRight = fillRect.TopRight();
|
||||
gfxPoint snappedFillRectBottomRight = fillRect.BottomRight();
|
||||
// Snap three points instead of just two to ensure we choose the
|
||||
// correct orientation if there's a reflection.
|
||||
if (isCTMPreservingAxisAlignedRectangles &&
|
||||
ctx->UserToDevicePixelSnapped(snappedFillRectTopLeft, true) &&
|
||||
ctx->UserToDevicePixelSnapped(snappedFillRectBottomRight, true)) {
|
||||
ctx->UserToDevicePixelSnapped(snappedFillRectBottomRight, true) &&
|
||||
ctx->UserToDevicePixelSnapped(snappedFillRectTopRight, true)) {
|
||||
if (snappedFillRectTopLeft.x == snappedFillRectBottomRight.x ||
|
||||
snappedFillRectTopLeft.y == snappedFillRectBottomRight.y) {
|
||||
// Nothing to draw; avoid scaling by zero and other weirdness that
|
||||
@ -2405,11 +2438,10 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
|
||||
// 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->Translate(snappedFillRectTopLeft);
|
||||
ctx->Scale((snappedFillRectBottomRight.x - snappedFillRectTopLeft.x)/fillRect.width,
|
||||
(snappedFillRectBottomRight.y - snappedFillRectTopLeft.y)/fillRect.height);
|
||||
ctx->Translate(-fillRect.TopLeft());
|
||||
gfxMatrix transform = TransformRectToRect(fillRect,
|
||||
snappedFillRectTopLeft, snappedFillRectTopRight,
|
||||
snappedFillRectBottomRight);
|
||||
ctx->SetMatrix(transform);
|
||||
}
|
||||
ctx->Rectangle(fillRect);
|
||||
ctx->Translate(tileRect.TopLeft());
|
||||
|
7
layout/reftests/css-gradients/linear-rotated-1-ref.html
Normal file
7
layout/reftests/css-gradients/linear-rotated-1-ref.html
Normal file
@ -0,0 +1,7 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<div style="width:100px; height:100px; background:linear-gradient(to left, red, green);"></div>
|
||||
<div style="width:100px; height:100px; background:linear-gradient(to right, red, green);"></div>
|
||||
</body>
|
||||
</html>
|
7
layout/reftests/css-gradients/linear-rotated-1.html
Normal file
7
layout/reftests/css-gradients/linear-rotated-1.html
Normal file
@ -0,0 +1,7 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<div style="width:100px; height:100px; transform:rotate(90deg); background:linear-gradient(red, green);"></div>
|
||||
<div style="width:100px; height:100px; transform:rotate(270deg); background:linear-gradient(red, green);"></div>
|
||||
</body>
|
||||
</html>
|
@ -30,6 +30,7 @@ fails-if(d2d) == linear-repeat-1d.html linear-repeat-1-ref.html # bug 582236
|
||||
== linear-repeat-1e.html linear-repeat-1-ref.html
|
||||
fails-if(d2d) == linear-repeat-1f.html linear-repeat-1-ref.html # bug 582236
|
||||
fails-if(d2d) == linear-repeat-1g.html linear-repeat-1-ref.html # bug 582236
|
||||
== linear-rotated-1.html linear-rotated-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
|
||||
|
Loading…
Reference in New Issue
Block a user