Bug 355267 - remove svg fragment tree code. r=longsonr, sr=roc

This commit is contained in:
tor%cs.brown.edu 2006-11-14 00:48:33 +00:00
Родитель 37d4118e51
Коммит 402f35a66e
11 изменённых файлов: 56 добавлений и 311 удалений

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

@ -50,9 +50,8 @@ class nsIDOMSVGPoint;
#define TRIM_LEADING_WHITESPACE 0x02 #define TRIM_LEADING_WHITESPACE 0x02
#define TRIM_TRAILING_WHITESPACE 0x04 #define TRIM_TRAILING_WHITESPACE 0x04
// {9C7406A8-86F0-45e2-85DF-74BB63BE6F4A}
#define NS_ISVGGLYPHFRAGMENTNODE_IID \ #define NS_ISVGGLYPHFRAGMENTNODE_IID \
{ 0x9c7406a8, 0x86f0, 0x45e2, { 0x85, 0xdf, 0x74, 0xbb, 0x63, 0xbe, 0x6f, 0x4a } } { 0x1297716a, 0xd68d, 0x4c9d, { 0x8e, 0xf8, 0x9e, 0x01, 0x1d, 0x78, 0x21, 0xd0 } }
class nsISVGGlyphFragmentNode : public nsISupports class nsISVGGlyphFragmentNode : public nsISupports
{ {
@ -67,8 +66,6 @@ public:
NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetFirstGlyphFragment()=0; NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetFirstGlyphFragment()=0;
NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetNextGlyphFragment()=0; NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetNextGlyphFragment()=0;
NS_IMETHOD_(void) SetWhitespaceHandling(PRUint8 aWhitespaceHandling)=0; NS_IMETHOD_(void) SetWhitespaceHandling(PRUint8 aWhitespaceHandling)=0;
NS_IMETHOD_(void) NotifyGlyphFragmentTreeSuspended()=0;
NS_IMETHOD_(void) NotifyGlyphFragmentTreeUnsuspended()=0;
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(nsISVGGlyphFragmentNode, NS_DEFINE_STATIC_IID_ACCESSOR(nsISVGGlyphFragmentNode,

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

@ -74,8 +74,7 @@ NS_NewSVGGlyphFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame* pa
nsSVGGlyphFrame::nsSVGGlyphFrame(nsStyleContext* aContext) nsSVGGlyphFrame::nsSVGGlyphFrame(nsStyleContext* aContext)
: nsSVGGlyphFrameBase(aContext), : nsSVGGlyphFrameBase(aContext),
mWhitespaceHandling(COMPRESS_WHITESPACE), mWhitespaceHandling(COMPRESS_WHITESPACE)
mFragmentTreeDirty(PR_FALSE)
{ {
} }
@ -105,19 +104,9 @@ nsSVGGlyphFrame::UpdateGraphic(PRBool suppressInvalidation)
if (GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD) if (GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)
return NS_OK; return NS_OK;
#ifdef DEBUG nsSVGTextFrame *textFrame = GetTextFrame();
// printf("** nsSVGGlyphFrame::Update\n"); if (textFrame)
#endif textFrame->NotifyGlyphMetricsChange();
nsSVGOuterSVGFrame* outerSVGFrame = nsSVGUtils::GetOuterSVGFrame(this);
if (!outerSVGFrame) {
NS_ERROR("No outerSVGFrame");
return NS_ERROR_FAILURE;
}
outerSVGFrame->SuspendRedraw();
UpdateFragmentTree();
UpdateGeometry(PR_TRUE, PR_FALSE);
outerSVGFrame->UnsuspendRedraw();
return NS_OK; return NS_OK;
} }
@ -127,7 +116,7 @@ nsSVGGlyphFrame::DidSetStyleContext()
{ {
nsSVGGlyphFrameBase::DidSetStyleContext(); nsSVGGlyphFrameBase::DidSetStyleContext();
return CharacterDataChanged(nsnull, nsnull, PR_FALSE); return UpdateGraphic();
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -464,8 +453,6 @@ nsSVGGlyphFrame::NotifyRedrawSuspended()
NS_IMETHODIMP NS_IMETHODIMP
nsSVGGlyphFrame::NotifyRedrawUnsuspended() nsSVGGlyphFrame::NotifyRedrawUnsuspended()
{ {
NS_ASSERTION(!mFragmentTreeDirty, "dirty fragmenttree in nsSVGGlyphFrame::NotifyRedrawUnsuspended");
if (GetStateBits() & NS_STATE_SVG_DIRTY) if (GetStateBits() & NS_STATE_SVG_DIRTY)
UpdateGeometry(PR_TRUE, PR_FALSE); UpdateGeometry(PR_TRUE, PR_FALSE);
@ -1245,26 +1232,6 @@ nsSVGGlyphFrame::SetWhitespaceHandling(PRUint8 aWhitespaceHandling)
mWhitespaceHandling = aWhitespaceHandling; mWhitespaceHandling = aWhitespaceHandling;
} }
NS_IMETHODIMP_(void)
nsSVGGlyphFrame::NotifyGlyphFragmentTreeSuspended()
{
// do nothing
}
NS_IMETHODIMP_(void)
nsSVGGlyphFrame::NotifyGlyphFragmentTreeUnsuspended()
{
if (mFragmentTreeDirty) {
nsSVGTextFrame* text_frame = GetTextFrame();
NS_ASSERTION(text_frame, "null text frame");
if (text_frame)
text_frame->NotifyGlyphFragmentTreeChange(this);
mFragmentTreeDirty = PR_FALSE;
}
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// //
@ -1362,23 +1329,6 @@ void nsSVGGlyphFrame::UpdateGeometry(PRBool bRedraw,
} }
} }
void nsSVGGlyphFrame::UpdateFragmentTree()
{
mFragmentTreeDirty = PR_TRUE;
nsSVGTextFrame* text_frame = GetTextFrame();
if (!text_frame) {
NS_ERROR("null text_frame");
return;
}
PRBool suspended = text_frame->IsGlyphFragmentTreeSuspended();
if (!suspended) {
text_frame->NotifyGlyphFragmentTreeChange(this);
mFragmentTreeDirty = PR_FALSE;
}
}
nsSVGTextFrame * nsSVGTextFrame *
nsSVGGlyphFrame::GetTextFrame() nsSVGGlyphFrame::GetTextFrame()
{ {

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

@ -141,9 +141,7 @@ public:
NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetFirstGlyphFragment(); NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetFirstGlyphFragment();
NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetNextGlyphFragment(); NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetNextGlyphFragment();
NS_IMETHOD_(void) SetWhitespaceHandling(PRUint8 aWhitespaceHandling); NS_IMETHOD_(void) SetWhitespaceHandling(PRUint8 aWhitespaceHandling);
NS_IMETHOD_(void) NotifyGlyphFragmentTreeSuspended();
NS_IMETHOD_(void) NotifyGlyphFragmentTreeUnsuspended();
protected: protected:
struct nsSVGCharacterPosition { struct nsSVGCharacterPosition {
PRBool draw; PRBool draw;
@ -198,7 +196,6 @@ protected:
void UpdateGeometry(PRBool bRedraw, PRBool suppressInvalidation); void UpdateGeometry(PRBool bRedraw, PRBool suppressInvalidation);
void UpdateMetrics(); void UpdateMetrics();
void UpdateFragmentTree();
nsSVGTextFrame *GetTextFrame(); nsSVGTextFrame *GetTextFrame();
PRBool ContainsPoint(float x, float y); PRBool ContainsPoint(float x, float y);
nsresult GetGlobalTransform(cairo_t *ctx, nsISVGCairoCanvas *aCanvas); nsresult GetGlobalTransform(cairo_t *ctx, nsISVGCairoCanvas *aCanvas);
@ -207,7 +204,6 @@ protected:
float mX, mY; float mX, mY;
PRUint8 mWhitespaceHandling; PRUint8 mWhitespaceHandling;
PRPackedBool mFragmentTreeDirty;
}; };
#endif #endif

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

@ -102,15 +102,14 @@ nsSVGMutationObserver::AttributeChanged(nsIDocument *aDocument,
if (!frame) { if (!frame) {
continue; continue;
} }
// is the content a child of a text element // is the content a child of a text element
nsISVGTextContentMetrics* metrics; nsISVGTextContentMetrics* metrics;
CallQueryInterface(frame, &metrics); CallQueryInterface(frame, &metrics);
if (metrics) { if (metrics) {
nsSVGTextFrame* textFrame = NS_STATIC_CAST(nsSVGTextContainerFrame*, nsSVGTextFrame* textFrame = NS_STATIC_CAST(nsSVGTextContainerFrame*,
frame)->GetTextFrame(); frame)->GetTextFrame();
textFrame->NotifyGlyphMetricsChange();
if (!textFrame->IsGlyphFragmentTreeSuspended())
textFrame->UpdateFragmentTree();
continue; continue;
} }
// if not, are there text elements amongst its descendents // if not, are there text elements amongst its descendents
@ -128,9 +127,7 @@ nsSVGMutationObserver::UpdateTextFragmentTrees(nsIFrame *aFrame)
while (kid) { while (kid) {
if (kid->GetType() == nsLayoutAtoms::svgTextFrame) { if (kid->GetType() == nsLayoutAtoms::svgTextFrame) {
nsSVGTextFrame* textFrame = NS_STATIC_CAST(nsSVGTextFrame*, kid); nsSVGTextFrame* textFrame = NS_STATIC_CAST(nsSVGTextFrame*, kid);
if (!textFrame->IsGlyphFragmentTreeSuspended()) { textFrame->NotifyGlyphMetricsChange();
textFrame->UpdateFragmentTree();
}
} else { } else {
UpdateTextFragmentTrees(kid); UpdateTextFragmentTrees(kid);
} }

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

@ -84,23 +84,6 @@ NS_INTERFACE_MAP_END_INHERITING(nsSVGTSpanFrameBase)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// nsIFrame methods // nsIFrame methods
NS_IMETHODIMP
nsSVGTSpanFrame::RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame)
{
nsSVGOuterSVGFrame* outerSVGFrame = nsSVGUtils::GetOuterSVGFrame(this);
if (outerSVGFrame)
outerSVGFrame->SuspendRedraw();
mFragmentTreeDirty = PR_TRUE;
nsresult rv = nsSVGTSpanFrameBase::RemoveFrame(aListName, aOldFrame);
if (outerSVGFrame)
outerSVGFrame->UnsuspendRedraw();
return rv;
}
NS_IMETHODIMP NS_IMETHODIMP
nsSVGTSpanFrame::AttributeChanged(PRInt32 aNameSpaceID, nsSVGTSpanFrame::AttributeChanged(PRInt32 aNameSpaceID,
nsIAtom* aAttribute, nsIAtom* aAttribute,
@ -113,7 +96,7 @@ nsSVGTSpanFrame::AttributeChanged(PRInt32 aNameSpaceID,
aAttribute == nsGkAtoms::dy)) { aAttribute == nsGkAtoms::dy)) {
nsSVGTextFrame* text_frame = GetTextFrame(); nsSVGTextFrame* text_frame = GetTextFrame();
if (text_frame) if (text_frame)
text_frame->NotifyGlyphMetricsChange(this); text_frame->NotifyGlyphMetricsChange();
} }
return NS_OK; return NS_OK;
@ -229,37 +212,3 @@ nsSVGTSpanFrame::SetWhitespaceHandling(PRUint8 aWhitespaceHandling)
{ {
nsSVGTSpanFrameBase::SetWhitespaceHandling(); nsSVGTSpanFrameBase::SetWhitespaceHandling();
} }
NS_IMETHODIMP_(void)
nsSVGTSpanFrame::NotifyGlyphFragmentTreeSuspended()
{
nsIFrame* kid = mFrames.FirstChild();
while (kid) {
nsISVGGlyphFragmentNode *node = nsnull;
CallQueryInterface(kid, &node);
if (node)
node->NotifyGlyphFragmentTreeSuspended();
kid = kid->GetNextSibling();
}
}
NS_IMETHODIMP_(void)
nsSVGTSpanFrame::NotifyGlyphFragmentTreeUnsuspended()
{
if (mFragmentTreeDirty) {
nsSVGTextFrame* text_frame = GetTextFrame();
NS_ASSERTION(text_frame, "null text frame");
if (text_frame)
text_frame->NotifyGlyphFragmentTreeChange(this);
mFragmentTreeDirty = PR_FALSE;
}
nsIFrame* kid = mFrames.FirstChild();
while (kid) {
nsISVGGlyphFragmentNode *node = nsnull;
CallQueryInterface(kid, &node);
if (node)
node->NotifyGlyphFragmentTreeUnsuspended();
kid = kid->GetNextSibling();
}
}

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

@ -53,7 +53,7 @@ class nsSVGTSpanFrame : public nsSVGTSpanFrameBase,
protected: protected:
nsSVGTSpanFrame(nsStyleContext* aContext) : nsSVGTSpanFrame(nsStyleContext* aContext) :
nsSVGTextContainerFrame(aContext), nsSVGTextContainerFrame(aContext),
mFragmentTreeDirty(PR_FALSE), mPropagateTransform(PR_TRUE) {} mPropagateTransform(PR_TRUE) {}
// nsISupports interface: // nsISupports interface:
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
@ -63,8 +63,6 @@ private:
public: public:
// nsIFrame: // nsIFrame:
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame);
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID, NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
nsIAtom* aAttribute, nsIAtom* aAttribute,
PRInt32 aModType); PRInt32 aModType);
@ -97,12 +95,9 @@ public:
NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetFirstGlyphFragment(); NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetFirstGlyphFragment();
NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetNextGlyphFragment(); NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetNextGlyphFragment();
NS_IMETHOD_(void) SetWhitespaceHandling(PRUint8 aWhitespaceHandling); NS_IMETHOD_(void) SetWhitespaceHandling(PRUint8 aWhitespaceHandling);
NS_IMETHOD_(void) NotifyGlyphFragmentTreeSuspended();
NS_IMETHOD_(void) NotifyGlyphFragmentTreeUnsuspended();
private: private:
nsCOMPtr<nsIDOMSVGMatrix> mOverrideCTM; nsCOMPtr<nsIDOMSVGMatrix> mOverrideCTM;
PRPackedBool mFragmentTreeDirty;
PRPackedBool mPropagateTransform; PRPackedBool mPropagateTransform;
}; };

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

