Bug 619500: Part 2. When drawing an SVG image as a CSS border-image, use preverveAspectRatio="none"; r=dholbert

MozReview-Commit-ID: JH5E3An4opJ
This commit is contained in:
CJKu 2016-03-08 15:54:13 +08:00
parent 19414f3998
commit d57efebb5f
3 changed files with 41 additions and 5 deletions

View File

@ -828,15 +828,32 @@ VectorImage::Draw(gfxContext* aContext,
AutoRestore<bool> autoRestoreIsDrawing(mIsDrawing);
mIsDrawing = true;
Maybe<SVGImageContext> svgContext;
// If FLAG_FORCE_PRESERVEASPECTRATIO_NONE bit is set, that mean we should
// overwrite SVG preserveAspectRatio attibute of this image with none, and
// always stretch this image to viewport non-uniformly.
// And we can do this only if the caller pass in the the SVG viewport, via
// aSVGContext.
if ((aFlags & FLAG_FORCE_PRESERVEASPECTRATIO_NONE) && aSVGContext.isSome()) {
Maybe<SVGPreserveAspectRatio> aspectRatio =
Some(SVGPreserveAspectRatio(SVG_PRESERVEASPECTRATIO_NONE,
SVG_MEETORSLICE_UNKNOWN));
svgContext =
Some(SVGImageContext(aSVGContext->GetViewportSize(),
aspectRatio));
} else {
svgContext = aSVGContext;
}
float animTime =
(aWhichFrame == FRAME_FIRST) ? 0.0f
: mSVGDocumentWrapper->GetCurrentTime();
AutoSVGRenderingState autoSVGState(aSVGContext, animTime,
AutoSVGRenderingState autoSVGState(svgContext, animTime,
mSVGDocumentWrapper->GetRootSVGElem());
// Pack up the drawing parameters.
SVGDrawingParameters params(aContext, aSize, aRegion, aFilter,
aSVGContext, animTime, aFlags);
svgContext, animTime, aFlags);
if (aFlags & FLAG_BYPASS_SURFACE_CACHE) {
CreateSurfaceAndShow(params);

View File

@ -181,6 +181,16 @@ interface imgIContainer : nsISupports
* cached rendering from the surface cache. This is used when we are printing,
* for example, where we want the vector commands from VectorImages to end up
* in the PDF output rather than a cached rendering at screen resolution.
*
* FLAG_FORCE_PRESERVEASPECTRATIO_NONE: Force scaling this image
* non-uniformly if necessary. This flag is for vector image only. A raster
* image should ignore this flag. While drawing a vector image with this
* flag, do not force uniform scaling even if its root <svg> node has a
* preserveAspectRatio attribute that would otherwise require uniform
* scaling , such as xMinYMin/ xMidYMin. Always scale the graphic content of
* the given image non-uniformly if necessary such that the image's
* viewBox (if specified or implied by height/width attributes) exactly
* matches the viewport rectangle.
*/
const unsigned long FLAG_NONE = 0x0;
const unsigned long FLAG_SYNC_DECODE = 0x1;
@ -192,6 +202,7 @@ interface imgIContainer : nsISupports
const unsigned long FLAG_HIGH_QUALITY_SCALING = 0x40;
const unsigned long FLAG_WANT_DATA_SURFACE = 0x80;
const unsigned long FLAG_BYPASS_SURFACE_CACHE = 0x100;
const unsigned long FLAG_FORCE_PRESERVEASPECTRATIO_NONE = 0x200;
/**
* A constant specifying the default set of decode flags (i.e., the default

View File

@ -5280,6 +5280,14 @@ nsImageRenderer::DrawBorderImageComponent(nsPresContext* aPresContext,
if (mType == eStyleImageType_Image || mType == eStyleImageType_Element) {
nsCOMPtr<imgIContainer> subImage;
// To draw one portion of an image into a border component, we stretch that
// portion to match the size of that border component and then draw onto.
// However, preserveAspectRatio attribute of a SVG image may break this rule.
// To get correct rendering result, we add
// FLAG_FORCE_PRESERVEASPECTRATIO_NONE flag here, to tell mImage to ignore
// preserveAspectRatio attribute, and always do non-uniform stretch.
uint32_t drawFlags = ConvertImageRendererToDrawFlags(mFlags) |
imgIContainer::FLAG_FORCE_PRESERVEASPECTRATIO_NONE;
// Retrieve or create the subimage we'll draw.
nsIntRect srcRect(aSrc.x, aSrc.y, aSrc.width, aSrc.height);
if (mType == eStyleImageType_Image) {
@ -5319,7 +5327,7 @@ nsImageRenderer::DrawBorderImageComponent(nsPresContext* aPresContext,
filter,
aFill, aDirtyRect,
nullptr,
ConvertImageRendererToDrawFlags(mFlags));
drawFlags);
}
nsRect tile = ComputeTile(aFill, aHFill, aVFill, aUnitSize);
@ -5328,7 +5336,7 @@ nsImageRenderer::DrawBorderImageComponent(nsPresContext* aPresContext,
subImage,
filter,
tile, aFill, tile.TopLeft(), aDirtyRect,
ConvertImageRendererToDrawFlags(mFlags));
drawFlags);
}
nsRect destTile = RequiresScaling(aFill, aHFill, aVFill, aUnitSize)