Bug 1078337 - Correctly respect the source rect in DrawSingleImage. r=seth
This commit is contained in:
@@ -5310,31 +5310,39 @@ nsLayoutUtils::DrawSingleImage(nsRenderingContext* aRenderingContext,
|
|||||||
uint32_t aImageFlags,
|
uint32_t aImageFlags,
|
||||||
const nsRect* aSourceArea)
|
const nsRect* aSourceArea)
|
||||||
{
|
{
|
||||||
nsIntSize imageSize(ComputeSizeForDrawingWithFallback(aImage, aDest.Size()));
|
nscoord appUnitsPerCSSPixel = nsDeviceContext::AppUnitsPerCSSPixel();
|
||||||
NS_ENSURE_TRUE(imageSize.width > 0 && imageSize.height > 0, NS_ERROR_FAILURE);
|
nsIntSize pixelImageSize(ComputeSizeForDrawingWithFallback(aImage, aDest.Size()));
|
||||||
|
NS_ENSURE_TRUE(pixelImageSize.width > 0 && pixelImageSize.height > 0, NS_ERROR_FAILURE);
|
||||||
|
nsSize imageSize(pixelImageSize.width * appUnitsPerCSSPixel,
|
||||||
|
pixelImageSize.height * appUnitsPerCSSPixel);
|
||||||
|
|
||||||
nsRect source;
|
nsRect source;
|
||||||
nsCOMPtr<imgIContainer> image;
|
nsCOMPtr<imgIContainer> image;
|
||||||
if (aSourceArea) {
|
if (aSourceArea) {
|
||||||
source = *aSourceArea;
|
source = *aSourceArea;
|
||||||
nsIntRect subRect(source.x, source.y, source.width, source.height);
|
nsIntRect subRect(source.x, source.y, source.width, source.height);
|
||||||
subRect.ScaleInverseRoundOut(nsDeviceContext::AppUnitsPerCSSPixel());
|
subRect.ScaleInverseRoundOut(appUnitsPerCSSPixel);
|
||||||
image = ImageOps::Clip(aImage, subRect);
|
image = ImageOps::Clip(aImage, subRect);
|
||||||
|
|
||||||
|
nsRect imageRect;
|
||||||
|
imageRect.SizeTo(imageSize);
|
||||||
|
nsRect clippedSource = imageRect.Intersect(source);
|
||||||
|
|
||||||
|
source -= clippedSource.TopLeft();
|
||||||
|
imageSize = clippedSource.Size();
|
||||||
} else {
|
} else {
|
||||||
nscoord appUnitsPerCSSPixel = nsDeviceContext::AppUnitsPerCSSPixel();
|
source.SizeTo(imageSize);
|
||||||
source.SizeTo(imageSize.width*appUnitsPerCSSPixel,
|
|
||||||
imageSize.height*appUnitsPerCSSPixel);
|
|
||||||
image = aImage;
|
image = aImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRect dest = nsLayoutUtils::GetWholeImageDestination(imageSize, source,
|
nsRect dest = GetWholeImageDestination(imageSize, source, aDest);
|
||||||
aDest);
|
|
||||||
// Ensure that only a single image tile is drawn. If aSourceArea extends
|
// Ensure that only a single image tile is drawn. If aSourceArea extends
|
||||||
// outside the image bounds, we want to honor the aSourceArea-to-aDest
|
// outside the image bounds, we want to honor the aSourceArea-to-aDest
|
||||||
// transform but we don't want to actually tile the image.
|
// transform but we don't want to actually tile the image.
|
||||||
nsRect fill;
|
nsRect fill;
|
||||||
fill.IntersectRect(aDest, dest);
|
fill.IntersectRect(aDest, dest);
|
||||||
return DrawImageInternal(aRenderingContext, aPresContext, aImage,
|
return DrawImageInternal(aRenderingContext, aPresContext, image,
|
||||||
aGraphicsFilter, dest, fill, fill.TopLeft(),
|
aGraphicsFilter, dest, fill, fill.TopLeft(),
|
||||||
aDirty, aSVGContext, aImageFlags);
|
aDirty, aSVGContext, aImageFlags);
|
||||||
}
|
}
|
||||||
@@ -5445,7 +5453,7 @@ nsLayoutUtils::DrawImage(nsRenderingContext* aRenderingContext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* static */ nsRect
|
/* static */ nsRect
|
||||||
nsLayoutUtils::GetWholeImageDestination(const nsIntSize& aWholeImageSize,
|
nsLayoutUtils::GetWholeImageDestination(const nsSize& aWholeImageSize,
|
||||||
const nsRect& aImageSourceArea,
|
const nsRect& aImageSourceArea,
|
||||||
const nsRect& aDestArea)
|
const nsRect& aDestArea)
|
||||||
{
|
{
|
||||||
@@ -5453,13 +5461,24 @@ nsLayoutUtils::GetWholeImageDestination(const nsIntSize& aWholeImageSize,
|
|||||||
double scaleY = double(aDestArea.height)/aImageSourceArea.height;
|
double scaleY = double(aDestArea.height)/aImageSourceArea.height;
|
||||||
nscoord destOffsetX = NSToCoordRound(aImageSourceArea.x*scaleX);
|
nscoord destOffsetX = NSToCoordRound(aImageSourceArea.x*scaleX);
|
||||||
nscoord destOffsetY = NSToCoordRound(aImageSourceArea.y*scaleY);
|
nscoord destOffsetY = NSToCoordRound(aImageSourceArea.y*scaleY);
|
||||||
nscoord appUnitsPerCSSPixel = nsDeviceContext::AppUnitsPerCSSPixel();
|
nscoord wholeSizeX = NSToCoordRound(aWholeImageSize.width*scaleX);
|
||||||
nscoord wholeSizeX = NSToCoordRound(aWholeImageSize.width*appUnitsPerCSSPixel*scaleX);
|
nscoord wholeSizeY = NSToCoordRound(aWholeImageSize.height*scaleY);
|
||||||
nscoord wholeSizeY = NSToCoordRound(aWholeImageSize.height*appUnitsPerCSSPixel*scaleY);
|
|
||||||
return nsRect(aDestArea.TopLeft() - nsPoint(destOffsetX, destOffsetY),
|
return nsRect(aDestArea.TopLeft() - nsPoint(destOffsetX, destOffsetY),
|
||||||
nsSize(wholeSizeX, wholeSizeY));
|
nsSize(wholeSizeX, wholeSizeY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ nsRect
|
||||||
|
nsLayoutUtils::GetWholeImageDestination(const nsIntSize& aWholeImageSize,
|
||||||
|
const nsRect& aImageSourceArea,
|
||||||
|
const nsRect& aDestArea)
|
||||||
|
{
|
||||||
|
nscoord appUnitsPerCSSPixel = nsDeviceContext::AppUnitsPerCSSPixel();
|
||||||
|
return GetWholeImageDestination(nsSize(aWholeImageSize.width * appUnitsPerCSSPixel,
|
||||||
|
aWholeImageSize.height * appUnitsPerCSSPixel),
|
||||||
|
aImageSourceArea,
|
||||||
|
aDestArea);
|
||||||
|
}
|
||||||
|
|
||||||
/* static */ already_AddRefed<imgIContainer>
|
/* static */ already_AddRefed<imgIContainer>
|
||||||
nsLayoutUtils::OrientImage(imgIContainer* aContainer,
|
nsLayoutUtils::OrientImage(imgIContainer* aContainer,
|
||||||
const nsStyleImageOrientation& aOrientation)
|
const nsStyleImageOrientation& aOrientation)
|
||||||
|
|||||||
@@ -1613,6 +1613,10 @@ public:
|
|||||||
const nsRect& aImageSourceArea,
|
const nsRect& aImageSourceArea,
|
||||||
const nsRect& aDestArea);
|
const nsRect& aDestArea);
|
||||||
|
|
||||||
|
static nsRect GetWholeImageDestination(const nsSize& aWholeImageSize,
|
||||||
|
const nsRect& aImageSourceArea,
|
||||||
|
const nsRect& aDestArea);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an image container and an orientation, returns an image container
|
* Given an image container and an orientation, returns an image container
|
||||||
* that contains the same image, reoriented appropriately. May return the
|
* that contains the same image, reoriented appropriately. May return the
|
||||||
|
|||||||
Reference in New Issue
Block a user