From 2e96bf74ce1f5852f25c32d728a07c2a2df94682 Mon Sep 17 00:00:00 2001 From: Robert Longson Date: Tue, 25 Oct 2011 09:18:13 +0100 Subject: [PATCH] Bug 653928 - Animation of path d attribute with elliptical arcs discrete instead of continuous when flags change. r=dholbert --- .../content/src/SVGPathSegListSMILType.cpp | 46 +++++-------------- .../test/test_pathAnimInterpolation.xhtml | 19 ++------ 2 files changed, 15 insertions(+), 50 deletions(-) diff --git a/content/svg/content/src/SVGPathSegListSMILType.cpp b/content/svg/content/src/SVGPathSegListSMILType.cpp index f7e015f27d90..d0414c7d7fde 100644 --- a/content/svg/content/src/SVGPathSegListSMILType.cpp +++ b/content/svg/content/src/SVGPathSegListSMILType.cpp @@ -95,21 +95,6 @@ SVGPathSegListSMILType::IsEqual(const nsSMILValue& aLeft, *static_cast(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; } } diff --git a/content/svg/content/test/test_pathAnimInterpolation.xhtml b/content/svg/content/test/test_pathAnimInterpolation.xhtml index 66b89f09f1c9..36f8e4de5ebc 100644 --- a/content/svg/content/test/test_pathAnimInterpolation.xhtml +++ b/content/svg/content/test/test_pathAnimInterpolation.xhtml @@ -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);