Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/svg/SVGEllipseElement.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/SVGEllipseElement.h"
8
#include "mozilla/dom/SVGEllipseElementBinding.h"
9
#include "mozilla/dom/SVGLengthBinding.h"
10
#include "mozilla/gfx/2D.h"
11
#include "mozilla/gfx/PathHelpers.h"
12
#include "mozilla/RefPtr.h"
13
14
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(Ellipse)
15
16
using namespace mozilla::gfx;
17
18
namespace mozilla {
19
namespace dom {
20
21
JSObject*
22
SVGEllipseElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
23
0
{
24
0
  return SVGEllipseElement_Binding::Wrap(aCx, this, aGivenProto);
25
0
}
26
27
nsSVGElement::LengthInfo SVGEllipseElement::sLengthInfo[4] =
28
{
29
  { &nsGkAtoms::cx, 0, SVGLength_Binding::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X },
30
  { &nsGkAtoms::cy, 0, SVGLength_Binding::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y },
31
  { &nsGkAtoms::rx, 0, SVGLength_Binding::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X },
32
  { &nsGkAtoms::ry, 0, SVGLength_Binding::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y },
33
};
34
35
//----------------------------------------------------------------------
36
// Implementation
37
38
SVGEllipseElement::SVGEllipseElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
39
  : SVGEllipseElementBase(std::move(aNodeInfo))
40
0
{
41
0
}
42
43
//----------------------------------------------------------------------
44
// nsINode methods
45
46
NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGEllipseElement)
47
48
//----------------------------------------------------------------------
49
// nsIDOMSVGEllipseElement methods
50
51
already_AddRefed<SVGAnimatedLength>
52
SVGEllipseElement::Cx()
53
0
{
54
0
  return mLengthAttributes[CX].ToDOMAnimatedLength(this);
55
0
}
56
57
already_AddRefed<SVGAnimatedLength>
58
SVGEllipseElement::Cy()
59
0
{
60
0
  return mLengthAttributes[CY].ToDOMAnimatedLength(this);
61
0
}
62
63
already_AddRefed<SVGAnimatedLength>
64
SVGEllipseElement::Rx()
65
0
{
66
0
  return mLengthAttributes[RX].ToDOMAnimatedLength(this);
67
0
}
68
69
already_AddRefed<SVGAnimatedLength>
70
SVGEllipseElement::Ry()
71
0
{
72
0
  return mLengthAttributes[RY].ToDOMAnimatedLength(this);
73
0
}
74
75
//----------------------------------------------------------------------
76
// nsSVGElement methods
77
78
/* virtual */ bool
79
SVGEllipseElement::HasValidDimensions() const
80
0
{
81
0
  return mLengthAttributes[RX].IsExplicitlySet() &&
82
0
         mLengthAttributes[RX].GetAnimValInSpecifiedUnits() > 0 &&
83
0
         mLengthAttributes[RY].IsExplicitlySet() &&
84
0
         mLengthAttributes[RY].GetAnimValInSpecifiedUnits() > 0;
85
0
}
86
87
nsSVGElement::LengthAttributesInfo
88
SVGEllipseElement::GetLengthInfo()
89
0
{
90
0
  return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
91
0
                              ArrayLength(sLengthInfo));
92
0
}
93
94
//----------------------------------------------------------------------
95
// SVGGeometryElement methods
96
97
bool
98
SVGEllipseElement::GetGeometryBounds(Rect* aBounds,
99
                                     const StrokeOptions& aStrokeOptions,
100
                                     const Matrix& aToBoundsSpace,
101
                                     const Matrix* aToNonScalingStrokeSpace)
102
0
{
103
0
  float x, y, rx, ry;
104
0
  GetAnimatedLengthValues(&x, &y, &rx, &ry, nullptr);
105
0
106
0
  if (rx <= 0.f || ry <= 0.f) {
107
0
    // Rendering of the element is disabled
108
0
    *aBounds = Rect(aToBoundsSpace.TransformPoint(Point(x, y)), Size());
109
0
    return true;
110
0
  }
111
0
112
0
  if (aToBoundsSpace.IsRectilinear()) {
113
0
    // Optimize the case where we can treat the ellipse as a rectangle and
114
0
    // still get tight bounds.
115
0
    if (aStrokeOptions.mLineWidth > 0.f) {
116
0
      if (aToNonScalingStrokeSpace) {
117
0
        if (aToNonScalingStrokeSpace->IsRectilinear()) {
118
0
          MOZ_ASSERT(!aToNonScalingStrokeSpace->IsSingular());
119
0
          Rect userBounds(x - rx, y - ry, 2 * rx, 2 * ry);
120
0
          SVGContentUtils::RectilinearGetStrokeBounds(
121
0
            userBounds, aToBoundsSpace, *aToNonScalingStrokeSpace,
122
0
            aStrokeOptions.mLineWidth, aBounds);
123
0
          return true;
124
0
        }
125
0
        return false;
126
0
      }
127
0
      rx += aStrokeOptions.mLineWidth / 2.f;
128
0
      ry += aStrokeOptions.mLineWidth / 2.f;
129
0
    }
130
0
    Rect rect(x - rx, y - ry, 2 * rx, 2 * ry);
131
0
    *aBounds = aToBoundsSpace.TransformBounds(rect);
132
0
    return true;
133
0
  }
134
0
135
0
  return false;
136
0
}
137
138
already_AddRefed<Path>
139
SVGEllipseElement::BuildPath(PathBuilder* aBuilder)
140
0
{
141
0
  float x, y, rx, ry;
142
0
  GetAnimatedLengthValues(&x, &y, &rx, &ry, nullptr);
143
0
144
0
  if (rx <= 0.0f || ry <= 0.0f) {
145
0
    return nullptr;
146
0
  }
147
0
148
0
  EllipseToBezier(aBuilder, Point(x, y), Size(rx, ry));
149
0
150
0
  return aBuilder->Finish();
151
0
}
152
153
} // namespace dom
154
} // namespace mozilla