mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-24 11:27:49 +00:00
Bug 336803 - Remove nsISVGGradient. r=jwatt, sr=roc
This commit is contained in:
parent
314fa97a97
commit
ebdff7da40
@ -37,10 +37,9 @@
|
||||
#include "nsPresContext.h"
|
||||
#include "nsSVGGradient.h"
|
||||
#include "nsSVGPattern.h"
|
||||
#include "nsISVGValueUtils.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsSVGGeometryFrame.h"
|
||||
#include "nsISVGGradient.h"
|
||||
#include "nsSVGGradientFrame.h"
|
||||
#include "nsSVGPatternFrame.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -63,10 +62,10 @@ nsSVGGeometryFrame::nsSVGGeometryFrame(nsStyleContext* aContext)
|
||||
nsSVGGeometryFrame::~nsSVGGeometryFrame()
|
||||
{
|
||||
if (mFillGradient) {
|
||||
NS_REMOVE_SVGVALUE_OBSERVER(mFillGradient);
|
||||
mFillGradient->RemoveObserver(this);
|
||||
}
|
||||
if (mStrokeGradient) {
|
||||
NS_REMOVE_SVGVALUE_OBSERVER(mStrokeGradient);
|
||||
mStrokeGradient->RemoveObserver(this);
|
||||
}
|
||||
if (mFillPattern) {
|
||||
mFillPattern->RemoveObserver(this);
|
||||
@ -82,11 +81,11 @@ nsSVGGeometryFrame::DidSetStyleContext()
|
||||
// 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->RemoveObserver(this);
|
||||
mFillGradient = nsnull;
|
||||
}
|
||||
if (mStrokeGradient) {
|
||||
NS_REMOVE_SVGVALUE_OBSERVER(mStrokeGradient);
|
||||
mStrokeGradient->RemoveObserver(this);
|
||||
mStrokeGradient = nsnull;
|
||||
}
|
||||
if (mFillPattern) {
|
||||
@ -112,45 +111,32 @@ NS_IMETHODIMP
|
||||
nsSVGGeometryFrame::DidModifySVGObservable(nsISVGValue* observable,
|
||||
nsISVGValue::modificationType aModType)
|
||||
{
|
||||
nsISVGGradient *gradient;
|
||||
CallQueryInterface(observable, &gradient);
|
||||
|
||||
if (gradient) {
|
||||
// Yes, we need to handle this differently
|
||||
if (mFillGradient == gradient) {
|
||||
if (aModType == nsISVGValue::mod_die) {
|
||||
mFillGradient = nsnull;
|
||||
}
|
||||
UpdateGraphic(nsSVGGeometryFrame::UPDATEMASK_FILL_PAINT);
|
||||
} else {
|
||||
// No real harm in assuming a stroke gradient at this point
|
||||
if (aModType == nsISVGValue::mod_die) {
|
||||
mStrokeGradient = nsnull;
|
||||
}
|
||||
UpdateGraphic(nsSVGGeometryFrame::UPDATEMASK_STROKE_PAINT);
|
||||
}
|
||||
nsIFrame *frame;
|
||||
CallQueryInterface(observable, &frame);
|
||||
|
||||
if (!frame)
|
||||
return NS_OK;
|
||||
|
||||
if (frame == mFillGradient) {
|
||||
if (aModType == nsISVGValue::mod_die)
|
||||
mFillGradient = nsnull;
|
||||
UpdateGraphic(nsSVGGeometryFrame::UPDATEMASK_FILL_PAINT);
|
||||
}
|
||||
else if (frame == mFillPattern) {
|
||||
if (aModType == nsISVGValue::mod_die)
|
||||
mFillPattern = nsnull;
|
||||
UpdateGraphic(nsSVGGeometryFrame::UPDATEMASK_FILL_PAINT);
|
||||
}
|
||||
|
||||
nsIFrame *pval;
|
||||
CallQueryInterface(observable, &pval);
|
||||
|
||||
if (pval && pval->GetType() == nsLayoutAtoms::svgPatternFrame) {
|
||||
// Handle Patterns
|
||||
if (mFillPattern == pval) {
|
||||
if (aModType == nsISVGValue::mod_die) {
|
||||
mFillPattern = nsnull;
|
||||
}
|
||||
UpdateGraphic(nsSVGGeometryFrame::UPDATEMASK_FILL_PAINT);
|
||||
} else {
|
||||
// Assume stroke pattern
|
||||
if (aModType == nsISVGValue::mod_die) {
|
||||
mStrokePattern = nsnull;
|
||||
}
|
||||
UpdateGraphic(nsSVGGeometryFrame::UPDATEMASK_STROKE_PAINT);
|
||||
}
|
||||
return NS_OK;
|
||||
if (frame == mStrokeGradient) {
|
||||
if (aModType == nsISVGValue::mod_die)
|
||||
mStrokeGradient = nsnull;
|
||||
UpdateGraphic(nsSVGGeometryFrame::UPDATEMASK_STROKE_PAINT);
|
||||
}
|
||||
else if (frame == mStrokePattern) {
|
||||
if (aModType == nsISVGValue::mod_die)
|
||||
mStrokePattern = nsnull;
|
||||
UpdateGraphic(nsSVGGeometryFrame::UPDATEMASK_STROKE_PAINT);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -251,7 +237,7 @@ nsSVGGeometryFrame::GetStrokePaintServerType(PRUint16 *aStrokePaintServerType) {
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGGeometryFrame::GetStrokeGradient(nsISVGGradient **aGrad)
|
||||
nsSVGGeometryFrame::GetStrokeGradient(nsSVGGradientFrame **aGrad)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
*aGrad = nsnull;
|
||||
@ -263,7 +249,8 @@ nsSVGGeometryFrame::GetStrokeGradient(nsISVGGradient **aGrad)
|
||||
// Now have the URI. Get the gradient
|
||||
rv = NS_GetSVGGradient(&mStrokeGradient, aServer, mContent,
|
||||
GetPresContext()->PresShell());
|
||||
NS_ADD_SVGVALUE_OBSERVER(mStrokeGradient);
|
||||
if (mStrokeGradient)
|
||||
mStrokeGradient->AddObserver(this);
|
||||
}
|
||||
*aGrad = mStrokeGradient;
|
||||
return rv;
|
||||
@ -304,7 +291,7 @@ nsSVGGeometryFrame::GetFillPaintServerType(PRUint16 *aFillPaintServerType)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGGeometryFrame::GetFillGradient(nsISVGGradient **aGrad)
|
||||
nsSVGGeometryFrame::GetFillGradient(nsSVGGradientFrame **aGrad)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
*aGrad = nsnull;
|
||||
@ -316,7 +303,8 @@ nsSVGGeometryFrame::GetFillGradient(nsISVGGradient **aGrad)
|
||||
// Now have the URI. Get the gradient
|
||||
rv = NS_GetSVGGradient(&mFillGradient, aServer, mContent,
|
||||
GetPresContext()->PresShell());
|
||||
NS_ADD_SVGVALUE_OBSERVER(mFillGradient);
|
||||
if (mFillGradient)
|
||||
mFillGradient->AddObserver(this);
|
||||
}
|
||||
*aGrad = mFillGradient;
|
||||
return rv;
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include "nsISVGValueObserver.h"
|
||||
#include <cairo.h>
|
||||
|
||||
class nsISVGGradient;
|
||||
class nsSVGGradientFrame;
|
||||
class nsSVGPatternFrame;
|
||||
|
||||
typedef nsFrame nsSVGGeometryFrameBase;
|
||||
@ -84,11 +84,11 @@ public:
|
||||
|
||||
PRUint16 GetStrokePaintType();
|
||||
nsresult GetStrokePaintServerType(PRUint16 *aStrokePaintServerType);
|
||||
nsresult GetStrokeGradient(nsISVGGradient **aGrad);
|
||||
nsresult GetStrokeGradient(nsSVGGradientFrame **aGrad);
|
||||
nsresult GetStrokePattern(nsSVGPatternFrame **aPat);
|
||||
PRUint16 GetFillPaintType();
|
||||
nsresult GetFillPaintServerType(PRUint16 *aFillPaintServerType);
|
||||
nsresult GetFillGradient(nsISVGGradient **aGrad);
|
||||
nsresult GetFillGradient(nsSVGGradientFrame **aGrad);
|
||||
nsresult GetFillPattern(nsSVGPatternFrame **aPat);
|
||||
|
||||
// Set up a cairo context for filling a path
|
||||
@ -132,8 +132,8 @@ private:
|
||||
nsresult GetStrokeDashArray(double **arr, PRUint32 *count);
|
||||
float GetStrokeDashoffset();
|
||||
|
||||
nsISVGGradient* mFillGradient;
|
||||
nsISVGGradient* mStrokeGradient;
|
||||
nsSVGGradientFrame* mFillGradient;
|
||||
nsSVGGradientFrame* mStrokeGradient;
|
||||
nsSVGPatternFrame* mFillPattern;
|
||||
nsSVGPatternFrame* mStrokePattern;
|
||||
};
|
||||
|
@ -41,14 +41,14 @@
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
class nsISVGGradient;
|
||||
class nsSVGGradientFrame;
|
||||
class nsIURI;
|
||||
class nsIContent;
|
||||
class nsIPresShell;
|
||||
class nsStyleContext;
|
||||
class nsIFrame;
|
||||
|
||||
nsresult NS_GetSVGGradient(nsISVGGradient** result,
|
||||
nsresult NS_GetSVGGradient(nsSVGGradientFrame** result,
|
||||
nsIURI* aURI,
|
||||
nsIContent* aContent,
|
||||
nsIPresShell* aPresShell);
|
||||
|
@ -37,255 +37,15 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGGenericContainerFrame.h"
|
||||
#include "nsIDOMSVGAnimatedNumber.h"
|
||||
#include "nsIDOMSVGAnimatedString.h"
|
||||
#include "nsIDOMSVGAnimTransformList.h"
|
||||
#include "nsIDOMSVGTransformList.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "nsISVGGradient.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIDOMSVGStopElement.h"
|
||||
#include "nsSVGDefsFrame.h"
|
||||
#include "nsSVGGradientElement.h"
|
||||
#include "nsSVGGeometryFrame.h"
|
||||
|
||||
class nsSVGLinearGradientFrame;
|
||||
class nsSVGRadialGradientFrame;
|
||||
|
||||
typedef nsSVGDefsFrame nsSVGGradientFrameBase;
|
||||
|
||||
class nsSVGGradientFrame : public nsSVGGradientFrameBase,
|
||||
public nsSVGValue,
|
||||
public nsISVGValueObserver,
|
||||
public nsSupportsWeakReference,
|
||||
public nsISVGGradient
|
||||
{
|
||||
public:
|
||||
friend nsIFrame* NS_NewSVGLinearGradientFrame(nsIPresShell* aPresShell,
|
||||
nsIContent* aContent,
|
||||
nsStyleContext* aContext);
|
||||
|
||||
friend nsIFrame* NS_NewSVGRadialGradientFrame(nsIPresShell* aPresShell,
|
||||
nsIContent* aContent,
|
||||
nsStyleContext* aContext);
|
||||
|
||||
friend nsIFrame* NS_NewSVGStopFrame(nsIPresShell* aPresShell,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsStyleContext* aContext);
|
||||
|
||||
friend nsresult NS_GetSVGGradientFrame(nsIFrame** result,
|
||||
nsIURI* aURI,
|
||||
nsIContent* aContent,
|
||||
nsIPresShell* aPresShell);
|
||||
|
||||
nsSVGGradientFrame(nsStyleContext* aContext) :
|
||||
nsSVGGradientFrameBase(aContext) {}
|
||||
|
||||
// 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
|
||||
|
||||
// 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();
|
||||
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
virtual nsIAtom* GetType() const; // frame type: nsGkAtoms::svgGradientFrame
|
||||
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
#ifdef DEBUG
|
||||
// nsIFrameDebug interface:
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("SVGGradient"), aResult);
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
// nsISVGChildFrame interface:
|
||||
NS_IMETHOD PaintSVG(nsISVGRendererCanvas* canvas)
|
||||
{
|
||||
return NS_OK; // override - our frames don't directly render
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Helper methods to aid gradient implementation
|
||||
// ---------------------------------------------
|
||||
// The SVG specification allows gradient elements to reference another
|
||||
// gradient element to "inherit" its attributes or gradient stops. Reference
|
||||
// chains of arbitrary length are allowed, and loop checking is essential!
|
||||
// Use the following helpers to safely get attributes and stops.
|
||||
|
||||
// Parse our xlink:href and set mNextGrad if we reference another gradient.
|
||||
void GetRefedGradientFromHref();
|
||||
|
||||
// Helpers to look at our gradient and then along its reference chain (if any)
|
||||
// to find the first gradient with the specified attribute.
|
||||
nsIContent* GetGradientWithAttr(nsIAtom *aAttrName);
|
||||
|
||||
// Some attributes are only valid on one type of gradient, and we *must* get
|
||||
// the right type or we won't have the data structures we require.
|
||||
nsIContent* GetGradientWithAttr(nsIAtom *aAttrName, nsIAtom *aGradType);
|
||||
|
||||
// Get a stop element and (optionally) its frame (returns stop index/count)
|
||||
PRInt32 GetStopElement(PRInt32 aIndex,
|
||||
nsIDOMSVGStopElement * *aStopElement,
|
||||
nsIFrame * *aStopFrame);
|
||||
|
||||
protected:
|
||||
|
||||
// Use these inline methods instead of GetGradientWithAttr(..., aGradType)
|
||||
nsIContent* GetLinearGradientWithAttr(nsIAtom *aAttrName)
|
||||
{
|
||||
return GetGradientWithAttr(aAttrName, nsGkAtoms::svgLinearGradientFrame);
|
||||
}
|
||||
nsIContent* GetRadialGradientWithAttr(nsIAtom *aAttrName)
|
||||
{
|
||||
return GetGradientWithAttr(aAttrName, nsGkAtoms::svgRadialGradientFrame);
|
||||
}
|
||||
|
||||
// We must loop check notifications too: see bug 330387 comment 18 + testcase
|
||||
// and comment 19. The mLoopFlag check is in Will/DidModifySVGObservable.
|
||||
void WillModify(modificationType aModType = mod_other)
|
||||
{
|
||||
mLoopFlag = PR_TRUE;
|
||||
nsSVGValue::WillModify(aModType);
|
||||
mLoopFlag = PR_FALSE;
|
||||
}
|
||||
void DidModify(modificationType aModType = mod_other)
|
||||
{
|
||||
mLoopFlag = PR_TRUE;
|
||||
nsSVGValue::DidModify(aModType);
|
||||
mLoopFlag = PR_FALSE;
|
||||
}
|
||||
|
||||
// Get the value of our gradientUnits attribute
|
||||
PRUint16 GetGradientUnits();
|
||||
|
||||
virtual ~nsSVGGradientFrame();
|
||||
|
||||
// The graphic element our gradient is (currently) being applied to
|
||||
nsRefPtr<nsSVGElement> mSourceContent;
|
||||
|
||||
private:
|
||||
|
||||
// href of the other gradient we reference (if any)
|
||||
nsCOMPtr<nsIDOMSVGAnimatedString> mHref;
|
||||
|
||||
// Frame of the gradient we reference (if any). Do NOT use this directly.
|
||||
// Use Get[Xxx]GradientWithAttr instead to ensure proper loop checking.
|
||||
nsSVGGradientFrame *mNextGrad;
|
||||
|
||||
// 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
|
||||
PRPackedBool mLoopFlag;
|
||||
|
||||
// Ideally we'd set mNextGrad by implementing Init(), but the frame of the
|
||||
// gradient we reference isn't available at that stage. Our only option is to
|
||||
// set mNextGrad lazily in GetGradientWithAttr, and to make that efficient
|
||||
// we need this flag. Our class size is the same since it just fills padding.
|
||||
PRPackedBool mInitialized;
|
||||
};
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Linear Gradients
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
typedef nsSVGGradientFrame nsSVGLinearGradientFrameBase;
|
||||
|
||||
class nsSVGLinearGradientFrame : public nsSVGLinearGradientFrameBase,
|
||||
public nsISVGLinearGradient
|
||||
{
|
||||
public:
|
||||
nsSVGLinearGradientFrame(nsStyleContext* aContext) :
|
||||
nsSVGLinearGradientFrameBase(aContext) {}
|
||||
|
||||
// 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
|
||||
|
||||
// nsISVGGradient interface gets inherited from nsSVGGradientFrame
|
||||
|
||||
// nsIFrame interface:
|
||||
virtual nsIAtom* GetType() const; // frame type: nsGkAtoms::svgLinearGradientFrame
|
||||
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
#ifdef DEBUG
|
||||
// nsIFrameDebug interface:
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("SVGLinearGradient"), aResult);
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Radial Gradients
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
typedef nsSVGGradientFrame nsSVGRadialGradientFrameBase;
|
||||
|
||||
class nsSVGRadialGradientFrame : public nsSVGRadialGradientFrameBase,
|
||||
public nsISVGRadialGradient
|
||||
{
|
||||
public:
|
||||
nsSVGRadialGradientFrame(nsStyleContext* aContext) :
|
||||
nsSVGRadialGradientFrameBase(aContext) {}
|
||||
|
||||
// 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
|
||||
|
||||
// nsIFrame interface:
|
||||
virtual nsIAtom* GetType() const; // frame type: nsGkAtoms::svgRadialGradientFrame
|
||||
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
#ifdef DEBUG
|
||||
// nsIFrameDebug interface:
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("SVGRadialGradient"), aResult);
|
||||
}
|
||||
#endif // DEBUG
|
||||
};
|
||||
#include "nsSVGGradientFrame.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
@ -305,7 +65,6 @@ nsSVGGradientFrame::~nsSVGGradientFrame()
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsSVGGradientFrame)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGValue)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGGradient)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISVGValue)
|
||||
@ -344,14 +103,11 @@ nsSVGGradientFrame::DidModifySVGObservable(nsISVGValue* observable,
|
||||
}
|
||||
|
||||
// If we reference another gradient and it's going away, null out mNextGrad
|
||||
nsCOMPtr<nsISVGGradient> gradient;
|
||||
if (mNextGrad && aModType == nsISVGValue::mod_die &&
|
||||
(gradient = do_QueryInterface(observable))) {
|
||||
nsISVGGradient *grad;
|
||||
CallQueryInterface(mNextGrad, &grad);
|
||||
if (grad == gradient) {
|
||||
if (mNextGrad && aModType == nsISVGValue::mod_die) {
|
||||
nsIFrame *gradient = nsnull;
|
||||
CallQueryInterface(observable, &gradient);
|
||||
if (mNextGrad == gradient)
|
||||
mNextGrad = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't pass on mod_die - our gradient observers would stop observing us!
|
||||
@ -417,55 +173,45 @@ nsSVGGradientFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
aAttribute, aModType);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGGradient implementation
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGGradientFrame::GetStopCount(PRUint32 *aStopCount)
|
||||
PRUint32
|
||||
nsSVGGradientFrame::GetStopCount()
|
||||
{
|
||||
nsIDOMSVGStopElement *stopElement = nsnull;
|
||||
*aStopCount = GetStopElement(-1, &stopElement, nsnull);
|
||||
return NS_OK; // no stops is valid - paint as for 'none'
|
||||
return GetStopElement(-1, &stopElement, nsnull);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGGradientFrame::GetStopOffset(PRInt32 aIndex, float *aOffset)
|
||||
void
|
||||
nsSVGGradientFrame::GetStopInformation(PRInt32 aIndex,
|
||||
float *aOffset, nscolor *aColor, float *aOpacity)
|
||||
{
|
||||
*aOffset = 0.0f;
|
||||
*aColor = 0;
|
||||
*aOpacity = 1.0f;
|
||||
|
||||
nsIDOMSVGStopElement *stopElement = nsnull;
|
||||
PRInt32 stopCount = GetStopElement(aIndex, &stopElement, nsnull);
|
||||
nsIFrame *stopFrame = nsnull;
|
||||
GetStopElement(aIndex, &stopElement, &stopFrame);
|
||||
|
||||
if (stopElement) {
|
||||
nsCOMPtr<nsIDOMSVGAnimatedNumber> aNum;
|
||||
stopElement->GetOffset(getter_AddRefs(aNum));
|
||||
|
||||
aNum->GetAnimVal(aOffset);
|
||||
if (*aOffset < 0.0f)
|
||||
*aOffset = 0.0f;
|
||||
else if (*aOffset > 1.0f)
|
||||
*aOffset = 1.0f;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(stopCount == 0, "Don't call me with an invalid stop index!");
|
||||
*aOffset = 0.0f;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGGradientFrame::GetStopColor(PRInt32 aIndex, nscolor *aStopColor)
|
||||
{
|
||||
nsIDOMSVGStopElement *stopElement = nsnull;
|
||||
nsIFrame *stopFrame = nsnull;
|
||||
PRInt32 stopCount = GetStopElement(aIndex, &stopElement, &stopFrame);
|
||||
if (stopFrame) {
|
||||
*aStopColor = stopFrame->GetStyleSVGReset()->mStopColor.mPaint.mColor;
|
||||
return NS_OK;
|
||||
*aColor = stopFrame->GetStyleSVGReset()->mStopColor.mPaint.mColor;
|
||||
*aOpacity = stopFrame->GetStyleSVGReset()->mStopOpacity;
|
||||
}
|
||||
|
||||
// One way or another we have an implementation problem if we get here
|
||||
#ifdef DEBUG
|
||||
if (stopElement) {
|
||||
// One way or another we have an implementation problem if we get here
|
||||
else if (stopElement) {
|
||||
NS_WARNING("We *do* have a stop but can't use it because it doesn't have "
|
||||
"a frame - we need frame free gradients and stops!");
|
||||
}
|
||||
@ -473,54 +219,9 @@ nsSVGGradientFrame::GetStopColor(PRInt32 aIndex, nscolor *aStopColor)
|
||||
NS_ERROR("Don't call me with an invalid stop index!");
|
||||
}
|
||||
#endif
|
||||
|
||||
*aStopColor = 0;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGGradientFrame::GetStopOpacity(PRInt32 aIndex, float *aStopOpacity)
|
||||
{
|
||||
nsIDOMSVGStopElement *stopElement = nsnull;
|
||||
nsIFrame *stopFrame = nsnull;
|
||||
PRInt32 stopCount = GetStopElement(aIndex, &stopElement, &stopFrame);
|
||||
if (stopFrame) {
|
||||
*aStopOpacity = stopFrame->GetStyleSVGReset()->mStopOpacity;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// One way or another we have an implementation problem if we get here
|
||||
#ifdef DEBUG
|
||||
if (stopElement) {
|
||||
NS_WARNING("We *do* have a stop but can't use it because it doesn't have "
|
||||
"a frame - we need frame free gradients and stops!");
|
||||
}
|
||||
else {
|
||||
NS_ERROR("Don't call me with an invalid stop index!");
|
||||
}
|
||||
#endif
|
||||
|
||||
*aStopOpacity = 1;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGGradientFrame::GetGradientType(PRUint32 *aType)
|
||||
{
|
||||
if (GetType() == nsGkAtoms::svgLinearGradientFrame) {
|
||||
*aType = nsISVGGradient::SVG_LINEAR_GRADIENT;
|
||||
return NS_OK;
|
||||
}
|
||||
if (GetType() == nsGkAtoms::svgRadialGradientFrame) {
|
||||
*aType = nsISVGGradient::SVG_RADIAL_GRADIENT;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_NOTREACHED("Unknown gradient type!");
|
||||
*aType = nsISVGGradient::SVG_UNKNOWN_GRADIENT;
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsSVGGradientFrame::GetGradientTransform(nsIDOMSVGMatrix **aGradientTransform,
|
||||
nsSVGGeometryFrame *aSource)
|
||||
{
|
||||
@ -591,8 +292,8 @@ nsSVGGradientFrame::GetGradientTransform(nsIDOMSVGMatrix **aGradientTransform,
|
||||
return bboxTransform->Multiply(gradientTransform, aGradientTransform);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGGradientFrame::GetSpreadMethod(PRUint16 *aSpreadMethod)
|
||||
PRUint16
|
||||
nsSVGGradientFrame::GetSpreadMethod()
|
||||
{
|
||||
nsIContent *gradient = GetGradientWithAttr(nsGkAtoms::spreadMethod);
|
||||
if (!gradient)
|
||||
@ -601,7 +302,10 @@ nsSVGGradientFrame::GetSpreadMethod(PRUint16 *aSpreadMethod)
|
||||
nsCOMPtr<nsIDOMSVGGradientElement> gradElement = do_QueryInterface(gradient);
|
||||
nsCOMPtr<nsIDOMSVGAnimatedEnumeration> method;
|
||||
gradElement->GetSpreadMethod(getter_AddRefs(method));
|
||||
return method->GetAnimVal(aSpreadMethod);
|
||||
|
||||
PRUint16 val;
|
||||
method->GetAnimVal(&val);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
@ -795,17 +499,12 @@ nsSVGLinearGradientFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISupports methods
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsSVGLinearGradientFrame)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGLinearGradient)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsSVGLinearGradientFrameBase)
|
||||
|
||||
// nsISVGLinearGradient
|
||||
NS_IMETHODIMP
|
||||
nsSVGLinearGradientFrame::GetX1(float *aX1)
|
||||
float
|
||||
nsSVGLinearGradientFrame::GradientLookupAttribute(nsIAtom *aAtomName,
|
||||
PRUint16 aEnumName)
|
||||
{
|
||||
nsIContent *gradient = GetLinearGradientWithAttr(nsGkAtoms::x1);
|
||||
nsIContent *gradient = GetLinearGradientWithAttr(aAtomName);
|
||||
if (!gradient)
|
||||
gradient = mContent; // use our gradient to get the correct default value
|
||||
|
||||
@ -818,108 +517,24 @@ nsSVGLinearGradientFrame::GetX1(float *aX1)
|
||||
|
||||
PRUint16 gradientUnits = GetGradientUnits();
|
||||
if (gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_USERSPACEONUSE) {
|
||||
*aX1 = nsSVGUtils::UserSpace(mSourceContent,
|
||||
&element->mLengthAttributes[nsSVGLinearGradientElement::X1]);
|
||||
return NS_OK;
|
||||
return nsSVGUtils::UserSpace(mSourceContent,
|
||||
&element->mLengthAttributes[aEnumName]);
|
||||
}
|
||||
|
||||
NS_ASSERTION(gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX,
|
||||
"Unknown gradientUnits type");
|
||||
|
||||
*aX1 = element->mLengthAttributes[nsSVGLinearGradientElement::X1].
|
||||
return element->mLengthAttributes[aEnumName].
|
||||
GetAnimValue(NS_STATIC_CAST(nsSVGCoordCtxProvider*, nsnull));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGLinearGradientFrame::GetY1(float *aY1)
|
||||
void
|
||||
nsSVGLinearGradientFrame::GetParameters(float *aX1, float *aY1, float *aX2, float *aY2)
|
||||
{
|
||||
nsIContent *gradient = GetLinearGradientWithAttr(nsGkAtoms::y1);
|
||||
if (!gradient)
|
||||
gradient = mContent; // use our gradient to get the correct default value
|
||||
|
||||
nsSVGLinearGradientElement *element =
|
||||
NS_STATIC_CAST(nsSVGLinearGradientElement*, gradient);
|
||||
|
||||
// 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 gradientUnits = GetGradientUnits();
|
||||
if (gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_USERSPACEONUSE) {
|
||||
*aY1 = nsSVGUtils::UserSpace(mSourceContent,
|
||||
&element->mLengthAttributes[nsSVGLinearGradientElement::Y1]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX,
|
||||
"Unknown gradientUnits type");
|
||||
|
||||
*aY1 = element->mLengthAttributes[nsSVGLinearGradientElement::Y1].
|
||||
GetAnimValue(NS_STATIC_CAST(nsSVGCoordCtxProvider*, nsnull));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGLinearGradientFrame::GetX2(float *aX2)
|
||||
{
|
||||
nsIContent *gradient = GetLinearGradientWithAttr(nsGkAtoms::x2);
|
||||
if (!gradient)
|
||||
gradient = mContent; // use our gradient to get the correct default value
|
||||
|
||||
nsSVGLinearGradientElement *element =
|
||||
NS_STATIC_CAST(nsSVGLinearGradientElement*, gradient);
|
||||
|
||||
// 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 gradientUnits = GetGradientUnits();
|
||||
if (gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_USERSPACEONUSE) {
|
||||
*aX2 = nsSVGUtils::UserSpace(mSourceContent,
|
||||
&element->mLengthAttributes[nsSVGLinearGradientElement::X2]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX,
|
||||
"Unknown gradientUnits type");
|
||||
|
||||
*aX2 = element->mLengthAttributes[nsSVGLinearGradientElement::X2].
|
||||
GetAnimValue(NS_STATIC_CAST(nsSVGCoordCtxProvider*, nsnull));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGLinearGradientFrame::GetY2(float *aY2)
|
||||
{
|
||||
nsIContent *gradient = GetLinearGradientWithAttr(nsGkAtoms::y2);
|
||||
if (!gradient)
|
||||
gradient = mContent; // use our gradient to get the correct default value
|
||||
|
||||
nsSVGLinearGradientElement *element =
|
||||
NS_STATIC_CAST(nsSVGLinearGradientElement*, gradient);
|
||||
|
||||
// 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 gradientUnits = GetGradientUnits();
|
||||
if (gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_USERSPACEONUSE) {
|
||||
*aY2 = nsSVGUtils::UserSpace(mSourceContent,
|
||||
&element->mLengthAttributes[nsSVGLinearGradientElement::Y2]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX,
|
||||
"Unknown gradientUnits type");
|
||||
|
||||
*aY2 = element->mLengthAttributes[nsSVGLinearGradientElement::Y2].
|
||||
GetAnimValue(NS_STATIC_CAST(nsSVGCoordCtxProvider*, nsnull));
|
||||
|
||||
return NS_OK;
|
||||
*aX1 = GradientLookupAttribute(nsGkAtoms::x1, nsSVGLinearGradientElement::X1);
|
||||
*aY1 = GradientLookupAttribute(nsGkAtoms::y1, nsSVGLinearGradientElement::Y1);
|
||||
*aX2 = GradientLookupAttribute(nsGkAtoms::x2, nsSVGLinearGradientElement::X2);
|
||||
*aY2 = GradientLookupAttribute(nsGkAtoms::y2, nsSVGLinearGradientElement::Y2);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -953,19 +568,21 @@ nsSVGRadialGradientFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISupports methods
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsSVGRadialGradientFrame)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGRadialGradient)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsSVGRadialGradientFrameBase)
|
||||
|
||||
// nsISVGRadialGradient
|
||||
NS_IMETHODIMP
|
||||
nsSVGRadialGradientFrame::GetFx(float *aFx)
|
||||
float
|
||||
nsSVGRadialGradientFrame::GradientLookupAttribute(nsIAtom *aAtomName,
|
||||
PRUint16 aEnumName,
|
||||
nsIContent *aElement)
|
||||
{
|
||||
nsIContent *gradient = GetRadialGradientWithAttr(nsGkAtoms::fx);
|
||||
if (!gradient)
|
||||
return GetCx(aFx); // if fx isn't set, we must use cx
|
||||
nsIContent *gradient;
|
||||
|
||||
if (aElement) {
|
||||
gradient = aElement;
|
||||
} else {
|
||||
gradient = GetRadialGradientWithAttr(aAtomName);
|
||||
if (!gradient)
|
||||
gradient = mContent; // use our gradient to get the correct default value
|
||||
}
|
||||
|
||||
nsSVGRadialGradientElement *element =
|
||||
NS_STATIC_CAST(nsSVGRadialGradientElement*, gradient);
|
||||
@ -976,138 +593,36 @@ nsSVGRadialGradientFrame::GetFx(float *aFx)
|
||||
|
||||
PRUint16 gradientUnits = GetGradientUnits();
|
||||
if (gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_USERSPACEONUSE) {
|
||||
*aFx = nsSVGUtils::UserSpace(mSourceContent,
|
||||
&element->mLengthAttributes[nsSVGRadialGradientElement::FX]);
|
||||
return NS_OK;
|
||||
return nsSVGUtils::UserSpace(mSourceContent,
|
||||
&element->mLengthAttributes[aEnumName]);
|
||||
}
|
||||
|
||||
NS_ASSERTION(gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX,
|
||||
"Unknown gradientUnits type");
|
||||
|
||||
*aFx = element->mLengthAttributes[nsSVGRadialGradientElement::FX].
|
||||
return element->mLengthAttributes[aEnumName].
|
||||
GetAnimValue(NS_STATIC_CAST(nsSVGCoordCtxProvider*, nsnull));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGRadialGradientFrame::GetFy(float *aFy)
|
||||
void
|
||||
nsSVGRadialGradientFrame::GetParameters(float *aCx, float *aCy, float *aR,
|
||||
float *aFx, float *aFy)
|
||||
{
|
||||
nsIContent *gradient = GetRadialGradientWithAttr(nsGkAtoms::fy);
|
||||
if (!gradient)
|
||||
return GetCy(aFy); // if fy isn't set, we must use cy
|
||||
*aCx = GradientLookupAttribute(nsGkAtoms::cx, nsSVGRadialGradientElement::CX);
|
||||
*aCy = GradientLookupAttribute(nsGkAtoms::cy, nsSVGRadialGradientElement::CY);
|
||||
*aR = GradientLookupAttribute(nsGkAtoms::r, nsSVGRadialGradientElement::R);
|
||||
|
||||
nsSVGRadialGradientElement *element =
|
||||
NS_STATIC_CAST(nsSVGRadialGradientElement*, gradient);
|
||||
nsIContent *gradient;
|
||||
|
||||
// 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.
|
||||
if (!(gradient = GetRadialGradientWithAttr(nsGkAtoms::fx)))
|
||||
*aFx = *aCx; // if fx isn't set, we must use cx
|
||||
else
|
||||
*aFx = GradientLookupAttribute(nsGkAtoms::fx, nsSVGRadialGradientElement::FX, gradient);
|
||||
|
||||
PRUint16 gradientUnits = GetGradientUnits();
|
||||
if (gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_USERSPACEONUSE) {
|
||||
*aFy = nsSVGUtils::UserSpace(mSourceContent,
|
||||
&element->mLengthAttributes[nsSVGRadialGradientElement::FY]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX,
|
||||
"Unknown gradientUnits type");
|
||||
|
||||
*aFy = element->mLengthAttributes[nsSVGRadialGradientElement::FY].
|
||||
GetAnimValue(NS_STATIC_CAST(nsSVGCoordCtxProvider*, nsnull));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGRadialGradientFrame::GetCx(float *aCx)
|
||||
{
|
||||
nsIContent *gradient = GetRadialGradientWithAttr(nsGkAtoms::cx);
|
||||
if (!gradient)
|
||||
gradient = mContent; // use our gradient to get the correct default value
|
||||
|
||||
nsSVGRadialGradientElement *element =
|
||||
NS_STATIC_CAST(nsSVGRadialGradientElement*, gradient);
|
||||
|
||||
// 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 gradientUnits = GetGradientUnits();
|
||||
if (gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_USERSPACEONUSE) {
|
||||
*aCx = nsSVGUtils::UserSpace(mSourceContent,
|
||||
&element->mLengthAttributes[nsSVGRadialGradientElement::CX]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX,
|
||||
"Unknown gradientUnits type");
|
||||
|
||||
*aCx = element->mLengthAttributes[nsSVGRadialGradientElement::CX].
|
||||
GetAnimValue(NS_STATIC_CAST(nsSVGCoordCtxProvider*, nsnull));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGRadialGradientFrame::GetCy(float *aCy)
|
||||
{
|
||||
nsIContent *gradient = GetRadialGradientWithAttr(nsGkAtoms::cy);
|
||||
if (!gradient)
|
||||
gradient = mContent; // use our gradient to get the correct default value
|
||||
|
||||
nsSVGRadialGradientElement *element =
|
||||
NS_STATIC_CAST(nsSVGRadialGradientElement*, gradient);
|
||||
|
||||
// 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 gradientUnits = GetGradientUnits();
|
||||
if (gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_USERSPACEONUSE) {
|
||||
*aCy = nsSVGUtils::UserSpace(mSourceContent,
|
||||
&element->mLengthAttributes[nsSVGRadialGradientElement::CY]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX,
|
||||
"Unknown gradientUnits type");
|
||||
|
||||
*aCy = element->mLengthAttributes[nsSVGRadialGradientElement::CY].
|
||||
GetAnimValue(NS_STATIC_CAST(nsSVGCoordCtxProvider*, nsnull));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGRadialGradientFrame::GetR(float *aR)
|
||||
{
|
||||
nsIContent *gradient = GetRadialGradientWithAttr(nsGkAtoms::r);
|
||||
if (!gradient)
|
||||
gradient = mContent; // use our gradient to get the correct default value
|
||||
|
||||
nsSVGRadialGradientElement *element =
|
||||
NS_STATIC_CAST(nsSVGRadialGradientElement*, gradient);
|
||||
|
||||
// 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 gradientUnits = GetGradientUnits();
|
||||
if (gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_USERSPACEONUSE) {
|
||||
*aR = nsSVGUtils::UserSpace(mSourceContent,
|
||||
&element->mLengthAttributes[nsSVGRadialGradientElement::R]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(gradientUnits == nsIDOMSVGGradientElement::SVG_GRUNITS_OBJECTBOUNDINGBOX,
|
||||
"Unknown gradientUnits type");
|
||||
|
||||
*aR = element->mLengthAttributes[nsSVGRadialGradientElement::R].
|
||||
GetAnimValue(NS_STATIC_CAST(nsSVGCoordCtxProvider*, nsnull));
|
||||
|
||||
return NS_OK;
|
||||
if (!(gradient = GetRadialGradientWithAttr(nsGkAtoms::fy)))
|
||||
*aFy = *aCy; // if fy isn't set, we must use cy
|
||||
else
|
||||
*aFy = GradientLookupAttribute(nsGkAtoms::fy, nsSVGRadialGradientElement::FY, gradient);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -1167,9 +682,9 @@ NS_NewSVGRadialGradientFrame(nsIPresShell* aPresShell,
|
||||
}
|
||||
|
||||
// Public function to locate the SVGGradientFrame structure pointed to by a URI
|
||||
// and return a nsISVGGradient
|
||||
nsresult NS_GetSVGGradient(nsISVGGradient **aGrad, nsIURI *aURI, nsIContent *aContent,
|
||||
nsIPresShell *aPresShell)
|
||||
// and return a nsSVGGradientFrame
|
||||
nsresult NS_GetSVGGradient(nsSVGGradientFrame **aGrad, nsIURI *aURI,
|
||||
nsIContent *aContent, nsIPresShell *aPresShell)
|
||||
{
|
||||
*aGrad = nsnull;
|
||||
|
||||
@ -1182,5 +697,11 @@ nsresult NS_GetSVGGradient(nsISVGGradient **aGrad, nsIURI *aURI, nsIContent *aCo
|
||||
if (!NS_SUCCEEDED(nsSVGUtils::GetReferencedFrame(&result, aURI, aContent, aPresShell))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return result->QueryInterface(NS_GET_IID(nsISVGGradient), (void **)aGrad);
|
||||
if (result->GetType() == nsGkAtoms::svgLinearGradientFrame ||
|
||||
result->GetType() == nsGkAtoms::svgRadialGradientFrame) {
|
||||
*aGrad = NS_STATIC_CAST(nsSVGGradientFrame*, result);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -39,9 +39,253 @@
|
||||
#ifndef __NS_SVGGRADIENTFRAME_H__
|
||||
#define __NS_SVGGRADIENTFRAME_H__
|
||||
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsSVGDefsFrame.h"
|
||||
#include "nsSVGValue.h"
|
||||
#include "nsISVGValueObserver.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsIDOMSVGAnimatedString.h"
|
||||
#include "nsSVGElement.h"
|
||||
|
||||
class nsIDOMSVGStopElement;
|
||||
|
||||
typedef nsSVGDefsFrame nsSVGGradientFrameBase;
|
||||
|
||||
class nsSVGGradientFrame : public nsSVGGradientFrameBase,
|
||||
public nsSVGValue,
|
||||
public nsISVGValueObserver,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
friend nsIFrame* NS_NewSVGLinearGradientFrame(nsIPresShell* aPresShell,
|
||||
nsIContent* aContent,
|
||||
nsStyleContext* aContext);
|
||||
|
||||
friend nsIFrame* NS_NewSVGRadialGradientFrame(nsIPresShell* aPresShell,
|
||||
nsIContent* aContent,
|
||||
nsStyleContext* aContext);
|
||||
|
||||
friend nsIFrame* NS_NewSVGStopFrame(nsIPresShell* aPresShell,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParentFrame,
|
||||
nsStyleContext* aContext);
|
||||
|
||||
friend nsresult NS_GetSVGGradientFrame(nsIFrame** result,
|
||||
nsIURI* aURI,
|
||||
nsIContent* aContent,
|
||||
nsIPresShell* aPresShell);
|
||||
|
||||
nsSVGGradientFrame(nsStyleContext* aContext) :
|
||||
nsSVGGradientFrameBase(aContext) {}
|
||||
|
||||
enum {
|
||||
SVG_LINEAR_GRADIENT = 0,
|
||||
SVG_RADIAL_GRADIENT = 1
|
||||
};
|
||||
|
||||
virtual PRUint16 GetGradientType() = 0;
|
||||
PRUint16 GetSpreadMethod();
|
||||
PRUint32 GetStopCount();
|
||||
|
||||
void GetStopInformation(PRInt32 aIndex,
|
||||
float *aOffset, nscolor *aColor, float *aOpacity);
|
||||
|
||||
nsresult GetGradientTransform(nsIDOMSVGMatrix **retval,
|
||||
nsSVGGeometryFrame *aSource);
|
||||
|
||||
// nsISupports interface:
|
||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
|
||||
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
|
||||
|
||||
// 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();
|
||||
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
virtual nsIAtom* GetType() const; // frame type: nsGkAtoms::svgGradientFrame
|
||||
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
#ifdef DEBUG
|
||||
// nsIFrameDebug interface:
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("SVGGradient"), aResult);
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
// nsISVGChildFrame interface:
|
||||
NS_IMETHOD PaintSVG(nsISVGRendererCanvas* canvas)
|
||||
{
|
||||
return NS_OK; // override - our frames don't directly render
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Helper methods to aid gradient implementation
|
||||
// ---------------------------------------------
|
||||
// The SVG specification allows gradient elements to reference another
|
||||
// gradient element to "inherit" its attributes or gradient stops. Reference
|
||||
// chains of arbitrary length are allowed, and loop checking is essential!
|
||||
// Use the following helpers to safely get attributes and stops.
|
||||
|
||||
// Parse our xlink:href and set mNextGrad if we reference another gradient.
|
||||
void GetRefedGradientFromHref();
|
||||
|
||||
// Helpers to look at our gradient and then along its reference chain (if any)
|
||||
// to find the first gradient with the specified attribute.
|
||||
nsIContent* GetGradientWithAttr(nsIAtom *aAttrName);
|
||||
|
||||
// Some attributes are only valid on one type of gradient, and we *must* get
|
||||
// the right type or we won't have the data structures we require.
|
||||
nsIContent* GetGradientWithAttr(nsIAtom *aAttrName, nsIAtom *aGradType);
|
||||
|
||||
// Get a stop element and (optionally) its frame (returns stop index/count)
|
||||
PRInt32 GetStopElement(PRInt32 aIndex,
|
||||
nsIDOMSVGStopElement * *aStopElement,
|
||||
nsIFrame * *aStopFrame);
|
||||
|
||||
protected:
|
||||
|
||||
// Use these inline methods instead of GetGradientWithAttr(..., aGradType)
|
||||
nsIContent* GetLinearGradientWithAttr(nsIAtom *aAttrName)
|
||||
{
|
||||
return GetGradientWithAttr(aAttrName, nsGkAtoms::svgLinearGradientFrame);
|
||||
}
|
||||
nsIContent* GetRadialGradientWithAttr(nsIAtom *aAttrName)
|
||||
{
|
||||
return GetGradientWithAttr(aAttrName, nsGkAtoms::svgRadialGradientFrame);
|
||||
}
|
||||
|
||||
// We must loop check notifications too: see bug 330387 comment 18 + testcase
|
||||
// and comment 19. The mLoopFlag check is in Will/DidModifySVGObservable.
|
||||
void WillModify(modificationType aModType = mod_other)
|
||||
{
|
||||
mLoopFlag = PR_TRUE;
|
||||
nsSVGValue::WillModify(aModType);
|
||||
mLoopFlag = PR_FALSE;
|
||||
}
|
||||
void DidModify(modificationType aModType = mod_other)
|
||||
{
|
||||
mLoopFlag = PR_TRUE;
|
||||
nsSVGValue::DidModify(aModType);
|
||||
mLoopFlag = PR_FALSE;
|
||||
}
|
||||
|
||||
// Get the value of our gradientUnits attribute
|
||||
PRUint16 GetGradientUnits();
|
||||
|
||||
virtual ~nsSVGGradientFrame();
|
||||
|
||||
// The graphic element our gradient is (currently) being applied to
|
||||
nsRefPtr<nsSVGElement> mSourceContent;
|
||||
|
||||
private:
|
||||
|
||||
// href of the other gradient we reference (if any)
|
||||
nsCOMPtr<nsIDOMSVGAnimatedString> mHref;
|
||||
|
||||
// Frame of the gradient we reference (if any). Do NOT use this directly.
|
||||
// Use Get[Xxx]GradientWithAttr instead to ensure proper loop checking.
|
||||
nsSVGGradientFrame *mNextGrad;
|
||||
|
||||
// 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
|
||||
PRPackedBool mLoopFlag;
|
||||
|
||||
// Ideally we'd set mNextGrad by implementing Init(), but the frame of the
|
||||
// gradient we reference isn't available at that stage. Our only option is to
|
||||
// set mNextGrad lazily in GetGradientWithAttr, and to make that efficient
|
||||
// we need this flag. Our class size is the same since it just fills padding.
|
||||
PRPackedBool mInitialized;
|
||||
};
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Linear Gradients
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
typedef nsSVGGradientFrame nsSVGLinearGradientFrameBase;
|
||||
|
||||
class nsSVGLinearGradientFrame : public nsSVGLinearGradientFrameBase
|
||||
{
|
||||
public:
|
||||
nsSVGLinearGradientFrame(nsStyleContext* aContext) :
|
||||
nsSVGLinearGradientFrameBase(aContext) {}
|
||||
|
||||
void GetParameters(float *aX1, float *aY1, float *aX2, float *aY2);
|
||||
|
||||
virtual PRUint16 GetGradientType() { return SVG_LINEAR_GRADIENT; }
|
||||
|
||||
// nsIFrame interface:
|
||||
virtual nsIAtom* GetType() const; // frame type: nsGkAtoms::svgLinearGradientFrame
|
||||
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
#ifdef DEBUG
|
||||
// nsIFrameDebug interface:
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("SVGLinearGradient"), aResult);
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
protected:
|
||||
float GradientLookupAttribute(nsIAtom *aAtomName, PRUint16 aEnumName);
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Radial Gradients
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
typedef nsSVGGradientFrame nsSVGRadialGradientFrameBase;
|
||||
|
||||
class nsSVGRadialGradientFrame : public nsSVGRadialGradientFrameBase
|
||||
{
|
||||
public:
|
||||
nsSVGRadialGradientFrame(nsStyleContext* aContext) :
|
||||
nsSVGRadialGradientFrameBase(aContext) {}
|
||||
|
||||
void GetParameters(float *aCx, float *aCy, float *aR,
|
||||
float *aFx, float *aFy);
|
||||
|
||||
virtual PRUint16 GetGradientType() { return SVG_RADIAL_GRADIENT; }
|
||||
|
||||
// nsIFrame interface:
|
||||
virtual nsIAtom* GetType() const; // frame type: nsGkAtoms::svgRadialGradientFrame
|
||||
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
#ifdef DEBUG
|
||||
// nsIFrameDebug interface:
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("SVGRadialGradient"), aResult);
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
protected:
|
||||
float GradientLookupAttribute(nsIAtom *aAtomName, PRUint16 aEnumName,
|
||||
nsIContent *aElement = nsnull);
|
||||
};
|
||||
|
||||
|
||||
nsIFrame* NS_NewSVGLinearGradientFrame(nsIPresShell* aPresShell,
|
||||
nsIContent* aContent,
|
||||
|
@ -47,7 +47,6 @@ XPIDL_MODULE = gksvgrenderer
|
||||
XPIDLSRCS = \
|
||||
nsISVGGlyphGeometrySource.idl \
|
||||
nsISVGGlyphMetricsSource.idl \
|
||||
nsISVGGradient.idl \
|
||||
nsISVGPathGeometrySource.idl \
|
||||
nsISVGRectangleSink.idl \
|
||||
nsISVGRenderer.idl \
|
||||
|
@ -1,108 +0,0 @@
|
||||
/* -*- Mode: IDL; 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
|
||||
* Crocodile Clips Ltd.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Scooter Morris <scootermorris@comcast.net> (original author)
|
||||
*
|
||||
* 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 "nsISupports.idl"
|
||||
|
||||
%{C++
|
||||
#include "nsColor.h"
|
||||
%}
|
||||
|
||||
native nscolor(nscolor);
|
||||
|
||||
interface nsIDOMSVGMatrix;
|
||||
interface nsISVGLinearGradient;
|
||||
interface nsISVGRadialGradient;
|
||||
interface nsIFrame;
|
||||
interface nsSVGGeometryFrame;
|
||||
|
||||
/**
|
||||
* \addtogroup rendering_backend_interfaces Rendering Backend Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Describes the 'gradient' objects (either linear or a radial) to the
|
||||
* rendering backends.
|
||||
*
|
||||
* @nosubgrouping
|
||||
*/
|
||||
[uuid(9966f240-8515-4d60-a931-628b201524e1)]
|
||||
interface nsISVGGradient : nsISupports
|
||||
{
|
||||
const unsigned long SVG_UNKNOWN_GRADIENT = 0;
|
||||
const unsigned long SVG_LINEAR_GRADIENT = 1;
|
||||
const unsigned long SVG_RADIAL_GRADIENT = 2;
|
||||
|
||||
readonly attribute PRUint32 gradientType;
|
||||
readonly attribute PRUint16 spreadMethod;
|
||||
|
||||
void GetStopCount(out PRUint32 aStopCount);
|
||||
void GetStopOffset(in PRInt32 aIndex, out float aOffset);
|
||||
void GetStopColor(in PRInt32 aIndex, out nscolor aStopColor);
|
||||
void GetStopOpacity(in PRInt32 aIndex, out float aStopOpacity);
|
||||
void GetGradientTransform(out nsIDOMSVGMatrix retval,
|
||||
in nsSVGGeometryFrame aSource);
|
||||
/** @} */
|
||||
};
|
||||
|
||||
[uuid(995ad9e6-6bb1-47c5-b402-fc93ce12f5e7)]
|
||||
interface nsISVGLinearGradient : nsISupports
|
||||
{
|
||||
readonly attribute float X1;
|
||||
readonly attribute float X2;
|
||||
readonly attribute float Y1;
|
||||
readonly attribute float Y2;
|
||||
|
||||
/** @} */
|
||||
};
|
||||
|
||||
[uuid(446435ff-6699-4b4d-85c1-09c18145f5ce)]
|
||||
interface nsISVGRadialGradient : nsISupports
|
||||
{
|
||||
readonly attribute float Cx;
|
||||
readonly attribute float Cy;
|
||||
readonly attribute float R;
|
||||
readonly attribute float Fx;
|
||||
readonly attribute float Fy;
|
||||
|
||||
/** @} */
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
|
@ -67,6 +67,8 @@ REQUIRES = \
|
||||
layout \
|
||||
cairo \
|
||||
libpixman \
|
||||
js \
|
||||
webshell \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
@ -95,6 +97,7 @@ LOCAL_INCLUDES = \
|
||||
-I$(topsrcdir)/layout/svg/base/src \
|
||||
-I$(topsrcdir)/layout/xul/base/src \
|
||||
-I$(topsrcdir)/content/svg/content/src \
|
||||
-I$(topsrcdir)/content/base/src \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_ENABLE_GTK
|
||||
|
@ -56,7 +56,6 @@
|
||||
#include "nsMemory.h"
|
||||
#include <cairo.h>
|
||||
|
||||
#include "nsISVGGradient.h"
|
||||
#include "nsSVGCairoGradient.h"
|
||||
#include "nsISVGCairoSurface.h"
|
||||
#include "nsSVGCairoPattern.h"
|
||||
@ -247,7 +246,7 @@ nsSVGCairoGlyphGeometry::Render(nsSVGGlyphFrame *aSource,
|
||||
LOOP_CHARS(cairo_show_text)
|
||||
} else if (filltype == eStyleSVGPaintType_Server) {
|
||||
if (fillServerType == nsSVGGeometryFrame::PAINT_TYPE_GRADIENT) {
|
||||
nsISVGGradient *aGrad;
|
||||
nsSVGGradientFrame *aGrad;
|
||||
aSource->GetFillGradient(&aGrad);
|
||||
|
||||
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, aSource);
|
||||
@ -285,7 +284,7 @@ nsSVGCairoGlyphGeometry::Render(nsSVGGlyphFrame *aSource,
|
||||
cairo_stroke(ctx);
|
||||
} else if (stroketype == eStyleSVGPaintType_Server) {
|
||||
if (strokeServerType == nsSVGGeometryFrame::PAINT_TYPE_GRADIENT) {
|
||||
nsISVGGradient *aGrad;
|
||||
nsSVGGradientFrame *aGrad;
|
||||
aSource->GetStrokeGradient(&aGrad);
|
||||
|
||||
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, aSource);
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include "nsISVGPathGeometrySource.h"
|
||||
#include "nsSVGCairoGradient.h"
|
||||
#include "nsSVGGeometryFrame.h"
|
||||
#include "nsISVGGradient.h"
|
||||
#include "nsSVGGradientFrame.h"
|
||||
|
||||
static cairo_matrix_t SVGToMatrix(nsIDOMSVGMatrix *ctm)
|
||||
{
|
||||
@ -64,20 +64,17 @@ static cairo_matrix_t SVGToMatrix(nsIDOMSVGMatrix *ctm)
|
||||
|
||||
|
||||
static void
|
||||
CairoSetStops(cairo_pattern_t *aPattern, nsISVGGradient *aGrad, float aOpacity)
|
||||
CairoSetStops(cairo_pattern_t *aPattern,
|
||||
nsSVGGradientFrame *aGrad, float aOpacity)
|
||||
{
|
||||
PRUint32 nStops;
|
||||
PRUint32 nStops = aGrad->GetStopCount();
|
||||
float lastOffset = 0.0f;
|
||||
|
||||
aGrad->GetStopCount(&nStops);
|
||||
for (PRUint32 i = 0; i < nStops; i++) {
|
||||
float offset, opacity;
|
||||
nscolor rgba;
|
||||
float offset;
|
||||
float opacity;
|
||||
|
||||
aGrad->GetStopOffset(i, &offset);
|
||||
aGrad->GetStopColor(i, &rgba);
|
||||
aGrad->GetStopOpacity(i, &opacity);
|
||||
aGrad->GetStopInformation(i, &offset, &rgba, &opacity);
|
||||
|
||||
if (offset < lastOffset)
|
||||
offset = lastOffset;
|
||||
@ -94,40 +91,28 @@ CairoSetStops(cairo_pattern_t *aPattern, nsISVGGradient *aGrad, float aOpacity)
|
||||
|
||||
|
||||
static cairo_pattern_t *
|
||||
CairoLinearGradient(cairo_t *ctx, nsISVGGradient *aGrad)
|
||||
CairoLinearGradient(cairo_t *ctx, nsSVGGradientFrame *aGrad)
|
||||
{
|
||||
float fX1, fY1, fX2, fY2;
|
||||
|
||||
nsISVGLinearGradient *aLgrad;
|
||||
CallQueryInterface(aGrad, &aLgrad);
|
||||
NS_ASSERTION(aLgrad, "error gradient did not provide a Linear Gradient interface");
|
||||
nsSVGLinearGradientFrame *aLgrad =
|
||||
NS_STATIC_CAST(nsSVGLinearGradientFrame*, aGrad);
|
||||
|
||||
aLgrad->GetX1(&fX1);
|
||||
aLgrad->GetX2(&fX2);
|
||||
aLgrad->GetY1(&fY1);
|
||||
aLgrad->GetY2(&fY2);
|
||||
float x1, y1, x2, y2;
|
||||
aLgrad->GetParameters(&x1, &y1, &x2, &y2);
|
||||
|
||||
return cairo_pattern_create_linear(fX1, fY1, fX2, fY2);
|
||||
return cairo_pattern_create_linear(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
|
||||
static cairo_pattern_t *
|
||||
CairoRadialGradient(cairo_t *ctx, nsISVGGradient *aGrad)
|
||||
CairoRadialGradient(cairo_t *ctx, nsSVGGradientFrame *aGrad)
|
||||
{
|
||||
float fCx, fCy, fR, fFx, fFy;
|
||||
nsSVGRadialGradientFrame *aRgrad =
|
||||
NS_STATIC_CAST(nsSVGRadialGradientFrame*, aGrad);
|
||||
|
||||
// Get the Radial Gradient interface
|
||||
nsISVGRadialGradient *aRgrad;
|
||||
CallQueryInterface(aGrad, &aRgrad);
|
||||
NS_ASSERTION(aRgrad, "error gradient did not provide a Linear Gradient interface");
|
||||
float cx, cy, r, fx, fy;
|
||||
aRgrad->GetParameters(&cx, &cy, &r, &fx, &fy);
|
||||
|
||||
aRgrad->GetCx(&fCx);
|
||||
aRgrad->GetCy(&fCy);
|
||||
aRgrad->GetR(&fR);
|
||||
aRgrad->GetFx(&fFx);
|
||||
aRgrad->GetFy(&fFy);
|
||||
|
||||
if (fFx != fCx || fFy != fCy) {
|
||||
if (fx != cx || fy != cy) {
|
||||
// The focal point (fFx and fFy) must be clamped to be *inside* - not on -
|
||||
// the circumference of the gradient or we'll get rendering anomalies. We
|
||||
// calculate the distance from the focal point to the gradient center and
|
||||
@ -135,23 +120,23 @@ CairoRadialGradient(cairo_t *ctx, nsISVGGradient *aGrad)
|
||||
// factor of the radius because it's close enough to 1 that we won't get a
|
||||
// fringe at the edge of the gradient if we clamp, but not so close to 1
|
||||
// that rounding error will give us the same results as using fR itself.
|
||||
double dMax = 0.999 * fR;
|
||||
float dx = fFx - fCx;
|
||||
float dy = fFy - fCy;
|
||||
double dMax = 0.999 * r;
|
||||
float dx = fx - cx;
|
||||
float dy = fy - cy;
|
||||
double d = sqrt((dx * dx) + (dy * dy));
|
||||
if (d > dMax) {
|
||||
double angle = atan2(dy, dx);
|
||||
fFx = (float)(dMax * cos(angle)) + fCx;
|
||||
fFy = (float)(dMax * sin(angle)) + fCy;
|
||||
fx = (float)(dMax * cos(angle)) + cx;
|
||||
fy = (float)(dMax * sin(angle)) + cy;
|
||||
}
|
||||
}
|
||||
|
||||
return cairo_pattern_create_radial(fFx, fFy, 0, fCx, fCy, fR);
|
||||
return cairo_pattern_create_radial(fx, fy, 0, cx, cy, r);
|
||||
}
|
||||
|
||||
|
||||
cairo_pattern_t *
|
||||
CairoGradient(cairo_t *ctx, nsISVGGradient *aGrad,
|
||||
CairoGradient(cairo_t *ctx, nsSVGGradientFrame *aGrad,
|
||||
nsSVGGeometryFrame *aSource)
|
||||
{
|
||||
NS_ASSERTION(aGrad, "Called CairoGradient without a gradient!");
|
||||
@ -162,6 +147,8 @@ CairoGradient(cairo_t *ctx, nsISVGGradient *aGrad,
|
||||
nsCOMPtr<nsIDOMSVGMatrix> svgMatrix;
|
||||
aGrad->GetGradientTransform(getter_AddRefs(svgMatrix), aSource);
|
||||
NS_ASSERTION(svgMatrix, "CairoGradient: GetGradientTransform returns null");
|
||||
if (!svgMatrix)
|
||||
return nsnull;
|
||||
|
||||
cairo_matrix_t patternMatrix = SVGToMatrix(svgMatrix);
|
||||
if (cairo_matrix_invert(&patternMatrix)) {
|
||||
@ -171,17 +158,15 @@ CairoGradient(cairo_t *ctx, nsISVGGradient *aGrad,
|
||||
cairo_pattern_t *gradient;
|
||||
|
||||
// Linear or Radial?
|
||||
PRUint32 type;
|
||||
aGrad->GetGradientType(&type);
|
||||
if (type == nsISVGGradient::SVG_LINEAR_GRADIENT)
|
||||
PRUint16 type = aGrad->GetGradientType();
|
||||
if (type == nsSVGGradientFrame::SVG_LINEAR_GRADIENT)
|
||||
gradient = CairoLinearGradient(ctx, aGrad);
|
||||
else if (type == nsISVGGradient::SVG_RADIAL_GRADIENT)
|
||||
else if (type == nsSVGGradientFrame::SVG_RADIAL_GRADIENT)
|
||||
gradient = CairoRadialGradient(ctx, aGrad);
|
||||
else
|
||||
return nsnull; // Shouldn't happen
|
||||
|
||||
PRUint16 aSpread;
|
||||
aGrad->GetSpreadMethod(&aSpread);
|
||||
PRUint16 aSpread = aGrad->GetSpreadMethod();
|
||||
if (aSpread == nsIDOMSVGGradientElement::SVG_SPREADMETHOD_PAD)
|
||||
cairo_pattern_set_extend(gradient, CAIRO_EXTEND_PAD);
|
||||
else if (aSpread == nsIDOMSVGGradientElement::SVG_SPREADMETHOD_REFLECT)
|
||||
|
@ -44,12 +44,12 @@
|
||||
|
||||
#include "cairo.h"
|
||||
|
||||
class nsISVGGradient;
|
||||
class nsSVGGradientFrame;
|
||||
class nsSVGGeometryFrame;
|
||||
|
||||
cairo_pattern_t *
|
||||
CairoGradient(cairo_t *ctx,
|
||||
nsISVGGradient *aGrad,
|
||||
nsSVGGradientFrame *aGrad,
|
||||
nsSVGGeometryFrame *aSource);
|
||||
|
||||
#endif
|
||||
|
@ -52,7 +52,6 @@
|
||||
#include <float.h>
|
||||
#include <cairo.h>
|
||||
#include "nsSVGCairoRegion.h"
|
||||
#include "nsISVGGradient.h"
|
||||
#include "nsSVGCairoGradient.h"
|
||||
#include "nsISVGCairoSurface.h"
|
||||
#include "nsSVGCairoPattern.h"
|
||||
@ -250,7 +249,7 @@ nsSVGCairoPathGeometry::Render(nsSVGPathGeometryFrame *aSource,
|
||||
cairo_fill_preserve(ctx);
|
||||
} else if (fillType == eStyleSVGPaintType_Server) {
|
||||
if (fillServerType == nsSVGGeometryFrame::PAINT_TYPE_GRADIENT) {
|
||||
nsISVGGradient *aGrad;
|
||||
nsSVGGradientFrame *aGrad;
|
||||
aSource->GetFillGradient(&aGrad);
|
||||
|
||||
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, aSource);
|
||||
@ -287,7 +286,7 @@ nsSVGCairoPathGeometry::Render(nsSVGPathGeometryFrame *aSource,
|
||||
cairo_stroke(ctx);
|
||||
} else if (strokeType == eStyleSVGPaintType_Server) {
|
||||
if (strokeServerType == nsSVGGeometryFrame::PAINT_TYPE_GRADIENT) {
|
||||
nsISVGGradient *aGrad;
|
||||
nsSVGGradientFrame *aGrad;
|
||||
aSource->GetStrokeGradient(&aGrad);
|
||||
|
||||
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, aSource);
|
||||
|
Loading…
x
Reference in New Issue
Block a user