Bug 464811. Snap the anchor point to pixels using a method that guarantees the source rect and the subimage rect intersect. r+sr=dbaron

This commit is contained in:
Robert O'Callahan 2008-11-18 20:48:46 +13:00
Родитель af14965574
Коммит f5b9109022
5 изменённых файлов: 54 добавлений и 11 удалений

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

@ -2662,6 +2662,14 @@ nsLayoutUtils::GetClosestLayer(nsIFrame* aFrame)
return aFrame->PresContext()->PresShell()->FrameManager()->GetRootFrame(); 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 static gfxPoint
MapToFloatImagePixels(const nsIntSize& aSize, MapToFloatImagePixels(const nsIntSize& aSize,
const nsRect& aDest, const nsPoint& aPt) const nsRect& aDest, const nsPoint& aPt)
@ -2670,6 +2678,22 @@ MapToFloatImagePixels(const nsIntSize& aSize,
(gfxFloat(aPt.y - aDest.y)*aSize.height)/aDest.height); (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 /* static */ nsresult
nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext, nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
imgIContainer* aImage, imgIContainer* aImage,
@ -2733,15 +2757,22 @@ nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
// device unit! // device unit!
gfxPoint anchorPoint(aAnchor.x/appUnitsPerDevPixel, gfxPoint anchorPoint(aAnchor.x/appUnitsPerDevPixel,
aAnchor.y/appUnitsPerDevPixel); aAnchor.y/appUnitsPerDevPixel);
gfxPoint imageSpaceAnchorPoint =
MapToFloatImagePixels(imageSize, aDest, aAnchor);
gfxMatrix currentMatrix = ctx->CurrentMatrix(); gfxMatrix currentMatrix = ctx->CurrentMatrix();
gfxRect finalFillRect = fill; gfxRect finalFillRect = fill;
if (didSnap) { if (didSnap) {
NS_ASSERTION(!currentMatrix.HasNonAxisAlignedTransform(), NS_ASSERTION(!currentMatrix.HasNonAxisAlignedTransform(),
"How did we snap, then?"); "How did we snap, then?");
anchorPoint.x = fill.pos.x + imageSpaceAnchorPoint.Round();
(anchorPoint.x - devPixelFill.pos.x)*fill.size.width/devPixelFill.size.width; anchorPoint = imageSpaceAnchorPoint;
anchorPoint.y = fill.pos.y + gfxRect devPixelDest(aDest.x/appUnitsPerDevPixel,
(anchorPoint.y - devPixelFill.pos.y)*fill.size.height/devPixelFill.size.height; aDest.y/appUnitsPerDevPixel,
aDest.width/appUnitsPerDevPixel,
aDest.height/appUnitsPerDevPixel);
anchorPoint = MapToFloatUserPixels(imageSize, devPixelDest, anchorPoint);
anchorPoint = currentMatrix.Transform(anchorPoint);
anchorPoint.Round(); anchorPoint.Round();
// This form of Transform is safe to call since non-axis-aligned // This form of Transform is safe to call since non-axis-aligned
@ -2759,9 +2790,6 @@ nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
// to be aligned perfectly with pixel boundaries or the choice of // to be aligned perfectly with pixel boundaries or the choice of
// dirty rect will affect the values of rendered pixels. // 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 scaleX = imageSize.width*appUnitsPerDevPixel/aDest.width;
gfxFloat scaleY = imageSize.height*appUnitsPerDevPixel/aDest.height; gfxFloat scaleY = imageSize.height*appUnitsPerDevPixel/aDest.height;
if (didSnap) { if (didSnap) {

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

@ -28,8 +28,8 @@
<div> <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 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.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.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:-15px -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>
<div> <div>
@ -42,8 +42,8 @@
<div> <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 </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.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.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 -15px;" 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> </div>
</body></html> </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 fails == 461512-1.html 461512-1-ref.html # Bug 461512
== 463204-1.html 463204-1-ref.html == 463204-1.html 463204-1-ref.html
== 463217-1.xul 463217-1-ref.xul == 463217-1.xul 463217-1-ref.xul
== 464811-1.html 464811-1-ref.html