/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package org.robolectric.shadows; import android.graphics.drawable.VectorDrawable; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import java.nio.ByteBuffer; import java.nio.ByteOrder; import static android.os.Build.VERSION_CODES.N; import static org.robolectric.shadows.ShadowVirtualRefBasePtr.get; import static org.robolectric.shadows.ShadowVirtualRefBasePtr.put; @Implements(value = VectorDrawable.class, minSdk = N) public class ShadowVectorDrawable extends ShadowDrawable { // private static native long nCreateTree(long rootGroupPtr); // private static native long nCreateTreeFromCopy(long treeToCopy, long rootGroupPtr); // private static native void nSetRendererViewportSize(long rendererPtr, float viewportWidth, // float viewportHeight); // private static native boolean nSetRootAlpha(long rendererPtr, float alpha); // private static native float nGetRootAlpha(long rendererPtr); // private static native void nSetAllowCaching(long rendererPtr, boolean allowCaching); // // private static native int nDraw(long rendererPtr, long canvasWrapperPtr, // long colorFilterPtr, Rect bounds, boolean needsMirroring, boolean canReuseCache); private static final int STROKE_WIDTH_INDEX = 0; private static final int STROKE_COLOR_INDEX = 1; private static final int STROKE_ALPHA_INDEX = 2; private static final int FILL_COLOR_INDEX = 3; private static final int FILL_ALPHA_INDEX = 4; private static final int TRIM_PATH_START_INDEX = 5; private static final int TRIM_PATH_END_INDEX = 6; private static final int TRIM_PATH_OFFSET_INDEX = 7; private static final int STROKE_LINE_CAP_INDEX = 8; private static final int STROKE_LINE_JOIN_INDEX = 9; private static final int STROKE_MITER_LIMIT_INDEX = 10; private static final int FILL_TYPE_INDEX = 11; private static final int TOTAL_PROPERTY_COUNT = 12; private static class Path implements Cloneable { float strokeWidth; int strokeColor; float strokeAlpha; int fillColor; float fillAlpha; float trimPathStart; float trimPathEnd; float trimPathOffset; int strokeLineCap; int strokeLineJoin; float strokeMiterLimit; int fillType; @Override protected Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } } } private static Path getPath(long pathPtr) { return get(pathPtr); } @Implementation public static long nCreateFullPath() { return put(new Path()); } @Implementation public static long nCreateFullPath(long nativeFullPathPtr) { return put(getPath(nativeFullPathPtr).clone()); } @Implementation public static boolean nGetFullPathProperties(long pathPtr, byte[] properties, int length) { if (length != TOTAL_PROPERTY_COUNT * 4) return false; Path path = getPath(pathPtr); ByteBuffer propertiesBB = ByteBuffer.wrap(properties); propertiesBB.order(ByteOrder.nativeOrder()); propertiesBB.putFloat(STROKE_WIDTH_INDEX * 4, path.strokeWidth); propertiesBB.putInt(STROKE_COLOR_INDEX * 4, path.strokeColor); propertiesBB.putFloat(STROKE_ALPHA_INDEX * 4, path.strokeAlpha); propertiesBB.putInt(FILL_COLOR_INDEX * 4, path.fillColor); propertiesBB.putFloat(FILL_ALPHA_INDEX * 4, path.fillAlpha); propertiesBB.putFloat(TRIM_PATH_START_INDEX * 4, path.trimPathStart); propertiesBB.putFloat(TRIM_PATH_END_INDEX * 4, path.trimPathEnd); propertiesBB.putFloat(TRIM_PATH_OFFSET_INDEX * 4, path.trimPathOffset); propertiesBB.putInt(STROKE_LINE_CAP_INDEX * 4, path.strokeLineCap); propertiesBB.putInt(STROKE_LINE_JOIN_INDEX * 4, path.strokeLineJoin); propertiesBB.putFloat(STROKE_MITER_LIMIT_INDEX * 4, path.strokeMiterLimit); propertiesBB.putInt(FILL_TYPE_INDEX * 4, path.fillType); return true; } @Implementation public static void nUpdateFullPathProperties(long pathPtr, float strokeWidth, int strokeColor, float strokeAlpha, int fillColor, float fillAlpha, float trimPathStart, float trimPathEnd, float trimPathOffset, float strokeMiterLimit, int strokeLineCap, int strokeLineJoin, int fillType) { Path path = getPath(pathPtr); path.strokeWidth = strokeWidth; path.strokeColor = strokeColor; path.strokeAlpha = strokeAlpha; path.fillColor = fillColor; path.fillAlpha = fillAlpha; path.trimPathStart = trimPathStart; path.trimPathEnd = trimPathEnd; path.trimPathOffset = trimPathOffset; path.strokeLineCap = strokeLineCap; path.strokeLineJoin = strokeLineJoin; path.strokeMiterLimit = strokeMiterLimit; path.fillType = fillType; } // @Implementation // public static void nUpdateFullPathFillGradient(long pathPtr, long fillGradientPtr) { // // } // // @Implementation // public static void nUpdateFullPathStrokeGradient(long pathPtr, long strokeGradientPtr) { // // } // // private static native long nCreateClipPath(); // private static native long nCreateClipPath(long clipPathPtr); static class Group implements Cloneable { float rotation; float pivotX; float pivotY; float scaleX; float scaleY; float translateX; float translateY; @Override protected Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } } } private static Group getGroup(long groupPtr) { return get(groupPtr); } @Implementation public static long nCreateGroup() { return put(new Group()); } @Implementation public static long nCreateGroup(long groupPtr) { return put(getGroup(groupPtr).clone()); } // public static void nSetName(long nodePtr, String name) { // } @Implementation public static boolean nGetGroupProperties(long groupPtr, float[] properties, int length) { if (length != 7) return false; Group group = getGroup(groupPtr); properties[0] = group.rotation; properties[1] = group.pivotX; properties[2] = group.pivotY; properties[3] = group.scaleX; properties[4] = group.scaleY; properties[5] = group.translateX; properties[6] = group.translateY; return true; } @Implementation public static void nUpdateGroupProperties(long groupPtr, float rotate, float pivotX, float pivotY, float scaleX, float scaleY, float translateX, float translateY) { Group group = getGroup(groupPtr); group.rotation = rotate; group.pivotX = pivotX; group.pivotY = pivotY; group.scaleX = scaleX; group.scaleY = scaleY; group.translateX = translateX; group.translateY = translateY; } // private static native void nAddChild(long groupPtr, long nodePtr); // private static native void nSetPathString(long pathPtr, String pathString, int length); // // /** // * The setters and getters below for paths and groups are here temporarily, and will be // * removed once the animation in AVD is replaced with RenderNodeAnimator, in which case the // * animation will modify these properties in native. By then no JNI hopping would be necessary // * for VD during animation, and these setters and getters will be obsolete. // */ // // Setters and getters during animation. // private static native float nGetRotation(long groupPtr); // private static native void nSetRotation(long groupPtr, float rotation); // private static native float nGetPivotX(long groupPtr); // private static native void nSetPivotX(long groupPtr, float pivotX); // private static native float nGetPivotY(long groupPtr); // private static native void nSetPivotY(long groupPtr, float pivotY); // private static native float nGetScaleX(long groupPtr); // private static native void nSetScaleX(long groupPtr, float scaleX); // private static native float nGetScaleY(long groupPtr); // private static native void nSetScaleY(long groupPtr, float scaleY); // private static native float nGetTranslateX(long groupPtr); // private static native void nSetTranslateX(long groupPtr, float translateX); // private static native float nGetTranslateY(long groupPtr); // private static native void nSetTranslateY(long groupPtr, float translateY); // // // Setters and getters for VPath during animation. // private static native void nSetPathData(long pathPtr, long pathDataPtr); // private static native float nGetStrokeWidth(long pathPtr); // private static native void nSetStrokeWidth(long pathPtr, float width); // private static native int nGetStrokeColor(long pathPtr); // private static native void nSetStrokeColor(long pathPtr, int strokeColor); // private static native float nGetStrokeAlpha(long pathPtr); // private static native void nSetStrokeAlpha(long pathPtr, float alpha); // private static native int nGetFillColor(long pathPtr); // private static native void nSetFillColor(long pathPtr, int fillColor); // private static native float nGetFillAlpha(long pathPtr); // private static native void nSetFillAlpha(long pathPtr, float fillAlpha); // private static native float nGetTrimPathStart(long pathPtr); // private static native void nSetTrimPathStart(long pathPtr, float trimPathStart); // private static native float nGetTrimPathEnd(long pathPtr); // private static native void nSetTrimPathEnd(long pathPtr, float trimPathEnd); // private static native float nGetTrimPathOffset(long pathPtr); // private static native void nSetTrimPathOffset(long pathPtr, float trimPathOffset); }