зеркало из https://github.com/mozilla/gecko-dev.git
Bug 534612 - clipPath references with clipPath elements do not work correctly. r=roc
This commit is contained in:
Родитель
1d0a08e5af
Коммит
63e32ef130
|
@ -0,0 +1,84 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
|
||||
|
||||
<title>Testcase for clipPath referencing other clipPaths</title>
|
||||
|
||||
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=534612 -->
|
||||
|
||||
<defs>
|
||||
<clipPath id="clip1">
|
||||
<rect id="r1" x="20" y="-40" width="100" height="40" />
|
||||
</clipPath>
|
||||
<clipPath id="clip2">
|
||||
<rect x="20" y="20" width="100" height="100" clip-path="url(#clip1)" />
|
||||
</clipPath>
|
||||
<clipPath id="clip3">
|
||||
<rect x="140" y="-40" width="100" height="40" />
|
||||
</clipPath>
|
||||
<clipPath id="clip4" clip-path="url(#clip3)">
|
||||
<rect x="140" y="20" width="100" height="100" />
|
||||
</clipPath>
|
||||
<clipPath id="clip1">
|
||||
<rect x="20" y="-40" width="100" height="40" />
|
||||
</clipPath>
|
||||
<clipPath id="clip5">
|
||||
<rect id="r5" x="20" y="140" width="100" height="100" />
|
||||
</clipPath>
|
||||
<clipPath id="clip6">
|
||||
<use xlink:href="#r5" clip-path="url(#clip5)" />
|
||||
</clipPath>
|
||||
<clipPath id="clip7">
|
||||
<rect id="r7" x="140" y="140" width="100" height="100" />
|
||||
</clipPath>
|
||||
<clipPath id="clip8">
|
||||
<use xlink:href="#r7" fill="red" clip-path="url(#clip1)"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip9">
|
||||
<rect x="20" y="260" width="100" height="100" />
|
||||
</clipPath>
|
||||
<clipPath id="clip10">
|
||||
<use xlink:href="#r1" fill="red" clip-path="url(#clip9)"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip11">
|
||||
<rect id="r11" x="140" y="260" width="100" height="100" clip-path="url(#clip1)"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip12">
|
||||
<use xlink:href="#r11" fill="red" clip-path="url(#clip11)"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip12" clipPathUnits="objectBoundingBox">
|
||||
<rect width=".5" height=".5"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip13" clip-path="url(#clip12)">
|
||||
<circle cx="100" cy="470" r="150"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip14">
|
||||
<use xlink:href="#clip1"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip15" clip-path="url(#clip14)">
|
||||
<text x="140" y="500" font-size="100px">CLIP</text>
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
<rect width="100%" height="100%" fill="lime" />
|
||||
<!-- clip path where an object is itself clipped -->
|
||||
<rect x="20" y="20" width="100" height="100" fill="red" clip-path="url(#clip2)" />
|
||||
|
||||
<!-- clip path referencing another clip-path -->
|
||||
<rect x="140" y="20" width="100" height="100" fill="red" clip-path="url(#clip4)" />
|
||||
|
||||
<!-- clip paths where object has complex clipping -->
|
||||
<rect x="20" y="140" width="100" height="100" fill="red" />
|
||||
<rect x="20" y="140" width="100" height="100" fill="lime" clip-path="url(#clip6)" />
|
||||
|
||||
<rect x="140" y="140" width="100" height="100" fill="red" clip-path="url(#clip8)" />
|
||||
|
||||
<rect x="20" y="260" width="100" height="100" fill="red" clip-path="url(#clip10)" />
|
||||
|
||||
<rect x="140" y="260" width="100" height="100" fill="red" clip-path="url(#clip12)" />
|
||||
|
||||
<!-- clip paths with different clipPathUnits -->
|
||||
<rect x="20" y="400" height="300" width="300" fill="red" clip-path="url(#clip13)" />
|
||||
<rect x="20" y="400" width="100" height="100" fill="lime" />
|
||||
|
||||
<!-- text clipping -->
|
||||
<rect x="140" y="400" height="300" width="300" fill="red" clip-path="url(#clip15)" />
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 3.1 KiB |
|
@ -19,6 +19,7 @@ include svg-integration/reftest.list
|
|||
== clip-01.svg pass.svg
|
||||
== clip-02a.svg clip-02-ref.svg
|
||||
== clip-02b.svg clip-02-ref.svg
|
||||
== clipPath-advanced-01.svg pass.svg
|
||||
== clipPath-and-shape-rendering-01.svg clipPath-and-shape-rendering-01-ref.svg
|
||||
== clipPath-basic-01.svg pass.svg
|
||||
== clipPath-winding-01.svg pass.svg
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "nsSVGClipPathFrame.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsSVGEffects.h"
|
||||
#include "nsSVGClipPathElement.h"
|
||||
#include "gfxContext.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
|
@ -69,7 +70,7 @@ nsSVGClipPathFrame::ClipPaint(nsSVGRenderState* aContext,
|
|||
}
|
||||
AutoClipPathReferencer clipRef(this);
|
||||
|
||||
mClipParent = aParent,
|
||||
mClipParent = aParent;
|
||||
mClipParentMatrix = NS_NewSVGMatrix(aMatrix);
|
||||
|
||||
PRBool isTrivial = IsTrivial();
|
||||
|
@ -78,6 +79,23 @@ nsSVGClipPathFrame::ClipPaint(nsSVGRenderState* aContext,
|
|||
isTrivial ? nsSVGRenderState::CLIP
|
||||
: nsSVGRenderState::CLIP_MASK);
|
||||
|
||||
|
||||
gfxContext *gfx = aContext->GetGfxContext();
|
||||
|
||||
PRBool isOK = PR_TRUE;
|
||||
nsSVGClipPathFrame *clipPathFrame =
|
||||
nsSVGEffects::GetEffectProperties(this).GetClipPathFrame(&isOK);
|
||||
PRBool referencedClipIsTrivial;
|
||||
if (clipPathFrame) {
|
||||
referencedClipIsTrivial = clipPathFrame->IsTrivial();
|
||||
gfx->Save();
|
||||
if (referencedClipIsTrivial) {
|
||||
clipPathFrame->ClipPaint(aContext, aParent, aMatrix);
|
||||
} else {
|
||||
gfx->PushGroup(gfxASurface::CONTENT_ALPHA);
|
||||
}
|
||||
}
|
||||
|
||||
for (nsIFrame* kid = mFrames.FirstChild(); kid;
|
||||
kid = kid->GetNextSibling()) {
|
||||
nsISVGChildFrame* SVGFrame = do_QueryFrame(kid);
|
||||
|
@ -85,13 +103,64 @@ nsSVGClipPathFrame::ClipPaint(nsSVGRenderState* aContext,
|
|||
// The CTM of each frame referencing us can be different.
|
||||
SVGFrame->NotifySVGChanged(nsISVGChildFrame::SUPPRESS_INVALIDATION |
|
||||
nsISVGChildFrame::TRANSFORM_CHANGED);
|
||||
|
||||
PRBool isOK = PR_TRUE;
|
||||
nsSVGClipPathFrame *clipPathFrame =
|
||||
nsSVGEffects::GetEffectProperties(kid).GetClipPathFrame(&isOK);
|
||||
|
||||
PRBool isTrivial;
|
||||
|
||||
if (clipPathFrame) {
|
||||
isTrivial = clipPathFrame->IsTrivial();
|
||||
gfx->Save();
|
||||
if (isTrivial) {
|
||||
clipPathFrame->ClipPaint(aContext, aParent, aMatrix);
|
||||
} else {
|
||||
gfx->PushGroup(gfxASurface::CONTENT_ALPHA);
|
||||
}
|
||||
}
|
||||
|
||||
SVGFrame->PaintSVG(aContext, nsnull);
|
||||
|
||||
if (clipPathFrame) {
|
||||
if (!isTrivial) {
|
||||
gfx->PopGroupToSource();
|
||||
|
||||
nsRefPtr<gfxPattern> clipMaskSurface;
|
||||
gfx->PushGroup(gfxASurface::CONTENT_ALPHA);
|
||||
|
||||
clipPathFrame->ClipPaint(aContext, aParent, aMatrix);
|
||||
clipMaskSurface = gfx->PopGroup();
|
||||
|
||||
if (clipMaskSurface) {
|
||||
gfx->Mask(clipMaskSurface);
|
||||
}
|
||||
}
|
||||
gfx->Restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (clipPathFrame) {
|
||||
if (!referencedClipIsTrivial) {
|
||||
gfx->PopGroupToSource();
|
||||
|
||||
nsRefPtr<gfxPattern> clipMaskSurface;
|
||||
gfx->PushGroup(gfxASurface::CONTENT_ALPHA);
|
||||
|
||||
clipPathFrame->ClipPaint(aContext, aParent, aMatrix);
|
||||
clipMaskSurface = gfx->PopGroup();
|
||||
|
||||
if (clipMaskSurface) {
|
||||
gfx->Mask(clipMaskSurface);
|
||||
}
|
||||
}
|
||||
gfx->Restore();
|
||||
}
|
||||
|
||||
if (isTrivial) {
|
||||
aContext->GetGfxContext()->Clip();
|
||||
aContext->GetGfxContext()->NewPath();
|
||||
gfx->Clip();
|
||||
gfx->NewPath();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -111,9 +180,15 @@ nsSVGClipPathFrame::ClipHitTest(nsIFrame* aParent,
|
|||
}
|
||||
AutoClipPathReferencer clipRef(this);
|
||||
|
||||
mClipParent = aParent,
|
||||
mClipParent = aParent;
|
||||
mClipParentMatrix = NS_NewSVGMatrix(aMatrix);
|
||||
|
||||
PRBool isOK = PR_TRUE;
|
||||
nsSVGClipPathFrame *clipPathFrame =
|
||||
nsSVGEffects::GetEffectProperties(this).GetClipPathFrame(&isOK);
|
||||
if (clipPathFrame && !clipPathFrame->ClipHitTest(aParent, aMatrix, aPoint))
|
||||
return PR_FALSE;
|
||||
|
||||
for (nsIFrame* kid = mFrames.FirstChild(); kid;
|
||||
kid = kid->GetNextSibling()) {
|
||||
nsISVGChildFrame* SVGFrame = do_QueryFrame(kid);
|
||||
|
@ -133,6 +208,11 @@ nsSVGClipPathFrame::ClipHitTest(nsIFrame* aParent,
|
|||
PRBool
|
||||
nsSVGClipPathFrame::IsTrivial()
|
||||
{
|
||||
// If the clip path is clipped then it's non-trivial
|
||||
PRBool isOK = PR_TRUE;
|
||||
if (nsSVGEffects::GetEffectProperties(this).GetClipPathFrame(&isOK))
|
||||
return PR_FALSE;
|
||||
|
||||
PRBool foundChild = PR_FALSE;
|
||||
|
||||
for (nsIFrame* kid = mFrames.FirstChild(); kid;
|
||||
|
@ -143,6 +223,11 @@ nsSVGClipPathFrame::IsTrivial()
|
|||
// either more than one svg child and/or a svg container
|
||||
if (foundChild || svgChild->IsDisplayContainer())
|
||||
return PR_FALSE;
|
||||
|
||||
// or where the child is itself clipped
|
||||
if (nsSVGEffects::GetEffectProperties(kid).GetClipPathFrame(&isOK))
|
||||
return PR_FALSE;
|
||||
|
||||
foundChild = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче