From fd3c4744f265c5277e6e2641a18d5ec3dff19f6b Mon Sep 17 00:00:00 2001 From: George Mount Date: Mon, 8 Sep 2014 13:23:36 -0700 Subject: Use intrinsic size for path animation in AnimatedVectorDrawable Bug 16984007 Animated Vector Drawables were using the viewport dimensions for calculating the allowable animation error. Instead of using viewport dimensions, it is better to use the intrinsic dimensions. Using the viewport dimensions meant that a small viewport (e.g. 1x1) would mean that animation paths within would only have an accuracy of 50% of the dimensions of the drawable. Change-Id: Id0152eabb4effd1e50c644eea7a371b38baeb7c1 --- .../graphics/drawable/AnimatedVectorDrawable.java | 10 +++++++--- .../android/graphics/drawable/VectorDrawable.java | 23 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) (limited to 'graphics/java') diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index ba225501284e..e5e2f1863988 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -252,6 +252,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable { throws XmlPullParserException, IOException { int eventType = parser.getEventType(); + float pathErrorScale = 1; while (eventType != XmlPullParser.END_DOCUMENT) { if (eventType == XmlPullParser.START_TAG) { final String tagName = parser.getName(); @@ -261,9 +262,11 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable { int drawableRes = a.getResourceId( R.styleable.AnimatedVectorDrawable_drawable, 0); if (drawableRes != 0) { - mAnimatedVectorState.mVectorDrawable = (VectorDrawable) res.getDrawable( + VectorDrawable vectorDrawable = (VectorDrawable) res.getDrawable( drawableRes, theme).mutate(); - mAnimatedVectorState.mVectorDrawable.setAllowCaching(false); + vectorDrawable.setAllowCaching(false); + pathErrorScale = vectorDrawable.getPixelSize(); + mAnimatedVectorState.mVectorDrawable = vectorDrawable; } a.recycle(); } else if (TARGET.equals(tagName)) { @@ -275,7 +278,8 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable { int id = a.getResourceId( R.styleable.AnimatedVectorDrawableTarget_animation, 0); if (id != 0) { - Animator objectAnimator = AnimatorInflater.loadAnimator(res, theme, id); + Animator objectAnimator = AnimatorInflater.loadAnimator(res, theme, id, + pathErrorScale); setupAnimatorsForTarget(target, objectAnimator); } a.recycle(); diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index 042da5b250d5..a07ccc42bc85 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -368,6 +368,29 @@ public class VectorDrawable extends Drawable { } } + /** + * The size of a pixel when scaled from the intrinsic dimension to the viewport dimension. + * This is used to calculate the path animation accuracy. + * + * @hide + */ + public float getPixelSize() { + if (mVectorState == null && mVectorState.mVPathRenderer == null || + mVectorState.mVPathRenderer.mBaseWidth == 0 || + mVectorState.mVPathRenderer.mBaseHeight == 0 || + mVectorState.mVPathRenderer.mViewportHeight == 0 || + mVectorState.mVPathRenderer.mViewportWidth == 0) { + return 1; // fall back to 1:1 pixel mapping. + } + float intrinsicWidth = mVectorState.mVPathRenderer.mBaseWidth; + float intrinsicHeight = mVectorState.mVPathRenderer.mBaseHeight; + float viewportWidth = mVectorState.mVPathRenderer.mViewportWidth; + float viewportHeight = mVectorState.mVPathRenderer.mViewportHeight; + float scaleX = viewportWidth / intrinsicWidth; + float scaleY = viewportHeight / intrinsicHeight; + return Math.min(scaleX, scaleY); + } + /** @hide */ public static VectorDrawable create(Resources resources, int rid) { try { -- cgit v1.2.3-59-g8ed1b