SVGGradientElement.cpp (8295B)
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/SVGGradientElement.h" 8 9 #include "DOMSVGAnimatedTransformList.h" 10 #include "mozilla/AlreadyAddRefed.h" 11 #include "mozilla/dom/SVGElement.h" 12 #include "mozilla/dom/SVGGradientElementBinding.h" 13 #include "mozilla/dom/SVGLengthBinding.h" 14 #include "mozilla/dom/SVGLinearGradientElementBinding.h" 15 #include "mozilla/dom/SVGRadialGradientElementBinding.h" 16 #include "mozilla/dom/SVGUnitTypesBinding.h" 17 #include "nsGkAtoms.h" 18 19 NS_IMPL_NS_NEW_SVG_ELEMENT(LinearGradient) 20 NS_IMPL_NS_NEW_SVG_ELEMENT(RadialGradient) 21 22 namespace mozilla::dom { 23 24 using namespace SVGGradientElement_Binding; 25 using namespace SVGUnitTypes_Binding; 26 27 //--------------------- Gradients------------------------ 28 29 SVGEnumMapping SVGGradientElement::sSpreadMethodMap[] = { 30 {nsGkAtoms::pad, SVG_SPREADMETHOD_PAD}, 31 {nsGkAtoms::reflect, SVG_SPREADMETHOD_REFLECT}, 32 {nsGkAtoms::repeat, SVG_SPREADMETHOD_REPEAT}, 33 {nullptr, 0}}; 34 35 SVGElement::EnumInfo SVGGradientElement::sEnumInfo[2] = { 36 {nsGkAtoms::gradientUnits, sSVGUnitTypesMap, 37 SVG_UNIT_TYPE_OBJECTBOUNDINGBOX}, 38 {nsGkAtoms::spreadMethod, sSpreadMethodMap, SVG_SPREADMETHOD_PAD}}; 39 40 SVGElement::StringInfo SVGGradientElement::sStringInfo[2] = { 41 {nsGkAtoms::href, kNameSpaceID_None, true}, 42 {nsGkAtoms::href, kNameSpaceID_XLink, true}}; 43 44 //---------------------------------------------------------------------- 45 // Implementation 46 47 SVGGradientElement::SVGGradientElement( 48 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) 49 : SVGGradientElementBase(std::move(aNodeInfo)) {} 50 51 //---------------------------------------------------------------------- 52 // SVGElement methods 53 54 SVGElement::EnumAttributesInfo SVGGradientElement::GetEnumInfo() { 55 return EnumAttributesInfo(mEnumAttributes, sEnumInfo, std::size(sEnumInfo)); 56 } 57 58 SVGElement::StringAttributesInfo SVGGradientElement::GetStringInfo() { 59 return StringAttributesInfo(mStringAttributes, sStringInfo, 60 std::size(sStringInfo)); 61 } 62 63 already_AddRefed<DOMSVGAnimatedEnumeration> 64 SVGGradientElement::GradientUnits() { 65 return mEnumAttributes[GRADIENTUNITS].ToDOMAnimatedEnum(this); 66 } 67 68 already_AddRefed<DOMSVGAnimatedTransformList> 69 SVGGradientElement::GradientTransform() { 70 // We're creating a DOM wrapper, so we must tell GetAnimatedTransformList 71 // to allocate the DOMSVGAnimatedTransformList if it hasn't already done so: 72 return DOMSVGAnimatedTransformList::GetDOMWrapper( 73 GetAnimatedTransformList(DO_ALLOCATE), this); 74 } 75 76 already_AddRefed<DOMSVGAnimatedEnumeration> SVGGradientElement::SpreadMethod() { 77 return mEnumAttributes[SPREADMETHOD].ToDOMAnimatedEnum(this); 78 } 79 80 already_AddRefed<DOMSVGAnimatedString> SVGGradientElement::Href() { 81 return mStringAttributes[HREF].IsExplicitlySet() || 82 !mStringAttributes[XLINK_HREF].IsExplicitlySet() 83 ? mStringAttributes[HREF].ToDOMAnimatedString(this) 84 : mStringAttributes[XLINK_HREF].ToDOMAnimatedString(this); 85 } 86 87 //---------------------Linear Gradients------------------------ 88 89 JSObject* SVGLinearGradientElement::WrapNode( 90 JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { 91 return SVGLinearGradientElement_Binding::Wrap(aCx, this, aGivenProto); 92 } 93 94 SVGElement::LengthInfo SVGLinearGradientElement::sLengthInfo[4] = { 95 {nsGkAtoms::x1, 0, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE, 96 SVGContentUtils::X}, 97 {nsGkAtoms::y1, 0, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE, 98 SVGContentUtils::Y}, 99 {nsGkAtoms::x2, 100, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE, 100 SVGContentUtils::X}, 101 {nsGkAtoms::y2, 0, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE, 102 SVGContentUtils::Y}, 103 }; 104 105 //---------------------------------------------------------------------- 106 // Implementation 107 108 SVGLinearGradientElement::SVGLinearGradientElement( 109 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) 110 : SVGLinearGradientElementBase(std::move(aNodeInfo)) {} 111 112 //---------------------------------------------------------------------- 113 // nsINode methods 114 115 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGLinearGradientElement) 116 117 //---------------------------------------------------------------------- 118 119 already_AddRefed<DOMSVGAnimatedLength> SVGLinearGradientElement::X1() { 120 return mLengthAttributes[ATTR_X1].ToDOMAnimatedLength(this); 121 } 122 123 already_AddRefed<DOMSVGAnimatedLength> SVGLinearGradientElement::Y1() { 124 return mLengthAttributes[ATTR_Y1].ToDOMAnimatedLength(this); 125 } 126 127 already_AddRefed<DOMSVGAnimatedLength> SVGLinearGradientElement::X2() { 128 return mLengthAttributes[ATTR_X2].ToDOMAnimatedLength(this); 129 } 130 131 already_AddRefed<DOMSVGAnimatedLength> SVGLinearGradientElement::Y2() { 132 return mLengthAttributes[ATTR_Y2].ToDOMAnimatedLength(this); 133 } 134 135 //---------------------------------------------------------------------- 136 // SVGElement methods 137 138 SVGAnimatedTransformList* SVGGradientElement::GetAnimatedTransformList( 139 uint32_t aFlags) { 140 if (!mGradientTransform && (aFlags & DO_ALLOCATE)) { 141 mGradientTransform = MakeUnique<SVGAnimatedTransformList>(); 142 } 143 return mGradientTransform.get(); 144 } 145 146 SVGElement::LengthAttributesInfo SVGLinearGradientElement::GetLengthInfo() { 147 return LengthAttributesInfo(mLengthAttributes, sLengthInfo, 148 std::size(sLengthInfo)); 149 } 150 151 //-------------------------- Radial Gradients ---------------------------- 152 153 JSObject* SVGRadialGradientElement::WrapNode( 154 JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { 155 return SVGRadialGradientElement_Binding::Wrap(aCx, this, aGivenProto); 156 } 157 158 SVGElement::LengthInfo SVGRadialGradientElement::sLengthInfo[6] = { 159 {nsGkAtoms::cx, 50, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE, 160 SVGContentUtils::X}, 161 {nsGkAtoms::cy, 50, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE, 162 SVGContentUtils::Y}, 163 {nsGkAtoms::r, 50, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE, 164 SVGContentUtils::XY}, 165 {nsGkAtoms::fx, 50, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE, 166 SVGContentUtils::X}, 167 {nsGkAtoms::fy, 50, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE, 168 SVGContentUtils::Y}, 169 {nsGkAtoms::fr, 0, SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE, 170 SVGContentUtils::XY}, 171 }; 172 173 //---------------------------------------------------------------------- 174 // Implementation 175 176 SVGRadialGradientElement::SVGRadialGradientElement( 177 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) 178 : SVGRadialGradientElementBase(std::move(aNodeInfo)) {} 179 180 //---------------------------------------------------------------------- 181 // nsINode methods 182 183 NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGRadialGradientElement) 184 185 //---------------------------------------------------------------------- 186 187 already_AddRefed<DOMSVGAnimatedLength> SVGRadialGradientElement::Cx() { 188 return mLengthAttributes[ATTR_CX].ToDOMAnimatedLength(this); 189 } 190 191 already_AddRefed<DOMSVGAnimatedLength> SVGRadialGradientElement::Cy() { 192 return mLengthAttributes[ATTR_CY].ToDOMAnimatedLength(this); 193 } 194 195 already_AddRefed<DOMSVGAnimatedLength> SVGRadialGradientElement::R() { 196 return mLengthAttributes[ATTR_R].ToDOMAnimatedLength(this); 197 } 198 199 already_AddRefed<DOMSVGAnimatedLength> SVGRadialGradientElement::Fx() { 200 return mLengthAttributes[ATTR_FX].ToDOMAnimatedLength(this); 201 } 202 203 already_AddRefed<DOMSVGAnimatedLength> SVGRadialGradientElement::Fy() { 204 return mLengthAttributes[ATTR_FY].ToDOMAnimatedLength(this); 205 } 206 207 already_AddRefed<DOMSVGAnimatedLength> SVGRadialGradientElement::Fr() { 208 return mLengthAttributes[ATTR_FR].ToDOMAnimatedLength(this); 209 } 210 211 bool SVGGradientElement::IsAttributeMapped(const nsAtom* aAttribute) const { 212 return aAttribute == nsGkAtoms::gradientTransform || 213 SVGElement::IsAttributeMapped(aAttribute); 214 } 215 216 //---------------------------------------------------------------------- 217 // SVGElement methods 218 219 SVGElement::LengthAttributesInfo SVGRadialGradientElement::GetLengthInfo() { 220 return LengthAttributesInfo(mLengthAttributes, sLengthInfo, 221 std::size(sLengthInfo)); 222 } 223 224 } // namespace mozilla::dom