Bug 1074820 - Refactor nsSVGPatternFrame, part 1. r=longsonr

This commit is contained in:
Jonathan Watt 2014-09-30 18:08:14 +01:00
parent f8de383809
commit 0fb55f23f7
2 changed files with 29 additions and 23 deletions

View File

@ -251,11 +251,11 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
* Return
*/
// Get the first child of the pattern data we will render
nsIFrame* firstKid = GetPatternFirstChild();
if (!firstKid) {
nsSVGPatternFrame* patternWithChildren = GetPatternWithChildren();
if (!patternWithChildren) {
return nullptr; // Either no kids or a bad reference
}
nsIFrame* firstKid = patternWithChildren->mFrames.FirstChild();
const nsSVGViewBox& viewBox = GetViewBox();
@ -303,13 +303,10 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
return nullptr;
}
// Get the pattern we are going to render
nsSVGPatternFrame *patternFrame =
static_cast<nsSVGPatternFrame*>(firstKid->GetParent());
if (patternFrame->mCTM) {
*patternFrame->mCTM = ctm;
if (patternWithChildren->mCTM) {
*patternWithChildren->mCTM = ctm;
} else {
patternFrame->mCTM = new gfxMatrix(ctm);
patternWithChildren->mCTM = new gfxMatrix(ctm);
}
// Get the bounding box of the pattern. This will be used to determine
@ -368,7 +365,7 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
gfxMatrix(surfaceSize.width / patternWidth, 0.0f,
0.0f, surfaceSize.height / patternHeight,
0.0f, 0.0f);
patternFrame->mCTM->PreMultiply(tempTM);
patternWithChildren->mCTM->PreMultiply(tempTM);
// and rescale pattern to compensate
patternMatrix->PreScale(patternWidth / surfaceSize.width,
@ -401,13 +398,13 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
if (aSource->IsFrameOfType(nsIFrame::eSVGGeometry)) {
// Set the geometrical parent of the pattern we are rendering
patternFrame->mSource = static_cast<nsSVGPathGeometryFrame*>(aSource);
patternWithChildren->mSource = static_cast<nsSVGPathGeometryFrame*>(aSource);
}
// Delay checking NS_FRAME_DRAWING_AS_PAINTSERVER bit until here so we can
// give back a clear surface if there's a loop
if (!(patternFrame->GetStateBits() & NS_FRAME_DRAWING_AS_PAINTSERVER)) {
patternFrame->AddStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER);
if (!(patternWithChildren->GetStateBits() & NS_FRAME_DRAWING_AS_PAINTSERVER)) {
patternWithChildren->AddStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER);
for (nsIFrame* kid = firstKid; kid;
kid = kid->GetNextSibling()) {
// The CTM of each frame referencing us can be different
@ -415,17 +412,17 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
if (SVGFrame) {
SVGFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
}
gfxMatrix tm = *(patternFrame->mCTM);
gfxMatrix tm = *(patternWithChildren->mCTM);
if (kid->GetContent()->IsSVG()) {
tm = static_cast<nsSVGElement*>(kid->GetContent())->
PrependLocalTransformsTo(tm, nsSVGElement::eUserSpaceToParent);
}
nsSVGUtils::PaintFrameWithEffects(kid, context, tm);
}
patternFrame->RemoveStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER);
patternWithChildren->RemoveStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER);
}
patternFrame->mSource = nullptr;
patternWithChildren->mSource = nullptr;
if (aGraphicOpacity != 1.0f) {
gfx->PopGroupToSource();
@ -441,13 +438,12 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
// How do we handle the insertion of a new frame?
// We really don't want to rerender this every time,
// do we?
nsIFrame*
nsSVGPatternFrame::GetPatternFirstChild()
nsSVGPatternFrame*
nsSVGPatternFrame::GetPatternWithChildren()
{
// Do we have any children ourselves?
nsIFrame* kid = mFrames.FirstChild();
if (kid)
return kid;
if (!mFrames.IsEmpty())
return this;
// No, see if we chain to someone who does
AutoPatternReferencer patternRef(this);
@ -456,7 +452,7 @@ nsSVGPatternFrame::GetPatternFirstChild()
if (!next)
return nullptr;
return next->GetPatternFirstChild();
return next->GetPatternWithChildren();
}
uint16_t

View File

@ -120,7 +120,17 @@ protected:
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
float aGraphicOpacity,
const gfxRect *aOverrideBounds);
nsIFrame* GetPatternFirstChild();
/**
* A <pattern> element may reference another <pattern> element using
* xlink:href and, if it doesn't have any child content of its own, then it
* will "inherit" the children of the referenced pattern (which may itself be
* inheriting its children if it references another <pattern>). This
* function returns this nsSVGPatternFrame or the first pattern along the
* reference chain (if there is one) to have children.
*/
nsSVGPatternFrame* GetPatternWithChildren();
gfxRect GetPatternRect(uint16_t aPatternUnits,
const gfxRect &bbox,
const Matrix &callerCTM,