--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -5439,30 +5439,37 @@ struct SnappedImageDrawingParameters {
// A transform from image space to device space.
gfxMatrix imageSpaceToDeviceSpace;
// The size at which the image should be drawn (which may not be its
// intrinsic size due to, for example, HQ scaling).
nsIntSize size;
// The region in tiled image space which will be drawn, with an associated
// region to which sampling should be restricted.
ImageRegion region;
+ // The default viewport size for SVG images, which we use unless a different
+ // one has been explicitly specified. This is the same as |size| except that
+ // it does not take into account any transformation on the gfxContext we're
+ // drawing to - for example, CSS transforms are not taken into account.
+ nsIntSize svgViewportSize;
// Whether there's anything to draw at all.
bool shouldDraw;
SnappedImageDrawingParameters()
: region(ImageRegion::Empty())
, shouldDraw(false)
{}
SnappedImageDrawingParameters(const gfxMatrix& aImageSpaceToDeviceSpace,
const nsIntSize& aSize,
- const ImageRegion& aRegion)
+ const ImageRegion& aRegion,
+ const nsIntSize& aSVGViewportSize)
: imageSpaceToDeviceSpace(aImageSpaceToDeviceSpace)
, size(aSize)
, region(aRegion)
+ , svgViewportSize(aSVGViewportSize)
, shouldDraw(true)
{}
};
/**
* Given two axis-aligned rectangles, returns the transformation that maps the
* first onto the second.
*
@@ -5567,16 +5574,21 @@ ComputeSnappedImageDrawingParameters(gfx
}
nsIntSize intImageSize =
aImage->OptimalImageSizeForDest(snappedScaledDest,
imgIContainer::FRAME_CURRENT,
aGraphicsFilter, aImageFlags);
gfxSize imageSize(intImageSize.width, intImageSize.height);
+ nsIntSize svgViewportSize = currentMatrix.IsIdentity()
+ ? intImageSize
+ : nsIntSize(NSAppUnitsToIntPixels(dest.width, aAppUnitsPerDevPixel),
+ NSAppUnitsToIntPixels(dest.height, aAppUnitsPerDevPixel));
+
// 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));
@@ -5644,17 +5656,19 @@ ComputeSnappedImageDrawingParameters(gfx
// get the final matrix we'll draw with, because we didn't take it into
// account when computing the matrices above.
if (!didSnap) {
transform = transform * currentMatrix;
}
ImageRegion region =
ImageRegion::CreateWithSamplingRestriction(imageSpaceFill, subimage);
- return SnappedImageDrawingParameters(transform, intImageSize, region);
+
+ return SnappedImageDrawingParameters(transform, intImageSize,
+ region, svgViewportSize);
}
static nsresult
DrawImageInternal(gfxContext& aContext,
nsPresContext* aPresContext,
imgIContainer* aImage,
GraphicsFilter aGraphicsFilter,
@@ -5682,18 +5696,24 @@ DrawImageInternal(gfxContext&
aGraphicsFilter, aImageFlags);
if (!params.shouldDraw)
return NS_OK;
gfxContextMatrixAutoSaveRestore contextMatrixRestorer(&aContext);
aContext.SetMatrix(params.imageSpaceToDeviceSpace);
+ Maybe<SVGImageContext> svgContext = ToMaybe(aSVGContext);
+ if (!svgContext) {
+ // Use the default viewport.
+ svgContext = Some(SVGImageContext(params.svgViewportSize, Nothing()));
+ }
+
aImage->Draw(&aContext, params.size, params.region, imgIContainer::FRAME_CURRENT,
- aGraphicsFilter, ToMaybe(aSVGContext), aImageFlags);
+ aGraphicsFilter, svgContext, aImageFlags);
return NS_OK;
}
/* static */ nsresult
nsLayoutUtils::DrawSingleUnscaledImage(gfxContext& aContext,
nsPresContext* aPresContext,
imgIContainer* aImage,