Bug 464811. Tweak the anchor point snapping algorithm again. This time we have a proof that the resulting snapping algorithm guarantees the subimage rectangle intersects the logical source rectangle. r+sr=dbaron

This commit is contained in:
Robert O'Callahan 2008-11-18 09:32:11 +13:00
Родитель 7c336c14ed
Коммит 0dfe03d1a8
5 изменённых файлов: 54 добавлений и 12 удалений

Просмотреть файл

@ -2662,6 +2662,14 @@ nsLayoutUtils::GetClosestLayer(nsIFrame* aFrame)
return aFrame->PresContext()->PresShell()->FrameManager()->GetRootFrame();
}
/**
* Given an image being drawn into an appunit coordinate system, and
* a point in that coordinate system, map the point back into image
* pixel space.
* @param aSize the size of the image, in pixels
* @param aDest the rectangle that the image is being mapped into
* @param aPt a point in the same coordinate system as the rectangle
*/
static gfxPoint
MapToFloatImagePixels(const nsIntSize& aSize,
const nsRect& aDest, const nsPoint& aPt)
@ -2670,6 +2678,22 @@ MapToFloatImagePixels(const nsIntSize& aSize,
(gfxFloat(aPt.y - aDest.y)*aSize.height)/aDest.height);
}
/**
* Given an image being drawn into an pixel-based coordinate system, and
* a point in image space, map the point into the pixel-based coordinate
* system.
* @param aSize the size of the image, in pixels
* @param aDest the rectangle that the image is being mapped into
* @param aPt a point in image space
*/
static gfxPoint
MapToFloatUserPixels(const nsIntSize& aSize,
const gfxRect& aDest, const gfxPoint& aPt)
{
return gfxPoint(aPt.x*aDest.size.width/aSize.width + aDest.pos.x,
aPt.y*aDest.size.height/aSize.height + aDest.pos.y);
}
/* static */ nsresult
nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
imgIContainer* aImage,
@ -2733,16 +2757,22 @@ nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
// device unit!
gfxPoint anchorPoint(aAnchor.x/appUnitsPerDevPixel,
aAnchor.y/appUnitsPerDevPixel);
gfxPoint imageSpaceAnchorPoint =
MapToFloatImagePixels(imageSize, aDest, aAnchor);
gfxMatrix currentMatrix = ctx->CurrentMatrix();
gfxRect finalFillRect = fill;
if (didSnap) {
NS_ASSERTION(!currentMatrix.HasNonAxisAlignedTransform(),
"How did we snap, then?");
anchorPoint.x = fill.pos.x +
(anchorPoint.x - devPixelFill.pos.x)*fill.size.width/devPixelFill.size.width;
anchorPoint.y = fill.pos.y +
(anchorPoint.y - devPixelFill.pos.y)*fill.size.height/devPixelFill.size.height;
anchorPoint.Round();
imageSpaceAnchorPoint.Round();
anchorPoint = imageSpaceAnchorPoint;
gfxRect devPixelDest(aDest.x/appUnitsPerDevPixel,
aDest.y/appUnitsPerDevPixel,
aDest.width/appUnitsPerDevPixel,
aDest.height/appUnitsPerDevPixel);
anchorPoint = MapToFloatUserPixels(imageSize, devPixelDest, anchorPoint);
anchorPoint = currentMatrix.Transform(anchorPoint);
// This form of Transform is safe to call since non-axis-aligned
// transforms wouldn't be snapped.
@ -2759,9 +2789,6 @@ nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
// to be aligned perfectly with pixel boundaries or the choice of
// dirty rect will affect the values of rendered pixels.
gfxPoint imageSpaceAnchorPoint =
MapToFloatImagePixels(imageSize, aDest, aAnchor);
imageSpaceAnchorPoint.Round();
gfxFloat scaleX = imageSize.width*appUnitsPerDevPixel/aDest.width;
gfxFloat scaleY = imageSize.height*appUnitsPerDevPixel/aDest.height;
if (didSnap) {

Просмотреть файл

@ -28,8 +28,8 @@
<div>
<div class="cell"><p>32 x 32</p><div style="width:32px; background-position:-16px -16px;" class="image"></div></div>
<div class="cell"><p>32.1 x 32</p><div style="width:32px; background-position:-16px -16px;" class="image"></div></div>
<div class="cell"><p>32.5 x 32</p><div style="width:33px; background-position:-15px -16px;" class="image"></div></div>
<div class="cell"><p>32.8 x 32</p><div style="width:33px; background-position:-15px -16px;" class="image"></div></div>
<div class="cell"><p>32.5 x 32</p><div style="width:33px; background-position:-16px -16px;" class="image"></div></div>
<div class="cell"><p>32.8 x 32</p><div style="width:33px; background-position:-16px -16px;" class="image"></div></div>
</div>
<div>
@ -42,8 +42,8 @@
<div>
<div class="cell"><p>32 x 32 </p><div style="height:32px; background-position:-16px -16px;" class="image"></div></div>
<div class="cell"><p>32 x 32.1 </p><div style="height:32px; background-position:-16px -16px;" class="image"></div></div>
<div class="cell"><p>32 x 32.5 </p><div style="height:33px; background-position:-16px -15px;" class="image"></div></div>
<div class="cell"><p>32 x 32.8 </p><div style="height:33px; background-position:-16px -15px;" class="image"></div></div>
<div class="cell"><p>32 x 32.5 </p><div style="height:33px; background-position:-16px -16px;" class="image"></div></div>
<div class="cell"><p>32 x 32.8 </p><div style="height:33px; background-position:-16px -16px;" class="image"></div></div>
</div>
</body></html>

Просмотреть файл

@ -0,0 +1,7 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="background:url(mozilla-banner.gif); width:600px; height:58px;"></div>
<div style="margin-left: 100px; background:url(mozilla-banner.gif) -100px 0px; width:1px; height:58px;"></div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,7 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="background:url(mozilla-banner.gif); width:600px; height:58px;"></div>
<div style="margin-left: 100.4px; background:url(mozilla-banner.gif) -100.4px 0px; width:0.2px; height:58px;"></div>
</body>
</html>

Просмотреть файл

@ -960,3 +960,4 @@ fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == 456147.xul 456147-ref.html # bug 456147
fails == 461512-1.html 461512-1-ref.html # Bug 461512
== 463204-1.html 463204-1-ref.html
== 463217-1.xul 463217-1-ref.xul
== 464811-1.html 464811-1-ref.thml