1c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa/* 2c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Copyright (C) 2014 The Android Open Source Project 3c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * 4c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * use this file except in compliance with the License. You may obtain a copy of 6c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * the License at 7c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * 8c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * http://www.apache.org/licenses/LICENSE-2.0 9c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * 10c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Unless required by applicable law or agreed to in writing, software 11c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * License for the specific language governing permissions and limitations under 14c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * the License. 15c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 16c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 17c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawapackage android.view.inputmethod; 18c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 19c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawaimport android.graphics.RectF; 20c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawaimport android.os.Parcel; 21c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawaimport android.os.Parcelable; 22c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 23c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawaimport java.util.Arrays; 24c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 25c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa/** 26c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * An implementation of SparseArray specialized for {@link android.graphics.RectF}. 27c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * <p> 28c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * As this is a sparse array, it represents an array of {@link RectF} most of which are null. This 29c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * class could be in some other packages like android.graphics or android.util but currently 30c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * belong to android.view.inputmethod because this class is hidden and used only in input method 31c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * framework. 32c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * </p> 33c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @hide 34c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 35c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawapublic final class SparseRectFArray implements Parcelable { 36c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 37c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * The keys, in ascending order, of those {@link RectF} that are not null. For example, 38c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * {@code [null, null, null, Rect1, null, Rect2]} would be represented by {@code [3,5]}. 39c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @see #mCoordinates 40c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 41c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa private final int[] mKeys; 42c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 43c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 44c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Stores coordinates of the rectangles, in the order of 45c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * {@code rects[mKeys[0]].left}, {@code rects[mKeys[0]].top}, 46c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * {@code rects[mKeys[0]].right}, {@code rects[mKeys[0]].bottom}, 47c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * {@code rects[mKeys[1]].left}, {@code rects[mKeys[1]].top}, 48c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * {@code rects[mKeys[1]].right}, {@code rects[mKeys[1]].bottom}, 49c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * {@code rects[mKeys[2]].left}, {@code rects[mKeys[2]].top}, .... 50c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 51c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa private final float[] mCoordinates; 52c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 530b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa /** 540b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa * Stores visibility information. 550b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa */ 560b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa private final int[] mFlagsArray; 570b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa 58c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public SparseRectFArray(final Parcel source) { 59c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mKeys = source.createIntArray(); 60c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mCoordinates = source.createFloatArray(); 610b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa mFlagsArray = source.createIntArray(); 62c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 63c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 64c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 65c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Used to package this object into a {@link Parcel}. 66c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * 67c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @param dest The {@link Parcel} to be written. 68c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @param flags The flags used for parceling. 69c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 70c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa @Override 71c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public void writeToParcel(Parcel dest, int flags) { 72c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa dest.writeIntArray(mKeys); 73c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa dest.writeFloatArray(mCoordinates); 740b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa dest.writeIntArray(mFlagsArray); 75c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 76c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 77c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa @Override 78c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public int hashCode() { 79c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa // TODO: Improve the hash function. 80c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (mKeys == null || mKeys.length == 0) { 81c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return 0; 82c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 83c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa int hash = mKeys.length; 84c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa // For performance reasons, only the first rectangle is used for the hash code now. 85c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa for (int i = 0; i < 4; i++) { 86c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa hash *= 31; 87c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa hash += mCoordinates[i]; 88c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 890b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa hash *= 31; 900b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa hash += mFlagsArray[0]; 91c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return hash; 92c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 93c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 94c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa @Override 95c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public boolean equals(Object obj){ 96c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (obj == null) { 97c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return false; 98c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 99c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (this == obj) { 100c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return true; 101c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 102c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (!(obj instanceof SparseRectFArray)) { 103c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return false; 104c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 105c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa final SparseRectFArray that = (SparseRectFArray) obj; 106c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 1070b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa return Arrays.equals(mKeys, that.mKeys) && Arrays.equals(mCoordinates, that.mCoordinates) 1080b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa && Arrays.equals(mFlagsArray, that.mFlagsArray); 109c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 110c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 111c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa @Override 112c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public String toString() { 1130b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa if (mKeys == null || mCoordinates == null || mFlagsArray == null) { 114c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return "SparseRectFArray{}"; 115c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 116c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa final StringBuilder sb = new StringBuilder(); 117c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa sb.append("SparseRectFArray{"); 118c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa for (int i = 0; i < mKeys.length; i++) { 119c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (i != 0) { 120c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa sb.append(", "); 121c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 122c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa final int baseIndex = i * 4; 123c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa sb.append(mKeys[i]); 124c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa sb.append(":["); 125c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa sb.append(mCoordinates[baseIndex + 0]); 126c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa sb.append(","); 127c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa sb.append(mCoordinates[baseIndex + 1]); 128c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa sb.append("],["); 129c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa sb.append(mCoordinates[baseIndex + 2]); 130c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa sb.append(","); 131c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa sb.append(mCoordinates[baseIndex + 3]); 1320b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa sb.append("]:flagsArray="); 1330b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa sb.append(mFlagsArray[i]); 134c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 135c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa sb.append("}"); 136c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return sb.toString(); 137c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 138c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 139c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 140c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Builder for {@link SparseRectFArray}. This class is not designed to be thread-safe. 141c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @hide 142c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 143c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public static final class SparseRectFArrayBuilder { 144c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 145c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Throws {@link IllegalArgumentException} to make sure that this class is correctly used. 146c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @param key key to be checked. 147c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 148c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa private void checkIndex(final int key) { 149c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (mCount == 0) { 150c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return; 151c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 152c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (mKeys[mCount - 1] >= key) { 153c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa throw new IllegalArgumentException("key must be greater than all existing keys."); 154c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 155c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 156c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 157c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 158c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Extends the internal array if necessary. 159c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 160c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa private void ensureBufferSize() { 161c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (mKeys == null) { 162c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mKeys = new int[INITIAL_SIZE]; 163c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 164c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (mCoordinates == null) { 165c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mCoordinates = new float[INITIAL_SIZE * 4]; 166c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 1670b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa if (mFlagsArray == null) { 1680b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa mFlagsArray = new int[INITIAL_SIZE]; 1690b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa } 170c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa final int requiredIndexArraySize = mCount + 1; 171c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (mKeys.length <= requiredIndexArraySize) { 172c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa final int[] newArray = new int[requiredIndexArraySize * 2]; 173c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa System.arraycopy(mKeys, 0, newArray, 0, mCount); 174c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mKeys = newArray; 175c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 176c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa final int requiredCoordinatesArraySize = (mCount + 1) * 4; 177c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (mCoordinates.length <= requiredCoordinatesArraySize) { 178c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa final float[] newArray = new float[requiredCoordinatesArraySize * 2]; 179c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa System.arraycopy(mCoordinates, 0, newArray, 0, mCount * 4); 180c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mCoordinates = newArray; 181c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 1820b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa final int requiredFlagsArraySize = requiredIndexArraySize; 1830b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa if (mFlagsArray.length <= requiredFlagsArraySize) { 1840b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa final int[] newArray = new int[requiredFlagsArraySize * 2]; 1850b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa System.arraycopy(mFlagsArray, 0, newArray, 0, mCount); 1860b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa mFlagsArray = newArray; 1870b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa } 188c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 189c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 190c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 191c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Puts the rectangle with an integer key. 192c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @param key the key to be associated with the rectangle. It must be greater than all 193c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * existing keys that have been previously specified. 194c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @param left left of the rectangle. 195c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @param top top of the rectangle. 196c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @param right right of the rectangle. 197c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @param bottom bottom of the rectangle. 1980b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa * @param flags an arbitrary integer value to be associated with this rectangle. 199c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @return the receiver object itself for chaining method calls. 200c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @throws IllegalArgumentException If the index is not greater than all of existing keys. 201c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 202c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public SparseRectFArrayBuilder append(final int key, 2030b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa final float left, final float top, final float right, final float bottom, 2040b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa final int flags) { 205c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa checkIndex(key); 206c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa ensureBufferSize(); 207c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa final int baseCoordinatesIndex = mCount * 4; 208c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mCoordinates[baseCoordinatesIndex + 0] = left; 209c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mCoordinates[baseCoordinatesIndex + 1] = top; 210c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mCoordinates[baseCoordinatesIndex + 2] = right; 211c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mCoordinates[baseCoordinatesIndex + 3] = bottom; 2120b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa final int flagsIndex = mCount; 2130b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa mFlagsArray[flagsIndex] = flags; 214c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mKeys[mCount] = key; 215c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa ++mCount; 216c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return this; 217c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 218c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa private int mCount = 0; 219c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa private int[] mKeys = null; 220c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa private float[] mCoordinates = null; 2210b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa private int[] mFlagsArray = null; 222c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa private static int INITIAL_SIZE = 16; 223c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 224b5268dcc17cd9ecb540b06ad59bd74188b57a069Yohei Yukawa public boolean isEmpty() { 225b5268dcc17cd9ecb540b06ad59bd74188b57a069Yohei Yukawa return mCount <= 0; 226b5268dcc17cd9ecb540b06ad59bd74188b57a069Yohei Yukawa } 227b5268dcc17cd9ecb540b06ad59bd74188b57a069Yohei Yukawa 228c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 229c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @return {@link SparseRectFArray} using parameters in this {@link SparseRectFArray}. 230c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 231c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public SparseRectFArray build() { 232c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return new SparseRectFArray(this); 233c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 234c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 235c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public void reset() { 236c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (mCount == 0) { 237c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mKeys = null; 238c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mCoordinates = null; 2390b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa mFlagsArray = null; 240c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 241c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mCount = 0; 242c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 243c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 244c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 245c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa private SparseRectFArray(final SparseRectFArrayBuilder builder) { 246c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (builder.mCount == 0) { 247c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mKeys = null; 248c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mCoordinates = null; 2490b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa mFlagsArray = null; 250c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } else { 251c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mKeys = new int[builder.mCount]; 252c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mCoordinates = new float[builder.mCount * 4]; 2530b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa mFlagsArray = new int[builder.mCount]; 254c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa System.arraycopy(builder.mKeys, 0, mKeys, 0, builder.mCount); 255c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa System.arraycopy(builder.mCoordinates, 0, mCoordinates, 0, builder.mCount * 4); 2560b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa System.arraycopy(builder.mFlagsArray, 0, mFlagsArray, 0, builder.mCount); 257c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 258c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 259c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 260c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public RectF get(final int index) { 261c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (mKeys == null) { 262c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return null; 263c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 264c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (index < 0) { 265c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return null; 266c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 267c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa final int arrayIndex = Arrays.binarySearch(mKeys, index); 268c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (arrayIndex < 0) { 269c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return null; 270c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 271c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa final int baseCoordIndex = arrayIndex * 4; 272c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return new RectF(mCoordinates[baseCoordIndex], 273c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mCoordinates[baseCoordIndex + 1], 274c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mCoordinates[baseCoordIndex + 2], 275c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mCoordinates[baseCoordIndex + 3]); 276c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 277c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 2780b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa public int getFlags(final int index, final int valueIfKeyNotFound) { 2790b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa if (mKeys == null) { 2800b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa return valueIfKeyNotFound; 2810b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa } 2820b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa if (index < 0) { 2830b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa return valueIfKeyNotFound; 2840b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa } 2850b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa final int arrayIndex = Arrays.binarySearch(mKeys, index); 2860b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa if (arrayIndex < 0) { 2870b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa return valueIfKeyNotFound; 2880b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa } 2890b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa return mFlagsArray[arrayIndex]; 2900b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa } 2910b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa 292c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 293c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Used to make this class parcelable. 294c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 295c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public static final Parcelable.Creator<SparseRectFArray> CREATOR = 296c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa new Parcelable.Creator<SparseRectFArray>() { 297c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa @Override 298c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public SparseRectFArray createFromParcel(Parcel source) { 299c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return new SparseRectFArray(source); 300c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 301c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa @Override 302c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public SparseRectFArray[] newArray(int size) { 303c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return new SparseRectFArray[size]; 304c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 305c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa }; 306c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 307c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa @Override 308c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public int describeContents() { 309c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return 0; 310c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 311c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa} 312c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 313