mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 769103 - Get SVG masks working for HTML elements under CSS transforms. r=roc.
This commit is contained in:
parent
53377817cd
commit
85c5167bf8
@ -0,0 +1,42 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Test SVG masking of transformed HTML elements</title>
|
||||
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=769103 -->
|
||||
<style type="text/css">
|
||||
|
||||
* { margin: 0; border: 0; padding: 0;}
|
||||
|
||||
div {
|
||||
position: absolute;
|
||||
left: 1px;
|
||||
top: 1px;
|
||||
width: 3px;
|
||||
height: 3px;
|
||||
-moz-transform: scale(100,100);
|
||||
-moz-transform-origin: 0 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body bgcolor="lime">
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300"
|
||||
style="display:block; position:absolute;">
|
||||
<mask id="mask1" x="0" y="0" width="1" height="1" maskContentUnits="objectBoundingBox">
|
||||
<circle cx="0.5" cy="0.5" r="0.48" fill="white"/>
|
||||
</mask>
|
||||
<mask id="mask2" x="0" y="0" width="1" height="1" maskContentUnits="objectBoundingBox">
|
||||
<circle cx="0.5" cy="0.5" r="0.5" fill="white"/>
|
||||
</mask>
|
||||
<circle cx="150" cy="150" r="147" fill="red"/>
|
||||
</svg>
|
||||
|
||||
<div style="background: red; mask: url(#mask1);"/>
|
||||
<div style="background: lime; mask: url(#mask2);"/>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,42 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Test SVG masking of transformed HTML elements</title>
|
||||
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=769103 -->
|
||||
<style type="text/css">
|
||||
|
||||
* { margin: 0; border: 0; padding: 0;}
|
||||
|
||||
div {
|
||||
position: absolute;
|
||||
left: 50px;
|
||||
top: 50px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
-moz-transform: scale(2,2);
|
||||
-moz-transform-origin: 0 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body bgcolor="lime">
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="350" height="350"
|
||||
style="display:block; position:absolute;">
|
||||
<mask id="mask1" x="0" y="0" width="1" height="1" maskContentUnits="objectBoundingBox">
|
||||
<circle cx="0.5" cy="0.5" r="0.48" fill="white"/>
|
||||
</mask>
|
||||
<mask id="mask2" x="0" y="0" width="1" height="1" maskContentUnits="objectBoundingBox">
|
||||
<circle cx="0.5" cy="0.5" r="0.50" fill="white"/>
|
||||
</mask>
|
||||
<circle cx="200" cy="200" r="147" fill="red"/>
|
||||
</svg>
|
||||
|
||||
<div style="background: red; mask: url(#mask1);"/>
|
||||
<div style="background: lime; mask: url(#mask2);"/>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -25,3 +25,7 @@
|
||||
== mask-html-01-extref-02.xhtml mask-html-01-ref.svg
|
||||
== mask-html-zoomed-01.xhtml mask-html-01-ref.svg
|
||||
== mask-html-xbl-bound-01.html mask-html-01-ref.svg
|
||||
== mask-transformed-html-01.xhtml ../pass.svg
|
||||
== mask-transformed-html-02.xhtml ../pass.svg
|
||||
|
||||
|
||||
|
@ -53,18 +53,14 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsRenderingContext *aContext,
|
||||
|
||||
gfxContext *gfx = aContext->ThebesContext();
|
||||
|
||||
// Get the clip extents in device space:
|
||||
gfx->Save();
|
||||
nsSVGUtils::SetClipRect(gfx, aMatrix, maskArea);
|
||||
gfx->IdentityMatrix();
|
||||
gfxRect clipExtents = gfx->GetClipExtents();
|
||||
clipExtents.RoundOut();
|
||||
gfx->Restore();
|
||||
|
||||
#ifdef DEBUG_tor
|
||||
fprintf(stderr, "clip extent: %f,%f %fx%f\n",
|
||||
clipExtents.X(), clipExtents.Y(),
|
||||
clipExtents.Width(), clipExtents.Height());
|
||||
#endif
|
||||
|
||||
bool resultOverflows;
|
||||
gfxIntSize surfaceSize =
|
||||
nsSVGUtils::ConvertToSurfaceSize(gfxSize(clipExtents.Width(),
|
||||
@ -82,10 +78,19 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsRenderingContext *aContext,
|
||||
new gfxImageSurface(surfaceSize, gfxASurface::ImageFormatARGB32);
|
||||
if (!image || image->CairoStatus())
|
||||
return nsnull;
|
||||
image->SetDeviceOffset(-clipExtents.TopLeft());
|
||||
|
||||
// We would like to use gfxImageSurface::SetDeviceOffset() to position
|
||||
// 'image'. However, we need to set the same matrix on the temporary context
|
||||
// and pattern that we create below as is currently set on 'gfx'.
|
||||
// Unfortunately, any device offset set by SetDeviceOffset() is affected by
|
||||
// the transform passed to the SetMatrix() calls, so to avoid that we account
|
||||
// for the device offset in the transform rather than use SetDeviceOffset().
|
||||
gfxMatrix matrix =
|
||||
gfx->CurrentMatrix() * gfxMatrix().Translate(-clipExtents.TopLeft());
|
||||
|
||||
nsRenderingContext tmpCtx;
|
||||
tmpCtx.Init(this->PresContext()->DeviceContext(), image);
|
||||
tmpCtx.ThebesContext()->SetMatrix(matrix);
|
||||
|
||||
mMaskParent = aParent;
|
||||
if (mMaskParentMatrix) {
|
||||
@ -132,6 +137,7 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsRenderingContext *aContext,
|
||||
}
|
||||
|
||||
gfxPattern *retval = new gfxPattern(image);
|
||||
retval->SetMatrix(matrix);
|
||||
NS_IF_ADDREF(retval);
|
||||
return retval;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user