void SVGMotionSMILAnimationFunction:: RebuildPathAndVerticesFromBasicAttrs(const nsIContent* aContextElem) { NS_ABORT_IF_FALSE(!HasAttr(nsGkAtoms::path), "Should be using |path| attr if we have it"); NS_ABORT_IF_FALSE(!mPath, "regenerating when we aleady have path"); NS_ABORT_IF_FALSE(mPathVertices.IsEmpty(), "regenerating when we already have vertices"); if (!aContextElem->IsSVG()) { NS_ERROR("Uh oh, SVG animateMotion element targeting a non-SVG node"); return; } SVGMotionSMILPathUtils::PathGenerator pathGenerator(static_cast<const nsSVGElement*>(aContextElem)); bool success = false; if (HasAttr(nsGkAtoms::values)) { // Generate path based on our values array mPathSourceType = ePathSourceType_ValuesAttr; const nsAString& valuesStr = GetAttr(nsGkAtoms::values)->GetStringValue(); SVGMotionSMILPathUtils::MotionValueParser parser(&pathGenerator, &mPathVertices); success = NS_SUCCEEDED(nsSMILParserUtils::ParseValuesGeneric(valuesStr, parser)); } else if (HasAttr(nsGkAtoms::to) || HasAttr(nsGkAtoms::by)) { // Apply 'from' value (or a dummy 0,0 'from' value) if (HasAttr(nsGkAtoms::from)) { const nsAString& fromStr = GetAttr(nsGkAtoms::from)->GetStringValue(); success = pathGenerator.MoveToAbsolute(fromStr); mPathVertices.AppendElement(0.0); } else { // Create dummy 'from' value at 0,0, if we're doing by-animation. // (NOTE: We don't add the dummy 0-point to our list for *to-animation*, // because the nsSMILAnimationFunction logic for to-animation doesn't // expect a dummy value. It only expects one value: the final 'to' value.) pathGenerator.MoveToOrigin(); if (!HasAttr(nsGkAtoms::to)) { mPathVertices.AppendElement(0.0); } success = true; } // Apply 'to' or 'by' value if (success) { double dist; if (HasAttr(nsGkAtoms::to)) { mPathSourceType = ePathSourceType_ToAttr; const nsAString& toStr = GetAttr(nsGkAtoms::to)->GetStringValue(); success = pathGenerator.LineToAbsolute(toStr, dist); } else { // HasAttr(nsGkAtoms::by) mPathSourceType = ePathSourceType_ByAttr; const nsAString& byStr = GetAttr(nsGkAtoms::by)->GetStringValue(); success = pathGenerator.LineToRelative(byStr, dist); } if (success) { mPathVertices.AppendElement(dist); } } } if (success) { mPath = pathGenerator.GetResultingPath(); } else { // Parse failure. Leave path as null, and clear path-related member data. mPathVertices.Clear(); } }
void UnitTester::selectPath() { path.poses.resize(path_size); for (unsigned int pose_id = 0; pose_id < path.poses.size(); pose_id++) { path.poses[pose_id].pose = pathGenerator(pose_id); } }