SVGPolygonElement.cpp (2791B)
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/SVGPolygonElement.h" 8 9 #include "SVGContentUtils.h" 10 #include "mozilla/dom/SVGAnimatedLength.h" 11 #include "mozilla/dom/SVGPolygonElementBinding.h" 12 #include "mozilla/gfx/2D.h" 13 14 using namespace mozilla::gfx; 15 16 NS_IMPL_NS_NEW_SVG_ELEMENT(Polygon) 17 18 namespace mozilla::dom { 19 20 JSObject* SVGPolygonElement::WrapNode(JSContext* aCx, 21 JS::Handle<JSObject*> aGivenProto) { 22 return SVGPolygonElement_Binding::Wrap(aCx, this, aGivenProto); 23 } 24 25 //---------------------------------------------------------------------- 26 // Implementation 27 28 SVGPolygonElement::SVGPolygonElement( 29 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) 30 : SVGPolygonElementBase(std::move(aNodeInfo)) {} 31 32 //---------------------------------------------------------------------- 33 // nsINode methods 34 35 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGPolygonElement) 36 37 //---------------------------------------------------------------------- 38 // SVGGeometryElement methods 39 40 void SVGPolygonElement::GetMarkPoints(nsTArray<SVGMark>* aMarks) { 41 SVGPolyElement::GetMarkPoints(aMarks); 42 43 if (aMarks->IsEmpty() || aMarks->LastElement().type != SVGMark::eEnd) { 44 return; 45 } 46 47 SVGMark* endMark = &aMarks->LastElement(); 48 SVGMark* startMark = &aMarks->ElementAt(0); 49 float angle = 50 std::atan2(startMark->y - endMark->y, startMark->x - endMark->x); 51 52 endMark->type = SVGMark::eMid; 53 endMark->angle = SVGContentUtils::AngleBisect(angle, endMark->angle); 54 startMark->angle = SVGContentUtils::AngleBisect(angle, startMark->angle); 55 // for a polygon (as opposed to a polyline) there's an implicit extra point 56 // co-located with the start point that SVGPolyElement::GetMarkPoints 57 // doesn't return 58 aMarks->AppendElement( 59 SVGMark(startMark->x, startMark->y, startMark->angle, SVGMark::eEnd)); 60 } 61 62 already_AddRefed<Path> SVGPolygonElement::BuildPath(PathBuilder* aBuilder) { 63 const SVGPointList& points = mPoints.GetAnimValue(); 64 65 if (points.IsEmpty()) { 66 return nullptr; 67 } 68 69 float zoom = UserSpaceMetrics::GetZoom(this); 70 71 Point zoomedPoint = Point(points[0]) * zoom; 72 if (!zoomedPoint.IsFinite()) { 73 return nullptr; 74 } 75 aBuilder->MoveTo(zoomedPoint); 76 for (uint32_t i = 1; i < points.Length(); ++i) { 77 zoomedPoint = Point(points[i]) * zoom; 78 if (!zoomedPoint.IsFinite()) { 79 return nullptr; 80 } 81 aBuilder->LineTo(zoomedPoint); 82 } 83 84 aBuilder->Close(); 85 86 return aBuilder->Finish(); 87 } 88 89 } // namespace mozilla::dom