VectorDrawable.java revision 738177caf6a755a59ca6b17bb968be0aa4e8e10f
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; 33955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui inflateInternal(res, parser, attrs, theme); 3409cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3419cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 3429cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mVPathRenderer.setColorFilter(mTintFilter); 3439cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 3449cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3459cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette private void updateStateFromTypedArray(TypedArray a) { 3469cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final VectorDrawableState state = mVectorState; 3479cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3488e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 3498e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= a.getChangingConfigurations(); 3508e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 3519cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette // Extract the theme attributes, if any. 3529cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mThemeAttrs = a.extractThemeAttrs(); 3539cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3549cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final int tintMode = a.getInt(R.styleable.VectorDrawable_tintMode, -1); 3559cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette if (tintMode != -1) { 3569cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN); 3579cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 3589cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3599cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final ColorStateList tint = a.getColorStateList(R.styleable.VectorDrawable_tint); 3609cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette if (tint != null) { 3619cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mTint = tint; 3629cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 363738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 364738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui state.mAutoMirrored = a.getBoolean( 365738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui R.styleable.VectorDrawable_autoMirrored, state.mAutoMirrored); 3669cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 3679cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 36855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private void inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs, 3698e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette Theme theme) throws XmlPullParserException, IOException { 3708e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final VectorDrawableState state = mVectorState; 371ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui final VPathRenderer pathRenderer = new VPathRenderer(); 37255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui state.mVPathRenderer = pathRenderer; 3739453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 374abb7d134c02ac60091108c491dafb00877093170John Hoford boolean noSizeTag = true; 375abb7d134c02ac60091108c491dafb00877093170John Hoford boolean noViewportTag = true; 376abb7d134c02ac60091108c491dafb00877093170John Hoford boolean noPathTag = true; 3779453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 3784d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Use a stack to help to build the group tree. 3794d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // The top of the stack is always the current group. 3804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final Stack<VGroup> groupStack = new Stack<VGroup>(); 3814d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.push(pathRenderer.mRootGroup); 382abb7d134c02ac60091108c491dafb00877093170John Hoford 383abb7d134c02ac60091108c491dafb00877093170John Hoford int eventType = parser.getEventType(); 384abb7d134c02ac60091108c491dafb00877093170John Hoford while (eventType != XmlPullParser.END_DOCUMENT) { 385abb7d134c02ac60091108c491dafb00877093170John Hoford if (eventType == XmlPullParser.START_TAG) { 3869453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final String tagName = parser.getName(); 3874d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final VGroup currentGroup = groupStack.peek(); 3884d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 389abb7d134c02ac60091108c491dafb00877093170John Hoford if (SHAPE_PATH.equals(tagName)) { 3909453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final VPath path = new VPath(); 3919453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette path.inflate(res, attrs, theme); 3928d0d24f7a2b1a59060aa18926984491691d3c667ztenghui currentGroup.mChildren.add(path); 393e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (path.getPathName() != null) { 39455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui pathRenderer.mVGTargetsMap.put(path.getPathName(), path); 395e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 396abb7d134c02ac60091108c491dafb00877093170John Hoford noPathTag = false; 3978e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= path.mChangingConfigurations; 398abb7d134c02ac60091108c491dafb00877093170John Hoford } else if (SHAPE_SIZE.equals(tagName)) { 399ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui pathRenderer.parseSize(res, attrs); 400abb7d134c02ac60091108c491dafb00877093170John Hoford noSizeTag = false; 4018e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= pathRenderer.mChangingConfigurations; 402abb7d134c02ac60091108c491dafb00877093170John Hoford } else if (SHAPE_VIEWPORT.equals(tagName)) { 403ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui pathRenderer.parseViewport(res, attrs); 404abb7d134c02ac60091108c491dafb00877093170John Hoford noViewportTag = false; 4058e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= pathRenderer.mChangingConfigurations; 4066d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui } else if (SHAPE_GROUP.equals(tagName)) { 4074d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui VGroup newChildGroup = new VGroup(); 4084d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui newChildGroup.inflate(res, attrs, theme); 4098d0d24f7a2b1a59060aa18926984491691d3c667ztenghui currentGroup.mChildren.add(newChildGroup); 4104d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.push(newChildGroup); 411e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (newChildGroup.getGroupName() != null) { 41255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui pathRenderer.mVGTargetsMap.put(newChildGroup.getGroupName(), 41355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui newChildGroup); 414e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 4158e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= newChildGroup.mChangingConfigurations; 416abb7d134c02ac60091108c491dafb00877093170John Hoford } 4174d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } else if (eventType == XmlPullParser.END_TAG) { 4184d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final String tagName = parser.getName(); 4194d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui if (SHAPE_GROUP.equals(tagName)) { 4204d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.pop(); 4214d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 422abb7d134c02ac60091108c491dafb00877093170John Hoford } 423abb7d134c02ac60091108c491dafb00877093170John Hoford eventType = parser.next(); 424abb7d134c02ac60091108c491dafb00877093170John Hoford } 4259453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 4264d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Print the tree out for debug. 4274d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui if (DBG_VECTOR_DRAWABLE) { 4284d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui printGroupTree(pathRenderer.mRootGroup, 0); 4296d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui } 4306d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui 43146e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui if (noSizeTag || noViewportTag || noPathTag) { 4329453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final StringBuffer tag = new StringBuffer(); 4339453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 434abb7d134c02ac60091108c491dafb00877093170John Hoford if (noSizeTag) { 4359453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette tag.append(SHAPE_SIZE); 436abb7d134c02ac60091108c491dafb00877093170John Hoford } 4379453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 438d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette if (noViewportTag) { 439d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette if (tag.length() > 0) { 440abb7d134c02ac60091108c491dafb00877093170John Hoford tag.append(" & "); 441abb7d134c02ac60091108c491dafb00877093170John Hoford } 4429453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette tag.append(SHAPE_SIZE); 443abb7d134c02ac60091108c491dafb00877093170John Hoford } 4449453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 445d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette if (noPathTag) { 446d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette if (tag.length() > 0) { 447abb7d134c02ac60091108c491dafb00877093170John Hoford tag.append(" or "); 448abb7d134c02ac60091108c491dafb00877093170John Hoford } 4499453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette tag.append(SHAPE_PATH); 450abb7d134c02ac60091108c491dafb00877093170John Hoford } 4519453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 4529453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette throw new XmlPullParserException("no " + tag + " defined"); 453abb7d134c02ac60091108c491dafb00877093170John Hoford } 454abb7d134c02ac60091108c491dafb00877093170John Hoford } 455abb7d134c02ac60091108c491dafb00877093170John Hoford 4564d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void printGroupTree(VGroup currentGroup, int level) { 4574d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui String indent = ""; 4588d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < level; i++) { 4594d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui indent += " "; 4604d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 4614d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Print the current node 4628d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Log.v(LOGTAG, indent + "current group is :" + currentGroup.getGroupName() 4634d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui + " rotation is " + currentGroup.mRotate); 4648d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString()); 4658d0d24f7a2b1a59060aa18926984491691d3c667ztenghui // Then print all the children groups 4668d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < currentGroup.mChildren.size(); i++) { 4678d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = currentGroup.mChildren.get(i); 4688d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 4698d0d24f7a2b1a59060aa18926984491691d3c667ztenghui printGroupTree((VGroup) child, level + 1); 4708d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 4714d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 4724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 4734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 47455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui @Override 47555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public int getChangingConfigurations() { 47655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return super.getChangingConfigurations() | mVectorState.mChangingConfigurations; 47755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 47855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 479482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui void setAllowCaching(boolean allowCaching) { 480482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mAllowCaching = allowCaching; 481482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 482482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 483738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui private boolean needMirroring() { 484738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui return isAutoMirrored() && getLayoutDirection() == LayoutDirection.RTL; 485738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 486738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 487738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui @Override 488738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui public void setAutoMirrored(boolean mirrored) { 489738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui if (mVectorState.mAutoMirrored != mirrored) { 490738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui mVectorState.mAutoMirrored = mirrored; 491738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui invalidateSelf(); 492738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 493738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 494738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 495738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui @Override 496738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui public boolean isAutoMirrored() { 497738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui return mVectorState.mAutoMirrored; 498738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 499738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 5005c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette private static class VectorDrawableState extends ConstantState { 5019cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette int[] mThemeAttrs; 5025c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette int mChangingConfigurations; 503ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui VPathRenderer mVPathRenderer; 504b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette ColorStateList mTint; 505b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette Mode mTintMode; 506738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui boolean mAutoMirrored; 5075c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 508482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Bitmap mCachedBitmap; 509482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui int[] mCachedThemeAttrs; 510482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui ColorStateList mCachedTint; 511482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Mode mCachedTintMode; 512482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui int mCachedRootAlpha; 513482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 51455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Deep copy for mutate() or implicitly mutate. 5155c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public VectorDrawableState(VectorDrawableState copy) { 5165c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette if (copy != null) { 5179cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette mThemeAttrs = copy.mThemeAttrs; 5185c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette mChangingConfigurations = copy.mChangingConfigurations; 519ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui mVPathRenderer = new VPathRenderer(copy.mVPathRenderer); 520b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTint = copy.mTint; 521b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintMode = copy.mTintMode; 522738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui mAutoMirrored = copy.mAutoMirrored; 5235c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 5245c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 5255c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 526482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui public boolean canReuseCache(int width, int height) { 527482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui if (mCachedThemeAttrs == mThemeAttrs 528482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && mCachedTint == mTint 529482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && mCachedTintMode == mTintMode 530738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui && mAutoMirrored == mAutoMirrored 531482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && width == mCachedBitmap.getWidth() 532482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && height == mCachedBitmap.getHeight() 533482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && mCachedRootAlpha == mVPathRenderer.getRootAlpha()) { 534482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui return true; 535482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 536482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui return false; 537482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 538482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 539482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui public void updateCacheStates() { 540482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // Use shallow copy here and shallow comparison in canReuseCache(), 541482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // likely hit cache miss more, but practically not much difference. 542482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedThemeAttrs = mThemeAttrs; 543482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedTint = mTint; 544482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedTintMode = mTintMode; 545482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedRootAlpha = mVPathRenderer.getRootAlpha(); 546482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 547482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 54855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VectorDrawableState() { 54955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVPathRenderer = new VPathRenderer(); 55055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 55155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 5525c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 5535c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable() { 5545c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, null, null); 5555c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 5565c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 5575c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 5585c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable(Resources res) { 5595c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, res, null); 5605c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 5615c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 5625c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 5635c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable(Resources res, Theme theme) { 5645c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, res, theme); 5655c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 5665c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 5675c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 5685c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public int getChangingConfigurations() { 5695c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return mChangingConfigurations; 5705c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 5715c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 5725c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 573ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui private static class VPathRenderer { 5744d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui /* Right now the internal data structure is organized as a tree. 5754d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Each node can be a group node, or a path. 5764d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * A group node can have groups or paths as children, but a path node has 5774d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * no children. 5784d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * One example can be: 5794d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Root Group 5804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * / | \ 5814d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Group Path Group 5824d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * / \ | 5834d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Path Path Path 5844d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * 5854d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui */ 58655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables that only used temporarily inside the draw() call, so there 58755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // is no need for deep copying. 5884b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private final Path mPath = new Path(); 5894b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private final Path mRenderPath = new Path(); 5904d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private static final Matrix IDENTITY_MATRIX = new Matrix(); 59155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final Matrix mFinalPathMatrix = new Matrix(); 5924b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 5934b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private Paint mStrokePaint; 5944b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private Paint mFillPaint; 595fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette private ColorFilter mColorFilter; 596abb7d134c02ac60091108c491dafb00877093170John Hoford private PathMeasure mPathMeasure; 5974b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 59855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 59955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 6008e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private int mChangingConfigurations; 60155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final VGroup mRootGroup; 6024d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private float mBaseWidth = 0; 6034d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private float mBaseHeight = 0; 6044d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private float mViewportWidth = 0; 6054d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private float mViewportHeight = 0; 6062af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui private int mRootAlpha = 0xFF; 6079453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 60855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>(); 609abb7d134c02ac60091108c491dafb00877093170John Hoford 610ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui public VPathRenderer() { 6114d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mRootGroup = new VGroup(); 612abb7d134c02ac60091108c491dafb00877093170John Hoford } 6139453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 6142af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui public void setRootAlpha(int alpha) { 6152af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mRootAlpha = alpha; 6162af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 6172af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 6182af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui public int getRootAlpha() { 6192af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui return mRootAlpha; 6202af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 6212af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 622ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui public VPathRenderer(VPathRenderer copy) { 62355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap); 624abb7d134c02ac60091108c491dafb00877093170John Hoford mBaseWidth = copy.mBaseWidth; 625abb7d134c02ac60091108c491dafb00877093170John Hoford mBaseHeight = copy.mBaseHeight; 626abb7d134c02ac60091108c491dafb00877093170John Hoford mViewportWidth = copy.mViewportHeight; 627abb7d134c02ac60091108c491dafb00877093170John Hoford mViewportHeight = copy.mViewportHeight; 6288e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations = copy.mChangingConfigurations; 62955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRootAlpha = copy.mRootAlpha; 630abb7d134c02ac60091108c491dafb00877093170John Hoford } 631abb7d134c02ac60091108c491dafb00877093170John Hoford 6329453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public boolean canApplyTheme() { 6334d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // If one of the paths can apply theme, then return true; 6344d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui return recursiveCanApplyTheme(mRootGroup); 6354d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6364d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 6374d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private boolean recursiveCanApplyTheme(VGroup currentGroup) { 6384d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // We can do a tree traverse here, if there is one path return true, 6394d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // then we return true for the whole tree. 6408d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = currentGroup.mChildren; 6418d0d24f7a2b1a59060aa18926984491691d3c667ztenghui 6428d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 6438d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = children.get(i); 6448d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 6458d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 6468d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childGroup.canApplyTheme() 6478d0d24f7a2b1a59060aa18926984491691d3c667ztenghui || recursiveCanApplyTheme(childGroup)) { 6488d0d24f7a2b1a59060aa18926984491691d3c667ztenghui return true; 6498d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 6508d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 6518d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 6528d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childPath.canApplyTheme()) { 6538d0d24f7a2b1a59060aa18926984491691d3c667ztenghui return true; 6548d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 6554d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6564d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6579453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette return false; 6589453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 6599453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 6609453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public void applyTheme(Theme t) { 6614d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Apply theme to every path of the tree. 6624d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui recursiveApplyTheme(mRootGroup, t); 6634d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6644d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 6654d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void recursiveApplyTheme(VGroup currentGroup, Theme t) { 6664d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // We can do a tree traverse here, apply theme to all paths which 6674d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // can apply theme. 6688d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = currentGroup.mChildren; 6698d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 6708d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = children.get(i); 6718d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 6728d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 6738d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childGroup.canApplyTheme()) { 6748d0d24f7a2b1a59060aa18926984491691d3c667ztenghui childGroup.applyTheme(t); 6758d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 6768d0d24f7a2b1a59060aa18926984491691d3c667ztenghui recursiveApplyTheme(childGroup, t); 6778d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 6788d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 6798d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childPath.canApplyTheme()) { 6808d0d24f7a2b1a59060aa18926984491691d3c667ztenghui childPath.applyTheme(t); 6818d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 6824d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6834d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 684abb7d134c02ac60091108c491dafb00877093170John Hoford } 685abb7d134c02ac60091108c491dafb00877093170John Hoford 686fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette public void setColorFilter(ColorFilter colorFilter) { 687fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mColorFilter = colorFilter; 688fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 689fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette if (mFillPaint != null) { 690fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mFillPaint.setColorFilter(colorFilter); 691fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } 692fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 693fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette if (mStrokePaint != null) { 694fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mStrokePaint.setColorFilter(colorFilter); 695fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } 6966d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui 697fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } 698fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 6994d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void drawGroupTree(VGroup currentGroup, Matrix currentMatrix, 7002af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui float currentAlpha, Canvas canvas, int w, int h) { 7014d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Calculate current group's matrix by preConcat the parent's and 7024d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // and the current one on the top of the stack. 7034d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Basically the Mfinal = Mviewport * M0 * M1 * M2; 7044d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Mi the local matrix at level i of the group tree. 7054d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui currentGroup.mStackedMatrix.set(currentMatrix); 7064d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 7074d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix); 7084d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 7092af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui float stackedAlpha = currentAlpha * currentGroup.mGroupAlpha; 7108d0d24f7a2b1a59060aa18926984491691d3c667ztenghui 7118d0d24f7a2b1a59060aa18926984491691d3c667ztenghui // Draw the group tree in the same order as the XML file. 7128d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < currentGroup.mChildren.size(); i++) { 7138d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = currentGroup.mChildren.get(i); 7148d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 7158d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 7168d0d24f7a2b1a59060aa18926984491691d3c667ztenghui drawGroupTree(childGroup, currentGroup.mStackedMatrix, 7178d0d24f7a2b1a59060aa18926984491691d3c667ztenghui stackedAlpha, canvas, w, h); 7188d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 7198d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 7208d0d24f7a2b1a59060aa18926984491691d3c667ztenghui drawPath(currentGroup, childPath, stackedAlpha, canvas, w, h); 7218d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 722abb7d134c02ac60091108c491dafb00877093170John Hoford } 7234d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 724abb7d134c02ac60091108c491dafb00877093170John Hoford 7254d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui public void draw(Canvas canvas, int w, int h) { 7264d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Travese the tree in pre-order to draw. 7272af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui drawGroupTree(mRootGroup, IDENTITY_MATRIX, ((float) mRootAlpha) / 0xFF, canvas, w, h); 728abb7d134c02ac60091108c491dafb00877093170John Hoford } 729abb7d134c02ac60091108c491dafb00877093170John Hoford 7308d0d24f7a2b1a59060aa18926984491691d3c667ztenghui private void drawPath(VGroup vGroup, VPath vPath, float stackedAlpha, 7318d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Canvas canvas, int w, int h) { 7329453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final float scale = Math.min(h / mViewportHeight, w / mViewportWidth); 733abb7d134c02ac60091108c491dafb00877093170John Hoford 7344d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mFinalPathMatrix.set(vGroup.mStackedMatrix); 7354d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mFinalPathMatrix.postScale(scale, scale, mViewportWidth / 2f, mViewportHeight / 2f); 7368e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mFinalPathMatrix.postTranslate( 7378e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette w / 2f - mViewportWidth / 2f, h / 2f - mViewportHeight / 2f); 738abb7d134c02ac60091108c491dafb00877093170John Hoford 7398d0d24f7a2b1a59060aa18926984491691d3c667ztenghui vPath.toPath(mPath); 7408d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final Path path = mPath; 741abb7d134c02ac60091108c491dafb00877093170John Hoford 7428d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mTrimPathStart != 0.0f || vPath.mTrimPathEnd != 1.0f) { 7438d0d24f7a2b1a59060aa18926984491691d3c667ztenghui float start = (vPath.mTrimPathStart + vPath.mTrimPathOffset) % 1.0f; 7448d0d24f7a2b1a59060aa18926984491691d3c667ztenghui float end = (vPath.mTrimPathEnd + vPath.mTrimPathOffset) % 1.0f; 7459453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 7468d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mPathMeasure == null) { 7478d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mPathMeasure = new PathMeasure(); 7484b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette } 7498d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mPathMeasure.setPath(mPath, false); 7508d0d24f7a2b1a59060aa18926984491691d3c667ztenghui 7518d0d24f7a2b1a59060aa18926984491691d3c667ztenghui float len = mPathMeasure.getLength(); 7528d0d24f7a2b1a59060aa18926984491691d3c667ztenghui start = start * len; 7538d0d24f7a2b1a59060aa18926984491691d3c667ztenghui end = end * len; 7548d0d24f7a2b1a59060aa18926984491691d3c667ztenghui path.reset(); 7558d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (start > end) { 7568d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mPathMeasure.getSegment(start, len, path, true); 7578d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mPathMeasure.getSegment(0f, end, path, true); 7588d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else { 7598d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mPathMeasure.getSegment(start, end, path, true); 7608d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 7618d0d24f7a2b1a59060aa18926984491691d3c667ztenghui path.rLineTo(0, 0); // fix bug in measure 7628d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 7634b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 7648d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mRenderPath.reset(); 7659453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 7668d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mRenderPath.addPath(path, mFinalPathMatrix); 7674b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 7688d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mClip) { 7698d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.clipPath(mRenderPath, Region.Op.REPLACE); 7708d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else { 7718d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mFillColor != 0) { 7728d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mFillPaint == null) { 7738d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint = new Paint(); 7748d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setColorFilter(mColorFilter); 7758d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setStyle(Paint.Style.FILL); 7768d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setAntiAlias(true); 77763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 7788d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setColor(applyAlpha(vPath.mFillColor, stackedAlpha)); 7798d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.drawPath(mRenderPath, mFillPaint); 7808d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 78163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 7828d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mStrokeColor != 0) { 7838d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mStrokePaint == null) { 7848d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint = new Paint(); 7858d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setColorFilter(mColorFilter); 7868d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setStyle(Paint.Style.STROKE); 7878d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setAntiAlias(true); 7888d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 7894b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 7908d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final Paint strokePaint = mStrokePaint; 7918d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mStrokeLineJoin != null) { 7928d0d24f7a2b1a59060aa18926984491691d3c667ztenghui strokePaint.setStrokeJoin(vPath.mStrokeLineJoin); 7938d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 794abb7d134c02ac60091108c491dafb00877093170John Hoford 7958d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mStrokeLineCap != null) { 7968d0d24f7a2b1a59060aa18926984491691d3c667ztenghui strokePaint.setStrokeCap(vPath.mStrokeLineCap); 7978d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 79863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 7998d0d24f7a2b1a59060aa18926984491691d3c667ztenghui strokePaint.setStrokeMiter(vPath.mStrokeMiterlimit * scale); 80063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 8018d0d24f7a2b1a59060aa18926984491691d3c667ztenghui strokePaint.setColor(applyAlpha(vPath.mStrokeColor, stackedAlpha)); 8028d0d24f7a2b1a59060aa18926984491691d3c667ztenghui strokePaint.setStrokeWidth(vPath.mStrokeWidth * scale); 8038d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.drawPath(mRenderPath, strokePaint); 80463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 805abb7d134c02ac60091108c491dafb00877093170John Hoford } 806abb7d134c02ac60091108c491dafb00877093170John Hoford } 807abb7d134c02ac60091108c491dafb00877093170John Hoford 808abb7d134c02ac60091108c491dafb00877093170John Hoford private void parseViewport(Resources r, AttributeSet attrs) 809abb7d134c02ac60091108c491dafb00877093170John Hoford throws XmlPullParserException { 8104b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette final TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableViewport); 8118e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 8128e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 8138e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations |= a.getChangingConfigurations(); 8148e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 8158e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mViewportWidth = a.getFloat( 8168e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette R.styleable.VectorDrawableViewport_viewportWidth, mViewportWidth); 8178e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mViewportHeight = a.getFloat( 8188e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette R.styleable.VectorDrawableViewport_viewportHeight, mViewportHeight); 819fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 820fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette if (mViewportWidth <= 0) { 821fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette throw new XmlPullParserException(a.getPositionDescription() + 822fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette "<viewport> tag requires viewportWidth > 0"); 823fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } else if (mViewportHeight <= 0) { 824fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette throw new XmlPullParserException(a.getPositionDescription() + 825fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette "<viewport> tag requires viewportHeight > 0"); 826abb7d134c02ac60091108c491dafb00877093170John Hoford } 827fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 828abb7d134c02ac60091108c491dafb00877093170John Hoford a.recycle(); 829abb7d134c02ac60091108c491dafb00877093170John Hoford } 830abb7d134c02ac60091108c491dafb00877093170John Hoford 831abb7d134c02ac60091108c491dafb00877093170John Hoford private void parseSize(Resources r, AttributeSet attrs) 8328d0d24f7a2b1a59060aa18926984491691d3c667ztenghui throws XmlPullParserException { 8334b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette final TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableSize); 8348e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 8358e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 8368e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations |= a.getChangingConfigurations(); 8378e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 838fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mBaseWidth = a.getDimension(R.styleable.VectorDrawableSize_width, mBaseWidth); 839fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mBaseHeight = a.getDimension(R.styleable.VectorDrawableSize_height, mBaseHeight); 840fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 841fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette if (mBaseWidth <= 0) { 842fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette throw new XmlPullParserException(a.getPositionDescription() + 843fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette "<size> tag requires width > 0"); 844fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } else if (mBaseHeight <= 0) { 845fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette throw new XmlPullParserException(a.getPositionDescription() + 846fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette "<size> tag requires height > 0"); 847abb7d134c02ac60091108c491dafb00877093170John Hoford } 848fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 849abb7d134c02ac60091108c491dafb00877093170John Hoford a.recycle(); 850abb7d134c02ac60091108c491dafb00877093170John Hoford } 8514b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 852abb7d134c02ac60091108c491dafb00877093170John Hoford } 853abb7d134c02ac60091108c491dafb00877093170John Hoford 854e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui static class VGroup { 85555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // mStackedMatrix is only used temporarily when drawing, it combines all 85655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // the parents' local matrices with the current one. 85755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final Matrix mStackedMatrix = new Matrix(); 85855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 85955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 86055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 8618d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> mChildren = new ArrayList<Object>(); 862abb7d134c02ac60091108c491dafb00877093170John Hoford 86363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mRotate = 0; 86463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mPivotX = 0; 86563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mPivotY = 0; 866452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mScaleX = 1; 867452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mScaleY = 1; 868452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mTranslateX = 0; 869452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mTranslateY = 0; 8702af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui private float mGroupAlpha = 1; 8714d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 87255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // mLocalMatrix is updated based on the update of transformation information, 87355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // either parsed from the XML or by animation. 8744d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private final Matrix mLocalMatrix = new Matrix(); 8758e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private int mChangingConfigurations; 87663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private int[] mThemeAttrs; 877e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui private String mGroupName = null; 878e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 87955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VGroup(VGroup copy, ArrayMap<String, Object> targetsMap) { 88055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRotate = copy.mRotate; 88155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPivotX = copy.mPivotX; 88255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPivotY = copy.mPivotY; 88355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mScaleX = copy.mScaleX; 88455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mScaleY = copy.mScaleY; 88555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTranslateX = copy.mTranslateX; 88655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTranslateY = copy.mTranslateY; 88755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mGroupAlpha = copy.mGroupAlpha; 88855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mThemeAttrs = copy.mThemeAttrs; 88955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mGroupName = copy.mGroupName; 89055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mChangingConfigurations = copy.mChangingConfigurations; 89155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (mGroupName != null) { 89255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui targetsMap.put(mGroupName, this); 89355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 89455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 89555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mLocalMatrix.set(copy.mLocalMatrix); 89655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 8978d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = copy.mChildren; 8988d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 8998d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object copyChild = children.get(i); 9008d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (copyChild instanceof VGroup) { 9018d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup copyGroup = (VGroup) copyChild; 9028d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mChildren.add(new VGroup(copyGroup, targetsMap)); 9038d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (copyChild instanceof VPath) { 9048d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath copyPath = (VPath) copyChild; 9058d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath newPath = new VPath(copyPath); 9068d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mChildren.add(newPath); 9078d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (newPath.mPathName != null) { 9088d0d24f7a2b1a59060aa18926984491691d3c667ztenghui targetsMap.put(newPath.mPathName, newPath); 9098d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 91055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 91155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 91255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 91355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 91455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VGroup() { 91555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 91655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 917e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui /* Getter and Setter */ 918e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getRotation() { 919e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mRotate; 920e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 921e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 922e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setRotation(float rotation) { 923e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (rotation != mRotate) { 924e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mRotate = rotation; 925e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 926e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 927e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 928e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 929e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getPivotX() { 930e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPivotX; 931e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 932e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 933e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setPivotX(float pivotX) { 934e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (pivotX != mPivotX) { 935e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mPivotX = pivotX; 936e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 937e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 938e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 939e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 940e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getPivotY() { 941e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPivotY; 942e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 943e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 944e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setPivotY(float pivotY) { 945e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (pivotY != mPivotY) { 946e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mPivotY = pivotY; 947e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 948e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 949e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 950e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 951e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getScaleX() { 952e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mScaleX; 953e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 9544d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 955e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setScaleX(float scaleX) { 956e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (scaleX != mScaleX) { 957e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mScaleX = scaleX; 958e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 959e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 960e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 961e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 962e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getScaleY() { 963e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mScaleY; 964e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 965e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 966e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setScaleY(float scaleY) { 967e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (scaleY != mScaleY) { 968e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mScaleY = scaleY; 969e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 970e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 971e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 972e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 973e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getTranslateX() { 974e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTranslateX; 975e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 976e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 977e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setTranslateX(float translateX) { 978e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (translateX != mTranslateX) { 979e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTranslateX = translateX; 980e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 981e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 982e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 983e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 984e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getTranslateY() { 985e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTranslateY; 986e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 987e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 988e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setTranslateY(float translateY) { 989e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (translateY != mTranslateY) { 990e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTranslateY = translateY; 991e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 992e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 993e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 994e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 995e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getAlpha() { 996e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mGroupAlpha; 997e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 998e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 999e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setAlpha(float groupAlpha) { 1000e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (groupAlpha != mGroupAlpha) { 1001e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mGroupAlpha = groupAlpha; 1002e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1003e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1004e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1005e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public String getGroupName() { 1006e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mGroupName; 10074d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 10084d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 10094d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui public Matrix getLocalMatrix() { 10104d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui return mLocalMatrix; 10114d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 10124d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 10134d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui public boolean canApplyTheme() { 10144d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui return mThemeAttrs != null; 10154d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 10164d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 10178e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette public void inflate(Resources res, AttributeSet attrs, Theme theme) { 10188e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final TypedArray a = obtainAttributes(res, theme, attrs, 10198e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette R.styleable.VectorDrawableGroup); 10208e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 10218e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette a.recycle(); 10228e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 10238e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 10248e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private void updateStateFromTypedArray(TypedArray a) { 10258e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 10268e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations |= a.getChangingConfigurations(); 102763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 10288e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Extract the theme attributes, if any. 10298e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mThemeAttrs = a.extractThemeAttrs(); 103063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 103163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui mRotate = a.getFloat(R.styleable.VectorDrawableGroup_rotation, mRotate); 103263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui mPivotX = a.getFloat(R.styleable.VectorDrawableGroup_pivotX, mPivotX); 103363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui mPivotY = a.getFloat(R.styleable.VectorDrawableGroup_pivotY, mPivotY); 1034452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui mScaleX = a.getFloat(R.styleable.VectorDrawableGroup_scaleX, mScaleX); 1035452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY); 1036452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX); 1037452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY); 10382af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mGroupAlpha = a.getFloat(R.styleable.VectorDrawableGroup_alpha, mGroupAlpha); 103963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 10408e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final String groupName = a.getString(R.styleable.VectorDrawableGroup_name); 10418e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette if (groupName != null) { 10428e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mGroupName = groupName; 104363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 104463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 10458e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateLocalMatrix(); 10468e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 10474d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 10488e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette public void applyTheme(Theme t) { 10498e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette if (mThemeAttrs == null) { 10508e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette return; 10514d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 10524d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 10538e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawablePath); 10548e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 105563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui a.recycle(); 105663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 105763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 10584d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void updateLocalMatrix() { 10594d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // The order we apply is the same as the 10604d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // RenderNode.cpp::applyViewPropertyTransforms(). 10614d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mLocalMatrix.reset(); 10624d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mLocalMatrix.postTranslate(-mPivotX, -mPivotY); 10634d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mLocalMatrix.postScale(mScaleX, mScaleY); 10644d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mLocalMatrix.postRotate(mRotate, 0, 0); 10654d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY); 10664d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 1067abb7d134c02ac60091108c491dafb00877093170John Hoford } 1068abb7d134c02ac60091108c491dafb00877093170John Hoford 1069cf4832f69c8786b098ce18c24319021f8cd6733aztenghui private static class VPath { 107055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 107155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 10729453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private int[] mThemeAttrs; 10739453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1074abb7d134c02ac60091108c491dafb00877093170John Hoford int mStrokeColor = 0; 1075abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeWidth = 0; 1076abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeOpacity = Float.NaN; 10772af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui int mFillColor = Color.BLACK; 1078abb7d134c02ac60091108c491dafb00877093170John Hoford int mFillRule; 1079abb7d134c02ac60091108c491dafb00877093170John Hoford float mFillOpacity = Float.NaN; 1080abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathStart = 0; 1081abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathEnd = 1; 1082abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathOffset = 0; 10839453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1084abb7d134c02ac60091108c491dafb00877093170John Hoford boolean mClip = false; 10854b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette Paint.Cap mStrokeLineCap = Paint.Cap.BUTT; 10864b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette Paint.Join mStrokeLineJoin = Paint.Join.MITER; 1087abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeMiterlimit = 4; 10889453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 108955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private PathParser.PathDataNode[] mNodes = null; 10908d0d24f7a2b1a59060aa18926984491691d3c667ztenghui String mPathName; 109155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private int mChangingConfigurations; 1092abb7d134c02ac60091108c491dafb00877093170John Hoford 10939453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public VPath() { 10949453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette // Empty constructor. 10959453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 10969453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 109755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VPath(VPath copy) { 109855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mThemeAttrs = copy.mThemeAttrs; 109955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 110055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeColor = copy.mStrokeColor; 110155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeWidth = copy.mStrokeWidth; 110255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeOpacity = copy.mStrokeOpacity; 110355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillColor = copy.mFillColor; 110455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillRule = copy.mFillRule; 110555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillOpacity = copy.mFillOpacity; 110655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathStart = copy.mTrimPathStart; 110755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathEnd = copy.mTrimPathEnd; 110855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathOffset = copy.mTrimPathOffset; 110955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 111055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mClip = copy.mClip; 111155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeLineCap = copy.mStrokeLineCap; 111255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeLineJoin = copy.mStrokeLineJoin; 111355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeMiterlimit = copy.mStrokeMiterlimit; 111455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 111555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mNodes = PathParser.deepCopyNodes(copy.mNodes); 111655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPathName = copy.mPathName; 111755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mChangingConfigurations = copy.mChangingConfigurations; 111855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 111955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 1120abb7d134c02ac60091108c491dafb00877093170John Hoford public void toPath(Path path) { 1121abb7d134c02ac60091108c491dafb00877093170John Hoford path.reset(); 112255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (mNodes != null) { 112355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui PathParser.PathDataNode.nodesToPath(mNodes, path); 1124abb7d134c02ac60091108c491dafb00877093170John Hoford } 1125abb7d134c02ac60091108c491dafb00877093170John Hoford } 1126abb7d134c02ac60091108c491dafb00877093170John Hoford 1127e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public String getPathName() { 1128e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPathName; 1129abb7d134c02ac60091108c491dafb00877093170John Hoford } 1130abb7d134c02ac60091108c491dafb00877093170John Hoford 11317f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette private Paint.Cap getStrokeLineCap(int id, Paint.Cap defValue) { 11327f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette switch (id) { 11337f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_BUTT: 11347f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.BUTT; 11357f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_ROUND: 11367f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.ROUND; 11377f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_SQUARE: 11387f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.SQUARE; 11397f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette default: 11407f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return defValue; 11417f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 11427f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 11437f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette 11447f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette private Paint.Join getStrokeLineJoin(int id, Paint.Join defValue) { 11457f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette switch (id) { 11467f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_MITER: 11477f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.MITER; 11487f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_ROUND: 11497f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.ROUND; 11507f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_BEVEL: 11517f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.BEVEL; 11527f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette default: 11537f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return defValue; 11547f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 11557f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 11567f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette 1157eb034fbca40006c55db143047eb628c4b657730aztenghui /* Setters and Getters, mostly used by animator from AnimatedVectorDrawable. */ 1158eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1159eb034fbca40006c55db143047eb628c4b657730aztenghui public PathParser.PathDataNode[] getPathData() { 116055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return mNodes; 1161eb034fbca40006c55db143047eb628c4b657730aztenghui } 1162eb034fbca40006c55db143047eb628c4b657730aztenghui 1163eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 116455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public void setPathData(PathParser.PathDataNode[] nodes) { 116555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (!PathParser.canMorph(mNodes, nodes)) { 1166eb034fbca40006c55db143047eb628c4b657730aztenghui // This should not happen in the middle of animation. 116755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mNodes = PathParser.deepCopyNodes(nodes); 1168eb034fbca40006c55db143047eb628c4b657730aztenghui } else { 116955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui PathParser.updateNodes(mNodes, nodes); 1170eb034fbca40006c55db143047eb628c4b657730aztenghui } 1171eb034fbca40006c55db143047eb628c4b657730aztenghui } 1172eb034fbca40006c55db143047eb628c4b657730aztenghui 1173eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1174e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui int getStroke() { 1175e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeColor; 1176e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1177e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1178eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1179e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setStroke(int strokeColor) { 1180e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeColor = strokeColor; 1181e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1182e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1183eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1184e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getStrokeWidth() { 1185e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeWidth; 1186e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1187e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1188eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1189e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setStrokeWidth(float strokeWidth) { 1190e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeWidth = strokeWidth; 1191e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1192e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1193eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1194e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getStrokeOpacity() { 1195e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeOpacity; 1196e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1197e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1198eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1199e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setStrokeOpacity(float strokeOpacity) { 1200e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeOpacity = strokeOpacity; 1201e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1202e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1203eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1204e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui int getFill() { 1205e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mFillColor; 1206e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1207e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1208eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1209e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setFill(int fillColor) { 1210e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mFillColor = fillColor; 1211e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1212e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1213eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1214e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getFillOpacity() { 1215e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mFillOpacity; 1216e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1217e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1218eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1219e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setFillOpacity(float fillOpacity) { 1220e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mFillOpacity = fillOpacity; 1221e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1222e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1223eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1224e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathStart() { 1225e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathStart; 1226e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1227e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1228eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1229e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathStart(float trimPathStart) { 1230e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathStart = trimPathStart; 1231e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1232e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1233eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1234e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathEnd() { 1235e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathEnd; 1236e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1237e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1238eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1239e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathEnd(float trimPathEnd) { 1240e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathEnd = trimPathEnd; 1241e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1242e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1243eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1244e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathOffset() { 1245e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathOffset; 1246e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1247e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1248eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1249e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathOffset(float trimPathOffset) { 1250e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathOffset = trimPathOffset; 1251e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1252e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 12538e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette public boolean canApplyTheme() { 12548e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette return mThemeAttrs != null; 12558e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 12568e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 12579453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public void inflate(Resources r, AttributeSet attrs, Theme theme) { 12589453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.VectorDrawablePath); 12598e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 1260abb7d134c02ac60091108c491dafb00877093170John Hoford a.recycle(); 1261abb7d134c02ac60091108c491dafb00877093170John Hoford } 1262abb7d134c02ac60091108c491dafb00877093170John Hoford 12638e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private void updateStateFromTypedArray(TypedArray a) { 12648e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 12658e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations |= a.getChangingConfigurations(); 12669453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 12678e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Extract the theme attributes, if any. 12688e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mThemeAttrs = a.extractThemeAttrs(); 12699453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 12707f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mClip = a.getBoolean(R.styleable.VectorDrawablePath_clipToPath, mClip); 127155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 12728e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mPathName = a.getString(R.styleable.VectorDrawablePath_name); 127355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mNodes = PathParser.createNodesFromPathData(a.getString( 12748e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette R.styleable.VectorDrawablePath_pathData)); 127555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 12767f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mFillColor = a.getColor(R.styleable.VectorDrawablePath_fill, mFillColor); 12777f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mFillOpacity = a.getFloat(R.styleable.VectorDrawablePath_fillOpacity, mFillOpacity); 12787f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeLineCap = getStrokeLineCap(a.getInt( 12797f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_strokeLineCap, -1), mStrokeLineCap); 12807f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeLineJoin = getStrokeLineJoin(a.getInt( 12817f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_strokeLineJoin, -1), mStrokeLineJoin); 12827f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeMiterlimit = a.getFloat( 12837f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_strokeMiterLimit, mStrokeMiterlimit); 12847f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_stroke, mStrokeColor); 12857f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeOpacity = a.getFloat( 12867f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_strokeOpacity, mStrokeOpacity); 12877f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, mStrokeWidth); 12887f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd, mTrimPathEnd); 12897f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mTrimPathOffset = a.getFloat( 12907f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_trimPathOffset, mTrimPathOffset); 12917f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mTrimPathStart = a.getFloat( 12927f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_trimPathStart, mTrimPathStart); 12939453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 12949453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette updateColorAlphas(); 12958e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 12968e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 12978e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette public void applyTheme(Theme t) { 12988e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette if (mThemeAttrs == null) { 12998e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette return; 13008e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 13018e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 13028e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawablePath); 13038e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 130463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui a.recycle(); 13059453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 13069453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 13079453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private void updateColorAlphas() { 13089453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette if (!Float.isNaN(mFillOpacity)) { 13092af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mFillColor = applyAlpha(mFillColor, mFillOpacity); 13109453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 13119453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 13129453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette if (!Float.isNaN(mStrokeOpacity)) { 13132af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mStrokeColor = applyAlpha(mStrokeColor, mStrokeOpacity); 13149453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 13159453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 1316abb7d134c02ac60091108c491dafb00877093170John Hoford } 1317abb7d134c02ac60091108c491dafb00877093170John Hoford} 1318