Bug 653928 - Animation of path d attribute with elliptical arcs discrete instead of continuous when flags change. r=dholbert

This commit is contained in:
Robert Longson 2011-10-25 09:18:13 +01:00
parent 9bb956566a
commit 2e96bf74ce
2 changed files with 15 additions and 50 deletions

View File

@ -95,21 +95,6 @@ SVGPathSegListSMILType::IsEqual(const nsSMILValue& aLeft,
*static_cast<const SVGPathDataAndOwner*>(aRight.mU.mPtr);
}
static bool
ArcFlagsDiffer(SVGPathDataAndOwner::const_iterator aPathData1,
SVGPathDataAndOwner::const_iterator aPathData2)
{
NS_ABORT_IF_FALSE
(SVGPathSegUtils::IsArcType(SVGPathSegUtils::DecodeType(aPathData1[0])),
"ArcFlagsDiffer called with non-arc segment");
NS_ABORT_IF_FALSE
(SVGPathSegUtils::IsArcType(SVGPathSegUtils::DecodeType(aPathData2[0])),
"ArcFlagsDiffer called with non-arc segment");
return aPathData1[LARGE_ARC_FLAG_IDX] != aPathData2[LARGE_ARC_FLAG_IDX] ||
aPathData1[SWEEP_FLAG_IDX] != aPathData2[SWEEP_FLAG_IDX];
}
enum PathInterpolationResult {
eCannotInterpolate,
eRequiresConversion,
@ -139,12 +124,6 @@ CanInterpolate(const SVGPathDataAndOwner& aStart,
PRUint32 startType = SVGPathSegUtils::DecodeType(*pStart);
PRUint32 endType = SVGPathSegUtils::DecodeType(*pEnd);
if (SVGPathSegUtils::IsArcType(startType) &&
SVGPathSegUtils::IsArcType(endType) &&
ArcFlagsDiffer(pStart, pEnd)) {
return eCannotInterpolate;
}
if (startType != endType) {
if (!SVGPathSegUtils::SameTypeModuloRelativeness(startType, endType)) {
return eCannotInterpolate;
@ -215,25 +194,22 @@ AddWeightedPathSegs(double aCoeff1,
NS_ABORT_IF_FALSE(!aSeg1 || SVGPathSegUtils::DecodeType(*aSeg1) == segType,
"unexpected segment type");
// FIRST: Directly copy the arguments that don't make sense to add.
aResultSeg[0] = aSeg2[0]; // encoded segment type
bool isArcType = SVGPathSegUtils::IsArcType(segType);
if (isArcType) {
// Copy boolean arc flags.
NS_ABORT_IF_FALSE(!aSeg1 || !ArcFlagsDiffer(aSeg1, aSeg2),
"Expecting arc flags to match");
aResultSeg[LARGE_ARC_FLAG_IDX] = aSeg2[LARGE_ARC_FLAG_IDX];
aResultSeg[SWEEP_FLAG_IDX] = aSeg2[SWEEP_FLAG_IDX];
}
// SECOND: Add the arguments that are supposed to be added.
// FIRST: Add all the arguments.
// (The 1's below are to account for segment type)
PRUint32 numArgs = SVGPathSegUtils::ArgCountForType(segType);
for (PRUint32 i = 1; i < 1 + numArgs; ++i) {
// Need to skip arc flags for arc-type segments. (already handled them)
if (!(isArcType && (i == LARGE_ARC_FLAG_IDX || i == SWEEP_FLAG_IDX))) {
aResultSeg[i] = (aSeg1 ? aCoeff1 * aSeg1[i] : 0.0) + aCoeff2 * aSeg2[i];
aResultSeg[i] = (aSeg1 ? aCoeff1 * aSeg1[i] : 0.0) + aCoeff2 * aSeg2[i];
}
// SECOND: ensure non-zero flags become 1.
if (SVGPathSegUtils::IsArcType(segType)) {
if (aResultSeg[LARGE_ARC_FLAG_IDX] != 0.0f) {
aResultSeg[LARGE_ARC_FLAG_IDX] = 1.0f;
}
if (aResultSeg[SWEEP_FLAG_IDX] != 0.0f) {
aResultSeg[SWEEP_FLAG_IDX] = 1.0f;
}
}

View File

@ -138,10 +138,10 @@ var gSuffixes = {
[40, 50, 60, 70, 80, 90], [50, 70, 90, 110, 130, 150]],
QQ: [[10, 20, 30, 40], [50, 60, 70, 80], [30, 40, 50, 60], [40, 60, 80, 100]],
qq: [[10, 20, 30, 40], [50, 60, 70, 80], [30, 40, 50, 60], [40, 60, 80, 100]],
AA: [[10, 20, 30, 0, 0, 40, 50], [60, 70, 80, 0, 0, 90, 100],
[35, 45, 55, 0, 0, 65, 75], [45, 65, 85, 0, 0, 105, 125]],
aa: [[10, 20, 30, 0, 0, 40, 50], [60, 70, 80, 0, 0, 90, 100],
[35, 45, 55, 0, 0, 65, 75], [45, 65, 85, 0, 0, 105, 125]],
AA: [[10, 20, 30, 1, 0, 40, 50], [60, 70, 80, 0, 0, 90, 100],
[35, 45, 55, 1, 0, 65, 75], [45, 65, 85, 1, 0, 105, 125]],
aa: [[10, 20, 30, 0, 1, 40, 50], [60, 70, 80, 0, 0, 90, 100],
[35, 45, 55, 0, 1, 65, 75], [45, 65, 85, 0, 1, 105, 125]],
HH: [[10], [20], [15], [25]],
hh: [[10], [20], [15], [25]],
VV: [[10], [20], [15], [25]],
@ -286,17 +286,6 @@ function run()
}
}
// Test that differences in arc flag parameters cause the
// interpolation/addition not to occur.
addTest(1, "M100,100",
"A", [10, 20, 30, 0, 0, 40, 50],
"a", [60, 70, 80, 0, 1, 90, 100],
"a", [60, 70, 80, 0, 1, 90, 100], additive);
addTest(1, "M100,100",
"A", [10, 20, 30, 0, 0, 40, 50],
"a", [60, 70, 80, 1, 0, 90, 100],
"a", [60, 70, 80, 1, 0, 90, 100], additive);
// Test all pairs of segment types that cannot be interpolated between.
for each (let fromType in gTypes) {
let fromArguments = generatePathSegmentArguments(fromType, 0);