Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/svg/SVGPathElement.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 "mozilla/dom/SVGPathElement.h"
8
9
#include <algorithm>
10
11
#include "DOMSVGPathSeg.h"
12
#include "DOMSVGPathSegList.h"
13
#include "gfx2DGlue.h"
14
#include "gfxPlatform.h"
15
#include "mozilla/dom/SVGPathElementBinding.h"
16
#include "mozilla/gfx/2D.h"
17
#include "mozilla/RefPtr.h"
18
#include "nsCOMPtr.h"
19
#include "nsComputedDOMStyle.h"
20
#include "nsGkAtoms.h"
21
#include "nsStyleConsts.h"
22
#include "nsStyleStruct.h"
23
#include "nsWindowSizes.h"
24
#include "SVGContentUtils.h"
25
26
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(Path)
27
28
using namespace mozilla::gfx;
29
30
namespace mozilla {
31
namespace dom {
32
33
JSObject*
34
SVGPathElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
35
0
{
36
0
  return SVGPathElement_Binding::Wrap(aCx, this, aGivenProto);
37
0
}
38
39
//----------------------------------------------------------------------
40
// Implementation
41
42
SVGPathElement::SVGPathElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
43
  : SVGPathElementBase(std::move(aNodeInfo))
44
0
{
45
0
}
46
47
//----------------------------------------------------------------------
48
// memory reporting methods
49
50
void
51
SVGPathElement::AddSizeOfExcludingThis(nsWindowSizes& aSizes,
52
                                       size_t* aNodeSize) const
53
0
{
54
0
  SVGPathElementBase::AddSizeOfExcludingThis(aSizes, aNodeSize);
55
0
  *aNodeSize += mD.SizeOfExcludingThis(aSizes.mState.mMallocSizeOf);
56
0
}
57
58
//----------------------------------------------------------------------
59
// nsINode methods
60
61
NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGPathElement)
62
63
uint32_t
64
SVGPathElement::GetPathSegAtLength(float distance)
65
0
{
66
0
  return mD.GetAnimValue().GetPathSegAtLength(distance);
67
0
}
68
69
already_AddRefed<DOMSVGPathSegClosePath>
70
SVGPathElement::CreateSVGPathSegClosePath()
71
0
{
72
0
  RefPtr<DOMSVGPathSegClosePath> pathSeg = new DOMSVGPathSegClosePath();
73
0
  return pathSeg.forget();
74
0
}
75
76
already_AddRefed<DOMSVGPathSegMovetoAbs>
77
SVGPathElement::CreateSVGPathSegMovetoAbs(float x, float y)
78
0
{
79
0
  RefPtr<DOMSVGPathSegMovetoAbs> pathSeg = new DOMSVGPathSegMovetoAbs(x, y);
80
0
  return pathSeg.forget();
81
0
}
82
83
already_AddRefed<DOMSVGPathSegMovetoRel>
84
SVGPathElement::CreateSVGPathSegMovetoRel(float x, float y)
85
0
{
86
0
  RefPtr<DOMSVGPathSegMovetoRel> pathSeg = new DOMSVGPathSegMovetoRel(x, y);
87
0
  return pathSeg.forget();
88
0
}
89
90
already_AddRefed<DOMSVGPathSegLinetoAbs>
91
SVGPathElement::CreateSVGPathSegLinetoAbs(float x, float y)
92
0
{
93
0
  RefPtr<DOMSVGPathSegLinetoAbs> pathSeg = new DOMSVGPathSegLinetoAbs(x, y);
94
0
  return pathSeg.forget();
95
0
}
96
97
already_AddRefed<DOMSVGPathSegLinetoRel>
98
SVGPathElement::CreateSVGPathSegLinetoRel(float x, float y)
99
0
{
100
0
  RefPtr<DOMSVGPathSegLinetoRel> pathSeg = new DOMSVGPathSegLinetoRel(x, y);
101
0
  return pathSeg.forget();
102
0
}
103
104
already_AddRefed<DOMSVGPathSegCurvetoCubicAbs>
105
SVGPathElement::CreateSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2)
106
0
{
107
0
  // Note that we swap from DOM API argument order to the argument order used
108
0
  // in the <path> element's 'd' attribute (i.e. we put the arguments for the
109
0
  // end point of the segment last instead of first).
110
0
  RefPtr<DOMSVGPathSegCurvetoCubicAbs> pathSeg =
111
0
    new DOMSVGPathSegCurvetoCubicAbs(x1, y1, x2, y2, x, y);
112
0
  return pathSeg.forget();
113
0
}
114
115
already_AddRefed<DOMSVGPathSegCurvetoCubicRel>
116
SVGPathElement::CreateSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2)
117
0
{
118
0
  // See comment in CreateSVGPathSegCurvetoCubicAbs
119
0
  RefPtr<DOMSVGPathSegCurvetoCubicRel> pathSeg =
120
0
    new DOMSVGPathSegCurvetoCubicRel(x1, y1, x2, y2, x, y);
121
0
  return pathSeg.forget();
122
0
}
123
124
already_AddRefed<DOMSVGPathSegCurvetoQuadraticAbs>
125
SVGPathElement::CreateSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1)
126
0
{
127
0
  // See comment in CreateSVGPathSegCurvetoCubicAbs
128
0
  RefPtr<DOMSVGPathSegCurvetoQuadraticAbs> pathSeg =
129
0
    new DOMSVGPathSegCurvetoQuadraticAbs(x1, y1, x, y);
130
0
  return pathSeg.forget();
131
0
}
132
133
already_AddRefed<DOMSVGPathSegCurvetoQuadraticRel>
134
SVGPathElement::CreateSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1)
135
0
{
136
0
  // See comment in CreateSVGPathSegCurvetoCubicAbs
137
0
  RefPtr<DOMSVGPathSegCurvetoQuadraticRel> pathSeg =
138
0
    new DOMSVGPathSegCurvetoQuadraticRel(x1, y1, x, y);
139
0
  return pathSeg.forget();
140
0
}
141
142
already_AddRefed<DOMSVGPathSegArcAbs>
143
SVGPathElement::CreateSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag)
144
0
{
145
0
  // See comment in CreateSVGPathSegCurvetoCubicAbs
146
0
  RefPtr<DOMSVGPathSegArcAbs> pathSeg =
147
0
    new DOMSVGPathSegArcAbs(r1, r2, angle, largeArcFlag, sweepFlag, x, y);
148
0
  return pathSeg.forget();
149
0
}
150
151
already_AddRefed<DOMSVGPathSegArcRel>
152
SVGPathElement::CreateSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag)
153
0
{
154
0
  // See comment in CreateSVGPathSegCurvetoCubicAbs
155
0
  RefPtr<DOMSVGPathSegArcRel> pathSeg =
156
0
    new DOMSVGPathSegArcRel(r1, r2, angle, largeArcFlag, sweepFlag, x, y);
157
0
  return pathSeg.forget();
158
0
}
159
160
already_AddRefed<DOMSVGPathSegLinetoHorizontalAbs>
161
SVGPathElement::CreateSVGPathSegLinetoHorizontalAbs(float x)
162
0
{
163
0
  RefPtr<DOMSVGPathSegLinetoHorizontalAbs> pathSeg =
164
0
    new DOMSVGPathSegLinetoHorizontalAbs(x);
165
0
  return pathSeg.forget();
166
0
}
167
168
already_AddRefed<DOMSVGPathSegLinetoHorizontalRel>
169
SVGPathElement::CreateSVGPathSegLinetoHorizontalRel(float x)
170
0
{
171
0
  RefPtr<DOMSVGPathSegLinetoHorizontalRel> pathSeg =
172
0
    new DOMSVGPathSegLinetoHorizontalRel(x);
173
0
  return pathSeg.forget();
174
0
}
175
176
already_AddRefed<DOMSVGPathSegLinetoVerticalAbs>
177
SVGPathElement::CreateSVGPathSegLinetoVerticalAbs(float y)
178
0
{
179
0
  RefPtr<DOMSVGPathSegLinetoVerticalAbs> pathSeg =
180
0
    new DOMSVGPathSegLinetoVerticalAbs(y);
181
0
  return pathSeg.forget();
182
0
}
183
184
already_AddRefed<DOMSVGPathSegLinetoVerticalRel>
185
SVGPathElement::CreateSVGPathSegLinetoVerticalRel(float y)
186
0
{
187
0
  RefPtr<DOMSVGPathSegLinetoVerticalRel> pathSeg =
188
0
    new DOMSVGPathSegLinetoVerticalRel(y);
189
0
  return pathSeg.forget();
190
0
}
191
192
already_AddRefed<DOMSVGPathSegCurvetoCubicSmoothAbs>
193
SVGPathElement::CreateSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2)
194
0
{
195
0
  // See comment in CreateSVGPathSegCurvetoCubicAbs
196
0
  RefPtr<DOMSVGPathSegCurvetoCubicSmoothAbs> pathSeg =
197
0
    new DOMSVGPathSegCurvetoCubicSmoothAbs(x2, y2, x, y);
198
0
  return pathSeg.forget();
199
0
}
200
201
already_AddRefed<DOMSVGPathSegCurvetoCubicSmoothRel>
202
SVGPathElement::CreateSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2)
203
0
{
204
0
  // See comment in CreateSVGPathSegCurvetoCubicAbs
205
0
  RefPtr<DOMSVGPathSegCurvetoCubicSmoothRel> pathSeg =
206
0
    new DOMSVGPathSegCurvetoCubicSmoothRel(x2, y2, x, y);
207
0
  return pathSeg.forget();
208
0
}
209
210
already_AddRefed<DOMSVGPathSegCurvetoQuadraticSmoothAbs>
211
SVGPathElement::CreateSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y)
212
0
{
213
0
  RefPtr<DOMSVGPathSegCurvetoQuadraticSmoothAbs> pathSeg =
214
0
    new DOMSVGPathSegCurvetoQuadraticSmoothAbs(x, y);
215
0
  return pathSeg.forget();
216
0
}
217
218
already_AddRefed<DOMSVGPathSegCurvetoQuadraticSmoothRel>
219
SVGPathElement::CreateSVGPathSegCurvetoQuadraticSmoothRel(float x, float y)
220
0
{
221
0
  RefPtr<DOMSVGPathSegCurvetoQuadraticSmoothRel> pathSeg =
222
0
    new DOMSVGPathSegCurvetoQuadraticSmoothRel(x, y);
223
0
  return pathSeg.forget();
224
0
}
225
226
already_AddRefed<DOMSVGPathSegList>
227
SVGPathElement::PathSegList()
228
0
{
229
0
  return DOMSVGPathSegList::GetDOMWrapper(mD.GetBaseValKey(), this, false);
230
0
}
231
232
already_AddRefed<DOMSVGPathSegList>
233
SVGPathElement::AnimatedPathSegList()
234
0
{
235
0
  return DOMSVGPathSegList::GetDOMWrapper(mD.GetAnimValKey(), this, true);
236
0
}
237
238
//----------------------------------------------------------------------
239
// nsSVGElement methods
240
241
/* virtual */ bool
242
SVGPathElement::HasValidDimensions() const
243
0
{
244
0
  return !mD.GetAnimValue().IsEmpty();
245
0
}
246
247
//----------------------------------------------------------------------
248
// nsIContent methods
249
250
NS_IMETHODIMP_(bool)
251
SVGPathElement::IsAttributeMapped(const nsAtom* name) const
252
0
{
253
0
  static const MappedAttributeEntry* const map[] = {
254
0
    sMarkersMap
255
0
  };
256
0
257
0
  return FindAttributeDependence(name, map) ||
258
0
    SVGPathElementBase::IsAttributeMapped(name);
259
0
}
260
261
already_AddRefed<Path>
262
SVGPathElement::GetOrBuildPathForMeasuring()
263
0
{
264
0
  return mD.GetAnimValue().BuildPathForMeasuring();
265
0
}
266
267
//----------------------------------------------------------------------
268
// SVGGeometryElement methods
269
270
bool
271
SVGPathElement::AttributeDefinesGeometry(const nsAtom *aName)
272
0
{
273
0
  return aName == nsGkAtoms::d ||
274
0
         aName == nsGkAtoms::pathLength;
275
0
}
276
277
bool
278
SVGPathElement::IsMarkable()
279
0
{
280
0
  return true;
281
0
}
282
283
void
284
SVGPathElement::GetMarkPoints(nsTArray<nsSVGMark> *aMarks)
285
0
{
286
0
  mD.GetAnimValue().GetMarkerPositioningData(aMarks);
287
0
}
288
289
already_AddRefed<Path>
290
SVGPathElement::BuildPath(PathBuilder* aBuilder)
291
0
{
292
0
  // The Moz2D PathBuilder that our SVGPathData will be using only cares about
293
0
  // the fill rule. However, in order to fulfill the requirements of the SVG
294
0
  // spec regarding zero length sub-paths when square line caps are in use,
295
0
  // SVGPathData needs to know our stroke-linecap style and, if "square", then
296
0
  // also our stroke width. See the comment for
297
0
  // ApproximateZeroLengthSubpathSquareCaps for more info.
298
0
299
0
  uint8_t strokeLineCap = NS_STYLE_STROKE_LINECAP_BUTT;
300
0
  Float strokeWidth = 0;
301
0
302
0
  RefPtr<ComputedStyle> computedStyle =
303
0
    nsComputedDOMStyle::GetComputedStyleNoFlush(this, nullptr);
304
0
  if (computedStyle) {
305
0
    const nsStyleSVG* style = computedStyle->StyleSVG();
306
0
    // Note: the path that we return may be used for hit-testing, and SVG
307
0
    // exposes hit-testing of strokes that are not actually painted. For that
308
0
    // reason we do not check for eStyleSVGPaintType_None or check the stroke
309
0
    // opacity here.
310
0
    if (style->mStrokeLinecap != NS_STYLE_STROKE_LINECAP_BUTT) {
311
0
      strokeLineCap = style->mStrokeLinecap;
312
0
      strokeWidth =
313
0
        SVGContentUtils::GetStrokeWidth(this, computedStyle, nullptr);
314
0
    }
315
0
  }
316
0
317
0
  return mD.GetAnimValue().BuildPath(aBuilder, strokeLineCap, strokeWidth);
318
0
}
319
320
} // namespace dom
321
} // namespace mozilla