bool DOMSVGTransform::IndexIsValid() { SVGAnimatedTransformList *alist = Element()->GetAnimatedTransformList(); return (mIsAnimValItem && mListIndex < alist->GetAnimValue().Length()) || (!mIsAnimValItem && mListIndex < alist->GetBaseValue().Length()); }
bool SVGFragmentIdentifier::ProcessSVGViewSpec(const nsAString &aViewSpec, nsSVGSVGElement *root) { if (!IsMatchingParameter(aViewSpec, NS_LITERAL_STRING("svgView"))) { return false; } // SVGViewAttributes may occur in any order, but each type may only occur // at most one time in a correctly formed SVGViewSpec. // If we encounter any attribute more than once or get any syntax errors // we're going to return false and cancel any changes. bool viewBoxFound = false; bool preserveAspectRatioFound = false; bool transformFound = false; bool zoomAndPanFound = false; // Each token is a SVGViewAttribute int32_t bracketPos = aViewSpec.FindChar('('); uint32_t lengthOfViewSpec = aViewSpec.Length() - bracketPos - 2; nsCharSeparatedTokenizerTemplate<IgnoreWhitespace> tokenizer( Substring(aViewSpec, bracketPos + 1, lengthOfViewSpec), ';'); if (!tokenizer.hasMoreTokens()) { return false; } do { nsAutoString token(tokenizer.nextToken()); bracketPos = token.FindChar('('); if (bracketPos < 1 || token.Last() != ')') { // invalid SVGViewAttribute syntax return false; } const nsAString ¶ms = Substring(token, bracketPos + 1, token.Length() - bracketPos - 2); if (IsMatchingParameter(token, NS_LITERAL_STRING("viewBox"))) { if (viewBoxFound || NS_FAILED(root->mViewBox.SetBaseValueString( params, root, true))) { return false; } viewBoxFound = true; } else if (IsMatchingParameter(token, NS_LITERAL_STRING("preserveAspectRatio"))) { if (preserveAspectRatioFound || NS_FAILED(root->mPreserveAspectRatio.SetBaseValueString( params, root, true))) { return false; } preserveAspectRatioFound = true; } else if (IsMatchingParameter(token, NS_LITERAL_STRING("transform"))) { SVGAnimatedTransformList transforms; if (transformFound || NS_FAILED(transforms.SetBaseValueString(params))) { return false; } if (!root->mFragmentIdentifierTransform) { root->mFragmentIdentifierTransform = new gfxMatrix(); } *root->mFragmentIdentifierTransform = transforms.GetBaseValue().GetConsolidationMatrix(); root->InvalidateTransformNotifyFrame(); transformFound = true; } else if (IsMatchingParameter(token, NS_LITERAL_STRING("zoomAndPan"))) { if (zoomAndPanFound) { return false; } nsIAtom *valAtom = NS_GetStaticAtom(params); if (!valAtom) { return false; } const nsSVGEnumMapping *mapping = nsSVGSVGElement::sZoomAndPanMap; while (mapping->mKey) { if (valAtom == *(mapping->mKey)) { // If we've got a valid zoomAndPan value, then set it on our root element. if (NS_FAILED(root->mEnumAttributes[nsSVGSVGElement::ZOOMANDPAN].SetBaseValue( mapping->mVal, root))) { return false; } break; } mapping++; } if (!mapping->mKey) { // Unrecognised zoomAndPan value return false; } zoomAndPanFound = true; } else { // We don't support viewTarget currently return false; } } while (tokenizer.hasMoreTokens()); if (root->mUseCurrentView) { // A previous SVGViewSpec may have overridden some attributes. // If they are no longer overridden we need to restore the old values. if (!transformFound) { ClearTransform(root); } if (!viewBoxFound) { RestoreOldViewBox(root); } if (!preserveAspectRatioFound) { RestoreOldPreserveAspectRatio(root); } if (!zoomAndPanFound) { RestoreOldZoomAndPan(root); } } return true; }