2004-10-14 23:02:53 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2004-12-01 22:27:03 +00:00
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
2004-10-14 23:02:53 +00:00
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
|
|
*
|
2004-12-01 22:27:03 +00:00
|
|
|
* 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
|
2004-10-14 23:02:53 +00:00
|
|
|
* 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.
|
|
|
|
*
|
2004-12-01 22:27:03 +00:00
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
* Scooter Morris.
|
2004-10-14 23:02:53 +00:00
|
|
|
* Portions created by the Initial Developer are Copyright (C) 2004
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
2004-12-01 22:27:03 +00:00
|
|
|
* Scooter Morris <scootermorris@comcast.net>
|
2004-10-14 23:02:53 +00:00
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
2004-12-01 22:27:03 +00:00
|
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
2004-10-14 23:02:53 +00:00
|
|
|
* 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
|
2004-12-01 22:27:03 +00:00
|
|
|
* use your version of this file under the terms of the MPL, indicate your
|
2004-10-14 23:02:53 +00:00
|
|
|
* 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.
|
|
|
|
*
|
2004-12-01 22:27:03 +00:00
|
|
|
* ***** END LICENSE BLOCK ***** */
|
2004-10-14 23:02:53 +00:00
|
|
|
|
2005-10-03 00:59:03 +00:00
|
|
|
#include "nsSVGGenericContainerFrame.h"
|
2005-03-09 19:24:18 +00:00
|
|
|
#include "nsSVGGradient.h"
|
2004-10-14 23:02:53 +00:00
|
|
|
#include "nsIDOMDocument.h"
|
|
|
|
#include "nsIDocument.h"
|
|
|
|
#include "nsIDOMSVGStopElement.h"
|
|
|
|
#include "nsSVGAtoms.h"
|
|
|
|
#include "nsIDOMSVGLength.h"
|
2005-03-09 19:24:18 +00:00
|
|
|
#include "nsIDOMSVGAnimatedEnum.h"
|
|
|
|
#include "nsIDOMSVGAnimatedLength.h"
|
2004-10-14 23:02:53 +00:00
|
|
|
#include "nsIDOMSVGAnimatedNumber.h"
|
|
|
|
#include "nsIDOMSVGAnimatedString.h"
|
|
|
|
#include "nsIDOMSVGAnimTransformList.h"
|
|
|
|
#include "nsIDOMSVGTransformList.h"
|
|
|
|
#include "nsIDOMSVGNumber.h"
|
|
|
|
#include "nsIDOMSVGGradientElement.h"
|
|
|
|
#include "nsIDOMSVGURIReference.h"
|
|
|
|
#include "nsISVGValue.h"
|
2005-03-09 19:24:18 +00:00
|
|
|
#include "nsISVGValueUtils.h"
|
2004-10-14 23:02:53 +00:00
|
|
|
#include "nsStyleContext.h"
|
2005-03-09 19:24:18 +00:00
|
|
|
#include "nsSVGValue.h"
|
2004-10-14 23:02:53 +00:00
|
|
|
#include "nsNetUtil.h"
|
2005-01-17 05:00:01 +00:00
|
|
|
#include "nsINameSpaceManager.h"
|
2005-02-18 23:17:48 +00:00
|
|
|
#include "nsISVGChildFrame.h"
|
|
|
|
#include "nsIDOMSVGRect.h"
|
|
|
|
#include "nsSVGMatrix.h"
|
|
|
|
#include "nsISVGGeometrySource.h"
|
2005-03-09 19:24:18 +00:00
|
|
|
#include "nsISVGGradient.h"
|
|
|
|
#include "nsIURI.h"
|
|
|
|
#include "nsIContent.h"
|
|
|
|
#include "nsSVGNumber.h"
|
|
|
|
#include "nsIDOMSVGStopElement.h"
|
2005-08-04 20:32:02 +00:00
|
|
|
#include "nsSVGUtils.h"
|
2005-10-03 00:59:03 +00:00
|
|
|
#include "nsWeakReference.h"
|
|
|
|
#include "nsISVGValueObserver.h"
|
2006-01-26 16:39:39 +00:00
|
|
|
#include "nsContentUtils.h"
|
2005-03-09 19:24:18 +00:00
|
|
|
|
2005-10-03 00:59:03 +00:00
|
|
|
typedef nsSVGGenericContainerFrame nsSVGGradientFrameBase;
|
2004-10-14 23:02:53 +00:00
|
|
|
|
|
|
|
class nsSVGGradientFrame : public nsSVGGradientFrameBase,
|
2005-03-09 19:24:18 +00:00
|
|
|
public nsSVGValue,
|
|
|
|
public nsISVGValueObserver,
|
|
|
|
public nsSupportsWeakReference,
|
2004-10-14 23:02:53 +00:00
|
|
|
public nsISVGGradient
|
|
|
|
{
|
|
|
|
protected:
|
2005-11-11 02:36:29 +00:00
|
|
|
friend nsIFrame* NS_NewSVGLinearGradientFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIContent* aContent);
|
2004-10-14 23:02:53 +00:00
|
|
|
|
2005-11-11 02:36:29 +00:00
|
|
|
friend nsIFrame* NS_NewSVGRadialGradientFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIContent* aContent);
|
2004-10-14 23:02:53 +00:00
|
|
|
|
2005-11-11 02:36:29 +00:00
|
|
|
friend nsIFrame* NS_NewSVGStopFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrame);
|
2004-10-14 23:02:53 +00:00
|
|
|
|
|
|
|
friend nsresult NS_GetSVGGradientFrame(nsIFrame** result,
|
|
|
|
nsIURI* aURI,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIPresShell* aPresShell);
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
// nsISupports interface:
|
|
|
|
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
|
|
|
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
|
|
|
|
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
|
|
|
|
|
|
|
|
// nsISVGGradient interface:
|
|
|
|
NS_DECL_NSISVGGRADIENT
|
|
|
|
|
2005-03-09 19:24:18 +00:00
|
|
|
// nsISVGValue interface:
|
|
|
|
NS_IMETHOD SetValueString(const nsAString &aValue) { return NS_OK; }
|
|
|
|
NS_IMETHOD GetValueString(nsAString& aValue) { return NS_ERROR_NOT_IMPLEMENTED; }
|
|
|
|
|
|
|
|
// nsISVGValueObserver interface:
|
|
|
|
NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable,
|
|
|
|
nsISVGValue::modificationType aModType);
|
|
|
|
NS_IMETHOD DidModifySVGObservable(nsISVGValue* observable,
|
|
|
|
nsISVGValue::modificationType aModType);
|
|
|
|
|
|
|
|
// nsIFrame interface:
|
|
|
|
NS_IMETHOD DidSetStyleContext(nsPresContext* aPresContext);
|
2005-10-03 00:59:03 +00:00
|
|
|
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
|
|
|
|
nsIFrame* aOldFrame);
|
2005-03-09 19:24:18 +00:00
|
|
|
|
2005-04-01 19:56:08 +00:00
|
|
|
/**
|
|
|
|
* Get the "type" of the frame
|
|
|
|
*
|
|
|
|
* @see nsLayoutAtoms::svgGradientFrame
|
|
|
|
*/
|
|
|
|
virtual nsIAtom* GetType() const;
|
|
|
|
|
2005-10-03 00:59:03 +00:00
|
|
|
// nsISVGChildFrame interface:
|
|
|
|
// Override PaintSVG (our frames don't directly render)
|
|
|
|
NS_IMETHOD PaintSVG(nsISVGRendererCanvas* canvas,
|
|
|
|
const nsRect& dirtyRectTwips,
|
|
|
|
PRBool ignoreFilter) {return NS_OK;}
|
|
|
|
|
2005-04-01 19:56:08 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
|
|
|
{
|
|
|
|
return MakeFrameName(NS_LITERAL_STRING("SVGGradient"), aResult);
|
|
|
|
}
|
|
|
|
#endif // DEBUG
|
|
|
|
|
2005-03-09 19:24:18 +00:00
|
|
|
protected:
|
|
|
|
virtual ~nsSVGGradientFrame();
|
|
|
|
|
|
|
|
// Internal methods for handling referenced gradients
|
2005-01-17 05:00:01 +00:00
|
|
|
PRBool checkURITarget(nsIAtom *);
|
2004-10-14 23:02:53 +00:00
|
|
|
PRBool checkURITarget();
|
2005-03-09 19:24:18 +00:00
|
|
|
//
|
|
|
|
NS_IMETHOD PrivateGetGradientUnits(nsIDOMSVGAnimatedEnumeration * *aEnum);
|
|
|
|
NS_IMETHOD PrivateGetSpreadMethod(nsIDOMSVGAnimatedEnumeration * *aValue);
|
|
|
|
//
|
|
|
|
|
|
|
|
nsSVGGradientFrame *mNextGrad;
|
2006-01-18 23:50:40 +00:00
|
|
|
nsCOMPtr<nsIContent> mSourceContent;
|
2005-03-09 19:24:18 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
// Cached values
|
|
|
|
nsCOMPtr<nsIDOMSVGAnimatedEnumeration> mGradientUnits;
|
|
|
|
nsCOMPtr<nsIDOMSVGAnimatedEnumeration> mSpreadMethod;
|
|
|
|
|
|
|
|
nsAutoString mNextGradStr;
|
|
|
|
|
|
|
|
PRInt32 GetStopElement(PRInt32 aIndex,
|
|
|
|
nsIDOMSVGStopElement * *aStopElement,
|
|
|
|
nsIFrame * *aStopFrame);
|
2006-03-01 10:59:36 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
PRPackedBool mLoopFlag;
|
2005-03-09 19:24:18 +00:00
|
|
|
};
|
2004-10-14 23:02:53 +00:00
|
|
|
|
2005-03-09 19:24:18 +00:00
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
// Linear Gradients
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
|
|
|
typedef nsSVGGradientFrame nsSVGLinearGradientFrameBase;
|
|
|
|
|
|
|
|
class nsSVGLinearGradientFrame : public nsSVGLinearGradientFrameBase,
|
|
|
|
public nsISVGLinearGradient
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// nsISupports interface:
|
|
|
|
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
|
|
|
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
|
|
|
|
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
|
|
|
|
|
|
|
|
// nsISVGLinearGradient interface:
|
|
|
|
NS_DECL_NSISVGLINEARGRADIENT
|
2004-10-14 23:02:53 +00:00
|
|
|
|
2005-03-09 19:24:18 +00:00
|
|
|
// nsISVGGradient interface gets inherited from nsSVGGradientFrame
|
|
|
|
|
2005-04-01 19:56:08 +00:00
|
|
|
/**
|
|
|
|
* Get the "type" of the frame
|
|
|
|
*
|
|
|
|
* @see nsLayoutAtoms::svgLinearGradientFrame
|
|
|
|
*/
|
|
|
|
virtual nsIAtom* GetType() const;
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
|
|
|
{
|
|
|
|
return MakeFrameName(NS_LITERAL_STRING("SVGLinearGradient"), aResult);
|
|
|
|
}
|
|
|
|
#endif // DEBUG
|
|
|
|
|
|
|
|
|
2005-03-09 19:24:18 +00:00
|
|
|
protected:
|
|
|
|
virtual ~nsSVGLinearGradientFrame();
|
|
|
|
|
|
|
|
NS_IMETHOD PrivateGetX1(nsIDOMSVGLength * *aX1);
|
|
|
|
NS_IMETHOD PrivateGetX2(nsIDOMSVGLength * *aX2);
|
|
|
|
NS_IMETHOD PrivateGetY1(nsIDOMSVGLength * *aY1);
|
|
|
|
NS_IMETHOD PrivateGetY2(nsIDOMSVGLength * *aY2);
|
|
|
|
|
|
|
|
private:
|
|
|
|
nsCOMPtr<nsIDOMSVGLength> mX1;
|
|
|
|
nsCOMPtr<nsIDOMSVGLength> mX2;
|
|
|
|
nsCOMPtr<nsIDOMSVGLength> mY1;
|
|
|
|
nsCOMPtr<nsIDOMSVGLength> mY2;
|
2004-10-14 23:02:53 +00:00
|
|
|
};
|
|
|
|
|
2005-03-09 19:24:18 +00:00
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
// Radial Gradients
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
|
|
|
typedef nsSVGGradientFrame nsSVGRadialGradientFrameBase;
|
|
|
|
|
|
|
|
class nsSVGRadialGradientFrame : public nsSVGRadialGradientFrameBase,
|
|
|
|
public nsISVGRadialGradient
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// nsISupports interface:
|
|
|
|
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
|
|
|
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
|
|
|
|
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
|
|
|
|
|
|
|
|
// nsISVGRadialGradient interface:
|
|
|
|
NS_DECL_NSISVGRADIALGRADIENT
|
|
|
|
|
|
|
|
// nsISVGGradient interface gets inherited from nsSVGGradientFrame
|
|
|
|
|
2005-04-01 19:56:08 +00:00
|
|
|
/**
|
|
|
|
* Get the "type" of the frame
|
|
|
|
*
|
|
|
|
* @see nsLayoutAtoms::svgLinearGradientFrame
|
|
|
|
*/
|
|
|
|
virtual nsIAtom* GetType() const;
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
|
|
|
{
|
|
|
|
return MakeFrameName(NS_LITERAL_STRING("SVGRadialGradient"), aResult);
|
|
|
|
}
|
|
|
|
#endif // DEBUG
|
|
|
|
|
2005-03-09 19:24:18 +00:00
|
|
|
protected:
|
|
|
|
virtual ~nsSVGRadialGradientFrame();
|
|
|
|
|
|
|
|
NS_IMETHOD PrivateGetCx(nsIDOMSVGLength * *aCx);
|
|
|
|
NS_IMETHOD PrivateGetCy(nsIDOMSVGLength * *aCy);
|
|
|
|
NS_IMETHOD PrivateGetFx(nsIDOMSVGLength * *aFx);
|
|
|
|
NS_IMETHOD PrivateGetFy(nsIDOMSVGLength * *aFy);
|
|
|
|
NS_IMETHOD PrivateGetR(nsIDOMSVGLength * *aR);
|
|
|
|
|
|
|
|
private:
|
|
|
|
nsCOMPtr<nsIDOMSVGLength> mCx;
|
|
|
|
nsCOMPtr<nsIDOMSVGLength> mCy;
|
|
|
|
nsCOMPtr<nsIDOMSVGLength> mFx;
|
|
|
|
nsCOMPtr<nsIDOMSVGLength> mFy;
|
|
|
|
nsCOMPtr<nsIDOMSVGLength> mR;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2004-10-14 23:02:53 +00:00
|
|
|
//----------------------------------------------------------------------
|
2005-03-09 19:24:18 +00:00
|
|
|
// Implementation
|
|
|
|
|
|
|
|
nsSVGGradientFrame::~nsSVGGradientFrame()
|
|
|
|
{
|
|
|
|
WillModify();
|
|
|
|
// Notify the world that we're dying
|
|
|
|
DidModify(mod_die);
|
|
|
|
|
|
|
|
// Remove observers on gradient attributes
|
|
|
|
if (mGradientUnits) NS_REMOVE_SVGVALUE_OBSERVER(mGradientUnits);
|
|
|
|
if (mSpreadMethod) NS_REMOVE_SVGVALUE_OBSERVER(mSpreadMethod);
|
2005-09-08 00:25:24 +00:00
|
|
|
if (mNextGrad) mNextGrad->RemoveObserver(this);
|
2005-03-09 19:24:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// nsISupports methods:
|
2004-10-14 23:02:53 +00:00
|
|
|
|
|
|
|
NS_INTERFACE_MAP_BEGIN(nsSVGGradientFrame)
|
2005-03-09 19:24:18 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISVGValue)
|
2004-10-14 23:02:53 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISVGGradient)
|
2005-03-09 19:24:18 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver)
|
2006-01-18 16:31:42 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
2005-03-09 19:24:18 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISVGValue)
|
2004-10-14 23:02:53 +00:00
|
|
|
NS_INTERFACE_MAP_END_INHERITING(nsSVGGradientFrameBase)
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2005-03-09 19:24:18 +00:00
|
|
|
// nsISVGValueObserver methods:
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGGradientFrame::WillModifySVGObservable(nsISVGValue* observable,
|
|
|
|
modificationType aModType)
|
|
|
|
{
|
|
|
|
WillModify(aModType);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGGradientFrame::DidModifySVGObservable(nsISVGValue* observable,
|
|
|
|
nsISVGValue::modificationType aModType)
|
|
|
|
{
|
2005-09-08 00:25:24 +00:00
|
|
|
nsCOMPtr<nsISVGGradient> gradient = do_QueryInterface(observable);
|
|
|
|
// Is this a gradient we are observing that is going away?
|
|
|
|
if (mNextGrad && aModType == nsISVGValue::mod_die && gradient) {
|
|
|
|
// Yes, we need to handle this differently
|
|
|
|
nsISVGGradient *grad;
|
|
|
|
CallQueryInterface(mNextGrad, &grad);
|
|
|
|
if (grad == gradient) {
|
|
|
|
mNextGrad = nsnull;
|
|
|
|
}
|
|
|
|
}
|
2005-03-09 19:24:18 +00:00
|
|
|
// Something we depend on was modified -- pass it on!
|
|
|
|
DidModify(aModType);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// nsIFrame methods:
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGGradientFrame::DidSetStyleContext(nsPresContext* aPresContext)
|
|
|
|
{
|
|
|
|
WillModify(mod_other);
|
|
|
|
DidModify(mod_other);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-10-03 00:59:03 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGGradientFrame::RemoveFrame(nsIAtom* aListName,
|
|
|
|
nsIFrame* aOldFrame)
|
|
|
|
{
|
|
|
|
WillModify(mod_other);
|
|
|
|
PRBool result = mFrames.DestroyFrame(GetPresContext(), aOldFrame);
|
|
|
|
DidModify(mod_other);
|
|
|
|
return result ? NS_OK : NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2005-04-01 19:56:08 +00:00
|
|
|
nsIAtom*
|
|
|
|
nsSVGGradientFrame::GetType() const
|
|
|
|
{
|
|
|
|
return nsLayoutAtoms::svgGradientFrame;
|
|
|
|
}
|
|
|
|
|
2005-03-09 19:24:18 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// nsISVGGradient implementation
|
|
|
|
//----------------------------------------------------------------------
|
2004-10-14 23:02:53 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGGradientFrame::GetStopCount(PRUint32 *aStopCount)
|
|
|
|
{
|
2005-03-09 19:24:18 +00:00
|
|
|
nsresult rv = NS_OK;
|
2004-10-14 23:02:53 +00:00
|
|
|
nsIDOMSVGStopElement *stopElement = nsnull;
|
2005-03-09 19:24:18 +00:00
|
|
|
*aStopCount = GetStopElement(-1, &stopElement, nsnull);
|
|
|
|
if (*aStopCount == 0) {
|
2004-10-14 23:02:53 +00:00
|
|
|
// No stops? check for URI target
|
|
|
|
if (checkURITarget())
|
2005-03-09 19:24:18 +00:00
|
|
|
rv = mNextGrad->GetStopCount(aStopCount);
|
2005-09-08 00:25:24 +00:00
|
|
|
else
|
|
|
|
rv = NS_ERROR_FAILURE;
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2005-03-09 19:24:18 +00:00
|
|
|
return rv;
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGGradientFrame::GetStopOffset(PRInt32 aIndex, float *aOffset)
|
|
|
|
{
|
|
|
|
nsIDOMSVGStopElement *stopElement = nsnull;
|
2005-09-08 00:25:24 +00:00
|
|
|
nsresult rv = NS_OK;
|
2005-03-09 19:24:18 +00:00
|
|
|
PRInt32 stopCount = GetStopElement(aIndex, &stopElement, nsnull);
|
2005-09-08 00:25:24 +00:00
|
|
|
|
2005-09-16 22:07:25 +00:00
|
|
|
if (stopElement) {
|
2005-09-08 00:25:24 +00:00
|
|
|
nsCOMPtr<nsIDOMSVGAnimatedNumber> aNum;
|
|
|
|
stopElement->GetOffset(getter_AddRefs(aNum));
|
|
|
|
aNum->GetAnimVal(aOffset);
|
|
|
|
if (*aOffset < 0.0f)
|
|
|
|
*aOffset = 0.0f;
|
|
|
|
if (*aOffset > 1.0f)
|
|
|
|
*aOffset = 1.0f;
|
2005-09-16 22:07:25 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
2005-09-08 00:25:24 +00:00
|
|
|
}
|
2004-10-14 23:02:53 +00:00
|
|
|
|
2005-09-16 22:07:25 +00:00
|
|
|
// if our gradient doesn't have its own stops we must check if it references
|
|
|
|
// another gradient in which case we must attempt to "inherit" its stops
|
|
|
|
if (stopCount == 0 && checkURITarget()) {
|
|
|
|
rv = mNextGrad->GetStopOffset(aIndex, aOffset);
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
2005-09-16 22:07:25 +00:00
|
|
|
else {
|
|
|
|
*aOffset = 0.0f;
|
|
|
|
rv = NS_ERROR_FAILURE;
|
2005-09-08 00:25:24 +00:00
|
|
|
}
|
|
|
|
mLoopFlag = PR_FALSE;
|
|
|
|
return rv;
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGGradientFrame::GetStopColor(PRInt32 aIndex, nscolor *aStopColor)
|
|
|
|
{
|
|
|
|
nsIDOMSVGStopElement *stopElement = nsnull;
|
2004-10-14 23:02:53 +00:00
|
|
|
nsIFrame *stopFrame = nsnull;
|
2005-09-08 00:25:24 +00:00
|
|
|
nsresult rv = NS_OK;
|
2005-03-09 19:24:18 +00:00
|
|
|
PRInt32 stopCount = GetStopElement(aIndex, &stopElement, &stopFrame);
|
2005-09-16 22:07:25 +00:00
|
|
|
|
|
|
|
if (stopElement) {
|
2005-09-08 00:25:24 +00:00
|
|
|
if (!stopFrame) {
|
2005-09-16 22:07:25 +00:00
|
|
|
NS_ERROR("No stop frame found!");
|
2005-09-08 00:25:24 +00:00
|
|
|
*aStopColor = 0;
|
2005-09-16 22:07:25 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2005-09-08 00:25:24 +00:00
|
|
|
}
|
2005-09-16 22:07:25 +00:00
|
|
|
*aStopColor = stopFrame->GetStyleSVGReset()->mStopColor.mPaint.mColor;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if our gradient doesn't have its own stops we must check if it references
|
|
|
|
// another gradient in which case we must attempt to "inherit" its stops
|
|
|
|
if (stopCount == 0 && checkURITarget()) {
|
|
|
|
rv = mNextGrad->GetStopColor(aIndex, aStopColor);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aStopColor = 0;
|
|
|
|
rv = NS_ERROR_FAILURE;
|
2005-09-08 00:25:24 +00:00
|
|
|
}
|
|
|
|
mLoopFlag = PR_FALSE;
|
|
|
|
return rv;
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGGradientFrame::GetStopOpacity(PRInt32 aIndex, float *aStopOpacity)
|
|
|
|
{
|
|
|
|
nsIDOMSVGStopElement *stopElement = nsnull;
|
2004-10-14 23:02:53 +00:00
|
|
|
nsIFrame *stopFrame = nsnull;
|
2005-09-08 00:25:24 +00:00
|
|
|
nsresult rv = NS_OK;
|
2005-03-09 19:24:18 +00:00
|
|
|
PRInt32 stopCount = GetStopElement(aIndex, &stopElement, &stopFrame);
|
2005-09-16 22:07:25 +00:00
|
|
|
|
|
|
|
if (stopElement) {
|
2005-09-08 00:25:24 +00:00
|
|
|
if (!stopFrame) {
|
2005-09-16 22:07:25 +00:00
|
|
|
NS_ERROR("No stop frame found!");
|
2005-09-08 00:25:24 +00:00
|
|
|
*aStopOpacity = 1.0f;
|
2005-09-16 22:07:25 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2005-09-08 00:25:24 +00:00
|
|
|
}
|
2005-09-16 22:07:25 +00:00
|
|
|
*aStopOpacity = stopFrame->GetStyleSVGReset()->mStopOpacity;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if our gradient doesn't have its own stops we must check if it references
|
|
|
|
// another gradient in which case we must attempt to "inherit" its stops
|
|
|
|
if (stopCount == 0 && checkURITarget()) {
|
|
|
|
rv = mNextGrad->GetStopOpacity(aIndex, aStopOpacity);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aStopOpacity = 0;
|
|
|
|
rv = NS_ERROR_FAILURE;
|
2005-09-08 00:25:24 +00:00
|
|
|
}
|
|
|
|
mLoopFlag = PR_FALSE;
|
|
|
|
return rv;
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGGradientFrame::GetGradientType(PRUint32 *aType)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMSVGLinearGradientElement> aLe = do_QueryInterface(mContent);
|
|
|
|
if (aLe) {
|
|
|
|
*aType = nsISVGGradient::SVG_LINEAR_GRADIENT;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMSVGRadialGradientElement> aRe = do_QueryInterface(mContent);
|
|
|
|
if (aRe) {
|
|
|
|
*aType = nsISVGGradient::SVG_RADIAL_GRADIENT;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
*aType = nsISVGGradient::SVG_UNKNOWN_GRADIENT;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGGradientFrame::GetGradientUnits(PRUint16 *aUnits)
|
|
|
|
{
|
2005-03-09 19:24:18 +00:00
|
|
|
if (!mGradientUnits) {
|
|
|
|
PrivateGetGradientUnits(getter_AddRefs(mGradientUnits));
|
|
|
|
if (!mGradientUnits)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
NS_ADD_SVGVALUE_OBSERVER(mGradientUnits);
|
|
|
|
}
|
|
|
|
mGradientUnits->GetAnimVal(aUnits);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGGradientFrame::GetGradientTransform(nsIDOMSVGMatrix **aGradientTransform,
|
|
|
|
nsISVGGeometrySource *aSource)
|
2004-10-14 23:02:53 +00:00
|
|
|
{
|
2005-02-18 23:17:48 +00:00
|
|
|
*aGradientTransform = nsnull;
|
2004-10-14 23:02:53 +00:00
|
|
|
nsCOMPtr<nsIDOMSVGAnimatedTransformList> aTrans;
|
|
|
|
nsCOMPtr<nsIDOMSVGGradientElement> aGrad = do_QueryInterface(mContent);
|
|
|
|
NS_ASSERTION(aGrad, "Wrong content element (not gradient)");
|
|
|
|
if (aGrad == nsnull) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2005-02-18 23:17:48 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMSVGMatrix> bboxTransform;
|
|
|
|
PRUint16 bbox;
|
|
|
|
GetGradientUnits(&bbox);
|
|
|
|
if (bbox == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX) {
|
|
|
|
nsISVGChildFrame *frame = nsnull;
|
|
|
|
if (aSource)
|
|
|
|
CallQueryInterface(aSource, &frame);
|
|
|
|
nsCOMPtr<nsIDOMSVGRect> rect;
|
|
|
|
if (frame) {
|
|
|
|
frame->SetMatrixPropagation(PR_FALSE);
|
2005-09-06 22:30:40 +00:00
|
|
|
frame->NotifyCanvasTMChanged(PR_TRUE);
|
2005-02-18 23:17:48 +00:00
|
|
|
frame->GetBBox(getter_AddRefs(rect));
|
|
|
|
frame->SetMatrixPropagation(PR_TRUE);
|
2005-09-06 22:30:40 +00:00
|
|
|
frame->NotifyCanvasTMChanged(PR_TRUE);
|
2005-02-18 23:17:48 +00:00
|
|
|
}
|
|
|
|
if (rect) {
|
|
|
|
float x, y, width, height;
|
|
|
|
rect->GetX(&x);
|
|
|
|
rect->GetY(&y);
|
|
|
|
rect->GetWidth(&width);
|
|
|
|
rect->GetHeight(&height);
|
|
|
|
NS_NewSVGMatrix(getter_AddRefs(bboxTransform),
|
|
|
|
width, 0, 0, height, x, y);
|
|
|
|
}
|
2006-01-18 23:50:40 +00:00
|
|
|
} else {
|
|
|
|
nsIFrame *frame = nsnull;
|
|
|
|
CallQueryInterface(aSource, &frame);
|
2006-02-03 21:11:17 +00:00
|
|
|
|
|
|
|
// If this gradient is applied to text, our caller
|
|
|
|
// will be the glyph, which is not a container, so we
|
|
|
|
// need to get the parent
|
|
|
|
nsIAtom *callerType = frame->GetType();
|
|
|
|
if (callerType == nsLayoutAtoms::svgGlyphFrame)
|
|
|
|
mSourceContent = frame->GetContent()->GetParent();
|
|
|
|
else
|
|
|
|
mSourceContent = frame->GetContent();
|
|
|
|
NS_ASSERTION(mSourceContent, "Can't get content for gradient");
|
2005-02-18 23:17:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!bboxTransform)
|
|
|
|
NS_NewSVGMatrix(getter_AddRefs(bboxTransform));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMSVGMatrix> gradientTransform;
|
2004-10-14 23:02:53 +00:00
|
|
|
// See if we need to get the value from another gradient
|
2005-01-17 05:00:01 +00:00
|
|
|
if (!checkURITarget(nsSVGAtoms::gradientTransform)) {
|
2004-10-14 23:02:53 +00:00
|
|
|
// No, return the values
|
|
|
|
aGrad->GetGradientTransform(getter_AddRefs(aTrans));
|
|
|
|
nsCOMPtr<nsIDOMSVGTransformList> lTrans;
|
2005-02-02 20:31:51 +00:00
|
|
|
aTrans->GetAnimVal(getter_AddRefs(lTrans));
|
2005-02-18 23:17:48 +00:00
|
|
|
lTrans->GetConsolidationMatrix(getter_AddRefs(gradientTransform));
|
2004-10-14 23:02:53 +00:00
|
|
|
} else {
|
|
|
|
// Yes, get it from the target
|
2005-04-11 16:35:02 +00:00
|
|
|
mNextGrad->GetGradientTransform(getter_AddRefs(gradientTransform), nsnull);
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
2005-02-18 23:17:48 +00:00
|
|
|
|
|
|
|
bboxTransform->Multiply(gradientTransform, aGradientTransform);
|
2005-09-16 22:07:25 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-04-11 16:35:02 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGGradientFrame::GetSpreadMethod(PRUint16 *aSpreadMethod)
|
|
|
|
{
|
|
|
|
if (!mSpreadMethod) {
|
|
|
|
PrivateGetSpreadMethod(getter_AddRefs(mSpreadMethod));
|
|
|
|
if (!mSpreadMethod)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
NS_ADD_SVGVALUE_OBSERVER(mSpreadMethod);
|
|
|
|
}
|
|
|
|
mSpreadMethod->GetAnimVal(aSpreadMethod);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -------------------------------------------------------------
|
|
|
|
// Protected versions of the various "Get" routines. These need
|
|
|
|
// to be used to allow for the ability to delegate to referenced
|
|
|
|
// gradients
|
|
|
|
// -------------------------------------------------------------
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGGradientFrame::PrivateGetGradientUnits(nsIDOMSVGAnimatedEnumeration * *aEnum)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMSVGGradientElement> aGrad = do_QueryInterface(mContent);
|
|
|
|
NS_ASSERTION(aGrad, "Wrong content element (not gradient)");
|
|
|
|
if (aGrad == nsnull) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
// See if we need to get the value from another gradient
|
|
|
|
if (!checkURITarget(nsSVGAtoms::gradientUnits)) {
|
|
|
|
// No, return the values
|
|
|
|
aGrad->GetGradientUnits(aEnum);
|
|
|
|
} else {
|
|
|
|
// Yes, get it from the target
|
|
|
|
mNextGrad->PrivateGetGradientUnits(aEnum);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2005-04-11 16:35:02 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2004-10-14 23:02:53 +00:00
|
|
|
NS_IMETHODIMP
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGGradientFrame::PrivateGetSpreadMethod(nsIDOMSVGAnimatedEnumeration * *aEnum)
|
2004-10-14 23:02:53 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMSVGGradientElement> aGrad = do_QueryInterface(mContent);
|
|
|
|
NS_ASSERTION(aGrad, "Wrong content element (not gradient)");
|
|
|
|
if (aGrad == nsnull) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
// See if we need to get the value from another gradient
|
2005-01-17 05:00:01 +00:00
|
|
|
if (!checkURITarget(nsSVGAtoms::spreadMethod)) {
|
2004-10-14 23:02:53 +00:00
|
|
|
// No, return the values
|
2005-03-09 19:24:18 +00:00
|
|
|
aGrad->GetSpreadMethod(aEnum);
|
2004-10-14 23:02:53 +00:00
|
|
|
} else {
|
|
|
|
// Yes, get it from the target
|
2005-03-09 19:24:18 +00:00
|
|
|
mNextGrad->PrivateGetSpreadMethod(aEnum);
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
2005-09-16 22:07:25 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGGradientFrame::GetNextGradient(nsISVGGradient * *aNextGrad, PRUint32 aType) {
|
2005-09-08 00:25:24 +00:00
|
|
|
PRUint32 nextType;
|
2006-01-13 18:20:00 +00:00
|
|
|
if (!mNextGrad) {
|
|
|
|
*aNextGrad = nsnull;
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2005-09-08 00:25:24 +00:00
|
|
|
mNextGrad->GetGradientType(&nextType);
|
|
|
|
if (nextType == aType) {
|
|
|
|
*aNextGrad = mNextGrad;
|
|
|
|
return NS_OK;
|
2004-10-14 23:02:53 +00:00
|
|
|
} else {
|
2005-09-08 00:25:24 +00:00
|
|
|
return mNextGrad->GetNextGradient(aNextGrad, aType);
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Private (helper) methods
|
|
|
|
PRBool
|
2005-01-17 05:00:01 +00:00
|
|
|
nsSVGGradientFrame::checkURITarget(nsIAtom *attr) {
|
2004-10-14 23:02:53 +00:00
|
|
|
// Was the attribute explicitly set?
|
2005-01-17 05:00:01 +00:00
|
|
|
if (mContent->HasAttr(kNameSpaceID_None, attr)) {
|
2004-10-14 23:02:53 +00:00
|
|
|
// Yes, just return
|
2004-10-26 23:38:18 +00:00
|
|
|
return PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
|
|
|
return checkURITarget();
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsSVGGradientFrame::checkURITarget(void) {
|
2005-08-04 20:32:02 +00:00
|
|
|
nsIFrame *aNextGrad;
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_TRUE; // Set our loop detection flag
|
2004-10-14 23:02:53 +00:00
|
|
|
// Have we already figured out the next Gradient?
|
|
|
|
if (mNextGrad != nsnull) {
|
2004-10-26 23:38:18 +00:00
|
|
|
return PR_TRUE;
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Do we have URI?
|
|
|
|
if (mNextGradStr.Length() == 0) {
|
2004-10-26 23:38:18 +00:00
|
|
|
return PR_FALSE; // No, return the default
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
|
|
|
|
2005-10-18 20:33:35 +00:00
|
|
|
nsCOMPtr<nsIURI> targetURI;
|
|
|
|
nsCOMPtr<nsIURI> base = mContent->GetBaseURI();
|
|
|
|
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI),
|
|
|
|
mNextGradStr, mContent->GetCurrentDoc(), base);
|
|
|
|
|
2004-10-14 23:02:53 +00:00
|
|
|
// Note that we are using *our* frame tree for this call, otherwise we're going to have
|
|
|
|
// to get the PresShell in each call
|
2005-10-18 20:33:35 +00:00
|
|
|
if (nsSVGUtils::GetReferencedFrame(&aNextGrad, targetURI, mContent, GetPresContext()->PresShell()) == NS_OK) {
|
2005-08-04 20:32:02 +00:00
|
|
|
nsIAtom* frameType = aNextGrad->GetType();
|
|
|
|
if ((frameType != nsLayoutAtoms::svgLinearGradientFrame) &&
|
|
|
|
(frameType != nsLayoutAtoms::svgRadialGradientFrame))
|
|
|
|
return PR_FALSE;
|
2005-09-08 00:25:24 +00:00
|
|
|
|
2005-08-04 20:32:02 +00:00
|
|
|
mNextGrad = (nsSVGGradientFrame *)aNextGrad;
|
2005-09-08 00:25:24 +00:00
|
|
|
if (mNextGrad->mLoopFlag) {
|
|
|
|
// Yes, remove the reference and return an error
|
|
|
|
NS_WARNING("Gradient loop detected!");
|
|
|
|
CopyUTF8toUTF16("", mNextGradStr);
|
|
|
|
mNextGrad = nsnull;
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
2005-03-09 19:24:18 +00:00
|
|
|
// Add ourselves to the observer list
|
|
|
|
if (mNextGrad) {
|
|
|
|
// Can't use the NS_ADD macro here because of nsISupports ambiguity
|
|
|
|
mNextGrad->AddObserver(this);
|
|
|
|
}
|
2004-10-26 23:38:18 +00:00
|
|
|
return PR_TRUE;
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
2004-10-26 23:38:18 +00:00
|
|
|
return PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------
|
2005-03-09 19:24:18 +00:00
|
|
|
// Private helper method to simplify getting stop elements
|
|
|
|
// returns non-addrefed stop element
|
2004-10-14 23:02:53 +00:00
|
|
|
// -------------------------------------------------------------------------
|
2005-03-09 19:24:18 +00:00
|
|
|
PRInt32
|
|
|
|
nsSVGGradientFrame::GetStopElement(PRInt32 aIndex, nsIDOMSVGStopElement * *aStopElement,
|
|
|
|
nsIFrame * *aStopFrame)
|
2004-10-14 23:02:53 +00:00
|
|
|
{
|
2005-03-09 19:24:18 +00:00
|
|
|
PRInt32 stopCount = 0;
|
|
|
|
nsIFrame *stopFrame;
|
|
|
|
for (stopFrame = mFrames.FirstChild(); stopFrame;
|
|
|
|
stopFrame = stopFrame->GetNextSibling()) {
|
|
|
|
nsCOMPtr<nsIDOMSVGStopElement>stopElement = do_QueryInterface(stopFrame->GetContent());
|
|
|
|
if (stopElement) {
|
|
|
|
// Is this the one we're looking for?
|
2005-09-16 22:07:25 +00:00
|
|
|
if (stopCount++ == aIndex) {
|
2005-03-09 19:24:18 +00:00
|
|
|
*aStopElement = stopElement;
|
|
|
|
break; // Yes, break out of the loop
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (aStopFrame)
|
|
|
|
*aStopFrame = stopFrame;
|
|
|
|
return stopCount;
|
|
|
|
}
|
2004-10-14 23:02:53 +00:00
|
|
|
|
2005-03-09 19:24:18 +00:00
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
// Linear Gradients
|
|
|
|
// -------------------------------------------------------------------------
|
2004-10-14 23:02:53 +00:00
|
|
|
|
2005-04-01 19:56:08 +00:00
|
|
|
nsIAtom*
|
|
|
|
nsSVGLinearGradientFrame::GetType() const
|
|
|
|
{
|
|
|
|
return nsLayoutAtoms::svgLinearGradientFrame;
|
|
|
|
}
|
|
|
|
|
2004-10-14 23:02:53 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// nsISupports methods
|
|
|
|
|
|
|
|
NS_INTERFACE_MAP_BEGIN(nsSVGLinearGradientFrame)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISVGLinearGradient)
|
|
|
|
NS_INTERFACE_MAP_END_INHERITING(nsSVGLinearGradientFrameBase)
|
|
|
|
|
|
|
|
// Implementation
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGLinearGradientFrame::~nsSVGLinearGradientFrame()
|
|
|
|
{
|
|
|
|
if (mX1) NS_REMOVE_SVGVALUE_OBSERVER(mX1);
|
|
|
|
if (mY1) NS_REMOVE_SVGVALUE_OBSERVER(mY1);
|
|
|
|
if (mX2) NS_REMOVE_SVGVALUE_OBSERVER(mX2);
|
|
|
|
if (mY2) NS_REMOVE_SVGVALUE_OBSERVER(mY2);
|
|
|
|
}
|
|
|
|
|
2004-10-14 23:02:53 +00:00
|
|
|
nsresult
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGLinearGradientFrame::PrivateGetX1(nsIDOMSVGLength * *aX1)
|
2004-10-14 23:02:53 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMSVGLinearGradientElement> aLgrad = do_QueryInterface(mContent);
|
|
|
|
NS_ASSERTION(aLgrad, "Wrong content element (not linear gradient)");
|
|
|
|
if (aLgrad == nsnull) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
// See if we need to get the value from another gradient
|
2005-01-17 05:00:01 +00:00
|
|
|
if (checkURITarget(nsSVGAtoms::x1)) {
|
2004-10-14 23:02:53 +00:00
|
|
|
// Yes, get it from the target
|
|
|
|
nsISVGGradient *aNextGrad;
|
|
|
|
if (nsSVGGradientFrame::GetNextGradient(&aNextGrad, nsISVGGradient::SVG_LINEAR_GRADIENT) == NS_OK) {
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGLinearGradientFrame *aLNgrad = (nsSVGLinearGradientFrame *)aNextGrad;
|
|
|
|
aLNgrad->PrivateGetX1(aX1);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
// There are no gradients in the list with our type -- fall through
|
|
|
|
// and return our default value
|
|
|
|
}
|
|
|
|
// No, return the values
|
|
|
|
nsCOMPtr<nsIDOMSVGAnimatedLength> aLen;
|
|
|
|
aLgrad->GetX1(getter_AddRefs(aLen));
|
2005-03-09 19:24:18 +00:00
|
|
|
aLen->GetAnimVal(aX1);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGLinearGradientFrame::PrivateGetY1(nsIDOMSVGLength * *aY1)
|
2004-10-14 23:02:53 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMSVGLinearGradientElement> aLgrad = do_QueryInterface(mContent);
|
|
|
|
NS_ASSERTION(aLgrad, "Wrong content element (not linear gradient)");
|
|
|
|
if (aLgrad == nsnull) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
// See if we need to get the value from another gradient
|
2005-01-17 05:00:01 +00:00
|
|
|
if (checkURITarget(nsSVGAtoms::y1)) {
|
2004-10-14 23:02:53 +00:00
|
|
|
// Yes, get it from the target
|
|
|
|
nsISVGGradient *aNextGrad;
|
|
|
|
if (nsSVGGradientFrame::GetNextGradient(&aNextGrad, nsISVGGradient::SVG_LINEAR_GRADIENT) == NS_OK) {
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGLinearGradientFrame *aLNgrad = (nsSVGLinearGradientFrame *)aNextGrad;
|
|
|
|
aLNgrad->PrivateGetY1(aY1);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
// There are no gradients in the list with our type -- fall through
|
|
|
|
// and return our default value
|
|
|
|
}
|
|
|
|
// No, return the values
|
|
|
|
nsCOMPtr<nsIDOMSVGAnimatedLength> aLen;
|
|
|
|
aLgrad->GetY1(getter_AddRefs(aLen));
|
2005-03-09 19:24:18 +00:00
|
|
|
aLen->GetAnimVal(aY1);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGLinearGradientFrame::PrivateGetX2(nsIDOMSVGLength * *aX2)
|
2004-10-14 23:02:53 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMSVGLinearGradientElement> aLgrad = do_QueryInterface(mContent);
|
|
|
|
NS_ASSERTION(aLgrad, "Wrong content element (not linear gradient)");
|
|
|
|
if (aLgrad == nsnull) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
// See if we need to get the value from another gradient
|
2005-01-17 05:00:01 +00:00
|
|
|
if (checkURITarget(nsSVGAtoms::x2)) {
|
2004-10-14 23:02:53 +00:00
|
|
|
// Yes, get it from the target
|
|
|
|
nsISVGGradient *aNextGrad;
|
|
|
|
if (nsSVGGradientFrame::GetNextGradient(&aNextGrad, nsISVGGradient::SVG_LINEAR_GRADIENT) == NS_OK) {
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGLinearGradientFrame *aLNgrad = (nsSVGLinearGradientFrame *)aNextGrad;
|
|
|
|
aLNgrad->PrivateGetX2(aX2);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
// There are no gradients in the list with our type -- fall through
|
|
|
|
// and return our default value
|
|
|
|
}
|
|
|
|
// No, return the values
|
|
|
|
nsCOMPtr<nsIDOMSVGAnimatedLength> aLen;
|
|
|
|
aLgrad->GetX2(getter_AddRefs(aLen));
|
2005-03-09 19:24:18 +00:00
|
|
|
aLen->GetAnimVal(aX2);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGLinearGradientFrame::PrivateGetY2(nsIDOMSVGLength * *aY2)
|
2004-10-14 23:02:53 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMSVGLinearGradientElement> aLgrad = do_QueryInterface(mContent);
|
|
|
|
NS_ASSERTION(aLgrad, "Wrong content element (not linear gradient)");
|
|
|
|
if (aLgrad == nsnull) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
// See if we need to get the value from another gradient
|
2005-01-17 05:00:01 +00:00
|
|
|
if (checkURITarget(nsSVGAtoms::y2)) {
|
2004-10-14 23:02:53 +00:00
|
|
|
// Yes, get it from the target
|
|
|
|
nsISVGGradient *aNextGrad;
|
|
|
|
if (nsSVGGradientFrame::GetNextGradient(&aNextGrad, nsISVGGradient::SVG_LINEAR_GRADIENT) == NS_OK) {
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGLinearGradientFrame *aLNgrad = (nsSVGLinearGradientFrame *)aNextGrad;
|
|
|
|
aLNgrad->PrivateGetY2(aY2);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
// There are no gradients in the list with our type -- fall through
|
|
|
|
// and return our default value
|
|
|
|
}
|
|
|
|
// No, return the values
|
|
|
|
nsCOMPtr<nsIDOMSVGAnimatedLength> aLen;
|
|
|
|
aLgrad->GetY2(getter_AddRefs(aLen));
|
2005-03-09 19:24:18 +00:00
|
|
|
aLen->GetAnimVal(aY2);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2005-03-09 19:24:18 +00:00
|
|
|
// nsISVGLinearGradient
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGLinearGradientFrame::GetX1(float *aX1)
|
|
|
|
{
|
|
|
|
if (!mX1) {
|
|
|
|
PrivateGetX1(getter_AddRefs(mX1));
|
|
|
|
if (!mX1)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
NS_ADD_SVGVALUE_OBSERVER(mX1);
|
|
|
|
}
|
2006-01-18 23:50:40 +00:00
|
|
|
|
|
|
|
// Object bounding box units are handled by setting the appropriate
|
|
|
|
// transform in GetGradientTransfrom, but we need to handle user
|
|
|
|
// space units as part of the individual Get* routines. Fixes 323669.
|
|
|
|
|
|
|
|
PRUint16 bbox;
|
|
|
|
GetGradientUnits(&bbox);
|
|
|
|
if (bbox == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX) {
|
|
|
|
mX1->GetValue(aX1);
|
|
|
|
} else {
|
|
|
|
*aX1 = nsSVGUtils::UserSpace(mSourceContent, mX1, nsSVGUtils::X);
|
|
|
|
}
|
2005-03-09 19:24:18 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2004-10-14 23:02:53 +00:00
|
|
|
|
2005-03-09 19:24:18 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGLinearGradientFrame::GetY1(float *aY1)
|
|
|
|
{
|
|
|
|
if (!mY1) {
|
|
|
|
PrivateGetY1(getter_AddRefs(mY1));
|
|
|
|
if (!mY1)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
NS_ADD_SVGVALUE_OBSERVER(mY1);
|
|
|
|
}
|
2006-01-18 23:50:40 +00:00
|
|
|
PRUint16 bbox;
|
|
|
|
GetGradientUnits(&bbox);
|
|
|
|
if (bbox == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX) {
|
|
|
|
mY1->GetValue(aY1);
|
|
|
|
} else {
|
|
|
|
*aY1 = nsSVGUtils::UserSpace(mSourceContent, mY1, nsSVGUtils::Y);
|
|
|
|
}
|
2005-03-09 19:24:18 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2004-10-14 23:02:53 +00:00
|
|
|
|
2005-03-09 19:24:18 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGLinearGradientFrame::GetX2(float *aX2)
|
2004-10-14 23:02:53 +00:00
|
|
|
{
|
2005-03-09 19:24:18 +00:00
|
|
|
if (!mX2) {
|
|
|
|
PrivateGetX2(getter_AddRefs(mX2));
|
|
|
|
if (!mX2)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
NS_ADD_SVGVALUE_OBSERVER(mX2);
|
|
|
|
}
|
2006-01-18 23:50:40 +00:00
|
|
|
PRUint16 bbox;
|
|
|
|
GetGradientUnits(&bbox);
|
|
|
|
if (bbox == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX) {
|
|
|
|
mX2->GetValue(aX2);
|
|
|
|
} else {
|
|
|
|
*aX2 = nsSVGUtils::UserSpace(mSourceContent, mX2, nsSVGUtils::X);
|
|
|
|
}
|
2005-03-09 19:24:18 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2004-10-14 23:02:53 +00:00
|
|
|
|
2005-03-09 19:24:18 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGLinearGradientFrame::GetY2(float *aY2)
|
|
|
|
{
|
|
|
|
if (!mY2) {
|
|
|
|
PrivateGetY2(getter_AddRefs(mY2));
|
|
|
|
if (!mY2)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
NS_ADD_SVGVALUE_OBSERVER(mY2);
|
|
|
|
}
|
2006-01-18 23:50:40 +00:00
|
|
|
PRUint16 bbox;
|
|
|
|
GetGradientUnits(&bbox);
|
|
|
|
if (bbox == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX) {
|
|
|
|
mY2->GetValue(aY2);
|
|
|
|
} else {
|
|
|
|
*aY2 = nsSVGUtils::UserSpace(mSourceContent, mY2, nsSVGUtils::Y);
|
|
|
|
}
|
2005-03-09 19:24:18 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2004-10-14 23:02:53 +00:00
|
|
|
|
2005-03-09 19:24:18 +00:00
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
// Radial Gradients
|
|
|
|
// -------------------------------------------------------------------------
|
2004-10-14 23:02:53 +00:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// nsISupports methods
|
|
|
|
|
|
|
|
NS_INTERFACE_MAP_BEGIN(nsSVGRadialGradientFrame)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISVGRadialGradient)
|
|
|
|
NS_INTERFACE_MAP_END_INHERITING(nsSVGRadialGradientFrameBase)
|
|
|
|
|
2005-04-01 19:56:08 +00:00
|
|
|
nsIAtom*
|
|
|
|
nsSVGRadialGradientFrame::GetType() const
|
|
|
|
{
|
|
|
|
return nsLayoutAtoms::svgRadialGradientFrame;
|
|
|
|
}
|
|
|
|
|
2004-10-14 23:02:53 +00:00
|
|
|
// Implementation
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGRadialGradientFrame::~nsSVGRadialGradientFrame()
|
|
|
|
{
|
|
|
|
if (mCx) NS_REMOVE_SVGVALUE_OBSERVER(mCx);
|
|
|
|
if (mCy) NS_REMOVE_SVGVALUE_OBSERVER(mCy);
|
|
|
|
if (mFx) NS_REMOVE_SVGVALUE_OBSERVER(mFx);
|
|
|
|
if (mFy) NS_REMOVE_SVGVALUE_OBSERVER(mFy);
|
|
|
|
if (mR) NS_REMOVE_SVGVALUE_OBSERVER(mR);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-10-14 23:02:53 +00:00
|
|
|
nsresult
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGRadialGradientFrame::PrivateGetCx(nsIDOMSVGLength * *aCx)
|
2004-10-14 23:02:53 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMSVGRadialGradientElement> aRgrad = do_QueryInterface(mContent);
|
|
|
|
NS_ASSERTION(aRgrad, "Wrong content element (not radial gradient)");
|
|
|
|
if (aRgrad == nsnull) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
// See if we need to get the value from another gradient
|
2005-01-17 05:00:01 +00:00
|
|
|
if (checkURITarget(nsSVGAtoms::cx)) {
|
2004-10-14 23:02:53 +00:00
|
|
|
// Yes, get it from the target
|
|
|
|
nsISVGGradient *aNextGrad;
|
|
|
|
if (nsSVGGradientFrame::GetNextGradient(&aNextGrad, nsISVGGradient::SVG_RADIAL_GRADIENT) == NS_OK) {
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGRadialGradientFrame *aRNgrad = (nsSVGRadialGradientFrame *)aNextGrad;
|
|
|
|
aRNgrad->PrivateGetCx(aCx);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
// There are no gradients in the list with our type -- fall through
|
|
|
|
// and return our default value
|
|
|
|
}
|
|
|
|
// No, return the values
|
|
|
|
nsCOMPtr<nsIDOMSVGAnimatedLength> aLen;
|
|
|
|
aRgrad->GetCx(getter_AddRefs(aLen));
|
2005-03-09 19:24:18 +00:00
|
|
|
aLen->GetAnimVal(aCx);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGRadialGradientFrame::PrivateGetCy(nsIDOMSVGLength * *aCy)
|
2004-10-14 23:02:53 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMSVGRadialGradientElement> aRgrad = do_QueryInterface(mContent);
|
|
|
|
NS_ASSERTION(aRgrad, "Wrong content element (not radial gradient)");
|
|
|
|
if (aRgrad == nsnull) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
// See if we need to get the value from another gradient
|
2005-01-17 05:00:01 +00:00
|
|
|
if (checkURITarget(nsSVGAtoms::cy)) {
|
2004-10-14 23:02:53 +00:00
|
|
|
// Yes, get it from the target
|
|
|
|
nsISVGGradient *aNextGrad;
|
|
|
|
if (nsSVGGradientFrame::GetNextGradient(&aNextGrad, nsISVGGradient::SVG_RADIAL_GRADIENT) == NS_OK) {
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGRadialGradientFrame *aRNgrad = (nsSVGRadialGradientFrame *)aNextGrad;
|
|
|
|
aRNgrad->PrivateGetCy(aCy);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
// There are no gradients in the list with our type -- fall through
|
|
|
|
// and return our default value
|
|
|
|
}
|
|
|
|
// No, return the values
|
|
|
|
nsCOMPtr<nsIDOMSVGAnimatedLength> aLen;
|
|
|
|
aRgrad->GetCy(getter_AddRefs(aLen));
|
2005-03-09 19:24:18 +00:00
|
|
|
aLen->GetAnimVal(aCy);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGRadialGradientFrame::PrivateGetR(nsIDOMSVGLength * *aR)
|
2004-10-14 23:02:53 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMSVGRadialGradientElement> aRgrad = do_QueryInterface(mContent);
|
|
|
|
NS_ASSERTION(aRgrad, "Wrong content element (not radial gradient)");
|
|
|
|
if (aRgrad == nsnull) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
// See if we need to get the value from another gradient
|
2005-01-17 05:00:01 +00:00
|
|
|
if (checkURITarget(nsSVGAtoms::r)) {
|
2004-10-14 23:02:53 +00:00
|
|
|
// Yes, get it from the target
|
|
|
|
nsISVGGradient *aNextGrad;
|
|
|
|
if (nsSVGGradientFrame::GetNextGradient(&aNextGrad, nsISVGGradient::SVG_RADIAL_GRADIENT) == NS_OK) {
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGRadialGradientFrame *aRNgrad = (nsSVGRadialGradientFrame *)aNextGrad;
|
|
|
|
aRNgrad->PrivateGetR(aR);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
// There are no gradients in the list with our type -- fall through
|
|
|
|
// and return our default value
|
|
|
|
}
|
|
|
|
// No, return the values
|
|
|
|
nsCOMPtr<nsIDOMSVGAnimatedLength> aLen;
|
|
|
|
aRgrad->GetR(getter_AddRefs(aLen));
|
2005-03-09 19:24:18 +00:00
|
|
|
aLen->GetAnimVal(aR);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGRadialGradientFrame::PrivateGetFx(nsIDOMSVGLength * *aFx)
|
2004-10-14 23:02:53 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMSVGRadialGradientElement> aRgrad = do_QueryInterface(mContent);
|
|
|
|
NS_ASSERTION(aRgrad, "Wrong content element (not radial gradient)");
|
|
|
|
if (aRgrad == nsnull) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
// See if we need to get the value from another gradient
|
2005-01-17 05:00:01 +00:00
|
|
|
if (checkURITarget(nsSVGAtoms::fx)) {
|
2004-10-14 23:02:53 +00:00
|
|
|
// Yes, get it from the target
|
|
|
|
nsISVGGradient *aNextGrad;
|
|
|
|
if (nsSVGGradientFrame::GetNextGradient(&aNextGrad, nsISVGGradient::SVG_RADIAL_GRADIENT) == NS_OK) {
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGRadialGradientFrame *aRNgrad = (nsSVGRadialGradientFrame *)aNextGrad;
|
|
|
|
aRNgrad->PrivateGetFx(aFx);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-06-14 20:28:53 +00:00
|
|
|
// There are no gradients in the list with our type -- fall through
|
|
|
|
// and return our default value
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
2005-06-14 20:28:53 +00:00
|
|
|
// See if the value was explicitly set -- the spec
|
|
|
|
// states that if there is no explicit fx value, we return the cx value
|
|
|
|
// see http://www.w3.org/TR/SVG11/pservers.html#RadialGradients
|
|
|
|
if (!mContent->HasAttr(kNameSpaceID_None, nsSVGAtoms::fx))
|
|
|
|
return PrivateGetCx(aFx);
|
2004-10-14 23:02:53 +00:00
|
|
|
// No, return the values
|
|
|
|
nsCOMPtr<nsIDOMSVGAnimatedLength> aLen;
|
2004-10-26 23:38:18 +00:00
|
|
|
aRgrad->GetFx(getter_AddRefs(aLen));
|
2005-03-09 19:24:18 +00:00
|
|
|
aLen->GetAnimVal(aFx);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGRadialGradientFrame::PrivateGetFy(nsIDOMSVGLength * *aFy)
|
2004-10-14 23:02:53 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMSVGRadialGradientElement> aRgrad = do_QueryInterface(mContent);
|
|
|
|
NS_ASSERTION(aRgrad, "Wrong content element (not radial gradient)");
|
|
|
|
if (aRgrad == nsnull) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
// See if we need to get the value from another gradient
|
2005-01-17 05:00:01 +00:00
|
|
|
if (checkURITarget(nsSVGAtoms::fy)) {
|
2004-10-14 23:02:53 +00:00
|
|
|
// Yes, get it from the target
|
|
|
|
nsISVGGradient *aNextGrad;
|
|
|
|
if (nsSVGGradientFrame::GetNextGradient(&aNextGrad, nsISVGGradient::SVG_RADIAL_GRADIENT) == NS_OK) {
|
2005-03-09 19:24:18 +00:00
|
|
|
nsSVGRadialGradientFrame *aRNgrad = (nsSVGRadialGradientFrame *)aNextGrad;
|
|
|
|
aRNgrad->PrivateGetFy(aFy);
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2005-06-14 20:28:53 +00:00
|
|
|
// There are no gradients in the list with our type -- fall through
|
|
|
|
// and return our default value
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
2005-06-14 20:28:53 +00:00
|
|
|
// See if the value was explicitly set -- the spec
|
|
|
|
// states that if there is no explicit fy value, we return the cy value
|
|
|
|
// see http://www.w3.org/TR/SVG11/pservers.html#RadialGradients
|
2005-09-08 00:25:24 +00:00
|
|
|
mLoopFlag = PR_FALSE;
|
2005-06-14 20:28:53 +00:00
|
|
|
if (!mContent->HasAttr(kNameSpaceID_None, nsSVGAtoms::fy))
|
|
|
|
return PrivateGetCy(aFy);
|
2004-10-14 23:02:53 +00:00
|
|
|
// No, return the values
|
|
|
|
nsCOMPtr<nsIDOMSVGAnimatedLength> aLen;
|
|
|
|
aRgrad->GetFy(getter_AddRefs(aLen));
|
2005-03-09 19:24:18 +00:00
|
|
|
aLen->GetAnimVal(aFy);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// nsISVGRadialGradient
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGRadialGradientFrame::GetFx(float *aFx)
|
|
|
|
{
|
|
|
|
if (!mFx) {
|
|
|
|
PrivateGetFx(getter_AddRefs(mFx));
|
|
|
|
if (!mFx)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
NS_ADD_SVGVALUE_OBSERVER(mFx);
|
|
|
|
}
|
2006-01-18 23:50:40 +00:00
|
|
|
PRUint16 bbox;
|
|
|
|
GetGradientUnits(&bbox);
|
|
|
|
if (bbox == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX) {
|
|
|
|
mFx->GetValue(aFx);
|
|
|
|
} else {
|
|
|
|
*aFx = nsSVGUtils::UserSpace(mSourceContent, mFx, nsSVGUtils::X);
|
|
|
|
}
|
2005-03-09 19:24:18 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGRadialGradientFrame::GetFy(float *aFy)
|
|
|
|
{
|
|
|
|
if (!mFy) {
|
|
|
|
PrivateGetFy(getter_AddRefs(mFy));
|
|
|
|
if (!mFy)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
NS_ADD_SVGVALUE_OBSERVER(mFy);
|
|
|
|
}
|
2006-01-18 23:50:40 +00:00
|
|
|
PRUint16 bbox;
|
|
|
|
GetGradientUnits(&bbox);
|
|
|
|
if (bbox == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX) {
|
|
|
|
mFy->GetValue(aFy);
|
|
|
|
} else {
|
|
|
|
*aFy = nsSVGUtils::UserSpace(mSourceContent, mFy, nsSVGUtils::Y);
|
|
|
|
}
|
2005-03-09 19:24:18 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGRadialGradientFrame::GetCx(float *aCx)
|
|
|
|
{
|
|
|
|
if (!mCx) {
|
|
|
|
PrivateGetCx(getter_AddRefs(mCx));
|
|
|
|
if (!mCx)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
NS_ADD_SVGVALUE_OBSERVER(mCx);
|
|
|
|
}
|
2006-01-18 23:50:40 +00:00
|
|
|
PRUint16 bbox;
|
|
|
|
GetGradientUnits(&bbox);
|
|
|
|
if (bbox == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX) {
|
|
|
|
mCx->GetValue(aCx);
|
|
|
|
} else {
|
|
|
|
*aCx = nsSVGUtils::UserSpace(mSourceContent, mCx, nsSVGUtils::X);
|
|
|
|
}
|
2005-03-09 19:24:18 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGRadialGradientFrame::GetCy(float *aCy)
|
|
|
|
{
|
|
|
|
if (!mCy) {
|
|
|
|
PrivateGetCy(getter_AddRefs(mCy));
|
|
|
|
if (!mCy)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
NS_ADD_SVGVALUE_OBSERVER(mCy);
|
|
|
|
}
|
2006-01-18 23:50:40 +00:00
|
|
|
PRUint16 bbox;
|
|
|
|
GetGradientUnits(&bbox);
|
|
|
|
if (bbox == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX) {
|
|
|
|
mCy->GetValue(aCy);
|
|
|
|
} else {
|
|
|
|
*aCy = nsSVGUtils::UserSpace(mSourceContent, mCy, nsSVGUtils::Y);
|
|
|
|
}
|
2005-03-09 19:24:18 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSVGRadialGradientFrame::GetR(float *aR)
|
|
|
|
{
|
|
|
|
if (!mR) {
|
|
|
|
PrivateGetR(getter_AddRefs(mR));
|
|
|
|
if (!mR)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
NS_ADD_SVGVALUE_OBSERVER(mR);
|
|
|
|
}
|
2006-01-18 23:50:40 +00:00
|
|
|
PRUint16 bbox;
|
|
|
|
GetGradientUnits(&bbox);
|
|
|
|
if (bbox == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX) {
|
|
|
|
mR->GetValue(aR);
|
|
|
|
} else {
|
|
|
|
*aR = nsSVGUtils::UserSpace(mSourceContent, mR, nsSVGUtils::XY);
|
|
|
|
}
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
// Public functions
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
2005-11-11 02:36:29 +00:00
|
|
|
nsIFrame* NS_NewSVGLinearGradientFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIContent* aContent)
|
2004-10-14 23:02:53 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMSVGLinearGradientElement> grad = do_QueryInterface(aContent);
|
|
|
|
NS_ASSERTION(grad, "NS_NewSVGLinearGradientFrame -- Content doesn't support nsIDOMSVGLinearGradient");
|
|
|
|
if (!grad)
|
2005-11-11 02:36:29 +00:00
|
|
|
return nsnull;
|
2004-10-14 23:02:53 +00:00
|
|
|
|
|
|
|
nsSVGLinearGradientFrame* it = new (aPresShell) nsSVGLinearGradientFrame;
|
|
|
|
if (nsnull == it)
|
2005-11-11 02:36:29 +00:00
|
|
|
return nsnull;
|
2004-10-14 23:02:53 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMSVGURIReference> aRef = do_QueryInterface(aContent);
|
|
|
|
NS_ASSERTION(aRef, "NS_NewSVGLinearGradientFrame -- Content doesn't support nsIDOMSVGURIReference");
|
|
|
|
if (!aRef) {
|
|
|
|
it->mNextGrad = nsnull;
|
|
|
|
} else {
|
|
|
|
// Get the hRef
|
|
|
|
nsCOMPtr<nsIDOMSVGAnimatedString> aHref;
|
|
|
|
aRef->GetHref(getter_AddRefs(aHref));
|
2005-03-09 19:24:18 +00:00
|
|
|
|
2004-10-14 23:02:53 +00:00
|
|
|
nsAutoString aStr;
|
2005-02-02 20:31:51 +00:00
|
|
|
aHref->GetAnimVal(aStr);
|
2004-10-14 23:02:53 +00:00
|
|
|
it->mNextGradStr = aStr;
|
|
|
|
it->mNextGrad = nsnull;
|
|
|
|
}
|
|
|
|
|
2005-09-08 00:25:24 +00:00
|
|
|
it->mLoopFlag = PR_FALSE;
|
2005-11-11 02:36:29 +00:00
|
|
|
return it;
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
|
|
|
|
2005-11-11 02:36:29 +00:00
|
|
|
nsIFrame*
|
|
|
|
NS_NewSVGRadialGradientFrame(nsIPresShell* aPresShell, nsIContent* aContent)
|
2004-10-14 23:02:53 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMSVGRadialGradientElement> grad = do_QueryInterface(aContent);
|
|
|
|
NS_ASSERTION(grad, "NS_NewSVGRadialGradientFrame -- Content doesn't support nsIDOMSVGRadialGradient");
|
|
|
|
if (!grad)
|
2005-11-11 02:36:29 +00:00
|
|
|
return nsnull;
|
2004-10-14 23:02:53 +00:00
|
|
|
|
|
|
|
nsSVGRadialGradientFrame* it = new (aPresShell) nsSVGRadialGradientFrame;
|
|
|
|
if (nsnull == it)
|
2005-11-11 02:36:29 +00:00
|
|
|
return nsnull;
|
2004-10-14 23:02:53 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMSVGURIReference> aRef = do_QueryInterface(aContent);
|
|
|
|
NS_ASSERTION(aRef, "NS_NewSVGRadialGradientFrame -- Content doesn't support nsIDOMSVGURIReference");
|
|
|
|
if (!aRef) {
|
|
|
|
it->mNextGrad = nsnull;
|
|
|
|
} else {
|
|
|
|
// Get the hRef
|
|
|
|
nsCOMPtr<nsIDOMSVGAnimatedString> aHref;
|
|
|
|
aRef->GetHref(getter_AddRefs(aHref));
|
2005-03-09 19:24:18 +00:00
|
|
|
|
2004-10-14 23:02:53 +00:00
|
|
|
nsAutoString aStr;
|
2005-02-02 20:31:51 +00:00
|
|
|
aHref->GetAnimVal(aStr);
|
2004-10-14 23:02:53 +00:00
|
|
|
it->mNextGradStr = aStr;
|
|
|
|
it->mNextGrad = nsnull;
|
|
|
|
}
|
|
|
|
|
2005-09-08 00:25:24 +00:00
|
|
|
it->mLoopFlag = PR_FALSE;
|
2005-11-11 02:36:29 +00:00
|
|
|
return it;
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Public function to locate the SVGGradientFrame structure pointed to by a URI
|
|
|
|
// and return a nsISVGGradient
|
2005-03-09 19:24:18 +00:00
|
|
|
nsresult NS_GetSVGGradient(nsISVGGradient **aGrad, nsIURI *aURI, nsIContent *aContent,
|
2004-10-14 23:02:53 +00:00
|
|
|
nsIPresShell *aPresShell)
|
|
|
|
{
|
2005-03-09 19:24:18 +00:00
|
|
|
*aGrad = nsnull;
|
2004-10-14 23:02:53 +00:00
|
|
|
|
2005-10-18 20:33:35 +00:00
|
|
|
#ifdef DEBUG_scooter
|
2004-10-14 23:02:53 +00:00
|
|
|
nsCAutoString uriSpec;
|
|
|
|
aURI->GetSpec(uriSpec);
|
2005-08-04 20:32:02 +00:00
|
|
|
printf("NS_GetSVGGradient: uri = %s\n",uriSpec.get());
|
|
|
|
#endif
|
|
|
|
nsIFrame *result;
|
2005-10-18 20:33:35 +00:00
|
|
|
if (!NS_SUCCEEDED(nsSVGUtils::GetReferencedFrame(&result, aURI, aContent, aPresShell))) {
|
2004-10-14 23:02:53 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2005-08-04 20:32:02 +00:00
|
|
|
return result->QueryInterface(NS_GET_IID(nsISVGGradient), (void **)aGrad);
|
2004-10-14 23:02:53 +00:00
|
|
|
}
|