Bug 651036 - SMIL: Make discrete to-animations behave consistently with discrete from-to animations r=dholbert
@ -395,6 +395,10 @@ nsSMILAnimationFunction::InterpolateResult(const nsSMILValueArray& aValues,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (IsToAnimation() && aBaseValue.IsNull()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Get the normalised progress through the simple duration.
|
||||
//
|
||||
// If we have an indefinite simple duration, just set the progress to be
|
||||
@ -428,19 +432,15 @@ nsSMILAnimationFunction::InterpolateResult(const nsSMILValueArray& aValues,
|
||||
// NS_ABORT_IF_FALSE that tests that intervalProgress is in range will fail.
|
||||
double intervalProgress = -1.f;
|
||||
if (IsToAnimation()) {
|
||||
if (aBaseValue.IsNull()) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
from = &aBaseValue;
|
||||
to = &aValues[0];
|
||||
if (calcMode == CALC_PACED) {
|
||||
// Note: key[Times/Splines/Points] are ignored for calcMode="paced"
|
||||
intervalProgress = simpleProgress;
|
||||
} else {
|
||||
from = &aBaseValue;
|
||||
to = &aValues[0];
|
||||
if (calcMode == CALC_PACED) {
|
||||
// Note: key[Times/Splines/Points] are ignored for calcMode="paced"
|
||||
intervalProgress = simpleProgress;
|
||||
} else {
|
||||
double scaledSimpleProgress =
|
||||
ScaleSimpleProgress(simpleProgress, calcMode);
|
||||
intervalProgress = ScaleIntervalProgress(scaledSimpleProgress, 0);
|
||||
}
|
||||
double scaledSimpleProgress =
|
||||
ScaleSimpleProgress(simpleProgress, calcMode);
|
||||
intervalProgress = ScaleIntervalProgress(scaledSimpleProgress, 0);
|
||||
}
|
||||
} else if (calcMode == CALC_PACED) {
|
||||
rv = ComputePacedPosition(aValues, simpleProgress,
|
||||
@ -474,13 +474,16 @@ nsSMILAnimationFunction::InterpolateResult(const nsSMILValueArray& aValues,
|
||||
// Note: If interpolation failed (isn't supported for this type), the SVG
|
||||
// spec says to force discrete mode.
|
||||
if (calcMode == CALC_DISCRETE || NS_FAILED(rv)) {
|
||||
double scaledSimpleProgress =
|
||||
ScaleSimpleProgress(simpleProgress, CALC_DISCRETE);
|
||||
if (IsToAnimation()) {
|
||||
// SMIL 3, 12.6.4: Since a to animation has only 1 value, a discrete to
|
||||
// animation will simply set the to value for the simple duration.
|
||||
aResult = aValues[0];
|
||||
// We don't follow SMIL 3, 12.6.4, where discrete to animations
|
||||
// are the same as <set> animations. Instead, we treat it as a
|
||||
// discrete animation with two values (the underlying value and
|
||||
// the to="" value), and honor keyTimes="" as well.
|
||||
PRUint32 index = (PRUint32)floor(scaledSimpleProgress * 2);
|
||||
aResult = index == 0 ? aBaseValue : aValues[0];
|
||||
} else {
|
||||
double scaledSimpleProgress =
|
||||
ScaleSimpleProgress(simpleProgress, CALC_DISCRETE);
|
||||
PRUint32 index = (PRUint32)floor(scaledSimpleProgress * aValues.Length());
|
||||
aResult = aValues[index];
|
||||
}
|
||||
@ -865,11 +868,9 @@ nsSMILAnimationFunction::CheckKeyTimes(PRUint32 aNumValues)
|
||||
}
|
||||
|
||||
// no. keyTimes == no. values
|
||||
// For to-animation the number of values is considered to be 2 unless it's
|
||||
// discrete to-animation in which case either 1 or 2 is acceptable.
|
||||
PRBool matchingNumOfValues = IsToAnimation() ?
|
||||
calcMode == CALC_DISCRETE ? numKeyTimes <= 2 : numKeyTimes == 2 :
|
||||
numKeyTimes == aNumValues;
|
||||
// For to-animation the number of values is considered to be 2.
|
||||
PRBool matchingNumOfValues =
|
||||
numKeyTimes == (IsToAnimation() ? 2 : aNumValues);
|
||||
if (!matchingNumOfValues) {
|
||||
SetKeyTimesErrorFlag(PR_TRUE);
|
||||
return;
|
||||
|
@ -152,26 +152,36 @@ function main()
|
||||
'times': [ [ 2, -100 ] ]
|
||||
});
|
||||
|
||||
// to calcMode=discrete two keyTimes
|
||||
// (technically, for discrete to-animation there is only ONE animation value
|
||||
// but we allow two keyTimes to be specified since they're not going to have
|
||||
// any effect anyway and this part of the spec is somewhat counter-intuitive.
|
||||
// See bug 544855)
|
||||
// unfrozen to calcMode=discrete two keyTimes
|
||||
testCases.push({
|
||||
'attr' : { 'to': '100',
|
||||
'calcMode': 'discrete',
|
||||
'keyTimes': '0.0; 1.0',
|
||||
'fill': 'remove' },
|
||||
'times': [ [ 0, -100 ],
|
||||
[ 7, -100 ],
|
||||
[ 10, -100 ],
|
||||
[ 12, -100 ]]
|
||||
});
|
||||
|
||||
// frozen to calcMode=discrete two keyTimes
|
||||
testCases.push({
|
||||
'attr' : { 'to': '100',
|
||||
'calcMode': 'discrete',
|
||||
'keyTimes': '0.0; 1.0' },
|
||||
'times': [ [ 0, 100 ],
|
||||
[ 7, 100 ] ]
|
||||
'times': [ [ 0, -100 ],
|
||||
[ 7, -100 ],
|
||||
[ 10, 100 ],
|
||||
[ 12, 100 ] ]
|
||||
});
|
||||
|
||||
// to calcMode=discrete one keyTime
|
||||
// to calcMode=discrete -- bad number of keyTimes (one, expecting two)
|
||||
testCases.push({
|
||||
'attr' : { 'to': '100',
|
||||
'calcMode': 'discrete',
|
||||
'keyTimes': '0' },
|
||||
'times': [ [ 0, 100 ],
|
||||
[ 7, 100 ] ]
|
||||
'times': [ [ 0, -100 ],
|
||||
[ 7, -100 ] ]
|
||||
});
|
||||
|
||||
// values calcMode=discrete
|
||||
|
@ -3,8 +3,8 @@
|
||||
class="reftest-wait"
|
||||
onload="setTimeAndSnapshot(0.0, true)">
|
||||
<script xlink:href="smil-util.js" type="text/javascript"/>
|
||||
<rect x="15" y="15" width="200" height="100" fill="blue">
|
||||
<rect x="15" y="15" width="200" height="200" fill="blue">
|
||||
<animate attributeName="height" calcMode="discrete"
|
||||
to="200" dur="2s"/>
|
||||
to="100" dur="2s"/>
|
||||
</rect>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 386 B After Width: | Height: | Size: 386 B |
@ -3,8 +3,8 @@
|
||||
class="reftest-wait"
|
||||
onload="setTimeAndSnapshot(0.99, true)">
|
||||
<script xlink:href="smil-util.js" type="text/javascript"/>
|
||||
<rect x="15" y="15" width="200" height="100" fill="blue">
|
||||
<rect x="15" y="15" width="200" height="200" fill="blue">
|
||||
<animate attributeName="height" calcMode="discrete"
|
||||
to="200" dur="2s"/>
|
||||
to="100" dur="2s"/>
|
||||
</rect>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 387 B |
@ -85,10 +85,10 @@
|
||||
<feComponentTransfer>
|
||||
<feFuncR type="table" tableValues="0 0 0 0">
|
||||
|
||||
<!-- The value should be "0 2 2 0" immediately. -->
|
||||
<!-- The value should be "0 2 2 0" from 1s onwards. -->
|
||||
<animate attributeName="tableValues"
|
||||
calcMode="discrete"
|
||||
begin="0s" dur="3s"
|
||||
begin="0s" dur="2s"
|
||||
to="0 2 2 0"
|
||||
fill="freeze"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
@ -1,14 +1,18 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
class="reftest-wait" onload="setTimeAndSnapshot(2, true)">
|
||||
<script xlink:href="smil-util.js" type="text/javascript"/>
|
||||
<!-- In this test we will attempt to interpolate since fill is interpolatable
|
||||
but fail since the base value can't be converted to an RGB color value
|
||||
and hence should fall back to discrete calcMode which, in the case of
|
||||
to-animation, sets the to value for the entire simple duration. -->
|
||||
to-animation, sets the to value for the second half of the simple
|
||||
duration. -->
|
||||
<defs>
|
||||
<linearGradient id="red">
|
||||
<stop offset="0.0" stop-color="#f00"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#red)">
|
||||
<animate attributeName="fill" to="lime" dur="500s"/>
|
||||
<animate attributeName="fill" to="lime" dur="3s"/>
|
||||
</rect>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 594 B After Width: | Height: | Size: 783 B |
@ -1,8 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Test that an indefinite to-animation with discrete calcMode still applies
|
||||
the to-value for the whole time. -->
|
||||
<rect x="15" y="15" width="200" height="100" fill="blue">
|
||||
<animate attributeName="height" to="200" dur="indefinite"
|
||||
<!-- Test that an indefinite to-animation with discrete calcMode applies
|
||||
the underlying value for the whole time. -->
|
||||
<rect x="15" y="15" width="200" height="200" fill="blue">
|
||||
<animate attributeName="height" to="100" dur="indefinite"
|
||||
calcMode="discrete"/>
|
||||
</rect>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 333 B After Width: | Height: | Size: 335 B |
@ -1,8 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Test that an indefinite to-animation that falls back to discrete calcMode
|
||||
because the property is not interpolatable, still applies the to-value
|
||||
because the property is not interpolatable, applies the underlying value
|
||||
for the whole time. -->
|
||||
<rect x="15" y="15" width="200" height="200" fill="blue" visibility="hidden">
|
||||
<animate attributeName="visibility" to="visible" dur="indefinite"/>
|
||||
<rect x="15" y="15" width="200" height="200" fill="blue" visibility="visible">
|
||||
<animate attributeName="visibility" to="hidden" dur="indefinite"/>
|
||||
</rect>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 400 B After Width: | Height: | Size: 402 B |
@ -302,7 +302,7 @@
|
||||
">
|
||||
<animate attributeName="d"
|
||||
calcMode="discrete"
|
||||
begin="0s" dur="20s"
|
||||
begin="0s" dur="2s"
|
||||
to="M10,10
|
||||
L40,10
|
||||
l-30,60
|
||||
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
@ -65,7 +65,7 @@
|
||||
points="10,10 70,70 110,10 160,10 210,10">
|
||||
<animate attributeName="points"
|
||||
calcMode="discrete"
|
||||
begin="0s" dur="20s"
|
||||
begin="0s" dur="2s"
|
||||
to="10,10 70,10 110,10 160,70 210,10"
|
||||
fill="freeze"/>
|
||||
</polygon>
|
||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
@ -65,7 +65,7 @@
|
||||
points="10,10 70,70 110,10 160,10 210,10">
|
||||
<animate attributeName="points"
|
||||
calcMode="discrete"
|
||||
begin="0s" dur="20s"
|
||||
begin="0s" dur="2s"
|
||||
to="10,10 70,10 110,10 160,70 210,10"
|
||||
fill="freeze"/>
|
||||
</polyline>
|
||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
@ -61,10 +61,10 @@
|
||||
|
||||
<text transform="translate(320, 20)" rotate="10 20 30">JKL
|
||||
|
||||
<!-- The value should be "310 320 330" immediately. -->
|
||||
<!-- The value should be "310 320 330" at 3s. -->
|
||||
<animate attributeName="rotate"
|
||||
calcMode="discrete"
|
||||
begin="0s" dur="30s"
|
||||
begin="0s" dur="6s"
|
||||
to="310 320 330"
|
||||
fill="freeze"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |