Bug 397749 - New style nsSVGAngle. r=tor,sr+a=roc,a=mconnor

This commit is contained in:
longsonr@gmail.com 2007-10-05 02:11:00 -07:00
Родитель 71db48272f
Коммит dc5258eb9d
12 изменённых файлов: 523 добавлений и 648 удалений

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

@ -71,7 +71,6 @@ CPPSRCS = \
nsDOMSVGEvent.cpp \
nsSVGAElement.cpp \
nsSVGAngle.cpp \
nsSVGAnimatedAngle.cpp \
nsSVGAnimatedLengthList.cpp \
nsSVGAnimatedNumberList.cpp \
nsSVGAnimatedRect.cpp \

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

@ -36,273 +36,170 @@
#include "nsSVGAngle.h"
#include "prdtoa.h"
#include "nsGkAtoms.h"
#include "nsSVGValue.h"
#include "nsReadableUtils.h"
#include "nsTextFormatter.h"
#include "nsCRT.h"
#include "nsIDOMSVGNumber.h"
#include "nsISVGValueUtils.h"
#include "nsWeakReference.h"
#include "nsContentUtils.h"
#include "nsSVGUtils.h"
#include <math.h>
////////////////////////////////////////////////////////////////////////
// nsSVGAngle class
class nsSVGAngle : public nsIDOMSVGAngle,
public nsSVGValue,
public nsISVGValueObserver
class DOMSVGAngle : public nsIDOMSVGAngle
{
protected:
friend nsresult NS_NewSVGAngle(nsIDOMSVGAngle** result,
float value,
PRUint16 unit);
friend nsresult NS_NewSVGAngle(nsIDOMSVGAngle** result,
const nsAString &value);
nsSVGAngle(float value, PRUint16 unit);
nsSVGAngle();
public:
// nsISupports interface:
NS_DECL_ISUPPORTS
// nsIDOMSVGAngle interface:
NS_DECL_NSIDOMSVGANGLE
DOMSVGAngle()
{ mVal.Init(); }
// nsISVGValue interface:
NS_IMETHOD SetValueString(const nsAString& aValue);
NS_IMETHOD GetValueString(nsAString& aValue);
NS_IMETHOD GetUnitType(PRUint16* aResult)
{ *aResult = mVal.mSpecifiedUnitType; return NS_OK; }
// nsISVGValueObserver interface:
NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable,
modificationType aModType);
NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable,
modificationType aModType);
NS_IMETHOD GetValue(float* aResult)
{ *aResult = mVal.GetBaseValue(); return NS_OK; }
NS_IMETHOD SetValue(float aValue)
{ mVal.SetBaseValue(aValue, nsnull); return NS_OK; }
// nsISupportsWeakReference
// implementation inherited from nsSupportsWeakReference
NS_IMETHOD GetValueInSpecifiedUnits(float* aResult)
{ *aResult = mVal.mBaseVal; return NS_OK; }
NS_IMETHOD SetValueInSpecifiedUnits(float aValue)
{ mVal.mBaseVal = aValue; return NS_OK; }
protected:
// implementation helpers:
void GetUnitString(nsAString& unit);
PRUint16 GetUnitTypeForString(const char* unitStr);
PRBool IsValidUnitType(PRUint16 unit);
NS_IMETHOD SetValueAsString(const nsAString& aValue)
{ return mVal.SetBaseValueString(aValue, nsnull, PR_FALSE); }
NS_IMETHOD GetValueAsString(nsAString& aValue)
{ mVal.GetBaseValueString(aValue); return NS_OK; }
float mValueInSpecifiedUnits;
PRUint8 mSpecifiedUnitType;
NS_IMETHOD NewValueSpecifiedUnits(PRUint16 unitType,
float valueInSpecifiedUnits)
{ mVal.NewValueSpecifiedUnits(unitType, valueInSpecifiedUnits, nsnull);
return NS_OK; }
NS_IMETHOD ConvertToSpecifiedUnits(PRUint16 unitType)
{ mVal.ConvertToSpecifiedUnits(unitType, nsnull); return NS_OK; }
private:
nsSVGAngle mVal;
};
NS_IMPL_ADDREF(nsSVGAngle::DOMBaseVal)
NS_IMPL_RELEASE(nsSVGAngle::DOMBaseVal)
//----------------------------------------------------------------------
// Implementation
NS_IMPL_ADDREF(nsSVGAngle::DOMAnimVal)
NS_IMPL_RELEASE(nsSVGAngle::DOMAnimVal)
nsresult
NS_NewSVGAngle(nsIDOMSVGAngle** result,
float value,
PRUint16 unit)
{
nsSVGAngle *pl = new nsSVGAngle(value, unit);
NS_ENSURE_TRUE(pl, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(pl);
*result = pl;
return NS_OK;
}
NS_IMPL_ADDREF(nsSVGAngle::DOMAnimatedAngle)
NS_IMPL_RELEASE(nsSVGAngle::DOMAnimatedAngle)
nsresult
NS_NewSVGAngle(nsIDOMSVGAngle** result,
const nsAString &value)
{
*result = nsnull;
nsSVGAngle *pl = new nsSVGAngle();
NS_ENSURE_TRUE(pl, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(pl);
if (NS_FAILED(pl->SetValueAsString(value))) {
NS_RELEASE(pl);
return NS_ERROR_FAILURE;
}
*result = pl;
return NS_OK;
}
NS_IMPL_ADDREF(DOMSVGAngle)
NS_IMPL_RELEASE(DOMSVGAngle)
nsSVGAngle::nsSVGAngle(float value,
PRUint16 unit)
: mValueInSpecifiedUnits(value)
{
NS_ASSERTION(unit == SVG_ANGLETYPE_UNKNOWN || IsValidUnitType(unit), "unknown unit");
mSpecifiedUnitType = unit;
}
nsSVGAngle::nsSVGAngle()
{
}
//----------------------------------------------------------------------
// nsISupports methods:
NS_IMPL_ADDREF(nsSVGAngle)
NS_IMPL_RELEASE(nsSVGAngle)
NS_INTERFACE_MAP_BEGIN(nsSVGAngle)
NS_INTERFACE_MAP_ENTRY(nsISVGValue)
NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver)
NS_INTERFACE_MAP_BEGIN(nsSVGAngle::DOMBaseVal)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAngle)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGAngle)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISVGValue)
NS_INTERFACE_MAP_END
//----------------------------------------------------------------------
// nsISVGValue methods:
NS_IMETHODIMP
nsSVGAngle::SetValueString(const nsAString& aValue)
NS_INTERFACE_MAP_BEGIN(nsSVGAngle::DOMAnimVal)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAngle)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGAngle)
NS_INTERFACE_MAP_END
NS_INTERFACE_MAP_BEGIN(nsSVGAngle::DOMAnimatedAngle)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedAngle)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGAnimatedAngle)
NS_INTERFACE_MAP_END
NS_INTERFACE_MAP_BEGIN(DOMSVGAngle)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAngle)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGAngle)
NS_INTERFACE_MAP_END
static nsIAtom** const unitMap[] =
{
return SetValueAsString(aValue);
nsnull, /* SVG_ANGLETYPE_UNKNOWN */
nsnull, /* SVG_ANGLETYPE_UNSPECIFIED */
&nsGkAtoms::deg,
&nsGkAtoms::rad,
&nsGkAtoms::grad
};
/* Helper functions */
static PRBool
IsValidUnitType(PRUint16 unit)
{
if (unit > nsIDOMSVGAngle::SVG_ANGLETYPE_UNKNOWN &&
unit <= nsIDOMSVGAngle::SVG_ANGLETYPE_GRAD)
return PR_TRUE;
return PR_FALSE;
}
NS_IMETHODIMP
nsSVGAngle::GetValueString(nsAString& aValue)
static void
GetUnitString(nsAString& unit, PRUint16 unitType)
{
return GetValueAsString(aValue);
}
//----------------------------------------------------------------------
// nsISVGValueObserver methods
NS_IMETHODIMP
nsSVGAngle::WillModifySVGObservable(nsISVGValue* observable,
modificationType aModType)
{
WillModify(aModType);
return NS_OK;
}
NS_IMETHODIMP
nsSVGAngle::DidModifySVGObservable(nsISVGValue* observable,
modificationType aModType)
{
DidModify(aModType);
return NS_OK;
}
//----------------------------------------------------------------------
// nsIDOMSVGAngle methods:
/* readonly attribute unsigned short unitType; */
NS_IMETHODIMP
nsSVGAngle::GetUnitType(PRUint16 *aUnitType)
{
*aUnitType = mSpecifiedUnitType;
return NS_OK;
}
/* attribute float value; */
NS_IMETHODIMP
nsSVGAngle::GetValue(float *aValue)
{
nsresult rv = NS_OK;
switch (mSpecifiedUnitType) {
case SVG_ANGLETYPE_UNSPECIFIED:
case SVG_ANGLETYPE_DEG:
*aValue = float((mValueInSpecifiedUnits * M_PI) / 180.0);
break;
case SVG_ANGLETYPE_RAD:
*aValue = mValueInSpecifiedUnits;
break;
case SVG_ANGLETYPE_GRAD:
*aValue = float((mValueInSpecifiedUnits * M_PI) / 100.0);
break;
default:
rv = NS_ERROR_FAILURE;
break;
}
return rv;
}
NS_IMETHODIMP
nsSVGAngle::SetValue(float aValue)
{
nsresult rv;
switch (mSpecifiedUnitType) {
case SVG_ANGLETYPE_UNSPECIFIED:
case SVG_ANGLETYPE_DEG:
rv = SetValueInSpecifiedUnits(float((aValue * 180.0) / M_PI));
break;
case SVG_ANGLETYPE_RAD:
rv = SetValueInSpecifiedUnits(aValue);
break;
case SVG_ANGLETYPE_GRAD:
rv = SetValueInSpecifiedUnits(float((aValue * 100.0) / M_PI));
break;
default:
rv = NS_ERROR_FAILURE;
break;
if (IsValidUnitType(unitType)) {
if (unitMap[unitType]) {
(*unitMap[unitType])->ToString(unit);
}
return;
}
return rv;
NS_NOTREACHED("Unknown unit type");
return;
}
/* attribute float valueInSpecifiedUnits; */
NS_IMETHODIMP
nsSVGAngle::GetValueInSpecifiedUnits(float *aValueInSpecifiedUnits)
static PRUint16
GetUnitTypeForString(const char* unitStr)
{
*aValueInSpecifiedUnits = mValueInSpecifiedUnits;
return NS_OK;
if (!unitStr || *unitStr == '\0')
return nsIDOMSVGAngle::SVG_ANGLETYPE_UNSPECIFIED;
nsCOMPtr<nsIAtom> unitAtom = do_GetAtom(unitStr);
for (int i = 0 ; i < NS_ARRAY_LENGTH(unitMap) ; i++) {
if (unitMap[i] && *unitMap[i] == unitAtom) {
return i;
}
}
return nsIDOMSVGAngle::SVG_ANGLETYPE_UNKNOWN;
}
NS_IMETHODIMP
nsSVGAngle::SetValueInSpecifiedUnits(float aValueInSpecifiedUnits)
{
WillModify();
mValueInSpecifiedUnits = aValueInSpecifiedUnits;
DidModify();
return NS_OK;
}
/* attribute DOMString valueAsString; */
NS_IMETHODIMP
nsSVGAngle::GetValueAsString(nsAString & aValueAsString)
static void
GetValueString(nsAString &aValueAsString, float aValue, PRUint16 aUnitType)
{
PRUnichar buf[24];
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
NS_LITERAL_STRING("%g").get(),
(double)mValueInSpecifiedUnits);
(double)aValue);
aValueAsString.Assign(buf);
nsAutoString unitString;
GetUnitString(unitString);
GetUnitString(unitString, aUnitType);
aValueAsString.Append(unitString);
return NS_OK;
}
NS_IMETHODIMP
nsSVGAngle::SetValueAsString(const nsAString & aValueAsString)
static nsresult
GetValueFromString(const nsAString &aValueAsString,
float *aValue,
PRUint16 *aUnitType)
{
nsresult rv = NS_OK;
char *str = ToNewCString(aValueAsString);
if (!str)
return NS_ERROR_OUT_OF_MEMORY;
char* number = str;
while (*number && isspace(*number))
++number;
nsresult rv = NS_ERROR_FAILURE;
if (*number) {
if (*str) {
char *rest;
double value = PR_strtod(number, &rest);
if (rest!=number) {
PRUint16 unitType = GetUnitTypeForString(nsCRT::strtok(rest, "\x20\x9\xD\xA", &rest));
rv = NewValueSpecifiedUnits(unitType, (float)value);
}
else { // parse error
// no number
rv = NS_ERROR_FAILURE;
*aValue = static_cast<float>(PR_strtod(str, &rest));
if (rest != str) {
*aUnitType = GetUnitTypeForString(nsCRT::strtok(rest,
"\x20\x9\xD\xA",
&rest));
if (IsValidUnitType(*aUnitType)) {
rv = NS_OK;
}
}
}
@ -311,85 +208,142 @@ nsSVGAngle::SetValueAsString(const nsAString & aValueAsString)
return rv;
}
/* void newValueSpecifiedUnits (in unsigned short unitType, in float valueInSpecifiedUnits); */
NS_IMETHODIMP
nsSVGAngle::NewValueSpecifiedUnits(PRUint16 unitType, float valueInSpecifiedUnits)
float
nsSVGAngle::GetUnitScaleFactor() const
{
if (!IsValidUnitType(unitType)) return NS_ERROR_FAILURE;
WillModify();
mValueInSpecifiedUnits = valueInSpecifiedUnits;
mSpecifiedUnitType = unitType;
DidModify();
return NS_OK;
}
/* void convertToSpecifiedUnits (in unsigned short unitType); */
NS_IMETHODIMP
nsSVGAngle::ConvertToSpecifiedUnits(PRUint16 unitType)
{
if (!IsValidUnitType(unitType)) return NS_ERROR_FAILURE;
float valueInUserUnits;
GetValue(&valueInUserUnits);
mSpecifiedUnitType = unitType;
SetValue(valueInUserUnits);
return NS_OK;
}
//----------------------------------------------------------------------
// Implementation helpers:
void nsSVGAngle::GetUnitString(nsAString& unit)
{
nsIAtom* UnitAtom = nsnull;
switch (mSpecifiedUnitType) {
case SVG_ANGLETYPE_UNSPECIFIED:
UnitAtom = nsnull;
break;
case SVG_ANGLETYPE_DEG:
UnitAtom = nsGkAtoms::deg;
break;
case SVG_ANGLETYPE_GRAD:
UnitAtom = nsGkAtoms::grad;
break;
case SVG_ANGLETYPE_RAD:
UnitAtom = nsGkAtoms::rad;
break;
case nsIDOMSVGAngle::SVG_ANGLETYPE_UNSPECIFIED:
case nsIDOMSVGAngle::SVG_ANGLETYPE_DEG:
return static_cast<float>(180.0 / M_PI);
case nsIDOMSVGAngle::SVG_ANGLETYPE_RAD:
return 1;
case nsIDOMSVGAngle::SVG_ANGLETYPE_GRAD:
return static_cast<float>(100.0 / M_PI);
default:
NS_ASSERTION(PR_FALSE, "unknown unit");
break;
NS_NOTREACHED("Unknown unit type");
return 0;
}
if (!UnitAtom) return;
UnitAtom->ToString(unit);
}
PRUint16 nsSVGAngle::GetUnitTypeForString(const char* unitStr)
void
nsSVGAngle::SetBaseValueInSpecifiedUnits(float aValue,
nsSVGElement *aSVGElement)
{
if (!unitStr || *unitStr=='\0') return SVG_ANGLETYPE_UNSPECIFIED;
nsCOMPtr<nsIAtom> unitAtom = do_GetAtom(unitStr);
if (unitAtom == nsGkAtoms::deg)
return SVG_ANGLETYPE_DEG;
else if (unitAtom == nsGkAtoms::grad)
return SVG_ANGLETYPE_GRAD;
else if (unitAtom == nsGkAtoms::rad)
return SVG_ANGLETYPE_RAD;
return SVG_ANGLETYPE_UNKNOWN;
mBaseVal = aValue;
aSVGElement->DidChangeAngle(mAttrEnum, PR_TRUE);
}
PRBool nsSVGAngle::IsValidUnitType(PRUint16 unit)
void
nsSVGAngle::ConvertToSpecifiedUnits(PRUint16 unitType,
nsSVGElement *aSVGElement)
{
if (unit > SVG_ANGLETYPE_UNKNOWN && unit <= SVG_ANGLETYPE_GRAD)
return PR_TRUE;
if (!IsValidUnitType(unitType))
return;
return PR_FALSE;
float valueInUserUnits = mBaseVal / GetUnitScaleFactor();
mSpecifiedUnitType = PRUint8(unitType);
SetBaseValue(valueInUserUnits, aSVGElement);
}
void
nsSVGAngle::NewValueSpecifiedUnits(PRUint16 unitType,
float valueInSpecifiedUnits,
nsSVGElement *aSVGElement)
{
if (!IsValidUnitType(unitType))
return;
mBaseVal = mAnimVal = valueInSpecifiedUnits;
mSpecifiedUnitType = PRUint8(unitType);
if (aSVGElement) {
aSVGElement->DidChangeAngle(mAttrEnum, PR_TRUE);
}
}
nsresult
nsSVGAngle::ToDOMBaseVal(nsIDOMSVGAngle **aResult, nsSVGElement *aSVGElement)
{
*aResult = new DOMBaseVal(this, aSVGElement);
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}
nsresult
nsSVGAngle::ToDOMAnimVal(nsIDOMSVGAngle **aResult, nsSVGElement *aSVGElement)
{
*aResult = new DOMAnimVal(this, aSVGElement);
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}
/* Implementation */
nsresult
nsSVGAngle::SetBaseValueString(const nsAString &aValueAsString,
nsSVGElement *aSVGElement,
PRBool aDoSetAttr)
{
float value;
PRUint16 unitType;
nsresult rv = GetValueFromString(aValueAsString, &value, &unitType);
NS_ENSURE_SUCCESS(rv, rv);
mBaseVal = mAnimVal = value;
mSpecifiedUnitType = PRUint8(unitType);
if (aSVGElement) {
aSVGElement->DidChangeAngle(mAttrEnum, aDoSetAttr);
}
return NS_OK;
}
void
nsSVGAngle::GetBaseValueString(nsAString & aValueAsString)
{
GetValueString(aValueAsString, mBaseVal, mSpecifiedUnitType);
}
void
nsSVGAngle::GetAnimValueString(nsAString & aValueAsString)
{
GetValueString(aValueAsString, mAnimVal, mSpecifiedUnitType);
}
void
nsSVGAngle::SetBaseValue(float aValue, nsSVGElement *aSVGElement)
{
mAnimVal = mBaseVal = aValue * GetUnitScaleFactor();
if (aSVGElement) {
aSVGElement->DidChangeAngle(mAttrEnum, PR_TRUE);
}
}
nsresult
nsSVGAngle::ToDOMAnimatedAngle(nsIDOMSVGAnimatedAngle **aResult,
nsSVGElement *aSVGElement)
{
*aResult = new DOMAnimatedAngle(this, aSVGElement);
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}
nsresult
NS_NewDOMSVGAngle(nsIDOMSVGAngle** aResult)
{
*aResult = new DOMSVGAngle;
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}

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

@ -38,15 +38,153 @@
#define __NS_SVGANGLE_H__
#include "nsIDOMSVGAngle.h"
#include "nsAString.h"
#include "nsIDOMSVGAnimatedAngle.h"
#include "nsSVGElement.h"
#include "nsDOMError.h"
class nsSVGAngle
{
friend class DOMSVGAngle;
public:
void Init(PRUint8 aAttrEnum = 0xff,
float aValue = 0,
PRUint8 aUnitType = nsIDOMSVGAngle::SVG_ANGLETYPE_UNSPECIFIED) {
mAnimVal = mBaseVal = aValue;
mSpecifiedUnitType = aUnitType;
mAttrEnum = aAttrEnum;
}
nsresult SetBaseValueString(const nsAString& aValue,
nsSVGElement *aSVGElement,
PRBool aDoSetAttr);
void GetBaseValueString(nsAString& aValue);
void GetAnimValueString(nsAString& aValue);
float GetBaseValue() const
{ return mBaseVal / GetUnitScaleFactor(); }
float GetAnimValue() const
{ return mAnimVal / GetUnitScaleFactor(); }
void SetBaseValue(float aValue, nsSVGElement *aSVGElement);
PRUint8 GetSpecifiedUnitType() const { return mSpecifiedUnitType; }
float GetAnimValInSpecifiedUnits() const { return mAnimVal; }
float GetBaseValInSpecifiedUnits() const { return mBaseVal; }
static nsresult ToDOMSVGAngle(nsIDOMSVGAngle **aResult);
nsresult ToDOMAnimatedAngle(nsIDOMSVGAnimatedAngle **aResult,
nsSVGElement* aSVGElement);
private:
float mAnimVal;
float mBaseVal;
PRUint8 mSpecifiedUnitType;
PRUint8 mAttrEnum; // element specified tracking for attribute
float GetUnitScaleFactor() const;
void SetBaseValueInSpecifiedUnits(float aValue, nsSVGElement *aSVGElement);
void NewValueSpecifiedUnits(PRUint16 aUnitType, float aValue,
nsSVGElement *aSVGElement);
void ConvertToSpecifiedUnits(PRUint16 aUnitType, nsSVGElement *aSVGElement);
nsresult ToDOMBaseVal(nsIDOMSVGAngle **aResult, nsSVGElement* aSVGElement);
nsresult ToDOMAnimVal(nsIDOMSVGAngle **aResult, nsSVGElement* aSVGElement);
struct DOMBaseVal : public nsIDOMSVGAngle
{
NS_DECL_ISUPPORTS
DOMBaseVal(nsSVGAngle* aVal, nsSVGElement *aSVGElement)
: mVal(aVal), mSVGElement(aSVGElement) {}
nsSVGAngle* mVal; // kept alive because it belongs to mSVGElement
nsRefPtr<nsSVGElement> mSVGElement;
NS_IMETHOD GetUnitType(PRUint16* aResult)
{ *aResult = mVal->mSpecifiedUnitType; return NS_OK; }
NS_IMETHOD GetValue(float* aResult)
{ *aResult = mVal->GetBaseValue(); return NS_OK; }
NS_IMETHOD SetValue(float aValue)
{ mVal->SetBaseValue(aValue, mSVGElement); return NS_OK; }
NS_IMETHOD GetValueInSpecifiedUnits(float* aResult)
{ *aResult = mVal->mBaseVal; return NS_OK; }
NS_IMETHOD SetValueInSpecifiedUnits(float aValue)
{ mVal->SetBaseValueInSpecifiedUnits(aValue, mSVGElement);
return NS_OK; }
NS_IMETHOD SetValueAsString(const nsAString& aValue)
{ return mVal->SetBaseValueString(aValue, mSVGElement, PR_TRUE); }
NS_IMETHOD GetValueAsString(nsAString& aValue)
{ mVal->GetBaseValueString(aValue); return NS_OK; }
NS_IMETHOD NewValueSpecifiedUnits(PRUint16 unitType,
float valueInSpecifiedUnits)
{ mVal->NewValueSpecifiedUnits(unitType, valueInSpecifiedUnits,
mSVGElement);
return NS_OK; }
NS_IMETHOD ConvertToSpecifiedUnits(PRUint16 unitType)
{ mVal->ConvertToSpecifiedUnits(unitType, mSVGElement); return NS_OK; }
};
struct DOMAnimVal : public nsIDOMSVGAngle
{
NS_DECL_ISUPPORTS
DOMAnimVal(nsSVGAngle* aVal, nsSVGElement *aSVGElement)
: mVal(aVal), mSVGElement(aSVGElement) {}
nsSVGAngle* mVal; // kept alive because it belongs to mSVGElement
nsRefPtr<nsSVGElement> mSVGElement;
NS_IMETHOD GetUnitType(PRUint16* aResult)
{ *aResult = mVal->mSpecifiedUnitType; return NS_OK; }
NS_IMETHOD GetValue(float* aResult)
{ *aResult = mVal->GetAnimValue(); return NS_OK; }
NS_IMETHOD SetValue(float aValue)
{ return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; }
NS_IMETHOD GetValueInSpecifiedUnits(float* aResult)
{ *aResult = mVal->mAnimVal; return NS_OK; }
NS_IMETHOD SetValueInSpecifiedUnits(float aValue)
{ return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; }
NS_IMETHOD SetValueAsString(const nsAString& aValue)
{ return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; }
NS_IMETHOD GetValueAsString(nsAString& aValue)
{ mVal->GetAnimValueString(aValue); return NS_OK; }
NS_IMETHOD NewValueSpecifiedUnits(PRUint16 unitType,
float valueInSpecifiedUnits)
{ return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; }
NS_IMETHOD ConvertToSpecifiedUnits(PRUint16 unitType)
{ return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; }
};
struct DOMAnimatedAngle : public nsIDOMSVGAnimatedAngle
{
NS_DECL_ISUPPORTS
DOMAnimatedAngle(nsSVGAngle* aVal, nsSVGElement *aSVGElement)
: mVal(aVal), mSVGElement(aSVGElement) {}
nsSVGAngle* mVal; // kept alive because it belongs to content
nsRefPtr<nsSVGElement> mSVGElement;
NS_IMETHOD GetBaseVal(nsIDOMSVGAngle **aBaseVal)
{ return mVal->ToDOMBaseVal(aBaseVal, mSVGElement); }
NS_IMETHOD GetAnimVal(nsIDOMSVGAngle **aAnimVal)
{ return mVal->ToDOMAnimVal(aAnimVal, mSVGElement); }
};
};
nsresult
NS_NewSVGAngle(nsIDOMSVGAngle** result,
float value=0.0f,
PRUint16 unit=nsIDOMSVGAngle::SVG_ANGLETYPE_UNSPECIFIED);
nsresult
NS_NewSVGAngle(nsIDOMSVGAngle** result,
const nsAString &value);
NS_NewDOMSVGAngle(nsIDOMSVGAngle** result);
#endif //__NS_SVGANGLE_H__

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

@ -1,201 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla SVG project.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of 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 "nsSVGValue.h"
#include "nsWeakReference.h"
#include "nsSVGAnimatedAngle.h"
#include "nsSVGLength.h"
#include "nsContentUtils.h"
////////////////////////////////////////////////////////////////////////
// nsSVGAnimatedAngle
class nsSVGAnimatedAngle : public nsIDOMSVGAnimatedAngle,
public nsSVGValue,
public nsISVGValueObserver
{
protected:
friend nsresult NS_NewSVGAnimatedAngle(nsIDOMSVGAnimatedAngle** result,
nsIDOMSVGAngle* baseVal);
nsSVGAnimatedAngle();
~nsSVGAnimatedAngle();
void Init(nsIDOMSVGAngle* baseVal);
public:
// nsISupports interface:
NS_DECL_ISUPPORTS
// nsIDOMSVGAnimatedAngle interface:
NS_DECL_NSIDOMSVGANIMATEDANGLE
// remainder of nsISVGValue interface:
NS_IMETHOD SetValueString(const nsAString& aValue);
NS_IMETHOD GetValueString(nsAString& aValue);
// nsISVGValueObserver
NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable,
modificationType aModType);
NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable,
modificationType aModType);
// nsISupportsWeakReference
// implementation inherited from nsSupportsWeakReference
protected:
nsCOMPtr<nsIDOMSVGAngle> mBaseVal;
};
//----------------------------------------------------------------------
// Implementation
nsSVGAnimatedAngle::nsSVGAnimatedAngle()
{
}
nsSVGAnimatedAngle::~nsSVGAnimatedAngle()
{
if (!mBaseVal) return;
nsCOMPtr<nsISVGValue> val = do_QueryInterface(mBaseVal);
if (!val) return;
val->RemoveObserver(this);
}
void
nsSVGAnimatedAngle::Init(nsIDOMSVGAngle* baseVal)
{
mBaseVal = baseVal;
if (!mBaseVal) return;
nsCOMPtr<nsISVGValue> val = do_QueryInterface(mBaseVal);
NS_ASSERTION(val, "baseval needs to implement nsISVGValue interface");
if (!val) return;
val->AddObserver(this);
}
//----------------------------------------------------------------------
// nsISupports methods:
NS_IMPL_ADDREF(nsSVGAnimatedAngle)
NS_IMPL_RELEASE(nsSVGAnimatedAngle)
NS_INTERFACE_MAP_BEGIN(nsSVGAnimatedAngle)
NS_INTERFACE_MAP_ENTRY(nsISVGValue)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedAngle)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGAnimatedAngle)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISVGValue)
NS_INTERFACE_MAP_END
//----------------------------------------------------------------------
// nsISVGValue methods:
NS_IMETHODIMP
nsSVGAnimatedAngle::SetValueString(const nsAString& aValue)
{
nsCOMPtr<nsISVGValue> value = do_QueryInterface(mBaseVal);
return value->SetValueString(aValue);
}
NS_IMETHODIMP
nsSVGAnimatedAngle::GetValueString(nsAString& aValue)
{
nsCOMPtr<nsISVGValue> value = do_QueryInterface(mBaseVal);
return value->GetValueString(aValue);
}
//----------------------------------------------------------------------
// nsIDOMSVGAnimatedAngle methods:
/* readonly attribute nsIDOMSVGAngle baseVal; */
NS_IMETHODIMP
nsSVGAnimatedAngle::GetBaseVal(nsIDOMSVGAngle * *aBaseVal)
{
*aBaseVal = mBaseVal;
NS_ADDREF(*aBaseVal);
return NS_OK;
}
/* readonly attribute nsIDOMSVGAngle animVal; */
NS_IMETHODIMP
nsSVGAnimatedAngle::GetAnimVal(nsIDOMSVGAngle * *aAnimVal)
{
*aAnimVal = mBaseVal;
NS_ADDREF(*aAnimVal);
return NS_OK;
}
//----------------------------------------------------------------------
// nsISVGValueObserver methods
NS_IMETHODIMP
nsSVGAnimatedAngle::WillModifySVGObservable(nsISVGValue* observable,
modificationType aModType)
{
WillModify(aModType);
return NS_OK;
}
NS_IMETHODIMP
nsSVGAnimatedAngle::DidModifySVGObservable (nsISVGValue* observable,
modificationType aModType)
{
DidModify(aModType);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
// Exported creation functions
nsresult
NS_NewSVGAnimatedAngle(nsIDOMSVGAnimatedAngle** aResult,
nsIDOMSVGAngle* baseVal)
{
*aResult = nsnull;
nsSVGAnimatedAngle* animatedLength = new nsSVGAnimatedAngle();
if(!animatedLength) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(animatedLength);
animatedLength->Init(baseVal);
*aResult = (nsIDOMSVGAnimatedAngle*) animatedLength;
return NS_OK;
}

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

@ -1,46 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla SVG project.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of 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 ***** */
#ifndef __NS_SVGANIMATEDANGLE_H__
#define __NS_SVGANIMATEDANGLE_H__
#include "nsIDOMSVGAnimatedAngle.h"
#include "nsIDOMSVGAngle.h"
nsresult NS_NewSVGAnimatedAngle(nsIDOMSVGAnimatedAngle** result,
nsIDOMSVGAngle* baseVal);
#endif //__NS_SVGANIMATEDANGLE_H__

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

@ -68,14 +68,10 @@
#include "nsSVGLength2.h"
#include "nsSVGNumber2.h"
#include "nsSVGInteger.h"
#include "nsSVGAngle.h"
#include "nsSVGBoolean.h"
#include "nsSVGEnum.h"
#include "nsIDOMSVGUnitTypes.h"
#include "nsIDOMSVGAngle.h"
#include "nsIDOMSVGAnimatedAngle.h"
#include "nsIDOMSVGAnimatedBoolean.h"
#include "nsIDOMSVGAnimatedInteger.h"
#include "nsIDOMSVGLength.h"
#include "nsIDOMSVGLengthList.h"
#include "nsIDOMSVGAnimatedLengthList.h"
#include "nsIDOMSVGNumberList.h"
@ -131,6 +127,14 @@ nsSVGElement::Init()
integerInfo.mIntegers[i].Init(i, integerInfo.mIntegerInfo[i].mDefaultValue);
}
AngleAttributesInfo angleInfo = GetAngleInfo();
for (i = 0; i < angleInfo.mAngleCount; i++) {
angleInfo.mAngles[i].Init(i,
angleInfo.mAngleInfo[i].mDefaultValue,
angleInfo.mAngleInfo[i].mDefaultUnitType);
}
BooleanAttributesInfo booleanInfo = GetBooleanInfo();
for (i = 0; i < booleanInfo.mBooleanCount; i++) {
@ -259,7 +263,9 @@ nsSVGElement::ParseAttribute(PRInt32 aNamespaceID,
// Check for nsSVGLength2 attribute
LengthAttributesInfo lengthInfo = GetLengthInfo();
for (PRUint32 i = 0; i < lengthInfo.mLengthCount && !foundMatch; i++) {
PRUint32 i;
for (i = 0; i < lengthInfo.mLengthCount && !foundMatch; i++) {
if (aAttribute == *lengthInfo.mLengthInfo[i].mName) {
rv = lengthInfo.mLengths[i].SetBaseValueString(aValue, this, PR_FALSE);
foundMatch = PR_TRUE;
@ -268,7 +274,7 @@ nsSVGElement::ParseAttribute(PRInt32 aNamespaceID,
// Check for nsSVGNumber2 attribute
NumberAttributesInfo numberInfo = GetNumberInfo();
for (PRUint32 i = 0; i < numberInfo.mNumberCount && !foundMatch; i++) {
for (i = 0; i < numberInfo.mNumberCount && !foundMatch; i++) {
if (aAttribute == *numberInfo.mNumberInfo[i].mName) {
rv = numberInfo.mNumbers[i].SetBaseValueString(aValue, this, PR_FALSE);
foundMatch = PR_TRUE;
@ -277,16 +283,25 @@ nsSVGElement::ParseAttribute(PRInt32 aNamespaceID,
// Check for nsSVGInteger attribute
IntegerAttributesInfo integerInfo = GetIntegerInfo();
for (PRUint32 i = 0; i < integerInfo.mIntegerCount && !foundMatch; i++) {
for (i = 0; i < integerInfo.mIntegerCount && !foundMatch; i++) {
if (aAttribute == *integerInfo.mIntegerInfo[i].mName) {
rv = integerInfo.mIntegers[i].SetBaseValueString(aValue, this, PR_FALSE);
foundMatch = PR_TRUE;
}
}
// Check for nsSVGAngle attribute
AngleAttributesInfo angleInfo = GetAngleInfo();
for (i = 0; i < angleInfo.mAngleCount && !foundMatch; i++) {
if (aAttribute == *angleInfo.mAngleInfo[i].mName) {
rv = angleInfo.mAngles[i].SetBaseValueString(aValue, this, PR_FALSE);
foundMatch = PR_TRUE;
}
}
// Check for nsSVGBoolean attribute
BooleanAttributesInfo booleanInfo = GetBooleanInfo();
for (PRUint32 i = 0; i < booleanInfo.mBooleanCount && !foundMatch; i++) {
for (i = 0; i < booleanInfo.mBooleanCount && !foundMatch; i++) {
if (aAttribute == *booleanInfo.mBooleanInfo[i].mName) {
rv = booleanInfo.mBooleans[i].SetBaseValueString(aValue, this, PR_FALSE);
foundMatch = PR_TRUE;
@ -295,7 +310,7 @@ nsSVGElement::ParseAttribute(PRInt32 aNamespaceID,
// Check for nsSVGEnum attribute
EnumAttributesInfo enumInfo = GetEnumInfo();
for (PRUint32 i = 0; i < enumInfo.mEnumCount && !foundMatch; i++) {
for (i = 0; i < enumInfo.mEnumCount && !foundMatch; i++) {
if (aAttribute == *enumInfo.mEnumInfo[i].mName) {
rv = enumInfo.mEnums[i].SetBaseValueString(aValue, this, PR_FALSE);
foundMatch = PR_TRUE;
@ -366,6 +381,18 @@ nsSVGElement::UnsetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
}
}
// Check if this is an angle attribute going away
AngleAttributesInfo angleInfo = GetAngleInfo();
for (i = 0; i < angleInfo.mAngleCount; i++) {
if (aName == *angleInfo.mAngleInfo[i].mName) {
angleInfo.mAngles[i].Init(i,
angleInfo.mAngleInfo[i].mDefaultValue,
angleInfo.mAngleInfo[i].mDefaultUnitType);
DidChangeAngle(i, PR_FALSE);
}
}
// Check if this is a boolean attribute going away
BooleanAttributesInfo boolInfo = GetBooleanInfo();
@ -390,11 +417,6 @@ nsSVGElement::UnsetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
nsCOMPtr<nsISVGValue> svg_value = GetMappedAttribute(aNamespaceID, aName);
if (svg_value) {
#ifdef DEBUG_tor
nsCOMPtr<nsIDOMSVGAnimatedAngle> a = do_QueryInterface(svg_value);
NS_ASSERTION(!a, "must provide element processing for unset angle");
#endif
nsCOMPtr<nsIDOMSVGAnimatedRect> r = do_QueryInterface(svg_value);
if (r) {
nsCOMPtr<nsIDOMSVGRect> rect;
@ -1063,6 +1085,32 @@ nsSVGElement::GetAnimatedIntegerValues(PRInt32 *aFirst, ...)
va_end(args);
}
nsSVGElement::AngleAttributesInfo
nsSVGElement::GetAngleInfo()
{
return AngleAttributesInfo(nsnull, nsnull, 0);
}
void
nsSVGElement::DidChangeAngle(PRUint8 aAttrEnum, PRBool aDoSetAttr)
{
if (!aDoSetAttr)
return;
AngleAttributesInfo info = GetAngleInfo();
NS_ASSERTION(info.mAngleCount > 0,
"DidChangeAngle on element with no angle attribs");
NS_ASSERTION(aAttrEnum < info.mAngleCount, "aAttrEnum out of range");
nsAutoString newStr;
info.mAngles[aAttrEnum].GetBaseValueString(newStr);
SetAttr(kNameSpaceID_None, *info.mAngleInfo[aAttrEnum].mName,
newStr, PR_TRUE);
}
nsSVGElement::BooleanAttributesInfo
nsSVGElement::GetBooleanInfo()
{
@ -1078,7 +1126,7 @@ nsSVGElement::DidChangeBoolean(PRUint8 aAttrEnum, PRBool aDoSetAttr)
BooleanAttributesInfo info = GetBooleanInfo();
NS_ASSERTION(info.mBooleanCount > 0,
"DidChangeInteger on element with no boolean attribs");
"DidChangeBoolean on element with no boolean attribs");
NS_ASSERTION(aAttrEnum < info.mBooleanCount, "aAttrEnum out of range");

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

@ -58,6 +58,7 @@ class nsSVGSVGElement;
class nsSVGLength2;
class nsSVGNumber2;
class nsSVGInteger;
class nsSVGAngle;
class nsSVGBoolean;
class nsSVGEnum;
struct nsSVGEnumMapping;
@ -121,6 +122,7 @@ public:
virtual void DidChangeLength(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeNumber(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeInteger(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeAngle(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeBoolean(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeEnum(PRUint8 aAttrEnum, PRBool aDoSetAttr);
@ -151,7 +153,7 @@ protected:
struct LengthInfo {
nsIAtom** mName;
float mDefaultValue;
PRUint16 mDefaultUnitType;
PRUint8 mDefaultUnitType;
PRUint8 mCtxType;
};
@ -201,6 +203,24 @@ protected:
{}
};
struct AngleInfo {
nsIAtom** mName;
float mDefaultValue;
PRUint8 mDefaultUnitType;
};
struct AngleAttributesInfo {
nsSVGAngle* mAngles;
AngleInfo* mAngleInfo;
PRUint32 mAngleCount;
AngleAttributesInfo(nsSVGAngle *aAngles,
AngleInfo *aAngleInfo,
PRUint32 aAngleCount) :
mAngles(aAngles), mAngleInfo(aAngleInfo), mAngleCount(aAngleCount)
{}
};
struct BooleanInfo {
nsIAtom** mName;
PRPackedBool mDefaultValue;
@ -241,15 +261,16 @@ protected:
virtual LengthAttributesInfo GetLengthInfo();
virtual NumberAttributesInfo GetNumberInfo();
virtual IntegerAttributesInfo GetIntegerInfo();
virtual AngleAttributesInfo GetAngleInfo();
virtual BooleanAttributesInfo GetBooleanInfo();
virtual EnumAttributesInfo GetEnumInfo();
static nsSVGEnumMapping sSVGUnitTypesMap[];
static nsresult ReportAttributeParseFailure(nsIDocument* aDocument,
nsIAtom* aAttribute,
const nsAString& aValue);
static nsSVGEnumMapping sSVGUnitTypesMap[];
nsCOMPtr<nsICSSStyleRule> mContentStyleRule;
nsAttrAndChildArray mMappedAttributes;

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

@ -104,7 +104,7 @@ nsSVGEnum::SetBaseValue(PRUint16 aValue,
while (tmp && tmp->mKey) {
if (tmp->mVal == aValue) {
mAnimVal = mBaseVal = static_cast<PRUint8>(aValue);
mAnimVal = mBaseVal = PRUint8(aValue);
aSVGElement->DidChangeEnum(mAttrEnum, aDoSetAttr);
return NS_OK;
}

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

@ -50,9 +50,11 @@ struct nsSVGEnumMapping {
class nsSVGEnum
{
friend class nsSVGMarkerElement;
public:
void Init(PRUint8 aAttrEnum, PRUint16 aValue) {
mAnimVal = mBaseVal = static_cast<PRUint8>(aValue);
mAnimVal = mBaseVal = PRUint8(aValue);
mAttrEnum = aAttrEnum;
}
@ -81,6 +83,10 @@ private:
nsSVGEnumMapping *GetMapping(nsSVGElement *aSVGElement);
nsresult SetBaseValue(PRUint16 aValue)
{ mAnimVal = mBaseVal = PRUint8(aValue);
return NS_OK; }
struct DOMAnimatedEnum : public nsIDOMSVGAnimatedEnumeration
{
NS_DECL_ISUPPORTS

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

@ -35,10 +35,7 @@
* ***** END LICENSE BLOCK ***** */
#include "nsGkAtoms.h"
#include "nsSVGAnimatedAngle.h"
#include "nsSVGAnimatedRect.h"
#include "nsSVGLength.h"
#include "nsSVGAngle.h"
#include "nsSVGRect.h"
#include "nsCOMPtr.h"
#include "nsISVGValueUtils.h"
@ -71,6 +68,11 @@ nsSVGElement::EnumInfo nsSVGMarkerElement::sEnumInfo[1] =
}
};
nsSVGElement::AngleInfo nsSVGMarkerElement::sAngleInfo[1] =
{
{ &nsGkAtoms::orient, 0, nsIDOMSVGAngle::SVG_ANGLETYPE_UNSPECIFIED }
};
NS_IMPL_NS_NEW_SVG_ELEMENT(Marker)
//----------------------------------------------------------------------
@ -107,15 +109,6 @@ nsSVGMarkerElement::Init()
// DOM property: orientType
mOrientType.Init(ORIENTTYPE, SVG_MARKER_ORIENT_ANGLE);
// DOM property: orientAngle
{
nsCOMPtr<nsIDOMSVGAngle> angle;
rv = NS_NewSVGAngle(getter_AddRefs(angle), 0.0f);
NS_ENSURE_SUCCESS(rv,rv);
rv = NS_NewSVGAnimatedAngle(getter_AddRefs(mOrientAngle), angle);
NS_ENSURE_SUCCESS(rv,rv);
}
// Create mapped properties:
// DOM property: viewBox
@ -213,15 +206,14 @@ NS_IMETHODIMP nsSVGMarkerElement::GetOrientType(nsIDOMSVGAnimatedEnumeration * *
/* readonly attribute nsIDOMSVGAnimatedLength orientAngle; */
NS_IMETHODIMP nsSVGMarkerElement::GetOrientAngle(nsIDOMSVGAnimatedAngle * *aOrientAngle)
{
*aOrientAngle = mOrientAngle;
NS_IF_ADDREF(*aOrientAngle);
return NS_OK;
return mAngleAttributes[ORIENT].ToDOMAnimatedAngle(aOrientAngle, this);
}
/* void setOrientToAuto (); */
NS_IMETHODIMP nsSVGMarkerElement::SetOrientToAuto()
{
mOrientType.SetBaseValue(SVG_MARKER_ORIENT_AUTO, this, PR_TRUE);
SetAttr(kNameSpaceID_None, nsGkAtoms::orient, nsnull,
NS_LITERAL_STRING("auto"), PR_TRUE);
return NS_OK;
}
@ -231,13 +223,9 @@ NS_IMETHODIMP nsSVGMarkerElement::SetOrientToAngle(nsIDOMSVGAngle *angle)
if (!angle)
return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
nsIDOMSVGAngle *a;
mOrientAngle->GetBaseVal(&a);
float f;
angle->GetValue(&f);
a->SetValue(f);
mOrientType.SetBaseValue(SVG_MARKER_ORIENT_ANGLE, this, PR_TRUE);
mAngleAttributes[ORIENT].SetBaseValue(f, this);
return NS_OK;
}
@ -281,15 +269,10 @@ PRBool
nsSVGMarkerElement::GetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsAString &aResult) const
{
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::orient) {
if (mOrientType.GetBaseValue() == SVG_MARKER_ORIENT_AUTO) {
aResult.AssignLiteral("auto");
} else {
nsCOMPtr<nsIDOMSVGAngle> a;
mOrientAngle->GetBaseVal(getter_AddRefs(a));
nsCOMPtr<nsISVGValue> value = do_QueryInterface(a);
value->GetValueString(aResult);
}
if (aNameSpaceID == kNameSpaceID_None &&
aName == nsGkAtoms::orient &&
mOrientType.GetBaseValue() == SVG_MARKER_ORIENT_AUTO) {
aResult.AssignLiteral("auto");
return PR_TRUE;
}
return nsSVGMarkerElementBase::GetAttr(aNameSpaceID, aName, aResult);
@ -301,15 +284,9 @@ nsSVGMarkerElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
PRBool aNotify)
{
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::orient) {
if (aValue.EqualsLiteral("auto")) {
mOrientType.SetBaseValue(SVG_MARKER_ORIENT_AUTO, this, PR_FALSE);
} else {
mOrientType.SetBaseValue(SVG_MARKER_ORIENT_ANGLE, this, PR_FALSE);
nsCOMPtr<nsIDOMSVGAngle> a;
mOrientAngle->GetBaseVal(getter_AddRefs(a));
nsCOMPtr<nsISVGValue> value = do_QueryInterface(a);
value->SetValueString(aValue);
}
mOrientType.SetBaseValue(aValue.EqualsLiteral("auto") ?
SVG_MARKER_ORIENT_AUTO :
SVG_MARKER_ORIENT_ANGLE);
}
return nsSVGMarkerElementBase::SetAttr(aNameSpaceID, aName,
@ -328,15 +305,10 @@ nsSVGMarkerElement::UnsetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
vb->SetY(0);
vb->SetWidth(mLengthAttributes[MARKERWIDTH].GetAnimValue(mCoordCtx));
vb->SetHeight(mLengthAttributes[MARKERHEIGHT].GetAnimValue(mCoordCtx));
return nsGenericElement::UnsetAttr(aNamespaceID, aName, aNotify);
} else if (aName == nsGkAtoms::orient) {
mOrientType.SetBaseValue(SVG_MARKER_ORIENT_ANGLE, this, PR_FALSE);
nsIDOMSVGAngle *angle;
mOrientAngle->GetBaseVal(&angle);
angle->NewValueSpecifiedUnits(nsIDOMSVGAngle::SVG_ANGLETYPE_UNSPECIFIED,
0.0f);
mOrientType.SetBaseValue(SVG_MARKER_ORIENT_ANGLE);
}
return nsGenericElement::UnsetAttr(aNamespaceID, aName, aNotify);
}
return nsSVGMarkerElementBase::UnsetAttr(aNamespaceID, aName, aNotify);
@ -361,31 +333,6 @@ nsSVGMarkerElement::DidChangeLength(PRUint8 aAttrEnum, PRBool aDoSetAttr)
}
}
void
nsSVGMarkerElement::DidChangeEnum(PRUint8 aAttrEnum, PRBool aDoSetAttr)
{
if (!aDoSetAttr)
return;
if (aAttrEnum == ORIENTTYPE) {
if (mOrientType.GetBaseValue() == SVG_MARKER_ORIENT_AUTO) {
nsSVGMarkerElementBase::SetAttr(kNameSpaceID_None, nsGkAtoms::orient,
NS_LITERAL_STRING("auto"), PR_TRUE);
} else {
nsAutoString value;
GetAttr(kNameSpaceID_None, nsGkAtoms::orient, value);
if (value.EqualsLiteral("auto")) {
// type is being set to non-auto - remove an "auto" valued
// attribute if it's set, otherwise leave the angle specified.
UnsetAttr(kNameSpaceID_None, nsGkAtoms::orient, PR_TRUE);
}
}
return;
}
nsSVGMarkerElementBase::DidChangeEnum(aAttrEnum, aDoSetAttr);
}
void
nsSVGMarkerElement::SetParentCoordCtxProvider(nsSVGSVGElement *aContext)
{
@ -407,6 +354,13 @@ nsSVGMarkerElement::GetLengthInfo()
NS_ARRAY_LENGTH(sLengthInfo));
}
nsSVGElement::AngleAttributesInfo
nsSVGMarkerElement::GetAngleInfo()
{
return AngleAttributesInfo(mAngleAttributes, sAngleInfo,
NS_ARRAY_LENGTH(sAngleInfo));
}
nsSVGElement::EnumAttributesInfo
nsSVGMarkerElement::GetEnumInfo()
{
@ -427,10 +381,8 @@ nsSVGMarkerElement::GetMarkerTransform(float aStrokeWidth,
SVG_MARKERUNITS_STROKEWIDTH)
scale = aStrokeWidth;
if (mOrientType.GetBaseValue() != SVG_MARKER_ORIENT_AUTO) {
nsCOMPtr<nsIDOMSVGAngle> a;
mOrientAngle->GetAnimVal(getter_AddRefs(a));
a->GetValue(&aAngle);
if (mOrientType.GetAnimValue() != SVG_MARKER_ORIENT_AUTO) {
aAngle = mAngleAttributes[ORIENT].GetAnimValue();
}
nsCOMPtr<nsIDOMSVGMatrix> matrix;

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

@ -42,6 +42,7 @@
#include "nsIDOMSVGFitToViewBox.h"
#include "nsSVGLength2.h"
#include "nsSVGEnum.h"
#include "nsSVGAngle.h"
typedef nsSVGGraphicElement nsSVGMarkerElementBase;
@ -86,7 +87,6 @@ public:
// nsSVGElement specializations:
virtual void DidChangeLength(PRUint8 aAttrEnum, PRBool aDoSetAttr);
virtual void DidChangeEnum(PRUint8 aAttrEnum, PRBool aDoSetAttr);
// public helpers
nsresult GetMarkerTransform(float aStrokeWidth,
@ -101,6 +101,7 @@ protected:
void SetParentCoordCtxProvider(nsSVGSVGElement *aContext);
virtual LengthAttributesInfo GetLengthInfo();
virtual AngleAttributesInfo GetAngleInfo();
virtual EnumAttributesInfo GetEnumInfo();
enum { REFX, REFY, MARKERWIDTH, MARKERHEIGHT };
@ -112,9 +113,12 @@ protected:
static nsSVGEnumMapping sUnitsMap[];
static EnumInfo sEnumInfo[1];
enum { ORIENT };
nsSVGAngle mAngleAttributes[1];
static AngleInfo sAngleInfo[1];
// derived properties (from 'orient') handled separately
nsSVGEnum mOrientType;
nsCOMPtr<nsIDOMSVGAnimatedAngle> mOrientAngle;
nsSVGSVGElement *mCoordCtx;
nsCOMPtr<nsIDOMSVGAnimatedRect> mViewBox;

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

@ -567,7 +567,7 @@ nsSVGSVGElement::CreateSVGLength(nsIDOMSVGLength **_retval)
NS_IMETHODIMP
nsSVGSVGElement::CreateSVGAngle(nsIDOMSVGAngle **_retval)
{
return NS_NewSVGAngle(_retval);
return NS_NewDOMSVGAngle(_retval);
}
/* nsIDOMSVGPoint createSVGPoint (); */