1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 15package org.robolectric.shadows; 16 17import static android.os.Build.VERSION_CODES.N; 18import static org.robolectric.shadows.ShadowVirtualRefBasePtr.get; 19import static org.robolectric.shadows.ShadowVirtualRefBasePtr.put; 20 21import android.graphics.drawable.VectorDrawable; 22import java.nio.ByteBuffer; 23import java.nio.ByteOrder; 24import org.robolectric.annotation.Implementation; 25import org.robolectric.annotation.Implements; 26 27@Implements(value = VectorDrawable.class, minSdk = N) 28public class ShadowVectorDrawable extends ShadowDrawable { 29 // private static native long nCreateTree(long rootGroupPtr); 30// private static native long nCreateTreeFromCopy(long treeToCopy, long rootGroupPtr); 31// private static native void nSetRendererViewportSize(long rendererPtr, float viewportWidth, 32// float viewportHeight); 33// private static native boolean nSetRootAlpha(long rendererPtr, float alpha); 34// private static native float nGetRootAlpha(long rendererPtr); 35// private static native void nSetAllowCaching(long rendererPtr, boolean allowCaching); 36// 37// private static native int nDraw(long rendererPtr, long canvasWrapperPtr, 38// long colorFilterPtr, Rect bounds, boolean needsMirroring, boolean canReuseCache); 39 40 private static final int STROKE_WIDTH_INDEX = 0; 41 private static final int STROKE_COLOR_INDEX = 1; 42 private static final int STROKE_ALPHA_INDEX = 2; 43 private static final int FILL_COLOR_INDEX = 3; 44 private static final int FILL_ALPHA_INDEX = 4; 45 private static final int TRIM_PATH_START_INDEX = 5; 46 private static final int TRIM_PATH_END_INDEX = 6; 47 private static final int TRIM_PATH_OFFSET_INDEX = 7; 48 private static final int STROKE_LINE_CAP_INDEX = 8; 49 private static final int STROKE_LINE_JOIN_INDEX = 9; 50 private static final int STROKE_MITER_LIMIT_INDEX = 10; 51 private static final int FILL_TYPE_INDEX = 11; 52 private static final int TOTAL_PROPERTY_COUNT = 12; 53 54 private static class Path implements Cloneable { 55 float strokeWidth; 56 int strokeColor; 57 float strokeAlpha; 58 int fillColor; 59 float fillAlpha; 60 float trimPathStart; 61 float trimPathEnd; 62 float trimPathOffset; 63 int strokeLineCap; 64 int strokeLineJoin; 65 float strokeMiterLimit; 66 int fillType; 67 68 @Override 69 protected Object clone() { 70 try { 71 return super.clone(); 72 } catch (CloneNotSupportedException e) { 73 throw new RuntimeException(e); 74 } 75 } 76 } 77 78 private static Path getPath(long pathPtr) { 79 return get(pathPtr, Path.class); 80 } 81 82 83 @Implementation 84 public static long nCreateFullPath() { 85 return put(new Path()); 86 } 87 88 @Implementation 89 public static long nCreateFullPath(long nativeFullPathPtr) { 90 return put(getPath(nativeFullPathPtr).clone()); 91 } 92 93 @Implementation 94 public static boolean nGetFullPathProperties(long pathPtr, byte[] properties, 95 int length) { 96 if (length != TOTAL_PROPERTY_COUNT * 4) return false; 97 98 Path path = getPath(pathPtr); 99 ByteBuffer propertiesBB = ByteBuffer.wrap(properties); 100 propertiesBB.order(ByteOrder.nativeOrder()); 101 propertiesBB.putFloat(STROKE_WIDTH_INDEX * 4, path.strokeWidth); 102 propertiesBB.putInt(STROKE_COLOR_INDEX * 4, path.strokeColor); 103 propertiesBB.putFloat(STROKE_ALPHA_INDEX * 4, path.strokeAlpha); 104 propertiesBB.putInt(FILL_COLOR_INDEX * 4, path.fillColor); 105 propertiesBB.putFloat(FILL_ALPHA_INDEX * 4, path.fillAlpha); 106 propertiesBB.putFloat(TRIM_PATH_START_INDEX * 4, path.trimPathStart); 107 propertiesBB.putFloat(TRIM_PATH_END_INDEX * 4, path.trimPathEnd); 108 propertiesBB.putFloat(TRIM_PATH_OFFSET_INDEX * 4, path.trimPathOffset); 109 propertiesBB.putInt(STROKE_LINE_CAP_INDEX * 4, path.strokeLineCap); 110 propertiesBB.putInt(STROKE_LINE_JOIN_INDEX * 4, path.strokeLineJoin); 111 propertiesBB.putFloat(STROKE_MITER_LIMIT_INDEX * 4, path.strokeMiterLimit); 112 propertiesBB.putInt(FILL_TYPE_INDEX * 4, path.fillType); 113 114 return true; 115 } 116 117 @Implementation 118 public static void nUpdateFullPathProperties(long pathPtr, float strokeWidth, 119 int strokeColor, float strokeAlpha, int fillColor, float fillAlpha, float trimPathStart, 120 float trimPathEnd, float trimPathOffset, float strokeMiterLimit, int strokeLineCap, 121 int strokeLineJoin, int fillType) { 122 Path path = getPath(pathPtr); 123 path.strokeWidth = strokeWidth; 124 path.strokeColor = strokeColor; 125 path.strokeAlpha = strokeAlpha; 126 path.fillColor = fillColor; 127 path.fillAlpha = fillAlpha; 128 path.trimPathStart = trimPathStart; 129 path.trimPathEnd = trimPathEnd; 130 path.trimPathOffset = trimPathOffset; 131 path.strokeLineCap = strokeLineCap; 132 path.strokeLineJoin = strokeLineJoin; 133 path.strokeMiterLimit = strokeMiterLimit; 134 path.fillType = fillType; 135 } 136 137// @Implementation 138// public static void nUpdateFullPathFillGradient(long pathPtr, long fillGradientPtr) { 139// 140// } 141// 142// @Implementation 143// public static void nUpdateFullPathStrokeGradient(long pathPtr, long strokeGradientPtr) { 144// 145// } 146// 147// private static native long nCreateClipPath(); 148// private static native long nCreateClipPath(long clipPathPtr); 149 150 151 static class Group implements Cloneable { 152 float rotation; 153 float pivotX; 154 float pivotY; 155 float scaleX; 156 float scaleY; 157 float translateX; 158 float translateY; 159 160 @Override 161 protected Object clone() { 162 try { 163 return super.clone(); 164 } catch (CloneNotSupportedException e) { 165 throw new RuntimeException(e); 166 } 167 } 168 } 169 170 private static Group getGroup(long groupPtr) { 171 return get(groupPtr, Group.class); 172 } 173 174 @Implementation 175 public static long nCreateGroup() { 176 return put(new Group()); 177 } 178 179 @Implementation 180 public static long nCreateGroup(long groupPtr) { 181 return put(getGroup(groupPtr).clone()); 182 } 183 184// public static void nSetName(long nodePtr, String name) { 185// } 186 187 @Implementation 188 public static boolean nGetGroupProperties(long groupPtr, float[] properties, 189 int length) { 190 if (length != 7) return false; 191 Group group = getGroup(groupPtr); 192 properties[0] = group.rotation; 193 properties[1] = group.pivotX; 194 properties[2] = group.pivotY; 195 properties[3] = group.scaleX; 196 properties[4] = group.scaleY; 197 properties[5] = group.translateX; 198 properties[6] = group.translateY; 199 return true; 200 } 201 202 @Implementation 203 public static void nUpdateGroupProperties(long groupPtr, float rotate, float pivotX, 204 float pivotY, float scaleX, float scaleY, float translateX, float translateY) { 205 Group group = getGroup(groupPtr); 206 group.rotation = rotate; 207 group.pivotX = pivotX; 208 group.pivotY = pivotY; 209 group.scaleX = scaleX; 210 group.scaleY = scaleY; 211 group.translateX = translateX; 212 group.translateY = translateY; 213 } 214 215// private static native void nAddChild(long groupPtr, long nodePtr); 216// private static native void nSetPathString(long pathPtr, String pathString, int length); 217// 218// /** 219// * The setters and getters below for paths and groups are here temporarily, and will be 220// * removed once the animation in AVD is replaced with RenderNodeAnimator, in which case the 221// * animation will modify these properties in native. By then no JNI hopping would be necessary 222// * for VD during animation, and these setters and getters will be obsolete. 223// */ 224// // Setters and getters during animation. 225// private static native float nGetRotation(long groupPtr); 226// private static native void nSetRotation(long groupPtr, float rotation); 227// private static native float nGetPivotX(long groupPtr); 228// private static native void nSetPivotX(long groupPtr, float pivotX); 229// private static native float nGetPivotY(long groupPtr); 230// private static native void nSetPivotY(long groupPtr, float pivotY); 231// private static native float nGetScaleX(long groupPtr); 232// private static native void nSetScaleX(long groupPtr, float scaleX); 233// private static native float nGetScaleY(long groupPtr); 234// private static native void nSetScaleY(long groupPtr, float scaleY); 235// private static native float nGetTranslateX(long groupPtr); 236// private static native void nSetTranslateX(long groupPtr, float translateX); 237// private static native float nGetTranslateY(long groupPtr); 238// private static native void nSetTranslateY(long groupPtr, float translateY); 239// 240// // Setters and getters for VPath during animation. 241// private static native void nSetPathData(long pathPtr, long pathDataPtr); 242// private static native float nGetStrokeWidth(long pathPtr); 243// private static native void nSetStrokeWidth(long pathPtr, float width); 244// private static native int nGetStrokeColor(long pathPtr); 245// private static native void nSetStrokeColor(long pathPtr, int strokeColor); 246// private static native float nGetStrokeAlpha(long pathPtr); 247// private static native void nSetStrokeAlpha(long pathPtr, float alpha); 248// private static native int nGetFillColor(long pathPtr); 249// private static native void nSetFillColor(long pathPtr, int fillColor); 250// private static native float nGetFillAlpha(long pathPtr); 251// private static native void nSetFillAlpha(long pathPtr, float fillAlpha); 252// private static native float nGetTrimPathStart(long pathPtr); 253// private static native void nSetTrimPathStart(long pathPtr, float trimPathStart); 254// private static native float nGetTrimPathEnd(long pathPtr); 255// private static native void nSetTrimPathEnd(long pathPtr, float trimPathEnd); 256// private static native float nGetTrimPathOffset(long pathPtr); 257// private static native void nSetTrimPathOffset(long pathPtr, float trimPathOffset); 258 259}