Bug 276316 - gradients should be "live".

Patch by scootermorris@comcast.net, r=afri.
This commit is contained in:
tor%cs.brown.edu 2005-03-09 19:24:18 +00:00
Родитель fced62404c
Коммит 5e8bf8ecda
9 изменённых файлов: 783 добавлений и 302 удалений

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

@ -67,7 +67,8 @@ class nsISVGValue : public nsISupports
public:
enum modificationType {
mod_other = 0,
mod_context
mod_context,
mod_die
};
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISVGVALUE_IID)

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

@ -85,6 +85,7 @@ CPPSRCS = \
nsSVGPolygonFrame.cpp \
nsSVGPolylineFrame.cpp \
nsSVGRectFrame.cpp \
nsSVGStopFrame.cpp \
nsSVGTSpanFrame.cpp \
nsSVGTextFrame.cpp \
nsSVGUseFrame.cpp \

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

@ -49,7 +49,8 @@
#include "nsISVGRendererRegion.h"
#include "nsISVGContainerFrame.h"
#include "nsISVGTextContainerFrame.h"
#include "nsSVGGradientFrame.h"
#include "nsSVGGradient.h"
#include "nsISVGValueUtils.h"
#include "nsReadableUtils.h"
#include "nsCRT.h"
#include "prdtoa.h"
@ -66,6 +67,8 @@
typedef nsFrame nsSVGGlyphFrameBase;
class nsSVGGlyphFrame : public nsSVGGlyphFrameBase,
public nsISVGValueObserver,
public nsSupportsWeakReference,
public nsISVGGlyphGeometrySource, // : nsISVGGlyphMetricsSource : nsISVGGeometrySource
public nsISVGGlyphFragmentLeaf, // : nsISVGGlyphFragmentNode
public nsISVGChildFrame
@ -104,6 +107,12 @@ public:
NS_IMETHOD GetSelected(PRBool *aSelected) const;
NS_IMETHOD IsSelectable(PRBool* aIsSelectable, PRUint8* aSelectStyle);
// nsISVGValueObserver
NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable,
nsISVGValue::modificationType aModType);
NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable,
nsISVGValue::modificationType aModType);
// nsISVGChildFrame interface:
NS_IMETHOD Paint(nsISVGRendererCanvas* canvas, const nsRect& dirtyRectTwips);
NS_IMETHOD GetFrameForPoint(float x, float y, nsIFrame** hit);
@ -157,15 +166,18 @@ protected:
nsISVGOuterSVGFrame *GetOuterSVGFrame();
nsISVGTextFrame *GetTextFrame();
void TransformPoint(float& x, float& y);
NS_IMETHOD Update(PRUint32 aFlags);
nsCOMPtr<nsISVGRendererGlyphGeometry> mGeometry;
nsCOMPtr<nsISVGRendererGlyphMetrics> mMetrics;
float mX, mY;
PRUint32 mCharOffset;
PRUint32 mGeometryUpdateFlags;
PRUint32 mMetricsUpdateFlags;
PRUint32 mCharOffset;
PRBool mFragmentTreeDirty;
nsString mCharacterData;
nsCOMPtr<nsISVGGradient> mFillGradient;
nsCOMPtr<nsISVGGradient> mStrokeGradient;
};
//----------------------------------------------------------------------
@ -204,7 +216,12 @@ nsSVGGlyphFrame::nsSVGGlyphFrame()
nsSVGGlyphFrame::~nsSVGGlyphFrame()
{
if (mFillGradient) {
NS_ADD_SVGVALUE_OBSERVER(mFillGradient);
}
if (mStrokeGradient) {
NS_ADD_SVGVALUE_OBSERVER(mStrokeGradient);
}
}
@ -217,6 +234,8 @@ NS_INTERFACE_MAP_BEGIN(nsSVGGlyphFrame)
NS_INTERFACE_MAP_ENTRY(nsISVGGlyphGeometrySource)
NS_INTERFACE_MAP_ENTRY(nsISVGGlyphFragmentLeaf)
NS_INTERFACE_MAP_ENTRY(nsISVGGlyphFragmentNode)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver)
NS_INTERFACE_MAP_ENTRY(nsISVGChildFrame)
NS_INTERFACE_MAP_END_INHERITING(nsSVGGlyphFrameBase)
@ -263,9 +282,15 @@ NS_IMETHODIMP
nsSVGGlyphFrame::CharacterDataChanged(nsPresContext* aPresContext,
nsIContent* aChild,
PRBool aAppend)
{
return Update(nsISVGGeometrySource::UPDATEMASK_ALL);
}
NS_IMETHODIMP
nsSVGGlyphFrame::Update(PRUint32 aFlags)
{
#ifdef DEBUG
// printf("** nsSVGGlyphFrame::CharacterDataChanged\n");
// printf("** nsSVGGlyphFrame::Update\n");
#endif
nsISVGOuterSVGFrame* outerSVGFrame = GetOuterSVGFrame();
if (!outerSVGFrame) {
@ -275,8 +300,8 @@ nsSVGGlyphFrame::CharacterDataChanged(nsPresContext* aPresContext,
outerSVGFrame->SuspendRedraw();
UpdateFragmentTree();
UpdateMetrics(nsISVGGeometrySource::UPDATEMASK_ALL);
UpdateGeometry(nsISVGGeometrySource::UPDATEMASK_ALL);
UpdateMetrics(aFlags);
UpdateGeometry(aFlags);
outerSVGFrame->UnsuspendRedraw();
return NS_OK;
@ -285,7 +310,18 @@ nsSVGGlyphFrame::CharacterDataChanged(nsPresContext* aPresContext,
NS_IMETHODIMP
nsSVGGlyphFrame::DidSetStyleContext(nsPresContext* aPresContext)
{
return CharacterDataChanged(aPresContext, NULL, PR_FALSE);
// One of the styles that might have been changed are the urls that
// point to gradients, etc. Drop our cached values to those
if (mFillGradient) {
NS_ADD_SVGVALUE_OBSERVER(mFillGradient);
mFillGradient = nsnull;
}
if (mStrokeGradient) {
NS_ADD_SVGVALUE_OBSERVER(mStrokeGradient);
mStrokeGradient = nsnull;
}
return CharacterDataChanged(aPresContext, nsnull, PR_FALSE);
}
NS_IMETHODIMP
@ -339,6 +375,44 @@ nsSVGGlyphFrame::IsSelectable(PRBool* aIsSelectable,
return rv;
}
//----------------------------------------------------------------------
// nsISVGValueObserver methods:
NS_IMETHODIMP
nsSVGGlyphFrame::WillModifySVGObservable(nsISVGValue* observable,
nsISVGValue::modificationType aModType)
{
return NS_OK;
}
NS_IMETHODIMP
nsSVGGlyphFrame::DidModifySVGObservable (nsISVGValue* observable,
nsISVGValue::modificationType aModType)
{
// Is this a gradient?
nsCOMPtr<nsISVGGradient>val = do_QueryInterface(observable);
if (val) {
// Yes, we need to handle this differently
nsCOMPtr<nsISVGGradient>fill = do_QueryInterface(mFillGradient);
if (fill == val) {
if (aModType == nsISVGValue::mod_die) {
mFillGradient = nsnull;
}
return Update(nsISVGGeometrySource::UPDATEMASK_FILL_PAINT);
} else {
// No real harm in assuming a stroke gradient at this point
if (aModType == nsISVGValue::mod_die) {
mStrokeGradient = nsnull;
}
return Update(nsISVGGeometrySource::UPDATEMASK_STROKE_PAINT);
}
} else {
// No, all of our other observables update the canvastm by default
return Update(nsISVGGeometrySource::UPDATEMASK_CANVAS_TM);
}
return NS_OK;
}
//----------------------------------------------------------------------
// nsISVGChildFrame methods
@ -418,19 +492,7 @@ nsSVGGlyphFrame::GetCoveredRegion()
NS_IMETHODIMP
nsSVGGlyphFrame::InitialUpdate()
{
nsISVGOuterSVGFrame* outerSVGFrame = GetOuterSVGFrame();
if (!outerSVGFrame) {
NS_ERROR("No outerSVGFrame");
return NS_ERROR_FAILURE;
}
outerSVGFrame->SuspendRedraw();
UpdateFragmentTree();
UpdateMetrics(nsISVGGeometrySource::UPDATEMASK_ALL);
UpdateGeometry(nsISVGGeometrySource::UPDATEMASK_ALL);
outerSVGFrame->UnsuspendRedraw();
return NS_OK;
return Update(nsISVGGeometrySource::UPDATEMASK_ALL);
}
NS_IMETHODIMP
@ -660,12 +722,19 @@ nsSVGGlyphFrame::GetStrokePaint(nscolor *aStrokePaint)
NS_IMETHODIMP
nsSVGGlyphFrame::GetStrokeGradient(nsISVGGradient **aGrad)
{
nsIURI *aServer;
aServer = GetStyleSVG()->mStroke.mPaint.mPaintServer;
if (aServer == nsnull)
return NS_ERROR_FAILURE;
// Now have the URI. Get the gradient
return NS_GetSVGGradient(aGrad, aServer, mContent, nsSVGGlyphFrameBase::GetPresContext()->PresShell());
nsresult rv = NS_OK;
if (!mStrokeGradient) {
nsIURI *aServer;
aServer = GetStyleSVG()->mStroke.mPaint.mPaintServer;
if (aServer == nsnull)
return NS_ERROR_FAILURE;
// Now have the URI. Get the gradient
rv = NS_GetSVGGradient(getter_AddRefs(mStrokeGradient), aServer, mContent,
nsSVGGlyphFrameBase::GetPresContext()->PresShell());
NS_ADD_SVGVALUE_OBSERVER(mStrokeGradient);
}
*aGrad = mStrokeGradient;
return rv;
}
/* readonly attribute unsigned short fillPaintType; */
@ -684,19 +753,25 @@ nsSVGGlyphFrame::GetFillPaint(nscolor *aFillPaint)
return NS_OK;
}
/* [noscript] void GetStrokeGradient(nsISVGGradient **aGrad); */
/* [noscript] void GetFillGradient(nsISVGGradient **aGrad); */
NS_IMETHODIMP
nsSVGGlyphFrame::GetFillGradient(nsISVGGradient **aGrad)
{
nsIURI *aServer;
aServer = GetStyleSVG()->mFill.mPaint.mPaintServer;
if (aServer == nsnull)
return NS_ERROR_FAILURE;
// Now have the URI. Get the gradient
return NS_GetSVGGradient(aGrad, aServer, mContent, nsSVGGlyphFrameBase::GetPresContext()->PresShell());
nsresult rv = NS_OK;
if (!mFillGradient) {
nsIURI *aServer;
aServer = GetStyleSVG()->mFill.mPaint.mPaintServer;
if (aServer == nsnull)
return NS_ERROR_FAILURE;
// Now have the URI. Get the gradient
rv = NS_GetSVGGradient(getter_AddRefs(mFillGradient), aServer, mContent,
nsSVGGlyphFrameBase::GetPresContext()->PresShell());
NS_ADD_SVGVALUE_OBSERVER(mFillGradient);
}
*aGrad = mFillGradient;
return rv;
}
/* [noscript] boolean isClipChild; */
NS_IMETHODIMP
nsSVGGlyphFrame::IsClipChild(PRBool *_retval)

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

@ -43,6 +43,18 @@
#include "nsIURI.h"
#include "nsIContent.h"
nsresult NS_NewSVGGradient(nsISVGGradient **result, nsIURI *uri, nsIContent *aContent);
nsresult NS_GetSVGGradient(nsISVGGradient** result,
nsIURI* aURI,
nsIContent* aContent,
nsIPresShell* aPresShell);
nsresult NS_NewSVGLinearGradientFrame(nsIPresShell* aPresShell,
nsIContent* aContent,
nsIFrame** aNewFrame);
nsresult NS_NewSVGRadialGradientFrame(nsIPresShell* aPresShell,
nsIContent* aContent,
nsIFrame** aNewFrame);
#endif // __NS_SVGGRADIENT_H__

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -39,9 +39,9 @@
#ifndef __NS_SVGGRADIENTFRAME_H__
#define __NS_SVGGRADIENTFRAME_H__
#include "nsISVGGradient.h"
#include "nsIURI.h"
#include "nsIFrame.h"
#include "nsIContent.h"
#include "nsIPresShell.h"
nsresult NS_NewSVGLinearGradientFrame(nsIPresShell* aPresShell,
nsIContent* aContent,
@ -50,15 +50,5 @@ nsresult NS_NewSVGLinearGradientFrame(nsIPresShell* aPresShell,
nsresult NS_NewSVGRadialGradientFrame(nsIPresShell* aPresShell,
nsIContent* aContent,
nsIFrame** aNewFrame);
nsresult NS_NewSVGStopFrame(nsIPresShell* aPresShell,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame** aNewFrame);
nsresult NS_GetSVGGradient(nsISVGGradient** result,
nsIURI* aURI,
nsIContent* aContent,
nsIPresShell* aPresShell);
#endif // __NS_SVGGRADIENTFRAME_H__

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

@ -47,7 +47,6 @@
#include "nsIDOMSVGAnimTransformList.h"
#include "nsIDOMSVGTransformList.h"
#include "nsISVGContainerFrame.h"
#include "nsSVGGradientFrame.h"
#include "nsReadableUtils.h"
#include "nsUnicharUtils.h"
#include "nsSVGAtoms.h"
@ -66,7 +65,8 @@
// nsSVGPathGeometryFrame
nsSVGPathGeometryFrame::nsSVGPathGeometryFrame()
: mUpdateFlags(0), mPropagateTransform(PR_TRUE)
: mUpdateFlags(0), mPropagateTransform(PR_TRUE),
mFillGradient(nsnull), mStrokeGradient(nsnull)
{
#ifdef DEBUG
// printf("nsSVGPathGeometryFrame %p CTOR\n", this);
@ -83,8 +83,13 @@ nsSVGPathGeometryFrame::~nsSVGPathGeometryFrame()
NS_ASSERTION(transformable, "wrong content element");
nsCOMPtr<nsIDOMSVGAnimatedTransformList> transforms;
transformable->GetTransform(getter_AddRefs(transforms));
nsCOMPtr<nsISVGValue> value = do_QueryInterface(transforms);
NS_REMOVE_SVGVALUE_OBSERVER(transforms);
if (mFillGradient) {
NS_REMOVE_SVGVALUE_OBSERVER(mFillGradient);
}
if (mStrokeGradient) {
NS_REMOVE_SVGVALUE_OBSERVER(mStrokeGradient);
}
}
//----------------------------------------------------------------------
@ -108,9 +113,6 @@ nsSVGPathGeometryFrame::Init(nsPresContext* aPresContext,
nsStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
// rv = nsSVGPathGeometryFrameBase::Init(aPresContext, aContent, aParent,
// aContext, aPrevInFlow);
mContent = aContent;
NS_IF_ADDREF(mContent);
mParent = aParent;
@ -147,6 +149,17 @@ nsSVGPathGeometryFrame::AttributeChanged(nsIContent* aChild,
NS_IMETHODIMP
nsSVGPathGeometryFrame::DidSetStyleContext(nsPresContext* aPresContext)
{
// One of the styles that might have been changed are the urls that
// point to gradients, etc. Drop our cached values to those
if (mFillGradient) {
NS_REMOVE_SVGVALUE_OBSERVER(mFillGradient);
mFillGradient = nsnull;
}
if (mStrokeGradient) {
NS_REMOVE_SVGVALUE_OBSERVER(mStrokeGradient);
mStrokeGradient = nsnull;
}
// XXX: we'd like to use the style_hint mechanism and the
// ContentStateChanged/AttributeChanged functions for style changes
// to get slightly finer granularity, but unfortunately the
@ -407,11 +420,27 @@ NS_IMETHODIMP
nsSVGPathGeometryFrame::DidModifySVGObservable (nsISVGValue* observable,
nsISVGValue::modificationType aModType)
{
// the observables we're listening in on affect the canvastm by
// default. We can specialize in the subclasses when needed.
UpdateGraphic(nsISVGGeometrySource::UPDATEMASK_CANVAS_TM);
// Is this a gradient?
nsCOMPtr<nsISVGGradient>val = do_QueryInterface(observable);
if (val) {
// Yes, we need to handle this differently
nsCOMPtr<nsISVGGradient>fill = do_QueryInterface(mFillGradient);
if (fill == val) {
if (aModType == nsISVGValue::mod_die) {
mFillGradient = nsnull;
}
UpdateGraphic(nsISVGGeometrySource::UPDATEMASK_FILL_PAINT);
} else {
// No real harm in assuming a stroke gradient at this point
if (aModType == nsISVGValue::mod_die) {
mStrokeGradient = nsnull;
}
UpdateGraphic(nsISVGGeometrySource::UPDATEMASK_STROKE_PAINT);
}
} else {
// No, all of our other observables update the canvastm by default
UpdateGraphic(nsISVGGeometrySource::UPDATEMASK_CANVAS_TM);
}
return NS_OK;
}
@ -586,12 +615,19 @@ nsSVGPathGeometryFrame::GetStrokePaint(nscolor *aStrokePaint)
NS_IMETHODIMP
nsSVGPathGeometryFrame::GetStrokeGradient(nsISVGGradient **aGrad)
{
nsIURI *aServer;
aServer = GetStyleSVG()->mStroke.mPaint.mPaintServer;
if (aServer == nsnull)
return NS_ERROR_FAILURE;
// Now have the URI. Get the gradient
return NS_GetSVGGradient(aGrad, aServer, mContent, nsSVGPathGeometryFrameBase::GetPresContext()->PresShell());
nsresult rv = NS_OK;
if (!mStrokeGradient) {
nsIURI *aServer;
aServer = GetStyleSVG()->mStroke.mPaint.mPaintServer;
if (aServer == nsnull)
return NS_ERROR_FAILURE;
// Now have the URI. Get the gradient
rv = NS_GetSVGGradient(getter_AddRefs(mStrokeGradient), aServer, mContent,
nsSVGPathGeometryFrameBase::GetPresContext()->PresShell());
NS_ADD_SVGVALUE_OBSERVER(mStrokeGradient);
}
*aGrad = mStrokeGradient;
return rv;
}
/* readonly attribute unsigned short fillPaintType; */
@ -614,12 +650,19 @@ nsSVGPathGeometryFrame::GetFillPaint(nscolor *aFillPaint)
NS_IMETHODIMP
nsSVGPathGeometryFrame::GetFillGradient(nsISVGGradient **aGrad)
{
nsIURI *aServer;
aServer = GetStyleSVG()->mFill.mPaint.mPaintServer;
if (aServer == nsnull)
return NS_ERROR_FAILURE;
// Now have the URI. Get the gradient
return NS_GetSVGGradient(aGrad, aServer, mContent, nsSVGPathGeometryFrameBase::GetPresContext()->PresShell());
nsresult rv = NS_OK;
if (!mFillGradient) {
nsIURI *aServer;
aServer = GetStyleSVG()->mFill.mPaint.mPaintServer;
if (aServer == nsnull)
return NS_ERROR_FAILURE;
// Now have the URI. Get the gradient
rv = NS_GetSVGGradient(getter_AddRefs(mFillGradient), aServer, mContent,
nsSVGPathGeometryFrameBase::GetPresContext()->PresShell());
NS_ADD_SVGVALUE_OBSERVER(mFillGradient);
}
*aGrad = mFillGradient;
return rv;
}
/* [noscript] boolean isClipChild; */
@ -712,9 +755,6 @@ nsSVGPathGeometryFrame::GetShapeRendering(PRUint16 *aShapeRendering)
nsresult
nsSVGPathGeometryFrame::Init()
{
// nsresult rv = nsSVGPathGeometryFrameBase::Init();
// if (NS_FAILED(rv)) return rv;
// all path geometry frames listen in on changes to their
// corresponding content element's transform attribute:
nsCOMPtr<nsIDOMSVGTransformable> transformable = do_QueryInterface(mContent);

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

@ -48,6 +48,7 @@
#include "nsISVGValueObserver.h"
#include "nsISVGOuterSVGFrame.h"
#include "nsSVGMarkerFrame.h"
#include "nsSVGGradient.h"
class nsPresContext;
class nsIDOMSVGMatrix;
@ -126,6 +127,8 @@ private:
nsCOMPtr<nsISVGRendererPathGeometry> mGeometry;
PRUint32 mUpdateFlags;
PRBool mPropagateTransform;
nsCOMPtr<nsISVGGradient> mFillGradient;
nsCOMPtr<nsISVGGradient> mStrokeGradient;
void GetMarkerFrames(nsSVGMarkerFrame **markerStart,
nsSVGMarkerFrame **markerMid,

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

@ -0,0 +1,108 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla SVG project.
*
* The Initial Developer of the Original Code is
* Scooter Morris.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Scooter Morris <scootermorris@comcast.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsWeakReference.h"
#include "nsIDOMSVGStopElement.h"
#include "nsStyleContext.h"
#include "nsContainerFrame.h"
// This is a very simple frame whose only purpose is to capture style change
// events and propogate them to the parent. Most of the heavy lifting is done
// within the nsSVGGradientFrame, which is the parent for this frame
typedef nsContainerFrame nsSVGStopFrameBase;
class nsSVGStopFrame : public nsSVGStopFrameBase
{
protected:
friend nsresult NS_NewSVGStopFrame(nsIPresShell* aPresShell,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame** aNewFrame);
private:
// nsIFrame interface:
NS_IMETHOD DidSetStyleContext(nsPresContext* aPresContext);
};
//----------------------------------------------------------------------
// Implementation
//----------------------------------------------------------------------
// nsIFrame methods:
NS_IMETHODIMP
nsSVGStopFrame::DidSetStyleContext(nsPresContext* aPresContext)
{
#ifdef DEBUG_scooter
printf("nsSVGStopFrame::DidSetStyleContext\n");
#endif
// Tell our parent
if (mParent)
mParent->DidSetStyleContext(aPresContext);
return NS_OK;
}
// -------------------------------------------------------------------------
// Public functions
// -------------------------------------------------------------------------
nsresult NS_NewSVGStopFrame(nsIPresShell* aPresShell,
nsIContent* aContent,
nsIFrame* aParentFrame,
nsIFrame** aNewFrame)
{
*aNewFrame = nsnull;
#ifdef DEBUG_scooter
printf("NS_NewSVGStopFrame\n");
#endif
nsCOMPtr<nsIDOMSVGStopElement> grad = do_QueryInterface(aContent);
NS_ASSERTION(grad, "NS_NewSVGStopFrame -- Content doesn't support nsIDOMSVGStopElement");
if (!grad)
return NS_ERROR_FAILURE;
nsSVGStopFrame* it = new (aPresShell) nsSVGStopFrame;
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
*aNewFrame = it;
return NS_OK;
}