diff options
Diffstat (limited to 'graphics')
3 files changed, 124 insertions, 683 deletions
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index b050a02..e7a073c 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -1019,9 +1019,6 @@ public abstract class Drawable { drawable = new StateListDrawable(); } else if (name.equals("animated-selector")) { drawable = new AnimatedStateListDrawable(); - } else if (name.equals("material-progress")) { - // TODO: Replace this with something less ridiculous. - drawable = new MaterialProgressDrawable(); } else if (name.equals("level-list")) { drawable = new LevelListDrawable(); } else if (name.equals("layer-list")) { diff --git a/graphics/java/android/graphics/drawable/MaterialProgressDrawable.java b/graphics/java/android/graphics/drawable/MaterialProgressDrawable.java deleted file mode 100644 index c484094..0000000 --- a/graphics/java/android/graphics/drawable/MaterialProgressDrawable.java +++ /dev/null @@ -1,548 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.graphics.drawable; - -import android.animation.Animator; -import android.animation.ObjectAnimator; -import android.animation.TimeInterpolator; -import android.content.res.ColorStateList; -import android.content.res.Resources; -import android.content.res.Resources.Theme; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.ColorFilter; -import android.graphics.Paint; -import android.graphics.PorterDuffColorFilter; -import android.graphics.Paint.Cap; -import android.graphics.Paint.Style; -import android.graphics.PorterDuff.Mode; -import android.graphics.PixelFormat; -import android.graphics.Rect; -import android.graphics.RectF; -import android.util.AttributeSet; -import android.view.animation.AccelerateDecelerateInterpolator; -import android.view.animation.LinearInterpolator; - -import com.android.internal.R; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; -import java.util.ArrayList; - -/** - * Fancy progress indicator for Material theme. - * - * TODO: Replace this class with something less ridiculous. - */ -class MaterialProgressDrawable extends Drawable implements Animatable { - private static final TimeInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator(); - private static final TimeInterpolator END_CURVE_INTERPOLATOR = new EndCurveInterpolator(); - private static final TimeInterpolator START_CURVE_INTERPOLATOR = new StartCurveInterpolator(); - - /** The duration of a single progress spin in milliseconds. */ - private static final int ANIMATION_DURATION = 1000 * 80 / 60; - - /** The number of points in the progress "star". */ - private static final int NUM_POINTS = 5; - - /** The list of animators operating on this drawable. */ - private final ArrayList<Animator> mAnimators = new ArrayList<Animator>(); - - /** The indicator ring, used to manage animation state. */ - private final Ring mRing; - - private MaterialProgressState mState; - private PorterDuffColorFilter mTintFilter; - - /** Canvas rotation in degrees. */ - private float mRotation; - - private boolean mMutated; - - public MaterialProgressDrawable() { - this(new MaterialProgressState(null), null); - } - - private MaterialProgressDrawable(MaterialProgressState state, Theme theme) { - mState = state; - if (theme != null && state.canApplyTheme()) { - applyTheme(theme); - } - - mRing = new Ring(mCallback); - mMutated = false; - - initializeFromState(); - setupAnimators(); - } - - private void initializeFromState() { - final MaterialProgressState state = mState; - - final Ring ring = mRing; - ring.setStrokeWidth(state.mStrokeWidth); - - final int color = state.mColor.getColorForState(getState(), Color.TRANSPARENT); - ring.setColor(color); - - final float minEdge = Math.min(state.mWidth, state.mHeight); - if (state.mInnerRadius <= 0 || minEdge < 0) { - ring.setInsets((int) Math.ceil(state.mStrokeWidth / 2.0f)); - } else { - float insets = minEdge / 2.0f - state.mInnerRadius; - ring.setInsets(insets); - } - - mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); - } - - @Override - public Drawable mutate() { - if (!mMutated && super.mutate() == this) { - mState = new MaterialProgressState(mState); - mMutated = true; - } - return this; - } - - @Override - protected boolean onStateChange(int[] stateSet) { - boolean changed = super.onStateChange(stateSet); - - final MaterialProgressState state = mState; - final int color = state.mColor.getColorForState(stateSet, Color.TRANSPARENT); - if (color != mRing.getColor()) { - mRing.setColor(color); - changed = true; - } - - if (state.mTint != null && state.mTintMode != null) { - mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); - changed = true; - } - - return changed; - } - - @Override - public boolean isStateful() { - return super.isStateful() || mState.mColor.isStateful(); - } - - @Override - public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) - throws XmlPullParserException, IOException { - final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.MaterialProgressDrawable); - super.inflateWithAttributes(r, parser, a, R.styleable.MaterialProgressDrawable_visible); - updateStateFromTypedArray(a); - a.recycle(); - - initializeFromState(); - } - - @Override - public void applyTheme(Theme t) { - final TypedArray a = t.resolveAttributes(mState.mThemeAttrs, - R.styleable.MaterialProgressDrawable); - updateStateFromTypedArray(a); - a.recycle(); - } - - private void updateStateFromTypedArray(TypedArray a) { - final MaterialProgressState state = mState; - state.mThemeAttrs = a.extractThemeAttrs(); - state.mWidth = a.getDimensionPixelSize( - R.styleable.MaterialProgressDrawable_width, state.mWidth); - state.mHeight = a.getDimensionPixelSize( - R.styleable.MaterialProgressDrawable_height, state.mHeight); - state.mInnerRadius = a.getDimension( - R.styleable.MaterialProgressDrawable_innerRadius, state.mInnerRadius); - state.mStrokeWidth = a.getDimension( - R.styleable.MaterialProgressDrawable_thickness, state.mStrokeWidth); - - if (a.hasValue(R.styleable.MaterialProgressDrawable_color)) { - state.mColor = a.getColorStateList(R.styleable.MaterialProgressDrawable_color); - } - } - - @Override - public boolean setVisible(boolean visible, boolean restart) { - boolean changed = super.setVisible(visible, restart); - if (visible) { - if (changed || restart) { - start(); - } - } else { - stop(); - } - return changed; - } - - @Override - public int getIntrinsicHeight() { - return mState.mHeight; - } - - @Override - public int getIntrinsicWidth() { - return mState.mWidth; - } - - @Override - public void draw(Canvas c) { - final Rect bounds = getBounds(); - final int saveCount = c.save(); - c.rotate(mRotation, bounds.exactCenterX(), bounds.exactCenterY()); - mRing.draw(c, bounds); - c.restoreToCount(saveCount); - } - - @Override - public void setAlpha(int alpha) { - mRing.setAlpha(alpha); - } - - @Override - public int getAlpha() { - return mRing.getAlpha(); - } - - @Override - public void setColorFilter(ColorFilter colorFilter) { - mRing.setColorFilter(colorFilter); - } - - @Override - public ColorFilter getColorFilter() { - return mRing.getColorFilter(); - } - - @Override - public void setTint(ColorStateList tint, Mode tintMode) { - if (mState.mTint != tint || mState.mTintMode != tintMode) { - mState.mTint = tint; - mState.mTintMode = tintMode; - - mTintFilter = updateTintFilter(mTintFilter, tint, tintMode); - invalidateSelf(); - } - } - - @SuppressWarnings("unused") - private void setRotation(float rotation) { - mRotation = rotation; - invalidateSelf(); - } - - @SuppressWarnings("unused") - private float getRotation() { - return mRotation; - } - - @Override - public int getOpacity() { - return PixelFormat.TRANSLUCENT; - } - - @Override - public boolean isRunning() { - final ArrayList<Animator> animators = mAnimators; - final int N = animators.size(); - for (int i = 0; i < N; i++) { - final Animator animator = animators.get(i); - if (animator.isRunning()) { - return true; - } - } - return false; - } - - @Override - public void start() { - final ArrayList<Animator> animators = mAnimators; - final int N = animators.size(); - for (int i = 0; i < N; i++) { - final Animator animator = animators.get(i); - if (animator.isPaused()) { - animator.resume(); - } else if (!animator.isRunning()){ - animator.start(); - } - } - } - - @Override - public void stop() { - final ArrayList<Animator> animators = mAnimators; - final int N = animators.size(); - for (int i = 0; i < N; i++) { - final Animator animator = animators.get(i); - animator.pause(); - } - } - - private void setupAnimators() { - final Ring ring = mRing; - - final ObjectAnimator endTrim = ObjectAnimator.ofFloat(ring, "endTrim", 0, 0.75f); - endTrim.setDuration(ANIMATION_DURATION); - endTrim.setInterpolator(START_CURVE_INTERPOLATOR); - endTrim.setRepeatCount(ObjectAnimator.INFINITE); - endTrim.setRepeatMode(ObjectAnimator.RESTART); - - final ObjectAnimator startTrim = ObjectAnimator.ofFloat(ring, "startTrim", 0.0f, 0.75f); - startTrim.setDuration(ANIMATION_DURATION); - startTrim.setInterpolator(END_CURVE_INTERPOLATOR); - startTrim.setRepeatCount(ObjectAnimator.INFINITE); - startTrim.setRepeatMode(ObjectAnimator.RESTART); - - final ObjectAnimator rotation = ObjectAnimator.ofFloat(ring, "rotation", 0.0f, 0.25f); - rotation.setDuration(ANIMATION_DURATION); - rotation.setInterpolator(LINEAR_INTERPOLATOR); - rotation.setRepeatCount(ObjectAnimator.INFINITE); - rotation.setRepeatMode(ObjectAnimator.RESTART); - - final ObjectAnimator groupRotation = ObjectAnimator.ofFloat(this, "rotation", 0.0f, 360.0f); - groupRotation.setDuration(NUM_POINTS * ANIMATION_DURATION); - groupRotation.setInterpolator(LINEAR_INTERPOLATOR); - groupRotation.setRepeatCount(ObjectAnimator.INFINITE); - groupRotation.setRepeatMode(ObjectAnimator.RESTART); - - mAnimators.add(endTrim); - mAnimators.add(startTrim); - mAnimators.add(rotation); - mAnimators.add(groupRotation); - } - - private final Callback mCallback = new Callback() { - @Override - public void invalidateDrawable(Drawable d) { - invalidateSelf(); - } - - @Override - public void scheduleDrawable(Drawable d, Runnable what, long when) { - scheduleSelf(what, when); - } - - @Override - public void unscheduleDrawable(Drawable d, Runnable what) { - unscheduleSelf(what); - } - }; - - private static class MaterialProgressState extends ConstantState { - private int[] mThemeAttrs = null; - private float mStrokeWidth = 5.0f; - private float mInnerRadius = -1.0f; - private int mWidth = -1; - private int mHeight = -1; - private ColorStateList mColor = ColorStateList.valueOf(Color.TRANSPARENT); - private ColorStateList mTint = null; - private Mode mTintMode = null; - - public MaterialProgressState(MaterialProgressState orig) { - if (orig != null) { - mThemeAttrs = orig.mThemeAttrs; - mStrokeWidth = orig.mStrokeWidth; - mInnerRadius = orig.mInnerRadius; - mWidth = orig.mWidth; - mHeight = orig.mHeight; - mColor = orig.mColor; - mTint = orig.mTint; - mTintMode = orig.mTintMode; - } - } - - @Override - public boolean canApplyTheme() { - return mThemeAttrs != null; - } - - @Override - public Drawable newDrawable() { - return newDrawable(null, null); - } - - @Override - public Drawable newDrawable(Resources res) { - return newDrawable(res, null); - } - - @Override - public Drawable newDrawable(Resources res, Theme theme) { - return new MaterialProgressDrawable(this, theme); - } - - @Override - public int getChangingConfigurations() { - return 0; - } - } - - private static class Ring { - private final RectF mTempBounds = new RectF(); - private final Paint mPaint = new Paint(); - - private final Callback mCallback; - - private float mStartTrim = 0.0f; - private float mEndTrim = 0.0f; - private float mRotation = 0.0f; - private float mStrokeWidth = 5.0f; - private float mStrokeInset = 2.5f; - - private int mAlpha = 0xFF; - private int mColor = Color.BLACK; - - public Ring(Callback callback) { - mCallback = callback; - - mPaint.setStrokeCap(Cap.ROUND); - mPaint.setAntiAlias(true); - mPaint.setStyle(Style.STROKE); - } - - public void draw(Canvas c, Rect bounds) { - final RectF arcBounds = mTempBounds; - arcBounds.set(bounds); - arcBounds.inset(mStrokeInset, mStrokeInset); - - final float startAngle = (mStartTrim + mRotation) * 360; - final float endAngle = (mEndTrim + mRotation) * 360; - float sweepAngle = endAngle - startAngle; - - // Ensure the sweep angle isn't too small to draw. - final float diameter = Math.min(arcBounds.width(), arcBounds.height()); - final float minAngle = (float) (360.0 / (diameter * Math.PI)); - if (sweepAngle < minAngle && sweepAngle > -minAngle) { - sweepAngle = Math.signum(sweepAngle) * minAngle; - } - - c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint); - } - - public void setColorFilter(ColorFilter filter) { - mPaint.setColorFilter(filter); - invalidateSelf(); - } - - public ColorFilter getColorFilter() { - return mPaint.getColorFilter(); - } - - public void setAlpha(int alpha) { - mAlpha = alpha; - mPaint.setColor(mColor & 0xFFFFFF | alpha << 24); - invalidateSelf(); - } - - public int getAlpha() { - return mAlpha; - } - - public void setColor(int color) { - mColor = color; - mPaint.setColor(color & 0xFFFFFF | mAlpha << 24); - invalidateSelf(); - } - - public int getColor() { - return mColor; - } - - public void setStrokeWidth(float strokeWidth) { - mStrokeWidth = strokeWidth; - mPaint.setStrokeWidth(strokeWidth); - invalidateSelf(); - } - - @SuppressWarnings("unused") - public float getStrokeWidth() { - return mStrokeWidth; - } - - @SuppressWarnings("unused") - public void setStartTrim(float startTrim) { - mStartTrim = startTrim; - invalidateSelf(); - } - - @SuppressWarnings("unused") - public float getStartTrim() { - return mStartTrim; - } - - @SuppressWarnings("unused") - public void setEndTrim(float endTrim) { - mEndTrim = endTrim; - invalidateSelf(); - } - - @SuppressWarnings("unused") - public float getEndTrim() { - return mEndTrim; - } - - @SuppressWarnings("unused") - public void setRotation(float rotation) { - mRotation = rotation; - invalidateSelf(); - } - - @SuppressWarnings("unused") - public float getRotation() { - return mRotation; - } - - public void setInsets(float insets) { - mStrokeInset = insets; - } - - @SuppressWarnings("unused") - public float getInsets() { - return mStrokeInset; - } - - private void invalidateSelf() { - mCallback.invalidateDrawable(null); - } - } - - /** - * Squishes the interpolation curve into the second half of the animation. - */ - private static class EndCurveInterpolator extends AccelerateDecelerateInterpolator { - @Override - public float getInterpolation(float input) { - return super.getInterpolation(Math.max(0, (input - 0.5f) * 2.0f)); - } - } - - /** - * Squishes the interpolation curve into the first half of the animation. - */ - private static class StartCurveInterpolator extends AccelerateDecelerateInterpolator { - @Override - public float getInterpolation(float input) { - return super.getInterpolation(Math.min(1, input * 2.0f)); - } - } -} diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index 4ea0046..8783994 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -299,11 +299,10 @@ public class VectorDrawable extends Drawable { return color; } - @Override public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme) throws XmlPullParserException, IOException { - final TypedArray a = obtainAttributes(res, theme, attrs,R.styleable.VectorDrawable); + final TypedArray a = obtainAttributes(res, theme, attrs, R.styleable.VectorDrawable); updateStateFromTypedArray(a); a.recycle(); @@ -358,7 +357,7 @@ public class VectorDrawable extends Drawable { if (SHAPE_PATH.equals(tagName)) { final VPath path = new VPath(); path.inflate(res, attrs, theme); - currentGroup.add(path); + currentGroup.mChildren.add(path); if (path.getPathName() != null) { pathRenderer.mVGTargetsMap.put(path.getPathName(), path); } @@ -375,7 +374,7 @@ public class VectorDrawable extends Drawable { } else if (SHAPE_GROUP.equals(tagName)) { VGroup newChildGroup = new VGroup(); newChildGroup.inflate(res, attrs, theme); - currentGroup.mChildGroupList.add(newChildGroup); + currentGroup.mChildren.add(newChildGroup); groupStack.push(newChildGroup); if (newChildGroup.getGroupName() != null) { pathRenderer.mVGTargetsMap.put(newChildGroup.getGroupName(), @@ -424,16 +423,19 @@ public class VectorDrawable extends Drawable { private void printGroupTree(VGroup currentGroup, int level) { String indent = ""; - for (int i = 0 ; i < level ; i++) { + for (int i = 0; i < level; i++) { indent += " "; } // Print the current node - Log.v(LOGTAG, indent + "current group is :" + currentGroup.getGroupName() + Log.v(LOGTAG, indent + "current group is :" + currentGroup.getGroupName() + " rotation is " + currentGroup.mRotate); - Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString()); - // Then print all the children - for (int i = 0 ; i < currentGroup.mChildGroupList.size(); i++) { - printGroupTree(currentGroup.mChildGroupList.get(i), level + 1); + Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString()); + // Then print all the children groups + for (int i = 0; i < currentGroup.mChildren.size(); i++) { + Object child = currentGroup.mChildren.get(i); + if (child instanceof VGroup) { + printGroupTree((VGroup) child, level + 1); + } } } @@ -552,21 +554,21 @@ public class VectorDrawable extends Drawable { private boolean recursiveCanApplyTheme(VGroup currentGroup) { // We can do a tree traverse here, if there is one path return true, // then we return true for the whole tree. - final ArrayList<VPath> paths = currentGroup.mPathList; - for (int j = paths.size() - 1; j >= 0; j--) { - final VPath path = paths.get(j); - if (path.canApplyTheme()) { - return true; - } - } - - final ArrayList<VGroup> childGroups = currentGroup.mChildGroupList; - - for (int i = 0; i < childGroups.size(); i++) { - VGroup childGroup = childGroups.get(i); - if (childGroup.canApplyTheme() - || recursiveCanApplyTheme(childGroup)) { - return true; + final ArrayList<Object> children = currentGroup.mChildren; + + for (int i = 0; i < children.size(); i++) { + Object child = children.get(i); + if (child instanceof VGroup) { + VGroup childGroup = (VGroup) child; + if (childGroup.canApplyTheme() + || recursiveCanApplyTheme(childGroup)) { + return true; + } + } else if (child instanceof VPath) { + VPath childPath = (VPath) child; + if (childPath.canApplyTheme()) { + return true; + } } } return false; @@ -580,24 +582,22 @@ public class VectorDrawable extends Drawable { private void recursiveApplyTheme(VGroup currentGroup, Theme t) { // We can do a tree traverse here, apply theme to all paths which // can apply theme. - final ArrayList<VPath> paths = currentGroup.mPathList; - for (int j = paths.size() - 1; j >= 0; j--) { - final VPath path = paths.get(j); - if (path.canApplyTheme()) { - path.applyTheme(t); - } - } - - final ArrayList<VGroup> childGroups = currentGroup.mChildGroupList; - - for (int i = 0; i < childGroups.size(); i++) { - VGroup childGroup = childGroups.get(i); - if (childGroup.canApplyTheme()) { - childGroup.applyTheme(t); + final ArrayList<Object> children = currentGroup.mChildren; + for (int i = 0; i < children.size(); i++) { + Object child = children.get(i); + if (child instanceof VGroup) { + VGroup childGroup = (VGroup) child; + if (childGroup.canApplyTheme()) { + childGroup.applyTheme(t); + } + recursiveApplyTheme(childGroup, t); + } else if (child instanceof VPath) { + VPath childPath = (VPath) child; + if (childPath.canApplyTheme()) { + childPath.applyTheme(t); + } } - recursiveApplyTheme(childGroup, t); } - } public void setColorFilter(ColorFilter colorFilter) { @@ -624,11 +624,18 @@ public class VectorDrawable extends Drawable { currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix); float stackedAlpha = currentAlpha * currentGroup.mGroupAlpha; - drawPath(currentGroup, stackedAlpha, canvas, w, h); - // Draw the group tree in post order. - for (int i = 0 ; i < currentGroup.mChildGroupList.size(); i++) { - drawGroupTree(currentGroup.mChildGroupList.get(i), - currentGroup.mStackedMatrix, stackedAlpha, canvas, w, h); + + // Draw the group tree in the same order as the XML file. + for (int i = 0; i < currentGroup.mChildren.size(); i++) { + Object child = currentGroup.mChildren.get(i); + if (child instanceof VGroup) { + VGroup childGroup = (VGroup) child; + drawGroupTree(childGroup, currentGroup.mStackedMatrix, + stackedAlpha, canvas, w, h); + } else if (child instanceof VPath) { + VPath childPath = (VPath) child; + drawPath(currentGroup, childPath, stackedAlpha, canvas, w, h); + } } } @@ -637,7 +644,8 @@ public class VectorDrawable extends Drawable { drawGroupTree(mRootGroup, IDENTITY_MATRIX, ((float) mRootAlpha) / 0xFF, canvas, w, h); } - private void drawPath(VGroup vGroup, float stackedAlpha, Canvas canvas, int w, int h) { + private void drawPath(VGroup vGroup, VPath vPath, float stackedAlpha, + Canvas canvas, int w, int h) { final float scale = Math.min(h / mViewportHeight, w / mViewportWidth); mFinalPathMatrix.set(vGroup.mStackedMatrix); @@ -645,75 +653,71 @@ public class VectorDrawable extends Drawable { mFinalPathMatrix.postTranslate( w / 2f - mViewportWidth / 2f, h / 2f - mViewportHeight / 2f); - ArrayList<VPath> paths = vGroup.getPaths(); - for (int i = 0; i < paths.size(); i++) { - VPath vPath = paths.get(i); - vPath.toPath(mPath); - final Path path = mPath; + vPath.toPath(mPath); + final Path path = mPath; - if (vPath.mTrimPathStart != 0.0f || vPath.mTrimPathEnd != 1.0f) { - float start = (vPath.mTrimPathStart + vPath.mTrimPathOffset) % 1.0f; - float end = (vPath.mTrimPathEnd + vPath.mTrimPathOffset) % 1.0f; + if (vPath.mTrimPathStart != 0.0f || vPath.mTrimPathEnd != 1.0f) { + float start = (vPath.mTrimPathStart + vPath.mTrimPathOffset) % 1.0f; + float end = (vPath.mTrimPathEnd + vPath.mTrimPathOffset) % 1.0f; - if (mPathMeasure == null) { - mPathMeasure = new PathMeasure(); - } - mPathMeasure.setPath(mPath, false); - - float len = mPathMeasure.getLength(); - start = start * len; - end = end * len; - path.reset(); - if (start > end) { - mPathMeasure.getSegment(start, len, path, true); - mPathMeasure.getSegment(0f, end, path, true); - } else { - mPathMeasure.getSegment(start, end, path, true); - } - path.rLineTo(0, 0); // fix bug in measure + if (mPathMeasure == null) { + mPathMeasure = new PathMeasure(); } + mPathMeasure.setPath(mPath, false); + + float len = mPathMeasure.getLength(); + start = start * len; + end = end * len; + path.reset(); + if (start > end) { + mPathMeasure.getSegment(start, len, path, true); + mPathMeasure.getSegment(0f, end, path, true); + } else { + mPathMeasure.getSegment(start, end, path, true); + } + path.rLineTo(0, 0); // fix bug in measure + } - mRenderPath.reset(); + mRenderPath.reset(); - mRenderPath.addPath(path, mFinalPathMatrix); + mRenderPath.addPath(path, mFinalPathMatrix); - if (vPath.mClip) { - canvas.clipPath(mRenderPath, Region.Op.REPLACE); - } else { - if (vPath.mFillColor != 0) { - if (mFillPaint == null) { - mFillPaint = new Paint(); - mFillPaint.setColorFilter(mColorFilter); - mFillPaint.setStyle(Paint.Style.FILL); - mFillPaint.setAntiAlias(true); - } - mFillPaint.setColor(applyAlpha(vPath.mFillColor, stackedAlpha)); - canvas.drawPath(mRenderPath, mFillPaint); + if (vPath.mClip) { + canvas.clipPath(mRenderPath, Region.Op.REPLACE); + } else { + if (vPath.mFillColor != 0) { + if (mFillPaint == null) { + mFillPaint = new Paint(); + mFillPaint.setColorFilter(mColorFilter); + mFillPaint.setStyle(Paint.Style.FILL); + mFillPaint.setAntiAlias(true); } + mFillPaint.setColor(applyAlpha(vPath.mFillColor, stackedAlpha)); + canvas.drawPath(mRenderPath, mFillPaint); + } - if (vPath.mStrokeColor != 0) { - if (mStrokePaint == null) { - mStrokePaint = new Paint(); - mStrokePaint.setColorFilter(mColorFilter); - mStrokePaint.setStyle(Paint.Style.STROKE); - mStrokePaint.setAntiAlias(true); - } + if (vPath.mStrokeColor != 0) { + if (mStrokePaint == null) { + mStrokePaint = new Paint(); + mStrokePaint.setColorFilter(mColorFilter); + mStrokePaint.setStyle(Paint.Style.STROKE); + mStrokePaint.setAntiAlias(true); + } - final Paint strokePaint = mStrokePaint; - if (vPath.mStrokeLineJoin != null) { - strokePaint.setStrokeJoin(vPath.mStrokeLineJoin); - } + final Paint strokePaint = mStrokePaint; + if (vPath.mStrokeLineJoin != null) { + strokePaint.setStrokeJoin(vPath.mStrokeLineJoin); + } - if (vPath.mStrokeLineCap != null) { - strokePaint.setStrokeCap(vPath.mStrokeLineCap); - } + if (vPath.mStrokeLineCap != null) { + strokePaint.setStrokeCap(vPath.mStrokeLineCap); + } - strokePaint.setStrokeMiter(vPath.mStrokeMiterlimit * scale); + strokePaint.setStrokeMiter(vPath.mStrokeMiterlimit * scale); - strokePaint.setColor(applyAlpha(vPath.mStrokeColor, stackedAlpha)); - strokePaint.setStrokeWidth(vPath.mStrokeWidth * scale); - canvas.drawPath(mRenderPath, strokePaint); - } + strokePaint.setColor(applyAlpha(vPath.mStrokeColor, stackedAlpha)); + strokePaint.setStrokeWidth(vPath.mStrokeWidth * scale); + canvas.drawPath(mRenderPath, strokePaint); } } } @@ -742,7 +746,7 @@ public class VectorDrawable extends Drawable { } private void parseSize(Resources r, AttributeSet attrs) - throws XmlPullParserException { + throws XmlPullParserException { final TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableSize); // Account for any configuration changes. @@ -771,8 +775,7 @@ public class VectorDrawable extends Drawable { ///////////////////////////////////////////////////// // Variables below need to be copied (deep copy if applicable) for mutation. - private final ArrayList<VPath> mPathList = new ArrayList<VPath>(); - private final ArrayList<VGroup> mChildGroupList = new ArrayList<VGroup>(); + final ArrayList<Object> mChildren = new ArrayList<Object>(); private float mRotate = 0; private float mPivotX = 0; @@ -808,19 +811,21 @@ public class VectorDrawable extends Drawable { mLocalMatrix.set(copy.mLocalMatrix); - for (int i = 0; i < copy.mPathList.size(); i ++) { - VPath copyPath = copy.mPathList.get(i); - VPath newPath = new VPath(copyPath); - mPathList.add(newPath); - if (newPath.mPathName != null) { - targetsMap.put(copyPath.mPathName, newPath); + final ArrayList<Object> children = copy.mChildren; + for (int i = 0; i < children.size(); i++) { + Object copyChild = children.get(i); + if (copyChild instanceof VGroup) { + VGroup copyGroup = (VGroup) copyChild; + mChildren.add(new VGroup(copyGroup, targetsMap)); + } else if (copyChild instanceof VPath) { + VPath copyPath = (VPath) copyChild; + VPath newPath = new VPath(copyPath); + mChildren.add(newPath); + if (newPath.mPathName != null) { + targetsMap.put(newPath.mPathName, newPath); + } } } - - for (int i = 0; i < copy.mChildGroupList.size(); i ++) { - VGroup currentGroup = copy.mChildGroupList.get(i); - mChildGroupList.add(new VGroup(currentGroup, targetsMap)); - } } public VGroup() { @@ -922,10 +927,6 @@ public class VectorDrawable extends Drawable { return mLocalMatrix; } - public void add(VPath path) { - mPathList.add(path); - } - public boolean canApplyTheme() { return mThemeAttrs != null; } @@ -980,15 +981,6 @@ public class VectorDrawable extends Drawable { mLocalMatrix.postRotate(mRotate, 0, 0); mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY); } - - /** - * Must return in order of adding - * @return ordered list of paths - */ - public ArrayList<VPath> getPaths() { - return mPathList; - } - } private static class VPath { @@ -1012,7 +1004,7 @@ public class VectorDrawable extends Drawable { float mStrokeMiterlimit = 4; private PathParser.PathDataNode[] mNodes = null; - private String mPathName; + String mPathName; private int mChangingConfigurations; public VPath() { |