OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde .org> | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde .org> |
3 * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> | 3 * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> |
4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> | 4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> |
5 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 5 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
6 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
(...skipping 18 matching lines...) Expand all Loading... | |
29 #include "core/svg/SVGPathBlender.h" | 29 #include "core/svg/SVGPathBlender.h" |
30 #include "core/svg/SVGPathByteStream.h" | 30 #include "core/svg/SVGPathByteStream.h" |
31 #include "core/svg/SVGPathByteStreamBuilder.h" | 31 #include "core/svg/SVGPathByteStreamBuilder.h" |
32 #include "core/svg/SVGPathByteStreamSource.h" | 32 #include "core/svg/SVGPathByteStreamSource.h" |
33 #include "core/svg/SVGPathParser.h" | 33 #include "core/svg/SVGPathParser.h" |
34 #include "core/svg/SVGPathUtilities.h" | 34 #include "core/svg/SVGPathUtilities.h" |
35 #include "platform/graphics/Path.h" | 35 #include "platform/graphics/Path.h" |
36 | 36 |
37 namespace blink { | 37 namespace blink { |
38 | 38 |
39 namespace { | |
40 | |
41 PassOwnPtr<SVGPathByteStream> blendPathByteStreams(const SVGPathByteStream& from Stream, const SVGPathByteStream& toStream, float progress) | |
42 { | |
43 OwnPtr<SVGPathByteStream> resultStream = SVGPathByteStream::create(); | |
44 SVGPathByteStreamBuilder builder(*resultStream); | |
45 SVGPathByteStreamSource fromSource(fromStream); | |
46 SVGPathByteStreamSource toSource(toStream); | |
47 SVGPathBlender blender(&fromSource, &toSource, &builder); | |
48 blender.blendAnimatedPath(progress); | |
49 return resultStream.release(); | |
50 } | |
51 | |
52 PassOwnPtr<SVGPathByteStream> addPathByteStreams(PassOwnPtr<SVGPathByteStream> f romStream, const SVGPathByteStream& byStream, unsigned repeatCount = 1) | |
53 { | |
54 if (fromStream->isEmpty() || byStream.isEmpty()) | |
55 return fromStream; | |
56 OwnPtr<SVGPathByteStream> tempFromStream = fromStream; | |
57 OwnPtr<SVGPathByteStream> resultStream = SVGPathByteStream::create(); | |
58 SVGPathByteStreamBuilder builder(*resultStream); | |
59 SVGPathByteStreamSource fromSource(*tempFromStream); | |
60 SVGPathByteStreamSource bySource(byStream); | |
61 SVGPathBlender blender(&fromSource, &bySource, &builder); | |
62 blender.addAnimatedPath(repeatCount); | |
63 return resultStream.release(); | |
64 } | |
65 | |
66 } | |
67 | |
39 SVGPath::SVGPath() | 68 SVGPath::SVGPath() |
40 : SVGPropertyBase(classType()) | 69 : SVGPropertyBase(classType()) |
41 { | 70 { |
42 } | 71 } |
43 | 72 |
44 SVGPath::SVGPath(PassOwnPtr<SVGPathByteStream> byteStream) | 73 SVGPath::SVGPath(PassOwnPtr<SVGPathByteStream> byteStream) |
45 : SVGPropertyBase(classType()) | 74 : SVGPropertyBase(classType()) |
46 , m_byteStream(byteStream) | 75 , m_byteStream(byteStream) |
47 { | 76 { |
48 } | 77 } |
49 | 78 |
50 SVGPath::~SVGPath() | 79 SVGPath::~SVGPath() |
51 { | 80 { |
52 } | 81 } |
53 | 82 |
54 const Path& SVGPath::path() const | 83 const Path& SVGPath::path() const |
55 { | 84 { |
56 if (!m_cachedPath) { | 85 if (!m_cachedPath) { |
57 m_cachedPath = adoptPtr(new Path); | 86 m_cachedPath = adoptPtr(new Path); |
58 buildPathFromByteStream(byteStream(), *m_cachedPath); | 87 buildPathFromByteStream(byteStream(), *m_cachedPath); |
59 } | 88 } |
60 | 89 |
61 return *m_cachedPath; | 90 return *m_cachedPath; |
62 } | 91 } |
63 | 92 |
64 PassRefPtrWillBeRawPtr<SVGPath> SVGPath::clone() const | 93 PassRefPtrWillBeRawPtr<SVGPath> SVGPath::clone() const |
65 { | 94 { |
66 return adoptRefWillBeNoop(new SVGPath(byteStream().copy())); | 95 return SVGPath::create(byteStream().copy()); |
67 } | 96 } |
68 | 97 |
69 PassRefPtrWillBeRawPtr<SVGPropertyBase> SVGPath::cloneForAnimation(const String& value) const | 98 PassRefPtrWillBeRawPtr<SVGPropertyBase> SVGPath::cloneForAnimation(const String& value) const |
70 { | 99 { |
71 RefPtrWillBeRawPtr<SVGPath> svgPath = SVGPath::create(); | 100 RefPtrWillBeRawPtr<SVGPath> svgPath = SVGPath::create(); |
72 svgPath->setValueAsString(value, IGNORE_EXCEPTION); | 101 svgPath->setValueAsString(value, IGNORE_EXCEPTION); |
73 return svgPath; | 102 return svgPath; |
74 } | 103 } |
75 | 104 |
76 SVGPathByteStream& SVGPath::ensureByteStream() | 105 SVGPathByteStream& SVGPath::ensureByteStream() |
77 { | 106 { |
78 if (!m_byteStream) | 107 if (!m_byteStream) |
79 m_byteStream = SVGPathByteStream::create(); | 108 m_byteStream = SVGPathByteStream::create(); |
80 | 109 |
81 return *m_byteStream.get(); | 110 return *m_byteStream.get(); |
82 } | 111 } |
83 | 112 |
84 void SVGPath::byteStreamWillChange() | 113 void SVGPath::byteStreamWillChange() |
85 { | 114 { |
86 m_cachedPath.clear(); | 115 m_cachedPath.clear(); |
87 } | 116 } |
88 | 117 |
89 const SVGPathByteStream& SVGPath::byteStream() const | 118 const SVGPathByteStream& SVGPath::byteStream() const |
90 { | 119 { |
91 return const_cast<SVGPath*>(this)->ensureByteStream(); | 120 return const_cast<SVGPath*>(this)->ensureByteStream(); |
92 } | 121 } |
93 | 122 |
94 SVGPathByteStream& SVGPath::mutableByteStream() | |
95 { | |
96 byteStreamWillChange(); | |
97 return ensureByteStream(); | |
98 } | |
99 | |
100 String SVGPath::valueAsString() const | 123 String SVGPath::valueAsString() const |
101 { | 124 { |
102 String string; | 125 String string; |
103 buildStringFromByteStream(byteStream(), string, UnalteredParsing); | 126 buildStringFromByteStream(byteStream(), string, UnalteredParsing); |
104 return string; | 127 return string; |
105 } | 128 } |
106 | 129 |
107 void SVGPath::setValueAsString(const String& string, ExceptionState& exceptionSt ate) | 130 void SVGPath::setValueAsString(const String& string, ExceptionState& exceptionSt ate) |
108 { | 131 { |
109 if (!buildSVGPathByteStreamFromString(string, mutableByteStream(), Unaltered Parsing)) | 132 byteStreamWillChange(); |
f(malita)
2015/11/23 14:31:53
Nit: since we're no longer leaking a mutable bytes
fs
2015/11/23 15:24:56
Done.
| |
133 if (!buildSVGPathByteStreamFromString(string, ensureByteStream(), UnalteredP arsing)) | |
110 exceptionState.throwDOMException(SyntaxError, "Problem parsing path \"" + string + "\""); | 134 exceptionState.throwDOMException(SyntaxError, "Problem parsing path \"" + string + "\""); |
111 } | 135 } |
112 | 136 |
137 void SVGPath::setValueAsByteStream(PassOwnPtr<SVGPathByteStream> byteStream) | |
138 { | |
139 byteStreamWillChange(); | |
140 m_byteStream = byteStream; | |
141 } | |
142 | |
113 void SVGPath::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*) | 143 void SVGPath::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*) |
114 { | 144 { |
115 RefPtrWillBeRawPtr<SVGPath> otherList = toSVGPath(other); | 145 const SVGPathByteStream& otherPathByteStream = toSVGPath(other)->byteStream( ); |
116 if (byteStream().size() != otherList->byteStream().size()) | 146 if (byteStream().size() != otherPathByteStream.size()) |
117 return; | 147 return; |
118 | 148 |
119 addToSVGPathByteStream(mutableByteStream(), otherList->byteStream()); | 149 setValueAsByteStream(addPathByteStreams(m_byteStream.release(), otherPathByt eStream)); |
120 } | 150 } |
121 | 151 |
122 void SVGPath::calculateAnimatedValue(SVGAnimationElement* animationElement, floa t percentage, unsigned repeatCount, PassRefPtrWillBeRawPtr<SVGPropertyBase> from Value, PassRefPtrWillBeRawPtr<SVGPropertyBase> toValue, PassRefPtrWillBeRawPtr<S VGPropertyBase> toAtEndOfDurationValue, SVGElement*) | 152 void SVGPath::calculateAnimatedValue(SVGAnimationElement* animationElement, floa t percentage, unsigned repeatCount, PassRefPtrWillBeRawPtr<SVGPropertyBase> from Value, PassRefPtrWillBeRawPtr<SVGPropertyBase> toValue, PassRefPtrWillBeRawPtr<S VGPropertyBase> toAtEndOfDurationValue, SVGElement*) |
123 { | 153 { |
124 ASSERT(animationElement); | 154 ASSERT(animationElement); |
125 bool isToAnimation = animationElement->animationMode() == ToAnimation; | 155 bool isToAnimation = animationElement->animationMode() == ToAnimation; |
126 | 156 |
127 const RefPtrWillBeRawPtr<SVGPath> from = toSVGPath(fromValue); | |
128 const RefPtrWillBeRawPtr<SVGPath> to = toSVGPath(toValue); | 157 const RefPtrWillBeRawPtr<SVGPath> to = toSVGPath(toValue); |
129 const RefPtrWillBeRawPtr<SVGPath> toAtEndOfDuration = toSVGPath(toAtEndOfDur ationValue); | |
130 | |
131 const SVGPathByteStream& toStream = to->byteStream(); | 158 const SVGPathByteStream& toStream = to->byteStream(); |
132 const SVGPathByteStream* fromStream = &from->byteStream(); | |
133 OwnPtr<SVGPathByteStream> copy; | |
134 | 159 |
135 // If no 'to' value is given, nothing to animate. | 160 // If no 'to' value is given, nothing to animate. |
136 if (!toStream.size()) | 161 if (!toStream.size()) |
137 return; | 162 return; |
138 | 163 |
164 const RefPtrWillBeRawPtr<SVGPath> from = toSVGPath(fromValue); | |
165 const SVGPathByteStream* fromStream = &from->byteStream(); | |
166 | |
167 OwnPtr<SVGPathByteStream> copy; | |
139 if (isToAnimation) { | 168 if (isToAnimation) { |
140 copy = byteStream().copy(); | 169 copy = byteStream().copy(); |
141 fromStream = copy.get(); | 170 fromStream = copy.get(); |
142 } | 171 } |
143 | 172 |
144 byteStreamWillChange(); | |
145 | |
146 // If the 'from' value is given and it's length doesn't match the 'to' value list length, fallback to a discrete animation. | 173 // If the 'from' value is given and it's length doesn't match the 'to' value list length, fallback to a discrete animation. |
147 if (fromStream->size() != toStream.size() && fromStream->size()) { | 174 if (fromStream->size() != toStream.size() && fromStream->size()) { |
148 if (percentage < 0.5) { | 175 if (percentage < 0.5) { |
149 if (!isToAnimation) { | 176 if (!isToAnimation) { |
150 m_byteStream = fromStream->copy(); | 177 setValueAsByteStream(fromStream->copy()); |
151 return; | 178 return; |
152 } | 179 } |
153 } else { | 180 } else { |
154 m_byteStream = toStream.copy(); | 181 setValueAsByteStream(toStream.copy()); |
155 return; | 182 return; |
156 } | 183 } |
157 } | 184 } |
158 | 185 |
159 OwnPtr<SVGPathByteStream> lastAnimatedStream = m_byteStream.release(); | 186 OwnPtr<SVGPathByteStream> lastAnimatedStream = m_byteStream.release(); |
160 | 187 OwnPtr<SVGPathByteStream> newStream = blendPathByteStreams(*fromStream, toSt ream, percentage); |
161 m_byteStream = SVGPathByteStream::create(); | |
162 SVGPathByteStreamBuilder builder(*m_byteStream); | |
163 | |
164 SVGPathByteStreamSource fromSource(*fromStream); | |
165 SVGPathByteStreamSource toSource(toStream); | |
166 | |
167 SVGPathBlender blender(&fromSource, &toSource, &builder); | |
168 blender.blendAnimatedPath(percentage); | |
169 | 188 |
170 // Handle additive='sum'. | 189 // Handle additive='sum'. |
171 if (!fromStream->size() || (animationElement->isAdditive() && !isToAnimation )) | 190 if (!fromStream->size() || (animationElement->isAdditive() && !isToAnimation )) |
172 addToSVGPathByteStream(*m_byteStream, *lastAnimatedStream); | 191 newStream = addPathByteStreams(newStream.release(), *lastAnimatedStream) ; |
173 | 192 |
174 // Handle accumulate='sum'. | 193 // Handle accumulate='sum'. |
175 if (animationElement->isAccumulated() && repeatCount) | 194 if (animationElement->isAccumulated() && repeatCount) |
176 addToSVGPathByteStream(*m_byteStream, toAtEndOfDuration->byteStream(), r epeatCount); | 195 newStream = addPathByteStreams(newStream.release(), toSVGPath(toAtEndOfD urationValue)->byteStream(), repeatCount); |
196 | |
197 setValueAsByteStream(newStream.release()); | |
177 } | 198 } |
178 | 199 |
179 float SVGPath::calculateDistance(PassRefPtrWillBeRawPtr<SVGPropertyBase> to, SVG Element*) | 200 float SVGPath::calculateDistance(PassRefPtrWillBeRawPtr<SVGPropertyBase> to, SVG Element*) |
180 { | 201 { |
181 // FIXME: Support paced animations. | 202 // FIXME: Support paced animations. |
182 return -1; | 203 return -1; |
183 } | 204 } |
184 | 205 |
185 } | 206 } |
OLD | NEW |