SVGPathSegment.cpp (4840B)
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/SVGPathSegment.h" 8 9 #include "SVGPathSegUtils.h" 10 #include "mozilla/dom/SVGPathElementBinding.h" 11 12 namespace mozilla::dom { 13 14 JSObject* SVGPathSegment::WrapObject(JSContext* aCx, 15 JS::Handle<JSObject*> aGivenProto) { 16 return SVGPathSegment_Binding::Wrap(aCx, this, aGivenProto); 17 } 18 19 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(SVGPathSegment, mSVGPathElement) 20 21 //---------------------------------------------------------------------- 22 // Implementation 23 void SVGPathSegment::AppendEndPoint(const StyleEndPoint<StyleCSSFloat>& point) { 24 if (point.IsToPosition()) { 25 const auto& pos = point.AsToPosition(); 26 mValues.AppendElement(pos.horizontal); 27 mValues.AppendElement(pos.vertical); 28 } else if (point.IsByCoordinate()) { 29 const auto& coord = point.AsByCoordinate(); 30 mValues.AppendElement(coord.x); 31 mValues.AppendElement(coord.y); 32 } 33 } 34 35 void SVGPathSegment::AppendControlPoint( 36 const StyleCurveControlPoint<StyleCSSFloat>& point) { 37 if (point.IsAbsolute()) { 38 const auto& pos = point.AsAbsolute(); 39 mValues.AppendElement(pos.horizontal); 40 mValues.AppendElement(pos.vertical); 41 } else if (point.IsRelative()) { 42 const auto& rel_point = point.AsRelative(); 43 mValues.AppendElement(rel_point.coord.x); 44 mValues.AppendElement(rel_point.coord.y); 45 } 46 } 47 48 SVGPathSegment::SVGPathSegment(SVGPathElement* aSVGPathElement, 49 const StylePathCommand& aCommand) 50 : mSVGPathElement(aSVGPathElement) { 51 switch (aCommand.tag) { 52 case StylePathCommand::Tag::Close: 53 mCommand.AssignLiteral("Z"); 54 break; 55 case StylePathCommand::Tag::Move: 56 mCommand.AssignLiteral(aCommand.move.point.IsToPosition() ? "M" : "m"); 57 AppendEndPoint(aCommand.move.point); 58 break; 59 case StylePathCommand::Tag::Line: 60 mCommand.AssignLiteral(aCommand.line.point.IsToPosition() ? "L" : "l"); 61 AppendEndPoint(aCommand.line.point); 62 break; 63 case StylePathCommand::Tag::CubicCurve: 64 mCommand.AssignLiteral(aCommand.cubic_curve.point.IsToPosition() ? "C" 65 : "c"); 66 AppendControlPoint(aCommand.cubic_curve.control1); 67 AppendControlPoint(aCommand.cubic_curve.control2); 68 AppendEndPoint(aCommand.cubic_curve.point); 69 break; 70 case StylePathCommand::Tag::QuadCurve: 71 mCommand.AssignLiteral(aCommand.quad_curve.point.IsToPosition() ? "Q" 72 : "q"); 73 AppendControlPoint(aCommand.quad_curve.control1); 74 AppendEndPoint(aCommand.quad_curve.point); 75 break; 76 case StylePathCommand::Tag::Arc: { 77 mCommand.AssignLiteral(aCommand.arc.point.IsToPosition() ? "A" : "a"); 78 const auto r = aCommand.arc.radii.ToGfxPoint(); 79 mValues.AppendElement(r.x); 80 mValues.AppendElement(r.y); 81 mValues.AppendElement(aCommand.arc.rotate); 82 mValues.AppendElement(aCommand.arc.arc_size == StyleArcSize::Large); 83 mValues.AppendElement(aCommand.arc.arc_sweep == StyleArcSweep::Cw); 84 AppendEndPoint(aCommand.arc.point); 85 break; 86 } 87 case StylePathCommand::Tag::HLine: 88 mCommand.AssignLiteral(aCommand.h_line.x.IsToPosition() ? "H" : "h"); 89 mValues.AppendElement(aCommand.h_line.x.ToGfxCoord()); 90 break; 91 case StylePathCommand::Tag::VLine: 92 mCommand.AssignLiteral(aCommand.v_line.y.IsToPosition() ? "V" : "v"); 93 mValues.AppendElement(aCommand.v_line.y.ToGfxCoord()); 94 break; 95 case StylePathCommand::Tag::SmoothCubic: 96 mCommand.AssignLiteral(aCommand.smooth_cubic.point.IsToPosition() ? "S" 97 : "s"); 98 AppendControlPoint(aCommand.smooth_cubic.control2); 99 AppendEndPoint(aCommand.smooth_cubic.point); 100 break; 101 case StylePathCommand::Tag::SmoothQuad: 102 mCommand.AssignLiteral(aCommand.smooth_quad.point.IsToPosition() ? "T" 103 : "t"); 104 AppendEndPoint(aCommand.smooth_quad.point); 105 break; 106 } 107 } 108 109 void SVGPathSegment::GetType(DOMString& aType) { 110 aType.SetKnownLiveString(mCommand); 111 } 112 113 void SVGPathSegment::SetType(const nsAString& aType) { mCommand = aType; } 114 115 void SVGPathSegment::GetValues(nsTArray<float>& aValues) { 116 aValues = mValues.Clone(); 117 } 118 119 void SVGPathSegment::SetValues(const nsTArray<float>& aValues) { 120 mValues = aValues.Clone(); 121 } 122 123 } // namespace mozilla::dom