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.Matrix; 20c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawaimport android.graphics.RectF; 21c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawaimport android.os.Parcel; 22c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawaimport android.os.Parcelable; 23c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawaimport android.text.Layout; 24a1fda005f9583486f4372ecbb0eec503ee9cece8Yohei Yukawaimport android.text.SpannedString; 25a1fda005f9583486f4372ecbb0eec503ee9cece8Yohei Yukawaimport android.text.TextUtils; 26c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawaimport android.view.inputmethod.SparseRectFArray.SparseRectFArrayBuilder; 27c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 28c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawaimport java.util.Objects; 29c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 30c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa/** 31c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Positional information about the text insertion point and characters in the composition string. 32c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * 33c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * <p>This class encapsulates locations of the text insertion point and the composition string in 34c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * the screen coordinates so that IMEs can render their UI components near where the text is 35c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * actually inserted.</p> 36c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 37c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawapublic final class CursorAnchorInfo implements Parcelable { 385f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa /** 395f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * The index of the first character of the selected text (inclusive). {@code -1} when there is 405f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * no text selection. 415f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa */ 42c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa private final int mSelectionStart; 435f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa /** 445f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * The index of the first character of the selected text (exclusive). {@code -1} when there is 455f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * no text selection. 465f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa */ 47c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa private final int mSelectionEnd; 4881f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa 495f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa /** 505f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * The index of the first character of the composing text (inclusive). {@code -1} when there is 515f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * no composing text. 525f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa */ 5381f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa private final int mComposingTextStart; 5481f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa /** 5581f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa * The text, tracked as a composing region. 5681f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa */ 57a1fda005f9583486f4372ecbb0eec503ee9cece8Yohei Yukawa private final CharSequence mComposingText; 58c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 59c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 60cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa * Flags of the insertion marker. See {@link #FLAG_HAS_VISIBLE_REGION} for example. 610b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa */ 62cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa private final int mInsertionMarkerFlags; 630b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa /** 64c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Horizontal position of the insertion marker, in the local coordinates that will be 65c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * transformed with the transformation matrix when rendered on the screen. This should be 66c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * calculated or compatible with {@link Layout#getPrimaryHorizontal(int)}. This can be 67c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * {@code java.lang.Float.NaN} when no value is specified. 68c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 69c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa private final float mInsertionMarkerHorizontal; 70c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 71c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Vertical position of the insertion marker, in the local coordinates that will be 72c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * transformed with the transformation matrix when rendered on the screen. This should be 73c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * calculated or compatible with {@link Layout#getLineTop(int)}. This can be 74c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * {@code java.lang.Float.NaN} when no value is specified. 75c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 76c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa private final float mInsertionMarkerTop; 77c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 78c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Vertical position of the insertion marker, in the local coordinates that will be 79c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * transformed with the transformation matrix when rendered on the screen. This should be 80c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * calculated or compatible with {@link Layout#getLineBaseline(int)}. This can be 81c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * {@code java.lang.Float.NaN} when no value is specified. 82c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 83c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa private final float mInsertionMarkerBaseline; 84c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 85c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Vertical position of the insertion marker, in the local coordinates that will be 86c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * transformed with the transformation matrix when rendered on the screen. This should be 87c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * calculated or compatible with {@link Layout#getLineBottom(int)}. This can be 88c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * {@code java.lang.Float.NaN} when no value is specified. 89c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 90c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa private final float mInsertionMarkerBottom; 91c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 92c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 93c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Container of rectangular position of characters, keyed with character index in a unit of 94c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Java chars, in the local coordinates that will be transformed with the transformation matrix 95c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * when rendered on the screen. 96c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 975f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa private final SparseRectFArray mCharacterBoundsArray; 98c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 99c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 100c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Transformation matrix that is applied to any positional information of this class to 101c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * transform local coordinates into screen coordinates. 102c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 103c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa private final Matrix mMatrix; 104c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 105cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa /** 1065f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * Flag for {@link #getInsertionMarkerFlags()} and {@link #getCharacterBoundsFlags(int)}: the 107cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa * insertion marker or character bounds have at least one visible region. 108cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa */ 109cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa public static final int FLAG_HAS_VISIBLE_REGION = 0x01; 110cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa 111cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa /** 1125f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * Flag for {@link #getInsertionMarkerFlags()} and {@link #getCharacterBoundsFlags(int)}: the 113cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa * insertion marker or character bounds have at least one invisible (clipped) region. 114cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa */ 115cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa public static final int FLAG_HAS_INVISIBLE_REGION = 0x02; 116cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa 117cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa /** 1185f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * Flag for {@link #getInsertionMarkerFlags()} and {@link #getCharacterBoundsFlags(int)}: the 1195f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * insertion marker or character bounds is placed at right-to-left (RTL) character. 1205f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa */ 1215f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa public static final int FLAG_IS_RTL = 0x04; 1225f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa 123c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public CursorAnchorInfo(final Parcel source) { 124c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mSelectionStart = source.readInt(); 125c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mSelectionEnd = source.readInt(); 12681f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa mComposingTextStart = source.readInt(); 127a1fda005f9583486f4372ecbb0eec503ee9cece8Yohei Yukawa mComposingText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); 128cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa mInsertionMarkerFlags = source.readInt(); 129c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mInsertionMarkerHorizontal = source.readFloat(); 130c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mInsertionMarkerTop = source.readFloat(); 131c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mInsertionMarkerBaseline = source.readFloat(); 132c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mInsertionMarkerBottom = source.readFloat(); 1335f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa mCharacterBoundsArray = source.readParcelable(SparseRectFArray.class.getClassLoader()); 134c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mMatrix = new Matrix(); 135c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mMatrix.setValues(source.createFloatArray()); 136c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 137c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 138c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 139c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Used to package this object into a {@link Parcel}. 140c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * 141c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @param dest The {@link Parcel} to be written. 142c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @param flags The flags used for parceling. 143c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 144c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa @Override 145c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public void writeToParcel(Parcel dest, int flags) { 146c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa dest.writeInt(mSelectionStart); 147c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa dest.writeInt(mSelectionEnd); 14881f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa dest.writeInt(mComposingTextStart); 149a1fda005f9583486f4372ecbb0eec503ee9cece8Yohei Yukawa TextUtils.writeToParcel(mComposingText, dest, flags); 150cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa dest.writeInt(mInsertionMarkerFlags); 151c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa dest.writeFloat(mInsertionMarkerHorizontal); 152c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa dest.writeFloat(mInsertionMarkerTop); 153c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa dest.writeFloat(mInsertionMarkerBaseline); 154c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa dest.writeFloat(mInsertionMarkerBottom); 1555f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa dest.writeParcelable(mCharacterBoundsArray, flags); 156c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa final float[] matrixArray = new float[9]; 157c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mMatrix.getValues(matrixArray); 158c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa dest.writeFloatArray(matrixArray); 159c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 160c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 161c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa @Override 162c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public int hashCode(){ 16381f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa final float floatHash = mInsertionMarkerHorizontal + mInsertionMarkerTop 16481f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa + mInsertionMarkerBaseline + mInsertionMarkerBottom; 165c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa int hash = floatHash > 0 ? (int) floatHash : (int)(-floatHash); 16681f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa hash *= 31; 167cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa hash += mInsertionMarkerFlags; 1680b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa hash *= 31; 16981f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa hash += mSelectionStart + mSelectionEnd + mComposingTextStart; 17081f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa hash *= 31; 17181f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa hash += Objects.hashCode(mComposingText); 17281f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa hash *= 31; 1735f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa hash += Objects.hashCode(mCharacterBoundsArray); 17481f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa hash *= 31; 17581f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa hash += Objects.hashCode(mMatrix); 176c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return hash; 177c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 178c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 179eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa /** 180eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa * Compares two float values. Returns {@code true} if {@code a} and {@code b} are 181eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa * {@link Float#NaN} at the same time. 182eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa */ 183eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa private static boolean areSameFloatImpl(final float a, final float b) { 184eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa if (Float.isNaN(a) && Float.isNaN(b)) { 185eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa return true; 186eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa } 187eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa return a == b; 188eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa } 189eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa 190c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa @Override 191c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public boolean equals(Object obj){ 192c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (obj == null) { 193c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return false; 194c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 195c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (this == obj) { 196c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return true; 197c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 198c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (!(obj instanceof CursorAnchorInfo)) { 199c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return false; 200c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 201c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa final CursorAnchorInfo that = (CursorAnchorInfo) obj; 202c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (hashCode() != that.hashCode()) { 203c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return false; 204c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 205eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa if (mSelectionStart != that.mSelectionStart || mSelectionEnd != that.mSelectionEnd) { 206eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa return false; 207eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa } 208eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa if (mComposingTextStart != that.mComposingTextStart 209eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa || !Objects.equals(mComposingText, that.mComposingText)) { 210eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa return false; 211eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa } 212cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa if (mInsertionMarkerFlags != that.mInsertionMarkerFlags 2130b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa || !areSameFloatImpl(mInsertionMarkerHorizontal, that.mInsertionMarkerHorizontal) 214eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa || !areSameFloatImpl(mInsertionMarkerTop, that.mInsertionMarkerTop) 215eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa || !areSameFloatImpl(mInsertionMarkerBaseline, that.mInsertionMarkerBaseline) 216eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa || !areSameFloatImpl(mInsertionMarkerBottom, that.mInsertionMarkerBottom)) { 21781f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa return false; 21881f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa } 2195f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa if (!Objects.equals(mCharacterBoundsArray, that.mCharacterBoundsArray)) { 220c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return false; 221c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 222c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa if (!Objects.equals(mMatrix, that.mMatrix)) { 223c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return false; 224c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 225c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return true; 226c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 227c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 228c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa @Override 229c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public String toString() { 230c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return "SelectionInfo{mSelection=" + mSelectionStart + "," + mSelectionEnd 23181f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa + " mComposingTextStart=" + mComposingTextStart 23281f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa + " mComposingText=" + Objects.toString(mComposingText) 233cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa + " mInsertionMarkerFlags=" + mInsertionMarkerFlags 234c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa + " mInsertionMarkerHorizontal=" + mInsertionMarkerHorizontal 235c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa + " mInsertionMarkerTop=" + mInsertionMarkerTop 236c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa + " mInsertionMarkerBaseline=" + mInsertionMarkerBaseline 237c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa + " mInsertionMarkerBottom=" + mInsertionMarkerBottom 2385f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa + " mCharacterBoundsArray=" + Objects.toString(mCharacterBoundsArray) 23981f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa + " mMatrix=" + Objects.toString(mMatrix) 240c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa + "}"; 241c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 242c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 243c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 244c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Builder for {@link CursorAnchorInfo}. This class is not designed to be thread-safe. 245c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 246c46b5f04aa2a9fd292c117d2824f70fcf06e86baYohei Yukawa public static final class Builder { 2475f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa private int mSelectionStart = -1; 2485f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa private int mSelectionEnd = -1; 2495f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa private int mComposingTextStart = -1; 2505f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa private CharSequence mComposingText = null; 2515f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa private float mInsertionMarkerHorizontal = Float.NaN; 2525f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa private float mInsertionMarkerTop = Float.NaN; 2535f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa private float mInsertionMarkerBaseline = Float.NaN; 2545f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa private float mInsertionMarkerBottom = Float.NaN; 2555f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa private int mInsertionMarkerFlags = 0; 2565f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa private SparseRectFArrayBuilder mCharacterBoundsArrayBuilder = null; 2575f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa private final Matrix mMatrix = new Matrix(Matrix.IDENTITY_MATRIX); 2585f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa private boolean mMatrixInitialized = false; 2595f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa 260c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 261c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Sets the text range of the selection. Calling this can be skipped if there is no 262c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * selection. 263c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 264c46b5f04aa2a9fd292c117d2824f70fcf06e86baYohei Yukawa public Builder setSelectionRange(final int newStart, final int newEnd) { 265c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mSelectionStart = newStart; 266c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mSelectionEnd = newEnd; 267c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return this; 268c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 269c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 270c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 27181f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa * Sets the text range of the composing text. Calling this can be skipped if there is 27281f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa * no composing text. 273bb9f624252174afa49359ed2a90ec06113adff35Yohei Yukawa * @param composingTextStart index where the composing text starts. 27481f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa * @param composingText the entire composing text. 275c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 276bb9f624252174afa49359ed2a90ec06113adff35Yohei Yukawa public Builder setComposingText(final int composingTextStart, 277bb9f624252174afa49359ed2a90ec06113adff35Yohei Yukawa final CharSequence composingText) { 278bb9f624252174afa49359ed2a90ec06113adff35Yohei Yukawa mComposingTextStart = composingTextStart; 27981f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa if (composingText == null) { 28081f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa mComposingText = null; 28181f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa } else { 282a1fda005f9583486f4372ecbb0eec503ee9cece8Yohei Yukawa // Make a snapshot of the given char sequence. 283a1fda005f9583486f4372ecbb0eec503ee9cece8Yohei Yukawa mComposingText = new SpannedString(composingText); 28481f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa } 285c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return this; 286c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 287c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 288c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 289c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Sets the location of the text insertion point (zero width cursor) as a rectangle in 290c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * local coordinates. Calling this can be skipped when there is no text insertion point; 291c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * however if there is an insertion point, editors must call this method. 292c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @param horizontalPosition horizontal position of the insertion marker, in the local 293c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * coordinates that will be transformed with the transformation matrix when rendered on the 294c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * screen. This should be calculated or compatible with 295c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * {@link Layout#getPrimaryHorizontal(int)}. 296c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @param lineTop vertical position of the insertion marker, in the local coordinates that 297c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * will be transformed with the transformation matrix when rendered on the screen. This 298c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * should be calculated or compatible with {@link Layout#getLineTop(int)}. 299c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @param lineBaseline vertical position of the insertion marker, in the local coordinates 300c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * that will be transformed with the transformation matrix when rendered on the screen. This 301c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * should be calculated or compatible with {@link Layout#getLineBaseline(int)}. 302c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @param lineBottom vertical position of the insertion marker, in the local coordinates 303c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * that will be transformed with the transformation matrix when rendered on the screen. This 304c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * should be calculated or compatible with {@link Layout#getLineBottom(int)}. 305cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa * @param flags flags of the insertion marker. See {@link #FLAG_HAS_VISIBLE_REGION} for 306cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa * example. 307c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 308c46b5f04aa2a9fd292c117d2824f70fcf06e86baYohei Yukawa public Builder setInsertionMarkerLocation(final float horizontalPosition, 3090b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa final float lineTop, final float lineBaseline, final float lineBottom, 310cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa final int flags){ 311c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mInsertionMarkerHorizontal = horizontalPosition; 312c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mInsertionMarkerTop = lineTop; 313c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mInsertionMarkerBaseline = lineBaseline; 314c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mInsertionMarkerBottom = lineBottom; 315cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa mInsertionMarkerFlags = flags; 316c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return this; 317c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 3185f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa 3195f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa /** 3205f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * Adds the bounding box of the character specified with the index. 3215f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * 3225f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * @param index index of the character in Java chars units. Must be specified in 3235f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * ascending order across successive calls. 3245f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * @param left x coordinate of the left edge of the character in local coordinates. 3255f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * @param top y coordinate of the top edge of the character in local coordinates. 3265f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * @param right x coordinate of the right edge of the character in local coordinates. 3275f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * @param bottom y coordinate of the bottom edge of the character in local coordinates. 3285f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * @param flags flags for this character bounds. See {@link #FLAG_HAS_VISIBLE_REGION}, 3295f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * {@link #FLAG_HAS_INVISIBLE_REGION} and {@link #FLAG_IS_RTL}. These flags must be 3305f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * specified when necessary. 3315f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * @throws IllegalArgumentException If the index is a negative value, or not greater than 3325f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * all of the previously called indices. 3335f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa */ 3345f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa public Builder addCharacterBounds(final int index, final float left, final float top, 3355f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa final float right, final float bottom, final int flags) { 3365f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa if (index < 0) { 3375f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa throw new IllegalArgumentException("index must not be a negative integer."); 3385f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa } 3395f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa if (mCharacterBoundsArrayBuilder == null) { 3405f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa mCharacterBoundsArrayBuilder = new SparseRectFArrayBuilder(); 3415f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa } 3425f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa mCharacterBoundsArrayBuilder.append(index, left, top, right, bottom, flags); 3435f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa return this; 3445f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa } 345c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 346c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 347c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Sets the matrix that transforms local coordinates into screen coordinates. 348c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @param matrix transformation matrix from local coordinates into screen coordinates. null 349c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * is interpreted as an identity matrix. 350c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 351c46b5f04aa2a9fd292c117d2824f70fcf06e86baYohei Yukawa public Builder setMatrix(final Matrix matrix) { 352419b1b0498e33a556780be1702b444d54fcaa7ddYohei Yukawa mMatrix.set(matrix != null ? matrix : Matrix.IDENTITY_MATRIX); 353b5268dcc17cd9ecb540b06ad59bd74188b57a069Yohei Yukawa mMatrixInitialized = true; 354c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return this; 355c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 356c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 357c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 358b5268dcc17cd9ecb540b06ad59bd74188b57a069Yohei Yukawa * @return {@link CursorAnchorInfo} using parameters in this {@link Builder}. 359b5268dcc17cd9ecb540b06ad59bd74188b57a069Yohei Yukawa * @throws IllegalArgumentException if one or more positional parameters are specified but 360b5268dcc17cd9ecb540b06ad59bd74188b57a069Yohei Yukawa * the coordinate transformation matrix is not provided via {@link #setMatrix(Matrix)}. 361c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 362c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public CursorAnchorInfo build() { 363b5268dcc17cd9ecb540b06ad59bd74188b57a069Yohei Yukawa if (!mMatrixInitialized) { 3645f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa // Coordinate transformation matrix is mandatory when at least one positional 3655f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa // parameter is specified. 3665f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa final boolean hasCharacterBounds = (mCharacterBoundsArrayBuilder != null 3675f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa && !mCharacterBoundsArrayBuilder.isEmpty()); 3685f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa if (hasCharacterBounds 3695f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa || !Float.isNaN(mInsertionMarkerHorizontal) 3705f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa || !Float.isNaN(mInsertionMarkerTop) 3715f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa || !Float.isNaN(mInsertionMarkerBaseline) 3725f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa || !Float.isNaN(mInsertionMarkerBottom)) { 373b5268dcc17cd9ecb540b06ad59bd74188b57a069Yohei Yukawa throw new IllegalArgumentException("Coordinate transformation matrix is " + 374b5268dcc17cd9ecb540b06ad59bd74188b57a069Yohei Yukawa "required when positional parameters are specified."); 375b5268dcc17cd9ecb540b06ad59bd74188b57a069Yohei Yukawa } 376b5268dcc17cd9ecb540b06ad59bd74188b57a069Yohei Yukawa } 377c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return new CursorAnchorInfo(this); 378c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 379c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 380c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 381c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Resets the internal state so that this instance can be reused to build another 382c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * instance of {@link CursorAnchorInfo}. 383c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 384c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public void reset() { 385c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mSelectionStart = -1; 386c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mSelectionEnd = -1; 38781f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa mComposingTextStart = -1; 38881f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa mComposingText = null; 389cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa mInsertionMarkerFlags = 0; 390c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mInsertionMarkerHorizontal = Float.NaN; 391c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mInsertionMarkerTop = Float.NaN; 392c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mInsertionMarkerBaseline = Float.NaN; 393c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mInsertionMarkerBottom = Float.NaN; 394419b1b0498e33a556780be1702b444d54fcaa7ddYohei Yukawa mMatrix.set(Matrix.IDENTITY_MATRIX); 395b5268dcc17cd9ecb540b06ad59bd74188b57a069Yohei Yukawa mMatrixInitialized = false; 3965f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa if (mCharacterBoundsArrayBuilder != null) { 3975f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa mCharacterBoundsArrayBuilder.reset(); 398c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 399c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 400c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 401c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 402c46b5f04aa2a9fd292c117d2824f70fcf06e86baYohei Yukawa private CursorAnchorInfo(final Builder builder) { 403c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mSelectionStart = builder.mSelectionStart; 404c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mSelectionEnd = builder.mSelectionEnd; 40581f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa mComposingTextStart = builder.mComposingTextStart; 40681f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa mComposingText = builder.mComposingText; 407cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa mInsertionMarkerFlags = builder.mInsertionMarkerFlags; 408c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mInsertionMarkerHorizontal = builder.mInsertionMarkerHorizontal; 409c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mInsertionMarkerTop = builder.mInsertionMarkerTop; 410c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mInsertionMarkerBaseline = builder.mInsertionMarkerBaseline; 411c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa mInsertionMarkerBottom = builder.mInsertionMarkerBottom; 4125f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa mCharacterBoundsArray = builder.mCharacterBoundsArrayBuilder != null ? 4135f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa builder.mCharacterBoundsArrayBuilder.build() : null; 414419b1b0498e33a556780be1702b444d54fcaa7ddYohei Yukawa mMatrix = new Matrix(builder.mMatrix); 415c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 416c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 417c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 418c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Returns the index where the selection starts. 419eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa * @return {@code -1} if there is no selection. 420c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 421c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public int getSelectionStart() { 422c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return mSelectionStart; 423c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 424c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 425c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 426c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Returns the index where the selection ends. 427eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa * @return {@code -1} if there is no selection. 428c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 429c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public int getSelectionEnd() { 430c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return mSelectionEnd; 431c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 432c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 433c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 43481f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa * Returns the index where the composing text starts. 435eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa * @return {@code -1} if there is no composing text. 436c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 43781f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa public int getComposingTextStart() { 43881f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa return mComposingTextStart; 439c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 440c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 441c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 44281f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa * Returns the entire composing text. 443eea0b8b051e916051d0d09da3f41f9ec4d508bffYohei Yukawa * @return {@code null} if there is no composition. 444c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 445a1fda005f9583486f4372ecbb0eec503ee9cece8Yohei Yukawa public CharSequence getComposingText() { 44681f4cb3f858f46a4d9b793c4d326b9bf6aca868dYohei Yukawa return mComposingText; 447c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 448c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 449c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 450cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa * Returns the flag of the insertion marker. 451cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa * @return the flag of the insertion marker. {@code 0} if no flag is specified. 452cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa */ 453cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa public int getInsertionMarkerFlags() { 454cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa return mInsertionMarkerFlags; 455cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa } 456cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa 457cc24e2b6a2a429d70b75c6810a5cfd8816ce03adYohei Yukawa /** 458c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Returns the horizontal start of the insertion marker, in the local coordinates that will 459c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * be transformed with {@link #getMatrix()} when rendered on the screen. 460c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @return x coordinate that is compatible with {@link Layout#getPrimaryHorizontal(int)}. 461c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Pay special care to RTL/LTR handling. 462c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * {@code java.lang.Float.NaN} if not specified. 463c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @see Layout#getPrimaryHorizontal(int) 464c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 465c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public float getInsertionMarkerHorizontal() { 466c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return mInsertionMarkerHorizontal; 467c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 4680b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa 469c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 470c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Returns the vertical top position of the insertion marker, in the local coordinates that 471c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * will be transformed with {@link #getMatrix()} when rendered on the screen. 472c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @return y coordinate that is compatible with {@link Layout#getLineTop(int)}. 473c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * {@code java.lang.Float.NaN} if not specified. 474c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 475c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public float getInsertionMarkerTop() { 476c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return mInsertionMarkerTop; 477c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 4780b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa 479c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 480c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Returns the vertical baseline position of the insertion marker, in the local coordinates 481c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * that will be transformed with {@link #getMatrix()} when rendered on the screen. 482c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @return y coordinate that is compatible with {@link Layout#getLineBaseline(int)}. 483c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * {@code java.lang.Float.NaN} if not specified. 484c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 485c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public float getInsertionMarkerBaseline() { 486c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return mInsertionMarkerBaseline; 487c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 4880b01e7fc58cdde00d8350285a3386c4209b72d78Yohei Yukawa 489c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 490c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Returns the vertical bottom position of the insertion marker, in the local coordinates 491c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * that will be transformed with {@link #getMatrix()} when rendered on the screen. 492c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @return y coordinate that is compatible with {@link Layout#getLineBottom(int)}. 493c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * {@code java.lang.Float.NaN} if not specified. 494c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 495c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public float getInsertionMarkerBottom() { 496c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return mInsertionMarkerBottom; 497c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 498c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 499c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 500c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Returns a new instance of {@link RectF} that indicates the location of the character 501c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * specified with the index. 5025f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * @param index index of the character in a Java chars. 5035f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * @return the character bounds in local coordinates as a new instance of {@link RectF}. 5045f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa */ 5055f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa public RectF getCharacterBounds(final int index) { 5065f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa if (mCharacterBoundsArray == null) { 5075f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa return null; 5085f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa } 5095f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa return mCharacterBoundsArray.get(index); 5105f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa } 5115f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa 5125f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa /** 5135f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * Returns the flags associated with the character bounds specified with the index. 5145f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * @param index index of the character in a Java chars. 5155f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa * @return {@code 0} if no flag is specified. 5165f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa */ 5175f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa public int getCharacterBoundsFlags(final int index) { 5185f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa if (mCharacterBoundsArray == null) { 5195f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa return 0; 520c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 5215f183f0671dfa1d87ca6d741deb457170c432493Yohei Yukawa return mCharacterBoundsArray.getFlags(index, 0); 522c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 523c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 524c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 525c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Returns a new instance of {@link android.graphics.Matrix} that indicates the transformation 526c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * matrix that is to be applied other positional data in this class. 527c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * @return a new instance (copy) of the transformation matrix. 528c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 529c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public Matrix getMatrix() { 530c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return new Matrix(mMatrix); 531c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 532c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 533c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa /** 534c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa * Used to make this class parcelable. 535c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa */ 536c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public static final Parcelable.Creator<CursorAnchorInfo> CREATOR 537c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa = new Parcelable.Creator<CursorAnchorInfo>() { 538c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa @Override 539c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public CursorAnchorInfo createFromParcel(Parcel source) { 540c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return new CursorAnchorInfo(source); 541c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 542c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 543c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa @Override 544c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public CursorAnchorInfo[] newArray(int size) { 545c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return new CursorAnchorInfo[size]; 546c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 547c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa }; 548c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa 549c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa @Override 550c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa public int describeContents() { 551c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa return 0; 552c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa } 553c2ddd6023688db5ecf6c586e05f55e262b4a802eYohei Yukawa} 554