Changeset 154906 in webkit
- Timestamp:
- Aug 30, 2013 12:29:03 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 35 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r154896 r154906 1 2013-08-30 Dirk Schulze <krit@webkit.org> 2 3 Animate CSS Image filter() function 4 https://bugs.webkit.org/show_bug.cgi?id=119938 5 6 Reviewed by Simon Fraser. 7 8 Add tests to test animation between two filter() function values. 9 Furthermore, extended animation-test-helpers.js to parse all kind of CSS 10 image function where we support animations. CSS Image function can be 11 deeply nested as well now: 12 13 -wekit-filter(-webkit-cross-fade(url(a.png), url(b.png), 50%), sepia(0.5)) 14 15 Even the 50% can now be checked with a tolerance. If we should ever support 16 animations on nested CSS Images, the new code in animation-test-helpers.js 17 is prepared for it. 18 19 Fixed a bunch of tests that passed by accident or needed an update to the new 20 infrastructure. 21 22 * animations/resources/animation-test-helpers.js: 23 (parseCSSImage): For parsing of all kind of supported CSS Image functions. 24 Currently supported: -webkit-cross-fade, -webkit-filter, url, none 25 Still missing: linear and radial gradients (can not be animated yet). 26 CSS Image functions are allowed to be nested as deep JS allows. 27 (parseCrossFade): Add parsing of input CSS images. 28 (parseFilterImage): Parse -webkit-filter image function as well as input images. 29 (parseFilterFunctionList): Parse filter function list. We now parse the 30 function name as well. Added rudimentary support for drop-shadow and url. 31 (parseDeprecatedCustomFilterFunction): Special case old syntax of custom 32 filter function. Shall be removed in the future. 33 (compareCSSImages): Compares all kind (even deep nested) CSS images. 34 (compareFilterFunctions): Now compare filter function names as well. 35 (comparePropertyValue): Use new compareCSSImages function. 36 * fast/filter-image/filter-image-animation-expected.txt: Added. 37 * fast/filter-image/filter-image-animation.html: Added. 38 1 39 2013-08-30 Rob Buis <rwlbuis@webkit.org> 2 40 -
trunk/LayoutTests/animations/cross-fade-background-image.html
r102388 r154906 42 42 const expectedValues = [ 43 43 // [animation-name, time, element-id, property, expected-value, tolerance] 44 ["anim", 2.5, "box", "backgroundImage", 0.5, 0.05],45 ["anim", 2.5, ["box", "static:boxStatic"], "backgroundImage", 0.5, 0.05],46 ["animShorthand", 2.5, ["boxShorthand", "static:boxStatic"], "backgroundImage", 0.5, 0.05],44 ["anim", 2.5, "box", "backgroundImage", "-webkit-cross-fade(url(blue-100.png), url(green-100.png), 50%)", 0.05], 45 ["anim", 2.5, ["box", "static:boxStatic"], "backgroundImage", "-webkit-cross-fade(url(blue-100.png), url(green-100.png), 50%)", 0.05], 46 ["animShorthand", 2.5, ["boxShorthand", "static:boxStatic"], "backgroundImage", "-webkit-cross-fade(url(blue-100.png), url(green-100.png), 50%)", 0.05], 47 47 ]; 48 48 -
trunk/LayoutTests/animations/cross-fade-border-image-source.html
r102388 r154906 44 44 // [animation-name, time, element-id, property, expected-value, tolerance] 45 45 // FIXME: We can't test reading the borderImage shorthand because of bug #13658. 46 ["anim", 2.5, "box", "borderImageSource", 0.5, 0.05],47 ["anim", 2.5, ["box", "static:boxStatic"], "borderImageSource", 0.5, 0.05],48 ["animShorthand", 2.5, ["boxShorthand", "static:boxStatic"], "borderImageSource", 0.5, 0.05],46 ["anim", 2.5, "box", "borderImageSource", "-webkit-cross-fade(url(stripes-100.png), url(green-100.png), 0.5)", 0.05], 47 ["anim", 2.5, ["box", "static:boxStatic"], "borderImageSource", "-webkit-cross-fade(url(stripes-100.png), url(green-100.png), 50%)", 0.05], 48 ["animShorthand", 2.5, ["boxShorthand", "static:boxStatic"], "borderImageSource", "-webkit-cross-fade(url(stripes-100), url(green-100.png), 50%)", 0.05], 49 49 ]; 50 50 -
trunk/LayoutTests/animations/cross-fade-list-style-image.html
r102388 r154906 39 39 const expectedValues = [ 40 40 // [animation-name, time, element-id, property, expected-value, tolerance] 41 ["anim", 2.5, "box", "listStyleImage", 0.5, 0.05],42 ["anim", 2.5, ["box", "static:boxStatic"], "listStyleImage", 0.5, 0.05],43 ["animShorthand", 2.5, ["boxShorthand", "static:boxStatic"], "listStyleImage", 0.5, 0.05],41 ["anim", 2.5, "box", "listStyleImage", "-webkit-cross-fade(url(blue-100.png), url(green-100.png), 50%)", 0.05], 42 ["anim", 2.5, ["box", "static:boxStatic"], "listStyleImage", "-webkit-cross-fade(url(blue-100.png), url(green-100.png), 50%)", 0.05], 43 ["animShorthand", 2.5, ["boxShorthand", "static:boxStatic"], "listStyleImage", "-webkit-cross-fade(url(blue-100.png), url(green-100.png), 50%)", 0.05], 44 44 ]; 45 45 -
trunk/LayoutTests/animations/cross-fade-webkit-mask-box-image.html
r104851 r154906 29 29 const expectedValues = [ 30 30 // [animation-name, time, element-id, property, expected-value, tolerance] 31 ["anim", 2.25, "box", "webkitMaskBoxImage", 0.25, 0.05],32 ["anim", 2.25, ["box", "static:boxStatic"], "webkitMaskBoxImage", 0.25, 0.05]31 ["anim", 2.25, "box", "webkitMaskBoxImage", "-webkit-cross-fade(url(stripes-100.png), url(green-100.png), 25%)", 0.05], 32 ["anim", 2.25, ["box", "static:boxStatic"], "webkitMaskBoxImage", "-webkit-cross-fade(url(stripes-100.png), url(green-100.png), 25%)", 0.05] 33 33 ]; 34 34 -
trunk/LayoutTests/animations/cross-fade-webkit-mask-image.html
r102388 r154906 29 29 const expectedValues = [ 30 30 // [animation-name, time, element-id, property, expected-value, tolerance] 31 ["anim", 2.25, "box", "webkitMaskImage", 0.25, 0.05],32 ["anim", 2.25, ["box", "static:boxStatic"], "webkitMaskImage", 0.25, 0.05]31 ["anim", 2.25, "box", "webkitMaskImage", "-webkit-cross-fade(url(stripes-100.png), url(green-100.png), 25%)", 0.05], 32 ["anim", 2.25, ["box", "static:boxStatic"], "webkitMaskImage", "-webkit-cross-fade(url(stripes-100.png), url(green-100.png), 25%)", 0.05] 33 33 ]; 34 34 -
trunk/LayoutTests/animations/resources/animation-test-helpers.js
r142171 r154906 35 35 */ 36 36 37 function isCloseEnough(actual, desired, tolerance) 38 { 39 var diff = Math.abs(actual - desired); 37 function isCloseEnough(actual, expected, tolerance) 38 { 39 if (isNaN(actual) || isNaN(expected)) 40 return false; 41 var diff = Math.abs(actual - expected); 40 42 return diff <= tolerance; 41 43 } … … 50 52 } 51 53 54 function parseCSSImage(s) 55 { 56 // Special case none. 57 if (s == "none") 58 return ["none"]; 59 60 // Separate function name from function value. 61 var matches = s.match("([\\w\\-]+)\\((.*)\\)"); 62 if (!matches){ 63 console.error("Parsing error. Value not a CSS Image function ", s); 64 return false; 65 } 66 67 var functionName = matches[1]; 68 var functionValue = matches[2]; 69 70 // Generator functions can have CSS images as values themself. 71 // These functions will call parseCSSImage for each CSS Image. 72 switch (functionName) { 73 case "-webkit-filter": 74 return parseFilterImage(functionValue); 75 case "-webkit-cross-fade": 76 return parseCrossFade(functionValue); 77 case "url": 78 return ["url", functionValue]; 79 // FIXME: Add support for linear and redial gradient. 80 default: 81 // All supported filter functions must be listed above. 82 return false; 83 } 84 } 85 86 // This should just be called by parseCSSImage. 52 87 function parseCrossFade(s) 53 88 { 54 var matches = s.match("-webkit-cross-fade\\((.*)\\s*,\\s*(.*)\\s*,\\s*(.*)\\)"); 55 56 if (!matches) 57 return null; 58 59 return {"from": matches[1], "to": matches[2], "percent": parseFloat(matches[3])} 89 var matches = s.match("(.*)\\s*,\\s*(.*)\\s*,\\s*(.*)\\s*"); 90 if (!matches) { 91 console.error("Parsing error on '-webkit-cross-fade()'."); 92 return null; 93 } 94 95 var from = parseCSSImage(matches[1]); 96 var to = parseCSSImage(matches[2]); 97 if (!from || !to) { 98 console.error("Parsing error on images passed to '-webkit-cross-fade()' ", s); 99 return null; 100 } 101 102 var fadeValue = matches[3]; 103 var percent; 104 if (isNaN(fadeValue)) { 105 // Check if last char is '%' and rip it off. 106 // Normalize it to number. 107 if (fadeValue.search('%') != fadeValue.length - 1) { 108 console.error("Passed value to '-webkit-cross-fade()' is not a number or percentage ", fadeValue); 109 return null; 110 } 111 fadeValue = fadeValue.slice(0, fadeValue.length - 1); 112 if (isNaN(fadeValue)) { 113 console.error("Passed value to '-webkit-cross-fade()' is not a number or percentage ", fadeValue); 114 return null; 115 } 116 percent = parseFloat(fadeValue) / 100; 117 } else 118 percent = parseFloat(fadeValue); 119 120 return ["-webkit-cross-fade", from, to, percent]; 121 } 122 123 // This should just be called by parseCSSImage. 124 function parseFilterImage(s) 125 { 126 // Separate image value from filter function list. 127 var matches = s.match("([\\-\\w]+\\(.*\\))\\s*,\\s*(.*)\\s*"); 128 if (!matches) { 129 console.error("Parsing error on 'fitler()' ", s); 130 return false; 131 } 132 133 var image = parseCSSImage(matches[1]); 134 if (!image) { 135 console.error("Parsing error on image passed to 'fitler()' ", s); 136 return false; 137 } 138 139 var filterFunctionList = parseFilterFunctionList(matches[2]); 140 if (!filterFunctionList) { 141 console.error("Parsing error on filter function list passed to 'fitler()' ", s); 142 return false; 143 } 144 145 return ["-webkit-filter", image, filterFunctionList]; 146 } 147 148 function parseFilterFunctionList(s) 149 { 150 var reg = /\)*\s*(blur|brightness|contrast|custom|drop\-shadow|grayscale|hue\-rotate|invert|opacity|saturate|sepia|url)\(/ 151 var matches = s.split(reg); 152 153 // First item must be empty. All other items are of functionName, functionValue. 154 if (!matches || matches.shift() != "") 155 return null; 156 157 // RegEx above can not handle deprecated custom() function 158 var customPos = matches.indexOf("custom"); 159 if (customPos >= 0 && matches[customPos+1] === "") 160 return parseDeprecatedCustomFilterFunction(s); 161 162 // Odd items are the function name, even items the function value. 163 if (!matches.length || matches.length % 2) 164 return null; 165 166 var functionList = []; 167 for (var i = 0; i < matches.length; i += 2) { 168 var functionName = matches[i]; 169 var functionValue = matches[i+1]; 170 functionList.push(functionName); 171 if (functionName == "drop-shadow" || functionName == "url") { 172 // FIXME: Support parsing of drop-shadow. 173 functionList.push(functionValue); 174 continue; 175 } else if (functionName == "custom") { 176 var filterParams; 177 if (!window.getCustomFilterParameters) 178 throw new Error("getCustomFilterParameters not found. Did you include custom-filter-parser.js?"); 179 var filterParams = getCustomFilterParameters(functionValue); 180 if (!filterParams) { 181 console.error("Error on parsing custom filter parameters ", functionValue); 182 return null; 183 } 184 functionList.push(filterParams); 185 continue; 186 } 187 functionList.push(parseFloat(functionValue)); 188 } 189 return functionList; 190 } 191 192 // FIXME: Remove function and caller when we removed the deprecated syntax of 193 // the custom filter function. 194 function parseDeprecatedCustomFilterFunction(s) 195 { 196 var filterResult = s.match(/(\w+)\((.+)\)/); 197 var filterParams = filterResult[2]; 198 199 if (filterResult[1] != "custom") 200 return null; 201 202 if (!window.getCustomFilterParameters) 203 throw new Error("getCustomFilterParameters not found. Did you include custom-filter-parser.js?"); 204 return ["custom", getCustomFilterParameters(filterParams)]; 60 205 } 61 206 … … 100 245 } 101 246 247 function compareCSSImages(computedValue, expectedValue, tolerance) 248 { 249 var actual = typeof computedValue === "string" ? parseCSSImage(computedValue) : computedValue; 250 var expected = typeof expectedValue === "string" ? parseCSSImage(expectedValue) : expectedValue; 251 if (!actual || !Array.isArray(actual) // Check that: actual is an array, 252 || !expected || !Array.isArray(expected) // expected is an array, 253 || actual[0] != expected[0]) { // and image function names are the same. 254 console.error("Unexpected mismatch between CSS Image functions."); 255 return false; 256 } 257 switch (actual[0]) { 258 case "none": 259 return true; 260 case "-webkit-filter": 261 return compareCSSImages(actual[1], expected[1], tolerance) 262 && compareFilterFunctions(actual[2], expected[2], tolerance); 263 case "-webkit-cross-fade": 264 return compareCSSImages(actual[1], expected[1], tolerance) 265 && compareCSSImages(actual[2], expected[2], tolerance) 266 && isCloseEnough(actual[3], expected[3], tolerance); 267 case "url": 268 return actual[1].search(expected[1]) >= 0; 269 default: 270 console.error("Unknown CSS Image function ", actual[0]); 271 return false; 272 } 273 } 274 275 // Called by CSS Image function filter() as well as filter property. 276 function compareFilterFunctions(computedValue, expectedValue, tolerance) 277 { 278 var actual = typeof computedValue === "string" ? parseFilterFunctionList(computedValue) : computedValue; 279 var expected = typeof expectedValue === "string" ? parseFilterFunctionList(expectedValue) : expectedValue; 280 if (!actual || !Array.isArray(actual) // Check that: actual is an array, 281 || !expected || !Array.isArray(expected) // expected is an array, 282 || !actual.length // actual array has entries, 283 || actual.length != expected.length // actual and expected have same length 284 || actual.length % 2 == 1) // and image function names are the same. 285 return false; 286 287 for (var i = 0; i < actual.length; i += 2) { 288 if (actual[i] != expected[i]) { 289 console.error("Filter functions do not match."); 290 return false; 291 } 292 if (actual[i] == "custom") { 293 if (!customFilterParameterMatch(actual[i+1], expected[i+1], tolerance)) { 294 console.error("Custom filter parameters do not match."); 295 return false; 296 } 297 continue; 298 } 299 if (!isCloseEnough(actual[i+1], expected[i+1], tolerance)) { 300 console.error("Filter function values do not match."); 301 return false; 302 } 303 } 304 return true; 305 } 306 102 307 function basicShapeParametersMatch(paramList1, paramList2, tolerance) 103 308 { … … 113 318 } 114 319 return true; 115 }116 117 // Return an array of numeric filter params in 0-1.118 function getFilterParameters(s)119 {120 var filterResult = s.match(/(\w+)\((.+)\)/);121 if (!filterResult)122 throw new Error("There's no filter in \"" + s + "\"");123 var filterParams = filterResult[2];124 if (filterResult[1] == "custom") {125 if (!window.getCustomFilterParameters)126 throw new Error("getCustomFilterParameters not found. Did you include custom-filter-parser.js?");127 return getCustomFilterParameters(filterParams);128 }129 var paramList = filterParams.split(' '); // FIXME: the spec may allow comma separation at some point.130 131 // Normalize percentage values.132 for (var i = 0; i < paramList.length; ++i) {133 var param = paramList[i];134 paramList[i] = parseFloat(paramList[i]);135 if (param.indexOf('%') != -1)136 paramList[i] = paramList[i] / 100;137 }138 139 return paramList;140 320 } 141 321 … … 183 363 } 184 364 185 function filterParametersMatch(paramList1, paramList2, tolerance)186 {187 if (paramList1.length != paramList2.length)188 return false;189 for (var i = 0; i < paramList1.length; ++i) {190 var param1 = paramList1[i],191 param2 = paramList2[i];192 if (typeof param1 == "object") {193 // This is a custom filter parameter.194 if (!customFilterParameterMatch(param1, param2, tolerance))195 return false;196 continue;197 }198 var match = isCloseEnough(param1, param2, tolerance);199 if (!match)200 return false;201 }202 return true;203 }204 205 365 function checkExpectedValue(expected, index) 206 366 { … … 330 490 } 331 491 } else if (property == "webkitFilter") { 332 var filterParameters = getFilterParameters(computedValue);333 var filter2Parameters = getFilterParameters(expectedValue);334 result = filterParametersMatch(filterParameters, filter2Parameters, tolerance);492 var filterParameters = parseFilterFunctionList(computedValue); 493 var filter2Parameters = parseFilterFunctionList(expectedValue); 494 result = compareFilterFunctions(filterParameters, filter2Parameters, tolerance); 335 495 } else if (property == "webkitClipPath" || property == "webkitShapeInside") { 336 496 var clipPathParameters = parseBasicShape(computedValue); … … 343 503 || property == "listStyleImage" 344 504 || property == "webkitMaskImage" 345 || property == "webkitMaskBoxImage") { 346 var computedCrossFade = parseCrossFade(computedValue); 347 348 if (!computedCrossFade) { 349 result = false; 350 } else { 351 if (typeof expectedValue == "string") { 352 var computedCrossFade2 = parseCrossFade(expectedValue); 353 result = isCloseEnough(computedCrossFade.percent, computedCrossFade2.percent, tolerance) && computedCrossFade.from == computedCrossFade2.from && computedCrossFade.to == computedCrossFade2.to; 354 } else { 355 result = isCloseEnough(computedCrossFade.percent, expectedValue, tolerance) 356 } 357 } 358 } else { 505 || property == "webkitMaskBoxImage") 506 result = compareCSSImages(computedValue, expectedValue, tolerance); 507 else { 359 508 result = isCloseEnough(computedValue, expectedValue, tolerance); 360 509 } -
trunk/LayoutTests/css3/filters/filter-animation-expected.txt
r103125 r154906 3 3 PASS - "webkitFilter" property for "sepia-box" element at 1s saw something close to: sepia(0.5) 4 4 PASS - "webkitFilter" property for "saturate-box" element at 1s saw something close to: saturate(0.5) 5 PASS - "webkitFilter" property for "huerotate-box" element at 1s saw something close to: hue rotate(90deg)5 PASS - "webkitFilter" property for "huerotate-box" element at 1s saw something close to: hue-rotate(90deg) 6 6 PASS - "webkitFilter" property for "invert-box" element at 1s saw something close to: invert(0.5) 7 7 PASS - "webkitFilter" property for "opacity-box" element at 1s saw something close to: opacity(0.5) -
trunk/LayoutTests/css3/filters/filter-animation-from-none-expected.txt
r103586 r154906 3 3 PASS - "webkitFilter" property for "sepia-box" element at 0.5s saw something close to: sepia(0.25) 4 4 PASS - "webkitFilter" property for "saturate-box" element at 0.5s saw something close to: saturate(0.75) 5 PASS - "webkitFilter" property for "huerotate-box" element at 0.5s saw something close to: hue rotate(45deg)5 PASS - "webkitFilter" property for "huerotate-box" element at 0.5s saw something close to: hue-rotate(45deg) 6 6 PASS - "webkitFilter" property for "invert-box" element at 0.5s saw something close to: invert(0.25) 7 7 PASS - "webkitFilter" property for "opacity-box" element at 0.5s saw something close to: opacity(0.75) -
trunk/LayoutTests/css3/filters/filter-animation-from-none-hw-expected.txt
r107422 r154906 3 3 PASS - "webkitFilter" property for "sepia-box" element at 1s saw something close to: sepia(0.5) 4 4 PASS - "webkitFilter" property for "saturate-box" element at 1s saw something close to: saturate(0.5) 5 PASS - "webkitFilter" property for "huerotate-box" element at 1s saw something close to: hue rotate(90deg)5 PASS - "webkitFilter" property for "huerotate-box" element at 1s saw something close to: hue-rotate(90deg) 6 6 PASS - "webkitFilter" property for "invert-box" element at 1s saw something close to: invert(0.5) 7 7 PASS - "webkitFilter" property for "opacity-box" element at 1s saw something close to: opacity(0.5) -
trunk/LayoutTests/css3/filters/filter-animation-from-none-hw.html
r107422 r154906 112 112 ["sepia-anim", 1, "sepia-box", "webkitFilter", 'sepia(0.5)', 0.05], 113 113 ["saturate-anim", 1, "saturate-box", "webkitFilter", 'saturate(0.5)', 0.05], 114 ["huerotate-anim", 1, "huerotate-box", "webkitFilter", 'hue rotate(90deg)', 5],114 ["huerotate-anim", 1, "huerotate-box", "webkitFilter", 'hue-rotate(90deg)', 5], 115 115 ["invert-anim", 1, "invert-box", "webkitFilter", 'invert(0.5)', 0.05], 116 116 ["opacity-anim", 1, "opacity-box", "webkitFilter", 'opacity(0.5)', 0.05], -
trunk/LayoutTests/css3/filters/filter-animation-from-none-multi-expected.txt
r107422 r154906 3 3 PASS - "webkitFilter" property for "sepia-box" element at 0.5s saw something close to: sepia(0.25) 4 4 PASS - "webkitFilter" property for "saturate-box" element at 0.5s saw something close to: saturate(0.75) 5 PASS - "webkitFilter" property for "huerotate-box" element at 0.5s saw something close to: hue rotate(45deg)5 PASS - "webkitFilter" property for "huerotate-box" element at 0.5s saw something close to: hue-rotate(45deg) 6 6 PASS - "webkitFilter" property for "invert-box" element at 0.5s saw something close to: invert(0.25) 7 7 PASS - "webkitFilter" property for "opacity-box" element at 0.5s saw something close to: opacity(0.75) -
trunk/LayoutTests/css3/filters/filter-animation-from-none-multi-hw-expected.txt
r107422 r154906 3 3 PASS - "webkitFilter" property for "sepia-box" element at 0.5s saw something close to: sepia(0.25) 4 4 PASS - "webkitFilter" property for "saturate-box" element at 0.5s saw something close to: saturate(0.75) 5 PASS - "webkitFilter" property for "huerotate-box" element at 0.5s saw something close to: hue rotate(45deg)5 PASS - "webkitFilter" property for "huerotate-box" element at 0.5s saw something close to: hue-rotate(45deg) 6 6 PASS - "webkitFilter" property for "invert-box" element at 0.5s saw something close to: invert(0.25) 7 7 PASS - "webkitFilter" property for "opacity-box" element at 0.5s saw something close to: opacity(0.75) -
trunk/LayoutTests/css3/filters/filter-animation-from-none-multi-hw.html
r107422 r154906 121 121 ["sepia-anim", 0.5, "sepia-box", "webkitFilter", 'sepia(0.25)', 0.05], 122 122 ["saturate-anim", 0.5, "saturate-box", "webkitFilter", 'saturate(0.75)', 0.05], 123 ["huerotate-anim", 0.5, "huerotate-box", "webkitFilter", 'hue rotate(45deg)', 3],123 ["huerotate-anim", 0.5, "huerotate-box", "webkitFilter", 'hue-rotate(45deg)', 3], 124 124 ["invert-anim", 0.5, "invert-box", "webkitFilter", 'invert(0.25)', 0.05], 125 125 ["opacity-anim", 0.5, "opacity-box", "webkitFilter", 'opacity(0.75)', 0.05], -
trunk/LayoutTests/css3/filters/filter-animation-from-none-multi.html
r107422 r154906 121 121 ["sepia-anim", 0.5, "sepia-box", "webkitFilter", 'sepia(0.25)', 0.05], 122 122 ["saturate-anim", 0.5, "saturate-box", "webkitFilter", 'saturate(0.75)', 0.05], 123 ["huerotate-anim", 0.5, "huerotate-box", "webkitFilter", 'hue rotate(45deg)', 5],123 ["huerotate-anim", 0.5, "huerotate-box", "webkitFilter", 'hue-rotate(45deg)', 5], 124 124 ["invert-anim", 0.5, "invert-box", "webkitFilter", 'invert(0.25)', 0.05], 125 125 ["opacity-anim", 0.5, "opacity-box", "webkitFilter", 'opacity(0.75)', 0.05], -
trunk/LayoutTests/css3/filters/filter-animation-from-none.html
r103586 r154906 111 111 ["sepia-anim", 0.5, "sepia-box", "webkitFilter", 'sepia(0.25)', 0.05], 112 112 ["saturate-anim", 0.5, "saturate-box", "webkitFilter", 'saturate(0.75)', 0.05], 113 ["huerotate-anim", 0.5, "huerotate-box", "webkitFilter", 'hue rotate(45deg)', 3],113 ["huerotate-anim", 0.5, "huerotate-box", "webkitFilter", 'hue-rotate(45deg)', 3], 114 114 ["invert-anim", 0.5, "invert-box", "webkitFilter", 'invert(0.25)', 0.05], 115 115 ["opacity-anim", 0.5, "opacity-box", "webkitFilter", 'opacity(0.75)', 0.05], -
trunk/LayoutTests/css3/filters/filter-animation-hw-expected.txt
r107422 r154906 3 3 PASS - "webkitFilter" property for "sepia-box" element at 1s saw something close to: sepia(0.5) 4 4 PASS - "webkitFilter" property for "saturate-box" element at 1s saw something close to: saturate(0.5) 5 PASS - "webkitFilter" property for "huerotate-box" element at 1s saw something close to: hue rotate(90deg)5 PASS - "webkitFilter" property for "huerotate-box" element at 1s saw something close to: hue-rotate(90deg) 6 6 PASS - "webkitFilter" property for "invert-box" element at 1s saw something close to: invert(0.5) 7 7 PASS - "webkitFilter" property for "opacity-box" element at 1s saw something close to: opacity(0.5) -
trunk/LayoutTests/css3/filters/filter-animation-hw.html
r107422 r154906 113 113 ["sepia-anim", 1, "sepia-box", "webkitFilter", 'sepia(0.5)', 0.05], 114 114 ["saturate-anim", 1, "saturate-box", "webkitFilter", 'saturate(0.5)', 0.05], 115 ["huerotate-anim", 1, "huerotate-box", "webkitFilter", 'hue rotate(90deg)', 2],115 ["huerotate-anim", 1, "huerotate-box", "webkitFilter", 'hue-rotate(90deg)', 2], 116 116 ["invert-anim", 1, "invert-box", "webkitFilter", 'invert(0.5)', 0.05], 117 117 ["opacity-anim", 1, "opacity-box", "webkitFilter", 'opacity(0.5)', 0.05], -
trunk/LayoutTests/css3/filters/filter-animation-multi-expected.txt
r107422 r154906 3 3 PASS - "webkitFilter" property for "sepia-box" element at 1s saw something close to: sepia(0.5) 4 4 PASS - "webkitFilter" property for "saturate-box" element at 1s saw something close to: saturate(0.5) 5 PASS - "webkitFilter" property for "huerotate-box" element at 1s saw something close to: hue rotate(90deg)5 PASS - "webkitFilter" property for "huerotate-box" element at 1s saw something close to: hue-rotate(90deg) 6 6 PASS - "webkitFilter" property for "invert-box" element at 1s saw something close to: invert(0.5) 7 7 PASS - "webkitFilter" property for "opacity-box" element at 1s saw something close to: opacity(0.5) -
trunk/LayoutTests/css3/filters/filter-animation-multi-hw-expected.txt
r107422 r154906 3 3 PASS - "webkitFilter" property for "sepia-box" element at 1s saw something close to: sepia(0.5) 4 4 PASS - "webkitFilter" property for "saturate-box" element at 1s saw something close to: saturate(0.5) 5 PASS - "webkitFilter" property for "huerotate-box" element at 1s saw something close to: hue rotate(90deg)5 PASS - "webkitFilter" property for "huerotate-box" element at 1s saw something close to: hue-rotate(90deg) 6 6 PASS - "webkitFilter" property for "invert-box" element at 1s saw something close to: invert(0.5) 7 7 PASS - "webkitFilter" property for "opacity-box" element at 1s saw something close to: opacity(0.5) -
trunk/LayoutTests/css3/filters/filter-animation-multi-hw.html
r107422 r154906 121 121 ["sepia-anim", 1, "sepia-box", "webkitFilter", 'sepia(0.5)', 0.05], 122 122 ["saturate-anim", 1, "saturate-box", "webkitFilter", 'saturate(0.5)', 0.05], 123 ["huerotate-anim", 1, "huerotate-box", "webkitFilter", 'hue rotate(90deg)', 2],123 ["huerotate-anim", 1, "huerotate-box", "webkitFilter", 'hue-rotate(90deg)', 2], 124 124 ["invert-anim", 1, "invert-box", "webkitFilter", 'invert(0.5)', 0.05], 125 125 ["opacity-anim", 1, "opacity-box", "webkitFilter", 'opacity(0.5)', 0.05], -
trunk/LayoutTests/css3/filters/filter-animation-multi.html
r107422 r154906 121 121 ["sepia-anim", 1, "sepia-box", "webkitFilter", 'sepia(0.5)', 0.05], 122 122 ["saturate-anim", 1, "saturate-box", "webkitFilter", 'saturate(0.5)', 0.05], 123 ["huerotate-anim", 1, "huerotate-box", "webkitFilter", 'hue rotate(90deg)', 2],123 ["huerotate-anim", 1, "huerotate-box", "webkitFilter", 'hue-rotate(90deg)', 2], 124 124 ["invert-anim", 1, "invert-box", "webkitFilter", 'invert(0.5)', 0.05], 125 125 ["opacity-anim", 1, "opacity-box", "webkitFilter", 'opacity(0.5)', 0.05], -
trunk/LayoutTests/css3/filters/filter-animation.html
r103586 r154906 111 111 ["sepia-anim", 1, "sepia-box", "webkitFilter", 'sepia(0.5)', 0.05], 112 112 ["saturate-anim", 1, "saturate-box", "webkitFilter", 'saturate(0.5)', 0.05], 113 ["huerotate-anim", 1, "huerotate-box", "webkitFilter", 'hue rotate(90deg)', 2],113 ["huerotate-anim", 1, "huerotate-box", "webkitFilter", 'hue-rotate(90deg)', 2], 114 114 ["invert-anim", 1, "invert-box", "webkitFilter", 'invert(0.5)', 0.05], 115 115 ["opacity-anim", 1, "opacity-box", "webkitFilter", 'opacity(0.5)', 0.05], -
trunk/LayoutTests/platform/mac/animations/cross-fade-background-image-expected.txt
r110096 r154906 4 4 RenderBlock {HTML} at (0,0) size 800x600 5 5 RenderBody {BODY} at (8,8) size 784x584 6 RenderBlock {DIV} at (0,0) size 784x54 7 RenderText {#text} at (0,0) size 577x18 8 text run at (0,0) width 577: "PASS - \"backgroundImage\" property for \"box\" element at 2.5s saw something close to: 0.5" 9 RenderBR {BR} at (577,14) size 0x0 10 RenderText {#text} at (0,18) size 704x18 11 text run at (0,18) width 704: "PASS - \"backgroundImage\" property for \"box\" and \"boxStatic\" elements at 2.5s are close enough to each other" 12 RenderBR {BR} at (704,32) size 0x0 13 RenderText {#text} at (0,36) size 769x18 14 text run at (0,36) width 769: "PASS - \"backgroundImage\" property for \"boxShorthand\" and \"boxStatic\" elements at 2.5s are close enough to each other" 15 RenderBR {BR} at (769,50) size 0x0 6 RenderBlock {DIV} at (0,0) size 784x72 7 RenderText {#text} at (0,0) size 733x36 8 text run at (0,0) width 733: "PASS - \"backgroundImage\" property for \"box\" element at 2.5s saw something close to: -webkit-cross-fade(url(blue-" 9 text run at (0,18) width 226: "100.png), url(green-100.png), 50%)" 10 RenderBR {BR} at (226,32) size 0x0 11 RenderText {#text} at (0,36) size 704x18 12 text run at (0,36) width 704: "PASS - \"backgroundImage\" property for \"box\" and \"boxStatic\" elements at 2.5s are close enough to each other" 13 RenderBR {BR} at (704,50) size 0x0 14 RenderText {#text} at (0,54) size 769x18 15 text run at (0,54) width 769: "PASS - \"backgroundImage\" property for \"boxShorthand\" and \"boxStatic\" elements at 2.5s are close enough to each other" 16 RenderBR {BR} at (769,68) size 0x0 16 17 layer at (100,100) size 100x100 17 18 RenderBlock (positioned) {DIV} at (100,100) size 100x100 [bgcolor=#FF0000] -
trunk/LayoutTests/platform/mac/animations/cross-fade-border-image-source-expected.txt
r126704 r154906 4 4 RenderBlock {HTML} at (0,0) size 800x600 5 5 RenderBody {BODY} at (8,8) size 784x584 6 RenderBlock {DIV} at (0,0) size 784x54 7 RenderText {#text} at (0,0) size 587x18 8 text run at (0,0) width 587: "PASS - \"borderImageSource\" property for \"box\" element at 2.5s saw something close to: 0.5" 9 RenderBR {BR} at (587,14) size 0x0 10 RenderText {#text} at (0,18) size 714x18 11 text run at (0,18) width 714: "PASS - \"borderImageSource\" property for \"box\" and \"boxStatic\" elements at 2.5s are close enough to each other" 12 RenderBR {BR} at (714,32) size 0x0 13 RenderText {#text} at (0,36) size 779x18 14 text run at (0,36) width 779: "PASS - \"borderImageSource\" property for \"boxShorthand\" and \"boxStatic\" elements at 2.5s are close enough to each other" 15 RenderBR {BR} at (779,50) size 0x0 6 RenderBlock {DIV} at (0,0) size 784x72 7 RenderText {#text} at (0,0) size 756x36 8 text run at (0,0) width 756: "PASS - \"borderImageSource\" property for \"box\" element at 2.5s saw something close to: -webkit-cross-fade(url(stripes-" 9 text run at (0,18) width 217: "100.png), url(green-100.png), 0.5)" 10 RenderBR {BR} at (217,32) size 0x0 11 RenderText {#text} at (0,36) size 714x18 12 text run at (0,36) width 714: "PASS - \"borderImageSource\" property for \"box\" and \"boxStatic\" elements at 2.5s are close enough to each other" 13 RenderBR {BR} at (714,50) size 0x0 14 RenderText {#text} at (0,54) size 779x18 15 text run at (0,54) width 779: "PASS - \"borderImageSource\" property for \"boxShorthand\" and \"boxStatic\" elements at 2.5s are close enough to each other" 16 RenderBR {BR} at (779,68) size 0x0 16 17 layer at (100,100) size 106x106 17 18 RenderBlock (positioned) {DIV} at (100,100) size 106x106 [bgcolor=#008000] [border: (3px none #000000)] -
trunk/LayoutTests/platform/mac/animations/cross-fade-list-style-image-expected.txt
r110096 r154906 4 4 RenderBlock {HTML} at (0,0) size 800x600 5 5 RenderBody {BODY} at (8,8) size 784x584 6 RenderBlock {DIV} at (0,0) size 784x54 7 RenderText {#text} at (0,0) size 552x18 8 text run at (0,0) width 552: "PASS - \"listStyleImage\" property for \"box\" element at 2.5s saw something close to: 0.5" 9 RenderBR {BR} at (552,14) size 0x0 10 RenderText {#text} at (0,18) size 679x18 11 text run at (0,18) width 679: "PASS - \"listStyleImage\" property for \"box\" and \"boxStatic\" elements at 2.5s are close enough to each other" 12 RenderBR {BR} at (679,32) size 0x0 13 RenderText {#text} at (0,36) size 744x18 14 text run at (0,36) width 744: "PASS - \"listStyleImage\" property for \"boxShorthand\" and \"boxStatic\" elements at 2.5s are close enough to each other" 15 RenderBR {BR} at (744,50) size 0x0 6 RenderBlock {DIV} at (0,0) size 784x72 7 RenderText {#text} at (0,0) size 769x36 8 text run at (0,0) width 769: "PASS - \"listStyleImage\" property for \"box\" element at 2.5s saw something close to: -webkit-cross-fade(url(blue-100.png)," 9 text run at (0,18) width 161: "url(green-100.png), 50%)" 10 RenderBR {BR} at (161,32) size 0x0 11 RenderText {#text} at (0,36) size 679x18 12 text run at (0,36) width 679: "PASS - \"listStyleImage\" property for \"box\" and \"boxStatic\" elements at 2.5s are close enough to each other" 13 RenderBR {BR} at (679,50) size 0x0 14 RenderText {#text} at (0,54) size 744x18 15 text run at (0,54) width 744: "PASS - \"listStyleImage\" property for \"boxShorthand\" and \"boxStatic\" elements at 2.5s are close enough to each other" 16 RenderBR {BR} at (744,68) size 0x0 16 17 layer at (100,116) size 140x100 17 18 RenderBlock (positioned) {UL} at (100,116) size 140x100 -
trunk/LayoutTests/platform/mac/animations/cross-fade-webkit-mask-box-image-expected.txt
r104884 r154906 4 4 RenderBlock {HTML} at (0,0) size 800x600 5 5 RenderBody {BODY} at (8,8) size 784x584 6 RenderBlock {DIV} at (0,0) size 784x36 7 RenderText {#text} at (0,0) size 623x18 8 text run at (0,0) width 623: "PASS - \"webkitMaskBoxImage\" property for \"box\" element at 2.25s saw something close to: 0.25" 9 RenderBR {BR} at (623,14) size 0x0 10 RenderText {#text} at (0,18) size 742x18 11 text run at (0,18) width 742: "PASS - \"webkitMaskBoxImage\" property for \"box\" and \"boxStatic\" elements at 2.25s are close enough to each other" 12 RenderBR {BR} at (742,32) size 0x0 6 RenderBlock {DIV} at (0,0) size 784x54 7 RenderText {#text} at (0,0) size 784x36 8 text run at (0,0) width 784: "PASS - \"webkitMaskBoxImage\" property for \"box\" element at 2.25s saw something close to: -webkit-cross-fade(url(stripes-" 9 text run at (0,18) width 226: "100.png), url(green-100.png), 25%)" 10 RenderBR {BR} at (226,32) size 0x0 11 RenderText {#text} at (0,36) size 742x18 12 text run at (0,36) width 742: "PASS - \"webkitMaskBoxImage\" property for \"box\" and \"boxStatic\" elements at 2.25s are close enough to each other" 13 RenderBR {BR} at (742,50) size 0x0 13 14 layer at (100,100) size 200x200 14 15 RenderImage {IMG} at (100,100) size 200x200 [bgcolor=#FF0000] -
trunk/LayoutTests/platform/mac/animations/cross-fade-webkit-mask-image-expected.txt
r110096 r154906 4 4 RenderBlock {HTML} at (0,0) size 800x600 5 5 RenderBody {BODY} at (8,8) size 784x584 6 RenderBlock {DIV} at (0,0) size 784x36 7 RenderText {#text} at (0,0) size 596x18 8 text run at (0,0) width 596: "PASS - \"webkitMaskImage\" property for \"box\" element at 2.25s saw something close to: 0.25" 9 RenderBR {BR} at (596,14) size 0x0 10 RenderText {#text} at (0,18) size 715x18 11 text run at (0,18) width 715: "PASS - \"webkitMaskImage\" property for \"box\" and \"boxStatic\" elements at 2.25s are close enough to each other" 12 RenderBR {BR} at (715,32) size 0x0 6 RenderBlock {DIV} at (0,0) size 784x54 7 RenderText {#text} at (0,0) size 757x36 8 text run at (0,0) width 757: "PASS - \"webkitMaskImage\" property for \"box\" element at 2.25s saw something close to: -webkit-cross-fade(url(stripes-" 9 text run at (0,18) width 226: "100.png), url(green-100.png), 25%)" 10 RenderBR {BR} at (226,32) size 0x0 11 RenderText {#text} at (0,36) size 715x18 12 text run at (0,36) width 715: "PASS - \"webkitMaskImage\" property for \"box\" and \"boxStatic\" elements at 2.25s are close enough to each other" 13 RenderBR {BR} at (715,50) size 0x0 13 14 layer at (100,100) size 100x100 14 15 RenderImage {IMG} at (100,100) size 100x100 [bgcolor=#FF0000] -
trunk/Source/WebCore/ChangeLog
r154905 r154906 1 2013-08-30 Dirk Schulze <krit@webkit.org> 2 3 Animate CSS Image filter() function 4 https://bugs.webkit.org/show_bug.cgi?id=119938 5 6 Reviewed by Simon Fraser. 7 8 With this patch, the new introduced CSS Image function filter() can be 9 animated. According to the spec, just filter functions can be 10 interpolated. 11 12 The patch also prepares StyleImage blending for interpolation of other 13 generated images like gradients or cross-fade(). 14 15 http://dev.w3.org/fxtf/filters/#interpolating-filter-image 16 17 Test: fast/filter-image/filter-image-animation.html 18 19 * css/CSSComputedStyleDeclaration.cpp: Reuse the code that creates a 20 CSSValueList from ComputeStyle logic. 21 (WebCore::valueForPixel): 22 For StyleRules we want to have not-adjusted length values. 23 (WebCore::ComputedStyleExtractor::valueForShadow): 24 Add argument to switch between adjusted and not-adjusted length. 25 (WebCore::ComputedStyleExtractor::valueForFilter): 26 Ditto. 27 (WebCore::ComputedStyleExtractor::propertyValue): 28 * css/CSSComputedStyleDeclaration.h: 29 * css/CSSFilterImageValue.h: Add helper functions 30 for animating filters. We need to pass the FilterOperations for 31 the image generation and the CSSValueList for StyleRule. 32 (WebCore::CSSFilterImageValue::filterOperations): 33 (WebCore::CSSFilterImageValue::setFilterOperations): 34 (WebCore::CSSFilterImageValue::cachedImage): 35 * page/animation/CSSPropertyAnimation.cpp: 36 Add animation code to support animations between two filter() 37 function values. 38 (WebCore::blendFilterOperations): 39 (WebCore::blendFunc): 40 (WebCore::filterBlend): 41 * rendering/style/StyleGeneratedImage.h: Add helper functions. 42 (WebCore::CSSFilterImageValue::imageValue): 43 44 1 45 2013-08-30 Leo Yang <leoyang@blackberry.com> 2 46 -
trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp
r154877 r154906 901 901 #endif // ENABLE(CSS_SHADERS) 902 902 903 static inline PassRefPtr<CSSPrimitiveValue> adjustLengthForZoom(double length, const RenderStyle* style, AdjustPixelValuesForComputedStyle adjust) 904 { 905 return adjust == AdjustPixelValues ? zoomAdjustedPixelValue(length, style) : cssValuePool().createValue(length, CSSPrimitiveValue::CSS_PX); 906 } 907 908 static inline PassRefPtr<CSSPrimitiveValue> adjustLengthForZoom(const Length& length, const RenderStyle* style, AdjustPixelValuesForComputedStyle adjust) 909 { 910 return adjust == AdjustPixelValues ? zoomAdjustedPixelValue(length.value(), style) : cssValuePool().createValue(length); 911 } 912 913 PassRefPtr<CSSValue> ComputedStyleExtractor::valueForShadow(const ShadowData* shadow, CSSPropertyID propertyID, const RenderStyle* style, AdjustPixelValuesForComputedStyle adjust) 914 { 915 if (!shadow) 916 return cssValuePool().createIdentifierValue(CSSValueNone); 917 918 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 919 for (const ShadowData* currShadowData = shadow; currShadowData; currShadowData = currShadowData->next()) { 920 RefPtr<CSSPrimitiveValue> x = adjustLengthForZoom(currShadowData->x(), style, adjust); 921 RefPtr<CSSPrimitiveValue> y = adjustLengthForZoom(currShadowData->y(), style, adjust); 922 RefPtr<CSSPrimitiveValue> blur = adjustLengthForZoom(currShadowData->radius(), style, adjust); 923 RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? PassRefPtr<CSSPrimitiveValue>() : adjustLengthForZoom(currShadowData->spread(), style, adjust); 924 RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || currShadowData->style() == Normal ? PassRefPtr<CSSPrimitiveValue>() : cssValuePool().createIdentifierValue(CSSValueInset); 925 RefPtr<CSSPrimitiveValue> color = cssValuePool().createColorValue(currShadowData->color().rgb()); 926 list->prepend(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release())); 927 } 928 return list.release(); 929 } 930 903 931 #if ENABLE(CSS_FILTERS) 904 PassRefPtr<CSSValue> ComputedStyleExtractor::valueForFilter(const RenderObject* renderer, const RenderStyle* style ) const932 PassRefPtr<CSSValue> ComputedStyleExtractor::valueForFilter(const RenderObject* renderer, const RenderStyle* style, const FilterOperations& filterOperations, AdjustPixelValuesForComputedStyle adjust) 905 933 { 906 934 #if !ENABLE(CSS_SHADERS) 907 935 UNUSED_PARAM(renderer); 908 936 #endif 909 if ( style->filter().operations().isEmpty())937 if (filterOperations.operations().isEmpty()) 910 938 return cssValuePool().createIdentifierValue(CSSValueNone); 911 939 … … 914 942 RefPtr<WebKitCSSFilterValue> filterValue; 915 943 916 Vector<RefPtr<FilterOperation> >::const_iterator end = style->filter().operations().end();917 for (Vector<RefPtr<FilterOperation> >::const_iterator it = style->filter().operations().begin(); it != end; ++it) {944 Vector<RefPtr<FilterOperation> >::const_iterator end = filterOperations.operations().end(); 945 for (Vector<RefPtr<FilterOperation> >::const_iterator it = filterOperations.operations().begin(); it != end; ++it) { 918 946 FilterOperation* filterOperation = (*it).get(); 919 947 switch (filterOperation->getOperationType()) { … … 975 1003 BlurFilterOperation* blurOperation = static_cast<BlurFilterOperation*>(filterOperation); 976 1004 filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::BlurFilterOperation); 977 filterValue->append( zoomAdjustedPixelValue(blurOperation->stdDeviation().value(), style));1005 filterValue->append(adjustLengthForZoom(blurOperation->stdDeviation(), style, adjust)); 978 1006 break; 979 1007 } … … 983 1011 // We want our computed style to look like that of a text shadow (has neither spread nor inset style). 984 1012 ShadowData shadowData = ShadowData(dropShadowOperation->location(), dropShadowOperation->stdDeviation(), 0, Normal, false, dropShadowOperation->color()); 985 filterValue->append(valueForShadow(&shadowData, CSSPropertyTextShadow, style ));1013 filterValue->append(valueForShadow(&shadowData, CSSPropertyTextShadow, style, adjust)); 986 1014 break; 987 1015 } … … 1329 1357 } 1330 1358 1331 PassRefPtr<CSSValue> ComputedStyleExtractor::valueForShadow(const ShadowData* shadow, CSSPropertyID propertyID, const RenderStyle* style) const1332 {1333 if (!shadow)1334 return cssValuePool().createIdentifierValue(CSSValueNone);1335 1336 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();1337 for (const ShadowData* s = shadow; s; s = s->next()) {1338 RefPtr<CSSPrimitiveValue> x = zoomAdjustedPixelValue(s->x(), style);1339 RefPtr<CSSPrimitiveValue> y = zoomAdjustedPixelValue(s->y(), style);1340 RefPtr<CSSPrimitiveValue> blur = zoomAdjustedPixelValue(s->radius(), style);1341 RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? PassRefPtr<CSSPrimitiveValue>() : zoomAdjustedPixelValue(s->spread(), style);1342 RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || s->style() == Normal ? PassRefPtr<CSSPrimitiveValue>() : cssValuePool().createIdentifierValue(CSSValueInset);1343 RefPtr<CSSPrimitiveValue> color = cssValuePool().createColorValue(s->color().rgb());1344 list->prepend(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));1345 }1346 return list.release();1347 }1348 1359 1349 1360 static CSSValueID identifierForFamily(const AtomicString& family) … … 2833 2844 #if ENABLE(CSS_FILTERS) 2834 2845 case CSSPropertyWebkitFilter: 2835 return valueForFilter(renderer, style.get() );2846 return valueForFilter(renderer, style.get(), style->filter()); 2836 2847 #endif 2837 2848 #if ENABLE(CSS_COMPOSITING) -
trunk/Source/WebCore/css/CSSComputedStyleDeclaration.h
r150960 r154906 32 32 class CSSValueList; 33 33 class Color; 34 class FilterOperations; 34 35 class MutableStylePropertySet; 35 36 class Node; … … 48 49 enum EUpdateLayout { DoNotUpdateLayout = false, UpdateLayout = true }; 49 50 51 enum AdjustPixelValuesForComputedStyle { AdjustPixelValues, DoNotAdjustPixelValues }; 52 50 53 class ComputedStyleExtractor { 51 54 public: … … 61 64 bool propertyMatches(CSSPropertyID, const CSSValue*) const; 62 65 66 #if ENABLE(CSS_FILTERS) 67 static PassRefPtr<CSSValue> valueForFilter(const RenderObject*, const RenderStyle*, const FilterOperations&, AdjustPixelValuesForComputedStyle = AdjustPixelValues); 68 #endif 69 63 70 private: 64 71 // The styled node is either the node passed into computedPropertyValue, or the … … 73 80 #endif 74 81 75 PassRefPtr<CSSValue> valueForShadow(const ShadowData*, CSSPropertyID, const RenderStyle*) const;82 static PassRefPtr<CSSValue> valueForShadow(const ShadowData*, CSSPropertyID, const RenderStyle*, AdjustPixelValuesForComputedStyle = AdjustPixelValues); 76 83 PassRefPtr<CSSPrimitiveValue> currentColorOrValidColor(RenderStyle*, const Color&) const; 77 78 #if ENABLE(CSS_FILTERS)79 PassRefPtr<CSSValue> valueForFilter(const RenderObject*, const RenderStyle*) const;80 #endif81 84 82 85 PassRefPtr<CSSValueList> getCSSPropertyValuesForShorthandProperties(const StylePropertyShorthand&) const; -
trunk/Source/WebCore/css/CSSFilterImageValue.cpp
r154580 r154906 163 163 bool CSSFilterImageValue::equals(const CSSFilterImageValue& other) const 164 164 { 165 return compareCSSValuePtr(m_imageValue, other.m_imageValue) 166 && compareCSSValuePtr(m_filterValue, other.m_filterValue); 165 return equalInputImages(other) && compareCSSValuePtr(m_filterValue, other.m_filterValue); 166 } 167 168 bool CSSFilterImageValue::equalInputImages(const CSSFilterImageValue& other) const 169 { 170 return compareCSSValuePtr(m_imageValue, other.m_imageValue); 167 171 } 168 172 -
trunk/Source/WebCore/css/CSSFilterImageValue.h
r154133 r154906 71 71 bool equals(const CSSFilterImageValue&) const; 72 72 73 bool equalInputImages(const CSSFilterImageValue&) const; 74 73 75 void createFilterOperations(StyleResolver*); 76 77 const FilterOperations& filterOperations() const { return m_filterOperations; } 78 void setFilterOperations(const FilterOperations& filterOperations) 79 { 80 m_filterOperations = filterOperations; 81 } 82 CachedImage* cachedImage() const { return m_cachedImage.get(); } 74 83 75 84 private: … … 111 120 }; 112 121 122 inline CSSFilterImageValue* toCSSFilterImageValue(CSSImageGeneratorValue* value) 123 { 124 ASSERT_WITH_SECURITY_IMPLICATION(!value || value->isFilterImageValue()); 125 return static_cast<CSSFilterImageValue*>(value); 126 } 127 113 128 } // namespace WebCore 114 129 -
trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp
r153764 r154906 32 32 33 33 #include "AnimationBase.h" 34 #include "CSSComputedStyleDeclaration.h" 34 35 #include "CSSCrossfadeValue.h" 36 #include "CSSFilterImageValue.h" 35 37 #include "CSSImageGeneratorValue.h" 36 38 #include "CSSImageValue.h" … … 173 175 } 174 176 177 static inline void blendFilterOperations(const AnimationBase* anim, FilterOperations& result, const FilterOperations& from, const FilterOperations& to, double progress) 178 { 179 size_t fromSize = from.operations().size(); 180 size_t toSize = to.operations().size(); 181 size_t size = max(fromSize, toSize); 182 for (size_t i = 0; i < size; i++) { 183 RefPtr<FilterOperation> fromOp = (i < fromSize) ? from.operations()[i].get() : 0; 184 RefPtr<FilterOperation> toOp = (i < toSize) ? to.operations()[i].get() : 0; 185 RefPtr<FilterOperation> blendedOp = toOp ? blendFunc(anim, fromOp.get(), toOp.get(), progress) : (fromOp ? blendFunc(anim, 0, fromOp.get(), progress, true) : 0); 186 if (blendedOp) 187 result.operations().append(blendedOp); 188 else { 189 RefPtr<FilterOperation> identityOp = PassthroughFilterOperation::create(); 190 if (progress > 0.5) 191 result.operations().append(toOp ? toOp : identityOp); 192 else 193 result.operations().append(fromOp ? fromOp : identityOp); 194 } 195 } 196 } 197 175 198 static inline FilterOperations blendFunc(const AnimationBase* anim, const FilterOperations& from, const FilterOperations& to, double progress) 176 199 { … … 178 201 179 202 // If we have a filter function list, use that to do a per-function animation. 180 if (anim->filterFunctionListsMatch()) { 181 size_t fromSize = from.operations().size(); 182 size_t toSize = to.operations().size(); 183 size_t size = max(fromSize, toSize); 184 for (size_t i = 0; i < size; i++) { 185 RefPtr<FilterOperation> fromOp = (i < fromSize) ? from.operations()[i].get() : 0; 186 RefPtr<FilterOperation> toOp = (i < toSize) ? to.operations()[i].get() : 0; 187 RefPtr<FilterOperation> blendedOp = toOp ? blendFunc(anim, fromOp.get(), toOp.get(), progress) : (fromOp ? blendFunc(anim, 0, fromOp.get(), progress, true) : 0); 188 if (blendedOp) 189 result.operations().append(blendedOp); 190 else { 191 RefPtr<FilterOperation> identityOp = PassthroughFilterOperation::create(); 192 if (progress > 0.5) 193 result.operations().append(toOp ? toOp : identityOp); 194 else 195 result.operations().append(fromOp ? fromOp : identityOp); 196 } 197 } 198 } else { 203 if (anim->filterFunctionListsMatch()) 204 blendFilterOperations(anim, result, from, to, progress); 205 else { 199 206 // If the filter function lists don't match, we could try to cross-fade, but don't yet have a way to represent that in CSS. 200 207 // For now we'll just fail to animate. … … 203 210 204 211 return result; 212 } 213 214 static inline PassRefPtr<StyleImage> filterBlend(const AnimationBase* anim, StyleImage* from, StyleImage* to, double progress) 215 { 216 CSSFilterImageValue* fromValue = static_cast<CSSFilterImageValue*>(from->data()); 217 CSSFilterImageValue* toValue = static_cast<CSSFilterImageValue*>(to->data()); 218 219 FilterOperations filterOperationsResult; 220 blendFilterOperations(anim, filterOperationsResult, fromValue->filterOperations(), toValue->filterOperations(), progress); 221 if (!toValue->cachedImage()) 222 return to; 223 224 RefPtr<StyleCachedImage> styledImage = StyleCachedImage::create(toValue->cachedImage()); 225 226 RefPtr<CSSImageValue> imageValue = CSSImageValue::create(toValue->cachedImage()->url(), styledImage.get()); 227 RefPtr<CSSValue> filterValue = ComputedStyleExtractor::valueForFilter(anim->renderer(), anim->renderer()->style(), 228 filterOperationsResult, DoNotAdjustPixelValues); 229 RefPtr<CSSFilterImageValue> result = CSSFilterImageValue::create(imageValue, filterValue); 230 result->setFilterOperations(filterOperationsResult); 231 232 return StyleGeneratedImage::create(result.get()); 205 233 } 206 234 #endif // ENABLE(CSS_FILTERS) … … 280 308 return to; 281 309 310 // Animation between two generated images. Cross fade for all other cases. 311 if (from->isGeneratedImage() && to->isGeneratedImage()) { 312 CSSImageGeneratorValue* fromGenerated = toStyleGeneratedImage(from)->imageValue(); 313 CSSImageGeneratorValue* toGenerated = toStyleGeneratedImage(to)->imageValue(); 314 315 #if ENABLE(CSS_FILTERS) 316 if (fromGenerated->isFilterImageValue() && toGenerated->isFilterImageValue()) { 317 // Animation of generated images just possible if input images are equal. 318 // Otherwise fall back to cross fade animation. 319 CSSFilterImageValue* fromFitler = toCSSFilterImageValue(fromGenerated); 320 CSSFilterImageValue* toFitler = toCSSFilterImageValue(toGenerated); 321 if (fromFitler->equalInputImages(*toFitler)) 322 return filterBlend(anim, from, to, progress); 323 } 324 #else 325 UNUSED_PARAM(fromGenerated); 326 UNUSED_PARAM(toGenerated); 327 #endif 328 // FIXME: Add support for animation between two cross-fade() functions. 329 // https://bugs.webkit.org/show_bug.cgi?id=119955 330 331 // FIXME: Add support for animation between two *gradient() functions. 332 // https://bugs.webkit.org/show_bug.cgi?id=119956 333 } 334 335 // FIXME: Add support cross fade between cached and generated images. 336 // https://bugs.webkit.org/show_bug.cgi?id=78293 282 337 if (from->isCachedImage() && to->isCachedImage()) 283 338 return crossfadeBlend(anim, static_cast<StyleCachedImage*>(from), static_cast<StyleCachedImage*>(to), progress); 284 285 // FIXME: Support transitioning generated images as well. (gradients, etc.)286 339 287 340 return to; -
trunk/Source/WebCore/rendering/style/StyleGeneratedImage.h
r141637 r154906 40 40 41 41 virtual WrappedImagePtr data() const { return m_imageGeneratorValue.get(); } 42 CSSImageGeneratorValue* imageValue() const { return m_imageGeneratorValue.get(); } 42 43 43 44 virtual PassRefPtr<CSSValue> cssValue() const; … … 62 63 }; 63 64 65 inline StyleGeneratedImage* toStyleGeneratedImage(StyleImage* image) 66 { 67 ASSERT_WITH_SECURITY_IMPLICATION(!image || image->isGeneratedImage()); 68 return static_cast<StyleGeneratedImage*>(image); 69 } 70 64 71 } 65 72 #endif
Note: See TracChangeset
for help on using the changeset viewer.