VectorDrawableCompat.java revision c39d9c75590eca86a5e7e32a8824ba04a0d42e9b
14fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui/* 24fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * Copyright (C) 2015 The Android Open Source Project 34fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * 44fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 54fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * in compliance with the License. You may obtain a copy of the License at 64fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * 74fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * http://www.apache.org/licenses/LICENSE-2.0 84fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * 94fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * Unless required by applicable law or agreed to in writing, software distributed under the License 104fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 114fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * or implied. See the License for the specific language governing permissions and limitations under 124fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * the License. 134fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui */ 144fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 154fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuipackage android.support.graphics.drawable; 164fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 17c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viveretteimport android.support.annotation.RestrictTo; 18ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhuimport android.support.v4.content.res.ResourcesCompat; 19ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhuimport android.support.v4.graphics.drawable.DrawableCompat; 20e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banesimport org.xmlpull.v1.XmlPullParser; 21e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banesimport org.xmlpull.v1.XmlPullParserException; 22e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banes 239f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhuimport android.annotation.TargetApi; 244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.content.res.ColorStateList; 254fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.content.res.Resources; 264fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.content.res.Resources.Theme; 274fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.content.res.TypedArray; 284fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.Bitmap; 294fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.Canvas; 304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.Color; 314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.ColorFilter; 324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.Matrix; 334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.Paint; 344fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.Path; 354fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.PathMeasure; 364fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.PixelFormat; 374fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.PorterDuff; 384fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.PorterDuff.Mode; 394fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.PorterDuffColorFilter; 404fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.Rect; 414fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.Region; 424fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.graphics.drawable.Drawable; 439f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhuimport android.graphics.drawable.VectorDrawable; 449f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhuimport android.os.Build; 45968dcfaff0c0a9e85ff4db2a985188f6996f5dadTeng-Hui Zhuimport android.support.annotation.DrawableRes; 464fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.support.annotation.NonNull; 474fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.support.annotation.Nullable; 484fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.support.v4.util.ArrayMap; 494fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.util.AttributeSet; 504fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.util.Log; 514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport android.util.Xml; 524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 534fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport java.io.IOException; 544fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport java.util.ArrayList; 554fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghuiimport java.util.Stack; 564fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 57c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viveretteimport static android.support.annotation.RestrictTo.Scope.GROUP_ID; 58c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viverette 594fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui/** 60c59ac731f7d38ee41d0aba567a9d3b77b40df628Teng-Hui Zhu * For API 24 and above, this class is delegating to the framework's {@link VectorDrawable}. 61ab9d2bf6fe28ff4a95985526daa128239c03d821Teng-Hui Zhu * For older API version, this class lets you create a drawable based on an XML vector graphic. 627c839dcff721b584defb5bedb18c05fae5b99d24Teng-Hui Zhu * <p> 637c839dcff721b584defb5bedb18c05fae5b99d24Teng-Hui Zhu * VectorDrawableCompat are defined in the same XML format as {@link VectorDrawable}. 647c839dcff721b584defb5bedb18c05fae5b99d24Teng-Hui Zhu * </p> 657c839dcff721b584defb5bedb18c05fae5b99d24Teng-Hui Zhu * You can always create a VectorDrawableCompat object and use it as a Drawable by the Java API. 667c839dcff721b584defb5bedb18c05fae5b99d24Teng-Hui Zhu * In order to refer to VectorDrawableCompat inside a XML file, you can use app:srcCompat attribute 677c839dcff721b584defb5bedb18c05fae5b99d24Teng-Hui Zhu * in AppCompat library's ImageButton or ImageView. 684fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui */ 699f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu@TargetApi(Build.VERSION_CODES.LOLLIPOP) 70968dcfaff0c0a9e85ff4db2a985188f6996f5dadTeng-Hui Zhupublic class VectorDrawableCompat extends VectorDrawableCommon { 714fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui static final String LOGTAG = "VectorDrawableCompat"; 724fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 734fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui static final PorterDuff.Mode DEFAULT_TINT_MODE = PorterDuff.Mode.SRC_IN; 744fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 754fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static final String SHAPE_CLIP_PATH = "clip-path"; 764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static final String SHAPE_GROUP = "group"; 774fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static final String SHAPE_PATH = "path"; 784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static final String SHAPE_VECTOR = "vector"; 794fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 804fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static final int LINECAP_BUTT = 0; 814fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static final int LINECAP_ROUND = 1; 824fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static final int LINECAP_SQUARE = 2; 834fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 844fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static final int LINEJOIN_MITER = 0; 854fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static final int LINEJOIN_ROUND = 1; 864fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static final int LINEJOIN_BEVEL = 2; 874fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 881f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // Cap the bitmap size, such that it won't hurt the performance too much 891f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // and it won't crash due to a very large scale. 901f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // The drawable will look blurry above this size. 911f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu private static final int MAX_CACHED_BITMAP_SIZE = 2048; 921f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu 93d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu private static final boolean DBG_VECTOR_DRAWABLE = false; 944fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 959f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu private VectorDrawableCompatState mVectorState; 964fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private PorterDuffColorFilter mTintFilter; 984fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private ColorFilter mColorFilter; 994fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1004fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private boolean mMutated; 1014fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1024fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // AnimatedVectorDrawable needs to turn off the cache all the time, otherwise, 1034fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // caching the bitmap by default is allowed. 1044fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private boolean mAllowCaching = true; 1054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1069f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu // The Constant state associated with the <code>mDelegateDrawable</code>. 1079f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu private ConstantState mCachedConstantStateDelegate; 1089f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 1091f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // Temp variable, only for saving "new" operation at the draw() time. 1101f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu private final float[] mTmpFloats = new float[9]; 1111f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu private final Matrix mTmpMatrix = new Matrix(); 1121f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu private final Rect mTmpBounds = new Rect(); 1131f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu 1148fbfb9b792b2978ba33bead0120a83b7af47a5f7Aurimas Liutikas VectorDrawableCompat() { 1159f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mVectorState = new VectorDrawableCompatState(); 1164fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 1174fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1188fbfb9b792b2978ba33bead0120a83b7af47a5f7Aurimas Liutikas VectorDrawableCompat(@NonNull VectorDrawableCompatState state) { 1194fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVectorState = state; 1204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 1214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 1224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1234fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 1244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public Drawable mutate() { 1259f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 1269f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mDelegateDrawable.mutate(); 1279f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return this; 1289f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 1299f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 1304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (!mMutated && super.mutate() == this) { 1319f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mVectorState = new VectorDrawableCompatState(mVectorState); 1324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mMutated = true; 1334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 1344fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return this; 1354fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 1364fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1374fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Object getTargetByName(String name) { 1384fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mVectorState.mVPathRenderer.mVGTargetsMap.get(name); 1394fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 1404fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1414fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 1424fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public ConstantState getConstantState() { 1439f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 1442c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu // Such that the configuration can be refreshed. 1452c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu return new VectorDrawableDelegateState(mDelegateDrawable.getConstantState()); 1469f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 1474fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVectorState.mChangingConfigurations = getChangingConfigurations(); 1484fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mVectorState; 1494fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 1504fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 1524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void draw(Canvas canvas) { 1539f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 1549f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mDelegateDrawable.draw(canvas); 1559f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 1569f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 1571f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // We will offset the bounds for drawBitmap, so copyBounds() here instead 1581f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // of getBounds(). 1591f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu copyBounds(mTmpBounds); 1601f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu if (mTmpBounds.width() <= 0 || mTmpBounds.height() <= 0) { 1611f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // Nothing to draw 1621f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu return; 1631f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu } 1649f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 1651f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // Color filters always override tint filters. 1661f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu final ColorFilter colorFilter = (mColorFilter == null ? mTintFilter : mColorFilter); 1671f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu 1681f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // The imageView can scale the canvas in different ways, in order to 1691f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // avoid blurry scaling, we have to draw into a bitmap with exact pixel 1701f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // size first. This bitmap size is determined by the bounds and the 1711f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // canvas scale. 1721f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu canvas.getMatrix(mTmpMatrix); 1731f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu mTmpMatrix.getValues(mTmpFloats); 1741f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu float canvasScaleX = Math.abs(mTmpFloats[Matrix.MSCALE_X]); 1751f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu float canvasScaleY = Math.abs(mTmpFloats[Matrix.MSCALE_Y]); 1761f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu 1771f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu float canvasSkewX = Math.abs(mTmpFloats[Matrix.MSKEW_X]); 1781f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu float canvasSkewY = Math.abs(mTmpFloats[Matrix.MSKEW_Y]); 1791f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu 1801f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // When there is any rotation / skew, then the scale value is not valid. 1811f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu if (canvasSkewX != 0 || canvasSkewY != 0) { 1821f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu canvasScaleX = 1.0f; 1831f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu canvasScaleY = 1.0f; 1841f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu } 1851f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu 1861f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu int scaledWidth = (int) (mTmpBounds.width() * canvasScaleX); 1871f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu int scaledHeight = (int) (mTmpBounds.height() * canvasScaleY); 1881f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu scaledWidth = Math.min(MAX_CACHED_BITMAP_SIZE, scaledWidth); 1891f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu scaledHeight = Math.min(MAX_CACHED_BITMAP_SIZE, scaledHeight); 1901f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu 1911f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu if (scaledWidth <= 0 || scaledHeight <= 0) { 1924fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return; 1934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 1944fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final int saveCount = canvas.save(); 1961f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu canvas.translate(mTmpBounds.left, mTmpBounds.top); 1974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1981f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // Handle RTL mirroring. 1991f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu final boolean needMirroring = needMirroring(); 2004fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (needMirroring) { 2011f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu canvas.translate(mTmpBounds.width(), 0); 2024fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui canvas.scale(-1.0f, 1.0f); 2034fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2044fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 2051f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // At this point, canvas has been translated to the right position. 2061f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // And we use this bound for the destination rect for the drawBitmap, so 2071f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu // we offset to (0, 0); 2081f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu mTmpBounds.offsetTo(0, 0); 2094fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 2101f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu mVectorState.createCachedBitmapIfNeeded(scaledWidth, scaledHeight); 2114fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (!mAllowCaching) { 2121f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu mVectorState.updateCachedBitmap(scaledWidth, scaledHeight); 2134fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } else { 2144fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (!mVectorState.canReuseCache()) { 2151f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu mVectorState.updateCachedBitmap(scaledWidth, scaledHeight); 2164fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVectorState.updateCacheStates(); 2174fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2184fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2191f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu mVectorState.drawCachedBitmapWithRootAlpha(canvas, colorFilter, mTmpBounds); 2204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui canvas.restoreToCount(saveCount); 2214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 22315375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 2244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public int getAlpha() { 2259f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 226ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu return DrawableCompat.getAlpha(mDelegateDrawable); 2279f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 2289f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 2294fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mVectorState.mVPathRenderer.getRootAlpha(); 2304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 2324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 2334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setAlpha(int alpha) { 2349f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 2359f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mDelegateDrawable.setAlpha(alpha); 2369f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 2379f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 2389f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 2394fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (mVectorState.mVPathRenderer.getRootAlpha() != alpha) { 2404fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVectorState.mVPathRenderer.setRootAlpha(alpha); 2414fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui invalidateSelf(); 2424fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2434fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2444fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 2454fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 2464fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setColorFilter(ColorFilter colorFilter) { 2479f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 2489f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mDelegateDrawable.setColorFilter(colorFilter); 2499f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 2509f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 2519f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 2524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mColorFilter = colorFilter; 2534fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui invalidateSelf(); 2544fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2554fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 2564fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui /** 2574fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * Ensures the tint filter is consistent with the current tint color and 2584fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * mode. 2594fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui */ 2604fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui PorterDuffColorFilter updateTintFilter(PorterDuffColorFilter tintFilter, ColorStateList tint, 2612c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu PorterDuff.Mode tintMode) { 2624fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (tint == null || tintMode == null) { 2634fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return null; 2644fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2654fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // setMode, setColor of PorterDuffColorFilter are not public method in SDK v7. 2664fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Therefore we create a new one all the time here. Don't expect this is called often. 2674fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final int color = tint.getColorForState(getState(), Color.TRANSPARENT); 2684fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return new PorterDuffColorFilter(color, tintMode); 2694fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2704fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 27115375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 2724fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setTint(int tint) { 2739f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 274ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu DrawableCompat.setTint(mDelegateDrawable, tint); 2759f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 2769f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 2779f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 2784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui setTintList(ColorStateList.valueOf(tint)); 2794fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2804fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 28115375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 2824fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setTintList(ColorStateList tint) { 2839f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 284ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu DrawableCompat.setTintList(mDelegateDrawable, tint); 2859f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 2869f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 2879f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 2889f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu final VectorDrawableCompatState state = mVectorState; 2894fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (state.mTint != tint) { 2904fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui state.mTint = tint; 2914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTintFilter = updateTintFilter(mTintFilter, tint, state.mTintMode); 2924fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui invalidateSelf(); 2934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2944fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 2954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 29615375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 2974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setTintMode(Mode tintMode) { 2989f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 299ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu DrawableCompat.setTintMode(mDelegateDrawable, tintMode); 3009f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 3019f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 3029f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 3039f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu final VectorDrawableCompatState state = mVectorState; 3044fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (state.mTintMode != tintMode) { 3054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui state.mTintMode = tintMode; 3064fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTintFilter = updateTintFilter(mTintFilter, state.mTint, tintMode); 3074fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui invalidateSelf(); 3084fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3094fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3104fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 3114fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 3124fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public boolean isStateful() { 3139f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 3149f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateDrawable.isStateful(); 3159f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 3169f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 3174fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return super.isStateful() || (mVectorState != null && mVectorState.mTint != null 3184fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui && mVectorState.mTint.isStateful()); 3194fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 3214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 3224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui protected boolean onStateChange(int[] stateSet) { 3239f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 3249f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateDrawable.setState(stateSet); 3259f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 3269f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 3279f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu final VectorDrawableCompatState state = mVectorState; 3284fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (state.mTint != null && state.mTintMode != null) { 3299f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 3304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui invalidateSelf(); 3314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return true; 3324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return false; 3344fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3354fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 3364fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 3374fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public int getOpacity() { 3389f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 3399f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateDrawable.getOpacity(); 3409f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 3419f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 3424fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return PixelFormat.TRANSLUCENT; 3434fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3444fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 3454fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 3464fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public int getIntrinsicWidth() { 3479f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 3489f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateDrawable.getIntrinsicWidth(); 3499f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 3509f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 3514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return (int) mVectorState.mVPathRenderer.mBaseWidth; 3524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3534fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 3544fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 3554fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public int getIntrinsicHeight() { 3569f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 3579f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateDrawable.getIntrinsicHeight(); 3589f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 3599f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 3604fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return (int) mVectorState.mVPathRenderer.mBaseHeight; 3614fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3624fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 3634fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Don't support re-applying themes. The initial theme loading is working. 36415375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 3654fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public boolean canApplyTheme() { 3669f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 367ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu DrawableCompat.canApplyTheme(mDelegateDrawable); 3689f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 3699f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 3704fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return false; 3714fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3724fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 3734fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui /** 3744fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * The size of a pixel when scaled from the intrinsic dimension to the viewport dimension. This 3754fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * is used to calculate the path animation accuracy. 3764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * 3774fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * @hide 3784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui */ 379c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viverette @RestrictTo(GROUP_ID) 3804fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public float getPixelSize() { 3814fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (mVectorState == null && mVectorState.mVPathRenderer == null || 3824fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVectorState.mVPathRenderer.mBaseWidth == 0 || 3834fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVectorState.mVPathRenderer.mBaseHeight == 0 || 3844fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVectorState.mVPathRenderer.mViewportHeight == 0 || 3854fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVectorState.mVPathRenderer.mViewportWidth == 0) { 3864fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return 1; // fall back to 1:1 pixel mapping. 3874fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3884fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float intrinsicWidth = mVectorState.mVPathRenderer.mBaseWidth; 3894fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float intrinsicHeight = mVectorState.mVPathRenderer.mBaseHeight; 3904fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float viewportWidth = mVectorState.mVPathRenderer.mViewportWidth; 3914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float viewportHeight = mVectorState.mVPathRenderer.mViewportHeight; 3924fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float scaleX = viewportWidth / intrinsicWidth; 3934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float scaleY = viewportHeight / intrinsicHeight; 3944fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return Math.min(scaleX, scaleY); 3954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 3964fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 3974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui /** 3984fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * Create a VectorDrawableCompat object. 3994fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * 4002c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu * @param res the resources. 4014fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * @param resId the resource ID for VectorDrawableCompat object. 4024fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * @param theme the theme of this vector drawable, it can be null. 4034fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * @return a new VectorDrawableCompat or null if parsing error is found. 4044fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui */ 4054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Nullable 4064fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public static VectorDrawableCompat create(@NonNull Resources res, @DrawableRes int resId, 4072c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu @Nullable Theme theme) { 408c59ac731f7d38ee41d0aba567a9d3b77b40df628Teng-Hui Zhu if (Build.VERSION.SDK_INT >= 24) { 4099f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu final VectorDrawableCompat drawable = new VectorDrawableCompat(); 410ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu drawable.mDelegateDrawable = ResourcesCompat.getDrawable(res, resId, theme); 4112c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu drawable.mCachedConstantStateDelegate = new VectorDrawableDelegateState( 4122c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu drawable.mDelegateDrawable.getConstantState()); 4139f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return drawable; 4149f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 4159f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 4164fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui try { 4174fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final XmlPullParser parser = res.getXml(resId); 4184fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final AttributeSet attrs = Xml.asAttributeSet(parser); 4194fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui int type; 4204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui while ((type = parser.next()) != XmlPullParser.START_TAG && 4214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui type != XmlPullParser.END_DOCUMENT) { 4224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Empty loop 4234fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (type != XmlPullParser.START_TAG) { 4254fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui throw new XmlPullParserException("No start tag found"); 4264fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 427e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banes return createFromXmlInner(res, parser, attrs, theme); 4284fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } catch (XmlPullParserException e) { 4294fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Log.e(LOGTAG, "parser error", e); 4304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } catch (IOException e) { 4314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Log.e(LOGTAG, "parser error", e); 4324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return null; 4344fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4354fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 436e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banes /** 437e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banes * Create a VectorDrawableCompat from inside an XML document using an optional 438e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banes * {@link Theme}. Called on a parser positioned at a tag in an XML 439e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banes * document, tries to create a Drawable from that tag. Returns {@code null} 440e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banes * if the tag is not a valid drawable. 441e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banes */ 442e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banes public static VectorDrawableCompat createFromXmlInner(Resources r, XmlPullParser parser, 443e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banes AttributeSet attrs, Theme theme) throws XmlPullParserException, IOException { 444e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banes final VectorDrawableCompat drawable = new VectorDrawableCompat(); 445e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banes drawable.inflate(r, parser, attrs, theme); 446e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banes return drawable; 447e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banes } 448e4beadba70aecabbd7f6677943ab7c0b94809b8aChris Banes 4498fbfb9b792b2978ba33bead0120a83b7af47a5f7Aurimas Liutikas static int applyAlpha(int color, float alpha) { 4504fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui int alphaBytes = Color.alpha(color); 4514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui color &= 0x00FFFFFF; 4524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui color |= ((int) (alphaBytes * alpha)) << 24; 4534fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return color; 4544fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4554fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 4564fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 4574fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs) 4584fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui throws XmlPullParserException, IOException { 4599f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 4609f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mDelegateDrawable.inflate(res, parser, attrs); 4619f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 4629f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 4639f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 4644fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui inflate(res, parser, attrs, null); 4654fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4664fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 46715375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 4684fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme) 4694fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui throws XmlPullParserException, IOException { 4709f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 471ebbed34a78fa6519de6c2848e68b97f9d3b98e08Tenghui Zhu DrawableCompat.inflate(mDelegateDrawable, res, parser, attrs, theme); 4729f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 4739f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 4749f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 4759f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu final VectorDrawableCompatState state = mVectorState; 4764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final VPathRenderer pathRenderer = new VPathRenderer(); 4774fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui state.mVPathRenderer = pathRenderer; 4784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 4799f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu final TypedArray a = obtainAttributes(res, theme, attrs, 4809f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu AndroidResources.styleable_VectorDrawableTypeArray); 481d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu 482d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu updateStateFromTypedArray(a, parser); 4834fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui a.recycle(); 4844fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui state.mChangingConfigurations = getChangingConfigurations(); 4854fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui state.mCacheDirty = true; 4864fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui inflateInternal(res, parser, attrs, theme); 4874fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 4884fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 4894fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 4904fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 491d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu 492d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu /** 493d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu * Parses a {@link android.graphics.PorterDuff.Mode} from a tintMode 494d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu * attribute's enum value. 495d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu */ 4966705492013ac9cf97407565d7bdeb0af45598b5bTeng-Hui Zhu private static PorterDuff.Mode parseTintModeCompat(int value, Mode defaultMode) { 497d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu switch (value) { 4982c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu case 3: 4992c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu return Mode.SRC_OVER; 5002c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu case 5: 5012c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu return Mode.SRC_IN; 5022c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu case 9: 5032c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu return Mode.SRC_ATOP; 5042c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu case 14: 5052c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu return Mode.MULTIPLY; 5062c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu case 15: 5072c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu return Mode.SCREEN; 5082c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu case 16: 5092c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu return Mode.ADD; 5102c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu default: 5112c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu return defaultMode; 512d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu } 513d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu } 514d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu 5159f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu private void updateStateFromTypedArray(TypedArray a, XmlPullParser parser) 5169f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu throws XmlPullParserException { 5179f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu final VectorDrawableCompatState state = mVectorState; 5184fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final VPathRenderer pathRenderer = state.mVPathRenderer; 5194fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 5204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Account for any configuration changes. 5214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // state.mChangingConfigurations |= Utils.getChangingConfigurations(a); 5224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 523d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu final int mode = TypedArrayUtils.getNamedInt(a, parser, "tintMode", 524d014251a4529b0eae3c313b7ede2b9d18421de44Chris Banes AndroidResources.styleable_VectorDrawable_tintMode, -1); 5256705492013ac9cf97407565d7bdeb0af45598b5bTeng-Hui Zhu state.mTintMode = parseTintModeCompat(mode, Mode.SRC_IN); 5264fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 5279f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu final ColorStateList tint = 5289f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu a.getColorStateList(AndroidResources.styleable_VectorDrawable_tint); 5294fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (tint != null) { 5304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui state.mTint = tint; 5314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 5324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 533d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu state.mAutoMirrored = TypedArrayUtils.getNamedBoolean(a, parser, "autoMirrored", 5342c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu AndroidResources.styleable_VectorDrawable_autoMirrored, state.mAutoMirrored); 535d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu 536d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu pathRenderer.mViewportWidth = TypedArrayUtils.getNamedFloat(a, parser, "viewportWidth", 5379f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu AndroidResources.styleable_VectorDrawable_viewportWidth, 5389f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu pathRenderer.mViewportWidth); 5394fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 540d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu pathRenderer.mViewportHeight = TypedArrayUtils.getNamedFloat(a, parser, "viewportHeight", 5419f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu AndroidResources.styleable_VectorDrawable_viewportHeight, 5429f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu pathRenderer.mViewportHeight); 5434fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 5444fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (pathRenderer.mViewportWidth <= 0) { 5454fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui throw new XmlPullParserException(a.getPositionDescription() + 5464fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui "<vector> tag requires viewportWidth > 0"); 5474fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } else if (pathRenderer.mViewportHeight <= 0) { 5484fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui throw new XmlPullParserException(a.getPositionDescription() + 5494fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui "<vector> tag requires viewportHeight > 0"); 5504fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 5514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 5524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui pathRenderer.mBaseWidth = a.getDimension( 553d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawable_width, pathRenderer.mBaseWidth); 5544fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui pathRenderer.mBaseHeight = a.getDimension( 555d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawable_height, pathRenderer.mBaseHeight); 5564fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (pathRenderer.mBaseWidth <= 0) { 5574fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui throw new XmlPullParserException(a.getPositionDescription() + 5584fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui "<vector> tag requires width > 0"); 5594fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } else if (pathRenderer.mBaseHeight <= 0) { 5604fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui throw new XmlPullParserException(a.getPositionDescription() + 5614fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui "<vector> tag requires height > 0"); 5624fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 5634fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 564d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu // shown up from API 11. 565d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu final float alphaInFloat = TypedArrayUtils.getNamedFloat(a, parser, "alpha", 566968dcfaff0c0a9e85ff4db2a985188f6996f5dadTeng-Hui Zhu AndroidResources.styleable_VectorDrawable_alpha, pathRenderer.getAlpha()); 5674fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui pathRenderer.setAlpha(alphaInFloat); 5684fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 569d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu final String name = a.getString(AndroidResources.styleable_VectorDrawable_name); 5704fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (name != null) { 5714fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui pathRenderer.mRootName = name; 5724fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui pathRenderer.mVGTargetsMap.put(name, pathRenderer); 5734fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 5744fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 5754fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 5764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private void inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs, 5772c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu Theme theme) throws XmlPullParserException, IOException { 5789f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu final VectorDrawableCompatState state = mVectorState; 5794fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final VPathRenderer pathRenderer = state.mVPathRenderer; 5804fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui boolean noPathTag = true; 5814fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 5824fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Use a stack to help to build the group tree. 5834fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // The top of the stack is always the current group. 5844fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final Stack<VGroup> groupStack = new Stack<VGroup>(); 5854fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui groupStack.push(pathRenderer.mRootGroup); 5864fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 5874fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui int eventType = parser.getEventType(); 5884fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui while (eventType != XmlPullParser.END_DOCUMENT) { 5894fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (eventType == XmlPullParser.START_TAG) { 5904fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final String tagName = parser.getName(); 5914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final VGroup currentGroup = groupStack.peek(); 5924fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (SHAPE_PATH.equals(tagName)) { 5934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final VFullPath path = new VFullPath(); 594d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu path.inflate(res, attrs, theme, parser); 5954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui currentGroup.mChildren.add(path); 5964fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (path.getPathName() != null) { 5974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui pathRenderer.mVGTargetsMap.put(path.getPathName(), path); 5984fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 5994fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui noPathTag = false; 6004fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui state.mChangingConfigurations |= path.mChangingConfigurations; 6014fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } else if (SHAPE_CLIP_PATH.equals(tagName)) { 6024fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final VClipPath path = new VClipPath(); 603d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu path.inflate(res, attrs, theme, parser); 6044fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui currentGroup.mChildren.add(path); 6054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (path.getPathName() != null) { 6064fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui pathRenderer.mVGTargetsMap.put(path.getPathName(), path); 6074fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6084fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui state.mChangingConfigurations |= path.mChangingConfigurations; 6094fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } else if (SHAPE_GROUP.equals(tagName)) { 6104fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui VGroup newChildGroup = new VGroup(); 611d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu newChildGroup.inflate(res, attrs, theme, parser); 6124fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui currentGroup.mChildren.add(newChildGroup); 6134fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui groupStack.push(newChildGroup); 6144fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (newChildGroup.getGroupName() != null) { 6154fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui pathRenderer.mVGTargetsMap.put(newChildGroup.getGroupName(), 6164fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui newChildGroup); 6174fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6184fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui state.mChangingConfigurations |= newChildGroup.mChangingConfigurations; 6194fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } else if (eventType == XmlPullParser.END_TAG) { 6214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final String tagName = parser.getName(); 6224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (SHAPE_GROUP.equals(tagName)) { 6234fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui groupStack.pop(); 6244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6254fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6264fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui eventType = parser.next(); 6274fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6284fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 6294fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Print the tree out for debug. 6304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (DBG_VECTOR_DRAWABLE) { 6314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui printGroupTree(pathRenderer.mRootGroup, 0); 6324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 6344fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (noPathTag) { 6354fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final StringBuffer tag = new StringBuffer(); 6364fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 6374fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (tag.length() > 0) { 6384fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui tag.append(" or "); 6394fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6404fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui tag.append(SHAPE_PATH); 6414fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 6424fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui throw new XmlPullParserException("no " + tag + " defined"); 6434fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6444fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6454fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 6464fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private void printGroupTree(VGroup currentGroup, int level) { 6474fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui String indent = ""; 6484fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui for (int i = 0; i < level; i++) { 6494fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui indent += " "; 6504fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Print the current node 6524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Log.v(LOGTAG, indent + "current group is :" + currentGroup.getGroupName() 6534fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui + " rotation is " + currentGroup.mRotate); 6544fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString()); 6554fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Then print all the children groups 6564fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui for (int i = 0; i < currentGroup.mChildren.size(); i++) { 6574fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Object child = currentGroup.mChildren.get(i); 6584fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (child instanceof VGroup) { 6594fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui printGroupTree((VGroup) child, level + 1); 660d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu } else { 661d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu ((VPath) child).printVPath(level + 1); 6624fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6634fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6644fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6654fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 6664fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui void setAllowCaching(boolean allowCaching) { 6674fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAllowCaching = allowCaching; 6684fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6694fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 6704fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // We don't support RTL auto mirroring since the getLayoutDirection() is for API 17+. 6714fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private boolean needMirroring() { 6724fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return false; 6734fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 6744fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 6759f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu // Extra override functions for delegation for SDK >= 7. 6769f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 6775f21d671a4afb439a61257b393d0b5e40879528aTeng-Hui Zhu protected void onBoundsChange(Rect bounds) { 6789f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 6795f21d671a4afb439a61257b393d0b5e40879528aTeng-Hui Zhu mDelegateDrawable.setBounds(bounds); 6809f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 6819f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 6829f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 6839f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 6849f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public int getChangingConfigurations() { 6859f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 6869f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateDrawable.getChangingConfigurations(); 6879f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 6882c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu return super.getChangingConfigurations() | mVectorState.getChangingConfigurations(); 6899f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 6909f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 6919f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 6929f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public void invalidateSelf() { 6939f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 6949f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mDelegateDrawable.invalidateSelf(); 6959f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 6969f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 6979f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu super.invalidateSelf(); 6989f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 6999f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 7009f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 7019f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public void scheduleSelf(Runnable what, long when) { 7029f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 7039f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mDelegateDrawable.scheduleSelf(what, when); 7049f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 7059f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 7069f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu super.scheduleSelf(what, when); 7079f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 7089f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 7099f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 7109f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public boolean setVisible(boolean visible, boolean restart) { 7119f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 7129f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateDrawable.setVisible(visible, restart); 7139f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 7149f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return super.setVisible(visible, restart); 7159f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 7169f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 7179f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 7189f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public void unscheduleSelf(Runnable what) { 7199f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu if (mDelegateDrawable != null) { 7209f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mDelegateDrawable.unscheduleSelf(what); 7219f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return; 7229f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 7239f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu super.unscheduleSelf(what); 7249f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 7259f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 7269f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu /** 727c59ac731f7d38ee41d0aba567a9d3b77b40df628Teng-Hui Zhu * Constant state for delegating the creating drawable job for SDK >= 24. 7289f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu * Instead of creating a VectorDrawable, create a VectorDrawableCompat instance which contains 7299f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu * a delegated VectorDrawable instance. 7309f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu */ 7319f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu private static class VectorDrawableDelegateState extends ConstantState { 7329f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu private final ConstantState mDelegateState; 7332c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu 7349f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public VectorDrawableDelegateState(ConstantState state) { 7359f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mDelegateState = state; 7369f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 7379f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 7389f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 7399f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public Drawable newDrawable() { 7409f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu VectorDrawableCompat drawableCompat = new VectorDrawableCompat(); 7419f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu drawableCompat.mDelegateDrawable = (VectorDrawable) mDelegateState.newDrawable(); 7429f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return drawableCompat; 7439f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 7449f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 7459f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 7469f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public Drawable newDrawable(Resources res) { 7479f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu VectorDrawableCompat drawableCompat = new VectorDrawableCompat(); 7489f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu drawableCompat.mDelegateDrawable = (VectorDrawable) mDelegateState.newDrawable(res); 7499f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return drawableCompat; 7509f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 7519f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 7529f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 7539f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public Drawable newDrawable(Resources res, Theme theme) { 7549f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu VectorDrawableCompat drawableCompat = new VectorDrawableCompat(); 7559f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu drawableCompat.mDelegateDrawable = 7569f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu (VectorDrawable) mDelegateState.newDrawable(res, theme); 7579f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return drawableCompat; 7589f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 7599f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 7609f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 7619f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public boolean canApplyTheme() { 7629f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateState.canApplyTheme(); 7639f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 7649f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 7659f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu @Override 7669f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public int getChangingConfigurations() { 7679f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu return mDelegateState.getChangingConfigurations(); 7689f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 7699f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu } 7709f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu 7719f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu private static class VectorDrawableCompatState extends ConstantState { 7724fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui int mChangingConfigurations; 7734fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui VPathRenderer mVPathRenderer; 7744fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui ColorStateList mTint = null; 7754fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Mode mTintMode = DEFAULT_TINT_MODE; 7764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui boolean mAutoMirrored; 7774fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 7784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Bitmap mCachedBitmap; 7794fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui int[] mCachedThemeAttrs; 7804fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui ColorStateList mCachedTint; 7814fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Mode mCachedTintMode; 7824fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui int mCachedRootAlpha; 7834fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui boolean mCachedAutoMirrored; 7844fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui boolean mCacheDirty; 7854fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 7862c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu /** 7872c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu * Temporary paint object used to draw cached bitmaps. 7882c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu */ 7894fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Paint mTempPaint; 7904fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 7914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Deep copy for mutate() or implicitly mutate. 7929f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public VectorDrawableCompatState(VectorDrawableCompatState copy) { 7934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (copy != null) { 7944fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mChangingConfigurations = copy.mChangingConfigurations; 7954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVPathRenderer = new VPathRenderer(copy.mVPathRenderer); 7964fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (copy.mVPathRenderer.mFillPaint != null) { 7974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVPathRenderer.mFillPaint = new Paint(copy.mVPathRenderer.mFillPaint); 7984fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 7994fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (copy.mVPathRenderer.mStrokePaint != null) { 8004fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVPathRenderer.mStrokePaint = new Paint(copy.mVPathRenderer.mStrokePaint); 8014fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8024fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTint = copy.mTint; 8034fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTintMode = copy.mTintMode; 8044fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mAutoMirrored = copy.mAutoMirrored; 8054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8064fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8074fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 8081f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu public void drawCachedBitmapWithRootAlpha(Canvas canvas, ColorFilter filter, 8091f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu Rect originalBounds) { 8104fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // The bitmap's size is the same as the bounds. 8114fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final Paint p = getPaint(filter); 8121f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu canvas.drawBitmap(mCachedBitmap, null, originalBounds, p); 8134fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8144fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 8154fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public boolean hasTranslucentRoot() { 8164fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mVPathRenderer.getRootAlpha() < 255; 8174fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8184fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 8194fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui /** 8204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * @return null when there is no need for alpha paint. 8214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui */ 8224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public Paint getPaint(ColorFilter filter) { 8234fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (!hasTranslucentRoot() && filter == null) { 8244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return null; 8254fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8264fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 8274fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (mTempPaint == null) { 8284fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTempPaint = new Paint(); 8294fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTempPaint.setFilterBitmap(true); 8304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTempPaint.setAlpha(mVPathRenderer.getRootAlpha()); 8324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTempPaint.setColorFilter(filter); 8334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mTempPaint; 8344fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8354fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 8361f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu public void updateCachedBitmap(int width, int height) { 8374fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mCachedBitmap.eraseColor(Color.TRANSPARENT); 8384fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Canvas tmpCanvas = new Canvas(mCachedBitmap); 8391f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu mVPathRenderer.draw(tmpCanvas, width, height, null); 8404fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8414fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 8421f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu public void createCachedBitmapIfNeeded(int width, int height) { 8431f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu if (mCachedBitmap == null || !canReuseBitmap(width, height)) { 8441f8664abb6cdd6962d58433e06dd9cc7ea856782Teng-Hui Zhu mCachedBitmap = Bitmap.createBitmap(width, height, 8454fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Bitmap.Config.ARGB_8888); 8464fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mCacheDirty = true; 8474fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8484fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 8494fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8504fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 8514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public boolean canReuseBitmap(int width, int height) { 8524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (width == mCachedBitmap.getWidth() 8534fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui && height == mCachedBitmap.getHeight()) { 8544fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return true; 8554fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8564fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return false; 8574fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8584fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 8594fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public boolean canReuseCache() { 8604fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (!mCacheDirty 8614fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui && mCachedTint == mTint 8624fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui && mCachedTintMode == mTintMode 8634fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui && mCachedAutoMirrored == mAutoMirrored 8644fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui && mCachedRootAlpha == mVPathRenderer.getRootAlpha()) { 8654fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return true; 8664fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8674fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return false; 8684fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8694fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 8704fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void updateCacheStates() { 8714fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Use shallow copy here and shallow comparison in canReuseCache(), 8724fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // likely hit cache miss more, but practically not much difference. 8734fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mCachedTint = mTint; 8744fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mCachedTintMode = mTintMode; 8754fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mCachedRootAlpha = mVPathRenderer.getRootAlpha(); 8764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mCachedAutoMirrored = mAutoMirrored; 8774fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mCacheDirty = false; 8784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8794fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 8809f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu public VectorDrawableCompatState() { 8814fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVPathRenderer = new VPathRenderer(); 8824fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8834fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 8844fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 8854fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public Drawable newDrawable() { 8864fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return new VectorDrawableCompat(this); 8874fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8884fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 8894fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 8904fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public Drawable newDrawable(Resources res) { 8914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return new VectorDrawableCompat(this); 8924fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 8944fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 8954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public int getChangingConfigurations() { 8964fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mChangingConfigurations; 8974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8984fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 8994fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 9004fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static class VPathRenderer { 9014fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui /* Right now the internal data structure is organized as a tree. 9024fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * Each node can be a group node, or a path. 9034fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * A group node can have groups or paths as children, but a path node has 9044fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * no children. 9054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * One example can be: 9064fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * Root Group 9074fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * / | \ 9084fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * Group Path Group 9094fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * / \ | 9104fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * Path Path Path 9114fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * 9124fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui */ 9134fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Variables that only used temporarily inside the draw() call, so there 9144fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // is no need for deep copying. 9154fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private final Path mPath; 9164fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private final Path mRenderPath; 9174fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static final Matrix IDENTITY_MATRIX = new Matrix(); 9184fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private final Matrix mFinalPathMatrix = new Matrix(); 9194fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 9204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private Paint mStrokePaint; 9214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private Paint mFillPaint; 9224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private PathMeasure mPathMeasure; 9234fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 9244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui ///////////////////////////////////////////////////// 9254fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 9264fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private int mChangingConfigurations; 9278fbfb9b792b2978ba33bead0120a83b7af47a5f7Aurimas Liutikas final VGroup mRootGroup; 9284fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float mBaseWidth = 0; 9294fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float mBaseHeight = 0; 9304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float mViewportWidth = 0; 9314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float mViewportHeight = 0; 9324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui int mRootAlpha = 0xFF; 9334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui String mRootName = null; 9344fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 9354fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>(); 9364fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 9374fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public VPathRenderer() { 9384fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mRootGroup = new VGroup(); 9394fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mPath = new Path(); 9404fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mRenderPath = new Path(); 9414fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 9424fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 9434fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setRootAlpha(int alpha) { 9444fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mRootAlpha = alpha; 9454fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 9464fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 9474fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public int getRootAlpha() { 9484fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mRootAlpha; 9494fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 9504fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 9514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // setAlpha() and getAlpha() are used mostly for animation purpose, since 9524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Animator like to use alpha from 0 to 1. 9534fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setAlpha(float alpha) { 9544fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui setRootAlpha((int) (alpha * 255)); 9554fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 9564fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 9574fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 9584fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public float getAlpha() { 9594fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return getRootAlpha() / 255.0f; 9604fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 9614fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 9624fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public VPathRenderer(VPathRenderer copy) { 9634fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap); 9644fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mPath = new Path(copy.mPath); 9654fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mRenderPath = new Path(copy.mRenderPath); 9664fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mBaseWidth = copy.mBaseWidth; 9674fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mBaseHeight = copy.mBaseHeight; 9684fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mViewportWidth = copy.mViewportWidth; 9694fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mViewportHeight = copy.mViewportHeight; 9704fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mChangingConfigurations = copy.mChangingConfigurations; 9714fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mRootAlpha = copy.mRootAlpha; 9724fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mRootName = copy.mRootName; 9734fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (copy.mRootName != null) { 9744fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mVGTargetsMap.put(copy.mRootName, this); 9754fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 9764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 9774fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 9784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private void drawGroupTree(VGroup currentGroup, Matrix currentMatrix, 9792c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu Canvas canvas, int w, int h, ColorFilter filter) { 9804fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Calculate current group's matrix by preConcat the parent's and 9814fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // and the current one on the top of the stack. 9824fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Basically the Mfinal = Mviewport * M0 * M1 * M2; 9834fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Mi the local matrix at level i of the group tree. 9844fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui currentGroup.mStackedMatrix.set(currentMatrix); 9854fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 9864fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix); 9874fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 98804027486ce99dc54f3ba88e517d76695c3ae90e8Teng-Hui Zhu // Save the current clip information, which is local to this group. 98904027486ce99dc54f3ba88e517d76695c3ae90e8Teng-Hui Zhu canvas.save(); 99004027486ce99dc54f3ba88e517d76695c3ae90e8Teng-Hui Zhu 9914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Draw the group tree in the same order as the XML file. 9924fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui for (int i = 0; i < currentGroup.mChildren.size(); i++) { 9934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Object child = currentGroup.mChildren.get(i); 9944fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (child instanceof VGroup) { 9954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui VGroup childGroup = (VGroup) child; 9964fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui drawGroupTree(childGroup, currentGroup.mStackedMatrix, 9974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui canvas, w, h, filter); 9984fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } else if (child instanceof VPath) { 9994fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui VPath childPath = (VPath) child; 10004fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui drawPath(currentGroup, childPath, canvas, w, h, filter); 10014fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 10024fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 100304027486ce99dc54f3ba88e517d76695c3ae90e8Teng-Hui Zhu 100404027486ce99dc54f3ba88e517d76695c3ae90e8Teng-Hui Zhu canvas.restore(); 10054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 10064fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 10074fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void draw(Canvas canvas, int w, int h, ColorFilter filter) { 1008c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas // Traverse the tree in pre-order to draw. 10094fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui drawGroupTree(mRootGroup, IDENTITY_MATRIX, canvas, w, h, filter); 10104fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 10114fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 10124fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private void drawPath(VGroup vGroup, VPath vPath, Canvas canvas, int w, int h, 10132c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu ColorFilter filter) { 10144fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final float scaleX = w / mViewportWidth; 10154fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final float scaleY = h / mViewportHeight; 10164fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final float minScale = Math.min(scaleX, scaleY); 10172c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu final Matrix groupStackedMatrix = vGroup.mStackedMatrix; 10184fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 10192c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu mFinalPathMatrix.set(groupStackedMatrix); 10204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mFinalPathMatrix.postScale(scaleX, scaleY); 10214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 10222c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu 10232c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu final float matrixScale = getMatrixScale(groupStackedMatrix); 10242c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu if (matrixScale == 0) { 10252c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu // When either x or y is scaled to 0, we don't need to draw anything. 10262c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu return; 10272c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu } 10284fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui vPath.toPath(mPath); 10294fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final Path path = mPath; 10304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 10314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mRenderPath.reset(); 10324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 10334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (vPath.isClipPath()) { 10344fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mRenderPath.addPath(path, mFinalPathMatrix); 103504027486ce99dc54f3ba88e517d76695c3ae90e8Teng-Hui Zhu canvas.clipPath(mRenderPath); 10364fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } else { 10374fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui VFullPath fullPath = (VFullPath) vPath; 10384fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (fullPath.mTrimPathStart != 0.0f || fullPath.mTrimPathEnd != 1.0f) { 10394fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float start = (fullPath.mTrimPathStart + fullPath.mTrimPathOffset) % 1.0f; 10404fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float end = (fullPath.mTrimPathEnd + fullPath.mTrimPathOffset) % 1.0f; 10414fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 10424fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (mPathMeasure == null) { 10434fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mPathMeasure = new PathMeasure(); 10444fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 10454fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mPathMeasure.setPath(mPath, false); 10464fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 10474fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float len = mPathMeasure.getLength(); 10484fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui start = start * len; 10494fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui end = end * len; 10504fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui path.reset(); 10514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (start > end) { 10524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mPathMeasure.getSegment(start, len, path, true); 10534fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mPathMeasure.getSegment(0f, end, path, true); 10544fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } else { 10554fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mPathMeasure.getSegment(start, end, path, true); 10564fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 10574fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui path.rLineTo(0, 0); // fix bug in measure 10584fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 10594fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mRenderPath.addPath(path, mFinalPathMatrix); 10604fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 10614fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (fullPath.mFillColor != Color.TRANSPARENT) { 10624fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (mFillPaint == null) { 10634fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mFillPaint = new Paint(); 10644fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mFillPaint.setStyle(Paint.Style.FILL); 10654fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mFillPaint.setAntiAlias(true); 10664fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 10674fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 10684fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final Paint fillPaint = mFillPaint; 10694fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui fillPaint.setColor(applyAlpha(fullPath.mFillColor, fullPath.mFillAlpha)); 10704fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui fillPaint.setColorFilter(filter); 10714fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui canvas.drawPath(mRenderPath, fillPaint); 10724fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 10734fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 10744fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (fullPath.mStrokeColor != Color.TRANSPARENT) { 10754fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (mStrokePaint == null) { 10764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mStrokePaint = new Paint(); 10774fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mStrokePaint.setStyle(Paint.Style.STROKE); 10784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mStrokePaint.setAntiAlias(true); 10794fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 10804fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 10814fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final Paint strokePaint = mStrokePaint; 10824fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (fullPath.mStrokeLineJoin != null) { 10834fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui strokePaint.setStrokeJoin(fullPath.mStrokeLineJoin); 10844fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 10854fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 10864fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (fullPath.mStrokeLineCap != null) { 10874fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui strokePaint.setStrokeCap(fullPath.mStrokeLineCap); 10884fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 10894fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 10904fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui strokePaint.setStrokeMiter(fullPath.mStrokeMiterlimit); 10914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui strokePaint.setColor(applyAlpha(fullPath.mStrokeColor, fullPath.mStrokeAlpha)); 10924fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui strokePaint.setColorFilter(filter); 10932c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu final float finalStrokeScale = minScale * matrixScale; 10942c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu strokePaint.setStrokeWidth(fullPath.mStrokeWidth * finalStrokeScale); 10954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui canvas.drawPath(mRenderPath, strokePaint); 10964fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 10974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 10984fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 10992c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu 11002c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu private static float cross(float v1x, float v1y, float v2x, float v2y) { 11012c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu return v1x * v2y - v1y * v2x; 11022c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu } 11032c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu 11042c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu private float getMatrixScale(Matrix groupStackedMatrix) { 11052c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu // Given unit vectors A = (0, 1) and B = (1, 0). 11062c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu // After matrix mapping, we got A' and B'. Let theta = the angel b/t A' and B'. 11072c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu // Therefore, the final scale we want is min(|A'| * sin(theta), |B'| * sin(theta)), 11082c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu // which is (|A'| * |B'| * sin(theta)) / max (|A'|, |B'|); 11092c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu // If max (|A'|, |B'|) = 0, that means either x or y has a scale of 0. 11102c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu // 11112c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu // For non-skew case, which is most of the cases, matrix scale is computing exactly the 11122c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu // scale on x and y axis, and take the minimal of these two. 11132c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu // For skew case, an unit square will mapped to a parallelogram. And this function will 11142c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu // return the minimal height of the 2 bases. 11152c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu float[] unitVectors = new float[]{0, 1, 1, 0}; 11162c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu groupStackedMatrix.mapVectors(unitVectors); 11172c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu float scaleX = (float) Math.hypot(unitVectors[0], unitVectors[1]); 11182c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu float scaleY = (float) Math.hypot(unitVectors[2], unitVectors[3]); 11192c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu float crossProduct = cross(unitVectors[0], unitVectors[1], unitVectors[2], 11202c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu unitVectors[3]); 11212c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu float maxScale = Math.max(scaleX, scaleY); 11222c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu 11232c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu float matrixScale = 0; 11242c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu if (maxScale > 0) { 11252c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu matrixScale = Math.abs(crossProduct) / maxScale; 11262c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu } 11272c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu if (DBG_VECTOR_DRAWABLE) { 11282c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu Log.d(LOGTAG, "Scale x " + scaleX + " y " + scaleY + " final " + matrixScale); 11292c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu } 11302c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu return matrixScale; 11312c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu } 11324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 11334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 11344fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static class VGroup { 11354fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // mStackedMatrix is only used temporarily when drawing, it combines all 11364fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // the parents' local matrices with the current one. 11374fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private final Matrix mStackedMatrix = new Matrix(); 11384fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 11394fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui ///////////////////////////////////////////////////// 11404fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 11414fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final ArrayList<Object> mChildren = new ArrayList<Object>(); 11424fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 11438fbfb9b792b2978ba33bead0120a83b7af47a5f7Aurimas Liutikas float mRotate = 0; 11444fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private float mPivotX = 0; 11454fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private float mPivotY = 0; 11464fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private float mScaleX = 1; 11474fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private float mScaleY = 1; 11484fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private float mTranslateX = 0; 11494fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private float mTranslateY = 0; 11504fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 11514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // mLocalMatrix is updated based on the update of transformation information, 11524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // either parsed from the XML or by animation. 11534fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private final Matrix mLocalMatrix = new Matrix(); 11548fbfb9b792b2978ba33bead0120a83b7af47a5f7Aurimas Liutikas int mChangingConfigurations; 11554fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private int[] mThemeAttrs; 11564fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private String mGroupName = null; 11574fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 11584fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public VGroup(VGroup copy, ArrayMap<String, Object> targetsMap) { 11594fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mRotate = copy.mRotate; 11604fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mPivotX = copy.mPivotX; 11614fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mPivotY = copy.mPivotY; 11624fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mScaleX = copy.mScaleX; 11634fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mScaleY = copy.mScaleY; 11644fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTranslateX = copy.mTranslateX; 11654fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTranslateY = copy.mTranslateY; 11664fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mThemeAttrs = copy.mThemeAttrs; 11674fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mGroupName = copy.mGroupName; 11684fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mChangingConfigurations = copy.mChangingConfigurations; 11694fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (mGroupName != null) { 11704fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui targetsMap.put(mGroupName, this); 11714fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 11724fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 11734fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mLocalMatrix.set(copy.mLocalMatrix); 11744fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 11754fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final ArrayList<Object> children = copy.mChildren; 11764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui for (int i = 0; i < children.size(); i++) { 11774fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Object copyChild = children.get(i); 11784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (copyChild instanceof VGroup) { 11794fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui VGroup copyGroup = (VGroup) copyChild; 11804fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mChildren.add(new VGroup(copyGroup, targetsMap)); 11814fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } else { 11824fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui VPath newPath = null; 11834fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (copyChild instanceof VFullPath) { 11844fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui newPath = new VFullPath((VFullPath) copyChild); 11854fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } else if (copyChild instanceof VClipPath) { 11864fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui newPath = new VClipPath((VClipPath) copyChild); 11874fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } else { 11884fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui throw new IllegalStateException("Unknown object in the tree!"); 11894fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 11904fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mChildren.add(newPath); 11914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (newPath.mPathName != null) { 11924fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui targetsMap.put(newPath.mPathName, newPath); 11934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 11944fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 11954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 11964fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 11974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 11984fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public VGroup() { 11994fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 12004fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 12014fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public String getGroupName() { 12024fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mGroupName; 12034fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 12044fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 12054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public Matrix getLocalMatrix() { 12064fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mLocalMatrix; 12074fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 12084fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1209d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu public void inflate(Resources res, AttributeSet attrs, Theme theme, XmlPullParser parser) { 12104fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final TypedArray a = obtainAttributes(res, theme, attrs, 1211d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawableGroup); 1212d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu updateStateFromTypedArray(a, parser); 12134fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui a.recycle(); 12144fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 12154fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1216d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu private void updateStateFromTypedArray(TypedArray a, XmlPullParser parser) { 12174fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Account for any configuration changes. 12184fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // mChangingConfigurations |= Utils.getChangingConfigurations(a); 12194fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 12204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Extract the theme attributes, if any. 12214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mThemeAttrs = null; // TODO TINT THEME Not supported yet a.extractThemeAttrs(); 12224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1223d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu // This is added in API 11 1224d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mRotate = TypedArrayUtils.getNamedFloat(a, parser, "rotation", 1225d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawableGroup_rotation, mRotate); 1226d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu 1227d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mPivotX = a.getFloat(AndroidResources.styleable_VectorDrawableGroup_pivotX, mPivotX); 1228d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mPivotY = a.getFloat(AndroidResources.styleable_VectorDrawableGroup_pivotY, mPivotY); 1229d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu 1230d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu // This is added in API 11 1231d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mScaleX = TypedArrayUtils.getNamedFloat(a, parser, "scaleX", 1232d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawableGroup_scaleX, mScaleX); 1233d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu 1234d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu // This is added in API 11 1235d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mScaleY = TypedArrayUtils.getNamedFloat(a, parser, "scaleY", 1236d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawableGroup_scaleY, mScaleY); 1237d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu 1238d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mTranslateX = TypedArrayUtils.getNamedFloat(a, parser, "translateX", 1239d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawableGroup_translateX, mTranslateX); 1240d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mTranslateY = TypedArrayUtils.getNamedFloat(a, parser, "translateY", 1241d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawableGroup_translateY, mTranslateY); 12424fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 12439f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu final String groupName = 12449f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu a.getString(AndroidResources.styleable_VectorDrawableGroup_name); 12454fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (groupName != null) { 12464fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mGroupName = groupName; 12474fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 12484fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 12494fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui updateLocalMatrix(); 12504fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 12514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 12524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private void updateLocalMatrix() { 12534fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // The order we apply is the same as the 12544fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // RenderNode.cpp::applyViewPropertyTransforms(). 12554fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mLocalMatrix.reset(); 12564fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mLocalMatrix.postTranslate(-mPivotX, -mPivotY); 12574fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mLocalMatrix.postScale(mScaleX, mScaleY); 12584fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mLocalMatrix.postRotate(mRotate, 0, 0); 12594fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY); 12604fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 12614fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 12624fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ 12634fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 12644fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public float getRotation() { 12654fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mRotate; 12664fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 12674fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 12684fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 12694fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setRotation(float rotation) { 12704fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (rotation != mRotate) { 12714fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mRotate = rotation; 12724fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui updateLocalMatrix(); 12734fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 12744fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 12754fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 12764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 12774fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public float getPivotX() { 12784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mPivotX; 12794fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 12804fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 12814fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 12824fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setPivotX(float pivotX) { 12834fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (pivotX != mPivotX) { 12844fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mPivotX = pivotX; 12854fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui updateLocalMatrix(); 12864fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 12874fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 12884fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 12894fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 12904fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public float getPivotY() { 12914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mPivotY; 12924fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 12934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 12944fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 12954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setPivotY(float pivotY) { 12964fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (pivotY != mPivotY) { 12974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mPivotY = pivotY; 12984fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui updateLocalMatrix(); 12994fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13004fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13014fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 13024fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 13034fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public float getScaleX() { 13044fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mScaleX; 13054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13064fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 13074fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 13084fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setScaleX(float scaleX) { 13094fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (scaleX != mScaleX) { 13104fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mScaleX = scaleX; 13114fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui updateLocalMatrix(); 13124fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13134fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13144fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 13154fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 13164fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public float getScaleY() { 13174fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mScaleY; 13184fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13194fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 13204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 13214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setScaleY(float scaleY) { 13224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (scaleY != mScaleY) { 13234fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mScaleY = scaleY; 13244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui updateLocalMatrix(); 13254fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13264fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13274fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 13284fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 13294fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public float getTranslateX() { 13304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mTranslateX; 13314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 13334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 13344fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setTranslateX(float translateX) { 13354fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (translateX != mTranslateX) { 13364fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTranslateX = translateX; 13374fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui updateLocalMatrix(); 13384fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13394fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13404fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 13414fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 13424fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public float getTranslateY() { 13434fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mTranslateY; 13444fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13454fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 13464fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 13474fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setTranslateY(float translateY) { 13484fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (translateY != mTranslateY) { 13494fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTranslateY = translateY; 13504fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui updateLocalMatrix(); 13514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13534fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13544fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 13554fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui /** 13564fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * Common Path information for clip path and normal path. 13574fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui */ 13584fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static class VPath { 13594fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui protected PathParser.PathDataNode[] mNodes = null; 13604fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui String mPathName; 13614fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui int mChangingConfigurations; 13624fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 13634fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public VPath() { 13644fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Empty constructor. 13654fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13664fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1367d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu public void printVPath(int level) { 1368d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu String indent = ""; 1369d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu for (int i = 0; i < level; i++) { 1370d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu indent += " "; 1371d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu } 1372d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu Log.v(LOGTAG, indent + "current path is :" + mPathName + 1373d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu " pathData is " + NodesToString(mNodes)); 1374d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu 1375d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu } 1376d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu 1377d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu public String NodesToString(PathParser.PathDataNode[] nodes) { 1378d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu String result = " "; 1379d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu for (int i = 0; i < nodes.length; i++) { 1380d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu result += nodes[i].type + ":"; 1381d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu float[] params = nodes[i].params; 1382d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu for (int j = 0; j < params.length; j++) { 1383d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu result += params[j] + ","; 1384d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu } 1385d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu } 1386d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu return result; 1387d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu } 1388d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu 13894fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public VPath(VPath copy) { 13904fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mPathName = copy.mPathName; 13914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mChangingConfigurations = copy.mChangingConfigurations; 13924fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mNodes = PathParser.deepCopyNodes(copy.mNodes); 13934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 13944fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 13954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void toPath(Path path) { 13964fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui path.reset(); 13974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (mNodes != null) { 13984fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui PathParser.PathDataNode.nodesToPath(mNodes, path); 13994fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14004fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14014fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 14024fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public String getPathName() { 14034fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mPathName; 14044fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 14064fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public boolean canApplyTheme() { 14074fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return false; 14084fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14094fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 14104fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void applyTheme(Theme t) { 14114fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14124fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 14134fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public boolean isClipPath() { 14144fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return false; 14154fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14164fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 14174fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ 14184fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 14194fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public PathParser.PathDataNode[] getPathData() { 14204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mNodes; 14214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 14234fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 14244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void setPathData(PathParser.PathDataNode[] nodes) { 14254fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (!PathParser.canMorph(mNodes, nodes)) { 14264fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // This should not happen in the middle of animation. 14274fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mNodes = PathParser.deepCopyNodes(nodes); 14284fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } else { 14294fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui PathParser.updateNodes(mNodes, nodes); 14304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 14344fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui /** 14354fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * Clip path, which only has name and pathData. 14364fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui */ 14374fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static class VClipPath extends VPath { 14384fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public VClipPath() { 14394fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Empty constructor. 14404fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14414fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 14424fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public VClipPath(VClipPath copy) { 14434fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui super(copy); 14444fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14454fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1446d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu public void inflate(Resources r, AttributeSet attrs, Theme theme, XmlPullParser parser) { 14474fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // TODO TINT THEME Not supported yet 1448d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu final boolean hasPathData = TypedArrayUtils.hasAttribute(parser, "pathData"); 1449d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu if (!hasPathData) { 1450d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu return; 1451d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu } 14524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final TypedArray a = obtainAttributes(r, theme, attrs, 1453d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawableClipPath); 14544fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui updateStateFromTypedArray(a); 14554fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui a.recycle(); 14564fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14574fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 14584fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private void updateStateFromTypedArray(TypedArray a) { 14594fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Account for any configuration changes. 14604fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // mChangingConfigurations |= Utils.getChangingConfigurations(a);; 14614fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 14629f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu final String pathName = 14639f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu a.getString(AndroidResources.styleable_VectorDrawableClipPath_name); 14644fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (pathName != null) { 14654fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mPathName = pathName; 14664fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14674fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 14689f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu final String pathData = 14699f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu a.getString(AndroidResources.styleable_VectorDrawableClipPath_pathData); 14704fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (pathData != null) { 14714fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mNodes = PathParser.createNodesFromPathData(pathData); 14724fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14734fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14744fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 14754fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 14764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public boolean isClipPath() { 14774fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return true; 14784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14794fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 14804fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 14814fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui /** 14824fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * Normal path, which contains all the fill / paint information. 14834fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui */ 14844fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private static class VFullPath extends VPath { 14854fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui ///////////////////////////////////////////////////// 14864fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 14874fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private int[] mThemeAttrs; 14884fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 14894fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui int mStrokeColor = Color.TRANSPARENT; 14904fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float mStrokeWidth = 0; 14914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 14924fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui int mFillColor = Color.TRANSPARENT; 14934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float mStrokeAlpha = 1.0f; 14944fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui int mFillRule; 14954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float mFillAlpha = 1.0f; 14964fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float mTrimPathStart = 0; 14974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float mTrimPathEnd = 1; 14984fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float mTrimPathOffset = 0; 14994fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 15004fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Paint.Cap mStrokeLineCap = Paint.Cap.BUTT; 15014fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui Paint.Join mStrokeLineJoin = Paint.Join.MITER; 15024fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float mStrokeMiterlimit = 4; 15034fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 15044fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public VFullPath() { 15054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Empty constructor. 15064fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 15074fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 15084fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public VFullPath(VFullPath copy) { 15094fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui super(copy); 15104fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mThemeAttrs = copy.mThemeAttrs; 15114fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 15124fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mStrokeColor = copy.mStrokeColor; 15134fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mStrokeWidth = copy.mStrokeWidth; 15144fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mStrokeAlpha = copy.mStrokeAlpha; 15154fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mFillColor = copy.mFillColor; 15164fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mFillRule = copy.mFillRule; 15174fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mFillAlpha = copy.mFillAlpha; 15184fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTrimPathStart = copy.mTrimPathStart; 15194fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTrimPathEnd = copy.mTrimPathEnd; 15204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTrimPathOffset = copy.mTrimPathOffset; 15214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 15224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mStrokeLineCap = copy.mStrokeLineCap; 15234fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mStrokeLineJoin = copy.mStrokeLineJoin; 15244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mStrokeMiterlimit = copy.mStrokeMiterlimit; 15254fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 15264fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 15274fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private Paint.Cap getStrokeLineCap(int id, Paint.Cap defValue) { 15284fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui switch (id) { 15294fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui case LINECAP_BUTT: 15304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return Paint.Cap.BUTT; 15314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui case LINECAP_ROUND: 15324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return Paint.Cap.ROUND; 15334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui case LINECAP_SQUARE: 15344fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return Paint.Cap.SQUARE; 15354fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui default: 15364fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return defValue; 15374fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 15384fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 15394fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 15404fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui private Paint.Join getStrokeLineJoin(int id, Paint.Join defValue) { 15414fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui switch (id) { 15424fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui case LINEJOIN_MITER: 15434fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return Paint.Join.MITER; 15444fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui case LINEJOIN_ROUND: 15454fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return Paint.Join.ROUND; 15464fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui case LINEJOIN_BEVEL: 15474fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return Paint.Join.BEVEL; 15484fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui default: 15494fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return defValue; 15504fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 15514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 15524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 15534fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 15544fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public boolean canApplyTheme() { 15554fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mThemeAttrs != null; 15564fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 15574fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1558d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu public void inflate(Resources r, AttributeSet attrs, Theme theme, XmlPullParser parser) { 15594fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui final TypedArray a = obtainAttributes(r, theme, attrs, 1560d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawablePath); 1561d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu updateStateFromTypedArray(a, parser); 15624fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui a.recycle(); 15634fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 15644fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1565d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu private void updateStateFromTypedArray(TypedArray a, XmlPullParser parser) { 15664fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Account for any configuration changes. 15674fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // mChangingConfigurations |= Utils.getChangingConfigurations(a); 15684fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 15694fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui // Extract the theme attributes, if any. 15704fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mThemeAttrs = null; // TODO TINT THEME Not supported yet a.extractThemeAttrs(); 15714fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 15729f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu // In order to work around the conflicting id issue, we need to double check the 15739f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu // existence of the attribute. 15749f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu // B/c if the attribute existed in the compiled XML, then calling TypedArray will be 15759f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu // safe since the framework will look up in the XML first. 15769f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu // Note that each getAttributeValue take roughly 0.03ms, it is a price we have to pay. 1577d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu final boolean hasPathData = TypedArrayUtils.hasAttribute(parser, "pathData"); 1578d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu if (!hasPathData) { 15799f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu // If there is no pathData in the <path> tag, then this is an empty path, 15809f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu // nothing need to be drawn. 1581d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu return; 1582d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu } 1583d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu 1584d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu final String pathName = a.getString(AndroidResources.styleable_VectorDrawablePath_name); 15854fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (pathName != null) { 15864fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mPathName = pathName; 15874fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 15889f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu final String pathData = 15899f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu a.getString(AndroidResources.styleable_VectorDrawablePath_pathData); 15904fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (pathData != null) { 15914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mNodes = PathParser.createNodesFromPathData(pathData); 15924fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 15934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 1594d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mFillColor = TypedArrayUtils.getNamedColor(a, parser, "fillColor", 1595d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawablePath_fillColor, mFillColor); 15962c3c8bff4c669316cdc2db24b72d9ac3f9b33725Teng-Hui Zhu mFillAlpha = TypedArrayUtils.getNamedFloat(a, parser, "fillAlpha", 1597d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawablePath_fillAlpha, mFillAlpha); 1598d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu final int lineCap = TypedArrayUtils.getNamedInt(a, parser, "strokeLineCap", 1599d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawablePath_strokeLineCap, -1); 1600d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mStrokeLineCap = getStrokeLineCap(lineCap, mStrokeLineCap); 1601d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu final int lineJoin = TypedArrayUtils.getNamedInt(a, parser, "strokeLineJoin", 1602d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawablePath_strokeLineJoin, -1); 1603d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mStrokeLineJoin = getStrokeLineJoin(lineJoin, mStrokeLineJoin); 1604d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mStrokeMiterlimit = TypedArrayUtils.getNamedFloat(a, parser, "strokeMiterLimit", 16059f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu AndroidResources.styleable_VectorDrawablePath_strokeMiterLimit, 16069f8d3b8d31e1e6a4bbdc68563691650ebff21353Teng-Hui Zhu mStrokeMiterlimit); 1607d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mStrokeColor = TypedArrayUtils.getNamedColor(a, parser, "strokeColor", 1608d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawablePath_strokeColor, mStrokeColor); 1609d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mStrokeAlpha = TypedArrayUtils.getNamedFloat(a, parser, "strokeAlpha", 1610d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawablePath_strokeAlpha, mStrokeAlpha); 1611d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mStrokeWidth = TypedArrayUtils.getNamedFloat(a, parser, "strokeWidth", 1612d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawablePath_strokeWidth, mStrokeWidth); 1613d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mTrimPathEnd = TypedArrayUtils.getNamedFloat(a, parser, "trimPathEnd", 1614d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawablePath_trimPathEnd, mTrimPathEnd); 1615d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mTrimPathOffset = TypedArrayUtils.getNamedFloat(a, parser, "trimPathOffset", 1616d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawablePath_trimPathOffset, mTrimPathOffset); 1617d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu mTrimPathStart = TypedArrayUtils.getNamedFloat(a, parser, "trimPathStart", 1618d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu AndroidResources.styleable_VectorDrawablePath_trimPathStart, mTrimPathStart); 16194fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 16204fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 16214fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @Override 16224fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui public void applyTheme(Theme t) { 16234fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui if (mThemeAttrs == null) { 16244fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return; 16254fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 16264fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 16274fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui /* 16284fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * TODO TINT THEME Not supported yet final TypedArray a = 1629d85f3e0b931d3e127242a375e0d00c4696bba912Teng-Hui Zhu * t.resolveAttributes(mThemeAttrs, styleable_VectorDrawablePath); 16304fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui * updateStateFromTypedArray(a); a.recycle(); 16314fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui */ 16324fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 16334fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 16344fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ 16354fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 16364fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui int getStrokeColor() { 16374fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mStrokeColor; 16384fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 16394fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 16404fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 16414fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui void setStrokeColor(int strokeColor) { 16424fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mStrokeColor = strokeColor; 16434fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 16444fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 16454fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 16464fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float getStrokeWidth() { 16474fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mStrokeWidth; 16484fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 16494fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 16504fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 16514fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui void setStrokeWidth(float strokeWidth) { 16524fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mStrokeWidth = strokeWidth; 16534fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 16544fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 16554fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 16564fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float getStrokeAlpha() { 16574fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mStrokeAlpha; 16584fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 16594fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 16604fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 16614fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui void setStrokeAlpha(float strokeAlpha) { 16624fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mStrokeAlpha = strokeAlpha; 16634fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 16644fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 16654fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 16664fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui int getFillColor() { 16674fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mFillColor; 16684fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 16694fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 16704fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 16714fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui void setFillColor(int fillColor) { 16724fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mFillColor = fillColor; 16734fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 16744fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 16754fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 16764fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float getFillAlpha() { 16774fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mFillAlpha; 16784fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 16794fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 16804fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 16814fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui void setFillAlpha(float fillAlpha) { 16824fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mFillAlpha = fillAlpha; 16834fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 16844fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 16854fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 16864fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float getTrimPathStart() { 16874fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mTrimPathStart; 16884fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 16894fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 16904fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 16914fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui void setTrimPathStart(float trimPathStart) { 16924fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTrimPathStart = trimPathStart; 16934fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 16944fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 16954fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 16964fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float getTrimPathEnd() { 16974fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mTrimPathEnd; 16984fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 16994fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 17004fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 17014fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui void setTrimPathEnd(float trimPathEnd) { 17024fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTrimPathEnd = trimPathEnd; 17034fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 17044fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 17054fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 17064fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui float getTrimPathOffset() { 17074fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui return mTrimPathOffset; 17084fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 17094fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui 17104fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui @SuppressWarnings("unused") 17114fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui void setTrimPathOffset(float trimPathOffset) { 17124fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui mTrimPathOffset = trimPathOffset; 17134fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 17144fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui } 17154fcaa70c2362e58a3fb30d140f0a0eeda8e35b44ztenghui} 1716