mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 578309 - mask and clipPath applied to foreignObject are translated. r=roc a=blocking
This commit is contained in:
parent
f7d3ed83ed
commit
c28d8f49a4
@ -104,21 +104,6 @@ NS_IMETHODIMP nsSVGForeignObjectElement::GetHeight(nsIDOMSVGAnimatedLength * *aH
|
||||
return mLengthAttributes[HEIGHT].ToDOMAnimatedLength(aHeight, this);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGElement methods
|
||||
|
||||
/* virtual */ gfxMatrix
|
||||
nsSVGForeignObjectElement::PrependLocalTransformTo(const gfxMatrix &aMatrix)
|
||||
{
|
||||
// 'transform' attribute:
|
||||
gfxMatrix matrix = nsSVGForeignObjectElementBase::PrependLocalTransformTo(aMatrix);
|
||||
|
||||
// now translate by our 'x' and 'y':
|
||||
float x, y;
|
||||
GetAnimatedLengthValues(&x, &y, nsnull);
|
||||
return gfxMatrix().Translate(gfxPoint(x, y)) * matrix;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIContent methods
|
||||
|
||||
|
@ -66,9 +66,6 @@ public:
|
||||
NS_FORWARD_NSIDOMELEMENT(nsSVGForeignObjectElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGForeignObjectElementBase::)
|
||||
|
||||
// nsSVGElement specializations:
|
||||
virtual gfxMatrix PrependLocalTransformTo(const gfxMatrix &aMatrix);
|
||||
|
||||
// nsIContent interface
|
||||
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* name) const;
|
||||
|
||||
|
22
layout/reftests/svg/clipPath-basic-05.svg
Normal file
22
layout/reftests/svg/clipPath-basic-05.svg
Normal file
@ -0,0 +1,22 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
|
||||
|
||||
<title>Testcase for basic clipPath on foreignObject</title>
|
||||
|
||||
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=578309 -->
|
||||
|
||||
<defs>
|
||||
<clipPath id="clip">
|
||||
<rect x="20" y="20" width="100" height="100"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="lime"/>
|
||||
|
||||
<rect x="20" y="20" width="100" height="100" fill="red"/>
|
||||
<foreignObject x="20" y="20" width="100" height="100" clip-path="url(#clip)">
|
||||
<svg>
|
||||
<rect width="100" height="100" fill="lime"/>
|
||||
</svg>
|
||||
</foreignObject>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 593 B |
@ -26,6 +26,7 @@ include svg-integration/reftest.list
|
||||
== clipPath-basic-02.svg pass.svg
|
||||
== clipPath-basic-03.svg pass.svg
|
||||
== clipPath-basic-04.svg pass.svg
|
||||
== clipPath-basic-05.svg pass.svg
|
||||
== clipPath-winding-01.svg pass.svg
|
||||
== clip-surface-clone-01.svg clip-surface-clone-01-ref.svg
|
||||
== conditions-01.svg pass.svg
|
||||
|
@ -206,12 +206,11 @@ nsSVGForeignObjectFrame::PaintSVG(nsSVGRenderState *aContext,
|
||||
if (!kid)
|
||||
return NS_OK;
|
||||
|
||||
gfxMatrix matrixForChildren = GetCanvasTMForChildren();
|
||||
gfxMatrix matrix = GetCanvasTM();
|
||||
gfxMatrix matrix = GetCanvasTMWithTranslation();
|
||||
|
||||
nsIRenderingContext *ctx = aContext->GetRenderingContext(this);
|
||||
|
||||
if (!ctx || matrixForChildren.IsSingular()) {
|
||||
if (!ctx || matrix.IsSingular()) {
|
||||
NS_WARNING("Can't render foreignObject element!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -237,7 +236,7 @@ nsSVGForeignObjectFrame::PaintSVG(nsSVGRenderState *aContext,
|
||||
nsSVGUtils::SetClipRect(gfx, matrix, clipRect);
|
||||
}
|
||||
|
||||
gfx->Multiply(matrixForChildren);
|
||||
gfx->Multiply(GetScaledMatrixForChildren(matrix));
|
||||
|
||||
// Transform the dirty rect into the rectangle containing the
|
||||
// transformed dirty rect.
|
||||
@ -277,7 +276,7 @@ nsSVGForeignObjectFrame::GetTransformMatrix(nsIFrame **aOutAncestor)
|
||||
NS_ASSERTION(*aOutAncestor, "How did we end up without an outer frame?");
|
||||
|
||||
/* Return the matrix back to the root, factoring in the x and y offsets. */
|
||||
return GetCanvasTMForChildren();
|
||||
return GetScaledMatrixForChildren(GetCanvasTMWithTranslation());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsIFrame*)
|
||||
@ -290,11 +289,7 @@ nsSVGForeignObjectFrame::GetFrameForPoint(const nsPoint &aPoint)
|
||||
if (!kid)
|
||||
return nsnull;
|
||||
|
||||
float x, y, width, height;
|
||||
static_cast<nsSVGElement*>(mContent)->
|
||||
GetAnimatedLengthValues(&x, &y, &width, &height, nsnull);
|
||||
|
||||
gfxMatrix tm = GetCanvasTM().Invert();
|
||||
gfxMatrix tm = GetCanvasTMWithTranslation().Invert();
|
||||
if (tm.IsSingular())
|
||||
return nsnull;
|
||||
|
||||
@ -303,6 +298,10 @@ nsSVGForeignObjectFrame::GetFrameForPoint(const nsPoint &aPoint)
|
||||
gfxPoint pt = gfxPoint(aPoint.x, aPoint.y) / PresContext()->AppUnitsPerDevPixel();
|
||||
pt = tm.Transform(pt);
|
||||
|
||||
float x, y, width, height;
|
||||
static_cast<nsSVGElement*>(mContent)->
|
||||
GetAnimatedLengthValues(&x, &y, &width, &height, nsnull);
|
||||
|
||||
if (!gfxRect(0.0f, 0.0f, width, height).Contains(pt))
|
||||
return nsnull;
|
||||
|
||||
@ -338,8 +337,8 @@ nsSVGForeignObjectFrame::UpdateCoveredRegion()
|
||||
if (w < 0.0f) w = 0.0f;
|
||||
if (h < 0.0f) h = 0.0f;
|
||||
|
||||
// GetCanvasTM includes the x,y translation
|
||||
mRect = ToCanvasBounds(gfxRect(0.0, 0.0, w, h), GetCanvasTM(), PresContext());
|
||||
mRect = ToCanvasBounds(gfxRect(0.0, 0.0, w, h), GetCanvasTMWithTranslation(),
|
||||
PresContext());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -453,11 +452,9 @@ nsSVGForeignObjectFrame::GetBBoxContribution(const gfxMatrix &aToBBoxUserspace)
|
||||
NS_ASSERTION(!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD),
|
||||
"Should not be calling this on a non-display child");
|
||||
|
||||
nsSVGForeignObjectElement *content =
|
||||
static_cast<nsSVGForeignObjectElement*>(mContent);
|
||||
|
||||
float x, y, w, h;
|
||||
content->GetAnimatedLengthValues(&x, &y, &w, &h, nsnull);
|
||||
static_cast<nsSVGForeignObjectElement*>(mContent)->
|
||||
GetAnimatedLengthValues(&x, &y, &w, &h, nsnull);
|
||||
|
||||
if (w < 0.0f) w = 0.0f;
|
||||
if (h < 0.0f) h = 0.0f;
|
||||
@ -492,12 +489,22 @@ nsSVGForeignObjectFrame::GetCanvasTM()
|
||||
// Implementation helpers
|
||||
|
||||
gfxMatrix
|
||||
nsSVGForeignObjectFrame::GetCanvasTMForChildren()
|
||||
nsSVGForeignObjectFrame::GetCanvasTMWithTranslation()
|
||||
{
|
||||
float x, y;
|
||||
static_cast<nsSVGElement*>(mContent)->
|
||||
GetAnimatedLengthValues(&x, &y, nsnull);
|
||||
|
||||
return (gfxMatrix().Translate(gfxPoint(x, y)) * GetCanvasTM());
|
||||
}
|
||||
|
||||
gfxMatrix
|
||||
nsSVGForeignObjectFrame::GetScaledMatrixForChildren(gfxMatrix canvasTMWithTranslation) const
|
||||
{
|
||||
float cssPxPerDevPx = PresContext()->
|
||||
AppUnitsToFloatCSSPixels(PresContext()->AppUnitsPerDevPixel());
|
||||
|
||||
return GetCanvasTM().Scale(cssPxPerDevPx, cssPxPerDevPx);
|
||||
return canvasTMWithTranslation.Scale(cssPxPerDevPx, cssPxPerDevPx);
|
||||
}
|
||||
|
||||
void nsSVGForeignObjectFrame::RequestReflow(nsIPresShell::IntrinsicDirty aType)
|
||||
@ -630,7 +637,7 @@ nsSVGForeignObjectFrame::InvalidateDirtyRect(nsSVGOuterSVGFrame* aOuter,
|
||||
gfxRect r(aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
r.Scale(1.0 / nsPresContext::AppUnitsPerCSSPixel());
|
||||
|
||||
nsRect rect = ToCanvasBounds(r, GetCanvasTM(), PresContext());
|
||||
nsRect rect = ToCanvasBounds(r, GetCanvasTMWithTranslation(), PresContext());
|
||||
|
||||
// Don't invalidate areas outside our bounds:
|
||||
rect.IntersectRect(rect, mRect);
|
||||
|
@ -145,9 +145,10 @@ protected:
|
||||
void RequestReflow(nsIPresShell::IntrinsicDirty aType);
|
||||
void UpdateGraphic();
|
||||
|
||||
// Returns GetCanvasTM followed by a scale from CSS px to Dev px. Used for
|
||||
// painting, because children expect to paint to device space, not userspace.
|
||||
gfxMatrix GetCanvasTMForChildren();
|
||||
gfxMatrix GetCanvasTMWithTranslation();
|
||||
// Scale TM from CSS px to Dev px. Used for painting, because children
|
||||
// expect to paint to device space, not userspace.
|
||||
gfxMatrix GetScaledMatrixForChildren(gfxMatrix canvasTMWithTranslation) const;
|
||||
void InvalidateDirtyRect(nsSVGOuterSVGFrame* aOuter,
|
||||
const nsRect& aRect, PRUint32 aFlags);
|
||||
void FlushDirtyRegion();
|
||||
|
Loading…
Reference in New Issue
Block a user