diff --git a/mozilla/content/svg/content/src/nsSVGLength.cpp b/mozilla/content/svg/content/src/nsSVGLength.cpp index a699d9b2956..966a178108c 100644 --- a/mozilla/content/svg/content/src/nsSVGLength.cpp +++ b/mozilla/content/svg/content/src/nsSVGLength.cpp @@ -21,6 +21,7 @@ * * Contributor(s): * Alex Fritze (original author) + * Jonathan Watt * * 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"), @@ -37,12 +38,11 @@ * ***** END LICENSE BLOCK ***** */ #include "nsSVGLength.h" -#include "prdtoa.h" #include "nsIDOMSVGMatrix.h" #include "nsSVGAtoms.h" #include "nsSVGValue.h" -#include "nsReadableUtils.h" #include "nsTextFormatter.h" +#include "prdtoa.h" #include "nsCRT.h" #include "nsSVGCoordCtx.h" #include "nsIDOMSVGNumber.h" @@ -95,13 +95,9 @@ public: protected: // implementation helpers: - float UserUnitsPerPixel(); float mmPerPixel(); float AxisLength(); - void GetUnitString(nsAString& unit); - PRUint16 GetUnitTypeForString(const char* unitStr); PRBool IsValidUnitType(PRUint16 unit); - void MaybeAddAsObserver(); void MaybeRemoveAsObserver(); @@ -119,10 +115,10 @@ NS_NewSVGLength(nsISVGLength** result, float value, PRUint16 unit) { - nsSVGLength *pl = new nsSVGLength(value, unit); - NS_ENSURE_TRUE(pl, NS_ERROR_OUT_OF_MEMORY); - NS_ADDREF(pl); - *result = pl; + *result = new nsSVGLength(value, unit); + if (!*result) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(*result); return NS_OK; } @@ -132,11 +128,13 @@ NS_NewSVGLength(nsISVGLength** result, { *result = nsnull; nsSVGLength *pl = new nsSVGLength(); - NS_ENSURE_TRUE(pl, NS_ERROR_OUT_OF_MEMORY); + if (!pl) + return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(pl); - if (NS_FAILED(pl->SetValueAsString(value))) { + nsresult rv = pl->SetValueAsString(value); + if (NS_FAILED(rv)) { NS_RELEASE(pl); - return NS_ERROR_FAILURE; + return rv; } *result = pl; return NS_OK; @@ -148,7 +146,7 @@ nsSVGLength::nsSVGLength(float value, : mValueInSpecifiedUnits(value), mSpecifiedUnitType(unit) { - MaybeAddAsObserver(); + // we don't have a context yet, so we don't call MaybeAddAsObserver() } nsSVGLength::nsSVGLength() @@ -178,6 +176,7 @@ NS_INTERFACE_MAP_END //---------------------------------------------------------------------- // nsISVGValue methods: + NS_IMETHODIMP nsSVGLength::SetValueString(const nsAString& aValue) { @@ -210,7 +209,7 @@ nsSVGLength::DidModifySVGObservable(nsISVGValue* observable, } //---------------------------------------------------------------------- -// nsISVGLength methods: +// nsIDOMSVGLength methods: /* readonly attribute unsigned short unitType; */ NS_IMETHODIMP @@ -224,85 +223,85 @@ nsSVGLength::GetUnitType(PRUint16 *aUnitType) NS_IMETHODIMP nsSVGLength::GetValue(float *aValue) { - nsresult rv = NS_OK; - switch (mSpecifiedUnitType) { case SVG_LENGTHTYPE_NUMBER: + case SVG_LENGTHTYPE_PX: *aValue = mValueInSpecifiedUnits; break; - case SVG_LENGTHTYPE_PX: - *aValue = mValueInSpecifiedUnits * UserUnitsPerPixel(); - break; case SVG_LENGTHTYPE_MM: - *aValue = mValueInSpecifiedUnits / mmPerPixel() * UserUnitsPerPixel(); + *aValue = mValueInSpecifiedUnits / mmPerPixel(); break; case SVG_LENGTHTYPE_CM: - *aValue = mValueInSpecifiedUnits * 10.0f / mmPerPixel() * UserUnitsPerPixel(); + *aValue = mValueInSpecifiedUnits * 10.0f / mmPerPixel(); break; case SVG_LENGTHTYPE_IN: - *aValue = mValueInSpecifiedUnits * 25.4f / mmPerPixel() * UserUnitsPerPixel(); + *aValue = mValueInSpecifiedUnits * 25.4f / mmPerPixel(); break; case SVG_LENGTHTYPE_PT: - *aValue = mValueInSpecifiedUnits * 25.4f/72.0f / mmPerPixel() * UserUnitsPerPixel(); + *aValue = mValueInSpecifiedUnits * 25.4f / 72.0f / mmPerPixel(); break; case SVG_LENGTHTYPE_PC: - *aValue = mValueInSpecifiedUnits * 25.4f*12.0f/72.0f / mmPerPixel() * UserUnitsPerPixel(); + *aValue = mValueInSpecifiedUnits * 25.4f * 12.0f / 72.0f / mmPerPixel(); break; case SVG_LENGTHTYPE_PERCENTAGE: *aValue = mValueInSpecifiedUnits * AxisLength() / 100.0f; break; case SVG_LENGTHTYPE_EMS: case SVG_LENGTHTYPE_EXS: - //XXX - NS_ASSERTION(PR_FALSE, "unit not implemented yet"); + NS_NOTYETIMPLEMENTED("unit not implemented - write me!"); + *aValue = 0; + return NS_ERROR_NOT_IMPLEMENTED; default: - rv = NS_ERROR_FAILURE; - break; + NS_NOTREACHED("Unknown unit type"); + *aValue = 0; + return NS_ERROR_UNEXPECTED; } - return rv; + return NS_OK; } NS_IMETHODIMP nsSVGLength::SetValue(float aValue) { nsresult rv = NS_OK; - + WillModify(); switch (mSpecifiedUnitType) { case SVG_LENGTHTYPE_NUMBER: + case SVG_LENGTHTYPE_PX: mValueInSpecifiedUnits = aValue; break; - case SVG_LENGTHTYPE_PX: - mValueInSpecifiedUnits = aValue / UserUnitsPerPixel(); - break; case SVG_LENGTHTYPE_MM: - mValueInSpecifiedUnits = aValue / UserUnitsPerPixel() * mmPerPixel(); + mValueInSpecifiedUnits = aValue * mmPerPixel(); break; case SVG_LENGTHTYPE_CM: - mValueInSpecifiedUnits = aValue / UserUnitsPerPixel() * mmPerPixel() / 10.0f; + mValueInSpecifiedUnits = aValue * mmPerPixel() / 10.0f; break; case SVG_LENGTHTYPE_IN: - mValueInSpecifiedUnits = aValue / UserUnitsPerPixel() * mmPerPixel() / 25.4f; + mValueInSpecifiedUnits = aValue * mmPerPixel() / 25.4f; break; case SVG_LENGTHTYPE_PT: - mValueInSpecifiedUnits = aValue / UserUnitsPerPixel() * mmPerPixel() * 72.0f/25.4f; + mValueInSpecifiedUnits = aValue * mmPerPixel() * 72.0f / 25.4f; break; case SVG_LENGTHTYPE_PC: - mValueInSpecifiedUnits = aValue / UserUnitsPerPixel() * mmPerPixel() * 72.0f/24.4f/12.0f; + mValueInSpecifiedUnits = aValue * mmPerPixel() * 72.0f / 24.4f / 12.0f; break; case SVG_LENGTHTYPE_PERCENTAGE: mValueInSpecifiedUnits = aValue * 100.0f / AxisLength(); break; case SVG_LENGTHTYPE_EMS: case SVG_LENGTHTYPE_EXS: - //XXX - NS_ASSERTION(PR_FALSE, "unit not implemented yet"); + NS_NOTYETIMPLEMENTED("unit not implemented - write me!"); + mValueInSpecifiedUnits = 0; + rv = NS_ERROR_NOT_IMPLEMENTED; + break; default: - rv = NS_ERROR_FAILURE; + NS_NOTREACHED("Unknown unit type"); + mValueInSpecifiedUnits = 0; + rv = NS_ERROR_UNEXPECTED; break; } - + DidModify(); return rv; } @@ -327,18 +326,53 @@ nsSVGLength::SetValueInSpecifiedUnits(float aValueInSpecifiedUnits) NS_IMETHODIMP nsSVGLength::GetValueAsString(nsAString & aValueAsString) { - aValueAsString.Truncate(); - PRUnichar buf[24]; nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar), NS_LITERAL_STRING("%g").get(), (double)mValueInSpecifiedUnits); - aValueAsString.Append(buf); - + aValueAsString.Assign(buf); + + nsIAtom* UnitAtom = nsnull; + + switch (mSpecifiedUnitType) { + case SVG_LENGTHTYPE_NUMBER: + return NS_OK; + case SVG_LENGTHTYPE_PX: + UnitAtom = nsSVGAtoms::px; + break; + case SVG_LENGTHTYPE_MM: + UnitAtom = nsSVGAtoms::mm; + break; + case SVG_LENGTHTYPE_CM: + UnitAtom = nsSVGAtoms::cm; + break; + case SVG_LENGTHTYPE_IN: + UnitAtom = nsSVGAtoms::in; + break; + case SVG_LENGTHTYPE_PT: + UnitAtom = nsSVGAtoms::pt; + break; + case SVG_LENGTHTYPE_PC: + UnitAtom = nsSVGAtoms::pc; + break; + case SVG_LENGTHTYPE_EMS: + UnitAtom = nsSVGAtoms::ems; + break; + case SVG_LENGTHTYPE_EXS: + UnitAtom = nsSVGAtoms::exs; + break; + case SVG_LENGTHTYPE_PERCENTAGE: + UnitAtom = nsSVGAtoms::percentage; + break; + default: + NS_NOTREACHED("Unknown unit"); + return NS_ERROR_UNEXPECTED; + } + nsAutoString unitString; - GetUnitString(unitString); + UnitAtom->ToString(unitString); aValueAsString.Append(unitString); - + return NS_OK; } @@ -357,7 +391,32 @@ nsSVGLength::SetValueAsString(const nsAString & aValueAsString) char *rest; double value = PR_strtod(number, &rest); if (rest!=number) { - PRUint16 unitType = GetUnitTypeForString(nsCRT::strtok(rest, "\x20\x9\xD\xA", &rest)); + const char* unitStr = nsCRT::strtok(rest, "\x20\x9\xD\xA", &rest); + PRUint16 unitType = SVG_LENGTHTYPE_UNKNOWN; + if (!unitStr || *unitStr=='\0') { + unitType = SVG_LENGTHTYPE_NUMBER; + } + else { + nsCOMPtr unitAtom = do_GetAtom(unitStr); + if (unitAtom == nsSVGAtoms::px) + unitType = SVG_LENGTHTYPE_PX; + else if (unitAtom == nsSVGAtoms::mm) + unitType = SVG_LENGTHTYPE_MM; + else if (unitAtom == nsSVGAtoms::cm) + unitType = SVG_LENGTHTYPE_CM; + else if (unitAtom == nsSVGAtoms::in) + unitType = SVG_LENGTHTYPE_IN; + else if (unitAtom == nsSVGAtoms::pt) + unitType = SVG_LENGTHTYPE_PT; + else if (unitAtom == nsSVGAtoms::pc) + unitType = SVG_LENGTHTYPE_PC; + else if (unitAtom == nsSVGAtoms::ems) + unitType = SVG_LENGTHTYPE_EMS; + else if (unitAtom == nsSVGAtoms::exs) + unitType = SVG_LENGTHTYPE_EXS; + else if (unitAtom == nsSVGAtoms::percentage) + unitType = SVG_LENGTHTYPE_PERCENTAGE; + } if (IsValidUnitType(unitType)){ WillModify(); mValueInSpecifiedUnits = (float)value; @@ -382,13 +441,14 @@ nsSVGLength::SetValueAsString(const nsAString & aValueAsString) } /* void newValueSpecifiedUnits (in unsigned short unitType, in float valueInSpecifiedUnits); */ - NS_IMETHODIMP +NS_IMETHODIMP nsSVGLength::NewValueSpecifiedUnits(PRUint16 unitType, float valueInSpecifiedUnits) { - if (!IsValidUnitType(unitType)) return NS_ERROR_FAILURE; + if (!IsValidUnitType(unitType)) + return NS_ERROR_FAILURE; + + PRBool observer_change = (unitType != mSpecifiedUnitType); - bool observer_change = (unitType != mSpecifiedUnitType); - WillModify(); if (observer_change) MaybeRemoveAsObserver(); @@ -405,9 +465,10 @@ nsSVGLength::NewValueSpecifiedUnits(PRUint16 unitType, float valueInSpecifiedUni NS_IMETHODIMP nsSVGLength::ConvertToSpecifiedUnits(PRUint16 unitType) { - if (!IsValidUnitType(unitType)) return NS_ERROR_FAILURE; + if (!IsValidUnitType(unitType)) + return NS_ERROR_FAILURE; - bool observer_change = (unitType != mSpecifiedUnitType); + PRBool observer_change = (unitType != mSpecifiedUnitType); WillModify(); if (observer_change) @@ -426,17 +487,15 @@ nsSVGLength::ConvertToSpecifiedUnits(PRUint16 unitType) /* float getTransformedValue (in nsIDOMSVGMatrix matrix); */ NS_IMETHODIMP nsSVGLength::GetTransformedValue(nsIDOMSVGMatrix *matrix, - float *_retval) + float *_retval) { - // XXX we don't have enough information here. is it the length part of // a coordinate pair (in which case it should transform like a point) // or is it used like a vector-component (in which case it doesn't // translate) - NS_NOTYETIMPLEMENTED("write me!"); - return NS_ERROR_UNEXPECTED; + return NS_ERROR_NOT_IMPLEMENTED; } @@ -466,59 +525,9 @@ nsSVGLength::SetContext(nsSVGCoordCtx* context) } - //---------------------------------------------------------------------- // Implementation helpers: -float nsSVGLength::UserUnitsPerPixel() -{ - float UUPerPx = 1.0f; - - // SVG CR 20001102: New: A px unit and a user unit are defined to be - // equivalent in SVG. Thus, a length of "5px" is the same as a - // length of "5". - // - - // old way of mapping pixels: -// if (!mOwnerElement) return UUPerPx; - -// nsCOMPtr locatable; -// locatable = do_QueryInterface(mOwnerElement); -// if (!locatable) return UUPerPx; - -// nsCOMPtr matrix; -// locatable->GetCTM( getter_AddRefs(matrix) ); -// if (!matrix) return UUPerPx; - -// nsCOMPtr point, XFormedPoint; -// nsSVGPoint::Create(1.0, 1.0, getter_AddRefs(point)); -// point->MatrixTransform(matrix, getter_AddRefs(XFormedPoint)); - -// switch (mDirection) { -// case eXDirection: -// XFormedPoint->GetX(&UUPerPx); -// break; -// case eYDirection: -// XFormedPoint->GetY(&UUPerPx); -// break; -// case eNoDirection: -// { -// float x,y; -// XFormedPoint->GetX(&x); -// XFormedPoint->GetY(&y); -// UUPerPx = (x==y ? x : (x+y)/2); -// break; -// } -// } - -// if (UUPerPx == 0.0f) { -// NS_ASSERTION(PR_FALSE, "invalid uu/pixels"); -// UUPerPx = 1e-20f; // some small value -// } - - return UUPerPx; -} - float nsSVGLength::mmPerPixel() { if (!mContext) { @@ -527,9 +536,9 @@ float nsSVGLength::mmPerPixel() } float mmPerPx = mContext->GetMillimeterPerPixel(); - + if (mmPerPx == 0.0f) { - NS_ASSERTION(PR_FALSE, "invalid mm/pixels"); + NS_ASSERTION(mmPerPx != 0.0f, "invalid mm/pixels"); mmPerPx = 1e-4f; // some small value } @@ -544,92 +553,21 @@ float nsSVGLength::AxisLength() } nsCOMPtr num = mContext->GetLength(); - NS_ASSERTION(num, "null interface"); + NS_ASSERTION(num != nsnull, "null interface"); float d; num->GetValue(&d); - - NS_ASSERTION(d!=0.0f, "zero axis length"); - - if (d == 0.0f) + + if (d == 0.0f) { + NS_WARNING("zero axis length"); d = 1e-20f; - return d; -} - -void nsSVGLength::GetUnitString(nsAString& unit) -{ - nsIAtom* UnitAtom = nsnull; - - switch (mSpecifiedUnitType) { - case SVG_LENGTHTYPE_NUMBER: - UnitAtom = nsnull; - break; - case SVG_LENGTHTYPE_PX: - UnitAtom = nsSVGAtoms::px; - break; - case SVG_LENGTHTYPE_MM: - UnitAtom = nsSVGAtoms::mm; - break; - case SVG_LENGTHTYPE_CM: - UnitAtom = nsSVGAtoms::cm; - break; - case SVG_LENGTHTYPE_IN: - UnitAtom = nsSVGAtoms::in; - break; - case SVG_LENGTHTYPE_PT: - UnitAtom = nsSVGAtoms::pt; - break; - case SVG_LENGTHTYPE_PC: - UnitAtom = nsSVGAtoms::pc; - break; - case SVG_LENGTHTYPE_EMS: - UnitAtom = nsSVGAtoms::ems; - break; - case SVG_LENGTHTYPE_EXS: - UnitAtom = nsSVGAtoms::exs; - break; - case SVG_LENGTHTYPE_PERCENTAGE: - UnitAtom = nsSVGAtoms::percentage; - break; - default: - NS_ASSERTION(PR_FALSE, "unknown unit"); - break; } - if (!UnitAtom) return; - UnitAtom->ToString(unit); -} - -PRUint16 nsSVGLength::GetUnitTypeForString(const char* unitStr) -{ - if (!unitStr || *unitStr=='\0') return SVG_LENGTHTYPE_NUMBER; - - nsCOMPtr unitAtom = do_GetAtom(unitStr); - - if (unitAtom == nsSVGAtoms::px) - return SVG_LENGTHTYPE_PX; - else if (unitAtom == nsSVGAtoms::mm) - return SVG_LENGTHTYPE_MM; - else if (unitAtom == nsSVGAtoms::cm) - return SVG_LENGTHTYPE_CM; - else if (unitAtom == nsSVGAtoms::in) - return SVG_LENGTHTYPE_IN; - else if (unitAtom == nsSVGAtoms::pt) - return SVG_LENGTHTYPE_PT; - else if (unitAtom == nsSVGAtoms::pc) - return SVG_LENGTHTYPE_PC; - else if (unitAtom == nsSVGAtoms::ems) - return SVG_LENGTHTYPE_EMS; - else if (unitAtom == nsSVGAtoms::exs) - return SVG_LENGTHTYPE_EXS; - else if (unitAtom == nsSVGAtoms::percentage) - return SVG_LENGTHTYPE_PERCENTAGE; - - return SVG_LENGTHTYPE_UNKNOWN; + return d; } PRBool nsSVGLength::IsValidUnitType(PRUint16 unit) { - if (unit>0 && unit<=10) + if (unit > SVG_LENGTHTYPE_UNKNOWN && unit <= SVG_LENGTHTYPE_PC) return PR_TRUE; return PR_FALSE;