Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/svg/SVGPolyElement.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 "SVGPolyElement.h"
8
#include "DOMSVGPointList.h"
9
#include "mozilla/gfx/2D.h"
10
#include "SVGContentUtils.h"
11
12
using namespace mozilla;
13
using namespace mozilla::gfx;
14
15
//----------------------------------------------------------------------
16
// Implementation
17
18
SVGPolyElement::SVGPolyElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
19
  : SVGPolyElementBase(std::move(aNodeInfo))
20
0
{
21
0
}
22
23
SVGPolyElement::~SVGPolyElement()
24
0
{
25
0
}
26
27
already_AddRefed<DOMSVGPointList>
28
SVGPolyElement::Points()
29
0
{
30
0
  void *key = mPoints.GetBaseValKey();
31
0
  RefPtr<DOMSVGPointList> points = DOMSVGPointList::GetDOMWrapper(key, this, false);
32
0
  return points.forget();
33
0
}
34
35
already_AddRefed<DOMSVGPointList>
36
SVGPolyElement::AnimatedPoints()
37
0
{
38
0
  void *key = mPoints.GetAnimValKey();
39
0
  RefPtr<DOMSVGPointList> points = DOMSVGPointList::GetDOMWrapper(key, this, true);
40
0
  return points.forget();
41
0
}
42
43
44
//----------------------------------------------------------------------
45
// nsIContent methods
46
47
NS_IMETHODIMP_(bool)
48
SVGPolyElement::IsAttributeMapped(const nsAtom* name) const
49
0
{
50
0
  static const MappedAttributeEntry* const map[] = {
51
0
    sMarkersMap
52
0
  };
53
0
54
0
  return FindAttributeDependence(name, map) ||
55
0
    SVGPolyElementBase::IsAttributeMapped(name);
56
0
}
57
58
//----------------------------------------------------------------------
59
// nsSVGElement methods
60
61
/* virtual */ bool
62
SVGPolyElement::HasValidDimensions() const
63
0
{
64
0
  return !mPoints.GetAnimValue().IsEmpty();
65
0
}
66
67
//----------------------------------------------------------------------
68
// SVGGeometryElement methods
69
70
bool
71
SVGPolyElement::AttributeDefinesGeometry(const nsAtom *aName)
72
0
{
73
0
  if (aName == nsGkAtoms::points)
74
0
    return true;
75
0
76
0
  return false;
77
0
}
78
79
void
80
SVGPolyElement::GetMarkPoints(nsTArray<nsSVGMark> *aMarks)
81
0
{
82
0
  const SVGPointList &points = mPoints.GetAnimValue();
83
0
84
0
  if (!points.Length())
85
0
    return;
86
0
87
0
  float px = points[0].mX, py = points[0].mY, prevAngle = 0.0;
88
0
89
0
  aMarks->AppendElement(nsSVGMark(px, py, 0, nsSVGMark::eStart));
90
0
91
0
  for (uint32_t i = 1; i < points.Length(); ++i) {
92
0
    float x = points[i].mX;
93
0
    float y = points[i].mY;
94
0
    float angle = atan2(y-py, x-px);
95
0
96
0
    // Vertex marker.
97
0
    if (i == 1) {
98
0
      aMarks->ElementAt(0).angle = angle;
99
0
    } else {
100
0
      aMarks->ElementAt(aMarks->Length() - 1).angle =
101
0
        SVGContentUtils::AngleBisect(prevAngle, angle);
102
0
    }
103
0
104
0
    aMarks->AppendElement(nsSVGMark(x, y, 0, nsSVGMark::eMid));
105
0
106
0
    prevAngle = angle;
107
0
    px = x;
108
0
    py = y;
109
0
  }
110
0
111
0
  aMarks->LastElement().angle = prevAngle;
112
0
  aMarks->LastElement().type = nsSVGMark::eEnd;
113
0
}
114
115
bool
116
SVGPolyElement::GetGeometryBounds(Rect* aBounds,
117
                                  const StrokeOptions& aStrokeOptions,
118
                                  const Matrix& aToBoundsSpace,
119
                                  const Matrix* aToNonScalingStrokeSpace)
120
0
{
121
0
  const SVGPointList &points = mPoints.GetAnimValue();
122
0
123
0
  if (!points.Length()) {
124
0
    // Rendering of the element is disabled
125
0
    aBounds->SetEmpty();
126
0
    return true;
127
0
  }
128
0
129
0
  if (aStrokeOptions.mLineWidth > 0 || aToNonScalingStrokeSpace) {
130
0
    // We don't handle non-scaling-stroke or stroke-miterlimit etc. yet
131
0
    return false;
132
0
  }
133
0
134
0
  if (aToBoundsSpace.IsRectilinear()) {
135
0
    // We can avoid transforming each point and just transform the result.
136
0
    // Important for large point lists.
137
0
    Rect bounds(points[0], Size());
138
0
    for (uint32_t i = 1; i < points.Length(); ++i) {
139
0
      bounds.ExpandToEnclose(points[i]);
140
0
    }
141
0
    *aBounds = aToBoundsSpace.TransformBounds(bounds);
142
0
  } else {
143
0
    *aBounds = Rect(aToBoundsSpace.TransformPoint(points[0]), Size());
144
0
    for (uint32_t i = 1; i < points.Length(); ++i) {
145
0
      aBounds->ExpandToEnclose(aToBoundsSpace.TransformPoint(points[i]));
146
0
    }
147
0
  }
148
0
  return true;
149
0
}
150