Bug 1317636 - Part 2. Extract PaintFrameIntoMask from nsSVGClipPathFrame::PaintClipMask. r=mstange

MozReview-Commit-ID: LgrortpuwN5

--HG--
extra : rebase_source : 428c0de82eda1301f499a84e8d6f70e06a9541b2
This commit is contained in:
cku 2016-11-16 16:58:59 +08:00
Родитель e935229722
Коммит a4e8c8d584
2 изменённых файлов: 69 добавлений и 54 удалений

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

@ -165,60 +165,7 @@ nsSVGClipPathFrame::PaintClipMask(gfxContext& aMaskContext,
// Paint our children into the mask:
for (nsIFrame* kid = mFrames.FirstChild(); kid;
kid = kid->GetNextSibling()) {
nsISVGChildFrame* SVGFrame = do_QueryFrame(kid);
if (SVGFrame) {
// The CTM of each frame referencing us can be different.
SVGFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
bool isOK = true;
// Children of this clipPath may themselves be clipped.
nsSVGClipPathFrame *clipPathThatClipsChild =
nsSVGEffects::GetEffectProperties(kid).GetClipPathFrame(&isOK);
if (!isOK) {
continue;
}
bool childsClipPathRequiresMasking;
if (clipPathThatClipsChild) {
childsClipPathRequiresMasking = !clipPathThatClipsChild->IsTrivial();
aMaskContext.Save();
if (!childsClipPathRequiresMasking) {
clipPathThatClipsChild->ApplyClipPath(aMaskContext, aClippedFrame,
aMatrix);
} else {
Matrix maskTransform;
RefPtr<SourceSurface> mask =
clipPathThatClipsChild->GetClipMask(aMaskContext, aClippedFrame,
aMatrix, &maskTransform);
aMaskContext.PushGroupForBlendBack(gfxContentType::ALPHA, 1.0,
mask, maskTransform);
// The corresponding PopGroupAndBlend call below will mask the
// blend using |mask|.
}
}
gfxMatrix toChildsUserSpace = mMatrixForChildren;
nsIFrame* child = do_QueryFrame(SVGFrame);
nsIContent* childContent = child->GetContent();
if (childContent->IsSVGElement()) {
toChildsUserSpace =
static_cast<const nsSVGElement*>(childContent)->
PrependLocalTransformsTo(mMatrixForChildren, eUserSpaceToParent);
}
// Our children have NS_STATE_SVG_CLIPPATH_CHILD set on them, and
// nsSVGPathGeometryFrame::Render checks for that state bit and paints
// only the geometry (opaque black) if set.
result &= SVGFrame->PaintSVG(aMaskContext, toChildsUserSpace);
if (clipPathThatClipsChild) {
if (childsClipPathRequiresMasking) {
aMaskContext.PopGroupAndBlend();
}
aMaskContext.Restore();
}
}
result &= PaintFrameIntoMask(kid, aClippedFrame, aMaskContext, aMatrix);
}
@ -254,6 +201,71 @@ nsSVGClipPathFrame::PaintClipMask(gfxContext& aMaskContext,
return result;
}
DrawResult
nsSVGClipPathFrame::PaintFrameIntoMask(nsIFrame *aFrame,
nsIFrame* aClippedFrame,
gfxContext& aTarget,
const gfxMatrix& aMatrix)
{
nsISVGChildFrame* frame = do_QueryFrame(aFrame);
if (!frame) {
return DrawResult::SUCCESS;
}
// The CTM of each frame referencing us can be different.
frame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
bool isOK = true;
// Children of this clipPath may themselves be clipped.
nsSVGClipPathFrame *clipPathThatClipsChild =
nsSVGEffects::GetEffectProperties(aFrame).GetClipPathFrame(&isOK);
if (!isOK) {
return DrawResult::SUCCESS;
}
bool childsClipPathRequiresMasking;
if (clipPathThatClipsChild) {
childsClipPathRequiresMasking = !clipPathThatClipsChild->IsTrivial();
aTarget.Save();
if (!childsClipPathRequiresMasking) {
clipPathThatClipsChild->ApplyClipPath(aTarget, aClippedFrame, aMatrix);
} else {
Matrix maskTransform;
RefPtr<SourceSurface> mask =
clipPathThatClipsChild->GetClipMask(aTarget, aClippedFrame,
aMatrix, &maskTransform);
aTarget.PushGroupForBlendBack(gfxContentType::ALPHA, 1.0,
mask, maskTransform);
// The corresponding PopGroupAndBlend call below will mask the
// blend using |mask|.
}
}
gfxMatrix toChildsUserSpace = mMatrixForChildren;
nsIFrame* child = do_QueryFrame(frame);
nsIContent* childContent = child->GetContent();
if (childContent->IsSVGElement()) {
toChildsUserSpace =
static_cast<const nsSVGElement*>(childContent)->
PrependLocalTransformsTo(mMatrixForChildren, eUserSpaceToParent);
}
// Our children have NS_STATE_SVG_CLIPPATH_CHILD set on them, and
// nsSVGPathGeometryFrame::Render checks for that state bit and paints
// only the geometry (opaque black) if set.
DrawResult result = frame->PaintSVG(aTarget, toChildsUserSpace);
if (clipPathThatClipsChild) {
if (childsClipPathRequiresMasking) {
aTarget.PopGroupAndBlend();
}
aTarget.Restore();
}
return result;
}
already_AddRefed<SourceSurface>
nsSVGClipPathFrame::GetClipMask(gfxContext& aReferenceContext,
nsIFrame* aClippedFrame,

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

@ -160,6 +160,9 @@ private:
already_AddRefed<DrawTarget>
CreateClipMask(gfxContext& aReferenceContext, IntPoint& aOffset);
DrawResult PaintFrameIntoMask(nsIFrame *aFrame, nsIFrame* aClippedFrame,
gfxContext& aTarget, const gfxMatrix& aMatrix);
// Set, during a GetClipMask() call, to the transform that still needs to be
// concatenated to the transform of the DrawTarget that was passed to
// GetClipMask in order to establish the coordinate space that the clipPath