1 /* 2 * Copyright (C) 2014 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef SVGPathSegList_h 32 #define SVGPathSegList_h 33 34 #include "core/svg/SVGPathByteStream.h" 35 #include "core/svg/SVGPathSeg.h" 36 #include "core/svg/properties/SVGAnimatedProperty.h" 37 #include "core/svg/properties/SVGListPropertyHelper.h" 38 #include "wtf/WeakPtr.h" 39 40 namespace blink { 41 42 class SVGPathElement; 43 class SVGPathSegListTearOff; 44 45 class SVGPathSegList : public SVGListPropertyHelper<SVGPathSegList, SVGPathSeg> { 46 public: 47 typedef void PrimitiveType; 48 typedef SVGPathSeg ItemPropertyType; 49 typedef SVGPathSegListTearOff TearOffType; 50 typedef SVGListPropertyHelper<SVGPathSegList, SVGPathSeg> Base; 51 52 static PassRefPtr<SVGPathSegList> create(SVGPathElement* contextElement) 53 { 54 return adoptRef(new SVGPathSegList(contextElement)); 55 } 56 static PassRefPtr<SVGPathSegList> create() { ASSERT_NOT_REACHED(); return nullptr; } 57 58 virtual ~SVGPathSegList(); 59 60 const SVGPathByteStream* byteStream() const; 61 void clearByteStream() { m_byteStream.clear(); } 62 63 // SVGListPropertyHelper methods with |m_byteStream| sync: 64 65 ItemPropertyType* at(size_t index) 66 { 67 updateListFromByteStream(); 68 return Base::at(index); 69 } 70 71 size_t length() 72 { 73 updateListFromByteStream(); 74 return Base::length(); 75 } 76 77 bool isEmpty() const 78 { 79 if (m_listSyncedToByteStream) 80 return Base::isEmpty(); 81 82 return !m_byteStream || m_byteStream->isEmpty(); 83 } 84 85 void clear() 86 { 87 clearByteStream(); 88 Base::clear(); 89 } 90 91 void append(PassRefPtr<ItemPropertyType> passNewItem) 92 { 93 updateListFromByteStream(); 94 clearByteStream(); 95 Base::append(passNewItem); 96 } 97 98 PassRefPtr<ItemPropertyType> initialize(PassRefPtr<ItemPropertyType> passItem) 99 { 100 clearByteStream(); 101 return Base::initialize(passItem); 102 } 103 104 PassRefPtr<ItemPropertyType> getItem(size_t index, ExceptionState& exceptionState) 105 { 106 updateListFromByteStream(); 107 return Base::getItem(index, exceptionState); 108 } 109 110 PassRefPtr<ItemPropertyType> insertItemBefore(PassRefPtr<ItemPropertyType> passItem, size_t index) 111 { 112 updateListFromByteStream(); 113 clearByteStream(); 114 return Base::insertItemBefore(passItem, index); 115 } 116 117 PassRefPtr<ItemPropertyType> replaceItem(PassRefPtr<ItemPropertyType> passItem, size_t index, ExceptionState& exceptionState) 118 { 119 updateListFromByteStream(); 120 clearByteStream(); 121 return Base::replaceItem(passItem, index, exceptionState); 122 } 123 124 PassRefPtr<ItemPropertyType> removeItem(size_t index, ExceptionState& exceptionState) 125 { 126 updateListFromByteStream(); 127 clearByteStream(); 128 return Base::removeItem(index, exceptionState); 129 } 130 131 PassRefPtr<ItemPropertyType> appendItem(PassRefPtr<ItemPropertyType> passItem); 132 133 // SVGPropertyBase: 134 virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE; 135 virtual PassRefPtr<SVGPathSegList> clone() OVERRIDE; 136 virtual String valueAsString() const OVERRIDE; 137 void setValueAsString(const String&, ExceptionState&); 138 139 virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE; 140 virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*) OVERRIDE; 141 virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement*) OVERRIDE; 142 143 static AnimatedPropertyType classType() { return AnimatedPath; } 144 145 private: 146 SVGPathSegList(SVGPathElement*); 147 SVGPathSegList(SVGPathElement*, PassOwnPtr<SVGPathByteStream>); 148 149 friend class SVGPathSegListBuilder; 150 // This is only to be called from SVGPathSegListBuilder. 151 void appendWithoutByteStreamSync(PassRefPtr<ItemPropertyType> passNewItem) 152 { 153 Base::append(passNewItem); 154 } 155 156 void updateListFromByteStream(); 157 void invalidateList(); 158 159 // FIXME: This pointer should be removed after SVGPathSeg has a tear-off. 160 // FIXME: oilpan: This is raw-ptr to avoid reference cycles. 161 // SVGPathSegList is either owned by SVGAnimatedPath or 162 // SVGPathSegListTearOff. Both keep |contextElement| alive, 163 // so this ptr is always valid. 164 SVGPathElement* m_contextElement; 165 166 mutable OwnPtr<SVGPathByteStream> m_byteStream; 167 bool m_listSyncedToByteStream; 168 }; 169 170 inline PassRefPtr<SVGPathSegList> toSVGPathSegList(PassRefPtr<SVGPropertyBase> passBase) 171 { 172 RefPtr<SVGPropertyBase> base = passBase; 173 ASSERT(base->type() == SVGPathSegList::classType()); 174 return static_pointer_cast<SVGPathSegList>(base.release()); 175 } 176 177 } // namespace blink 178 179 #endif 180