VectorDrawable.java revision 9d59a76dd0e850558e83ef1a48fefd865fac1336
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/** 52d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * 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/> 57abb7d134c02ac60091108c491dafb00877093170John Hoford * <dl> 58177dffd869ff1f5bdf816faead01a7dc4980bf75ztenghui * <dt><code><vector></code></dt> 59e3c45e7a6b2a7d2176aa46ee482e299b54feeb9fztenghui * <dd>Used to defined a vector drawable</dd> 60abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code><size></code></dt> 61abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Used to defined the intrinsic Width Height size of the drawable using 62d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <code>android:width</code> and <code>android:height</code></dd> 63abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code><viewport></code></dt> 64abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Used to defined the size of the virtual canvas the paths are drawn on. 65d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * The size is defined using the attributes <code>android:viewportHeight</code> 66d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <code>android:viewportWidth</code></dd> 676d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dt><code><group></code></dt> 68452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>Defines a group of paths or subgroups, plus transformation information. 69452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * The transformations are defined in the same coordinates as the viewport. 70452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * And the transformations are applied in the order of scale, rotate then translate. </dd> 71452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:rotation</code> 72452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The degrees of rotation of the group.</dd></dt> 73452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:pivotX</code> 74452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The X coordinate of the pivot for the scale and rotation of the group</dd></dt> 75452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:pivotY</code> 76452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The Y coordinate of the pivot for the scale and rotation of the group</dd></dt> 77452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:scaleX</code> 78452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The amount of scale on the X Coordinate</dd></dt> 79452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:scaleY</code> 80452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The amount of scale on the Y coordinate</dd></dt> 81452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:translateX</code> 82452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The amount of translation on the X coordinate</dd></dt> 83452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:translateY</code> 84452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The amount of translation on the Y coordinate</dd></dt> 85abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code><path></code></dt> 866d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dd>Defines paths to be drawn. 87abb7d134c02ac60091108c491dafb00877093170John Hoford * <dl> 88abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:name</code> 89abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Defines the name of the path.</dd></dt> 90abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:pathData</code> 9146e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * <dd>Defines path string. This is using exactly same format as "d" attribute 9246e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * in the SVG's path data</dd></dt> 93abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:fill</code> 94abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Defines the color to fill the path (none if not present).</dd></dt> 95abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:stroke</code> 96d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <dd>Defines the color to draw the path outline (none if not present).</dd> 97d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * </dt> 98abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeWidth</code> 99abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The width a path stroke</dd></dt> 100abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeOpacity</code> 101abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The opacity of a path stroke</dd></dt> 102abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:fillOpacity</code> 103abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The opacity to fill the path with</dd></dt> 104abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:trimPathStart</code> 105abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The fraction of the path to trim from the start from 0 to 1</dd></dt> 106abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:trimPathEnd</code> 107abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The fraction of the path to trim from the end from 0 to 1</dd></dt> 108abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:trimPathOffset</code> 109d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <dd>Shift trim region (allows showed region to include the start and end) 110d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * from 0 to 1</dd></dt> 111abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:clipToPath</code> 112abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Path will set the clip path</dd></dt> 113abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeLineCap</code> 114abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Sets the linecap for a stroked path: butt, round, square</dd></dt> 115abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeLineJoin</code> 116abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Sets the lineJoin for a stroked path: miter,round,bevel</dd></dt> 117abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeMiterLimit</code> 118abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Sets the Miter limit for a stroked path</dd></dt> 119abb7d134c02ac60091108c491dafb00877093170John Hoford * </dl> 120abb7d134c02ac60091108c491dafb00877093170John Hoford * </dd> 121abb7d134c02ac60091108c491dafb00877093170John Hoford */ 122abb7d134c02ac60091108c491dafb00877093170John Hofordpublic class VectorDrawable extends Drawable { 1239453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private static final String LOGTAG = VectorDrawable.class.getSimpleName(); 1249453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 125abb7d134c02ac60091108c491dafb00877093170John Hoford private static final String SHAPE_SIZE = "size"; 126abb7d134c02ac60091108c491dafb00877093170John Hoford private static final String SHAPE_VIEWPORT = "viewport"; 1276d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui private static final String SHAPE_GROUP = "group"; 128abb7d134c02ac60091108c491dafb00877093170John Hoford private static final String SHAPE_PATH = "path"; 129abb7d134c02ac60091108c491dafb00877093170John Hoford private static final String SHAPE_VECTOR = "vector"; 130abb7d134c02ac60091108c491dafb00877093170John Hoford 131abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_BUTT = 0; 132abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_ROUND = 1; 133abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_SQUARE = 2; 1349453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 135abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_MITER = 0; 136abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_ROUND = 1; 137abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_BEVEL = 2; 1389453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1394d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private static final boolean DBG_VECTOR_DRAWABLE = false; 1404d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 14155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private VectorDrawableState mVectorState; 142e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 143b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette private PorterDuffColorFilter mTintFilter; 144b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 14555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private boolean mMutated; 14655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 147482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // AnimatedVectorDrawable needs to turn off the cache all the time, otherwise, 148482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // caching the bitmap by default is allowed. 149482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui private boolean mAllowCaching = true; 150482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 151abb7d134c02ac60091108c491dafb00877093170John Hoford public VectorDrawable() { 15255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState = new VectorDrawableState(); 153abb7d134c02ac60091108c491dafb00877093170John Hoford } 154abb7d134c02ac60091108c491dafb00877093170John Hoford 1559453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private VectorDrawable(VectorDrawableState state, Resources res, Theme theme) { 15616c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui if (theme != null && state.canApplyTheme()) { 15716c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui // If we need to apply a theme, implicitly mutate. 15816c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui mVectorState = new VectorDrawableState(state); 1599453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette applyTheme(theme); 16016c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui } else { 16116c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui mVectorState = state; 1629453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 163b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 164b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 165b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mVectorState.mVPathRenderer.setColorFilter(mTintFilter); 166abb7d134c02ac60091108c491dafb00877093170John Hoford } 167abb7d134c02ac60091108c491dafb00877093170John Hoford 16855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui @Override 16955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public Drawable mutate() { 17055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (!mMutated && super.mutate() == this) { 17155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState = new VectorDrawableState(mVectorState); 17255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mMutated = true; 17355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 17455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return this; 17555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 17655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 177e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui Object getTargetByName(String name) { 17855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return mVectorState.mVPathRenderer.mVGTargetsMap.get(name); 179e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 180e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 181abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 182abb7d134c02ac60091108c491dafb00877093170John Hoford public ConstantState getConstantState() { 18355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState.mChangingConfigurations = getChangingConfigurations(); 18455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return mVectorState; 185abb7d134c02ac60091108c491dafb00877093170John Hoford } 186abb7d134c02ac60091108c491dafb00877093170John Hoford 1874554a6a5137d8e9bdfb623ad84ff344a48b7eb9dAlan Viverette @Override 188abb7d134c02ac60091108c491dafb00877093170John Hoford public void draw(Canvas canvas) { 1894b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette final int saveCount = canvas.save(); 1904b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette final Rect bounds = getBounds(); 191738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui final boolean needMirroring = needMirroring(); 192738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 1934b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette canvas.translate(bounds.left, bounds.top); 194738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui if (needMirroring) { 195738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui canvas.translate(bounds.width(), 0); 196738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui canvas.scale(-1.0f, 1.0f); 197738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 198482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 199482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui if (!mAllowCaching) { 200482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mVectorState.mVPathRenderer.draw(canvas, bounds.width(), bounds.height()); 201482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } else { 202482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Bitmap bitmap = mVectorState.mCachedBitmap; 203482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui if (bitmap == null || !mVectorState.canReuseCache(bounds.width(), 204482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui bounds.height())) { 205482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui bitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), 206482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Bitmap.Config.ARGB_8888); 207482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Canvas tmpCanvas = new Canvas(bitmap); 208482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mVectorState.mVPathRenderer.draw(tmpCanvas, bounds.width(), bounds.height()); 209482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mVectorState.mCachedBitmap = bitmap; 210482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 211482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mVectorState.updateCacheStates(); 212482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 213482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui canvas.drawBitmap(bitmap, null, bounds, null); 214482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 215738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 2164b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette canvas.restoreToCount(saveCount); 217abb7d134c02ac60091108c491dafb00877093170John Hoford } 218abb7d134c02ac60091108c491dafb00877093170John Hoford 219abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 220e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public int getAlpha() { 221e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mVectorState.mVPathRenderer.getRootAlpha(); 222e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 223e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 224e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 225abb7d134c02ac60091108c491dafb00877093170John Hoford public void setAlpha(int alpha) { 2262af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui if (mVectorState.mVPathRenderer.getRootAlpha() != alpha) { 2272af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mVectorState.mVPathRenderer.setRootAlpha(alpha); 228abb7d134c02ac60091108c491dafb00877093170John Hoford invalidateSelf(); 229abb7d134c02ac60091108c491dafb00877093170John Hoford } 230abb7d134c02ac60091108c491dafb00877093170John Hoford } 231abb7d134c02ac60091108c491dafb00877093170John Hoford 232abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 233abb7d134c02ac60091108c491dafb00877093170John Hoford public void setColorFilter(ColorFilter colorFilter) { 234b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final VectorDrawableState state = mVectorState; 235b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if (colorFilter != null) { 236b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette // Color filter overrides tint. 237b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = null; 238b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } else if (state.mTint != null && state.mTintMode != null) { 239b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette // Restore the tint filter, if we need one. 240b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final int color = state.mTint.getColorForState(getState(), Color.TRANSPARENT); 241b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = new PorterDuffColorFilter(color, state.mTintMode); 242b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette colorFilter = mTintFilter; 243b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 244b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 245b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette state.mVPathRenderer.setColorFilter(colorFilter); 246fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette invalidateSelf(); 247abb7d134c02ac60091108c491dafb00877093170John Hoford } 248abb7d134c02ac60091108c491dafb00877093170John Hoford 249abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 250b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette public void setTint(ColorStateList tint, Mode tintMode) { 251b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final VectorDrawableState state = mVectorState; 252b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if (state.mTint != tint || state.mTintMode != tintMode) { 253b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette state.mTint = tint; 254b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette state.mTintMode = tintMode; 255b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 256b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = updateTintFilter(mTintFilter, tint, tintMode); 257b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mVectorState.mVPathRenderer.setColorFilter(mTintFilter); 258b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette invalidateSelf(); 259b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 260b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 261b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 262b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 263b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette protected boolean onStateChange(int[] stateSet) { 264b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final VectorDrawableState state = mVectorState; 265b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if (state.mTint != null && state.mTintMode != null) { 266b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 267b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mVectorState.mVPathRenderer.setColorFilter(mTintFilter); 268b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette return true; 269b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 270b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette return false; 271b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 272b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 273b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 274abb7d134c02ac60091108c491dafb00877093170John Hoford public int getOpacity() { 275abb7d134c02ac60091108c491dafb00877093170John Hoford return PixelFormat.TRANSLUCENT; 276abb7d134c02ac60091108c491dafb00877093170John Hoford } 277abb7d134c02ac60091108c491dafb00877093170John Hoford 278abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 279abb7d134c02ac60091108c491dafb00877093170John Hoford public int getIntrinsicWidth() { 280ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui return (int) mVectorState.mVPathRenderer.mBaseWidth; 281abb7d134c02ac60091108c491dafb00877093170John Hoford } 282abb7d134c02ac60091108c491dafb00877093170John Hoford 283abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 284abb7d134c02ac60091108c491dafb00877093170John Hoford public int getIntrinsicHeight() { 285ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui return (int) mVectorState.mVPathRenderer.mBaseHeight; 286abb7d134c02ac60091108c491dafb00877093170John Hoford } 287abb7d134c02ac60091108c491dafb00877093170John Hoford 288abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 2899453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public boolean canApplyTheme() { 2909453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette return super.canApplyTheme() || mVectorState != null && mVectorState.canApplyTheme(); 2919453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 2929453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 2939453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette @Override 2949453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public void applyTheme(Theme t) { 2959453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette super.applyTheme(t); 2969453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 2979453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final VectorDrawableState state = mVectorState; 298ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui final VPathRenderer path = state.mVPathRenderer; 2999453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette if (path != null && path.canApplyTheme()) { 3009453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette path.applyTheme(t); 3019453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 3029453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 3039453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 3044b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette /** @hide */ 3054b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette public static VectorDrawable create(Resources resources, int rid) { 3064b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette try { 3074b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette final XmlPullParser xpp = resources.getXml(rid); 3084b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette final AttributeSet attrs = Xml.asAttributeSet(xpp); 3094b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette final XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); 3104b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette factory.setNamespaceAware(true); 3114b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 3124b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette final VectorDrawable drawable = new VectorDrawable(); 3134b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette drawable.inflate(resources, xpp, attrs); 3144b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 3154b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette return drawable; 3164b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } catch (XmlPullParserException e) { 3174b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette Log.e(LOGTAG, "parser error", e); 3184b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } catch (IOException e) { 3194b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette Log.e(LOGTAG, "parser error", e); 3204b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } 3214b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette return null; 3224b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } 3234b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 3242af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui private static int applyAlpha(int color, float alpha) { 3252af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui int alphaBytes = Color.alpha(color); 3262af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui color &= 0x00FFFFFF; 3272af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui color |= ((int) (alphaBytes * alpha)) << 24; 3282af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui return color; 3292af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 3302af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 3319cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette @Override 3329cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme) 3339cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette throws XmlPullParserException, IOException { 3348d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final TypedArray a = obtainAttributes(res, theme, attrs, R.styleable.VectorDrawable); 3359cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette updateStateFromTypedArray(a); 3369cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette a.recycle(); 3379cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3389cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final VectorDrawableState state = mVectorState; 339670689af43358568bf2b5916284f1cac5762f428ztenghui mVectorState.mCacheDirty = true; 34055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui inflateInternal(res, parser, attrs, theme); 3419cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3429cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 3439cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mVPathRenderer.setColorFilter(mTintFilter); 3449cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 3459cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3469cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette private void updateStateFromTypedArray(TypedArray a) { 3479cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final VectorDrawableState state = mVectorState; 3489cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3498e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 3508e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= a.getChangingConfigurations(); 3518e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 3529cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette // Extract the theme attributes, if any. 3539cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mThemeAttrs = a.extractThemeAttrs(); 3549cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3559cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final int tintMode = a.getInt(R.styleable.VectorDrawable_tintMode, -1); 3569cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette if (tintMode != -1) { 3579cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN); 3589cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 3599cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3609cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final ColorStateList tint = a.getColorStateList(R.styleable.VectorDrawable_tint); 3619cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette if (tint != null) { 3629cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mTint = tint; 3639cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 364738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 365738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui state.mAutoMirrored = a.getBoolean( 366738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui R.styleable.VectorDrawable_autoMirrored, state.mAutoMirrored); 3679cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 3689cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 36955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private void inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs, 3708e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette Theme theme) throws XmlPullParserException, IOException { 3718e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final VectorDrawableState state = mVectorState; 372ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui final VPathRenderer pathRenderer = new VPathRenderer(); 37355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui state.mVPathRenderer = pathRenderer; 3749453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 375abb7d134c02ac60091108c491dafb00877093170John Hoford boolean noSizeTag = true; 376abb7d134c02ac60091108c491dafb00877093170John Hoford boolean noViewportTag = true; 377abb7d134c02ac60091108c491dafb00877093170John Hoford boolean noPathTag = true; 3789453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 3794d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Use a stack to help to build the group tree. 3804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // The top of the stack is always the current group. 3814d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final Stack<VGroup> groupStack = new Stack<VGroup>(); 3824d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.push(pathRenderer.mRootGroup); 383abb7d134c02ac60091108c491dafb00877093170John Hoford 384abb7d134c02ac60091108c491dafb00877093170John Hoford int eventType = parser.getEventType(); 385abb7d134c02ac60091108c491dafb00877093170John Hoford while (eventType != XmlPullParser.END_DOCUMENT) { 386abb7d134c02ac60091108c491dafb00877093170John Hoford if (eventType == XmlPullParser.START_TAG) { 3879453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final String tagName = parser.getName(); 3884d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final VGroup currentGroup = groupStack.peek(); 3894d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 390abb7d134c02ac60091108c491dafb00877093170John Hoford if (SHAPE_PATH.equals(tagName)) { 3919453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final VPath path = new VPath(); 3929453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette path.inflate(res, attrs, theme); 3938d0d24f7a2b1a59060aa18926984491691d3c667ztenghui currentGroup.mChildren.add(path); 394e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (path.getPathName() != null) { 39555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui pathRenderer.mVGTargetsMap.put(path.getPathName(), path); 396e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 397abb7d134c02ac60091108c491dafb00877093170John Hoford noPathTag = false; 3988e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= path.mChangingConfigurations; 399abb7d134c02ac60091108c491dafb00877093170John Hoford } else if (SHAPE_SIZE.equals(tagName)) { 400ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui pathRenderer.parseSize(res, attrs); 401abb7d134c02ac60091108c491dafb00877093170John Hoford noSizeTag = false; 4028e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= pathRenderer.mChangingConfigurations; 403abb7d134c02ac60091108c491dafb00877093170John Hoford } else if (SHAPE_VIEWPORT.equals(tagName)) { 404ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui pathRenderer.parseViewport(res, attrs); 405abb7d134c02ac60091108c491dafb00877093170John Hoford noViewportTag = false; 4068e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= pathRenderer.mChangingConfigurations; 4076d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui } else if (SHAPE_GROUP.equals(tagName)) { 4084d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui VGroup newChildGroup = new VGroup(); 4094d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui newChildGroup.inflate(res, attrs, theme); 4108d0d24f7a2b1a59060aa18926984491691d3c667ztenghui currentGroup.mChildren.add(newChildGroup); 4114d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.push(newChildGroup); 412e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (newChildGroup.getGroupName() != null) { 41355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui pathRenderer.mVGTargetsMap.put(newChildGroup.getGroupName(), 41455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui newChildGroup); 415e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 4168e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= newChildGroup.mChangingConfigurations; 417abb7d134c02ac60091108c491dafb00877093170John Hoford } 4184d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } else if (eventType == XmlPullParser.END_TAG) { 4194d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final String tagName = parser.getName(); 4204d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui if (SHAPE_GROUP.equals(tagName)) { 4214d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.pop(); 4224d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 423abb7d134c02ac60091108c491dafb00877093170John Hoford } 424abb7d134c02ac60091108c491dafb00877093170John Hoford eventType = parser.next(); 425abb7d134c02ac60091108c491dafb00877093170John Hoford } 4269453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 4274d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Print the tree out for debug. 4284d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui if (DBG_VECTOR_DRAWABLE) { 4294d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui printGroupTree(pathRenderer.mRootGroup, 0); 4306d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui } 4316d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui 43246e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui if (noSizeTag || noViewportTag || noPathTag) { 4339453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final StringBuffer tag = new StringBuffer(); 4349453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 435abb7d134c02ac60091108c491dafb00877093170John Hoford if (noSizeTag) { 4369453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette tag.append(SHAPE_SIZE); 437abb7d134c02ac60091108c491dafb00877093170John Hoford } 4389453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 439d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette if (noViewportTag) { 440d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette if (tag.length() > 0) { 441abb7d134c02ac60091108c491dafb00877093170John Hoford tag.append(" & "); 442abb7d134c02ac60091108c491dafb00877093170John Hoford } 4439453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette tag.append(SHAPE_SIZE); 444abb7d134c02ac60091108c491dafb00877093170John Hoford } 4459453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 446d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette if (noPathTag) { 447d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette if (tag.length() > 0) { 448abb7d134c02ac60091108c491dafb00877093170John Hoford tag.append(" or "); 449abb7d134c02ac60091108c491dafb00877093170John Hoford } 4509453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette tag.append(SHAPE_PATH); 451abb7d134c02ac60091108c491dafb00877093170John Hoford } 4529453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 4539453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette throw new XmlPullParserException("no " + tag + " defined"); 454abb7d134c02ac60091108c491dafb00877093170John Hoford } 455abb7d134c02ac60091108c491dafb00877093170John Hoford } 456abb7d134c02ac60091108c491dafb00877093170John Hoford 4574d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void printGroupTree(VGroup currentGroup, int level) { 4584d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui String indent = ""; 4598d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < level; i++) { 4604d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui indent += " "; 4614d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 4624d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Print the current node 4638d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Log.v(LOGTAG, indent + "current group is :" + currentGroup.getGroupName() 4644d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui + " rotation is " + currentGroup.mRotate); 4658d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString()); 4668d0d24f7a2b1a59060aa18926984491691d3c667ztenghui // Then print all the children groups 4678d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < currentGroup.mChildren.size(); i++) { 4688d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = currentGroup.mChildren.get(i); 4698d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 4708d0d24f7a2b1a59060aa18926984491691d3c667ztenghui printGroupTree((VGroup) child, level + 1); 4718d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 4724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 4734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 4744d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 47555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui @Override 47655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public int getChangingConfigurations() { 47755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return super.getChangingConfigurations() | mVectorState.mChangingConfigurations; 47855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 47955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 480482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui void setAllowCaching(boolean allowCaching) { 481482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mAllowCaching = allowCaching; 482482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 483482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 484738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui private boolean needMirroring() { 485738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui return isAutoMirrored() && getLayoutDirection() == LayoutDirection.RTL; 486738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 487738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 488738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui @Override 489738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui public void setAutoMirrored(boolean mirrored) { 490738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui if (mVectorState.mAutoMirrored != mirrored) { 491738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui mVectorState.mAutoMirrored = mirrored; 492738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui invalidateSelf(); 493738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 494738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 495738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 496738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui @Override 497738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui public boolean isAutoMirrored() { 498738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui return mVectorState.mAutoMirrored; 499738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 500738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 5015c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette private static class VectorDrawableState extends ConstantState { 5029cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette int[] mThemeAttrs; 5035c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette int mChangingConfigurations; 504ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui VPathRenderer mVPathRenderer; 505b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette ColorStateList mTint; 506b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette Mode mTintMode; 507738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui boolean mAutoMirrored; 5085c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 509482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Bitmap mCachedBitmap; 510482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui int[] mCachedThemeAttrs; 511482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui ColorStateList mCachedTint; 512482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Mode mCachedTintMode; 513482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui int mCachedRootAlpha; 514670689af43358568bf2b5916284f1cac5762f428ztenghui boolean mCachedAutoMirrored; 515670689af43358568bf2b5916284f1cac5762f428ztenghui boolean mCacheDirty; 516482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 51755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Deep copy for mutate() or implicitly mutate. 5185c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public VectorDrawableState(VectorDrawableState copy) { 5195c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette if (copy != null) { 5209cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette mThemeAttrs = copy.mThemeAttrs; 5215c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette mChangingConfigurations = copy.mChangingConfigurations; 522ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui mVPathRenderer = new VPathRenderer(copy.mVPathRenderer); 523b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTint = copy.mTint; 524b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintMode = copy.mTintMode; 525738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui mAutoMirrored = copy.mAutoMirrored; 5265c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 5275c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 5285c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 529482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui public boolean canReuseCache(int width, int height) { 530670689af43358568bf2b5916284f1cac5762f428ztenghui if (!mCacheDirty 531670689af43358568bf2b5916284f1cac5762f428ztenghui && mCachedThemeAttrs == mThemeAttrs 532482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && mCachedTint == mTint 533482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && mCachedTintMode == mTintMode 534670689af43358568bf2b5916284f1cac5762f428ztenghui && mCachedAutoMirrored == mAutoMirrored 535482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && width == mCachedBitmap.getWidth() 536482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && height == mCachedBitmap.getHeight() 537482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && mCachedRootAlpha == mVPathRenderer.getRootAlpha()) { 538482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui return true; 539482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 540482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui return false; 541482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 542482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 543482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui public void updateCacheStates() { 544482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // Use shallow copy here and shallow comparison in canReuseCache(), 545482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // likely hit cache miss more, but practically not much difference. 546482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedThemeAttrs = mThemeAttrs; 547482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedTint = mTint; 548482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedTintMode = mTintMode; 549482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedRootAlpha = mVPathRenderer.getRootAlpha(); 550670689af43358568bf2b5916284f1cac5762f428ztenghui mCachedAutoMirrored = mAutoMirrored; 551670689af43358568bf2b5916284f1cac5762f428ztenghui mCacheDirty = false; 552482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 553482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 55455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VectorDrawableState() { 55555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVPathRenderer = new VPathRenderer(); 55655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 55755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 5585c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 5595c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable() { 5605c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, null, null); 5615c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 5625c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 5635c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 5645c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable(Resources res) { 5655c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, res, null); 5665c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 5675c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 5685c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 5695c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable(Resources res, Theme theme) { 5705c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, res, theme); 5715c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 5725c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 5735c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 5745c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public int getChangingConfigurations() { 5755c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return mChangingConfigurations; 5765c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 5775c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 5785c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 579ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui private static class VPathRenderer { 5804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui /* Right now the internal data structure is organized as a tree. 5814d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Each node can be a group node, or a path. 5824d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * A group node can have groups or paths as children, but a path node has 5834d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * no children. 5844d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * One example can be: 5854d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Root Group 5864d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * / | \ 5874d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Group Path Group 5884d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * / \ | 5894d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Path Path Path 5904d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * 5914d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui */ 59255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables that only used temporarily inside the draw() call, so there 59355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // is no need for deep copying. 5944b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private final Path mPath = new Path(); 5954b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private final Path mRenderPath = new Path(); 5964d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private static final Matrix IDENTITY_MATRIX = new Matrix(); 59755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final Matrix mFinalPathMatrix = new Matrix(); 5984b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 5994b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private Paint mStrokePaint; 6004b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private Paint mFillPaint; 601fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette private ColorFilter mColorFilter; 602abb7d134c02ac60091108c491dafb00877093170John Hoford private PathMeasure mPathMeasure; 6034b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 60455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 60555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 6068e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private int mChangingConfigurations; 60755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final VGroup mRootGroup; 6084d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private float mBaseWidth = 0; 6094d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private float mBaseHeight = 0; 6104d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private float mViewportWidth = 0; 6114d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private float mViewportHeight = 0; 6122af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui private int mRootAlpha = 0xFF; 6139453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 61455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>(); 615abb7d134c02ac60091108c491dafb00877093170John Hoford 616ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui public VPathRenderer() { 6174d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mRootGroup = new VGroup(); 618abb7d134c02ac60091108c491dafb00877093170John Hoford } 6199453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 6202af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui public void setRootAlpha(int alpha) { 6212af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mRootAlpha = alpha; 6222af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 6232af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 6242af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui public int getRootAlpha() { 6252af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui return mRootAlpha; 6262af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 6272af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 628ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui public VPathRenderer(VPathRenderer copy) { 62955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap); 630abb7d134c02ac60091108c491dafb00877093170John Hoford mBaseWidth = copy.mBaseWidth; 631abb7d134c02ac60091108c491dafb00877093170John Hoford mBaseHeight = copy.mBaseHeight; 632abb7d134c02ac60091108c491dafb00877093170John Hoford mViewportWidth = copy.mViewportHeight; 633abb7d134c02ac60091108c491dafb00877093170John Hoford mViewportHeight = copy.mViewportHeight; 6348e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations = copy.mChangingConfigurations; 63555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRootAlpha = copy.mRootAlpha; 636abb7d134c02ac60091108c491dafb00877093170John Hoford } 637abb7d134c02ac60091108c491dafb00877093170John Hoford 6389453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public boolean canApplyTheme() { 6394d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // If one of the paths can apply theme, then return true; 6404d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui return recursiveCanApplyTheme(mRootGroup); 6414d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6424d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 6434d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private boolean recursiveCanApplyTheme(VGroup currentGroup) { 6444d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // We can do a tree traverse here, if there is one path return true, 6454d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // then we return true for the whole tree. 6468d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = currentGroup.mChildren; 6478d0d24f7a2b1a59060aa18926984491691d3c667ztenghui 6488d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 6498d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = children.get(i); 6508d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 6518d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 6528d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childGroup.canApplyTheme() 6538d0d24f7a2b1a59060aa18926984491691d3c667ztenghui || recursiveCanApplyTheme(childGroup)) { 6548d0d24f7a2b1a59060aa18926984491691d3c667ztenghui return true; 6558d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 6568d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 6578d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 6588d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childPath.canApplyTheme()) { 6598d0d24f7a2b1a59060aa18926984491691d3c667ztenghui return true; 6608d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 6614d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6624d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6639453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette return false; 6649453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 6659453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 6669453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public void applyTheme(Theme t) { 6674d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Apply theme to every path of the tree. 6684d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui recursiveApplyTheme(mRootGroup, t); 6694d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6704d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 6714d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void recursiveApplyTheme(VGroup currentGroup, Theme t) { 6724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // We can do a tree traverse here, apply theme to all paths which 6734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // can apply theme. 6748d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = currentGroup.mChildren; 6758d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 6768d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = children.get(i); 6778d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 6788d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 6798d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childGroup.canApplyTheme()) { 6808d0d24f7a2b1a59060aa18926984491691d3c667ztenghui childGroup.applyTheme(t); 6818d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 6828d0d24f7a2b1a59060aa18926984491691d3c667ztenghui recursiveApplyTheme(childGroup, t); 6838d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 6848d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 6858d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childPath.canApplyTheme()) { 6868d0d24f7a2b1a59060aa18926984491691d3c667ztenghui childPath.applyTheme(t); 6878d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 6884d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6894d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 690abb7d134c02ac60091108c491dafb00877093170John Hoford } 691abb7d134c02ac60091108c491dafb00877093170John Hoford 692fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette public void setColorFilter(ColorFilter colorFilter) { 693fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mColorFilter = colorFilter; 694fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 695fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette if (mFillPaint != null) { 696fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mFillPaint.setColorFilter(colorFilter); 697fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } 698fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 699fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette if (mStrokePaint != null) { 700fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mStrokePaint.setColorFilter(colorFilter); 701fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } 7026d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui 703fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } 704fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 7054d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void drawGroupTree(VGroup currentGroup, Matrix currentMatrix, 7062af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui float currentAlpha, Canvas canvas, int w, int h) { 7074d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Calculate current group's matrix by preConcat the parent's and 7084d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // and the current one on the top of the stack. 7094d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Basically the Mfinal = Mviewport * M0 * M1 * M2; 7104d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Mi the local matrix at level i of the group tree. 7114d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui currentGroup.mStackedMatrix.set(currentMatrix); 7124d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 7134d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix); 7144d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 7152af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui float stackedAlpha = currentAlpha * currentGroup.mGroupAlpha; 7168d0d24f7a2b1a59060aa18926984491691d3c667ztenghui 7178d0d24f7a2b1a59060aa18926984491691d3c667ztenghui // Draw the group tree in the same order as the XML file. 7188d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < currentGroup.mChildren.size(); i++) { 7198d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = currentGroup.mChildren.get(i); 7208d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 7218d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 7228d0d24f7a2b1a59060aa18926984491691d3c667ztenghui drawGroupTree(childGroup, currentGroup.mStackedMatrix, 7238d0d24f7a2b1a59060aa18926984491691d3c667ztenghui stackedAlpha, canvas, w, h); 7248d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 7258d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 7268d0d24f7a2b1a59060aa18926984491691d3c667ztenghui drawPath(currentGroup, childPath, stackedAlpha, canvas, w, h); 7278d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 728abb7d134c02ac60091108c491dafb00877093170John Hoford } 7294d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 730abb7d134c02ac60091108c491dafb00877093170John Hoford 7314d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui public void draw(Canvas canvas, int w, int h) { 7324d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Travese the tree in pre-order to draw. 7332af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui drawGroupTree(mRootGroup, IDENTITY_MATRIX, ((float) mRootAlpha) / 0xFF, canvas, w, h); 734abb7d134c02ac60091108c491dafb00877093170John Hoford } 735abb7d134c02ac60091108c491dafb00877093170John Hoford 7368d0d24f7a2b1a59060aa18926984491691d3c667ztenghui private void drawPath(VGroup vGroup, VPath vPath, float stackedAlpha, 7378d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Canvas canvas, int w, int h) { 7389d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui final float scaleX = w / mViewportWidth; 7399d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui final float scaleY = h / mViewportHeight; 7409d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui final float minScale = Math.min(scaleX, scaleY); 741abb7d134c02ac60091108c491dafb00877093170John Hoford 7424d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mFinalPathMatrix.set(vGroup.mStackedMatrix); 7439d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui mFinalPathMatrix.postScale(scaleX, scaleY, mViewportWidth / 2f, mViewportHeight / 2f); 7448e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mFinalPathMatrix.postTranslate( 7458e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette w / 2f - mViewportWidth / 2f, h / 2f - mViewportHeight / 2f); 746abb7d134c02ac60091108c491dafb00877093170John Hoford 7478d0d24f7a2b1a59060aa18926984491691d3c667ztenghui vPath.toPath(mPath); 7488d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final Path path = mPath; 749abb7d134c02ac60091108c491dafb00877093170John Hoford 7508d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mTrimPathStart != 0.0f || vPath.mTrimPathEnd != 1.0f) { 7518d0d24f7a2b1a59060aa18926984491691d3c667ztenghui float start = (vPath.mTrimPathStart + vPath.mTrimPathOffset) % 1.0f; 7528d0d24f7a2b1a59060aa18926984491691d3c667ztenghui float end = (vPath.mTrimPathEnd + vPath.mTrimPathOffset) % 1.0f; 7539453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 7548d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mPathMeasure == null) { 7558d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mPathMeasure = new PathMeasure(); 7564b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette } 7578d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mPathMeasure.setPath(mPath, false); 7588d0d24f7a2b1a59060aa18926984491691d3c667ztenghui 7598d0d24f7a2b1a59060aa18926984491691d3c667ztenghui float len = mPathMeasure.getLength(); 7608d0d24f7a2b1a59060aa18926984491691d3c667ztenghui start = start * len; 7618d0d24f7a2b1a59060aa18926984491691d3c667ztenghui end = end * len; 7628d0d24f7a2b1a59060aa18926984491691d3c667ztenghui path.reset(); 7638d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (start > end) { 7648d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mPathMeasure.getSegment(start, len, path, true); 7658d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mPathMeasure.getSegment(0f, end, path, true); 7668d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else { 7678d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mPathMeasure.getSegment(start, end, path, true); 7688d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 7698d0d24f7a2b1a59060aa18926984491691d3c667ztenghui path.rLineTo(0, 0); // fix bug in measure 7708d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 7714b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 7728d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mRenderPath.reset(); 7739453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 7748d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mRenderPath.addPath(path, mFinalPathMatrix); 7754b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 7768d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mClip) { 7778d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.clipPath(mRenderPath, Region.Op.REPLACE); 7788d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else { 7798d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mFillColor != 0) { 7808d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mFillPaint == null) { 7818d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint = new Paint(); 7828d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setColorFilter(mColorFilter); 7838d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setStyle(Paint.Style.FILL); 7848d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setAntiAlias(true); 78563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 7868d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setColor(applyAlpha(vPath.mFillColor, stackedAlpha)); 7878d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.drawPath(mRenderPath, mFillPaint); 7888d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 78963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 7908d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mStrokeColor != 0) { 7918d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mStrokePaint == null) { 7928d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint = new Paint(); 7938d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setColorFilter(mColorFilter); 7948d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setStyle(Paint.Style.STROKE); 7958d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setAntiAlias(true); 7968d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 7974b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 7988d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final Paint strokePaint = mStrokePaint; 7998d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mStrokeLineJoin != null) { 8008d0d24f7a2b1a59060aa18926984491691d3c667ztenghui strokePaint.setStrokeJoin(vPath.mStrokeLineJoin); 8018d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 802abb7d134c02ac60091108c491dafb00877093170John Hoford 8038d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mStrokeLineCap != null) { 8048d0d24f7a2b1a59060aa18926984491691d3c667ztenghui strokePaint.setStrokeCap(vPath.mStrokeLineCap); 8058d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 80663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 8079d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui strokePaint.setStrokeMiter(vPath.mStrokeMiterlimit * minScale); 80863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 8098d0d24f7a2b1a59060aa18926984491691d3c667ztenghui strokePaint.setColor(applyAlpha(vPath.mStrokeColor, stackedAlpha)); 8109d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui strokePaint.setStrokeWidth(vPath.mStrokeWidth * minScale); 8118d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.drawPath(mRenderPath, strokePaint); 81263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 813abb7d134c02ac60091108c491dafb00877093170John Hoford } 814abb7d134c02ac60091108c491dafb00877093170John Hoford } 815abb7d134c02ac60091108c491dafb00877093170John Hoford 816abb7d134c02ac60091108c491dafb00877093170John Hoford private void parseViewport(Resources r, AttributeSet attrs) 817abb7d134c02ac60091108c491dafb00877093170John Hoford throws XmlPullParserException { 8184b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette final TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableViewport); 8198e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 8208e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 8218e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations |= a.getChangingConfigurations(); 8228e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 8238e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mViewportWidth = a.getFloat( 8248e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette R.styleable.VectorDrawableViewport_viewportWidth, mViewportWidth); 8258e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mViewportHeight = a.getFloat( 8268e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette R.styleable.VectorDrawableViewport_viewportHeight, mViewportHeight); 827fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 828fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette if (mViewportWidth <= 0) { 829fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette throw new XmlPullParserException(a.getPositionDescription() + 830fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette "<viewport> tag requires viewportWidth > 0"); 831fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } else if (mViewportHeight <= 0) { 832fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette throw new XmlPullParserException(a.getPositionDescription() + 833fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette "<viewport> tag requires viewportHeight > 0"); 834abb7d134c02ac60091108c491dafb00877093170John Hoford } 835fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 836abb7d134c02ac60091108c491dafb00877093170John Hoford a.recycle(); 837abb7d134c02ac60091108c491dafb00877093170John Hoford } 838abb7d134c02ac60091108c491dafb00877093170John Hoford 839abb7d134c02ac60091108c491dafb00877093170John Hoford private void parseSize(Resources r, AttributeSet attrs) 8408d0d24f7a2b1a59060aa18926984491691d3c667ztenghui throws XmlPullParserException { 8414b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette final TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableSize); 8428e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 8438e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 8448e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations |= a.getChangingConfigurations(); 8458e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 846fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mBaseWidth = a.getDimension(R.styleable.VectorDrawableSize_width, mBaseWidth); 847fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mBaseHeight = a.getDimension(R.styleable.VectorDrawableSize_height, mBaseHeight); 848fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 849fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette if (mBaseWidth <= 0) { 850fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette throw new XmlPullParserException(a.getPositionDescription() + 851fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette "<size> tag requires width > 0"); 852fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } else if (mBaseHeight <= 0) { 853fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette throw new XmlPullParserException(a.getPositionDescription() + 854fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette "<size> tag requires height > 0"); 855abb7d134c02ac60091108c491dafb00877093170John Hoford } 856fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 857abb7d134c02ac60091108c491dafb00877093170John Hoford a.recycle(); 858abb7d134c02ac60091108c491dafb00877093170John Hoford } 8594b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 860abb7d134c02ac60091108c491dafb00877093170John Hoford } 861abb7d134c02ac60091108c491dafb00877093170John Hoford 862e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui static class VGroup { 86355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // mStackedMatrix is only used temporarily when drawing, it combines all 86455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // the parents' local matrices with the current one. 86555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final Matrix mStackedMatrix = new Matrix(); 86655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 86755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 86855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 8698d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> mChildren = new ArrayList<Object>(); 870abb7d134c02ac60091108c491dafb00877093170John Hoford 87163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mRotate = 0; 87263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mPivotX = 0; 87363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mPivotY = 0; 874452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mScaleX = 1; 875452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mScaleY = 1; 876452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mTranslateX = 0; 877452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mTranslateY = 0; 8782af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui private float mGroupAlpha = 1; 8794d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 88055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // mLocalMatrix is updated based on the update of transformation information, 88155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // either parsed from the XML or by animation. 8824d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private final Matrix mLocalMatrix = new Matrix(); 8838e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private int mChangingConfigurations; 88463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private int[] mThemeAttrs; 885e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui private String mGroupName = null; 886e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 88755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VGroup(VGroup copy, ArrayMap<String, Object> targetsMap) { 88855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRotate = copy.mRotate; 88955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPivotX = copy.mPivotX; 89055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPivotY = copy.mPivotY; 89155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mScaleX = copy.mScaleX; 89255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mScaleY = copy.mScaleY; 89355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTranslateX = copy.mTranslateX; 89455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTranslateY = copy.mTranslateY; 89555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mGroupAlpha = copy.mGroupAlpha; 89655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mThemeAttrs = copy.mThemeAttrs; 89755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mGroupName = copy.mGroupName; 89855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mChangingConfigurations = copy.mChangingConfigurations; 89955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (mGroupName != null) { 90055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui targetsMap.put(mGroupName, this); 90155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 90255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 90355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mLocalMatrix.set(copy.mLocalMatrix); 90455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 9058d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = copy.mChildren; 9068d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 9078d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object copyChild = children.get(i); 9088d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (copyChild instanceof VGroup) { 9098d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup copyGroup = (VGroup) copyChild; 9108d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mChildren.add(new VGroup(copyGroup, targetsMap)); 9118d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (copyChild instanceof VPath) { 9128d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath copyPath = (VPath) copyChild; 9138d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath newPath = new VPath(copyPath); 9148d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mChildren.add(newPath); 9158d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (newPath.mPathName != null) { 9168d0d24f7a2b1a59060aa18926984491691d3c667ztenghui targetsMap.put(newPath.mPathName, newPath); 9178d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 91855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 91955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 92055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 92155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 92255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VGroup() { 92355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 92455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 925e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui /* Getter and Setter */ 926e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getRotation() { 927e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mRotate; 928e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 929e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 930e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setRotation(float rotation) { 931e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (rotation != mRotate) { 932e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mRotate = rotation; 933e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 934e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 935e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 936e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 937e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getPivotX() { 938e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPivotX; 939e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 940e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 941e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setPivotX(float pivotX) { 942e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (pivotX != mPivotX) { 943e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mPivotX = pivotX; 944e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 945e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 946e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 947e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 948e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getPivotY() { 949e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPivotY; 950e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 951e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 952e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setPivotY(float pivotY) { 953e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (pivotY != mPivotY) { 954e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mPivotY = pivotY; 955e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 956e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 957e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 958e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 959e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getScaleX() { 960e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mScaleX; 961e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 9624d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 963e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setScaleX(float scaleX) { 964e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (scaleX != mScaleX) { 965e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mScaleX = scaleX; 966e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 967e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 968e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 969e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 970e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getScaleY() { 971e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mScaleY; 972e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 973e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 974e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setScaleY(float scaleY) { 975e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (scaleY != mScaleY) { 976e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mScaleY = scaleY; 977e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 978e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 979e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 980e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 981e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getTranslateX() { 982e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTranslateX; 983e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 984e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 985e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setTranslateX(float translateX) { 986e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (translateX != mTranslateX) { 987e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTranslateX = translateX; 988e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 989e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 990e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 991e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 992e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getTranslateY() { 993e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTranslateY; 994e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 995e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 996e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setTranslateY(float translateY) { 997e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (translateY != mTranslateY) { 998e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTranslateY = translateY; 999e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1000e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1001e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1002e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1003e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getAlpha() { 1004e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mGroupAlpha; 1005e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1006e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1007e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setAlpha(float groupAlpha) { 1008e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (groupAlpha != mGroupAlpha) { 1009e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mGroupAlpha = groupAlpha; 1010e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1011e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1012e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1013e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public String getGroupName() { 1014e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mGroupName; 10154d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 10164d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 10174d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui public Matrix getLocalMatrix() { 10184d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui return mLocalMatrix; 10194d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 10204d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 10214d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui public boolean canApplyTheme() { 10224d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui return mThemeAttrs != null; 10234d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 10244d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 10258e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette public void inflate(Resources res, AttributeSet attrs, Theme theme) { 10268e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final TypedArray a = obtainAttributes(res, theme, attrs, 10278e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette R.styleable.VectorDrawableGroup); 10288e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 10298e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette a.recycle(); 10308e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 10318e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 10328e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private void updateStateFromTypedArray(TypedArray a) { 10338e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 10348e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations |= a.getChangingConfigurations(); 103563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 10368e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Extract the theme attributes, if any. 10378e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mThemeAttrs = a.extractThemeAttrs(); 103863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 103963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui mRotate = a.getFloat(R.styleable.VectorDrawableGroup_rotation, mRotate); 104063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui mPivotX = a.getFloat(R.styleable.VectorDrawableGroup_pivotX, mPivotX); 104163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui mPivotY = a.getFloat(R.styleable.VectorDrawableGroup_pivotY, mPivotY); 1042452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui mScaleX = a.getFloat(R.styleable.VectorDrawableGroup_scaleX, mScaleX); 1043452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY); 1044452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX); 1045452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY); 10462af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mGroupAlpha = a.getFloat(R.styleable.VectorDrawableGroup_alpha, mGroupAlpha); 104763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 10488e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final String groupName = a.getString(R.styleable.VectorDrawableGroup_name); 10498e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette if (groupName != null) { 10508e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mGroupName = groupName; 105163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 105263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 10538e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateLocalMatrix(); 10548e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 10554d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 10568e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette public void applyTheme(Theme t) { 10578e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette if (mThemeAttrs == null) { 10588e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette return; 10594d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 10604d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 10618e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawablePath); 10628e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 106363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui a.recycle(); 106463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 106563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 10664d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void updateLocalMatrix() { 10674d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // The order we apply is the same as the 10684d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // RenderNode.cpp::applyViewPropertyTransforms(). 10694d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mLocalMatrix.reset(); 10704d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mLocalMatrix.postTranslate(-mPivotX, -mPivotY); 10714d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mLocalMatrix.postScale(mScaleX, mScaleY); 10724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mLocalMatrix.postRotate(mRotate, 0, 0); 10734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY); 10744d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 1075abb7d134c02ac60091108c491dafb00877093170John Hoford } 1076abb7d134c02ac60091108c491dafb00877093170John Hoford 1077cf4832f69c8786b098ce18c24319021f8cd6733aztenghui private static class VPath { 107855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 107955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 10809453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private int[] mThemeAttrs; 10819453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1082abb7d134c02ac60091108c491dafb00877093170John Hoford int mStrokeColor = 0; 1083abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeWidth = 0; 1084abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeOpacity = Float.NaN; 10852af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui int mFillColor = Color.BLACK; 1086abb7d134c02ac60091108c491dafb00877093170John Hoford int mFillRule; 1087abb7d134c02ac60091108c491dafb00877093170John Hoford float mFillOpacity = Float.NaN; 1088abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathStart = 0; 1089abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathEnd = 1; 1090abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathOffset = 0; 10919453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1092abb7d134c02ac60091108c491dafb00877093170John Hoford boolean mClip = false; 10934b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette Paint.Cap mStrokeLineCap = Paint.Cap.BUTT; 10944b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette Paint.Join mStrokeLineJoin = Paint.Join.MITER; 1095abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeMiterlimit = 4; 10969453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 109755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private PathParser.PathDataNode[] mNodes = null; 10988d0d24f7a2b1a59060aa18926984491691d3c667ztenghui String mPathName; 109955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private int mChangingConfigurations; 1100abb7d134c02ac60091108c491dafb00877093170John Hoford 11019453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public VPath() { 11029453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette // Empty constructor. 11039453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 11049453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 110555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VPath(VPath copy) { 110655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mThemeAttrs = copy.mThemeAttrs; 110755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 110855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeColor = copy.mStrokeColor; 110955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeWidth = copy.mStrokeWidth; 111055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeOpacity = copy.mStrokeOpacity; 111155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillColor = copy.mFillColor; 111255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillRule = copy.mFillRule; 111355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillOpacity = copy.mFillOpacity; 111455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathStart = copy.mTrimPathStart; 111555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathEnd = copy.mTrimPathEnd; 111655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathOffset = copy.mTrimPathOffset; 111755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 111855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mClip = copy.mClip; 111955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeLineCap = copy.mStrokeLineCap; 112055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeLineJoin = copy.mStrokeLineJoin; 112155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeMiterlimit = copy.mStrokeMiterlimit; 112255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 112355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mNodes = PathParser.deepCopyNodes(copy.mNodes); 112455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPathName = copy.mPathName; 112555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mChangingConfigurations = copy.mChangingConfigurations; 112655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 112755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 1128abb7d134c02ac60091108c491dafb00877093170John Hoford public void toPath(Path path) { 1129abb7d134c02ac60091108c491dafb00877093170John Hoford path.reset(); 113055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (mNodes != null) { 113155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui PathParser.PathDataNode.nodesToPath(mNodes, path); 1132abb7d134c02ac60091108c491dafb00877093170John Hoford } 1133abb7d134c02ac60091108c491dafb00877093170John Hoford } 1134abb7d134c02ac60091108c491dafb00877093170John Hoford 1135e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public String getPathName() { 1136e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPathName; 1137abb7d134c02ac60091108c491dafb00877093170John Hoford } 1138abb7d134c02ac60091108c491dafb00877093170John Hoford 11397f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette private Paint.Cap getStrokeLineCap(int id, Paint.Cap defValue) { 11407f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette switch (id) { 11417f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_BUTT: 11427f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.BUTT; 11437f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_ROUND: 11447f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.ROUND; 11457f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_SQUARE: 11467f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.SQUARE; 11477f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette default: 11487f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return defValue; 11497f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 11507f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 11517f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette 11527f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette private Paint.Join getStrokeLineJoin(int id, Paint.Join defValue) { 11537f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette switch (id) { 11547f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_MITER: 11557f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.MITER; 11567f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_ROUND: 11577f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.ROUND; 11587f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_BEVEL: 11597f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.BEVEL; 11607f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette default: 11617f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return defValue; 11627f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 11637f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 11647f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette 1165eb034fbca40006c55db143047eb628c4b657730aztenghui /* Setters and Getters, mostly used by animator from AnimatedVectorDrawable. */ 1166eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1167eb034fbca40006c55db143047eb628c4b657730aztenghui public PathParser.PathDataNode[] getPathData() { 116855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return mNodes; 1169eb034fbca40006c55db143047eb628c4b657730aztenghui } 1170eb034fbca40006c55db143047eb628c4b657730aztenghui 1171eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 117255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public void setPathData(PathParser.PathDataNode[] nodes) { 117355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (!PathParser.canMorph(mNodes, nodes)) { 1174eb034fbca40006c55db143047eb628c4b657730aztenghui // This should not happen in the middle of animation. 117555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mNodes = PathParser.deepCopyNodes(nodes); 1176eb034fbca40006c55db143047eb628c4b657730aztenghui } else { 117755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui PathParser.updateNodes(mNodes, nodes); 1178eb034fbca40006c55db143047eb628c4b657730aztenghui } 1179eb034fbca40006c55db143047eb628c4b657730aztenghui } 1180eb034fbca40006c55db143047eb628c4b657730aztenghui 1181eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1182e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui int getStroke() { 1183e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeColor; 1184e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1185e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1186eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1187e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setStroke(int strokeColor) { 1188e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeColor = strokeColor; 1189e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1190e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1191eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1192e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getStrokeWidth() { 1193e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeWidth; 1194e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1195e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1196eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1197e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setStrokeWidth(float strokeWidth) { 1198e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeWidth = strokeWidth; 1199e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1200e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1201eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1202e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getStrokeOpacity() { 1203e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeOpacity; 1204e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1205e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1206eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1207e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setStrokeOpacity(float strokeOpacity) { 1208e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeOpacity = strokeOpacity; 1209e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1210e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1211eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1212e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui int getFill() { 1213e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mFillColor; 1214e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1215e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1216eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1217e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setFill(int fillColor) { 1218e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mFillColor = fillColor; 1219e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1220e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1221eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1222e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getFillOpacity() { 1223e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mFillOpacity; 1224e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1225e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1226eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1227e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setFillOpacity(float fillOpacity) { 1228e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mFillOpacity = fillOpacity; 1229e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1230e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1231eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1232e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathStart() { 1233e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathStart; 1234e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1235e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1236eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1237e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathStart(float trimPathStart) { 1238e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathStart = trimPathStart; 1239e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1240e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1241eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1242e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathEnd() { 1243e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathEnd; 1244e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1245e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1246eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1247e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathEnd(float trimPathEnd) { 1248e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathEnd = trimPathEnd; 1249e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1250e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1251eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1252e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathOffset() { 1253e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathOffset; 1254e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1255e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1256eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1257e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathOffset(float trimPathOffset) { 1258e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathOffset = trimPathOffset; 1259e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1260e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 12618e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette public boolean canApplyTheme() { 12628e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette return mThemeAttrs != null; 12638e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 12648e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 12659453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public void inflate(Resources r, AttributeSet attrs, Theme theme) { 12669453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.VectorDrawablePath); 12678e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 1268abb7d134c02ac60091108c491dafb00877093170John Hoford a.recycle(); 1269abb7d134c02ac60091108c491dafb00877093170John Hoford } 1270abb7d134c02ac60091108c491dafb00877093170John Hoford 12718e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private void updateStateFromTypedArray(TypedArray a) { 12728e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 12738e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations |= a.getChangingConfigurations(); 12749453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 12758e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Extract the theme attributes, if any. 12768e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mThemeAttrs = a.extractThemeAttrs(); 12779453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 12787f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mClip = a.getBoolean(R.styleable.VectorDrawablePath_clipToPath, mClip); 127955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 12808e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mPathName = a.getString(R.styleable.VectorDrawablePath_name); 128155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mNodes = PathParser.createNodesFromPathData(a.getString( 12828e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette R.styleable.VectorDrawablePath_pathData)); 128355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 12847f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mFillColor = a.getColor(R.styleable.VectorDrawablePath_fill, mFillColor); 12857f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mFillOpacity = a.getFloat(R.styleable.VectorDrawablePath_fillOpacity, mFillOpacity); 12867f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeLineCap = getStrokeLineCap(a.getInt( 12877f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_strokeLineCap, -1), mStrokeLineCap); 12887f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeLineJoin = getStrokeLineJoin(a.getInt( 12897f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_strokeLineJoin, -1), mStrokeLineJoin); 12907f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeMiterlimit = a.getFloat( 12917f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_strokeMiterLimit, mStrokeMiterlimit); 12927f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_stroke, mStrokeColor); 12937f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeOpacity = a.getFloat( 12947f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_strokeOpacity, mStrokeOpacity); 12957f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, mStrokeWidth); 12967f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd, mTrimPathEnd); 12977f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mTrimPathOffset = a.getFloat( 12987f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_trimPathOffset, mTrimPathOffset); 12997f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mTrimPathStart = a.getFloat( 13007f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_trimPathStart, mTrimPathStart); 13019453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 13029453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette updateColorAlphas(); 13038e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 13048e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 13058e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette public void applyTheme(Theme t) { 13068e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette if (mThemeAttrs == null) { 13078e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette return; 13088e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 13098e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 13108e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawablePath); 13118e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 131263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui a.recycle(); 13139453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 13149453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 13159453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private void updateColorAlphas() { 13169453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette if (!Float.isNaN(mFillOpacity)) { 13172af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mFillColor = applyAlpha(mFillColor, mFillOpacity); 13189453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 13199453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 13209453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette if (!Float.isNaN(mStrokeOpacity)) { 13212af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mStrokeColor = applyAlpha(mStrokeColor, mStrokeOpacity); 13229453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 13239453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 1324abb7d134c02ac60091108c491dafb00877093170John Hoford } 1325abb7d134c02ac60091108c491dafb00877093170John Hoford} 1326