From f5b9109022e1826e113a95cce0e902634fcff53c Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 18 Nov 2008 20:48:46 +1300 Subject: [PATCH] Bug 464811. Snap the anchor point to pixels using a method that guarantees the source rect and the subimage rect intersect. r+sr=dbaron --- layout/base/nsLayoutUtils.cpp | 42 +++++++++++++++++++++----- layout/reftests/bugs/433640-1-ref.html | 8 ++--- layout/reftests/bugs/464811-1-ref.html | 7 +++++ layout/reftests/bugs/464811-1.html | 7 +++++ layout/reftests/bugs/reftest.list | 1 + 5 files changed, 54 insertions(+), 11 deletions(-) create mode 100644 layout/reftests/bugs/464811-1-ref.html create mode 100644 layout/reftests/bugs/464811-1.html diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index aff6d05b097f..6cd2870d03bb 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -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,15 +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; + 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); anchorPoint.Round(); // 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 // 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) { diff --git a/layout/reftests/bugs/433640-1-ref.html b/layout/reftests/bugs/433640-1-ref.html index b99f710ace7a..49ff9596a47c 100644 --- a/layout/reftests/bugs/433640-1-ref.html +++ b/layout/reftests/bugs/433640-1-ref.html @@ -28,8 +28,8 @@

32 x 32

32.1 x 32

-

32.5 x 32

-

32.8 x 32

+

32.5 x 32

+

32.8 x 32

@@ -42,8 +42,8 @@

32 x 32

32 x 32.1

-

32 x 32.5

-

32 x 32.8

+

32 x 32.5

+

32 x 32.8

diff --git a/layout/reftests/bugs/464811-1-ref.html b/layout/reftests/bugs/464811-1-ref.html new file mode 100644 index 000000000000..daf09b483b2a --- /dev/null +++ b/layout/reftests/bugs/464811-1-ref.html @@ -0,0 +1,7 @@ + + + +
+
+ + diff --git a/layout/reftests/bugs/464811-1.html b/layout/reftests/bugs/464811-1.html new file mode 100644 index 000000000000..8d20db8f1172 --- /dev/null +++ b/layout/reftests/bugs/464811-1.html @@ -0,0 +1,7 @@ + + + +
+
+ + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 9630338e773b..e4c8dcb3883a 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -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.html