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