Bug 370416 - <textPath> not updating when referenced path changed.r=longsonr, sr=sicking

This commit is contained in:
tor@cs.brown.edu 2007-04-26 08:46:29 -07:00
Родитель 69e3219864
Коммит 3231a0ee55
2 изменённых файлов: 58 добавлений и 60 удалений

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

@ -44,13 +44,34 @@
#include "nsContentUtils.h"
#include "nsIDOMSVGAnimatedPathData.h"
#include "nsSVGPathElement.h"
#include "nsISVGValueUtils.h"
#include "nsIDOMSVGPathSegList.h"
NS_INTERFACE_MAP_BEGIN(nsSVGTextPathFrame)
NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_END_INHERITING(nsSVGTextPathFrameBase)
NS_IMPL_ISUPPORTS1(nsSVGPathListener, nsIMutationObserver)
nsSVGPathListener::nsSVGPathListener(nsIContent *aPathElement,
nsSVGTextPathFrame *aTextPathFrame) :
mTextPathFrame(aTextPathFrame)
{
mObservedPath = do_GetWeakReference(aPathElement);
aPathElement->AddMutationObserver(this);
}
nsSVGPathListener::~nsSVGPathListener()
{
nsCOMPtr<nsIContent> path = do_QueryReferent(mObservedPath);
if (path)
path->RemoveMutationObserver(this);
}
void
nsSVGPathListener::AttributeChanged(nsIDocument *aDocument,
nsIContent *aContent,
PRInt32 aNameSpaceID,
nsIAtom *aAttribute,
PRInt32 aModType)
{
mTextPathFrame->UpdateGraphic();
}
//----------------------------------------------------------------------
// Implementation
@ -75,12 +96,6 @@ NS_NewSVGTextPathFrame(nsIPresShell* aPresShell, nsIContent* aContent,
return new (aPresShell) nsSVGTextPathFrame(aContext);
}
nsSVGTextPathFrame::~nsSVGTextPathFrame()
{
if (mSegments)
NS_REMOVE_SVGVALUE_OBSERVER(mSegments);
}
NS_IMETHODIMP
nsSVGTextPathFrame::Init(nsIContent* aContent,
nsIFrame* aParent,
@ -193,40 +208,18 @@ nsSVGTextPathFrame::GetFlattenedPath() {
if (!path)
return nsnull;
if (!mSegments) {
nsCOMPtr<nsIDOMSVGAnimatedPathData> data =
do_QueryInterface(path->GetContent());
if (data) {
data->GetAnimatedPathSegList(getter_AddRefs(mSegments));
NS_ADD_SVGVALUE_OBSERVER(mSegments);
}
}
nsSVGPathGeometryElement *element = NS_STATIC_CAST(nsSVGPathGeometryElement*,
path->GetContent());
if (!mPathListener) {
mPathListener = new nsSVGPathListener(path->GetContent(), this);
}
nsCOMPtr<nsIDOMSVGMatrix> localTM = element->GetLocalTransformMatrix();
return element->GetFlattenedPath(localTM);
}
//----------------------------------------------------------------------
// nsISVGValueObserver methods:
NS_IMETHODIMP
nsSVGTextPathFrame::WillModifySVGObservable(nsISVGValue* observable,
nsISVGValue::modificationType aModType)
{
return NS_OK;
}
NS_IMETHODIMP
nsSVGTextPathFrame::DidModifySVGObservable(nsISVGValue* observable,
nsISVGValue::modificationType aModType)
{
UpdateGraphic();
return NS_OK;
}
//----------------------------------------------------------------------
// nsIFrame methods
@ -240,8 +233,8 @@ nsSVGTextPathFrame::AttributeChanged(PRInt32 aNameSpaceID,
UpdateGraphic();
} else if (aNameSpaceID == kNameSpaceID_XLink &&
aAttribute == nsGkAtoms::href) {
NS_REMOVE_SVGVALUE_OBSERVER(mSegments);
mSegments = nsnull;
mPathListener = nsnull;
UpdateGraphic();
}
return NS_OK;

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

@ -38,18 +38,34 @@
#define NSSVGTEXTPATHFRAME_H
#include "nsSVGTSpanFrame.h"
#include "nsISVGValueObserver.h"
#include "nsWeakReference.h"
#include "nsIDOMSVGAnimatedString.h"
#include "nsIDOMSVGPathSegList.h"
#include "nsSVGLengthList.h"
#include "nsIDOMSVGLength.h"
#include "gfxPath.h"
#include "nsStubMutationObserver.h"
class nsSVGTextPathFrame;
class nsSVGPathListener : public nsStubMutationObserver {
public:
nsSVGPathListener(nsIContent *aPathElement,
nsSVGTextPathFrame *aTextPathFrame);
~nsSVGPathListener();
// nsISupports
NS_DECL_ISUPPORTS
// nsIMutationObserver
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
private:
nsWeakPtr mObservedPath;
nsSVGTextPathFrame *mTextPathFrame;
};
typedef nsSVGTSpanFrame nsSVGTextPathFrameBase;
class nsSVGTextPathFrame : public nsSVGTextPathFrameBase,
public nsISVGValueObserver
class nsSVGTextPathFrame : public nsSVGTextPathFrameBase
{
public:
nsSVGTextPathFrame(nsStyleContext* aContext) : nsSVGTextPathFrameBase(aContext) {}
@ -75,24 +91,11 @@ public:
}
#endif
// nsISVGValueObserver interface:
NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable,
nsISVGValue::modificationType aModType);
NS_IMETHOD DidModifySVGObservable(nsISVGValue* observable,
nsISVGValue::modificationType aModType);
// nsSVGTextPathFrame methods:
already_AddRefed<gfxFlattenedPath> GetFlattenedPath();
nsIFrame *GetPathFrame();
// nsISupports interface:
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return 1; }
NS_IMETHOD_(nsrefcnt) Release() { return 1; }
protected:
virtual ~nsSVGTextPathFrame();
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetX();
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetY();
@ -103,9 +106,11 @@ private:
nsCOMPtr<nsIDOMSVGLength> mStartOffset;
nsCOMPtr<nsIDOMSVGAnimatedString> mHref;
nsCOMPtr<nsIDOMSVGPathSegList> mSegments;
nsRefPtr<nsSVGPathListener> mPathListener;
nsCOMPtr<nsIDOMSVGLengthList> mX;
friend class nsSVGPathListener;
};
#endif