Commit a3a0eeb5 authored by Fredrik Söderquist's avatar Fredrik Söderquist Committed by Commit Bot

Restrict 'keySplines' x-values to the [0, 1] range

Per SMIL[1], all the values in a key spline should be within [0, 1], but
to be consistent with CSS' timing function, allow y-values to be outside
that range (at least for now).

While in ParseKeySplinesInternal(...), rename the |pos_*| local
variables to something that carries a little bit more semantic meaning.

[1] https://www.w3.org/TR/SMIL3/smil-animation.html#adef-keySplines

Bug: 1006544
Change-Id: I6baa4085943eca8144605fb0a5c442bc8486ad87
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1821158Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#699373}
parent c0f9a899
......@@ -71,6 +71,10 @@ fail:
return false;
}
static bool IsInZeroToOneRange(float value) {
return value >= 0 && value <= 1;
}
static bool ParseKeyTimes(const String& string,
Vector<float>& result,
bool verify_order) {
......@@ -81,7 +85,7 @@ static bool ParseKeyTimes(const String& string,
String time_string = parse_list[n].StripWhiteSpace();
bool ok;
float time = time_string.ToFloat(&ok);
if (!ok || time < 0 || time > 1)
if (!ok || !IsInZeroToOneRange(time))
goto fail;
if (verify_order) {
if (!n) {
......@@ -108,20 +112,20 @@ static bool ParseKeySplinesInternal(const String& string,
SkipOptionalSVGSpaces(ptr, end);
while (ptr < end) {
float pos_a = 0;
if (!ParseNumber(ptr, end, pos_a))
float cp1x = 0;
if (!ParseNumber(ptr, end, cp1x))
return false;
float pos_b = 0;
if (!ParseNumber(ptr, end, pos_b))
float cp1y = 0;
if (!ParseNumber(ptr, end, cp1y))
return false;
float pos_c = 0;
if (!ParseNumber(ptr, end, pos_c))
float cp2x = 0;
if (!ParseNumber(ptr, end, cp2x))
return false;
float pos_d = 0;
if (!ParseNumber(ptr, end, pos_d, kDisallowWhitespace))
float cp2y = 0;
if (!ParseNumber(ptr, end, cp2y, kDisallowWhitespace))
return false;
SkipOptionalSVGSpaces(ptr, end);
......@@ -130,7 +134,11 @@ static bool ParseKeySplinesInternal(const String& string,
ptr++;
SkipOptionalSVGSpaces(ptr, end);
result.push_back(gfx::CubicBezier(pos_a, pos_b, pos_c, pos_d));
// Require that the x values are within the [0, 1] range.
if (!IsInZeroToOneRange(cp1x) || !IsInZeroToOneRange(cp2x))
return false;
result.push_back(gfx::CubicBezier(cp1x, cp1y, cp2x, cp2y));
}
return ptr == end;
......
<!DOCTYPE html>
<title>'keySplines' with x-values outside of the 0 to 1 range</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<svg>
<rect x="10" width="10" height="10" fill="blue">
<animate attributeName="x" values="0; 250" dur="5s"/>
</rect>
<rect x="10" width="10" height="10" y="20" fill="blue">
<animate attributeName="x" values="0; 250" dur="5s"
keyTimes="0; 1" keySplines="-1 0 1 1" calcMode="spline"/>
</rect>
<rect x="10" width="10" height="10" y="30" fill="blue">
<animate attributeName="x" values="0; 250" dur="5s"
keyTimes="0; 1" keySplines="2 0 1 1" calcMode="spline"/>
</rect>
<rect x="10" width="10" height="10" y="10" fill="blue">
<animate attributeName="x" values="0; 250" dur="5s"
keyTimes="0; 1" keySplines="0 0 -1 1" calcMode="spline"/>
</rect>
<rect x="10" width="10" height="10" y="40" fill="blue">
<animate attributeName="x" values="0; 250" dur="5s"
keyTimes="0; 1" keySplines="0 0 2 1" calcMode="spline"/>
</rect>
</svg>
<script>
async_test(t => {
let svg = document.querySelector('svg');
svg.pauseAnimations();
svg.setCurrentTime(2.5);
window.onload = t.step_func(() => {
requestAnimationFrame(t.step_func_done(() => {
let rects = document.getElementsByTagName('rect');
assert_equals(rects[0].getBBox().x, 125, 'animations applied');
assert_equals(rects[1].getBBox().x, 10, 'first control point x less than zero');
assert_equals(rects[2].getBBox().x, 10, 'first control point x greater than one');
assert_equals(rects[3].getBBox().x, 10, 'second control point x less than zero');
assert_equals(rects[4].getBBox().x, 10, 'second control point x greater than one');
}));
});
});
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment