зеркало из https://github.com/mozilla/gecko-dev.git
Bug 764860 - Simplify and comment the clipPath code. r=longsonr.
This commit is contained in:
Родитель
331dec4fd2
Коммит
072f5b2cb7
|
@ -47,14 +47,35 @@ nsSVGClipPathFrame::ClipPaint(nsRenderingContext* aContext,
|
|||
mClipParentMatrix = new gfxMatrix(aMatrix);
|
||||
}
|
||||
|
||||
bool isTrivial = IsTrivial();
|
||||
|
||||
SVGAutoRenderState mode(aContext,
|
||||
isTrivial ? SVGAutoRenderState::CLIP
|
||||
: SVGAutoRenderState::CLIP_MASK);
|
||||
|
||||
gfxContext *gfx = aContext->ThebesContext();
|
||||
|
||||
nsISVGChildFrame *singleClipPathChild = nsnull;
|
||||
|
||||
if (IsTrivial(&singleClipPathChild)) {
|
||||
// Notify our child that it's painting as part of a clipPath, and that
|
||||
// we only require it to draw its path (it should skip filling, etc.):
|
||||
SVGAutoRenderState mode(aContext, SVGAutoRenderState::CLIP);
|
||||
|
||||
if (!singleClipPathChild) {
|
||||
// We have no children - the spec says clip away everything:
|
||||
gfx->Rectangle(gfxRect());
|
||||
} else {
|
||||
singleClipPathChild->NotifySVGChanged(
|
||||
nsISVGChildFrame::DO_NOT_NOTIFY_RENDERING_OBSERVERS |
|
||||
nsISVGChildFrame::TRANSFORM_CHANGED);
|
||||
singleClipPathChild->PaintSVG(aContext, nsnull);
|
||||
}
|
||||
gfx->Clip();
|
||||
gfx->NewPath();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Seems like this is a non-trivial clipPath, so we need to use a clip mask.
|
||||
|
||||
// Notify our children that they're painting into a clip mask:
|
||||
SVGAutoRenderState mode(aContext, SVGAutoRenderState::CLIP_MASK);
|
||||
|
||||
// Check if this clipPath is itself clipped by another clipPath:
|
||||
nsSVGClipPathFrame *clipPathFrame =
|
||||
nsSVGEffects::GetEffectProperties(this).GetClipPathFrame(nsnull);
|
||||
bool referencedClipIsTrivial;
|
||||
|
@ -134,11 +155,6 @@ nsSVGClipPathFrame::ClipPaint(nsRenderingContext* aContext,
|
|||
gfx->Restore();
|
||||
}
|
||||
|
||||
if (isTrivial) {
|
||||
gfx->Clip();
|
||||
gfx->NewPath();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -185,13 +201,17 @@ nsSVGClipPathFrame::ClipHitTest(nsIFrame* aParent,
|
|||
}
|
||||
|
||||
bool
|
||||
nsSVGClipPathFrame::IsTrivial()
|
||||
nsSVGClipPathFrame::IsTrivial(nsISVGChildFrame **aSingleChild)
|
||||
{
|
||||
// If the clip path is clipped then it's non-trivial
|
||||
if (nsSVGEffects::GetEffectProperties(this).GetClipPathFrame(nsnull))
|
||||
return false;
|
||||
|
||||
bool foundChild = false;
|
||||
if (aSingleChild) {
|
||||
*aSingleChild = nsnull;
|
||||
}
|
||||
|
||||
nsISVGChildFrame *foundChild = nsnull;
|
||||
|
||||
for (nsIFrame* kid = mFrames.FirstChild(); kid;
|
||||
kid = kid->GetNextSibling()) {
|
||||
|
@ -206,9 +226,12 @@ nsSVGClipPathFrame::IsTrivial()
|
|||
if (nsSVGEffects::GetEffectProperties(kid).GetClipPathFrame(nsnull))
|
||||
return false;
|
||||
|
||||
foundChild = true;
|
||||
foundChild = svgChild;
|
||||
}
|
||||
}
|
||||
if (aSingleChild) {
|
||||
*aSingleChild = foundChild;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "nsSVGUtils.h"
|
||||
|
||||
class nsRenderingContext;
|
||||
class nsISVGChildFrame;
|
||||
|
||||
typedef nsSVGContainerFrame nsSVGClipPathFrameBase;
|
||||
|
||||
|
@ -41,7 +42,7 @@ public:
|
|||
// Check if this clipPath is made up of more than one geometry object.
|
||||
// If so, the clipping API in cairo isn't enough and we need to use
|
||||
// mask based clipping.
|
||||
bool IsTrivial();
|
||||
bool IsTrivial(nsISVGChildFrame **aSingleChild = nsnull);
|
||||
|
||||
bool IsValid();
|
||||
|
||||
|
|
|
@ -317,6 +317,9 @@ nsSVGGlyphFrame::PaintSVG(nsRenderingContext *aContext,
|
|||
}
|
||||
|
||||
if (renderMode != SVGAutoRenderState::NORMAL) {
|
||||
NS_ABORT_IF_FALSE(renderMode == SVGAutoRenderState::CLIP ||
|
||||
renderMode == SVGAutoRenderState::CLIP_MASK,
|
||||
"Unknown render mode");
|
||||
gfxContextMatrixAutoSaveRestore matrixAutoSaveRestore(gfx);
|
||||
SetupGlobalTransform(gfx);
|
||||
|
||||
|
|
|
@ -252,8 +252,6 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(nsRenderingContext* aCtx,
|
|||
gfxContext* gfx = aCtx->ThebesContext();
|
||||
gfxContextMatrixAutoSaveRestore matrixAutoSaveRestore(gfx);
|
||||
|
||||
//SVGAutoRenderState autoRenderState(aCtx, SVGAutoRenderState::NORMAL);
|
||||
|
||||
nsRect userSpaceRect = GetNonSVGUserSpace(firstFrame) + aBuilder->ToReferenceFrame(firstFrame);
|
||||
PRInt32 appUnitsPerDevPixel = aEffectsFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
userSpaceRect = userSpaceRect.ToNearestPixels(appUnitsPerDevPixel).ToAppUnits(appUnitsPerDevPixel);
|
||||
|
|
|
@ -461,6 +461,9 @@ nsSVGPathGeometryFrame::Render(nsRenderingContext *aContext)
|
|||
GeneratePath(gfx);
|
||||
|
||||
if (renderMode != SVGAutoRenderState::NORMAL) {
|
||||
NS_ABORT_IF_FALSE(renderMode == SVGAutoRenderState::CLIP ||
|
||||
renderMode == SVGAutoRenderState::CLIP_MASK,
|
||||
"Unknown render mode");
|
||||
gfx->Restore();
|
||||
|
||||
if (GetClipRule() == NS_STYLE_FILL_RULE_EVENODD)
|
||||
|
|
|
@ -161,7 +161,25 @@ private:
|
|||
class NS_STACK_CLASS SVGAutoRenderState
|
||||
{
|
||||
public:
|
||||
enum RenderMode { NORMAL, CLIP, CLIP_MASK };
|
||||
enum RenderMode {
|
||||
/**
|
||||
* Used to inform SVG frames that they should paint as normal.
|
||||
*/
|
||||
NORMAL,
|
||||
/**
|
||||
* Used to inform SVG frames when they are painting as the child of a
|
||||
* simple clipPath. In this case they should only draw their basic geometry
|
||||
* as a path. They should not fill, stroke, or paint anything else.
|
||||
*/
|
||||
CLIP,
|
||||
/**
|
||||
* Used to inform SVG frames when they are painting as the child of a
|
||||
* complex clipPath that requires the use of a clip mask. In this case they
|
||||
* should only draw their basic geometry as a path and then fill it using
|
||||
* fully opaque white. They should not stroke, or paint anything else.
|
||||
*/
|
||||
CLIP_MASK
|
||||
};
|
||||
|
||||
SVGAutoRenderState(nsRenderingContext *aContext, RenderMode aMode);
|
||||
~SVGAutoRenderState();
|
||||
|
|
Загрузка…
Ссылка в новой задаче