mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Bug 447567. Instead of brutally wiping out effects properties whenever the style context changes for an SVG frame (which wouldn't work for non-SVG frames), create a new style change hint to handle it. r=longsonr,sr=dbaron
This commit is contained in:
parent
19c8f95e49
commit
ab2b084996
@ -147,6 +147,9 @@
|
||||
#ifdef MOZ_MATHML
|
||||
#include "nsMathMLParts.h"
|
||||
#endif
|
||||
#ifdef MOZ_SVG
|
||||
#include "nsSVGUtils.h"
|
||||
#endif
|
||||
|
||||
nsIFrame*
|
||||
NS_NewHTMLCanvasFrame (nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
@ -9821,6 +9824,11 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
||||
RecreateFramesForContent(content);
|
||||
} else {
|
||||
NS_ASSERTION(frame, "This shouldn't happen");
|
||||
#ifdef MOZ_SVG
|
||||
if (hint & nsChangeHint_UpdateEffects) {
|
||||
nsSVGUtils::UpdateEffects(frame);
|
||||
}
|
||||
#endif
|
||||
if (hint & nsChangeHint_ReflowFrame) {
|
||||
StyleChangeReflow(frame);
|
||||
}
|
||||
|
@ -49,7 +49,17 @@ enum nsChangeHint {
|
||||
nsChangeHint_ReflowFrame = 0x02, // change requires reflow (e.g., WIDTH=)
|
||||
nsChangeHint_SyncFrameView = 0x04, // change requires view to be updated, if there is one (e.g., clip:)
|
||||
nsChangeHint_UpdateCursor = 0x08, // The currently shown mouse cursor needs to be updated
|
||||
nsChangeHint_ReconstructFrame = 0x10 // change requires frame change (e.g., display:)
|
||||
/**
|
||||
* SVG filter/mask/clip effects need to be recomputed because the URI
|
||||
* in the filter/mask/clip-path property has changed. This wipes
|
||||
* out cached nsSVGPropertyBase and subclasses which hold a reference to
|
||||
* the element referenced by the URI, and a mutation observer for
|
||||
* the DOM subtree rooted at that element. Also, for filters they store a
|
||||
* bounding-box for the filter result so that if the filter changes we can
|
||||
* invalidate the old covered area.
|
||||
*/
|
||||
nsChangeHint_UpdateEffects = 0x10,
|
||||
nsChangeHint_ReconstructFrame = 0x20 // change requires frame change (e.g., display:)
|
||||
// This subsumes all the above
|
||||
// TBD: add nsChangeHint_ForceFrameView to force frame reconstruction if the frame doesn't yet
|
||||
// have a view
|
||||
|
@ -447,6 +447,11 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aOther)
|
||||
// a framechange here and a reflow should be sufficient. See bug 35768.
|
||||
DO_STRUCT_DIFFERENCE(Quotes);
|
||||
|
||||
#ifdef MOZ_SVG
|
||||
maxHint = nsChangeHint(NS_STYLE_HINT_REFLOW | nsChangeHint_UpdateEffects);
|
||||
DO_STRUCT_DIFFERENCE(SVGReset);
|
||||
#endif
|
||||
|
||||
// At this point, we know that the worst kind of damage we could do is
|
||||
// a reflow.
|
||||
maxHint = NS_STYLE_HINT_REFLOW;
|
||||
|
@ -885,25 +885,34 @@ nsStyleSVGReset::nsStyleSVGReset(const nsStyleSVGReset& aSource)
|
||||
|
||||
nsChangeHint nsStyleSVGReset::CalcDifference(const nsStyleSVGReset& aOther) const
|
||||
{
|
||||
nsChangeHint hint = nsChangeHint(0);
|
||||
|
||||
if (!EqualURIs(mClipPath, aOther.mClipPath) ||
|
||||
!EqualURIs(mFilter, aOther.mFilter) ||
|
||||
!EqualURIs(mMask, aOther.mMask)) {
|
||||
NS_UpdateHint(hint, nsChangeHint_UpdateEffects);
|
||||
NS_UpdateHint(hint, nsChangeHint_ReflowFrame);
|
||||
NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
|
||||
}
|
||||
|
||||
if (mStopColor != aOther.mStopColor ||
|
||||
mFloodColor != aOther.mFloodColor ||
|
||||
mLightingColor != aOther.mLightingColor ||
|
||||
!EqualURIs(mClipPath, aOther.mClipPath) ||
|
||||
!EqualURIs(mFilter, aOther.mFilter) ||
|
||||
!EqualURIs(mMask, aOther.mMask) ||
|
||||
mStopOpacity != aOther.mStopOpacity ||
|
||||
mFloodOpacity != aOther.mFloodOpacity ||
|
||||
mDominantBaseline != aOther.mDominantBaseline)
|
||||
return NS_STYLE_HINT_VISUAL;
|
||||
|
||||
return NS_STYLE_HINT_NONE;
|
||||
NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
|
||||
|
||||
return hint;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* static */
|
||||
nsChangeHint nsStyleSVGReset::MaxDifference()
|
||||
{
|
||||
return NS_STYLE_HINT_VISUAL;
|
||||
return NS_CombineHint(NS_CombineHint(nsChangeHint_UpdateEffects,
|
||||
nsChangeHint_ReflowFrame),
|
||||
nsChangeHint_RepaintFrame);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -65,8 +65,6 @@ public:
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
NS_IMETHOD DidSetStyleContext();
|
||||
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
*
|
||||
@ -129,14 +127,6 @@ nsSVGAFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGAFrame::DidSetStyleContext()
|
||||
{
|
||||
nsSVGUtils::StyleEffects(this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIAtom *
|
||||
nsSVGAFrame::GetType() const
|
||||
{
|
||||
|
@ -105,13 +105,6 @@ nsSVGDisplayContainerFrame::Init(nsIContent* aContent,
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGDisplayContainerFrame::Destroy()
|
||||
{
|
||||
nsSVGUtils::StyleEffects(this);
|
||||
nsSVGContainerFrame::Destroy();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGDisplayContainerFrame::InsertFrames(nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
|
@ -91,7 +91,6 @@ private:
|
||||
|
||||
public:
|
||||
// nsIFrame:
|
||||
virtual void Destroy();
|
||||
NS_IMETHOD InsertFrames(nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
|
@ -106,10 +106,6 @@ nsSVGForeignObjectFrame::Init(nsIContent* aContent,
|
||||
void nsSVGForeignObjectFrame::Destroy()
|
||||
{
|
||||
nsSVGUtils::GetOuterSVGFrame(this)->UnregisterForeignObject(this);
|
||||
// Delete any clipPath/filter/mask properties _before_ we die. The properties
|
||||
// and property hash table have weak pointers to us that are dereferenced
|
||||
// when the properties are destroyed.
|
||||
nsSVGUtils::StyleEffects(this);
|
||||
nsSVGForeignObjectFrameBase::Destroy();
|
||||
}
|
||||
|
||||
@ -143,13 +139,6 @@ nsSVGForeignObjectFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGForeignObjectFrame::DidSetStyleContext()
|
||||
{
|
||||
nsSVGUtils::StyleEffects(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGForeignObjectFrame::Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
|
@ -75,8 +75,6 @@ public:
|
||||
return GetFirstChild(nsnull)->GetContentInsertionFrame();
|
||||
}
|
||||
|
||||
NS_IMETHOD DidSetStyleContext();
|
||||
|
||||
NS_IMETHOD Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
|
@ -140,13 +140,6 @@ nsSVGGFrame::GetCanvasTM()
|
||||
return retval;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGGFrame::DidSetStyleContext()
|
||||
{
|
||||
nsSVGUtils::StyleEffects(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGGFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
|
@ -67,7 +67,6 @@ public:
|
||||
#endif
|
||||
|
||||
// nsIFrame interface:
|
||||
NS_IMETHOD DidSetStyleContext();
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
@ -64,9 +64,6 @@ private:
|
||||
NS_IMETHOD_(nsrefcnt) Release() { return 1; }
|
||||
|
||||
public:
|
||||
// nsIFrame:
|
||||
NS_IMETHOD DidSetStyleContext();
|
||||
|
||||
// We don't define an AttributeChanged method since changes to the
|
||||
// 'x', 'y', 'width' and 'height' attributes of our content object
|
||||
// are handled in nsSVGSVGElement::DidModifySVGObservable
|
||||
@ -404,10 +401,3 @@ nsSVGInnerSVGFrame::DidModifySVGObservable (nsISVGValue* observable,
|
||||
NotifyViewportChange();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGInnerSVGFrame::DidSetStyleContext()
|
||||
{
|
||||
nsSVGUtils::StyleEffects(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -599,8 +599,6 @@ nsSVGPathGeometryFrame::UpdateMarkerProperty()
|
||||
void
|
||||
nsSVGPathGeometryFrame::RemovePathProperties()
|
||||
{
|
||||
nsSVGUtils::StyleEffects(this);
|
||||
|
||||
if (GetStateBits() & NS_STATE_SVG_HAS_MARKERS)
|
||||
DeleteProperty(nsGkAtoms::marker);
|
||||
}
|
||||
|
@ -99,14 +99,6 @@ nsSVGTextFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextFrame::DidSetStyleContext()
|
||||
{
|
||||
nsSVGUtils::StyleEffects(this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIAtom *
|
||||
nsSVGTextFrame::GetType() const
|
||||
{
|
||||
|
@ -59,7 +59,6 @@ public:
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
NS_IMETHOD DidSetStyleContext();
|
||||
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
|
@ -1391,7 +1391,7 @@ nsSVGUtils::PaintChildWithEffects(nsSVGRenderState *aContext,
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGUtils::StyleEffects(nsIFrame *aFrame)
|
||||
nsSVGUtils::UpdateEffects(nsIFrame *aFrame)
|
||||
{
|
||||
aFrame->DeleteProperty(nsGkAtoms::filter);
|
||||
aFrame->DeleteProperty(nsGkAtoms::mask);
|
||||
|
@ -336,11 +336,12 @@ public:
|
||||
nsRect *aDirtyRect,
|
||||
nsIFrame *aFrame);
|
||||
|
||||
/* Style change for effects (filter/clip/mask/opacity) - call when
|
||||
* the frame's style has changed to make sure the effects properties
|
||||
* stay in sync. */
|
||||
/**
|
||||
* Called by nsCSSFrameConstructor when style changes require the
|
||||
* effect properties on aFrame to be updated
|
||||
*/
|
||||
static void
|
||||
StyleEffects(nsIFrame *aFrame);
|
||||
UpdateEffects(nsIFrame *aFrame);
|
||||
|
||||
/* Hit testing - check if point hits the clipPath of indicated
|
||||
* frame. (x,y) are specified in device pixels relative to the
|
||||
|
Loading…
Reference in New Issue
Block a user