| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/animation/LengthListPropertyFunctions.h" | 5 #include "core/animation/LengthListPropertyFunctions.h" |
| 6 | 6 |
| 7 #include "core/style/ComputedStyle.h" | 7 #include "core/style/ComputedStyle.h" |
| 8 | 8 |
| 9 namespace blink { | 9 namespace blink { |
| 10 | 10 |
| 11 namespace { | 11 namespace { |
| 12 | 12 |
| 13 const FillLayer* getFillLayer(CSSPropertyID property, const ComputedStyle& style
) | 13 const FillLayer* getFillLayer(CSSPropertyID property, const ComputedStyle& style
) |
| 14 { | 14 { |
| 15 switch (property) { | 15 switch (property) { |
| 16 case CSSPropertyBackgroundPositionX: | 16 case CSSPropertyBackgroundPositionX: |
| 17 case CSSPropertyBackgroundPositionY: | 17 case CSSPropertyBackgroundPositionY: |
| 18 case CSSPropertyBackgroundSize: |
| 18 return &style.backgroundLayers(); | 19 return &style.backgroundLayers(); |
| 19 case CSSPropertyWebkitMaskPositionX: | 20 case CSSPropertyWebkitMaskPositionX: |
| 20 case CSSPropertyWebkitMaskPositionY: | 21 case CSSPropertyWebkitMaskPositionY: |
| 22 case CSSPropertyWebkitMaskSize: |
| 21 return &style.maskLayers(); | 23 return &style.maskLayers(); |
| 22 default: | 24 default: |
| 23 ASSERT_NOT_REACHED(); | 25 ASSERT_NOT_REACHED(); |
| 24 return nullptr; | 26 return nullptr; |
| 25 } | 27 } |
| 26 } | 28 } |
| 27 | 29 |
| 28 FillLayer* accessFillLayer(CSSPropertyID property, ComputedStyle& style) | 30 FillLayer* accessFillLayer(CSSPropertyID property, ComputedStyle& style) |
| 29 { | 31 { |
| 30 switch (property) { | 32 switch (property) { |
| 31 case CSSPropertyBackgroundPositionX: | 33 case CSSPropertyBackgroundPositionX: |
| 32 case CSSPropertyBackgroundPositionY: | 34 case CSSPropertyBackgroundPositionY: |
| 35 case CSSPropertyBackgroundSize: |
| 33 return &style.accessBackgroundLayers(); | 36 return &style.accessBackgroundLayers(); |
| 34 case CSSPropertyWebkitMaskPositionX: | 37 case CSSPropertyWebkitMaskPositionX: |
| 35 case CSSPropertyWebkitMaskPositionY: | 38 case CSSPropertyWebkitMaskPositionY: |
| 39 case CSSPropertyWebkitMaskSize: |
| 36 return &style.accessMaskLayers(); | 40 return &style.accessMaskLayers(); |
| 37 default: | 41 default: |
| 38 ASSERT_NOT_REACHED(); | 42 ASSERT_NOT_REACHED(); |
| 39 return nullptr; | 43 return nullptr; |
| 40 } | 44 } |
| 41 } | 45 } |
| 42 | 46 |
| 43 struct FillLayerMethods { | 47 struct FillLayerMethods { |
| 44 FillLayerMethods(CSSPropertyID property) | 48 FillLayerMethods(CSSPropertyID property) |
| 45 { | 49 { |
| 50 isSet = nullptr; |
| 51 getLength = nullptr; |
| 52 setLength = nullptr; |
| 53 getFillSize = nullptr; |
| 54 setFillSize = nullptr; |
| 55 clear = nullptr; |
| 46 switch (property) { | 56 switch (property) { |
| 47 case CSSPropertyBackgroundPositionX: | 57 case CSSPropertyBackgroundPositionX: |
| 48 case CSSPropertyWebkitMaskPositionX: | 58 case CSSPropertyWebkitMaskPositionX: |
| 49 isSet = &FillLayer::isXPositionSet; | 59 isSet = &FillLayer::isXPositionSet; |
| 50 get = &FillLayer::xPosition; | 60 getLength = &FillLayer::xPosition; |
| 51 set = &FillLayer::setXPosition; | 61 setLength = &FillLayer::setXPosition; |
| 52 clear = &FillLayer::clearXPosition; | 62 clear = &FillLayer::clearXPosition; |
| 53 break; | 63 break; |
| 54 case CSSPropertyBackgroundPositionY: | 64 case CSSPropertyBackgroundPositionY: |
| 55 case CSSPropertyWebkitMaskPositionY: | 65 case CSSPropertyWebkitMaskPositionY: |
| 56 isSet = &FillLayer::isYPositionSet; | 66 isSet = &FillLayer::isYPositionSet; |
| 57 get = &FillLayer::yPosition; | 67 getLength = &FillLayer::yPosition; |
| 58 set = &FillLayer::setYPosition; | 68 setLength = &FillLayer::setYPosition; |
| 59 clear = &FillLayer::clearYPosition; | 69 clear = &FillLayer::clearYPosition; |
| 60 break; | 70 break; |
| 71 case CSSPropertyBackgroundSize: |
| 72 case CSSPropertyWebkitMaskSize: |
| 73 isSet = &FillLayer::isSizeSet; |
| 74 getFillSize = &FillLayer::size; |
| 75 setFillSize = &FillLayer::setSize; |
| 76 clear = &FillLayer::clearSize; |
| 77 break; |
| 61 default: | 78 default: |
| 62 ASSERT_NOT_REACHED(); | 79 ASSERT_NOT_REACHED(); |
| 63 isSet = nullptr; | |
| 64 get = nullptr; | |
| 65 set = nullptr; | |
| 66 clear = nullptr; | |
| 67 break; | 80 break; |
| 68 } | 81 } |
| 69 } | 82 } |
| 70 | 83 |
| 71 bool (FillLayer::*isSet)() const; | 84 bool (FillLayer::*isSet)() const; |
| 72 const Length& (FillLayer::*get)() const; | 85 const Length& (FillLayer::*getLength)() const; |
| 73 void (FillLayer::*set)(const Length&); | 86 void (FillLayer::*setLength)(const Length&); |
| 87 FillSize (FillLayer::*getFillSize)() const; |
| 88 void (FillLayer::*setFillSize)(const FillSize&); |
| 74 void (FillLayer::*clear)(); | 89 void (FillLayer::*clear)(); |
| 75 }; | 90 }; |
| 76 | 91 |
| 77 } // namespace | 92 } // namespace |
| 78 | 93 |
| 79 ValueRange LengthListPropertyFunctions::valueRange(CSSPropertyID property) | 94 ValueRange LengthListPropertyFunctions::valueRange(CSSPropertyID property) |
| 80 { | 95 { |
| 81 switch (property) { | 96 switch (property) { |
| 82 case CSSPropertyBackgroundPositionX: | 97 case CSSPropertyBackgroundPositionX: |
| 83 case CSSPropertyBackgroundPositionY: | 98 case CSSPropertyBackgroundPositionY: |
| 84 case CSSPropertyObjectPosition: | 99 case CSSPropertyObjectPosition: |
| 85 case CSSPropertyPerspectiveOrigin: | 100 case CSSPropertyPerspectiveOrigin: |
| 86 case CSSPropertyTransformOrigin: | 101 case CSSPropertyTransformOrigin: |
| 87 case CSSPropertyWebkitMaskPositionX: | 102 case CSSPropertyWebkitMaskPositionX: |
| 88 case CSSPropertyWebkitMaskPositionY: | 103 case CSSPropertyWebkitMaskPositionY: |
| 89 return ValueRangeAll; | 104 return ValueRangeAll; |
| 90 | 105 |
| 106 case CSSPropertyBackgroundSize: |
| 91 case CSSPropertyBorderBottomLeftRadius: | 107 case CSSPropertyBorderBottomLeftRadius: |
| 92 case CSSPropertyBorderBottomRightRadius: | 108 case CSSPropertyBorderBottomRightRadius: |
| 93 case CSSPropertyBorderTopLeftRadius: | 109 case CSSPropertyBorderTopLeftRadius: |
| 94 case CSSPropertyBorderTopRightRadius: | 110 case CSSPropertyBorderTopRightRadius: |
| 95 case CSSPropertyStrokeDasharray: | 111 case CSSPropertyStrokeDasharray: |
| 112 case CSSPropertyWebkitMaskSize: |
| 96 return ValueRangeNonNegative; | 113 return ValueRangeNonNegative; |
| 97 | 114 |
| 98 default: | 115 default: |
| 99 ASSERT_NOT_REACHED(); | 116 ASSERT_NOT_REACHED(); |
| 100 return ValueRangeAll; | 117 return ValueRangeAll; |
| 101 } | 118 } |
| 102 } | 119 } |
| 103 | 120 |
| 104 Vector<Length> LengthListPropertyFunctions::getInitialLengthList(CSSPropertyID p
roperty) | 121 bool LengthListPropertyFunctions::getInitialLengthList(CSSPropertyID property, V
ector<Length>& result) |
| 105 { | 122 { |
| 106 return getLengthList(property, *ComputedStyle::initialStyle()); | 123 return getLengthList(property, *ComputedStyle::initialStyle(), result); |
| 107 } | 124 } |
| 108 | 125 |
| 109 static Vector<Length> toVector(const LengthPoint& point) | 126 static bool appendToVector(const LengthPoint& point, Vector<Length>& result) |
| 110 { | 127 { |
| 111 Vector<Length> result(2); | 128 result.append(point.x()); |
| 112 result[0] = point.x(); | 129 result.append(point.y()); |
| 113 result[1] = point.y(); | 130 return true; |
| 114 return result; | |
| 115 } | 131 } |
| 116 | 132 |
| 117 static Vector<Length> toVector(const LengthSize& size) | 133 static bool appendToVector(const LengthSize& size, Vector<Length>& result) |
| 118 { | 134 { |
| 119 Vector<Length> result(2); | 135 result.append(size.width()); |
| 120 result[0] = size.width(); | 136 result.append(size.height()); |
| 121 result[1] = size.height(); | 137 return true; |
| 122 return result; | |
| 123 } | 138 } |
| 124 | 139 |
| 125 static Vector<Length> toVector(const TransformOrigin& transformOrigin) | 140 static bool appendToVector(const TransformOrigin& transformOrigin, Vector<Length
>& result) |
| 126 { | 141 { |
| 127 Vector<Length> result(3); | 142 result.append(transformOrigin.x()); |
| 128 result[0] = transformOrigin.x(); | 143 result.append(transformOrigin.y()); |
| 129 result[1] = transformOrigin.y(); | 144 result.append(Length(transformOrigin.z(), Fixed)); |
| 130 result[2] = Length(transformOrigin.z(), Fixed); | 145 return true; |
| 131 return result; | |
| 132 } | 146 } |
| 133 | 147 |
| 134 Vector<Length> LengthListPropertyFunctions::getLengthList(CSSPropertyID property
, const ComputedStyle& style) | 148 bool LengthListPropertyFunctions::getLengthList(CSSPropertyID property, const Co
mputedStyle& style, Vector<Length>& result) |
| 135 { | 149 { |
| 150 ASSERT(result.isEmpty()); |
| 151 |
| 136 switch (property) { | 152 switch (property) { |
| 137 case CSSPropertyStrokeDasharray: { | 153 case CSSPropertyStrokeDasharray: { |
| 138 if (style.strokeDashArray()) | 154 if (style.strokeDashArray()) |
| 139 return style.strokeDashArray()->vector(); | 155 result.appendVector(style.strokeDashArray()->vector()); |
| 140 return Vector<Length>(); | 156 return true; |
| 141 } | |
| 142 case CSSPropertyObjectPosition: | |
| 143 return toVector(style.objectPosition()); | |
| 144 case CSSPropertyPerspectiveOrigin: | |
| 145 return toVector(style.perspectiveOrigin()); | |
| 146 case CSSPropertyBorderBottomLeftRadius: | |
| 147 return toVector(style.borderBottomLeftRadius()); | |
| 148 case CSSPropertyBorderBottomRightRadius: | |
| 149 return toVector(style.borderBottomRightRadius()); | |
| 150 case CSSPropertyBorderTopLeftRadius: | |
| 151 return toVector(style.borderTopLeftRadius()); | |
| 152 case CSSPropertyBorderTopRightRadius: | |
| 153 return toVector(style.borderTopRightRadius()); | |
| 154 case CSSPropertyTransformOrigin: | |
| 155 return toVector(style.transformOrigin()); | |
| 156 default: | |
| 157 break; | |
| 158 } | 157 } |
| 159 | 158 |
| 160 Vector<Length> result; | 159 case CSSPropertyObjectPosition: |
| 161 const FillLayer* fillLayer = getFillLayer(property, style); | 160 return appendToVector(style.objectPosition(), result); |
| 162 FillLayerMethods fillLayerMethods(property); | 161 case CSSPropertyPerspectiveOrigin: |
| 163 while (fillLayer && (fillLayer->*fillLayerMethods.isSet)()) { | 162 return appendToVector(style.perspectiveOrigin(), result); |
| 164 result.append((fillLayer->*fillLayerMethods.get)()); | 163 case CSSPropertyBorderBottomLeftRadius: |
| 165 fillLayer = fillLayer->next(); | 164 return appendToVector(style.borderBottomLeftRadius(), result); |
| 165 case CSSPropertyBorderBottomRightRadius: |
| 166 return appendToVector(style.borderBottomRightRadius(), result); |
| 167 case CSSPropertyBorderTopLeftRadius: |
| 168 return appendToVector(style.borderTopLeftRadius(), result); |
| 169 case CSSPropertyBorderTopRightRadius: |
| 170 return appendToVector(style.borderTopRightRadius(), result); |
| 171 case CSSPropertyTransformOrigin: |
| 172 return appendToVector(style.transformOrigin(), result); |
| 173 |
| 174 case CSSPropertyBackgroundPositionX: |
| 175 case CSSPropertyBackgroundPositionY: |
| 176 case CSSPropertyWebkitMaskPositionX: |
| 177 case CSSPropertyWebkitMaskPositionY: { |
| 178 const FillLayer* fillLayer = getFillLayer(property, style); |
| 179 FillLayerMethods fillLayerMethods(property); |
| 180 while (fillLayer && (fillLayer->*fillLayerMethods.isSet)()) { |
| 181 result.append((fillLayer->*fillLayerMethods.getLength)()); |
| 182 fillLayer = fillLayer->next(); |
| 183 } |
| 184 return true; |
| 166 } | 185 } |
| 167 return result; | 186 case CSSPropertyBackgroundSize: |
| 187 case CSSPropertyWebkitMaskSize: { |
| 188 const FillLayer* fillLayer = getFillLayer(property, style); |
| 189 FillLayerMethods fillLayerMethods(property); |
| 190 while (fillLayer && (fillLayer->*fillLayerMethods.isSet)()) { |
| 191 FillSize fillSize = (fillLayer->*fillLayerMethods.getFillSize)(); |
| 192 if (fillSize.type != SizeLength) { |
| 193 result.clear(); |
| 194 return false; |
| 195 } |
| 196 result.append(fillSize.size.width()); |
| 197 result.append(fillSize.size.height()); |
| 198 fillLayer = fillLayer->next(); |
| 199 } |
| 200 return true; |
| 201 } |
| 202 |
| 203 default: |
| 204 ASSERT_NOT_REACHED(); |
| 205 return false; |
| 206 } |
| 168 } | 207 } |
| 169 | 208 |
| 170 static LengthPoint pointFromVector(const Vector<Length>& list) | 209 static LengthPoint pointFromVector(const Vector<Length>& list) |
| 171 { | 210 { |
| 172 ASSERT(list.size() == 2); | 211 ASSERT(list.size() == 2); |
| 173 return LengthPoint(list[0], list[1]); | 212 return LengthPoint(list[0], list[1]); |
| 174 } | 213 } |
| 175 | 214 |
| 176 static LengthSize sizeFromVector(const Vector<Length>& list) | 215 static LengthSize sizeFromVector(const Vector<Length>& list) |
| 177 { | 216 { |
| 178 ASSERT(list.size() == 2); | 217 ASSERT(list.size() == 2); |
| 179 return LengthSize(list[0], list[1]); | 218 return LengthSize(list[0], list[1]); |
| 180 } | 219 } |
| 181 | 220 |
| 182 static TransformOrigin transformOriginFromVector(const Vector<Length>& list) | 221 static TransformOrigin transformOriginFromVector(const Vector<Length>& list) |
| 183 { | 222 { |
| 184 ASSERT(list.size() == 3); | 223 ASSERT(list.size() == 3); |
| 185 return TransformOrigin(list[0], list[1], list[2].pixels()); | 224 return TransformOrigin(list[0], list[1], list[2].pixels()); |
| 186 } | 225 } |
| 187 | 226 |
| 188 void LengthListPropertyFunctions::setLengthList(CSSPropertyID property, Computed
Style& style, Vector<Length>&& lengthList) | 227 void LengthListPropertyFunctions::setLengthList(CSSPropertyID property, Computed
Style& style, Vector<Length>&& lengthList) |
| 189 { | 228 { |
| 190 switch (property) { | 229 switch (property) { |
| 191 case CSSPropertyStrokeDasharray: | 230 case CSSPropertyStrokeDasharray: |
| 192 style.setStrokeDashArray(lengthList.isEmpty() ? nullptr : RefVector<Leng
th>::create(std::move(lengthList))); | 231 style.setStrokeDashArray(lengthList.isEmpty() ? nullptr : RefVector<Leng
th>::create(std::move(lengthList))); |
| 193 return; | 232 return; |
| 233 |
| 194 case CSSPropertyObjectPosition: | 234 case CSSPropertyObjectPosition: |
| 195 style.setObjectPosition(pointFromVector(lengthList)); | 235 style.setObjectPosition(pointFromVector(lengthList)); |
| 196 return; | 236 return; |
| 197 case CSSPropertyPerspectiveOrigin: | 237 case CSSPropertyPerspectiveOrigin: |
| 198 style.setPerspectiveOrigin(pointFromVector(lengthList)); | 238 style.setPerspectiveOrigin(pointFromVector(lengthList)); |
| 199 return; | 239 return; |
| 240 |
| 200 case CSSPropertyBorderBottomLeftRadius: | 241 case CSSPropertyBorderBottomLeftRadius: |
| 201 style.setBorderBottomLeftRadius(sizeFromVector(lengthList)); | 242 style.setBorderBottomLeftRadius(sizeFromVector(lengthList)); |
| 202 return; | 243 return; |
| 203 case CSSPropertyBorderBottomRightRadius: | 244 case CSSPropertyBorderBottomRightRadius: |
| 204 style.setBorderBottomRightRadius(sizeFromVector(lengthList)); | 245 style.setBorderBottomRightRadius(sizeFromVector(lengthList)); |
| 205 return; | 246 return; |
| 206 case CSSPropertyBorderTopLeftRadius: | 247 case CSSPropertyBorderTopLeftRadius: |
| 207 style.setBorderTopLeftRadius(sizeFromVector(lengthList)); | 248 style.setBorderTopLeftRadius(sizeFromVector(lengthList)); |
| 208 return; | 249 return; |
| 209 case CSSPropertyBorderTopRightRadius: | 250 case CSSPropertyBorderTopRightRadius: |
| 210 style.setBorderTopRightRadius(sizeFromVector(lengthList)); | 251 style.setBorderTopRightRadius(sizeFromVector(lengthList)); |
| 211 return; | 252 return; |
| 253 |
| 212 case CSSPropertyTransformOrigin: | 254 case CSSPropertyTransformOrigin: |
| 213 style.setTransformOrigin(transformOriginFromVector(lengthList)); | 255 style.setTransformOrigin(transformOriginFromVector(lengthList)); |
| 214 return; | 256 return; |
| 215 default: | 257 |
| 216 break; | 258 case CSSPropertyBackgroundPositionX: |
| 259 case CSSPropertyBackgroundPositionY: |
| 260 case CSSPropertyWebkitMaskPositionX: |
| 261 case CSSPropertyWebkitMaskPositionY: { |
| 262 FillLayer* fillLayer = accessFillLayer(property, style); |
| 263 FillLayer* prev = nullptr; |
| 264 FillLayerMethods fillLayerMethods(property); |
| 265 for (size_t i = 0; i < lengthList.size(); i++) { |
| 266 if (!fillLayer) |
| 267 fillLayer = prev->ensureNext(); |
| 268 (fillLayer->*fillLayerMethods.setLength)(lengthList[i]); |
| 269 prev = fillLayer; |
| 270 fillLayer = fillLayer->next(); |
| 271 } |
| 272 while (fillLayer) { |
| 273 (fillLayer->*fillLayerMethods.clear)(); |
| 274 fillLayer = fillLayer->next(); |
| 275 } |
| 276 return; |
| 217 } | 277 } |
| 218 | 278 |
| 219 FillLayer* fillLayer = accessFillLayer(property, style); | 279 case CSSPropertyBackgroundSize: |
| 220 FillLayer* prev = nullptr; | 280 case CSSPropertyWebkitMaskSize: { |
| 221 FillLayerMethods fillLayerMethods(property); | 281 ASSERT(lengthList.size() % 2 == 0); |
| 222 for (size_t i = 0; i < lengthList.size(); i++) { | 282 FillLayer* fillLayer = accessFillLayer(property, style); |
| 223 if (!fillLayer) | 283 FillLayer* prev = nullptr; |
| 224 fillLayer = prev->ensureNext(); | 284 FillLayerMethods fillLayerMethods(property); |
| 225 (fillLayer->*fillLayerMethods.set)(lengthList[i]); | 285 for (size_t i = 0; i < lengthList.size() / 2; i++) { |
| 226 prev = fillLayer; | 286 if (!fillLayer) |
| 227 fillLayer = fillLayer->next(); | 287 fillLayer = prev->ensureNext(); |
| 288 FillSize fillSize(SizeLength, LengthSize(lengthList[2 * i], lengthLi
st[2 * i + 1])); |
| 289 (fillLayer->*fillLayerMethods.setFillSize)(fillSize); |
| 290 prev = fillLayer; |
| 291 fillLayer = fillLayer->next(); |
| 292 } |
| 293 while (fillLayer) { |
| 294 (fillLayer->*fillLayerMethods.clear)(); |
| 295 fillLayer = fillLayer->next(); |
| 296 } |
| 297 return; |
| 228 } | 298 } |
| 229 while (fillLayer) { | 299 |
| 230 (fillLayer->*fillLayerMethods.clear)(); | 300 default: |
| 231 fillLayer = fillLayer->next(); | 301 ASSERT_NOT_REACHED(); |
| 302 break; |
| 232 } | 303 } |
| 233 } | 304 } |
| 234 | 305 |
| 235 } // namespace blink | 306 } // namespace blink |
| OLD | NEW |