@ -131,7 +131,20 @@ nsSVGTextContainerFrame::GetDy()
animLengthList->GetAnimVal(&retval); animLengthList->GetAnimVal(&retval);
return retval; return retval;
} }
//----------------------------------------------------------------------
// nsIFrame methods
NS_IMETHODIMP
nsSVGTextContainerFrame::RemoveFrame(nsIAtom *aListName, nsIFrame *aOldFrame)
{
nsSVGTextFrame *textFrame = GetTextFrame();
if (textFrame)
textFrame->NotifyGlyphMetricsChange();
return NS_OK;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// nsISVGTextContentMetrics methods // nsISVGTextContentMetrics methods

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

@ -67,6 +67,9 @@ private:
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; } NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
public: public:
// nsIFrame
NS_IMETHOD RemoveFrame(nsIAtom *aListName, nsIFrame *aOldFrame);
// nsISVGTextContentMetrics // nsISVGTextContentMetrics
NS_IMETHOD GetNumberOfChars(PRInt32 *_retval); NS_IMETHOD GetNumberOfChars(PRInt32 *_retval);
NS_IMETHOD GetComputedTextLength(float *_retval); NS_IMETHOD GetComputedTextLength(float *_retval);

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

@ -75,8 +75,8 @@ NS_NewSVGTextFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContex
nsSVGTextFrame::nsSVGTextFrame(nsStyleContext* aContext) nsSVGTextFrame::nsSVGTextFrame(nsStyleContext* aContext)
: nsSVGTextFrameBase(aContext), : nsSVGTextFrameBase(aContext),
mFragmentTreeState(suspended), mMetricsState(suspended), mMetricsState(unsuspended),
mFragmentTreeDirty(PR_FALSE), mPropagateTransform(PR_TRUE), mPropagateTransform(PR_TRUE),
mPositioningDirty(PR_FALSE) mPositioningDirty(PR_FALSE)
{ {
} }
@ -119,10 +119,7 @@ nsSVGTextFrame::AttributeChanged(PRInt32 aNameSpaceID,
aAttribute == nsGkAtoms::y || aAttribute == nsGkAtoms::y ||
aAttribute == nsGkAtoms::dx || aAttribute == nsGkAtoms::dx ||
aAttribute == nsGkAtoms::dy) { aAttribute == nsGkAtoms::dy) {
mPositioningDirty = PR_TRUE; UpdateGlyphPositioning();
if (mMetricsState == unsuspended) {
UpdateGlyphPositioning();
}
} }
return NS_OK; return NS_OK;
@ -131,9 +128,6 @@ nsSVGTextFrame::AttributeChanged(PRInt32 aNameSpaceID,
NS_IMETHODIMP NS_IMETHODIMP
nsSVGTextFrame::DidSetStyleContext() nsSVGTextFrame::DidSetStyleContext()
{ {
#ifdef DEBUG
printf("** nsSVGTextFrame::DidSetStyleContext\n");
#endif
nsSVGUtils::StyleEffects(this); nsSVGUtils::StyleEffects(this);
return NS_OK; return NS_OK;
@ -145,23 +139,6 @@ nsSVGTextFrame::GetType() const
return nsLayoutAtoms::svgTextFrame; return nsLayoutAtoms::svgTextFrame;
} }
NS_IMETHODIMP
nsSVGTextFrame::RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame)
{
nsSVGOuterSVGFrame* outerSVGFrame = nsSVGUtils::GetOuterSVGFrame(this);
if (outerSVGFrame)
outerSVGFrame->SuspendRedraw();
mFragmentTreeDirty = PR_TRUE;
nsresult rv = nsSVGTextFrameBase::RemoveFrame(aListName, aOldFrame);
if (outerSVGFrame)
outerSVGFrame->UnsuspendRedraw();
return rv;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// nsISVGValueObserver methods: // nsISVGValueObserver methods:
@ -189,7 +166,7 @@ nsSVGTextFrame::DidModifySVGObservable (nsISVGValue* observable,
NS_IMETHODIMP NS_IMETHODIMP
nsSVGTextFrame::GetNumberOfChars(PRInt32 *_retval) nsSVGTextFrame::GetNumberOfChars(PRInt32 *_retval)
{ {
EnsureFragmentTreeUpToDate(); UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetNumberOfChars(_retval); return nsSVGTextFrameBase::GetNumberOfChars(_retval);
} }
@ -197,7 +174,7 @@ nsSVGTextFrame::GetNumberOfChars(PRInt32 *_retval)
NS_IMETHODIMP NS_IMETHODIMP
nsSVGTextFrame::GetComputedTextLength(float *_retval) nsSVGTextFrame::GetComputedTextLength(float *_retval)
{ {
EnsureFragmentTreeUpToDate(); UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetComputedTextLength(_retval); return nsSVGTextFrameBase::GetComputedTextLength(_retval);
} }
@ -205,7 +182,7 @@ nsSVGTextFrame::GetComputedTextLength(float *_retval)
NS_IMETHODIMP NS_IMETHODIMP
nsSVGTextFrame::GetSubStringLength(PRUint32 charnum, PRUint32 nchars, float *_retval) nsSVGTextFrame::GetSubStringLength(PRUint32 charnum, PRUint32 nchars, float *_retval)
{ {
EnsureFragmentTreeUpToDate(); UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetSubStringLength(charnum, nchars, _retval); return nsSVGTextFrameBase::GetSubStringLength(charnum, nchars, _retval);
} }
@ -213,7 +190,7 @@ nsSVGTextFrame::GetSubStringLength(PRUint32 charnum, PRUint32 nchars, float *_re
NS_IMETHODIMP NS_IMETHODIMP
nsSVGTextFrame::GetStartPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval) nsSVGTextFrame::GetStartPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval)
{ {
EnsureFragmentTreeUpToDate(); UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetStartPositionOfChar(charnum, _retval); return nsSVGTextFrameBase::GetStartPositionOfChar(charnum, _retval);
} }
@ -221,7 +198,7 @@ nsSVGTextFrame::GetStartPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retva
NS_IMETHODIMP NS_IMETHODIMP
nsSVGTextFrame::GetEndPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval) nsSVGTextFrame::GetEndPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval)
{ {
EnsureFragmentTreeUpToDate(); UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetEndPositionOfChar(charnum, _retval); return nsSVGTextFrameBase::GetEndPositionOfChar(charnum, _retval);
} }
@ -229,7 +206,7 @@ nsSVGTextFrame::GetEndPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval)
NS_IMETHODIMP NS_IMETHODIMP
nsSVGTextFrame::GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval) nsSVGTextFrame::GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval)
{ {
EnsureFragmentTreeUpToDate(); UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetExtentOfChar(charnum, _retval); return nsSVGTextFrameBase::GetExtentOfChar(charnum, _retval);
} }
@ -237,7 +214,7 @@ nsSVGTextFrame::GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval)
NS_IMETHODIMP NS_IMETHODIMP
nsSVGTextFrame::GetRotationOfChar(PRUint32 charnum, float *_retval) nsSVGTextFrame::GetRotationOfChar(PRUint32 charnum, float *_retval)
{ {
EnsureFragmentTreeUpToDate(); UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetRotationOfChar(charnum, _retval); return nsSVGTextFrameBase::GetRotationOfChar(charnum, _retval);
} }
@ -245,7 +222,7 @@ nsSVGTextFrame::GetRotationOfChar(PRUint32 charnum, float *_retval)
NS_IMETHODIMP NS_IMETHODIMP
nsSVGTextFrame::GetCharNumAtPosition(nsIDOMSVGPoint *point, PRInt32 *_retval) nsSVGTextFrame::GetCharNumAtPosition(nsIDOMSVGPoint *point, PRInt32 *_retval)
{ {
EnsureFragmentTreeUpToDate(); UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetCharNumAtPosition(point, _retval); return nsSVGTextFrameBase::GetCharNumAtPosition(point, _retval);
} }
@ -267,50 +244,17 @@ NS_IMETHODIMP
nsSVGTextFrame::NotifyRedrawSuspended() nsSVGTextFrame::NotifyRedrawSuspended()
{ {
mMetricsState = suspended; mMetricsState = suspended;
mFragmentTreeState = suspended;
nsSVGTextFrameBase::NotifyRedrawSuspended(); return nsSVGTextFrameBase::NotifyRedrawSuspended();
for (nsIFrame* kid = mFrames.FirstChild(); kid;
kid = kid->GetNextSibling()) {
nsISVGGlyphFragmentNode* fragmentNode = nsnull;
CallQueryInterface(kid, &fragmentNode);
if (fragmentNode) {
fragmentNode->NotifyGlyphFragmentTreeSuspended();
}
}
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsSVGTextFrame::NotifyRedrawUnsuspended() nsSVGTextFrame::NotifyRedrawUnsuspended()
{ {
NS_ASSERTION(mMetricsState == suspended, "metrics state not suspended during redraw");
NS_ASSERTION(mFragmentTreeState == suspended, "fragment tree not suspended during redraw");
// 3 passes:
nsIFrame *kid;
mFragmentTreeState = updating;
for (kid = mFrames.FirstChild(); kid; kid = kid->GetNextSibling()) {
nsISVGGlyphFragmentNode* node = nsnull;
CallQueryInterface(kid, &node);
if (node) {
node->NotifyGlyphFragmentTreeUnsuspended();
}
}
mFragmentTreeState = unsuspended;
if (mFragmentTreeDirty)
UpdateFragmentTree();
mMetricsState = unsuspended; mMetricsState = unsuspended;
if (mPositioningDirty) UpdateGlyphPositioning();
UpdateGlyphPositioning();
return nsSVGTextFrameBase::NotifyRedrawUnsuspended();
nsSVGTextFrameBase::NotifyRedrawUnsuspended();
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -330,7 +274,7 @@ nsSVGTextFrame::SetOverrideCTM(nsIDOMSVGMatrix *aCTM)
NS_IMETHODIMP NS_IMETHODIMP
nsSVGTextFrame::GetBBox(nsIDOMSVGRect **_retval) nsSVGTextFrame::GetBBox(nsIDOMSVGRect **_retval)
{ {
EnsureFragmentTreeUpToDate(); UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetBBox(_retval); return nsSVGTextFrameBase::GetBBox(_retval);
} }
@ -380,100 +324,10 @@ nsSVGTextFrame::GetCanvasTM()
// //
void void
nsSVGTextFrame::NotifyGlyphMetricsChange(nsISVGGlyphFragmentNode* caller) nsSVGTextFrame::NotifyGlyphMetricsChange()
{ {
NS_ASSERTION(mMetricsState!=suspended, "notification during suspension");
mPositioningDirty = PR_TRUE; mPositioningDirty = PR_TRUE;
if (mMetricsState == unsuspended) { UpdateGlyphPositioning();
UpdateGlyphPositioning();
}
}
void
nsSVGTextFrame::NotifyGlyphFragmentTreeChange(nsISVGGlyphFragmentNode* caller)
{
NS_ASSERTION(mFragmentTreeState!=suspended, "notification during suspension");
mFragmentTreeDirty = PR_TRUE;
if (mFragmentTreeState == unsuspended) {
UpdateFragmentTree();
}
}
PRBool
nsSVGTextFrame::IsMetricsSuspended()
{
return (mMetricsState != unsuspended);
}
PRBool
nsSVGTextFrame::IsGlyphFragmentTreeSuspended()
{
return (mFragmentTreeState != unsuspended);
}
// ensure that the tree and positioning of the nodes is up-to-date
void
nsSVGTextFrame::EnsureFragmentTreeUpToDate()
{
PRBool resuspend_fragmenttree = PR_FALSE;
PRBool resuspend_metrics = PR_FALSE;
// give children a chance to flush their change notifications:
if (mFragmentTreeState == suspended) {
resuspend_fragmenttree = PR_TRUE;
mFragmentTreeState = updating;
nsIFrame* kid = mFrames.FirstChild();
while (kid) {
nsISVGGlyphFragmentNode* node = nsnull;
CallQueryInterface(kid, &node);
if (node)
node->NotifyGlyphFragmentTreeUnsuspended();
kid = kid->GetNextSibling();
}
mFragmentTreeState = unsuspended;
}
if (mFragmentTreeDirty)
UpdateFragmentTree();
if (mMetricsState == suspended) {
resuspend_metrics = PR_TRUE;
mMetricsState = unsuspended;
}
if (mPositioningDirty)
UpdateGlyphPositioning();
if (resuspend_fragmenttree || resuspend_metrics) {
mMetricsState = suspended;
mFragmentTreeState = suspended;
nsIFrame* kid = mFrames.FirstChild();
while (kid) {
nsISVGGlyphFragmentNode* fragmentNode = nsnull;
CallQueryInterface(kid, &fragmentNode);
if (fragmentNode) {
fragmentNode->NotifyGlyphFragmentTreeSuspended();
}
kid = kid->GetNextSibling();
}
}
}
void
nsSVGTextFrame::UpdateFragmentTree()
{
NS_ASSERTION(mFragmentTreeState == unsuspended, "updating during suspension!");
SetWhitespaceHandling();
mFragmentTreeDirty = PR_FALSE;
mPositioningDirty = PR_TRUE;
if (mMetricsState == unsuspended)
UpdateGlyphPositioning();
} }
static void static void
@ -538,7 +392,10 @@ GetSingleValue(nsISVGGlyphFragmentLeaf *fragment,
void void
nsSVGTextFrame::UpdateGlyphPositioning() nsSVGTextFrame::UpdateGlyphPositioning()
{ {
NS_ASSERTION(mMetricsState == unsuspended, "updating during suspension"); if (mMetricsState == suspended || !mPositioningDirty)
return;
SetWhitespaceHandling();
nsISVGGlyphFragmentNode* node = GetFirstGlyphFragmentChildNode(); nsISVGGlyphFragmentNode* node = GetFirstGlyphFragmentChildNode();
if (!node) return; if (!node) return;

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

@ -62,9 +62,6 @@ private:
public: public:
// nsIFrame: // nsIFrame:
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame);
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID, NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
nsIAtom* aAttribute, nsIAtom* aAttribute,
PRInt32 aModType); PRInt32 aModType);
@ -115,27 +112,18 @@ public:
NS_IMETHOD GetRotationOfChar(PRUint32 charnum, float *_retval); NS_IMETHOD GetRotationOfChar(PRUint32 charnum, float *_retval);
NS_IMETHOD GetCharNumAtPosition(nsIDOMSVGPoint *point, PRInt32 *_retval); NS_IMETHOD GetCharNumAtPosition(nsIDOMSVGPoint *point, PRInt32 *_retval);
void NotifyGlyphMetricsChange(nsISVGGlyphFragmentNode* caller); // nsSVGTextFrame
void NotifyGlyphFragmentTreeChange(nsISVGGlyphFragmentNode* caller); void NotifyGlyphMetricsChange();
PRBool IsMetricsSuspended();
PRBool IsGlyphFragmentTreeSuspended();
void UpdateFragmentTree();
private: private:
void EnsureFragmentTreeUpToDate();
void UpdateGlyphPositioning(); void UpdateGlyphPositioning();
nsCOMPtr<nsIDOMSVGMatrix> mCanvasTM; nsCOMPtr<nsIDOMSVGMatrix> mCanvasTM;
nsCOMPtr<nsIDOMSVGMatrix> mOverrideCTM; nsCOMPtr<nsIDOMSVGMatrix> mOverrideCTM;
enum UpdateState{ enum UpdateState { unsuspended, suspended };
unsuspended,
suspended,
updating};
UpdateState mFragmentTreeState;
UpdateState mMetricsState; UpdateState mMetricsState;
PRPackedBool mFragmentTreeDirty;
PRPackedBool mPropagateTransform; PRPackedBool mPropagateTransform;
PRPackedBool mPositioningDirty; PRPackedBool mPositioningDirty;
}; };

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

@ -224,7 +224,7 @@ nsSVGTextPathFrame::DidModifySVGObservable(nsISVGValue* observable,
{ {
nsSVGTextFrame* text_frame = GetTextFrame(); nsSVGTextFrame* text_frame = GetTextFrame();
if (text_frame) if (text_frame)
text_frame->NotifyGlyphMetricsChange(this); text_frame->NotifyGlyphMetricsChange();
return NS_OK; return NS_OK;
} }
@ -241,7 +241,7 @@ nsSVGTextPathFrame::AttributeChanged(PRInt32 aNameSpaceID,
aAttribute == nsGkAtoms::startOffset) { aAttribute == nsGkAtoms::startOffset) {
nsSVGTextFrame* text_frame = GetTextFrame(); nsSVGTextFrame* text_frame = GetTextFrame();
if (text_frame) if (text_frame)
text_frame->NotifyGlyphMetricsChange(this); text_frame->NotifyGlyphMetricsChange();
} else if (aNameSpaceID == kNameSpaceID_XLink && } else if (aNameSpaceID == kNameSpaceID_XLink &&
aAttribute == nsGkAtoms::href) { aAttribute == nsGkAtoms::href) {
NS_REMOVE_SVGVALUE_OBSERVER(mSegments); NS_REMOVE_SVGVALUE_OBSERVER(mSegments);