void SVGLengthListSMILType::Init(nsSMILValue &aValue) const { NS_ABORT_IF_FALSE(aValue.IsNull(), "Unexpected value type"); SVGLengthListAndInfo* lengthList = new SVGLengthListAndInfo(); // See the comment documenting Init() in our header file: lengthList->SetCanZeroPadList(true); aValue.mU.mPtr = lengthList; aValue.mType = this; }
nsresult SVGLengthListSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types"); NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value"); const SVGLengthListAndInfo* src = static_cast<const SVGLengthListAndInfo*>(aSrc.mU.mPtr); SVGLengthListAndInfo* dest = static_cast<SVGLengthListAndInfo*>(aDest.mU.mPtr); return dest->CopyFrom(*src); }
nsSMILValue SVGAnimatedLengthList::SMILAnimatedLengthList::GetBaseValue() const { // To benefit from Return Value Optimization and avoid copy constructor calls // due to our use of return-by-value, we must return the exact same object // from ALL return points. This function must only return THIS variable: nsSMILValue val; nsSMILValue tmp(&SVGLengthListSMILType::sSingleton); SVGLengthListAndInfo *llai = static_cast<SVGLengthListAndInfo*>(tmp.mU.mPtr); nsresult rv = llai->CopyFrom(mVal->mBaseVal); if (NS_SUCCEEDED(rv)) { llai->SetInfo(mElement, mAxis, mCanZeroPadList); val.Swap(tmp); } return val; }
nsresult SVGAnimatedLengthList:: SMILAnimatedLengthList::ValueFromString(const nsAString& aStr, const nsISMILAnimationElement* /*aSrcElement*/, nsSMILValue& aValue, bool& aPreventCachingOfSandwich) const { nsSMILValue val(&SVGLengthListSMILType::sSingleton); SVGLengthListAndInfo *llai = static_cast<SVGLengthListAndInfo*>(val.mU.mPtr); nsresult rv = llai->SetValueFromString(aStr); if (NS_SUCCEEDED(rv)) { llai->SetInfo(mElement, mAxis, mCanZeroPadList); aValue.Swap(val); // If any of the lengths in the list depend on their context, then we must // prevent caching of the entire animation sandwich. This is because the // units of a length at a given index can change from sandwich layer to // layer, and indeed even be different within a single sandwich layer. If // any length in the result of an animation sandwich is the result of the // addition of lengths where one or more of those lengths is context // dependent, then naturally the resultant length is also context // dependent, regardless of whether its actual unit is context dependent or // not. Unfortunately normal invalidation mechanisms won't cause us to // recalculate the result of the sandwich if the context changes, so we // take the (substantial) performance hit of preventing caching of the // sandwich layer, causing the animation sandwich to be recalculated every // single sample. aPreventCachingOfSandwich = PR_FALSE; for (PRUint32 i = 0; i < llai->Length(); ++i) { PRUint8 unit = (*llai)[i].GetUnit(); if (unit == nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE || unit == nsIDOMSVGLength::SVG_LENGTHTYPE_EMS || unit == nsIDOMSVGLength::SVG_LENGTHTYPE_EXS) { aPreventCachingOfSandwich = PR_TRUE; break; } } } return rv; }