Bug 1556713 - Transform dirtyRect down to <image> r=longsonr

aDirtyRect in PaintSVG() is in outer <svg> coordinate. Image painting
API needs dirty rect in image coordinate. We need to transform it.

Differential Revision: https://phabricator.services.mozilla.com/D33813

--HG--
extra : moz-landing-system : lando
This commit is contained in:
violet 2019-06-06 14:54:40 +00:00
Родитель 89baee69d9
Коммит fbc30b61cd
4 изменённых файлов: 42 добавлений и 4 удалений

Просмотреть файл

@ -0,0 +1,7 @@
<svg width="400" height="400">
<mask id="m">
<image x="20" y="20" width="100" height="100"
href="data:image/svg+xml,<svg width='100' height='100' xmlns='http://www.w3.org/2000/svg'><rect width='100%' height='100%' fill='red' /></svg>" />
</mask>
<rect mask="url(#m)" x="50" y="50" width="50%" height="50%" fill="black"></rect>
</svg>

После

Ширина:  |  Высота:  |  Размер: 355 B

Просмотреть файл

@ -0,0 +1,9 @@
<svg width="400" height="400" viewBox="0 0 800 800">
<mask id="m">
<g transform="scale(.5,.5)">
<image filter="blur(0)" x="80" y="80" width="400" height="400"
href="data:image/svg+xml,<svg width='100' height='100' xmlns='http://www.w3.org/2000/svg'><rect width='100%' height='100%' fill='red' /></svg>" />
</g>
</mask>
<rect mask="url(#m)" x="100" y="100" width="50%" height="50%" fill="black"></rect>
</svg>

После

Ширина:  |  Высота:  |  Размер: 442 B

Просмотреть файл

@ -58,6 +58,7 @@ skip == blend-difference-stacking.html blend-difference-stacking-ref.html # bug
fuzzy(0-11,0-7155) == blur-inside-clipPath.svg blur-inside-clipPath-ref.svg
== border-radius-01.html pass.svg
== mask-image-filter-transform.html mask-image-filter-transform-ref.html
== clip-01.svg pass.svg
== clip-02a.svg clip-02-ref.svg

Просмотреть файл

@ -307,10 +307,31 @@ void nsSVGImageFrame::PaintSVG(gfxContext& aContext,
(mState & NS_FRAME_IS_NONDISPLAY),
"Display lists handle dirty rect intersection test");
dirtyRect = ToAppUnits(*aDirtyRect, appUnitsPerDevPx);
// Adjust dirtyRect to match our local coordinate system.
nsRect rootRect = nsSVGUtils::TransformFrameRectToOuterSVG(
mRect, aTransform, PresContext());
dirtyRect.MoveBy(-rootRect.TopLeft());
// dirtyRect is relative to the outer <svg>, we should transform it
// down to <image>.
Rect dir(dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height);
dir.Scale(1.f / AppUnitsPerCSSPixel());
// FIXME: This isn't correct if there is an inner <svg> enclosing
// the <image>. But that seems to be a quite obscure usecase, we can
// add a dedicated utility for that purpose to replace the GetCTM
// here if necessary.
auto mat = SVGContentUtils::GetCTM(
static_cast<SVGImageElement*>(GetContent()), false);
if (mat.IsSingular()) {
return;
}
mat.Invert();
dir = mat.TransformRect(dir);
// x, y offset of <image> is not included in CTM.
dir.MoveBy(-x, -y);
dir.Scale(AppUnitsPerCSSPixel());
dir.Round();
dirtyRect = nsRect(dir.x, dir.y, dir.width, dir.height);
}
uint32_t flags = aImgParams.imageFlags;