tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SVGMotionSMILPathUtils.cpp (4245B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "SVGMotionSMILPathUtils.h"
      8 
      9 #include "SVGContentUtils.h"
     10 #include "SVGLength.h"
     11 #include "nsCharSeparatedTokenizer.h"
     12 #include "nsContentUtils.h"  // for NS_ENSURE_FINITE2
     13 
     14 using namespace mozilla::gfx;
     15 
     16 namespace mozilla {
     17 
     18 //----------------------------------------------------------------------
     19 // PathGenerator methods
     20 
     21 // For the dummy 'from' value used in pure by-animation & to-animation
     22 void SVGMotionSMILPathUtils::PathGenerator::MoveToOrigin() {
     23  MOZ_ASSERT(!mHaveReceivedCommands,
     24             "Not expecting requests for mid-path MoveTo commands");
     25  mHaveReceivedCommands = true;
     26  mPathBuilder->MoveTo(Point(0, 0));
     27 }
     28 
     29 // For 'from' and the first entry in 'values'.
     30 bool SVGMotionSMILPathUtils::PathGenerator::MoveToAbsolute(
     31    const nsAString& aCoordPairStr) {
     32  MOZ_ASSERT(!mHaveReceivedCommands,
     33             "Not expecting requests for mid-path MoveTo commands");
     34  mHaveReceivedCommands = true;
     35 
     36  float xVal, yVal;
     37  if (!ParseCoordinatePair(aCoordPairStr, xVal, yVal)) {
     38    return false;
     39  }
     40  mPathBuilder->MoveTo(Point(xVal, yVal));
     41  return true;
     42 }
     43 
     44 // For 'to' and every entry in 'values' except the first.
     45 bool SVGMotionSMILPathUtils::PathGenerator::LineToAbsolute(
     46    const nsAString& aCoordPairStr, double& aSegmentDistance) {
     47  mHaveReceivedCommands = true;
     48 
     49  float xVal, yVal;
     50  if (!ParseCoordinatePair(aCoordPairStr, xVal, yVal)) {
     51    return false;
     52  }
     53  Point initialPoint = mPathBuilder->CurrentPoint();
     54 
     55  mPathBuilder->LineTo(Point(xVal, yVal));
     56  aSegmentDistance = NS_hypot(initialPoint.x - xVal, initialPoint.y - yVal);
     57  return true;
     58 }
     59 
     60 // For 'by'.
     61 bool SVGMotionSMILPathUtils::PathGenerator::LineToRelative(
     62    const nsAString& aCoordPairStr, double& aSegmentDistance) {
     63  mHaveReceivedCommands = true;
     64 
     65  float xVal, yVal;
     66  if (!ParseCoordinatePair(aCoordPairStr, xVal, yVal)) {
     67    return false;
     68  }
     69  mPathBuilder->LineTo(mPathBuilder->CurrentPoint() + Point(xVal, yVal));
     70  aSegmentDistance = NS_hypot(xVal, yVal);
     71  return true;
     72 }
     73 
     74 already_AddRefed<Path>
     75 SVGMotionSMILPathUtils::PathGenerator::GetResultingPath() {
     76  return mPathBuilder->Finish();
     77 }
     78 
     79 //----------------------------------------------------------------------
     80 // Helper / protected methods
     81 
     82 bool SVGMotionSMILPathUtils::PathGenerator::ParseCoordinatePair(
     83    const nsAString& aCoordPairStr, float& aXVal, float& aYVal) {
     84  nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace,
     85                                   nsTokenizerFlags::SeparatorOptional>
     86      tokenizer(aCoordPairStr, ',');
     87 
     88  SVGLength x, y;
     89 
     90  if (!tokenizer.hasMoreTokens() ||
     91      !x.SetValueFromString(tokenizer.nextToken())) {
     92    return false;
     93  }
     94 
     95  if (!tokenizer.hasMoreTokens() ||
     96      !y.SetValueFromString(tokenizer.nextToken())) {
     97    return false;
     98  }
     99 
    100  if (tokenizer.separatorAfterCurrentToken() ||  // Trailing comma.
    101      tokenizer.hasMoreTokens()) {               // More text remains
    102    return false;
    103  }
    104 
    105  float xRes = x.GetValueInPixels(mSVGElement, SVGContentUtils::X);
    106  float yRes = y.GetValueInPixels(mSVGElement, SVGContentUtils::Y);
    107 
    108  NS_ENSURE_FINITE2(xRes, yRes, false);
    109 
    110  aXVal = xRes;
    111  aYVal = yRes;
    112  return true;
    113 }
    114 
    115 //----------------------------------------------------------------------
    116 // MotionValueParser methods
    117 bool SVGMotionSMILPathUtils::MotionValueParser::Parse(
    118    const nsAString& aValueStr) {
    119  bool success;
    120  if (!mPathGenerator->HaveReceivedCommands()) {
    121    // Interpret first value in "values" attribute as the path's initial MoveTo
    122    success = mPathGenerator->MoveToAbsolute(aValueStr);
    123    if (success) {
    124      success = !!mPointDistances->AppendElement(0.0, fallible);
    125    }
    126  } else {
    127    double dist;
    128    success = mPathGenerator->LineToAbsolute(aValueStr, dist);
    129    if (success) {
    130      mDistanceSoFar += dist;
    131      success = !!mPointDistances->AppendElement(mDistanceSoFar, fallible);
    132    }
    133  }
    134  return success;
    135 }
    136 
    137 }  // namespace mozilla