mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Bug 1074820 - Refactor nsSVGPatternFrame, part 1. r=longsonr
This commit is contained in:
parent
f8de383809
commit
0fb55f23f7
@ -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
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user