Bug 1290782 Part 1 - When drawing a border-image using an SVG image, we should not take into account any transformation of currentMatrix when computing svg viewport size. r?dholbert,cjku
MozReview-Commit-ID: 8rkwQGKJOvo
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -6529,18 +6529,18 @@ ComputeSnappedImageDrawingParameters(gfx
fill = devPixelFill;
dest = devPixelDest;
}
// If we snapped above, |dest| already takes into account |currentMatrix|'s scale
// and has integer coordinates. If not, we need these properties to compute
// the optimal drawn image size, so compute |snappedDestSize| here.
gfxSize snappedDestSize = dest.Size();
+ gfxSize scaleFactors = currentMatrix.ScaleFactors(true);
if (!didSnap) {
- gfxSize scaleFactors = currentMatrix.ScaleFactors(true);
snappedDestSize.Scale(scaleFactors.width, scaleFactors.height);
snappedDestSize.width = NS_round(snappedDestSize.width);
snappedDestSize.height = NS_round(snappedDestSize.height);
}
// We need to be sure that this is at least one pixel in width and height,
// or we'll end up drawing nothing even if we have a nonempty fill.
snappedDestSize.width = std::max(snappedDestSize.width, 1.0);
@@ -6550,23 +6550,35 @@ ComputeSnappedImageDrawingParameters(gfx
if (fill.IsEmpty() || snappedDestSize.IsEmpty()) {
return SnappedImageDrawingParameters();
}
nsIntSize intImageSize =
aImage->OptimalImageSizeForDest(snappedDestSize,
imgIContainer::FRAME_CURRENT,
aSamplingFilter, aImageFlags);
+
+ nsIntSize svgViewportSize;
+ if (scaleFactors.width == 1.0 && scaleFactors.height == 1.0) {
+ // intImageSize is scaled by currentMatrix. But since there are no scale
+ // factors in currentMatrix, it is safe to assign intImageSize to
+ // svgViewportSize directly.
+ svgViewportSize = intImageSize;
+ } else {
+ // We should not take into account any transformation of currentMatrix
+ // when computing svg viewport size. Since currentMatrix contains scale
+ // factors, we need to recompute SVG viewport by unscaled devPixelDest.
+ svgViewportSize = aImage->OptimalImageSizeForDest(devPixelDest.Size(),
+ imgIContainer::FRAME_CURRENT,
+ aSamplingFilter,
+ aImageFlags);
+ }
+
gfxSize imageSize(intImageSize.width, intImageSize.height);
- // XXX(seth): May be buggy; see bug 1151016.
- CSSIntSize svgViewportSize = currentMatrix.IsIdentity()
- ? CSSIntSize(intImageSize.width, intImageSize.height)
- : CSSIntSize::Truncate(devPixelDest.width, devPixelDest.height);
-
// Compute the set of pixels that would be sampled by an ideal rendering
gfxPoint subimageTopLeft =
MapToFloatImagePixels(imageSize, devPixelDest, devPixelFill.TopLeft());
gfxPoint subimageBottomRight =
MapToFloatImagePixels(imageSize, devPixelDest, devPixelFill.BottomRight());
gfxRect subimage;
subimage.MoveTo(NSToIntFloor(subimageTopLeft.x),
NSToIntFloor(subimageTopLeft.y));
@@ -6672,17 +6684,19 @@ ComputeSnappedImageDrawingParameters(gfx
MOZ_ASSERT(!(aImageFlags & imgIContainer::FLAG_CLAMP));
extendMode = ExtendMode::REPEAT;
}
ImageRegion region =
ImageRegion::CreateWithSamplingRestriction(imageSpaceFill, subimage, extendMode);
return SnappedImageDrawingParameters(transform, intImageSize,
- region, svgViewportSize);
+ region,
+ CSSIntSize(svgViewportSize.width,
+ svgViewportSize.height));
}
static DrawResult
DrawImageInternal(gfxContext& aContext,
nsPresContext* aPresContext,
imgIContainer* aImage,
const SamplingFilter aSamplingFilter,
const nsRect& aDest,