Bug 764860 - Simplify and comment the clipPath code. r=longsonr.

This commit is contained in:
Jonathan Watt 2012-06-15 10:06:34 +01:00
Родитель 331dec4fd2
Коммит 072f5b2cb7
6 изменённых файлов: 64 добавлений и 18 удалений

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

@ -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();