123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #include "SVGMotionSMILPathUtils.h"
- #include "nsCharSeparatedTokenizer.h"
- #include "nsContentUtils.h" // for NS_ENSURE_FINITE2
- #include "SVGContentUtils.h"
- #include "SVGLength.h"
- using namespace mozilla::gfx;
- namespace mozilla {
- //----------------------------------------------------------------------
- // PathGenerator methods
- // For the dummy 'from' value used in pure by-animation & to-animation
- void
- SVGMotionSMILPathUtils::PathGenerator::
- MoveToOrigin()
- {
- MOZ_ASSERT(!mHaveReceivedCommands,
- "Not expecting requests for mid-path MoveTo commands");
- mHaveReceivedCommands = true;
- mPathBuilder->MoveTo(Point(0, 0));
- }
- // For 'from' and the first entry in 'values'.
- bool
- SVGMotionSMILPathUtils::PathGenerator::
- MoveToAbsolute(const nsAString& aCoordPairStr)
- {
- MOZ_ASSERT(!mHaveReceivedCommands,
- "Not expecting requests for mid-path MoveTo commands");
- mHaveReceivedCommands = true;
- float xVal, yVal;
- if (!ParseCoordinatePair(aCoordPairStr, xVal, yVal)) {
- return false;
- }
- mPathBuilder->MoveTo(Point(xVal, yVal));
- return true;
- }
- // For 'to' and every entry in 'values' except the first.
- bool
- SVGMotionSMILPathUtils::PathGenerator::
- LineToAbsolute(const nsAString& aCoordPairStr, double& aSegmentDistance)
- {
- mHaveReceivedCommands = true;
- float xVal, yVal;
- if (!ParseCoordinatePair(aCoordPairStr, xVal, yVal)) {
- return false;
- }
- Point initialPoint = mPathBuilder->CurrentPoint();
- mPathBuilder->LineTo(Point(xVal, yVal));
- aSegmentDistance = NS_hypot(initialPoint.x - xVal, initialPoint.y -yVal);
- return true;
- }
- // For 'by'.
- bool
- SVGMotionSMILPathUtils::PathGenerator::
- LineToRelative(const nsAString& aCoordPairStr, double& aSegmentDistance)
- {
- mHaveReceivedCommands = true;
- float xVal, yVal;
- if (!ParseCoordinatePair(aCoordPairStr, xVal, yVal)) {
- return false;
- }
- mPathBuilder->LineTo(mPathBuilder->CurrentPoint() + Point(xVal, yVal));
- aSegmentDistance = NS_hypot(xVal, yVal);
- return true;
- }
- already_AddRefed<Path>
- SVGMotionSMILPathUtils::PathGenerator::GetResultingPath()
- {
- return mPathBuilder->Finish();
- }
- //----------------------------------------------------------------------
- // Helper / protected methods
- bool
- SVGMotionSMILPathUtils::PathGenerator::
- ParseCoordinatePair(const nsAString& aCoordPairStr,
- float& aXVal, float& aYVal)
- {
- nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
- tokenizer(aCoordPairStr, ',',
- nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
- SVGLength x, y;
- if (!tokenizer.hasMoreTokens() ||
- !x.SetValueFromString(tokenizer.nextToken())) {
- return false;
- }
- if (!tokenizer.hasMoreTokens() ||
- !y.SetValueFromString(tokenizer.nextToken())) {
- return false;
- }
- if (tokenizer.separatorAfterCurrentToken() || // Trailing comma.
- tokenizer.hasMoreTokens()) { // More text remains
- return false;
- }
- float xRes = x.GetValueInUserUnits(mSVGElement, SVGContentUtils::X);
- float yRes = y.GetValueInUserUnits(mSVGElement, SVGContentUtils::Y);
- NS_ENSURE_FINITE2(xRes, yRes, false);
- aXVal = xRes;
- aYVal = yRes;
- return true;
- }
- //----------------------------------------------------------------------
- // MotionValueParser methods
- bool
- SVGMotionSMILPathUtils::MotionValueParser::
- Parse(const nsAString& aValueStr)
- {
- bool success;
- if (!mPathGenerator->HaveReceivedCommands()) {
- // Interpret first value in "values" attribute as the path's initial MoveTo
- success = mPathGenerator->MoveToAbsolute(aValueStr);
- if (success) {
- success = !!mPointDistances->AppendElement(0.0, fallible);
- }
- } else {
- double dist;
- success = mPathGenerator->LineToAbsolute(aValueStr, dist);
- if (success) {
- mDistanceSoFar += dist;
- success = !!mPointDistances->AppendElement(mDistanceSoFar, fallible);
- }
- }
- return success;
- }
- } // namespace mozilla
|