Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/svg/SVGMotionSMILPathUtils.cpp
Line
Count
Source (jump to first uncovered line)
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 "nsCharSeparatedTokenizer.h"
10
#include "nsContentUtils.h" // for NS_ENSURE_FINITE2
11
#include "SVGContentUtils.h"
12
#include "SVGLength.h"
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
23
SVGMotionSMILPathUtils::PathGenerator::
24
  MoveToOrigin()
25
0
{
26
0
  MOZ_ASSERT(!mHaveReceivedCommands,
27
0
             "Not expecting requests for mid-path MoveTo commands");
28
0
  mHaveReceivedCommands = true;
29
0
  mPathBuilder->MoveTo(Point(0, 0));
30
0
}
31
32
// For 'from' and the first entry in 'values'.
33
bool
34
SVGMotionSMILPathUtils::PathGenerator::
35
  MoveToAbsolute(const nsAString& aCoordPairStr)
36
0
{
37
0
  MOZ_ASSERT(!mHaveReceivedCommands,
38
0
             "Not expecting requests for mid-path MoveTo commands");
39
0
  mHaveReceivedCommands = true;
40
0
41
0
  float xVal, yVal;
42
0
  if (!ParseCoordinatePair(aCoordPairStr, xVal, yVal)) {
43
0
    return false;
44
0
  }
45
0
  mPathBuilder->MoveTo(Point(xVal, yVal));
46
0
  return true;
47
0
}
48
49
// For 'to' and every entry in 'values' except the first.
50
bool
51
SVGMotionSMILPathUtils::PathGenerator::
52
  LineToAbsolute(const nsAString& aCoordPairStr, double& aSegmentDistance)
53
0
{
54
0
  mHaveReceivedCommands = true;
55
0
56
0
  float xVal, yVal;
57
0
  if (!ParseCoordinatePair(aCoordPairStr, xVal, yVal)) {
58
0
    return false;
59
0
  }
60
0
  Point initialPoint = mPathBuilder->CurrentPoint();
61
0
62
0
  mPathBuilder->LineTo(Point(xVal, yVal));
63
0
  aSegmentDistance = NS_hypot(initialPoint.x - xVal, initialPoint.y -yVal);
64
0
  return true;
65
0
}
66
67
// For 'by'.
68
bool
69
SVGMotionSMILPathUtils::PathGenerator::
70
  LineToRelative(const nsAString& aCoordPairStr, double& aSegmentDistance)
71
0
{
72
0
  mHaveReceivedCommands = true;
73
0
74
0
  float xVal, yVal;
75
0
  if (!ParseCoordinatePair(aCoordPairStr, xVal, yVal)) {
76
0
    return false;
77
0
  }
78
0
  mPathBuilder->LineTo(mPathBuilder->CurrentPoint() + Point(xVal, yVal));
79
0
  aSegmentDistance = NS_hypot(xVal, yVal);
80
0
  return true;
81
0
}
82
83
already_AddRefed<Path>
84
SVGMotionSMILPathUtils::PathGenerator::GetResultingPath()
85
0
{
86
0
  return mPathBuilder->Finish();
87
0
}
88
89
//----------------------------------------------------------------------
90
// Helper / protected methods
91
92
bool
93
SVGMotionSMILPathUtils::PathGenerator::
94
  ParseCoordinatePair(const nsAString& aCoordPairStr,
95
                      float& aXVal, float& aYVal)
96
0
{
97
0
  nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
98
0
    tokenizer(aCoordPairStr, ',',
99
0
              nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
100
0
101
0
  SVGLength x, y;
102
0
103
0
  if (!tokenizer.hasMoreTokens() ||
104
0
      !x.SetValueFromString(tokenizer.nextToken())) {
105
0
    return false;
106
0
  }
107
0
108
0
  if (!tokenizer.hasMoreTokens() ||
109
0
      !y.SetValueFromString(tokenizer.nextToken())) {
110
0
    return false;
111
0
  }
112
0
113
0
  if (tokenizer.separatorAfterCurrentToken() ||  // Trailing comma.
114
0
      tokenizer.hasMoreTokens()) {               // More text remains
115
0
    return false;
116
0
  }
117
0
118
0
  float xRes = x.GetValueInUserUnits(mSVGElement, SVGContentUtils::X);
119
0
  float yRes = y.GetValueInUserUnits(mSVGElement, SVGContentUtils::Y);
120
0
121
0
  NS_ENSURE_FINITE2(xRes, yRes, false);
122
0
123
0
  aXVal = xRes;
124
0
  aYVal = yRes;
125
0
  return true;
126
0
}
127
128
//----------------------------------------------------------------------
129
// MotionValueParser methods
130
bool
131
SVGMotionSMILPathUtils::MotionValueParser::
132
  Parse(const nsAString& aValueStr)
133
0
{
134
0
  bool success;
135
0
  if (!mPathGenerator->HaveReceivedCommands()) {
136
0
    // Interpret first value in "values" attribute as the path's initial MoveTo
137
0
    success = mPathGenerator->MoveToAbsolute(aValueStr);
138
0
    if (success) {
139
0
      success = !!mPointDistances->AppendElement(0.0, fallible);
140
0
    }
141
0
  } else {
142
0
    double dist;
143
0
    success = mPathGenerator->LineToAbsolute(aValueStr, dist);
144
0
    if (success) {
145
0
      mDistanceSoFar += dist;
146
0
      success = !!mPointDistances->AppendElement(mDistanceSoFar, fallible);
147
0
    }
148
0
  }
149
0
  return success;
150
0
}
151
152
} // namespace mozilla