171538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka/* 271538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka * Copyright (C) 2012 The Android Open Source Project 371538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka * 48aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); 58aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * you may not use this file except in compliance with the License. 68aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * You may obtain a copy of the License at 771538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka * 88aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * http://www.apache.org/licenses/LICENSE-2.0 971538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka * 1071538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka * Unless required by applicable law or agreed to in writing, software 118aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, 128aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * See the License for the specific language governing permissions and 148aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * limitations under the License. 1571538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka */ 1671538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka 1736799b2aa2982ec17341cd2c5ed81e608bcee8c6Jean Chalardpackage com.android.inputmethod.latin.common; 18e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka 1915f6d4ae34664ea3d92827a2c3003198c0bac70bTadashi G. Takaokaimport com.android.inputmethod.annotations.UsedForTesting; 2015f6d4ae34664ea3d92827a2c3003198c0bac70bTadashi G. Takaoka 21519df535996427c87242f8dbdd5993c6ab5a87d0Tadashi G. Takaokaimport javax.annotation.Nonnull; 22519df535996427c87242f8dbdd5993c6ab5a87d0Tadashi G. Takaoka 237247bff6d6d488640ac752127148e7746c43469dTadashi G. Takaoka// TODO: This class is not thread-safe. 24a28a05e971cc242b338331a3b78276fa95188d19Tadashi G. Takaokapublic final class InputPointers { 25e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka private static final boolean DEBUG_TIME = false; 26e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka 2757f7de0ba664187e13bcea5adff7f5f65eddd823Tadashi G. Takaoka private final int mDefaultCapacity; 289370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka private final ResizableIntArray mXCoordinates; 299370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka private final ResizableIntArray mYCoordinates; 309370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka private final ResizableIntArray mPointerIds; 319370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka private final ResizableIntArray mTimes; 3257f7de0ba664187e13bcea5adff7f5f65eddd823Tadashi G. Takaoka 33519df535996427c87242f8dbdd5993c6ab5a87d0Tadashi G. Takaoka public InputPointers(final int defaultCapacity) { 3457f7de0ba664187e13bcea5adff7f5f65eddd823Tadashi G. Takaoka mDefaultCapacity = defaultCapacity; 359370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka mXCoordinates = new ResizableIntArray(defaultCapacity); 369370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka mYCoordinates = new ResizableIntArray(defaultCapacity); 379370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka mPointerIds = new ResizableIntArray(defaultCapacity); 389370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka mTimes = new ResizableIntArray(defaultCapacity); 3957f7de0ba664187e13bcea5adff7f5f65eddd823Tadashi G. Takaoka } 4071538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka 41e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka private void fillWithLastTimeUntil(final int index) { 42e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka final int fromIndex = mTimes.getLength(); 43e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka // Fill the gap with the latest time. 44e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka // See {@link #getTime(int)} and {@link #isValidTimeStamps()}. 45e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka if (fromIndex <= 0) { 46e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka return; 47e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka } 48e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka final int fillLength = index - fromIndex + 1; 49e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka if (fillLength <= 0) { 50e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka return; 51e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka } 52e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka final int lastTime = mTimes.get(fromIndex - 1); 53e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka mTimes.fill(lastTime, fromIndex, fillLength); 54e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka } 55e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka 56519df535996427c87242f8dbdd5993c6ab5a87d0Tadashi G. Takaoka public void addPointerAt(final int index, final int x, final int y, final int pointerId, 57519df535996427c87242f8dbdd5993c6ab5a87d0Tadashi G. Takaoka final int time) { 58ad78058a93492d4f114c6a6eb56177be9231a9ebTadashi G. Takaoka mXCoordinates.addAt(index, x); 59ad78058a93492d4f114c6a6eb56177be9231a9ebTadashi G. Takaoka mYCoordinates.addAt(index, y); 60ad78058a93492d4f114c6a6eb56177be9231a9ebTadashi G. Takaoka mPointerIds.addAt(index, pointerId); 6136799b2aa2982ec17341cd2c5ed81e608bcee8c6Jean Chalard if (DEBUG_TIME) { 62e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka fillWithLastTimeUntil(index); 63e7dc5302afdaedc379e3725f2a5822b630b43276Tadashi G. Takaoka } 64ad78058a93492d4f114c6a6eb56177be9231a9ebTadashi G. Takaoka mTimes.addAt(index, time); 6571538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka } 6671538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka 6715f6d4ae34664ea3d92827a2c3003198c0bac70bTadashi G. Takaoka @UsedForTesting 68519df535996427c87242f8dbdd5993c6ab5a87d0Tadashi G. Takaoka public void addPointer(final int x, final int y, final int pointerId, final int time) { 6971538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mXCoordinates.add(x); 7071538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mYCoordinates.add(y); 7171538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mPointerIds.add(pointerId); 7271538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mTimes.add(time); 7371538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka } 7471538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka 75519df535996427c87242f8dbdd5993c6ab5a87d0Tadashi G. Takaoka public void set(@Nonnull final InputPointers ip) { 7671538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mXCoordinates.set(ip.mXCoordinates); 7771538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mYCoordinates.set(ip.mYCoordinates); 7871538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mPointerIds.set(ip.mPointerIds); 7971538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mTimes.set(ip.mTimes); 8071538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka } 8171538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka 82519df535996427c87242f8dbdd5993c6ab5a87d0Tadashi G. Takaoka public void copy(@Nonnull final InputPointers ip) { 8371538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mXCoordinates.copy(ip.mXCoordinates); 8471538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mYCoordinates.copy(ip.mYCoordinates); 8571538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mPointerIds.copy(ip.mPointerIds); 8671538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka mTimes.copy(ip.mTimes); 8771538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka } 8871538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka 891087c53f5a6ced093eb4e71f88cff19e89819d73Tadashi G. Takaoka /** 907519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka * Append the times, x-coordinates and y-coordinates in the specified {@link ResizableIntArray} 917519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka * to the end of this. 927519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka * @param pointerId the pointer id of the source. 937519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka * @param times the source {@link ResizableIntArray} to read the event times from. 947519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka * @param xCoordinates the source {@link ResizableIntArray} to read the x-coordinates from. 957519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka * @param yCoordinates the source {@link ResizableIntArray} to read the y-coordinates from. 967519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka * @param startPos the starting index of the data in {@code times} and etc. 977519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka * @param length the number of data to be appended. 987519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka */ 99519df535996427c87242f8dbdd5993c6ab5a87d0Tadashi G. Takaoka public void append(final int pointerId, @Nonnull final ResizableIntArray times, 100519df535996427c87242f8dbdd5993c6ab5a87d0Tadashi G. Takaoka @Nonnull final ResizableIntArray xCoordinates, 101519df535996427c87242f8dbdd5993c6ab5a87d0Tadashi G. Takaoka @Nonnull final ResizableIntArray yCoordinates, final int startPos, final int length) { 1027519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka if (length == 0) { 1037519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka return; 1047519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka } 1057519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka mXCoordinates.append(xCoordinates, startPos, length); 1067519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka mYCoordinates.append(yCoordinates, startPos, length); 10764a26b4389abb273afff7699a8c86596defd85bfTadashi G. Takaoka mPointerIds.fill(pointerId, mPointerIds.getLength(), length); 1087519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka mTimes.append(times, startPos, length); 1097519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka } 1107519091f7c15c50a9a1e50d82fa92400335852ecTadashi G. Takaoka 111e8754aba1c8f217e7ca828de25e0506ac58daa99Keisuke Kuroyanagi /** 112e8754aba1c8f217e7ca828de25e0506ac58daa99Keisuke Kuroyanagi * Shift to the left by elementCount, discarding elementCount pointers at the start. 113e8754aba1c8f217e7ca828de25e0506ac58daa99Keisuke Kuroyanagi * @param elementCount how many elements to shift. 114e8754aba1c8f217e7ca828de25e0506ac58daa99Keisuke Kuroyanagi */ 11554bf24f64b9bbd4c5e4b6d4c3c6144c047d6ddc6Mohammadinamul Sheik @UsedForTesting 116e8754aba1c8f217e7ca828de25e0506ac58daa99Keisuke Kuroyanagi public void shift(final int elementCount) { 117e8754aba1c8f217e7ca828de25e0506ac58daa99Keisuke Kuroyanagi mXCoordinates.shift(elementCount); 118e8754aba1c8f217e7ca828de25e0506ac58daa99Keisuke Kuroyanagi mYCoordinates.shift(elementCount); 119e8754aba1c8f217e7ca828de25e0506ac58daa99Keisuke Kuroyanagi mPointerIds.shift(elementCount); 120e8754aba1c8f217e7ca828de25e0506ac58daa99Keisuke Kuroyanagi mTimes.shift(elementCount); 121e8754aba1c8f217e7ca828de25e0506ac58daa99Keisuke Kuroyanagi } 122e8754aba1c8f217e7ca828de25e0506ac58daa99Keisuke Kuroyanagi 12371538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka public void reset() { 12457f7de0ba664187e13bcea5adff7f5f65eddd823Tadashi G. Takaoka final int defaultCapacity = mDefaultCapacity; 12557f7de0ba664187e13bcea5adff7f5f65eddd823Tadashi G. Takaoka mXCoordinates.reset(defaultCapacity); 12657f7de0ba664187e13bcea5adff7f5f65eddd823Tadashi G. Takaoka mYCoordinates.reset(defaultCapacity); 12757f7de0ba664187e13bcea5adff7f5f65eddd823Tadashi G. Takaoka mPointerIds.reset(defaultCapacity); 12857f7de0ba664187e13bcea5adff7f5f65eddd823Tadashi G. Takaoka mTimes.reset(defaultCapacity); 12971538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka } 13071538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka 13171538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka public int getPointerSize() { 13271538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka return mXCoordinates.getLength(); 13371538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka } 13471538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka 135519df535996427c87242f8dbdd5993c6ab5a87d0Tadashi G. Takaoka @Nonnull 13671538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka public int[] getXCoordinates() { 1371087c53f5a6ced093eb4e71f88cff19e89819d73Tadashi G. Takaoka return mXCoordinates.getPrimitiveArray(); 13871538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka } 13971538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka 140519df535996427c87242f8dbdd5993c6ab5a87d0Tadashi G. Takaoka @Nonnull 14171538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka public int[] getYCoordinates() { 1421087c53f5a6ced093eb4e71f88cff19e89819d73Tadashi G. Takaoka return mYCoordinates.getPrimitiveArray(); 14371538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka } 14471538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka 145519df535996427c87242f8dbdd5993c6ab5a87d0Tadashi G. Takaoka @Nonnull 14671538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka public int[] getPointerIds() { 1471087c53f5a6ced093eb4e71f88cff19e89819d73Tadashi G. Takaoka return mPointerIds.getPrimitiveArray(); 14871538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka } 14971538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka 1509cf69a45b24646bdd4bf365afe4e8e9fb30f9a22David Faden /** 1519cf69a45b24646bdd4bf365afe4e8e9fb30f9a22David Faden * Gets the time each point was registered, in milliseconds, relative to the first event in the 1529cf69a45b24646bdd4bf365afe4e8e9fb30f9a22David Faden * sequence. 1539cf69a45b24646bdd4bf365afe4e8e9fb30f9a22David Faden * @return The time each point was registered, in milliseconds, relative to the first event in 1549cf69a45b24646bdd4bf365afe4e8e9fb30f9a22David Faden * the sequence. 1559cf69a45b24646bdd4bf365afe4e8e9fb30f9a22David Faden */ 156519df535996427c87242f8dbdd5993c6ab5a87d0Tadashi G. Takaoka @Nonnull 15771538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka public int[] getTimes() { 1581087c53f5a6ced093eb4e71f88cff19e89819d73Tadashi G. Takaoka return mTimes.getPrimitiveArray(); 15971538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka } 16064ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka 16164ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka @Override 16264ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka public String toString() { 16364ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka return "size=" + getPointerSize() + " id=" + mPointerIds + " time=" + mTimes 16464ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka + " x=" + mXCoordinates + " y=" + mYCoordinates; 16564ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka } 16671538b08e4e08d556f700ad344562ca2c7b74d82Satoshi Kataoka} 167