Matrix_Delegate.java revision 88a8364c386c694f7ad56662ef89713dbf7c9d63
1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2010 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License. 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See the License for the specific language governing permissions and 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * limitations under the License. 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipackage android.graphics; 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.LayoutLog; 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.Bridge; 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.impl.DelegateManager; 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.tools.layoutlib.annotations.LayoutlibDelegate; 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.Matrix.ScaleToFit; 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.awt.geom.AffineTransform; 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.awt.geom.NoninvertibleTransformException; 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/** 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Delegate implementing the native methods of android.graphics.Matrix 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Through the layoutlib_create tool, the original native methods of Matrix have been replaced 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * by calls to methods of the same name in this delegate class. 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * This class behaves like the original native implementation, but in Java, keeping previously 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * native data into its own objects and mapping them to int that are sent back and forth between 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * it and the original Matrix class. 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see DelegateManager 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic final class Matrix_Delegate { 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final static int MATRIX_SIZE = 9; 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ---- delegate manager ---- 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static final DelegateManager<Matrix_Delegate> sManager = 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new DelegateManager<Matrix_Delegate>(Matrix_Delegate.class); 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ---- delegate data ---- 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private float mValues[] = new float[MATRIX_SIZE]; 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ---- Public Helper methods ---- 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 5688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath public static Matrix_Delegate getDelegate(long native_instance) { 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return sManager.getDelegate(native_instance); 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns an {@link AffineTransform} matching the given Matrix. 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static AffineTransform getAffineTransform(Matrix m) { 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate delegate = sManager.getDelegate(m.native_instance); 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (delegate == null) { 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return null; 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return delegate.getAffineTransform(); 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static boolean hasPerspective(Matrix m) { 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate delegate = sManager.getDelegate(m.native_instance); 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (delegate == null) { 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return delegate.hasPerspective(); 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Sets the content of the matrix with the content of another matrix. 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void set(Matrix_Delegate matrix) { 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski System.arraycopy(matrix.mValues, 0, mValues, 0, MATRIX_SIZE); 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Sets the content of the matrix with the content of another matrix represented as an array 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * of values. 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void set(float[] values) { 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski System.arraycopy(values, 0, mValues, 0, MATRIX_SIZE); 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Resets the matrix to be the identity matrix. 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void reset() { 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reset(mValues); 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns whether or not the matrix is identity. 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public boolean isIdentity() { 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 0, k = 0; i < 3; i++) { 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int j = 0; j < 3; j++, k++) { 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mValues[k] != ((i==j) ? 1 : 0)) { 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static float[] makeValues(AffineTransform matrix) { 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float[] values = new float[MATRIX_SIZE]; 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski values[0] = (float) matrix.getScaleX(); 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski values[1] = (float) matrix.getShearX(); 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski values[2] = (float) matrix.getTranslateX(); 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski values[3] = (float) matrix.getShearY(); 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski values[4] = (float) matrix.getScaleY(); 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski values[5] = (float) matrix.getTranslateY(); 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski values[6] = 0.f; 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski values[7] = 0.f; 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski values[8] = 1.f; 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return values; 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static Matrix_Delegate make(AffineTransform matrix) { 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new Matrix_Delegate(makeValues(matrix)); 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public boolean mapRect(RectF dst, RectF src) { 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // array with 4 corners 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float[] corners = new float[] { 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski src.left, src.top, 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski src.right, src.top, 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski src.right, src.bottom, 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski src.left, src.bottom, 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }; 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // apply the transform to them. 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mapPoints(corners); 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // now put the result in the rect. We take the min/max of Xs and min/max of Ys 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dst.left = Math.min(Math.min(corners[0], corners[2]), Math.min(corners[4], corners[6])); 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dst.right = Math.max(Math.max(corners[0], corners[2]), Math.max(corners[4], corners[6])); 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dst.top = Math.min(Math.min(corners[1], corners[3]), Math.min(corners[5], corners[7])); 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dst.bottom = Math.max(Math.max(corners[1], corners[3]), Math.max(corners[5], corners[7])); 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (computeTypeMask() & kRectStaysRect_Mask) != 0; 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns an {@link AffineTransform} matching the matrix. 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public AffineTransform getAffineTransform() { 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return getAffineTransform(mValues); 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public boolean hasPerspective() { 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (mValues[6] != 0 || mValues[7] != 0 || mValues[8] != 1); 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ---- native methods ---- 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 17788a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static long native_create(long native_src_or_zero) { 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // create the delegate 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate newDelegate = new Matrix_Delegate(); 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // copy from values if needed. 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (native_src_or_zero > 0) { 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate oldDelegate = sManager.getDelegate(native_src_or_zero); 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (oldDelegate != null) { 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski System.arraycopy( 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski oldDelegate.mValues, 0, 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski newDelegate.mValues, 0, 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MATRIX_SIZE); 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return sManager.addNewDelegate(newDelegate); 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 19688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_isIdentity(long native_object) { 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return d.isIdentity(); 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 20688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_rectStaysRect(long native_object) { 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (d.computeTypeMask() & kRectStaysRect_Mask) != 0; 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 21688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void native_reset(long native_object) { 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reset(d.mValues); 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 22688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void native_set(long native_object, long other) { 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate src = sManager.getDelegate(other); 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (src == null) { 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski System.arraycopy(src.mValues, 0, d.mValues, 0, MATRIX_SIZE); 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 24188a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void native_setTranslate(long native_object, float dx, float dy) { 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski setTranslate(d.mValues, dx, dy); 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 25188a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void native_setScale(long native_object, float sx, float sy, 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float px, float py) { 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues = getScale(sx, sy, px, py); 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 26288a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void native_setScale(long native_object, float sx, float sy) { 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[0] = sx; 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[1] = 0; 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[2] = 0; 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[3] = 0; 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[4] = sy; 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[5] = 0; 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[6] = 0; 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[7] = 0; 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[8] = 1; 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 28088a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void native_setRotate(long native_object, float degrees, float px, float py) { 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues = getRotate(degrees, px, py); 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 29088a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void native_setRotate(long native_object, float degrees) { 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski setRotate(d.mValues, degrees); 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 30088a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void native_setSinCos(long native_object, float sinValue, float cosValue, 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float px, float py) { 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // TODO: do it in one pass 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // translate so that the pivot is in 0,0 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski setTranslate(d.mValues, -px, -py); 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // scale 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.postTransform(getRotate(sinValue, cosValue)); 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // translate back the pivot 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.postTransform(getTranslate(px, py)); 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 31988a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void native_setSinCos(long native_object, float sinValue, float cosValue) { 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski setRotate(d.mValues, sinValue, cosValue); 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 32988a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void native_setSkew(long native_object, float kx, float ky, 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float px, float py) { 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues = getSkew(kx, ky, px, py); 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 34088a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void native_setSkew(long native_object, float kx, float ky) { 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[0] = 1; 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[1] = kx; 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[2] = -0; 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[3] = ky; 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[4] = 1; 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[5] = 0; 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[6] = 0; 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[7] = 0; 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[8] = 1; 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 35888a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_setConcat(long native_object, long a, long b) { 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (a == native_object) { 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return native_preConcat(native_object, b); 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (b == native_object) { 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return native_postConcat(native_object, a); 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate a_mtx = sManager.getDelegate(a); 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (a_mtx == null) { 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate b_mtx = sManager.getDelegate(b); 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (b_mtx == null) { 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski multiply(d.mValues, a_mtx.mValues, b_mtx.mValues); 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 38688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_preTranslate(long native_object, float dx, float dy) { 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.preTransform(getTranslate(dx, dy)); 393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 39788a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_preScale(long native_object, float sx, float sy, 398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float px, float py) { 399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.preTransform(getScale(sx, sy, px, py)); 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 40988a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_preScale(long native_object, float sx, float sy) { 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.preTransform(getScale(sx, sy)); 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 42088a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_preRotate(long native_object, float degrees, 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float px, float py) { 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.preTransform(getRotate(degrees, px, py)); 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 43288a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_preRotate(long native_object, float degrees) { 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski double rad = Math.toRadians(degrees); 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float sin = (float)Math.sin(rad); 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float cos = (float)Math.cos(rad); 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.preTransform(getRotate(sin, cos)); 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 44788a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_preSkew(long native_object, float kx, float ky, 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float px, float py) { 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.preTransform(getSkew(kx, ky, px, py)); 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 45988a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_preSkew(long native_object, float kx, float ky) { 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.preTransform(getSkew(kx, ky)); 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 47088a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_preConcat(long native_object, long other_matrix) { 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate other = sManager.getDelegate(other_matrix); 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (other == null) { 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.preTransform(other.mValues); 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 48688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_postTranslate(long native_object, float dx, float dy) { 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.postTransform(getTranslate(dx, dy)); 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 49788a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_postScale(long native_object, float sx, float sy, 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float px, float py) { 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.postTransform(getScale(sx, sy, px, py)); 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 50988a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_postScale(long native_object, float sx, float sy) { 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.postTransform(getScale(sx, sy)); 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 52088a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_postRotate(long native_object, float degrees, 521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float px, float py) { 522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.postTransform(getRotate(degrees, px, py)); 528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 53288a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_postRotate(long native_object, float degrees) { 533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.postTransform(getRotate(degrees)); 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 54388a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_postSkew(long native_object, float kx, float ky, 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float px, float py) { 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.postTransform(getSkew(kx, ky, px, py)); 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 55588a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_postSkew(long native_object, float kx, float ky) { 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.postTransform(getSkew(kx, ky)); 562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 56688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_postConcat(long native_object, long other_matrix) { 567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate other = sManager.getDelegate(other_matrix); 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (other == null) { 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.postTransform(other.mValues); 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 58288a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_setRectToRect(long native_object, RectF src, 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RectF dst, int stf) { 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (src.isEmpty()) { 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reset(d.mValues); 591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dst.isEmpty()) { 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[0] = d.mValues[1] = d.mValues[2] = d.mValues[3] = d.mValues[4] = d.mValues[5] 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski = d.mValues[6] = d.mValues[7] = 0; 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[8] = 1; 598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float tx, sx = dst.width() / src.width(); 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float ty, sy = dst.height() / src.height(); 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski boolean xLarger = false; 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (stf != ScaleToFit.FILL.nativeInt) { 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sx > sy) { 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski xLarger = true; 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sx = sy; 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sy = sx; 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tx = dst.left - src.left * sx; 613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ty = dst.top - src.top * sy; 614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (stf == ScaleToFit.CENTER.nativeInt || stf == ScaleToFit.END.nativeInt) { 615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float diff; 616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (xLarger) { 618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski diff = dst.width() - src.width() * sy; 619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski diff = dst.height() - src.height() * sy; 621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (stf == ScaleToFit.CENTER.nativeInt) { 624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski diff = diff / 2; 625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (xLarger) { 628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tx += diff; 629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ty += diff; 631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[0] = sx; 635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[4] = sy; 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[2] = tx; 637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[5] = ty; 638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[1] = d.mValues[3] = d.mValues[6] = d.mValues[7] = 0; 639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // shared cleanup 642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mValues[8] = 1; 643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 64788a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_setPolyToPoly(long native_object, float[] src, int srcIndex, 648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float[] dst, int dstIndex, int pointCount) { 649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // FIXME 650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, 651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Matrix.setPolyToPoly is not supported.", 652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski null, null /*data*/); 653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 65788a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_invert(long native_object, int inverse) { 658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate inv_mtx = sManager.getDelegate(inverse); 664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (inv_mtx == null) { 665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AffineTransform affineTransform = d.getAffineTransform(); 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AffineTransform inverseTransform = affineTransform.createInverse(); 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inv_mtx.mValues[0] = (float)inverseTransform.getScaleX(); 672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inv_mtx.mValues[1] = (float)inverseTransform.getShearX(); 673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inv_mtx.mValues[2] = (float)inverseTransform.getTranslateX(); 674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inv_mtx.mValues[3] = (float)inverseTransform.getScaleX(); 675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inv_mtx.mValues[4] = (float)inverseTransform.getShearY(); 676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski inv_mtx.mValues[5] = (float)inverseTransform.getTranslateY(); 677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } catch (NoninvertibleTransformException e) { 680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 68588a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void native_mapPoints(long native_object, float[] dst, int dstIndex, 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float[] src, int srcIndex, int ptCount, boolean isPts) { 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (isPts) { 693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mapPoints(dst, dstIndex, src, srcIndex, ptCount); 694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mapVectors(dst, dstIndex, src, srcIndex, ptCount); 696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 70088a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_mapRect(long native_object, RectF dst, RectF src) { 701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return d.mapRect(dst, src); 707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 71088a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static float native_mapRadius(long native_object, float radius) { 711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0.f; 714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float[] src = new float[] { radius, 0.f, 0.f, radius }; 717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.mapVectors(src, 0, src, 0, 2); 718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float l1 = getPointLength(src, 0); 720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float l2 = getPointLength(src, 2); 721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (float) Math.sqrt(l1 * l2); 723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 72688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void native_getValues(long native_object, float[] values) { 727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski System.arraycopy(d.mValues, 0, d.mValues, 0, MATRIX_SIZE); 733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 73688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void native_setValues(long native_object, float[] values) { 737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate d = sManager.getDelegate(native_object); 738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (d == null) { 739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski System.arraycopy(values, 0, d.mValues, 0, MATRIX_SIZE); 743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 74688a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static boolean native_equals(long native_a, long native_b) { 747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate a = sManager.getDelegate(native_a); 748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (a == null) { 749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate b = sManager.getDelegate(native_b); 753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (b == null) { 754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 0 ; i < MATRIX_SIZE ; i++) { 758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (a.mValues[i] != b.mValues[i]) { 759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @LayoutlibDelegate 76788a8364c386c694f7ad56662ef89713dbf7c9d63Narayan Kamath /*package*/ static void finalizer(long native_instance) { 768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sManager.removeJavaReferenceFor(native_instance); 769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ---- Private helper methods ---- 772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /*package*/ static AffineTransform getAffineTransform(float[] matrix) { 774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the AffineTransform constructor takes the value in a different order 775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // for a matrix [ 0 1 2 ] 776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // [ 3 4 5 ] 777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the order is 0, 3, 1, 4, 2, 5... 778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new AffineTransform( 779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski matrix[0], matrix[3], matrix[1], 780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski matrix[4], matrix[2], matrix[5]); 781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Reset a matrix to the identity 785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static void reset(float[] mtx) { 787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 0, k = 0; i < 3; i++) { 788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int j = 0; j < 3; j++, k++) { 789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mtx[k] = ((i==j) ? 1 : 0); 790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @SuppressWarnings("unused") 795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final static int kIdentity_Mask = 0; 796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final static int kTranslate_Mask = 0x01; //!< set if the matrix has translation 797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final static int kScale_Mask = 0x02; //!< set if the matrix has X or Y scale 798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final static int kAffine_Mask = 0x04; //!< set if the matrix skews or rotates 799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final static int kPerspective_Mask = 0x08; //!< set if the matrix is in perspective 800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final static int kRectStaysRect_Mask = 0x10; 801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @SuppressWarnings("unused") 802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final static int kUnknown_Mask = 0x80; 803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @SuppressWarnings("unused") 805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final static int kAllMasks = kTranslate_Mask | 806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski kScale_Mask | 807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski kAffine_Mask | 808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski kPerspective_Mask | 809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski kRectStaysRect_Mask; 810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // these guys align with the masks, so we can compute a mask from a variable 0/1 812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @SuppressWarnings("unused") 813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final static int kTranslate_Shift = 0; 814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @SuppressWarnings("unused") 815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final static int kScale_Shift = 1; 816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @SuppressWarnings("unused") 817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final static int kAffine_Shift = 2; 818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @SuppressWarnings("unused") 819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final static int kPerspective_Shift = 3; 820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final static int kRectStaysRect_Shift = 4; 821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private int computeTypeMask() { 823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int mask = 0; 824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mValues[6] != 0. || mValues[7] != 0. || mValues[8] != 1.) { 826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mask |= kPerspective_Mask; 827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mValues[2] != 0. || mValues[5] != 0.) { 830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mask |= kTranslate_Mask; 831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float m00 = mValues[0]; 834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float m01 = mValues[1]; 835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float m10 = mValues[3]; 836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float m11 = mValues[4]; 837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (m01 != 0. || m10 != 0.) { 839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mask |= kAffine_Mask; 840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (m00 != 1. || m11 != 1.) { 843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mask |= kScale_Mask; 844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((mask & kPerspective_Mask) == 0) { 847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // map non-zero to 1 848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int im00 = m00 != 0 ? 1 : 0; 849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int im01 = m01 != 0 ? 1 : 0; 850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int im10 = m10 != 0 ? 1 : 0; 851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int im11 = m11 != 0 ? 1 : 0; 852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // record if the (p)rimary and (s)econdary diagonals are all 0 or 854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // all non-zero (answer is 0 or 1) 855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int dp0 = (im00 | im11) ^ 1; // true if both are 0 856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int dp1 = im00 & im11; // true if both are 1 857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int ds0 = (im01 | im10) ^ 1; // true if both are 0 858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int ds1 = im01 & im10; // true if both are 1 859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 860282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // return 1 if primary is 1 and secondary is 0 or 861282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // primary is 0 and secondary is 1 862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mask |= ((dp0 & ds1) | (dp1 & ds0)) << kRectStaysRect_Shift; 863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mask; 866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private Matrix_Delegate() { 869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski reset(); 870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private Matrix_Delegate(float[] values) { 873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski System.arraycopy(values, 0, mValues, 0, MATRIX_SIZE); 874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Adds the given transformation to the current Matrix 878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p/>This in effect does this = this*matrix 879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param matrix 880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void postTransform(float[] matrix) { 882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float[] tmp = new float[9]; 883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski multiply(tmp, mValues, matrix); 884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mValues = tmp; 885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Adds the given transformation to the current Matrix 889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p/>This in effect does this = matrix*this 890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param matrix 891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void preTransform(float[] matrix) { 893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float[] tmp = new float[9]; 894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski multiply(tmp, matrix, mValues); 895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mValues = tmp; 896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Apply this matrix to the array of 2D points specified by src, and write 900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * the transformed points into the array of points specified by dst. The 901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * two arrays represent their "points" as pairs of floats [x, y]. 902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param dst The array of dst points (x,y pairs) 904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param dstIndex The index of the first [x,y] pair of dst floats 905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param src The array of src points (x,y pairs) 906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param srcIndex The index of the first [x,y] pair of src floats 907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param pointCount The number of points (x,y pairs) to transform 908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 910282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex, 911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int pointCount) { 912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int count = pointCount * 2; 913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float[] tmpDest = dst; 915282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski boolean inPlace = dst == src; 916282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (inPlace) { 917282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tmpDest = new float[dstIndex + count]; 918282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 919282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 920282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 0 ; i < count ; i += 2) { 921282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // just in case we are doing in place, we better put this in temp vars 922282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float x = mValues[0] * src[i + srcIndex] + 923282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mValues[1] * src[i + srcIndex + 1] + 924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mValues[2]; 925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float y = mValues[3] * src[i + srcIndex] + 926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mValues[4] * src[i + srcIndex + 1] + 927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mValues[5]; 928282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 929282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tmpDest[i + dstIndex] = x; 930282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tmpDest[i + dstIndex + 1] = y; 931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 933282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (inPlace) { 934282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski System.arraycopy(tmpDest, dstIndex, dst, dstIndex, count); 935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 937282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 938282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Apply this matrix to the array of 2D points, and write the transformed 940282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * points back into the array 941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 942282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param pts The array [x0, y0, x1, y1, ...] of points to transform. 943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void mapPoints(float[] pts) { 946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mapPoints(pts, 0, pts, 0, pts.length >> 1); 947282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 948282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 949282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, int ptCount) { 950282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasPerspective()) { 951282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // transform the (0,0) point 952282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float[] origin = new float[] { 0.f, 0.f}; 953282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mapPoints(origin); 954282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // translate the vector data as points 956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mapPoints(dst, dstIndex, src, srcIndex, ptCount); 957282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 958282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // then substract the transformed origin. 959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int count = ptCount * 2; 960282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 0 ; i < count ; i += 2) { 961282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dst[dstIndex + i] = dst[dstIndex + i] - origin[0]; 962282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dst[dstIndex + i + 1] = dst[dstIndex + i + 1] - origin[1]; 963282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 964282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // make a copy of the matrix 966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix_Delegate copy = new Matrix_Delegate(mValues); 967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // remove the translation 969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski setTranslate(copy.mValues, 0, 0); 970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 971282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // map the content as points. 972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski copy.mapPoints(dst, dstIndex, src, srcIndex, ptCount); 973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static float getPointLength(float[] src, int index) { 977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (float) Math.sqrt(src[index] * src[index] + src[index + 1] * src[index + 1]); 978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * multiply two matrices and store them in a 3rd. 982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p/>This in effect does dest = a*b 983282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * dest cannot be the same as a or b. 984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /*package*/ static void multiply(float dest[], float[] a, float[] b) { 986282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // first row 987282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[0] = b[0] * a[0] + b[1] * a[3] + b[2] * a[6]; 988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[1] = b[0] * a[1] + b[1] * a[4] + b[2] * a[7]; 989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[2] = b[0] * a[2] + b[1] * a[5] + b[2] * a[8]; 990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 2nd row 992282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[3] = b[3] * a[0] + b[4] * a[3] + b[5] * a[6]; 993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[4] = b[3] * a[1] + b[4] * a[4] + b[5] * a[7]; 994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[5] = b[3] * a[2] + b[4] * a[5] + b[5] * a[8]; 995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // 3rd row 997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[6] = b[6] * a[0] + b[7] * a[3] + b[8] * a[6]; 998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[7] = b[6] * a[1] + b[7] * a[4] + b[8] * a[7]; 999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[8] = b[6] * a[2] + b[7] * a[5] + b[8] * a[8]; 1000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 1003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns a matrix that represents a given translate 1004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param dx 1005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param dy 1006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return 1007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /*package*/ static float[] getTranslate(float dx, float dy) { 1009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return setTranslate(new float[9], dx, dy); 1010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1012282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /*package*/ static float[] setTranslate(float[] dest, float dx, float dy) { 1013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[0] = 1; 1014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[1] = 0; 1015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[2] = dx; 1016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[3] = 0; 1017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[4] = 1; 1018282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[5] = dy; 1019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[6] = 0; 1020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[7] = 0; 1021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[8] = 1; 1022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return dest; 1023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /*package*/ static float[] getScale(float sx, float sy) { 1026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new float[] { sx, 0, 0, 0, sy, 0, 0, 0, 1 }; 1027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1029282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 1030282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns a matrix that represents the given scale info. 1031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param sx 1032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param sy 1033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param px 1034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param py 1035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /*package*/ static float[] getScale(float sx, float sy, float px, float py) { 1037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float[] tmp = new float[9]; 1038282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float[] tmp2 = new float[9]; 1039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // TODO: do it in one pass 1041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // translate tmp so that the pivot is in 0,0 1043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski setTranslate(tmp, -px, -py); 1044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // scale into tmp2 1046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski multiply(tmp2, tmp, getScale(sx, sy)); 1047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // translate back the pivot back into tmp 1049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski multiply(tmp, tmp2, getTranslate(px, py)); 1050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return tmp; 1052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /*package*/ static float[] getRotate(float degrees) { 1056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski double rad = Math.toRadians(degrees); 1057282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float sin = (float)Math.sin(rad); 1058282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float cos = (float)Math.cos(rad); 1059282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1060282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return getRotate(sin, cos); 1061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /*package*/ static float[] getRotate(float sin, float cos) { 1064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return setRotate(new float[9], sin, cos); 1065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1067282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /*package*/ static float[] setRotate(float[] dest, float degrees) { 1068282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski double rad = Math.toRadians(degrees); 1069282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float sin = (float)Math.sin(rad); 1070282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float cos = (float)Math.cos(rad); 1071282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1072282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return setRotate(dest, sin, cos); 1073282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1074282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /*package*/ static float[] setRotate(float[] dest, float sin, float cos) { 1076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[0] = cos; 1077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[1] = -sin; 1078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[2] = 0; 1079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[3] = sin; 1080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[4] = cos; 1081282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[5] = 0; 1082282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[6] = 0; 1083282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[7] = 0; 1084282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest[8] = 1; 1085282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return dest; 1086282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1087282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1088282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /*package*/ static float[] getRotate(float degrees, float px, float py) { 1089282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float[] tmp = new float[9]; 1090282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float[] tmp2 = new float[9]; 1091282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1092282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // TODO: do it in one pass 1093282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1094282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // translate so that the pivot is in 0,0 1095282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski setTranslate(tmp, -px, -py); 1096282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1097282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // rotate into tmp2 1098282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski double rad = Math.toRadians(degrees); 1099282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float cos = (float)Math.cos(rad); 1100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float sin = (float)Math.sin(rad); 1101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski multiply(tmp2, tmp, getRotate(sin, cos)); 1102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // translate back the pivot back into tmp 1104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski multiply(tmp, tmp2, getTranslate(px, py)); 1105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return tmp; 1107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /*package*/ static float[] getSkew(float kx, float ky) { 1110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 }; 1111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /*package*/ static float[] getSkew(float kx, float ky, float px, float py) { 1114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float[] tmp = new float[9]; 1115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float[] tmp2 = new float[9]; 1116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // TODO: do it in one pass 1118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // translate so that the pivot is in 0,0 1120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski setTranslate(tmp, -px, -py); 1121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // skew into tmp2 1123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski multiply(tmp2, tmp, new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 }); 1124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // translate back the pivot back into tmp 1125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski multiply(tmp, tmp2, getTranslate(px, py)); 1126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return tmp; 1128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 1130