mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 04:15:43 +00:00
Bug 458010 - textPath should use nsReferencedElement instead of nsSVGUtils::GetReferencedFrame. r+sr=roc
This commit is contained in:
parent
22caaa4ccc
commit
76faac31ae
@ -41,6 +41,7 @@
|
||||
#include "nsSVGFilterFrame.h"
|
||||
#include "nsSVGClipPathFrame.h"
|
||||
#include "nsSVGMaskFrame.h"
|
||||
#include "nsSVGTextPathFrame.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsSVGRenderingObserver, nsIMutationObserver)
|
||||
|
||||
@ -248,6 +249,21 @@ nsSVGMarkerProperty::DoUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGTextPathProperty::DoUpdate()
|
||||
{
|
||||
nsSVGRenderingObserver::DoUpdate();
|
||||
if (!mFrame)
|
||||
return;
|
||||
|
||||
NS_ASSERTION(mFrame->IsFrameOfType(nsIFrame::eSVG), "SVG frame expected");
|
||||
|
||||
if (mFrame->GetType() == nsGkAtoms::svgTextPathFrame) {
|
||||
nsSVGTextPathFrame* textPathFrame = static_cast<nsSVGTextPathFrame*>(mFrame);
|
||||
textPathFrame->NotifyGlyphMetricsChange();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGPaintingProperty::DoUpdate()
|
||||
{
|
||||
@ -273,6 +289,10 @@ static nsSVGRenderingObserver *
|
||||
CreateMarkerProperty(nsIURI *aURI, nsIFrame *aFrame)
|
||||
{ return new nsSVGMarkerProperty(aURI, aFrame); }
|
||||
|
||||
static nsSVGRenderingObserver *
|
||||
CreateTextPathProperty(nsIURI *aURI, nsIFrame *aFrame)
|
||||
{ return new nsSVGTextPathProperty(aURI, aFrame); }
|
||||
|
||||
static nsSVGRenderingObserver *
|
||||
CreatePaintingProperty(nsIURI *aURI, nsIFrame *aFrame)
|
||||
{ return new nsSVGPaintingProperty(aURI, aFrame); }
|
||||
@ -304,6 +324,13 @@ nsSVGEffects::GetMarkerProperty(nsIURI *aURI, nsIFrame *aFrame, nsIAtom *aProp)
|
||||
GetEffectProperty(aURI, aFrame, aProp, CreateMarkerProperty));
|
||||
}
|
||||
|
||||
nsSVGTextPathProperty *
|
||||
nsSVGEffects::GetTextPathProperty(nsIURI *aURI, nsIFrame *aFrame, nsIAtom *aProp)
|
||||
{
|
||||
return static_cast<nsSVGTextPathProperty*>(
|
||||
GetEffectProperty(aURI, aFrame, aProp, CreateTextPathProperty));
|
||||
}
|
||||
|
||||
nsSVGPaintingProperty *
|
||||
nsSVGEffects::GetPaintingProperty(nsIURI *aURI, nsIFrame *aFrame, nsIAtom *aProp)
|
||||
{
|
||||
|
@ -159,6 +159,15 @@ protected:
|
||||
virtual void DoUpdate();
|
||||
};
|
||||
|
||||
class nsSVGTextPathProperty : public nsSVGRenderingObserver {
|
||||
public:
|
||||
nsSVGTextPathProperty(nsIURI *aURI, nsIFrame *aFrame)
|
||||
: nsSVGRenderingObserver(aURI, aFrame) {}
|
||||
|
||||
protected:
|
||||
virtual void DoUpdate();
|
||||
};
|
||||
|
||||
class nsSVGPaintingProperty : public nsSVGRenderingObserver {
|
||||
public:
|
||||
nsSVGPaintingProperty(nsIURI *aURI, nsIFrame *aFrame)
|
||||
@ -278,6 +287,11 @@ public:
|
||||
*/
|
||||
static nsSVGMarkerProperty *
|
||||
GetMarkerProperty(nsIURI *aURI, nsIFrame *aFrame, nsIAtom *aProp);
|
||||
/**
|
||||
* Get an nsSVGTextPathProperty for the frame, creating a fresh one if necessary
|
||||
*/
|
||||
static nsSVGTextPathProperty *
|
||||
GetTextPathProperty(nsIURI *aURI, nsIFrame *aFrame, nsIAtom *aProp);
|
||||
/**
|
||||
* Get an nsSVGPaintingProperty for the frame, creating a fresh one if necessary
|
||||
*/
|
||||
|
@ -53,16 +53,11 @@
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
||||
nsSVGGradientFrame::nsSVGGradientFrame(nsStyleContext* aContext,
|
||||
nsIDOMSVGURIReference *aRef) :
|
||||
nsSVGGradientFrame::nsSVGGradientFrame(nsStyleContext* aContext) :
|
||||
nsSVGGradientFrameBase(aContext),
|
||||
mLoopFlag(PR_FALSE),
|
||||
mNoHRefURI(PR_FALSE)
|
||||
{
|
||||
if (aRef) {
|
||||
// Get the href
|
||||
aRef->GetHref(getter_AddRefs(mHref));
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -303,8 +298,8 @@ nsSVGGradientFrame::GetReferencedGradient()
|
||||
|
||||
if (!property) {
|
||||
// Fetch our gradient element's xlink:href attribute
|
||||
nsAutoString href;
|
||||
mHref->GetAnimVal(href);
|
||||
nsSVGGradientElement *grad = static_cast<nsSVGGradientElement *>(mContent);
|
||||
const nsString &href = grad->mStringAttributes[nsSVGGradientElement::HREF].GetAnimValue();
|
||||
if (href.IsEmpty()) {
|
||||
mNoHRefURI = PR_TRUE;
|
||||
return nsnull; // no URL
|
||||
@ -620,10 +615,7 @@ NS_NewSVGLinearGradientFrame(nsIPresShell* aPresShell,
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMSVGURIReference> aRef = do_QueryInterface(aContent);
|
||||
NS_ASSERTION(aRef, "NS_NewSVGLinearGradientFrame -- Content doesn't support nsIDOMSVGURIReference");
|
||||
|
||||
return new (aPresShell) nsSVGLinearGradientFrame(aContext, aRef);
|
||||
return new (aPresShell) nsSVGLinearGradientFrame(aContext);
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
@ -637,8 +629,5 @@ NS_NewSVGRadialGradientFrame(nsIPresShell* aPresShell,
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMSVGURIReference> aRef = do_QueryInterface(aContent);
|
||||
NS_ASSERTION(aRef, "NS_NewSVGRadialGradientFrame -- Content doesn't support nsIDOMSVGURIReference");
|
||||
|
||||
return new (aPresShell) nsSVGRadialGradientFrame(aContext, aRef);
|
||||
return new (aPresShell) nsSVGRadialGradientFrame(aContext);
|
||||
}
|
||||
|
@ -57,8 +57,7 @@ typedef nsSVGPaintServerFrame nsSVGGradientFrameBase;
|
||||
class nsSVGGradientFrame : public nsSVGGradientFrameBase
|
||||
{
|
||||
protected:
|
||||
nsSVGGradientFrame(nsStyleContext* aContext,
|
||||
nsIDOMSVGURIReference *aRef);
|
||||
nsSVGGradientFrame(nsStyleContext* aContext);
|
||||
|
||||
public:
|
||||
// nsSVGPaintServerFrame methods:
|
||||
@ -136,10 +135,6 @@ protected:
|
||||
nsRefPtr<nsSVGElement> mSourceContent;
|
||||
|
||||
private:
|
||||
// href of the other gradient we reference (if any)
|
||||
// XXX this should go away, we can watch our content directly
|
||||
nsCOMPtr<nsIDOMSVGAnimatedString> mHref;
|
||||
|
||||
// Flag to mark this frame as "in use" during recursive calls along our
|
||||
// gradient's reference chain so we can detect reference loops. See:
|
||||
// http://www.w3.org/TR/SVG11/pservers.html#LinearGradientElementHrefAttribute
|
||||
@ -162,9 +157,8 @@ class nsSVGLinearGradientFrame : public nsSVGLinearGradientFrameBase
|
||||
nsIContent* aContent,
|
||||
nsStyleContext* aContext);
|
||||
protected:
|
||||
nsSVGLinearGradientFrame(nsStyleContext* aContext,
|
||||
nsIDOMSVGURIReference *aRef) :
|
||||
nsSVGLinearGradientFrameBase(aContext, aRef) {}
|
||||
nsSVGLinearGradientFrame(nsStyleContext* aContext) :
|
||||
nsSVGLinearGradientFrameBase(aContext) {}
|
||||
|
||||
public:
|
||||
// nsIFrame interface:
|
||||
@ -199,9 +193,8 @@ class nsSVGRadialGradientFrame : public nsSVGRadialGradientFrameBase
|
||||
nsIContent* aContent,
|
||||
nsStyleContext* aContext);
|
||||
protected:
|
||||
nsSVGRadialGradientFrame(nsStyleContext* aContext,
|
||||
nsIDOMSVGURIReference *aRef) :
|
||||
nsSVGRadialGradientFrameBase(aContext, aRef) {}
|
||||
nsSVGRadialGradientFrame(nsStyleContext* aContext) :
|
||||
nsSVGRadialGradientFrameBase(aContext) {}
|
||||
|
||||
public:
|
||||
// nsIFrame interface:
|
||||
|
@ -66,16 +66,11 @@ static void printRect(char *msg, nsIDOMSVGRect *aRect);
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
||||
nsSVGPatternFrame::nsSVGPatternFrame(nsStyleContext* aContext,
|
||||
nsIDOMSVGURIReference *aRef) :
|
||||
nsSVGPatternFrame::nsSVGPatternFrame(nsStyleContext* aContext) :
|
||||
nsSVGPatternFrameBase(aContext),
|
||||
mLoopFlag(PR_FALSE), mPaintLoopFlag(PR_FALSE),
|
||||
mNoHRefURI(PR_FALSE)
|
||||
{
|
||||
if (aRef) {
|
||||
// Get the hRef
|
||||
aRef->GetHref(getter_AddRefs(mHref));
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -437,8 +432,8 @@ nsSVGPatternFrame::GetReferencedPattern()
|
||||
|
||||
if (!property) {
|
||||
// Fetch our pattern element's xlink:href attribute
|
||||
nsAutoString href;
|
||||
mHref->GetAnimVal(href);
|
||||
nsSVGPatternElement *pattern = static_cast<nsSVGPatternElement *>(mContent);
|
||||
const nsString &href = pattern->mStringAttributes[nsSVGPatternElement::HREF].GetAnimValue();
|
||||
if (href.IsEmpty()) {
|
||||
mNoHRefURI = PR_TRUE;
|
||||
return nsnull; // no URL
|
||||
@ -761,14 +756,7 @@ nsIFrame* NS_NewSVGPatternFrame(nsIPresShell* aPresShell,
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMSVGURIReference> ref = do_QueryInterface(aContent);
|
||||
NS_ASSERTION(ref,
|
||||
"NS_NewSVGPatternFrame -- Content doesn't support nsIDOMSVGURIReference");
|
||||
|
||||
#ifdef DEBUG_scooter
|
||||
printf("NS_NewSVGPatternFrame\n");
|
||||
#endif
|
||||
return new (aPresShell) nsSVGPatternFrame(aContext, ref);
|
||||
return new (aPresShell) nsSVGPatternFrame(aContext);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_scooter
|
||||
|
@ -64,7 +64,7 @@ public:
|
||||
nsIContent* aContent,
|
||||
nsStyleContext* aContext);
|
||||
|
||||
nsSVGPatternFrame(nsStyleContext* aContext) : nsSVGPatternFrameBase(aContext) {}
|
||||
nsSVGPatternFrame(nsStyleContext* aContext);
|
||||
|
||||
nsresult PaintPattern(gfxASurface **surface,
|
||||
gfxMatrix *patternMatrix,
|
||||
@ -103,9 +103,6 @@ public:
|
||||
#endif // DEBUG
|
||||
|
||||
protected:
|
||||
nsSVGPatternFrame(nsStyleContext* aContext,
|
||||
nsIDOMSVGURIReference *aRef);
|
||||
|
||||
// Internal methods for handling referenced patterns
|
||||
nsSVGPatternFrame* GetReferencedPattern();
|
||||
// Helper to look at our pattern and then along its reference chain (if any)
|
||||
@ -150,7 +147,6 @@ private:
|
||||
nsCOMPtr<nsIDOMSVGMatrix> mCTM;
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIDOMSVGAnimatedString> mHref;
|
||||
// This flag is used to detect loops in xlink:href processing
|
||||
PRPackedBool mLoopFlag;
|
||||
// This flag is used to detect loops when painting this pattern
|
||||
|
@ -35,46 +35,14 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGTextPathFrame.h"
|
||||
#include "nsSVGTextFrame.h"
|
||||
#include "nsIDOMSVGTextPathElement.h"
|
||||
#include "nsIDOMSVGAnimatedLength.h"
|
||||
#include "nsSVGLength.h"
|
||||
#include "nsSVGLength2.h"
|
||||
#include "nsIDOMSVGURIReference.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsSVGEffects.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIDOMSVGAnimatedPathData.h"
|
||||
#include "nsSVGPathElement.h"
|
||||
#include "nsSVGTextPathElement.h"
|
||||
|
||||
|
||||
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,
|
||||
PRUint32 aStateMask)
|
||||
{
|
||||
mTextPathFrame->NotifyGlyphMetricsChange();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
||||
@ -97,24 +65,6 @@ NS_NewSVGTextPathFrame(nsIPresShell* aPresShell, nsIContent* aContent,
|
||||
return new (aPresShell) nsSVGTextPathFrame(aContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGTextPathFrame::Init(nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
nsSVGTextPathFrameBase::Init(aContent, aParent, aPrevInFlow);
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGURIReference> aRef = do_QueryInterface(mContent);
|
||||
if (aRef)
|
||||
aRef->GetHref(getter_AddRefs(mHref));
|
||||
if (!mHref)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIAtom *
|
||||
nsSVGTextPathFrame::GetType() const
|
||||
{
|
||||
@ -152,21 +102,32 @@ nsSVGTextPathFrame::GetDy()
|
||||
nsIFrame *
|
||||
nsSVGTextPathFrame::GetPathFrame()
|
||||
{
|
||||
nsIFrame *path = nsnull;
|
||||
nsSVGTextPathProperty *property =
|
||||
static_cast<nsSVGTextPathProperty*>(GetProperty(nsGkAtoms::href));
|
||||
|
||||
nsAutoString str;
|
||||
mHref->GetAnimVal(str);
|
||||
if (!property) {
|
||||
nsSVGTextPathElement *tp = static_cast<nsSVGTextPathElement*>(mContent);
|
||||
const nsString &href = tp->mStringAttributes[nsSVGTextPathElement::HREF].GetAnimValue();
|
||||
if (href.IsEmpty()) {
|
||||
return nsnull; // no URL
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> targetURI;
|
||||
nsCOMPtr<nsIURI> base = mContent->GetBaseURI();
|
||||
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI), str,
|
||||
mContent->GetCurrentDoc(), base);
|
||||
nsCOMPtr<nsIURI> targetURI;
|
||||
nsCOMPtr<nsIURI> base = mContent->GetBaseURI();
|
||||
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI), href,
|
||||
mContent->GetCurrentDoc(), base);
|
||||
|
||||
nsSVGUtils::GetReferencedFrame(&path, targetURI, mContent,
|
||||
PresContext()->PresShell());
|
||||
if (!path || (path->GetType() != nsGkAtoms::svgPathGeometryFrame))
|
||||
property = nsSVGEffects::GetTextPathProperty(
|
||||
targetURI, this, nsGkAtoms::href);
|
||||
if (!property)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIFrame *result = property->GetReferencedFrame();
|
||||
if (!result || result->GetType() != nsGkAtoms::svgPathGeometryFrame)
|
||||
return nsnull;
|
||||
return path;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
already_AddRefed<gfxFlattenedPath>
|
||||
@ -183,10 +144,6 @@ nsSVGTextPathFrame::GetFlattenedPath(nsIFrame *path)
|
||||
nsSVGPathGeometryElement *element = static_cast<nsSVGPathGeometryElement*>
|
||||
(path->GetContent());
|
||||
|
||||
if (!mPathListener) {
|
||||
mPathListener = new nsSVGPathListener(path->GetContent(), this);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> localTM = element->GetLocalTransformMatrix();
|
||||
|
||||
return element->GetFlattenedPath(localTM);
|
||||
@ -240,7 +197,8 @@ nsSVGTextPathFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
NotifyGlyphMetricsChange();
|
||||
} else if (aNameSpaceID == kNameSpaceID_XLink &&
|
||||
aAttribute == nsGkAtoms::href) {
|
||||
mPathListener = nsnull;
|
||||
// Blow away our reference, if any
|
||||
DeleteProperty(nsGkAtoms::href);
|
||||
NotifyGlyphMetricsChange();
|
||||
}
|
||||
|
||||
|
@ -40,29 +40,9 @@
|
||||
#include "nsSVGTSpanFrame.h"
|
||||
#include "nsIDOMSVGAnimatedString.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
|
||||
@ -75,9 +55,6 @@ protected:
|
||||
|
||||
public:
|
||||
// nsIFrame:
|
||||
NS_IMETHOD Init(nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIFrame* aPrevInFlow);
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
@ -110,11 +87,6 @@ protected:
|
||||
|
||||
private:
|
||||
already_AddRefed<gfxFlattenedPath> GetFlattenedPath(nsIFrame *path);
|
||||
|
||||
nsCOMPtr<nsIDOMSVGAnimatedString> mHref;
|
||||
nsRefPtr<nsSVGPathListener> mPathListener;
|
||||
|
||||
friend class nsSVGPathListener;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user