gfxMatrix nsSVGGraphicElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix, TransformTypes aWhich) const { NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(), "Skipping eUserSpaceToParent transforms makes no sense"); gfxMatrix result(aMatrix); if (aWhich == eChildToUserSpace) { // We don't have anything to prepend. // eChildToUserSpace is not the common case, which is why we return // 'result' to benefit from NRVO rather than returning aMatrix before // creating 'result'. return result; } NS_ABORT_IF_FALSE(aWhich == eAllTransforms || aWhich == eUserSpaceToParent, "Unknown TransformTypes"); // animateMotion's resulting transform is supposed to apply *on top of* // any transformations from the |transform| attribute. So since we're // PRE-multiplying, we need to apply the animateMotion transform *first*. if (mAnimateMotionTransform) { result.PreMultiply(*mAnimateMotionTransform); } if (mTransforms) { result.PreMultiply(mTransforms->GetAnimValue().GetConsolidationMatrix()); } return result; }
/* virtual */ gfxMatrix SVGUseElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix, TransformTypes aWhich) const { NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(), "Skipping eUserSpaceToParent transforms makes no sense"); // 'transform' attribute: gfxMatrix fromUserSpace = SVGUseElementBase::PrependLocalTransformsTo(aMatrix, aWhich); if (aWhich == eUserSpaceToParent) { return fromUserSpace; } // our 'x' and 'y' attributes: float x, y; const_cast<SVGUseElement*>(this)->GetAnimatedLengthValues(&x, &y, nullptr); gfxMatrix toUserSpace = gfxMatrix().Translate(gfxPoint(x, y)); if (aWhich == eChildToUserSpace) { return toUserSpace; } NS_ABORT_IF_FALSE(aWhich == eAllTransforms, "Unknown TransformTypes"); return toUserSpace * fromUserSpace; }