VectorDrawable.java revision 607bd848269fb802550e63aa61945790616f97a7
1abb7d134c02ac60091108c491dafb00877093170John Hoford/* 2abb7d134c02ac60091108c491dafb00877093170John Hoford * Copyright (C) 2014 The Android Open Source Project 3abb7d134c02ac60091108c491dafb00877093170John Hoford * 4abb7d134c02ac60091108c491dafb00877093170John Hoford * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5abb7d134c02ac60091108c491dafb00877093170John Hoford * in compliance with the License. You may obtain a copy of the License at 6abb7d134c02ac60091108c491dafb00877093170John Hoford * 7abb7d134c02ac60091108c491dafb00877093170John Hoford * http://www.apache.org/licenses/LICENSE-2.0 8abb7d134c02ac60091108c491dafb00877093170John Hoford * 9abb7d134c02ac60091108c491dafb00877093170John Hoford * Unless required by applicable law or agreed to in writing, software distributed under the License 10abb7d134c02ac60091108c491dafb00877093170John Hoford * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11abb7d134c02ac60091108c491dafb00877093170John Hoford * or implied. See the License for the specific language governing permissions and limitations under 12abb7d134c02ac60091108c491dafb00877093170John Hoford * the License. 13abb7d134c02ac60091108c491dafb00877093170John Hoford */ 14abb7d134c02ac60091108c491dafb00877093170John Hoford 15abb7d134c02ac60091108c491dafb00877093170John Hofordpackage android.graphics.drawable; 16abb7d134c02ac60091108c491dafb00877093170John Hoford 17b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.content.res.ColorStateList; 18abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.content.res.Resources; 19abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.content.res.Resources.Theme; 204b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viveretteimport android.content.res.TypedArray; 21482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghuiimport android.graphics.Bitmap; 22abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Canvas; 232af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghuiimport android.graphics.Color; 24abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.ColorFilter; 25abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Matrix; 26abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Paint; 27abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Path; 28abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.PathMeasure; 29abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.PixelFormat; 30b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuffColorFilter; 31abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Rect; 32abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Region; 33b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuff.Mode; 34e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.util.ArrayMap; 35abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.util.AttributeSet; 36738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghuiimport android.util.LayoutDirection; 37abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.util.Log; 38cf4832f69c8786b098ce18c24319021f8cd6733aztenghuiimport android.util.PathParser; 394b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viveretteimport android.util.Xml; 40abb7d134c02ac60091108c491dafb00877093170John Hoford 41abb7d134c02ac60091108c491dafb00877093170John Hofordimport com.android.internal.R; 42abb7d134c02ac60091108c491dafb00877093170John Hoford 43abb7d134c02ac60091108c491dafb00877093170John Hofordimport org.xmlpull.v1.XmlPullParser; 44abb7d134c02ac60091108c491dafb00877093170John Hofordimport org.xmlpull.v1.XmlPullParserException; 454b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viveretteimport org.xmlpull.v1.XmlPullParserFactory; 46abb7d134c02ac60091108c491dafb00877093170John Hoford 47abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.io.IOException; 48abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.util.ArrayList; 494d24caf1dec2babf273b18c99638fe2a0635ced4ztenghuiimport java.util.Stack; 504b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 51abb7d134c02ac60091108c491dafb00877093170John Hoford/** 526beeb75723cec42603b47664bce794a2b97d7bacChet Haase * This lets you create a drawable based on an XML vector graphic. It can be 53d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * defined in an XML file with the <code><vector></code> element. 54abb7d134c02ac60091108c491dafb00877093170John Hoford * <p/> 5546e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * The vector drawable has the following elements: 56abb7d134c02ac60091108c491dafb00877093170John Hoford * <p/> 57177dffd869ff1f5bdf816faead01a7dc4980bf75ztenghui * <dt><code><vector></code></dt> 58a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 59a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined a vector drawable 60a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 61a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:width</code></dt> 62a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the intrinsic width of the drawable. 63a95c8abb366d9c39450513335f550b56da13b30aztenghui * This support all the dimension units, normally specified with dp.</dd> 64a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:height</code></dt> 65a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the intrinsic height the drawable. 66a95c8abb366d9c39450513335f550b56da13b30aztenghui * This support all the dimension units, normally specified with dp.</dd> 67a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:viewportWidth</code></dt> 68a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the width of the viewport space. Viewport is basically 69a95c8abb366d9c39450513335f550b56da13b30aztenghui * the virtual canvas where the paths are drawn on.</dd> 70a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:viewportHeight</code></dt> 71a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the height of the viewport space. Viewport is basically 72a95c8abb366d9c39450513335f550b56da13b30aztenghui * the virtual canvas where the paths are drawn on.</dd> 73a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:tint</code></dt> 74a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The color to apply to the drawable as a tint. By default, no tint is applied.</dd> 75a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:tintMode</code></dt> 76a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The Porter-Duff blending mode for the tint color. The default value is src_in.</dd> 77a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:autoMirrored</code></dt> 78a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Indicates if the drawable needs to be mirrored when its layout direction is 79a95c8abb366d9c39450513335f550b56da13b30aztenghui * RTL (right-to-left).</dd> 80a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd> 81a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl> 82a95c8abb366d9c39450513335f550b56da13b30aztenghui * 83a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 846d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dt><code><group></code></dt> 85452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>Defines a group of paths or subgroups, plus transformation information. 86452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * The transformations are defined in the same coordinates as the viewport. 87a95c8abb366d9c39450513335f550b56da13b30aztenghui * And the transformations are applied in the order of scale, rotate then translate. 88a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 89a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:rotation</code></dt> 90a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The degrees of rotation of the group.</dd> 91a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pivotX</code></dt> 92a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The X coordinate of the pivot for the scale and rotation of the group. 93a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd> 94a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pivotY</code></dt> 95a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The Y coordinate of the pivot for the scale and rotation of the group. 96a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd> 97a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:scaleX</code></dt> 98a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of scale on the X Coordinate.</dd> 99a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:scaleY</code></dt> 100a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of scale on the Y coordinate.</dd> 101a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:translateX</code></dt> 102a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of translation on the X coordinate. 103a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd> 104a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:translateY</code></dt> 105a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of translation on the Y coordinate. 106a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd> 107a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd> 108a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl> 109a95c8abb366d9c39450513335f550b56da13b30aztenghui * 110a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 111abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code><path></code></dt> 1126d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dd>Defines paths to be drawn. 113abb7d134c02ac60091108c491dafb00877093170John Hoford * <dl> 114a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:name</code></dt> 115a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines the name of the path.</dd> 116a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pathData</code></dt> 11746e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * <dd>Defines path string. This is using exactly same format as "d" attribute 118a95c8abb366d9c39450513335f550b56da13b30aztenghui * in the SVG's path data. This is defined in the viewport space.</dd> 119a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:fillColor</code></dt> 120a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui * <dd>Defines the color to fill the path (none if not present).</dd> 121a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeColor</code></dt> 122d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <dd>Defines the color to draw the path outline (none if not present).</dd> 123a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeWidth</code></dt> 124a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The width a path stroke.</dd> 1252e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui * <dt><code>android:strokeAlpha</code></dt> 1262e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui * <dd>The opacity of a path stroke.</dd> 1272e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui * <dt><code>android:fillAlpha</code></dt> 1282e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui * <dd>The opacity to fill the path with.</dd> 129a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:trimPathStart</code></dt> 130a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The fraction of the path to trim from the start, in the range from 0 to 1.</dd> 131a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:trimPathEnd</code></dt> 132a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The fraction of the path to trim from the end, in the range from 0 to 1.</dd> 133a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:trimPathOffset</code></dt> 134a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Shift trim region (allows showed region to include the start and end), in the range 135a95c8abb366d9c39450513335f550b56da13b30aztenghui * from 0 to 1.</dd> 136a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeLineCap</code></dt> 137a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Sets the linecap for a stroked path: butt, round, square.</dd> 138a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeLineJoin</code></dt> 139a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Sets the lineJoin for a stroked path: miter,round,bevel.</dd> 140a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeMiterLimit</code></dt> 141a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Sets the Miter limit for a stroked path.</dd> 142a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd> 143a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl> 144a95c8abb366d9c39450513335f550b56da13b30aztenghui * 145a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 146a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code><clip-path></code></dt> 147a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines path to be the current clip. 148a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 149a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:name</code></dt> 150a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines the name of the clip path.</dd> 151a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pathData</code></dt> 152a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines clip path string. This is using exactly same format as "d" attribute 153a95c8abb366d9c39450513335f550b56da13b30aztenghui * in the SVG's path data.</dd> 154a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd> 155abb7d134c02ac60091108c491dafb00877093170John Hoford * </dl> 156a95c8abb366d9c39450513335f550b56da13b30aztenghui * <li>Here is a simple VectorDrawable in this vectordrawable.xml file. 157a95c8abb366d9c39450513335f550b56da13b30aztenghui * <pre> 158a95c8abb366d9c39450513335f550b56da13b30aztenghui * <vector xmlns:android="http://schemas.android.com/apk/res/android" 159a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:height="64dp" 160a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:width="64dp" 161a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:viewportHeight="600" 162a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:viewportWidth="600" > 163a95c8abb366d9c39450513335f550b56da13b30aztenghui * <group 164a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:name="rotationGroup" 165a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:pivotX="300.0" 166a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:pivotY="300.0" 167a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:rotation="45.0" > 168a95c8abb366d9c39450513335f550b56da13b30aztenghui * <path 169a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:name="v" 170a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:fillColor="#000000" 171a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /> 172a95c8abb366d9c39450513335f550b56da13b30aztenghui * </group> 173a95c8abb366d9c39450513335f550b56da13b30aztenghui * </vector> 174a95c8abb366d9c39450513335f550b56da13b30aztenghui * </pre></li> 175abb7d134c02ac60091108c491dafb00877093170John Hoford */ 176a95c8abb366d9c39450513335f550b56da13b30aztenghui 177abb7d134c02ac60091108c491dafb00877093170John Hofordpublic class VectorDrawable extends Drawable { 1789453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private static final String LOGTAG = VectorDrawable.class.getSimpleName(); 1799453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 180a95c8abb366d9c39450513335f550b56da13b30aztenghui private static final String SHAPE_CLIP_PATH = "clip-path"; 1816d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui private static final String SHAPE_GROUP = "group"; 182abb7d134c02ac60091108c491dafb00877093170John Hoford private static final String SHAPE_PATH = "path"; 183abb7d134c02ac60091108c491dafb00877093170John Hoford private static final String SHAPE_VECTOR = "vector"; 184abb7d134c02ac60091108c491dafb00877093170John Hoford 185abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_BUTT = 0; 186abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_ROUND = 1; 187abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_SQUARE = 2; 1889453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 189abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_MITER = 0; 190abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_ROUND = 1; 191abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_BEVEL = 2; 1929453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1934d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private static final boolean DBG_VECTOR_DRAWABLE = false; 1944d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 19555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private VectorDrawableState mVectorState; 196e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 197b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette private PorterDuffColorFilter mTintFilter; 198b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 19955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private boolean mMutated; 20055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 201482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // AnimatedVectorDrawable needs to turn off the cache all the time, otherwise, 202482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // caching the bitmap by default is allowed. 203482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui private boolean mAllowCaching = true; 204482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 205abb7d134c02ac60091108c491dafb00877093170John Hoford public VectorDrawable() { 20655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState = new VectorDrawableState(); 207abb7d134c02ac60091108c491dafb00877093170John Hoford } 208abb7d134c02ac60091108c491dafb00877093170John Hoford 2099453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private VectorDrawable(VectorDrawableState state, Resources res, Theme theme) { 21016c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui if (theme != null && state.canApplyTheme()) { 21116c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui // If we need to apply a theme, implicitly mutate. 21216c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui mVectorState = new VectorDrawableState(state); 2139453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette applyTheme(theme); 21416c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui } else { 21516c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui mVectorState = state; 2169453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 217b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 218b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 219607bd848269fb802550e63aa61945790616f97a7Alan Viverette state.setColorFilter(mTintFilter); 220abb7d134c02ac60091108c491dafb00877093170John Hoford } 221abb7d134c02ac60091108c491dafb00877093170John Hoford 22255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui @Override 22355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public Drawable mutate() { 22455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (!mMutated && super.mutate() == this) { 22555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState = new VectorDrawableState(mVectorState); 22655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mMutated = true; 22755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 22855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return this; 22955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 23055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 231e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui Object getTargetByName(String name) { 23255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return mVectorState.mVPathRenderer.mVGTargetsMap.get(name); 233e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 234e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 235abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 236abb7d134c02ac60091108c491dafb00877093170John Hoford public ConstantState getConstantState() { 23755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState.mChangingConfigurations = getChangingConfigurations(); 23855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return mVectorState; 239abb7d134c02ac60091108c491dafb00877093170John Hoford } 240abb7d134c02ac60091108c491dafb00877093170John Hoford 2414554a6a5137d8e9bdfb623ad84ff344a48b7eb9dAlan Viverette @Override 242abb7d134c02ac60091108c491dafb00877093170John Hoford public void draw(Canvas canvas) { 2434b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette final Rect bounds = getBounds(); 2441968201b44567262e7b2e382eee3d88990748d89Dan Sandler if (bounds.width() == 0 || bounds.height() == 0) { 2451968201b44567262e7b2e382eee3d88990748d89Dan Sandler // too small to draw 2461968201b44567262e7b2e382eee3d88990748d89Dan Sandler return; 2471968201b44567262e7b2e382eee3d88990748d89Dan Sandler } 2481968201b44567262e7b2e382eee3d88990748d89Dan Sandler 2490670f029a4e59448aa53b46a98e60dff6404f360ztenghui final int saveCount = canvas.save(); 250738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui final boolean needMirroring = needMirroring(); 251738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 2524b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette canvas.translate(bounds.left, bounds.top); 253738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui if (needMirroring) { 254738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui canvas.translate(bounds.width(), 0); 255738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui canvas.scale(-1.0f, 1.0f); 256738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 257482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 258482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui if (!mAllowCaching) { 259482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mVectorState.mVPathRenderer.draw(canvas, bounds.width(), bounds.height()); 260482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } else { 261482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Bitmap bitmap = mVectorState.mCachedBitmap; 262482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui if (bitmap == null || !mVectorState.canReuseCache(bounds.width(), 263482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui bounds.height())) { 264482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui bitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), 265482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Bitmap.Config.ARGB_8888); 266482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Canvas tmpCanvas = new Canvas(bitmap); 267482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mVectorState.mVPathRenderer.draw(tmpCanvas, bounds.width(), bounds.height()); 268482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mVectorState.mCachedBitmap = bitmap; 269482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 270482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mVectorState.updateCacheStates(); 271482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 27266613415966f2f1a43cdaa76560eb6d53a05f15dztenghui // The bitmap's size is the same as the bounds. 27366613415966f2f1a43cdaa76560eb6d53a05f15dztenghui canvas.drawBitmap(bitmap, 0, 0, null); 274482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 275738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 2764b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette canvas.restoreToCount(saveCount); 277abb7d134c02ac60091108c491dafb00877093170John Hoford } 278abb7d134c02ac60091108c491dafb00877093170John Hoford 279abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 280e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public int getAlpha() { 281e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mVectorState.mVPathRenderer.getRootAlpha(); 282e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 283e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 284e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 285abb7d134c02ac60091108c491dafb00877093170John Hoford public void setAlpha(int alpha) { 2862af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui if (mVectorState.mVPathRenderer.getRootAlpha() != alpha) { 2872af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mVectorState.mVPathRenderer.setRootAlpha(alpha); 288abb7d134c02ac60091108c491dafb00877093170John Hoford invalidateSelf(); 289abb7d134c02ac60091108c491dafb00877093170John Hoford } 290abb7d134c02ac60091108c491dafb00877093170John Hoford } 291abb7d134c02ac60091108c491dafb00877093170John Hoford 292abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 293abb7d134c02ac60091108c491dafb00877093170John Hoford public void setColorFilter(ColorFilter colorFilter) { 294b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final VectorDrawableState state = mVectorState; 295b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if (colorFilter != null) { 296b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette // Color filter overrides tint. 297b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = null; 298b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } else if (state.mTint != null && state.mTintMode != null) { 299b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette // Restore the tint filter, if we need one. 300b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final int color = state.mTint.getColorForState(getState(), Color.TRANSPARENT); 301b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = new PorterDuffColorFilter(color, state.mTintMode); 302b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette colorFilter = mTintFilter; 303b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 304b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 305607bd848269fb802550e63aa61945790616f97a7Alan Viverette state.setColorFilter(colorFilter); 306fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette invalidateSelf(); 307abb7d134c02ac60091108c491dafb00877093170John Hoford } 308abb7d134c02ac60091108c491dafb00877093170John Hoford 309abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 310a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette public void setTintList(ColorStateList tint) { 311b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final VectorDrawableState state = mVectorState; 312a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette if (state.mTint != tint) { 313b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette state.mTint = tint; 314a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette mTintFilter = updateTintFilter(mTintFilter, tint, state.mTintMode); 315607bd848269fb802550e63aa61945790616f97a7Alan Viverette state.setColorFilter(mTintFilter); 316a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette invalidateSelf(); 317a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette } 318a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette } 319b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 320a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette @Override 321a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette public void setTintMode(Mode tintMode) { 322a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette final VectorDrawableState state = mVectorState; 323a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette if (state.mTintMode != tintMode) { 324a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette state.mTintMode = tintMode; 325a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, tintMode); 326607bd848269fb802550e63aa61945790616f97a7Alan Viverette state.setColorFilter(mTintFilter); 327b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette invalidateSelf(); 328b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 329b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 330b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 331b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 332607bd848269fb802550e63aa61945790616f97a7Alan Viverette public boolean isStateful() { 333607bd848269fb802550e63aa61945790616f97a7Alan Viverette return super.isStateful() || (mVectorState != null && mVectorState.mTint != null 334607bd848269fb802550e63aa61945790616f97a7Alan Viverette && mVectorState.mTint.isStateful()); 335607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 336607bd848269fb802550e63aa61945790616f97a7Alan Viverette 337607bd848269fb802550e63aa61945790616f97a7Alan Viverette @Override 338b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette protected boolean onStateChange(int[] stateSet) { 339b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final VectorDrawableState state = mVectorState; 340b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if (state.mTint != null && state.mTintMode != null) { 341b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 342607bd848269fb802550e63aa61945790616f97a7Alan Viverette state.setColorFilter(mTintFilter); 343607bd848269fb802550e63aa61945790616f97a7Alan Viverette invalidateSelf(); 344b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette return true; 345b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 346b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette return false; 347b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 348b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 349b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 350abb7d134c02ac60091108c491dafb00877093170John Hoford public int getOpacity() { 351abb7d134c02ac60091108c491dafb00877093170John Hoford return PixelFormat.TRANSLUCENT; 352abb7d134c02ac60091108c491dafb00877093170John Hoford } 353abb7d134c02ac60091108c491dafb00877093170John Hoford 354abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 355abb7d134c02ac60091108c491dafb00877093170John Hoford public int getIntrinsicWidth() { 356ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui return (int) mVectorState.mVPathRenderer.mBaseWidth; 357abb7d134c02ac60091108c491dafb00877093170John Hoford } 358abb7d134c02ac60091108c491dafb00877093170John Hoford 359abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 360abb7d134c02ac60091108c491dafb00877093170John Hoford public int getIntrinsicHeight() { 361ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui return (int) mVectorState.mVPathRenderer.mBaseHeight; 362abb7d134c02ac60091108c491dafb00877093170John Hoford } 363abb7d134c02ac60091108c491dafb00877093170John Hoford 364abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 3659453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public boolean canApplyTheme() { 3669453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette return super.canApplyTheme() || mVectorState != null && mVectorState.canApplyTheme(); 3679453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 3689453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 3699453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette @Override 3709453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public void applyTheme(Theme t) { 3719453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette super.applyTheme(t); 3729453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 3739453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final VectorDrawableState state = mVectorState; 374607bd848269fb802550e63aa61945790616f97a7Alan Viverette if (state != null && state.mThemeAttrs != null) { 375607bd848269fb802550e63aa61945790616f97a7Alan Viverette final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.VectorDrawable); 376607bd848269fb802550e63aa61945790616f97a7Alan Viverette try { 377607bd848269fb802550e63aa61945790616f97a7Alan Viverette state.mCacheDirty = true; 378607bd848269fb802550e63aa61945790616f97a7Alan Viverette updateStateFromTypedArray(a); 379607bd848269fb802550e63aa61945790616f97a7Alan Viverette } catch (XmlPullParserException e) { 380607bd848269fb802550e63aa61945790616f97a7Alan Viverette throw new RuntimeException(e); 381607bd848269fb802550e63aa61945790616f97a7Alan Viverette } finally { 382607bd848269fb802550e63aa61945790616f97a7Alan Viverette a.recycle(); 383607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 384607bd848269fb802550e63aa61945790616f97a7Alan Viverette 385607bd848269fb802550e63aa61945790616f97a7Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 386607bd848269fb802550e63aa61945790616f97a7Alan Viverette state.setColorFilter(mTintFilter); 387607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 388607bd848269fb802550e63aa61945790616f97a7Alan Viverette 389ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui final VPathRenderer path = state.mVPathRenderer; 3909453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette if (path != null && path.canApplyTheme()) { 3919453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette path.applyTheme(t); 3929453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 3939453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 3949453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 395fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount /** 396fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount * The size of a pixel when scaled from the intrinsic dimension to the viewport dimension. 397fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount * This is used to calculate the path animation accuracy. 398fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount * 399fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount * @hide 400fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount */ 401fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount public float getPixelSize() { 402fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount if (mVectorState == null && mVectorState.mVPathRenderer == null || 403fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount mVectorState.mVPathRenderer.mBaseWidth == 0 || 404fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount mVectorState.mVPathRenderer.mBaseHeight == 0 || 405fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount mVectorState.mVPathRenderer.mViewportHeight == 0 || 406fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount mVectorState.mVPathRenderer.mViewportWidth == 0) { 407fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount return 1; // fall back to 1:1 pixel mapping. 408fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount } 409fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float intrinsicWidth = mVectorState.mVPathRenderer.mBaseWidth; 410fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float intrinsicHeight = mVectorState.mVPathRenderer.mBaseHeight; 411fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float viewportWidth = mVectorState.mVPathRenderer.mViewportWidth; 412fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float viewportHeight = mVectorState.mVPathRenderer.mViewportHeight; 413fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float scaleX = viewportWidth / intrinsicWidth; 414fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float scaleY = viewportHeight / intrinsicHeight; 415fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount return Math.min(scaleX, scaleY); 416fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount } 417fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount 4184b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette /** @hide */ 4194b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette public static VectorDrawable create(Resources resources, int rid) { 4204b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette try { 421874bcd82c223ce58c9d76edcf619b3988c672307ztenghui final XmlPullParser parser = resources.getXml(rid); 422874bcd82c223ce58c9d76edcf619b3988c672307ztenghui final AttributeSet attrs = Xml.asAttributeSet(parser); 423874bcd82c223ce58c9d76edcf619b3988c672307ztenghui int type; 424874bcd82c223ce58c9d76edcf619b3988c672307ztenghui while ((type=parser.next()) != XmlPullParser.START_TAG && 425874bcd82c223ce58c9d76edcf619b3988c672307ztenghui type != XmlPullParser.END_DOCUMENT) { 426874bcd82c223ce58c9d76edcf619b3988c672307ztenghui // Empty loop 427874bcd82c223ce58c9d76edcf619b3988c672307ztenghui } 428874bcd82c223ce58c9d76edcf619b3988c672307ztenghui if (type != XmlPullParser.START_TAG) { 429874bcd82c223ce58c9d76edcf619b3988c672307ztenghui throw new XmlPullParserException("No start tag found"); 430874bcd82c223ce58c9d76edcf619b3988c672307ztenghui } 4314b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 4324b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette final VectorDrawable drawable = new VectorDrawable(); 433874bcd82c223ce58c9d76edcf619b3988c672307ztenghui drawable.inflate(resources, parser, attrs); 4344b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 4354b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette return drawable; 4364b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } catch (XmlPullParserException e) { 4374b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette Log.e(LOGTAG, "parser error", e); 4384b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } catch (IOException e) { 4394b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette Log.e(LOGTAG, "parser error", e); 4404b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } 4414b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette return null; 4424b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } 4434b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 4442af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui private static int applyAlpha(int color, float alpha) { 4452af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui int alphaBytes = Color.alpha(color); 4462af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui color &= 0x00FFFFFF; 4472af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui color |= ((int) (alphaBytes * alpha)) << 24; 4482af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui return color; 4492af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 4502af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 4519cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette @Override 4529cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme) 4539cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette throws XmlPullParserException, IOException { 454a95c8abb366d9c39450513335f550b56da13b30aztenghui final VectorDrawableState state = mVectorState; 455a95c8abb366d9c39450513335f550b56da13b30aztenghui final VPathRenderer pathRenderer = new VPathRenderer(); 456a95c8abb366d9c39450513335f550b56da13b30aztenghui state.mVPathRenderer = pathRenderer; 457a95c8abb366d9c39450513335f550b56da13b30aztenghui 458607bd848269fb802550e63aa61945790616f97a7Alan Viverette final TypedArray a = obtainAttributes(res, theme, attrs, R.styleable.VectorDrawable); 4599cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette updateStateFromTypedArray(a); 4609cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette a.recycle(); 4619cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 462a95c8abb366d9c39450513335f550b56da13b30aztenghui state.mCacheDirty = true; 46355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui inflateInternal(res, parser, attrs, theme); 4649cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 4659cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 466607bd848269fb802550e63aa61945790616f97a7Alan Viverette state.setColorFilter(mTintFilter); 4679cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 4689cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 469a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException { 4709cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final VectorDrawableState state = mVectorState; 471a95c8abb366d9c39450513335f550b56da13b30aztenghui final VPathRenderer pathRenderer = state.mVPathRenderer; 4729cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 4738e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 4748e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= a.getChangingConfigurations(); 4758e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 4769cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette // Extract the theme attributes, if any. 4779cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mThemeAttrs = a.extractThemeAttrs(); 4789cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 4799cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final int tintMode = a.getInt(R.styleable.VectorDrawable_tintMode, -1); 4809cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette if (tintMode != -1) { 4819cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN); 4829cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 4839cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 4849cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final ColorStateList tint = a.getColorStateList(R.styleable.VectorDrawable_tint); 4859cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette if (tint != null) { 4869cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mTint = tint; 4879cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 488738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 489738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui state.mAutoMirrored = a.getBoolean( 490738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui R.styleable.VectorDrawable_autoMirrored, state.mAutoMirrored); 491a95c8abb366d9c39450513335f550b56da13b30aztenghui 492a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mViewportWidth = a.getFloat( 493a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawable_viewportWidth, pathRenderer.mViewportWidth); 494a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mViewportHeight = a.getFloat( 495a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawable_viewportHeight, pathRenderer.mViewportHeight); 496a95c8abb366d9c39450513335f550b56da13b30aztenghui 497a95c8abb366d9c39450513335f550b56da13b30aztenghui if (pathRenderer.mViewportWidth <= 0) { 498a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new XmlPullParserException(a.getPositionDescription() + 4991c4d8b2173bf4b5bbac94748959752599775628dztenghui "<vector> tag requires viewportWidth > 0"); 500a95c8abb366d9c39450513335f550b56da13b30aztenghui } else if (pathRenderer.mViewportHeight <= 0) { 501a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new XmlPullParserException(a.getPositionDescription() + 5021c4d8b2173bf4b5bbac94748959752599775628dztenghui "<vector> tag requires viewportHeight > 0"); 503a95c8abb366d9c39450513335f550b56da13b30aztenghui } 504a95c8abb366d9c39450513335f550b56da13b30aztenghui 505a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mBaseWidth = a.getDimension( 506a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawable_width, pathRenderer.mBaseWidth); 507a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mBaseHeight = a.getDimension( 508a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawable_height, pathRenderer.mBaseHeight); 509a95c8abb366d9c39450513335f550b56da13b30aztenghui 510a95c8abb366d9c39450513335f550b56da13b30aztenghui if (pathRenderer.mBaseWidth <= 0) { 511a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new XmlPullParserException(a.getPositionDescription() + 5121c4d8b2173bf4b5bbac94748959752599775628dztenghui "<vector> tag requires width > 0"); 513a95c8abb366d9c39450513335f550b56da13b30aztenghui } else if (pathRenderer.mBaseHeight <= 0) { 514a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new XmlPullParserException(a.getPositionDescription() + 5151c4d8b2173bf4b5bbac94748959752599775628dztenghui "<vector> tag requires height > 0"); 516a95c8abb366d9c39450513335f550b56da13b30aztenghui } 5179cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 5189cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 51955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private void inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs, 5208e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette Theme theme) throws XmlPullParserException, IOException { 5218e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final VectorDrawableState state = mVectorState; 522a95c8abb366d9c39450513335f550b56da13b30aztenghui final VPathRenderer pathRenderer = state.mVPathRenderer; 523abb7d134c02ac60091108c491dafb00877093170John Hoford boolean noPathTag = true; 5249453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 5254d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Use a stack to help to build the group tree. 5264d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // The top of the stack is always the current group. 5274d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final Stack<VGroup> groupStack = new Stack<VGroup>(); 5284d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.push(pathRenderer.mRootGroup); 529abb7d134c02ac60091108c491dafb00877093170John Hoford 530abb7d134c02ac60091108c491dafb00877093170John Hoford int eventType = parser.getEventType(); 531abb7d134c02ac60091108c491dafb00877093170John Hoford while (eventType != XmlPullParser.END_DOCUMENT) { 532abb7d134c02ac60091108c491dafb00877093170John Hoford if (eventType == XmlPullParser.START_TAG) { 5339453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final String tagName = parser.getName(); 5344d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final VGroup currentGroup = groupStack.peek(); 5354d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 536abb7d134c02ac60091108c491dafb00877093170John Hoford if (SHAPE_PATH.equals(tagName)) { 537a95c8abb366d9c39450513335f550b56da13b30aztenghui final VFullPath path = new VFullPath(); 5389453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette path.inflate(res, attrs, theme); 5398d0d24f7a2b1a59060aa18926984491691d3c667ztenghui currentGroup.mChildren.add(path); 540e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (path.getPathName() != null) { 54155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui pathRenderer.mVGTargetsMap.put(path.getPathName(), path); 542e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 543abb7d134c02ac60091108c491dafb00877093170John Hoford noPathTag = false; 5448e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= path.mChangingConfigurations; 545a95c8abb366d9c39450513335f550b56da13b30aztenghui } else if (SHAPE_CLIP_PATH.equals(tagName)) { 546a95c8abb366d9c39450513335f550b56da13b30aztenghui final VClipPath path = new VClipPath(); 547a95c8abb366d9c39450513335f550b56da13b30aztenghui path.inflate(res, attrs, theme); 548a95c8abb366d9c39450513335f550b56da13b30aztenghui currentGroup.mChildren.add(path); 549a95c8abb366d9c39450513335f550b56da13b30aztenghui if (path.getPathName() != null) { 550a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mVGTargetsMap.put(path.getPathName(), path); 551a95c8abb366d9c39450513335f550b56da13b30aztenghui } 552a95c8abb366d9c39450513335f550b56da13b30aztenghui state.mChangingConfigurations |= path.mChangingConfigurations; 5536d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui } else if (SHAPE_GROUP.equals(tagName)) { 5544d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui VGroup newChildGroup = new VGroup(); 5554d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui newChildGroup.inflate(res, attrs, theme); 5568d0d24f7a2b1a59060aa18926984491691d3c667ztenghui currentGroup.mChildren.add(newChildGroup); 5574d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.push(newChildGroup); 558e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (newChildGroup.getGroupName() != null) { 55955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui pathRenderer.mVGTargetsMap.put(newChildGroup.getGroupName(), 56055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui newChildGroup); 561e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 5628e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= newChildGroup.mChangingConfigurations; 563abb7d134c02ac60091108c491dafb00877093170John Hoford } 5644d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } else if (eventType == XmlPullParser.END_TAG) { 5654d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final String tagName = parser.getName(); 5664d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui if (SHAPE_GROUP.equals(tagName)) { 5674d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.pop(); 5684d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 569abb7d134c02ac60091108c491dafb00877093170John Hoford } 570abb7d134c02ac60091108c491dafb00877093170John Hoford eventType = parser.next(); 571abb7d134c02ac60091108c491dafb00877093170John Hoford } 5729453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 5734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Print the tree out for debug. 5744d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui if (DBG_VECTOR_DRAWABLE) { 5754d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui printGroupTree(pathRenderer.mRootGroup, 0); 5766d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui } 5776d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui 578a95c8abb366d9c39450513335f550b56da13b30aztenghui if (noPathTag) { 5799453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final StringBuffer tag = new StringBuffer(); 5809453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 581a95c8abb366d9c39450513335f550b56da13b30aztenghui if (tag.length() > 0) { 582a95c8abb366d9c39450513335f550b56da13b30aztenghui tag.append(" or "); 583abb7d134c02ac60091108c491dafb00877093170John Hoford } 584a95c8abb366d9c39450513335f550b56da13b30aztenghui tag.append(SHAPE_PATH); 5859453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 5869453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette throw new XmlPullParserException("no " + tag + " defined"); 587abb7d134c02ac60091108c491dafb00877093170John Hoford } 588abb7d134c02ac60091108c491dafb00877093170John Hoford } 589abb7d134c02ac60091108c491dafb00877093170John Hoford 5904d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void printGroupTree(VGroup currentGroup, int level) { 5914d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui String indent = ""; 5928d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < level; i++) { 5934d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui indent += " "; 5944d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 5954d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Print the current node 5968d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Log.v(LOGTAG, indent + "current group is :" + currentGroup.getGroupName() 5974d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui + " rotation is " + currentGroup.mRotate); 5988d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString()); 5998d0d24f7a2b1a59060aa18926984491691d3c667ztenghui // Then print all the children groups 6008d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < currentGroup.mChildren.size(); i++) { 6018d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = currentGroup.mChildren.get(i); 6028d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 6038d0d24f7a2b1a59060aa18926984491691d3c667ztenghui printGroupTree((VGroup) child, level + 1); 6048d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 6054d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6064d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6074d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 60855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui @Override 60955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public int getChangingConfigurations() { 61055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return super.getChangingConfigurations() | mVectorState.mChangingConfigurations; 61155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 61255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 613482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui void setAllowCaching(boolean allowCaching) { 614482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mAllowCaching = allowCaching; 615482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 616482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 617738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui private boolean needMirroring() { 618738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui return isAutoMirrored() && getLayoutDirection() == LayoutDirection.RTL; 619738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 620738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 621738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui @Override 622738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui public void setAutoMirrored(boolean mirrored) { 623738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui if (mVectorState.mAutoMirrored != mirrored) { 624738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui mVectorState.mAutoMirrored = mirrored; 625738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui invalidateSelf(); 626738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 627738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 628738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 629738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui @Override 630738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui public boolean isAutoMirrored() { 631738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui return mVectorState.mAutoMirrored; 632738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 633738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 6345c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette private static class VectorDrawableState extends ConstantState { 6359cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette int[] mThemeAttrs; 6365c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette int mChangingConfigurations; 637ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui VPathRenderer mVPathRenderer; 638607bd848269fb802550e63aa61945790616f97a7Alan Viverette ColorStateList mTint = null; 639607bd848269fb802550e63aa61945790616f97a7Alan Viverette Mode mTintMode = DEFAULT_TINT_MODE; 640738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui boolean mAutoMirrored; 6415c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 642482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Bitmap mCachedBitmap; 643482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui int[] mCachedThemeAttrs; 644482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui ColorStateList mCachedTint; 645482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Mode mCachedTintMode; 646482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui int mCachedRootAlpha; 647670689af43358568bf2b5916284f1cac5762f428ztenghui boolean mCachedAutoMirrored; 648670689af43358568bf2b5916284f1cac5762f428ztenghui boolean mCacheDirty; 649482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 65055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Deep copy for mutate() or implicitly mutate. 6515c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public VectorDrawableState(VectorDrawableState copy) { 6525c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette if (copy != null) { 6539cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette mThemeAttrs = copy.mThemeAttrs; 6545c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette mChangingConfigurations = copy.mChangingConfigurations; 655ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui mVPathRenderer = new VPathRenderer(copy.mVPathRenderer); 6566f6578e81c1df207da47e2e1337382341f271206Chet Haase if (copy.mVPathRenderer.mFillPaint != null) { 6576f6578e81c1df207da47e2e1337382341f271206Chet Haase mVPathRenderer.mFillPaint = new Paint(copy.mVPathRenderer.mFillPaint); 6586f6578e81c1df207da47e2e1337382341f271206Chet Haase } 6596f6578e81c1df207da47e2e1337382341f271206Chet Haase if (copy.mVPathRenderer.mStrokePaint != null) { 6606f6578e81c1df207da47e2e1337382341f271206Chet Haase mVPathRenderer.mStrokePaint = new Paint(copy.mVPathRenderer.mStrokePaint); 6616f6578e81c1df207da47e2e1337382341f271206Chet Haase } 6626f6578e81c1df207da47e2e1337382341f271206Chet Haase if (copy.mVPathRenderer.mColorFilter != null) { 6636f6578e81c1df207da47e2e1337382341f271206Chet Haase mVPathRenderer.mColorFilter = copy.mVPathRenderer.mColorFilter; 6646f6578e81c1df207da47e2e1337382341f271206Chet Haase } 665b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTint = copy.mTint; 666b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintMode = copy.mTintMode; 667738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui mAutoMirrored = copy.mAutoMirrored; 6685c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 6695c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 6705c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 671482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui public boolean canReuseCache(int width, int height) { 672670689af43358568bf2b5916284f1cac5762f428ztenghui if (!mCacheDirty 673670689af43358568bf2b5916284f1cac5762f428ztenghui && mCachedThemeAttrs == mThemeAttrs 674482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && mCachedTint == mTint 675482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && mCachedTintMode == mTintMode 676670689af43358568bf2b5916284f1cac5762f428ztenghui && mCachedAutoMirrored == mAutoMirrored 677482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && width == mCachedBitmap.getWidth() 678482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && height == mCachedBitmap.getHeight() 679482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && mCachedRootAlpha == mVPathRenderer.getRootAlpha()) { 680482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui return true; 681482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 682482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui return false; 683482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 684482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 685482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui public void updateCacheStates() { 686482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // Use shallow copy here and shallow comparison in canReuseCache(), 687482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // likely hit cache miss more, but practically not much difference. 688482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedThemeAttrs = mThemeAttrs; 689482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedTint = mTint; 690482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedTintMode = mTintMode; 691482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedRootAlpha = mVPathRenderer.getRootAlpha(); 692670689af43358568bf2b5916284f1cac5762f428ztenghui mCachedAutoMirrored = mAutoMirrored; 693670689af43358568bf2b5916284f1cac5762f428ztenghui mCacheDirty = false; 694482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 695482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 696607bd848269fb802550e63aa61945790616f97a7Alan Viverette @Override 697607bd848269fb802550e63aa61945790616f97a7Alan Viverette public boolean canApplyTheme() { 698607bd848269fb802550e63aa61945790616f97a7Alan Viverette return super.canApplyTheme() || mThemeAttrs != null 699607bd848269fb802550e63aa61945790616f97a7Alan Viverette || (mVPathRenderer != null && mVPathRenderer.canApplyTheme()); 700607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 701607bd848269fb802550e63aa61945790616f97a7Alan Viverette 702607bd848269fb802550e63aa61945790616f97a7Alan Viverette public void setColorFilter(ColorFilter colorFilter) { 703607bd848269fb802550e63aa61945790616f97a7Alan Viverette if (mVPathRenderer != null && mVPathRenderer.setColorFilter(colorFilter)) { 704607bd848269fb802550e63aa61945790616f97a7Alan Viverette mCacheDirty = true; 705607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 706607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 707607bd848269fb802550e63aa61945790616f97a7Alan Viverette 70855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VectorDrawableState() { 70955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVPathRenderer = new VPathRenderer(); 71055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 71155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 7125c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 7135c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable() { 7145c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, null, null); 7155c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 7165c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 7175c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 7185c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable(Resources res) { 7195c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, res, null); 7205c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 7215c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 7225c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 7235c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable(Resources res, Theme theme) { 7245c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, res, theme); 7255c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 7265c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 7275c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 7285c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public int getChangingConfigurations() { 7295c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return mChangingConfigurations; 7305c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 7315c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 7325c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 733ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui private static class VPathRenderer { 7344d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui /* Right now the internal data structure is organized as a tree. 7354d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Each node can be a group node, or a path. 7364d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * A group node can have groups or paths as children, but a path node has 7374d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * no children. 7384d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * One example can be: 7394d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Root Group 7404d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * / | \ 7414d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Group Path Group 7424d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * / \ | 7434d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Path Path Path 7444d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * 7454d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui */ 74655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables that only used temporarily inside the draw() call, so there 74755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // is no need for deep copying. 7486f6578e81c1df207da47e2e1337382341f271206Chet Haase private final Path mPath; 7496f6578e81c1df207da47e2e1337382341f271206Chet Haase private final Path mRenderPath; 7504d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private static final Matrix IDENTITY_MATRIX = new Matrix(); 75155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final Matrix mFinalPathMatrix = new Matrix(); 7524b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 7534b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private Paint mStrokePaint; 7544b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private Paint mFillPaint; 755fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette private ColorFilter mColorFilter; 756abb7d134c02ac60091108c491dafb00877093170John Hoford private PathMeasure mPathMeasure; 7574b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 75855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 75955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 7608e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private int mChangingConfigurations; 76155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final VGroup mRootGroup; 762a95c8abb366d9c39450513335f550b56da13b30aztenghui float mBaseWidth = 0; 763a95c8abb366d9c39450513335f550b56da13b30aztenghui float mBaseHeight = 0; 764a95c8abb366d9c39450513335f550b56da13b30aztenghui float mViewportWidth = 0; 765a95c8abb366d9c39450513335f550b56da13b30aztenghui float mViewportHeight = 0; 7662af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui private int mRootAlpha = 0xFF; 7679453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 76855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>(); 769abb7d134c02ac60091108c491dafb00877093170John Hoford 770ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui public VPathRenderer() { 7714d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mRootGroup = new VGroup(); 7726f6578e81c1df207da47e2e1337382341f271206Chet Haase mPath = new Path(); 7736f6578e81c1df207da47e2e1337382341f271206Chet Haase mRenderPath = new Path(); 774abb7d134c02ac60091108c491dafb00877093170John Hoford } 7759453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 7762af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui public void setRootAlpha(int alpha) { 7772af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mRootAlpha = alpha; 7782af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 7792af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 7802af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui public int getRootAlpha() { 7812af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui return mRootAlpha; 7822af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 7832af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 784ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui public VPathRenderer(VPathRenderer copy) { 78555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap); 7866f6578e81c1df207da47e2e1337382341f271206Chet Haase mPath = new Path(copy.mPath); 7876f6578e81c1df207da47e2e1337382341f271206Chet Haase mRenderPath = new Path(copy.mRenderPath); 788abb7d134c02ac60091108c491dafb00877093170John Hoford mBaseWidth = copy.mBaseWidth; 789abb7d134c02ac60091108c491dafb00877093170John Hoford mBaseHeight = copy.mBaseHeight; 7905eb5cde467081d1af628e5463ba55f110265a86fztenghui mViewportWidth = copy.mViewportWidth; 791abb7d134c02ac60091108c491dafb00877093170John Hoford mViewportHeight = copy.mViewportHeight; 7928e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations = copy.mChangingConfigurations; 79355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRootAlpha = copy.mRootAlpha; 794abb7d134c02ac60091108c491dafb00877093170John Hoford } 795abb7d134c02ac60091108c491dafb00877093170John Hoford 7969453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public boolean canApplyTheme() { 7974d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // If one of the paths can apply theme, then return true; 7984d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui return recursiveCanApplyTheme(mRootGroup); 7994d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 8004d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 8014d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private boolean recursiveCanApplyTheme(VGroup currentGroup) { 8024d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // We can do a tree traverse here, if there is one path return true, 8034d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // then we return true for the whole tree. 8048d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = currentGroup.mChildren; 8058d0d24f7a2b1a59060aa18926984491691d3c667ztenghui 8068d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 8078d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = children.get(i); 8088d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 8098d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 8108d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childGroup.canApplyTheme() 8118d0d24f7a2b1a59060aa18926984491691d3c667ztenghui || recursiveCanApplyTheme(childGroup)) { 8128d0d24f7a2b1a59060aa18926984491691d3c667ztenghui return true; 8138d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 8148d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 8158d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 8168d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childPath.canApplyTheme()) { 8178d0d24f7a2b1a59060aa18926984491691d3c667ztenghui return true; 8188d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 8194d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 8204d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 8219453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette return false; 8229453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 8239453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 8249453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public void applyTheme(Theme t) { 8254d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Apply theme to every path of the tree. 8264d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui recursiveApplyTheme(mRootGroup, t); 8274d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 8284d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 8294d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void recursiveApplyTheme(VGroup currentGroup, Theme t) { 8304d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // We can do a tree traverse here, apply theme to all paths which 8314d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // can apply theme. 8328d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = currentGroup.mChildren; 8338d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 8348d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = children.get(i); 8358d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 8368d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 8378d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childGroup.canApplyTheme()) { 8388d0d24f7a2b1a59060aa18926984491691d3c667ztenghui childGroup.applyTheme(t); 8398d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 8408d0d24f7a2b1a59060aa18926984491691d3c667ztenghui recursiveApplyTheme(childGroup, t); 8418d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 8428d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 8438d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childPath.canApplyTheme()) { 8448d0d24f7a2b1a59060aa18926984491691d3c667ztenghui childPath.applyTheme(t); 8458d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 8464d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 8474d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 848abb7d134c02ac60091108c491dafb00877093170John Hoford } 849abb7d134c02ac60091108c491dafb00877093170John Hoford 850607bd848269fb802550e63aa61945790616f97a7Alan Viverette public boolean setColorFilter(ColorFilter colorFilter) { 851607bd848269fb802550e63aa61945790616f97a7Alan Viverette if (colorFilter != mColorFilter 852607bd848269fb802550e63aa61945790616f97a7Alan Viverette || (colorFilter != null && !colorFilter.equals(mColorFilter))) { 853607bd848269fb802550e63aa61945790616f97a7Alan Viverette mColorFilter = colorFilter; 854fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 855607bd848269fb802550e63aa61945790616f97a7Alan Viverette if (mFillPaint != null) { 856607bd848269fb802550e63aa61945790616f97a7Alan Viverette mFillPaint.setColorFilter(colorFilter); 857607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 858fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 859607bd848269fb802550e63aa61945790616f97a7Alan Viverette if (mStrokePaint != null) { 860607bd848269fb802550e63aa61945790616f97a7Alan Viverette mStrokePaint.setColorFilter(colorFilter); 861607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 862607bd848269fb802550e63aa61945790616f97a7Alan Viverette return true; 863fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } 864607bd848269fb802550e63aa61945790616f97a7Alan Viverette return false; 865fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } 866fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 8674d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void drawGroupTree(VGroup currentGroup, Matrix currentMatrix, 8682e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui Canvas canvas, int w, int h) { 8694d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Calculate current group's matrix by preConcat the parent's and 8704d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // and the current one on the top of the stack. 8714d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Basically the Mfinal = Mviewport * M0 * M1 * M2; 8724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Mi the local matrix at level i of the group tree. 8734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui currentGroup.mStackedMatrix.set(currentMatrix); 8744d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 8754d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix); 8764d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 8778d0d24f7a2b1a59060aa18926984491691d3c667ztenghui // Draw the group tree in the same order as the XML file. 8788d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < currentGroup.mChildren.size(); i++) { 8798d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = currentGroup.mChildren.get(i); 8808d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 8818d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 8828d0d24f7a2b1a59060aa18926984491691d3c667ztenghui drawGroupTree(childGroup, currentGroup.mStackedMatrix, 8832e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui canvas, w, h); 8848d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 8858d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 8862e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui drawPath(currentGroup, childPath, canvas, w, h); 8878d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 888abb7d134c02ac60091108c491dafb00877093170John Hoford } 8894d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 890abb7d134c02ac60091108c491dafb00877093170John Hoford 8914d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui public void draw(Canvas canvas, int w, int h) { 8924d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Travese the tree in pre-order to draw. 8932e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui drawGroupTree(mRootGroup, IDENTITY_MATRIX, canvas, w, h); 894abb7d134c02ac60091108c491dafb00877093170John Hoford } 895abb7d134c02ac60091108c491dafb00877093170John Hoford 8962e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui private void drawPath(VGroup vGroup, VPath vPath, Canvas canvas, int w, int h) { 8979d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui final float scaleX = w / mViewportWidth; 8989d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui final float scaleY = h / mViewportHeight; 8999d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui final float minScale = Math.min(scaleX, scaleY); 900abb7d134c02ac60091108c491dafb00877093170John Hoford 9014d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mFinalPathMatrix.set(vGroup.mStackedMatrix); 9025a836f74df027bb568da17fbde4e641b6a56d2a9ztenghui mFinalPathMatrix.postScale(scaleX, scaleY); 903abb7d134c02ac60091108c491dafb00877093170John Hoford 9048d0d24f7a2b1a59060aa18926984491691d3c667ztenghui vPath.toPath(mPath); 9058d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final Path path = mPath; 906abb7d134c02ac60091108c491dafb00877093170John Hoford 9078d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mRenderPath.reset(); 9089453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 909a95c8abb366d9c39450513335f550b56da13b30aztenghui if (vPath.isClipPath()) { 910a95c8abb366d9c39450513335f550b56da13b30aztenghui mRenderPath.addPath(path, mFinalPathMatrix); 9118d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.clipPath(mRenderPath, Region.Op.REPLACE); 9128d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else { 913a95c8abb366d9c39450513335f550b56da13b30aztenghui VFullPath fullPath = (VFullPath) vPath; 914a95c8abb366d9c39450513335f550b56da13b30aztenghui if (fullPath.mTrimPathStart != 0.0f || fullPath.mTrimPathEnd != 1.0f) { 915a95c8abb366d9c39450513335f550b56da13b30aztenghui float start = (fullPath.mTrimPathStart + fullPath.mTrimPathOffset) % 1.0f; 916a95c8abb366d9c39450513335f550b56da13b30aztenghui float end = (fullPath.mTrimPathEnd + fullPath.mTrimPathOffset) % 1.0f; 917a95c8abb366d9c39450513335f550b56da13b30aztenghui 918a95c8abb366d9c39450513335f550b56da13b30aztenghui if (mPathMeasure == null) { 919a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure = new PathMeasure(); 920a95c8abb366d9c39450513335f550b56da13b30aztenghui } 921a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure.setPath(mPath, false); 922a95c8abb366d9c39450513335f550b56da13b30aztenghui 923a95c8abb366d9c39450513335f550b56da13b30aztenghui float len = mPathMeasure.getLength(); 924a95c8abb366d9c39450513335f550b56da13b30aztenghui start = start * len; 925a95c8abb366d9c39450513335f550b56da13b30aztenghui end = end * len; 926a95c8abb366d9c39450513335f550b56da13b30aztenghui path.reset(); 927a95c8abb366d9c39450513335f550b56da13b30aztenghui if (start > end) { 928a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure.getSegment(start, len, path, true); 929a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure.getSegment(0f, end, path, true); 930a95c8abb366d9c39450513335f550b56da13b30aztenghui } else { 931a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure.getSegment(start, end, path, true); 932a95c8abb366d9c39450513335f550b56da13b30aztenghui } 933a95c8abb366d9c39450513335f550b56da13b30aztenghui path.rLineTo(0, 0); // fix bug in measure 934a95c8abb366d9c39450513335f550b56da13b30aztenghui } 935a95c8abb366d9c39450513335f550b56da13b30aztenghui mRenderPath.addPath(path, mFinalPathMatrix); 936a95c8abb366d9c39450513335f550b56da13b30aztenghui 937a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui if (fullPath.mFillColor != Color.TRANSPARENT) { 9388d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mFillPaint == null) { 9398d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint = new Paint(); 9408d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setColorFilter(mColorFilter); 9418d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setStyle(Paint.Style.FILL); 9428d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setAntiAlias(true); 94363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 9442e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mFillPaint.setColor(applyAlpha(fullPath.mFillColor, 9452e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui fullPath.mFillAlpha)); 9468d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.drawPath(mRenderPath, mFillPaint); 9478d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 94863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 949a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui if (fullPath.mStrokeColor != Color.TRANSPARENT) { 9508d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mStrokePaint == null) { 9518d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint = new Paint(); 9528d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setColorFilter(mColorFilter); 9538d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setStyle(Paint.Style.STROKE); 9548d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setAntiAlias(true); 9558d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 9564b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 9578d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final Paint strokePaint = mStrokePaint; 958a95c8abb366d9c39450513335f550b56da13b30aztenghui if (fullPath.mStrokeLineJoin != null) { 959a95c8abb366d9c39450513335f550b56da13b30aztenghui strokePaint.setStrokeJoin(fullPath.mStrokeLineJoin); 9608d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 961abb7d134c02ac60091108c491dafb00877093170John Hoford 962a95c8abb366d9c39450513335f550b56da13b30aztenghui if (fullPath.mStrokeLineCap != null) { 963a95c8abb366d9c39450513335f550b56da13b30aztenghui strokePaint.setStrokeCap(fullPath.mStrokeLineCap); 9648d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 96563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 966c4d651ec8a8c190c5df173166357c2fdf47472ceztenghui strokePaint.setStrokeMiter(fullPath.mStrokeMiterlimit); 96763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 9682e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui strokePaint.setColor(applyAlpha(fullPath.mStrokeColor, 9692e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui fullPath.mStrokeAlpha)); 970a95c8abb366d9c39450513335f550b56da13b30aztenghui strokePaint.setStrokeWidth(fullPath.mStrokeWidth * minScale); 9718d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.drawPath(mRenderPath, strokePaint); 97263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 973abb7d134c02ac60091108c491dafb00877093170John Hoford } 974abb7d134c02ac60091108c491dafb00877093170John Hoford } 975abb7d134c02ac60091108c491dafb00877093170John Hoford } 976abb7d134c02ac60091108c491dafb00877093170John Hoford 977a95c8abb366d9c39450513335f550b56da13b30aztenghui private static class VGroup { 97855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // mStackedMatrix is only used temporarily when drawing, it combines all 97955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // the parents' local matrices with the current one. 98055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final Matrix mStackedMatrix = new Matrix(); 98155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 98255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 98355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 9848d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> mChildren = new ArrayList<Object>(); 985abb7d134c02ac60091108c491dafb00877093170John Hoford 98663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mRotate = 0; 98763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mPivotX = 0; 98863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mPivotY = 0; 989452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mScaleX = 1; 990452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mScaleY = 1; 991452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mTranslateX = 0; 992452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mTranslateY = 0; 9934d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 99455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // mLocalMatrix is updated based on the update of transformation information, 99555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // either parsed from the XML or by animation. 9964d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private final Matrix mLocalMatrix = new Matrix(); 9978e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private int mChangingConfigurations; 99863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private int[] mThemeAttrs; 999e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui private String mGroupName = null; 1000e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 100155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VGroup(VGroup copy, ArrayMap<String, Object> targetsMap) { 100255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRotate = copy.mRotate; 100355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPivotX = copy.mPivotX; 100455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPivotY = copy.mPivotY; 100555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mScaleX = copy.mScaleX; 100655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mScaleY = copy.mScaleY; 100755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTranslateX = copy.mTranslateX; 100855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTranslateY = copy.mTranslateY; 100955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mThemeAttrs = copy.mThemeAttrs; 101055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mGroupName = copy.mGroupName; 101155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mChangingConfigurations = copy.mChangingConfigurations; 101255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (mGroupName != null) { 101355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui targetsMap.put(mGroupName, this); 101455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 101555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 101655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mLocalMatrix.set(copy.mLocalMatrix); 101755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 10188d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = copy.mChildren; 10198d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 10208d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object copyChild = children.get(i); 10218d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (copyChild instanceof VGroup) { 10228d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup copyGroup = (VGroup) copyChild; 10238d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mChildren.add(new VGroup(copyGroup, targetsMap)); 1024a95c8abb366d9c39450513335f550b56da13b30aztenghui } else { 1025a95c8abb366d9c39450513335f550b56da13b30aztenghui VPath newPath = null; 1026a95c8abb366d9c39450513335f550b56da13b30aztenghui if (copyChild instanceof VFullPath) { 1027a95c8abb366d9c39450513335f550b56da13b30aztenghui newPath = new VFullPath((VFullPath) copyChild); 1028a95c8abb366d9c39450513335f550b56da13b30aztenghui } else if (copyChild instanceof VClipPath) { 1029a95c8abb366d9c39450513335f550b56da13b30aztenghui newPath = new VClipPath((VClipPath) copyChild); 1030a95c8abb366d9c39450513335f550b56da13b30aztenghui } else { 1031a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new IllegalStateException("Unknown object in the tree!"); 1032a95c8abb366d9c39450513335f550b56da13b30aztenghui } 10338d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mChildren.add(newPath); 10348d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (newPath.mPathName != null) { 10358d0d24f7a2b1a59060aa18926984491691d3c667ztenghui targetsMap.put(newPath.mPathName, newPath); 10368d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 103755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 103855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 103955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 104055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 104155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VGroup() { 104255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 104355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 1044a95c8abb366d9c39450513335f550b56da13b30aztenghui public String getGroupName() { 1045a95c8abb366d9c39450513335f550b56da13b30aztenghui return mGroupName; 1046a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1047a95c8abb366d9c39450513335f550b56da13b30aztenghui 1048a95c8abb366d9c39450513335f550b56da13b30aztenghui public Matrix getLocalMatrix() { 1049a95c8abb366d9c39450513335f550b56da13b30aztenghui return mLocalMatrix; 1050a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1051a95c8abb366d9c39450513335f550b56da13b30aztenghui 1052a95c8abb366d9c39450513335f550b56da13b30aztenghui public void inflate(Resources res, AttributeSet attrs, Theme theme) { 1053a95c8abb366d9c39450513335f550b56da13b30aztenghui final TypedArray a = obtainAttributes(res, theme, attrs, 1054a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawableGroup); 1055a95c8abb366d9c39450513335f550b56da13b30aztenghui updateStateFromTypedArray(a); 1056a95c8abb366d9c39450513335f550b56da13b30aztenghui a.recycle(); 1057a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1058a95c8abb366d9c39450513335f550b56da13b30aztenghui 1059a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateStateFromTypedArray(TypedArray a) { 1060a95c8abb366d9c39450513335f550b56da13b30aztenghui // Account for any configuration changes. 1061a95c8abb366d9c39450513335f550b56da13b30aztenghui mChangingConfigurations |= a.getChangingConfigurations(); 1062a95c8abb366d9c39450513335f550b56da13b30aztenghui 1063a95c8abb366d9c39450513335f550b56da13b30aztenghui // Extract the theme attributes, if any. 1064a95c8abb366d9c39450513335f550b56da13b30aztenghui mThemeAttrs = a.extractThemeAttrs(); 1065a95c8abb366d9c39450513335f550b56da13b30aztenghui 1066a95c8abb366d9c39450513335f550b56da13b30aztenghui mRotate = a.getFloat(R.styleable.VectorDrawableGroup_rotation, mRotate); 1067a95c8abb366d9c39450513335f550b56da13b30aztenghui mPivotX = a.getFloat(R.styleable.VectorDrawableGroup_pivotX, mPivotX); 1068a95c8abb366d9c39450513335f550b56da13b30aztenghui mPivotY = a.getFloat(R.styleable.VectorDrawableGroup_pivotY, mPivotY); 1069a95c8abb366d9c39450513335f550b56da13b30aztenghui mScaleX = a.getFloat(R.styleable.VectorDrawableGroup_scaleX, mScaleX); 1070a95c8abb366d9c39450513335f550b56da13b30aztenghui mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY); 1071a95c8abb366d9c39450513335f550b56da13b30aztenghui mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX); 1072a95c8abb366d9c39450513335f550b56da13b30aztenghui mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY); 1073a95c8abb366d9c39450513335f550b56da13b30aztenghui 1074a95c8abb366d9c39450513335f550b56da13b30aztenghui final String groupName = a.getString(R.styleable.VectorDrawableGroup_name); 1075a95c8abb366d9c39450513335f550b56da13b30aztenghui if (groupName != null) { 1076a95c8abb366d9c39450513335f550b56da13b30aztenghui mGroupName = groupName; 1077a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1078a95c8abb366d9c39450513335f550b56da13b30aztenghui 1079a95c8abb366d9c39450513335f550b56da13b30aztenghui updateLocalMatrix(); 1080a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1081a95c8abb366d9c39450513335f550b56da13b30aztenghui 1082607bd848269fb802550e63aa61945790616f97a7Alan Viverette public boolean canApplyTheme() { 1083607bd848269fb802550e63aa61945790616f97a7Alan Viverette return mThemeAttrs != null; 1084607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 1085607bd848269fb802550e63aa61945790616f97a7Alan Viverette 1086a95c8abb366d9c39450513335f550b56da13b30aztenghui public void applyTheme(Theme t) { 1087a95c8abb366d9c39450513335f550b56da13b30aztenghui if (mThemeAttrs == null) { 1088a95c8abb366d9c39450513335f550b56da13b30aztenghui return; 1089a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1090a95c8abb366d9c39450513335f550b56da13b30aztenghui 1091607bd848269fb802550e63aa61945790616f97a7Alan Viverette final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawableGroup); 1092a95c8abb366d9c39450513335f550b56da13b30aztenghui updateStateFromTypedArray(a); 1093a95c8abb366d9c39450513335f550b56da13b30aztenghui a.recycle(); 1094a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1095a95c8abb366d9c39450513335f550b56da13b30aztenghui 1096a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateLocalMatrix() { 1097a95c8abb366d9c39450513335f550b56da13b30aztenghui // The order we apply is the same as the 1098a95c8abb366d9c39450513335f550b56da13b30aztenghui // RenderNode.cpp::applyViewPropertyTransforms(). 1099a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.reset(); 1100a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.postTranslate(-mPivotX, -mPivotY); 1101a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.postScale(mScaleX, mScaleY); 1102a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.postRotate(mRotate, 0, 0); 1103a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY); 1104a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1105a95c8abb366d9c39450513335f550b56da13b30aztenghui 1106a95c8abb366d9c39450513335f550b56da13b30aztenghui /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ 1107a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1108e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getRotation() { 1109e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mRotate; 1110e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1111e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1112a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1113e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setRotation(float rotation) { 1114e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (rotation != mRotate) { 1115e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mRotate = rotation; 1116e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1117e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1118e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1119e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1120a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1121e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getPivotX() { 1122e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPivotX; 1123e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1124e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1125a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1126e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setPivotX(float pivotX) { 1127e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (pivotX != mPivotX) { 1128e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mPivotX = pivotX; 1129e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1130e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1131e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1132e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1133a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1134e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getPivotY() { 1135e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPivotY; 1136e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1137e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1138a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1139e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setPivotY(float pivotY) { 1140e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (pivotY != mPivotY) { 1141e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mPivotY = pivotY; 1142e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1143e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1144e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1145e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1146a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1147e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getScaleX() { 1148e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mScaleX; 1149e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 11504d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1151a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1152e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setScaleX(float scaleX) { 1153e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (scaleX != mScaleX) { 1154e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mScaleX = scaleX; 1155e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1156e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1157e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1158e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1159a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1160e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getScaleY() { 1161e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mScaleY; 1162e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1163e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1164a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1165e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setScaleY(float scaleY) { 1166e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (scaleY != mScaleY) { 1167e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mScaleY = scaleY; 1168e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1169e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1170e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1171e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1172a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1173e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getTranslateX() { 1174e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTranslateX; 1175e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1176e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1177a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1178e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setTranslateX(float translateX) { 1179e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (translateX != mTranslateX) { 1180e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTranslateX = translateX; 1181e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1182e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1183e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1184e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1185a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1186e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getTranslateY() { 1187e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTranslateY; 1188e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1189e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1190a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1191e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setTranslateY(float translateY) { 1192e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (translateY != mTranslateY) { 1193e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTranslateY = translateY; 1194e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1195e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1196e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1197a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1198e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1199a95c8abb366d9c39450513335f550b56da13b30aztenghui /** 1200a95c8abb366d9c39450513335f550b56da13b30aztenghui * Common Path information for clip path and normal path. 1201a95c8abb366d9c39450513335f550b56da13b30aztenghui */ 1202a95c8abb366d9c39450513335f550b56da13b30aztenghui private static class VPath { 1203a95c8abb366d9c39450513335f550b56da13b30aztenghui protected PathParser.PathDataNode[] mNodes = null; 1204a95c8abb366d9c39450513335f550b56da13b30aztenghui String mPathName; 1205a95c8abb366d9c39450513335f550b56da13b30aztenghui int mChangingConfigurations; 1206a95c8abb366d9c39450513335f550b56da13b30aztenghui 1207a95c8abb366d9c39450513335f550b56da13b30aztenghui public VPath() { 1208a95c8abb366d9c39450513335f550b56da13b30aztenghui // Empty constructor. 12094d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 12104d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1211a95c8abb366d9c39450513335f550b56da13b30aztenghui public VPath(VPath copy) { 1212a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathName = copy.mPathName; 1213a95c8abb366d9c39450513335f550b56da13b30aztenghui mChangingConfigurations = copy.mChangingConfigurations; 1214a95c8abb366d9c39450513335f550b56da13b30aztenghui mNodes = PathParser.deepCopyNodes(copy.mNodes); 12154d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 12164d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1217a95c8abb366d9c39450513335f550b56da13b30aztenghui public void toPath(Path path) { 1218a95c8abb366d9c39450513335f550b56da13b30aztenghui path.reset(); 1219a95c8abb366d9c39450513335f550b56da13b30aztenghui if (mNodes != null) { 1220a95c8abb366d9c39450513335f550b56da13b30aztenghui PathParser.PathDataNode.nodesToPath(mNodes, path); 1221a95c8abb366d9c39450513335f550b56da13b30aztenghui } 12224d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 12234d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1224a95c8abb366d9c39450513335f550b56da13b30aztenghui public String getPathName() { 1225a95c8abb366d9c39450513335f550b56da13b30aztenghui return mPathName; 12268e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 12278e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 1228a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean canApplyTheme() { 1229a95c8abb366d9c39450513335f550b56da13b30aztenghui return false; 1230a95c8abb366d9c39450513335f550b56da13b30aztenghui } 123163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1232a95c8abb366d9c39450513335f550b56da13b30aztenghui public void applyTheme(Theme t) { 1233a95c8abb366d9c39450513335f550b56da13b30aztenghui } 123463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1235a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean isClipPath() { 1236a95c8abb366d9c39450513335f550b56da13b30aztenghui return false; 1237a95c8abb366d9c39450513335f550b56da13b30aztenghui } 123863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1239a95c8abb366d9c39450513335f550b56da13b30aztenghui /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ 1240a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1241a95c8abb366d9c39450513335f550b56da13b30aztenghui public PathParser.PathDataNode[] getPathData() { 1242a95c8abb366d9c39450513335f550b56da13b30aztenghui return mNodes; 1243a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1244a95c8abb366d9c39450513335f550b56da13b30aztenghui 1245a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1246a95c8abb366d9c39450513335f550b56da13b30aztenghui public void setPathData(PathParser.PathDataNode[] nodes) { 1247a95c8abb366d9c39450513335f550b56da13b30aztenghui if (!PathParser.canMorph(mNodes, nodes)) { 1248a95c8abb366d9c39450513335f550b56da13b30aztenghui // This should not happen in the middle of animation. 1249a95c8abb366d9c39450513335f550b56da13b30aztenghui mNodes = PathParser.deepCopyNodes(nodes); 1250a95c8abb366d9c39450513335f550b56da13b30aztenghui } else { 1251a95c8abb366d9c39450513335f550b56da13b30aztenghui PathParser.updateNodes(mNodes, nodes); 125263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 1253a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1254a95c8abb366d9c39450513335f550b56da13b30aztenghui } 125563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1256a95c8abb366d9c39450513335f550b56da13b30aztenghui /** 1257a95c8abb366d9c39450513335f550b56da13b30aztenghui * Clip path, which only has name and pathData. 1258a95c8abb366d9c39450513335f550b56da13b30aztenghui */ 1259a95c8abb366d9c39450513335f550b56da13b30aztenghui private static class VClipPath extends VPath{ 1260a95c8abb366d9c39450513335f550b56da13b30aztenghui public VClipPath() { 1261a95c8abb366d9c39450513335f550b56da13b30aztenghui // Empty constructor. 12628e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 12634d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1264a95c8abb366d9c39450513335f550b56da13b30aztenghui public VClipPath(VClipPath copy) { 1265a95c8abb366d9c39450513335f550b56da13b30aztenghui super(copy); 1266a95c8abb366d9c39450513335f550b56da13b30aztenghui } 12674d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1268a95c8abb366d9c39450513335f550b56da13b30aztenghui public void inflate(Resources r, AttributeSet attrs, Theme theme) { 1269a95c8abb366d9c39450513335f550b56da13b30aztenghui final TypedArray a = obtainAttributes(r, theme, attrs, 1270a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawableClipPath); 12718e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 127263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui a.recycle(); 127363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 127463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1275a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateStateFromTypedArray(TypedArray a) { 1276a95c8abb366d9c39450513335f550b56da13b30aztenghui // Account for any configuration changes. 1277a95c8abb366d9c39450513335f550b56da13b30aztenghui mChangingConfigurations |= a.getChangingConfigurations(); 1278a95c8abb366d9c39450513335f550b56da13b30aztenghui 1279a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathName = a.getString(R.styleable.VectorDrawableClipPath_name); 1280a95c8abb366d9c39450513335f550b56da13b30aztenghui mNodes = PathParser.createNodesFromPathData(a.getString( 1281a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawableClipPath_pathData)); 1282a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1283a95c8abb366d9c39450513335f550b56da13b30aztenghui 1284a95c8abb366d9c39450513335f550b56da13b30aztenghui @Override 1285a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean isClipPath() { 1286a95c8abb366d9c39450513335f550b56da13b30aztenghui return true; 12874d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 1288abb7d134c02ac60091108c491dafb00877093170John Hoford } 1289abb7d134c02ac60091108c491dafb00877093170John Hoford 1290a95c8abb366d9c39450513335f550b56da13b30aztenghui /** 1291a95c8abb366d9c39450513335f550b56da13b30aztenghui * Normal path, which contains all the fill / paint information. 1292a95c8abb366d9c39450513335f550b56da13b30aztenghui */ 1293a95c8abb366d9c39450513335f550b56da13b30aztenghui private static class VFullPath extends VPath { 129455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 129555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 12969453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private int[] mThemeAttrs; 12979453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1298a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui int mStrokeColor = Color.TRANSPARENT; 1299abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeWidth = 0; 13002e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui 1301a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui int mFillColor = Color.TRANSPARENT; 13022e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui float mStrokeAlpha = 1.0f; 1303abb7d134c02ac60091108c491dafb00877093170John Hoford int mFillRule; 13042e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui float mFillAlpha = 1.0f; 1305abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathStart = 0; 1306abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathEnd = 1; 1307abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathOffset = 0; 13089453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 13094b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette Paint.Cap mStrokeLineCap = Paint.Cap.BUTT; 13104b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette Paint.Join mStrokeLineJoin = Paint.Join.MITER; 1311abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeMiterlimit = 4; 13129453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1313a95c8abb366d9c39450513335f550b56da13b30aztenghui public VFullPath() { 13149453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette // Empty constructor. 13159453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 13169453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1317a95c8abb366d9c39450513335f550b56da13b30aztenghui public VFullPath(VFullPath copy) { 1318a95c8abb366d9c39450513335f550b56da13b30aztenghui super(copy); 131955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mThemeAttrs = copy.mThemeAttrs; 132055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 132155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeColor = copy.mStrokeColor; 132255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeWidth = copy.mStrokeWidth; 13232e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mStrokeAlpha = copy.mStrokeAlpha; 132455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillColor = copy.mFillColor; 132555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillRule = copy.mFillRule; 13262e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mFillAlpha = copy.mFillAlpha; 132755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathStart = copy.mTrimPathStart; 132855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathEnd = copy.mTrimPathEnd; 132955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathOffset = copy.mTrimPathOffset; 133055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 133155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeLineCap = copy.mStrokeLineCap; 133255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeLineJoin = copy.mStrokeLineJoin; 133355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeMiterlimit = copy.mStrokeMiterlimit; 1334abb7d134c02ac60091108c491dafb00877093170John Hoford } 1335abb7d134c02ac60091108c491dafb00877093170John Hoford 13367f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette private Paint.Cap getStrokeLineCap(int id, Paint.Cap defValue) { 13377f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette switch (id) { 13387f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_BUTT: 13397f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.BUTT; 13407f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_ROUND: 13417f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.ROUND; 13427f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_SQUARE: 13437f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.SQUARE; 13447f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette default: 13457f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return defValue; 13467f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 13477f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 13487f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette 13497f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette private Paint.Join getStrokeLineJoin(int id, Paint.Join defValue) { 13507f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette switch (id) { 13517f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_MITER: 13527f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.MITER; 13537f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_ROUND: 13547f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.ROUND; 13557f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_BEVEL: 13567f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.BEVEL; 13577f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette default: 13587f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return defValue; 13597f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 13607f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 13617f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette 1362a95c8abb366d9c39450513335f550b56da13b30aztenghui @Override 1363a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean canApplyTheme() { 1364a95c8abb366d9c39450513335f550b56da13b30aztenghui return mThemeAttrs != null; 1365eb034fbca40006c55db143047eb628c4b657730aztenghui } 1366eb034fbca40006c55db143047eb628c4b657730aztenghui 1367a95c8abb366d9c39450513335f550b56da13b30aztenghui public void inflate(Resources r, AttributeSet attrs, Theme theme) { 1368a95c8abb366d9c39450513335f550b56da13b30aztenghui final TypedArray a = obtainAttributes(r, theme, attrs, 1369a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath); 1370a95c8abb366d9c39450513335f550b56da13b30aztenghui updateStateFromTypedArray(a); 1371a95c8abb366d9c39450513335f550b56da13b30aztenghui a.recycle(); 1372a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1373a95c8abb366d9c39450513335f550b56da13b30aztenghui 1374a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateStateFromTypedArray(TypedArray a) { 1375a95c8abb366d9c39450513335f550b56da13b30aztenghui // Account for any configuration changes. 1376a95c8abb366d9c39450513335f550b56da13b30aztenghui mChangingConfigurations |= a.getChangingConfigurations(); 1377a95c8abb366d9c39450513335f550b56da13b30aztenghui 1378a95c8abb366d9c39450513335f550b56da13b30aztenghui // Extract the theme attributes, if any. 1379a95c8abb366d9c39450513335f550b56da13b30aztenghui mThemeAttrs = a.extractThemeAttrs(); 1380a95c8abb366d9c39450513335f550b56da13b30aztenghui 1381a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathName = a.getString(R.styleable.VectorDrawablePath_name); 1382a95c8abb366d9c39450513335f550b56da13b30aztenghui mNodes = PathParser.createNodesFromPathData(a.getString( 1383a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_pathData)); 1384a95c8abb366d9c39450513335f550b56da13b30aztenghui 1385a95c8abb366d9c39450513335f550b56da13b30aztenghui mFillColor = a.getColor(R.styleable.VectorDrawablePath_fillColor, 1386a95c8abb366d9c39450513335f550b56da13b30aztenghui mFillColor); 13872e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mFillAlpha = a.getFloat(R.styleable.VectorDrawablePath_fillAlpha, 13882e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mFillAlpha); 1389a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeLineCap = getStrokeLineCap(a.getInt( 1390a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_strokeLineCap, -1), mStrokeLineCap); 1391a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeLineJoin = getStrokeLineJoin(a.getInt( 1392a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_strokeLineJoin, -1), mStrokeLineJoin); 1393a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeMiterlimit = a.getFloat( 1394a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_strokeMiterLimit, mStrokeMiterlimit); 1395a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_strokeColor, 1396a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeColor); 13972e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mStrokeAlpha = a.getFloat(R.styleable.VectorDrawablePath_strokeAlpha, 13982e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mStrokeAlpha); 1399a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, 1400a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeWidth); 1401a95c8abb366d9c39450513335f550b56da13b30aztenghui mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd, 1402a95c8abb366d9c39450513335f550b56da13b30aztenghui mTrimPathEnd); 1403a95c8abb366d9c39450513335f550b56da13b30aztenghui mTrimPathOffset = a.getFloat( 1404a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_trimPathOffset, mTrimPathOffset); 1405a95c8abb366d9c39450513335f550b56da13b30aztenghui mTrimPathStart = a.getFloat( 1406a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_trimPathStart, mTrimPathStart); 1407a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1408a95c8abb366d9c39450513335f550b56da13b30aztenghui 1409a95c8abb366d9c39450513335f550b56da13b30aztenghui @Override 1410a95c8abb366d9c39450513335f550b56da13b30aztenghui public void applyTheme(Theme t) { 1411a95c8abb366d9c39450513335f550b56da13b30aztenghui if (mThemeAttrs == null) { 1412a95c8abb366d9c39450513335f550b56da13b30aztenghui return; 1413a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1414a95c8abb366d9c39450513335f550b56da13b30aztenghui 1415607bd848269fb802550e63aa61945790616f97a7Alan Viverette final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawablePath); 1416a95c8abb366d9c39450513335f550b56da13b30aztenghui updateStateFromTypedArray(a); 1417a95c8abb366d9c39450513335f550b56da13b30aztenghui a.recycle(); 1418a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1419a95c8abb366d9c39450513335f550b56da13b30aztenghui 1420a95c8abb366d9c39450513335f550b56da13b30aztenghui /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ 1421eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1422e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui int getStroke() { 1423e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeColor; 1424e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1425e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1426eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1427e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setStroke(int strokeColor) { 1428e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeColor = strokeColor; 1429e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1430e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1431eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1432e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getStrokeWidth() { 1433e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeWidth; 1434e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1435e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1436eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1437e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setStrokeWidth(float strokeWidth) { 1438e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeWidth = strokeWidth; 1439e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1440e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1441eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 14422e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui float getstrokeAlpha() { 14432e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui return mStrokeAlpha; 14442e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui } 14452e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui 14462e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui @SuppressWarnings("unused") 14472e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui void setstrokeAlpha(float strokeAlpha) { 14482e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mStrokeAlpha = strokeAlpha; 14492e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui } 14502e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui 14512e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui @SuppressWarnings("unused") 1452e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui int getFill() { 1453e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mFillColor; 1454e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1455e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1456eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1457e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setFill(int fillColor) { 1458e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mFillColor = fillColor; 1459e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1460e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1461eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 14622e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui float getfillAlpha() { 14632e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui return mFillAlpha; 14642e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui } 14652e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui 14662e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui @SuppressWarnings("unused") 14672e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui void setfillAlpha(float fillAlpha) { 14682e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mFillAlpha = fillAlpha; 14692e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui } 14702e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui 14712e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui @SuppressWarnings("unused") 1472e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathStart() { 1473e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathStart; 1474e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1475e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1476eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1477e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathStart(float trimPathStart) { 1478e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathStart = trimPathStart; 1479e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1480e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1481eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1482e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathEnd() { 1483e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathEnd; 1484e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1485e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1486eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1487e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathEnd(float trimPathEnd) { 1488e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathEnd = trimPathEnd; 1489e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1490e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1491eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1492e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathOffset() { 1493e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathOffset; 1494e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1495e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1496eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1497e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathOffset(float trimPathOffset) { 1498e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathOffset = trimPathOffset; 1499e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1500abb7d134c02ac60091108c491dafb00877093170John Hoford } 1501abb7d134c02ac60091108c491dafb00877093170John Hoford} 1502