SVGPreserveAspectRatio.cpp (4498B)
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 "SVGPreserveAspectRatio.h" 8 9 #include "SVGAnimatedPreserveAspectRatio.h" 10 #include "mozilla/dom/SVGPreserveAspectRatioBinding.h" 11 #include "nsContentUtils.h" 12 #include "nsWhitespaceTokenizer.h" 13 14 using namespace mozilla::dom; 15 using namespace mozilla::dom::SVGPreserveAspectRatio_Binding; 16 17 namespace mozilla { 18 19 NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(DOMSVGPreserveAspectRatio, 20 mSVGElement) 21 22 static const char* sAlignStrings[] = { 23 "none", "xMinYMin", "xMidYMin", "xMaxYMin", "xMinYMid", 24 "xMidYMid", "xMaxYMid", "xMinYMax", "xMidYMax", "xMaxYMax"}; 25 26 static const char* sMeetOrSliceStrings[] = {"meet", "slice"}; 27 28 static uint16_t GetAlignForString(const nsAString& aAlignString) { 29 for (uint32_t i = 0; i < std::size(sAlignStrings); i++) { 30 if (aAlignString.EqualsASCII(sAlignStrings[i])) { 31 return (i + SVG_ALIGN_MIN_VALID); 32 } 33 } 34 35 return SVG_PRESERVEASPECTRATIO_UNKNOWN; 36 } 37 38 static uint16_t GetMeetOrSliceForString(const nsAString& aMeetOrSlice) { 39 for (uint32_t i = 0; i < std::size(sMeetOrSliceStrings); i++) { 40 if (aMeetOrSlice.EqualsASCII(sMeetOrSliceStrings[i])) { 41 return (i + SVG_MEETORSLICE_MIN_VALID); 42 } 43 } 44 45 return SVG_MEETORSLICE_UNKNOWN; 46 } 47 48 /* static */ 49 nsresult SVGPreserveAspectRatio::FromString(const nsAString& aString, 50 SVGPreserveAspectRatio* aValue) { 51 nsWhitespaceTokenizerTemplate<nsContentUtils::IsHTMLWhitespace> tokenizer( 52 aString); 53 if (tokenizer.whitespaceBeforeFirstToken() || !tokenizer.hasMoreTokens()) { 54 return NS_ERROR_DOM_SYNTAX_ERR; 55 } 56 const nsAString& token = tokenizer.nextToken(); 57 58 SVGPreserveAspectRatio val; 59 60 if (!val.SetAlign(GetAlignForString(token))) { 61 return NS_ERROR_DOM_SYNTAX_ERR; 62 } 63 64 if (tokenizer.hasMoreTokens()) { 65 if (!val.SetMeetOrSlice(GetMeetOrSliceForString(tokenizer.nextToken()))) { 66 return NS_ERROR_DOM_SYNTAX_ERR; 67 } 68 } else { 69 val.SetMeetOrSlice(SVG_MEETORSLICE_MEET); 70 } 71 72 if (tokenizer.whitespaceAfterCurrentToken()) { 73 return NS_ERROR_DOM_SYNTAX_ERR; 74 } 75 76 *aValue = val; 77 return NS_OK; 78 } 79 80 void SVGPreserveAspectRatio::ToString(nsAString& aValueAsString) const { 81 MOZ_ASSERT(mAlign >= SVG_ALIGN_MIN_VALID && mAlign <= SVG_ALIGN_MAX_VALID, 82 "Unknown align"); 83 aValueAsString.AssignASCII(sAlignStrings[mAlign - SVG_ALIGN_MIN_VALID]); 84 85 if (mAlign != uint8_t(SVG_PRESERVEASPECTRATIO_NONE)) { 86 MOZ_ASSERT(mMeetOrSlice >= SVG_MEETORSLICE_MIN_VALID && 87 mMeetOrSlice <= SVG_MEETORSLICE_MAX_VALID, 88 "Unknown meetOrSlice"); 89 aValueAsString.Append(' '); 90 aValueAsString.AppendASCII( 91 sMeetOrSliceStrings[mMeetOrSlice - SVG_MEETORSLICE_MIN_VALID]); 92 } 93 } 94 95 bool SVGPreserveAspectRatio::operator==( 96 const SVGPreserveAspectRatio& aOther) const { 97 return mAlign == aOther.mAlign && mMeetOrSlice == aOther.mMeetOrSlice; 98 } 99 100 JSObject* DOMSVGPreserveAspectRatio::WrapObject( 101 JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { 102 return mozilla::dom::SVGPreserveAspectRatio_Binding::Wrap(aCx, this, 103 aGivenProto); 104 } 105 106 uint16_t DOMSVGPreserveAspectRatio::Align() { 107 if (mIsBaseValue) { 108 return mVal->GetBaseValue().GetAlign(); 109 } 110 111 mSVGElement->FlushAnimations(); 112 return mVal->GetAnimValue().GetAlign(); 113 } 114 115 void DOMSVGPreserveAspectRatio::SetAlign(uint16_t aAlign, ErrorResult& aRv) { 116 if (!mIsBaseValue) { 117 aRv.ThrowNoModificationAllowedError("Animated values cannot be set"); 118 return; 119 } 120 aRv = mVal->SetBaseAlign(aAlign, mSVGElement); 121 } 122 123 uint16_t DOMSVGPreserveAspectRatio::MeetOrSlice() { 124 if (mIsBaseValue) { 125 return mVal->GetBaseValue().GetMeetOrSlice(); 126 } 127 128 mSVGElement->FlushAnimations(); 129 return mVal->GetAnimValue().GetMeetOrSlice(); 130 } 131 132 void DOMSVGPreserveAspectRatio::SetMeetOrSlice(uint16_t aMeetOrSlice, 133 ErrorResult& aRv) { 134 if (!mIsBaseValue) { 135 aRv.ThrowNoModificationAllowedError("Animated values cannot be set"); 136 return; 137 } 138 aRv = mVal->SetBaseMeetOrSlice(aMeetOrSlice, mSVGElement); 139 } 140 141 } // namespace mozilla