Merge "Add an @hide way to adjust CursorAnchorInfo for another Matrix" into qt-dev

This commit is contained in:
TreeHugger Robot
2019-05-03 15:56:32 +00:00
committed by Android (Google) Code Review
2 changed files with 102 additions and 450 deletions

View File

@@ -17,6 +17,7 @@
package android.view.inputmethod;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.os.Parcel;
@@ -388,7 +389,7 @@ public final class CursorAnchorInfo implements Parcelable {
"required when positional parameters are specified.");
}
}
return new CursorAnchorInfo(this);
return CursorAnchorInfo.create(this);
}
/**
@@ -412,30 +413,90 @@ public final class CursorAnchorInfo implements Parcelable {
}
}
private CursorAnchorInfo(final Builder builder) {
mSelectionStart = builder.mSelectionStart;
mSelectionEnd = builder.mSelectionEnd;
mComposingTextStart = builder.mComposingTextStart;
mComposingText = builder.mComposingText;
mInsertionMarkerFlags = builder.mInsertionMarkerFlags;
mInsertionMarkerHorizontal = builder.mInsertionMarkerHorizontal;
mInsertionMarkerTop = builder.mInsertionMarkerTop;
mInsertionMarkerBaseline = builder.mInsertionMarkerBaseline;
mInsertionMarkerBottom = builder.mInsertionMarkerBottom;
mCharacterBoundsArray = builder.mCharacterBoundsArrayBuilder != null ?
builder.mCharacterBoundsArrayBuilder.build() : null;
mMatrixValues = new float[9];
private static CursorAnchorInfo create(Builder builder) {
final SparseRectFArray characterBoundsArray =
builder.mCharacterBoundsArrayBuilder != null
? builder.mCharacterBoundsArrayBuilder.build()
: null;
final float[] matrixValues = new float[9];
if (builder.mMatrixInitialized) {
System.arraycopy(builder.mMatrixValues, 0, mMatrixValues, 0, 9);
System.arraycopy(builder.mMatrixValues, 0, matrixValues, 0, 9);
} else {
Matrix.IDENTITY_MATRIX.getValues(mMatrixValues);
Matrix.IDENTITY_MATRIX.getValues(matrixValues);
}
return new CursorAnchorInfo(builder.mSelectionStart, builder.mSelectionEnd,
builder.mComposingTextStart, builder.mComposingText, builder.mInsertionMarkerFlags,
builder.mInsertionMarkerHorizontal, builder.mInsertionMarkerTop,
builder.mInsertionMarkerBaseline, builder.mInsertionMarkerBottom,
characterBoundsArray, matrixValues);
}
private CursorAnchorInfo(int selectionStart, int selectionEnd, int composingTextStart,
@Nullable CharSequence composingText, int insertionMarkerFlags,
float insertionMarkerHorizontal, float insertionMarkerTop,
float insertionMarkerBaseline, float insertionMarkerBottom,
@Nullable SparseRectFArray characterBoundsArray, @NonNull float[] matrixValues) {
mSelectionStart = selectionStart;
mSelectionEnd = selectionEnd;
mComposingTextStart = composingTextStart;
mComposingText = composingText;
mInsertionMarkerFlags = insertionMarkerFlags;
mInsertionMarkerHorizontal = insertionMarkerHorizontal;
mInsertionMarkerTop = insertionMarkerTop;
mInsertionMarkerBaseline = insertionMarkerBaseline;
mInsertionMarkerBottom = insertionMarkerBottom;
mCharacterBoundsArray = characterBoundsArray;
mMatrixValues = matrixValues;
// To keep hash function simple, we only use some complex objects for hash.
int hash = Objects.hashCode(mComposingText);
hash *= 31;
hash += Arrays.hashCode(mMatrixValues);
mHashCode = hash;
int hashCode = Objects.hashCode(mComposingText);
hashCode *= 31;
hashCode += Arrays.hashCode(matrixValues);
mHashCode = hashCode;
}
/**
* Creates a new instance of {@link CursorAnchorInfo} by applying {@code parentMatrix} to
* the coordinate transformation matrix.
*
* @param original {@link CursorAnchorInfo} to be cloned from.
* @param parentMatrix {@link Matrix} to be applied to {@code original.getMatrix()}
* @return A new instance of {@link CursorAnchorInfo} whose {@link CursorAnchorInfo#getMatrix()}
* returns {@code parentMatrix * original.getMatrix()}.
* @hide
*/
public static CursorAnchorInfo createForAdditionalParentMatrix(CursorAnchorInfo original,
@NonNull Matrix parentMatrix) {
return new CursorAnchorInfo(original.mSelectionStart, original.mSelectionEnd,
original.mComposingTextStart, original.mComposingText,
original.mInsertionMarkerFlags, original.mInsertionMarkerHorizontal,
original.mInsertionMarkerTop, original.mInsertionMarkerBaseline,
original.mInsertionMarkerBottom, original.mCharacterBoundsArray,
computeMatrixValues(parentMatrix, original));
}
/**
* Returns a float array that represents {@link Matrix} elements for
* {@code parentMatrix * info.getMatrix()}.
*
* @param parentMatrix {@link Matrix} to be multiplied.
* @param info {@link CursorAnchorInfo} to provide {@link Matrix} to be multiplied.
* @return {@code parentMatrix * info.getMatrix()}.
*/
private static float[] computeMatrixValues(@NonNull Matrix parentMatrix,
@NonNull CursorAnchorInfo info) {
if (parentMatrix.isIdentity()) {
return info.mMatrixValues;
}
final Matrix newMatrix = new Matrix();
newMatrix.setValues(info.mMatrixValues);
newMatrix.postConcat(parentMatrix);
final float[] matrixValues = new float[9];
newMatrix.getValues(matrixValues);
return matrixValues;
}
/**

View File

@@ -16,19 +16,9 @@
package android.view.inputmethod;
import static android.view.inputmethod.CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION;
import static android.view.inputmethod.CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
import static android.view.inputmethod.CursorAnchorInfo.FLAG_IS_RTL;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.os.Parcel;
import android.text.TextUtils;
import android.view.inputmethod.CursorAnchorInfo.Builder;
import androidx.test.filters.SmallTest;
@@ -37,437 +27,38 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Objects;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class CursorAnchorInfoTest {
private static final float EPSILON = 0.0000001f;
private static final RectF[] MANY_BOUNDS = new RectF[] {
new RectF(101.0f, 201.0f, 301.0f, 401.0f),
new RectF(102.0f, 202.0f, 302.0f, 402.0f),
new RectF(103.0f, 203.0f, 303.0f, 403.0f),
new RectF(104.0f, 204.0f, 304.0f, 404.0f),
new RectF(105.0f, 205.0f, 305.0f, 405.0f),
new RectF(106.0f, 206.0f, 306.0f, 406.0f),
new RectF(107.0f, 207.0f, 307.0f, 407.0f),
new RectF(108.0f, 208.0f, 308.0f, 408.0f),
new RectF(109.0f, 209.0f, 309.0f, 409.0f),
new RectF(110.0f, 210.0f, 310.0f, 410.0f),
new RectF(111.0f, 211.0f, 311.0f, 411.0f),
new RectF(112.0f, 212.0f, 312.0f, 412.0f),
new RectF(113.0f, 213.0f, 313.0f, 413.0f),
new RectF(114.0f, 214.0f, 314.0f, 414.0f),
new RectF(115.0f, 215.0f, 315.0f, 415.0f),
new RectF(116.0f, 216.0f, 316.0f, 416.0f),
new RectF(117.0f, 217.0f, 317.0f, 417.0f),
new RectF(118.0f, 218.0f, 318.0f, 418.0f),
new RectF(119.0f, 219.0f, 319.0f, 419.0f),
};
private static final int[] MANY_FLAGS_ARRAY = new int[] {
FLAG_HAS_INVISIBLE_REGION,
FLAG_HAS_INVISIBLE_REGION | FLAG_HAS_VISIBLE_REGION,
FLAG_HAS_VISIBLE_REGION,
FLAG_HAS_VISIBLE_REGION,
FLAG_HAS_VISIBLE_REGION,
FLAG_HAS_VISIBLE_REGION,
FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
FLAG_HAS_INVISIBLE_REGION | FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
FLAG_HAS_INVISIBLE_REGION | FLAG_IS_RTL,
FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
FLAG_HAS_VISIBLE_REGION,
FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
FLAG_HAS_VISIBLE_REGION,
FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
FLAG_HAS_VISIBLE_REGION,
FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
FLAG_HAS_VISIBLE_REGION,
FLAG_HAS_INVISIBLE_REGION,
FLAG_HAS_INVISIBLE_REGION | FLAG_IS_RTL,
};
@Test
public void testBuilder() throws Exception {
final int SELECTION_START = 30;
final int SELECTION_END = 40;
final int COMPOSING_TEXT_START = 32;
final String COMPOSING_TEXT = "test";
final int INSERTION_MARKER_FLAGS =
FLAG_HAS_VISIBLE_REGION | FLAG_HAS_INVISIBLE_REGION | FLAG_IS_RTL;
final float INSERTION_MARKER_HORIZONTAL = 10.5f;
final float INSERTION_MARKER_TOP = 100.1f;
final float INSERTION_MARKER_BASELINE = 110.4f;
final float INSERTION_MARKER_BOTOM = 111.0f;
Matrix TRANSFORM_MATRIX = new Matrix(Matrix.IDENTITY_MATRIX);
TRANSFORM_MATRIX.setScale(10.0f, 20.0f);
public void testCreateForAdditionalParentMatrix() {
final Matrix originalMatrix = new Matrix();
originalMatrix.setTranslate(10.0f, 20.0f);
final Builder builder = new Builder();
builder.setSelectionRange(SELECTION_START, SELECTION_END)
.setComposingText(COMPOSING_TEXT_START, COMPOSING_TEXT)
.setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP,
INSERTION_MARKER_BASELINE, INSERTION_MARKER_BOTOM, INSERTION_MARKER_FLAGS)
.setMatrix(TRANSFORM_MATRIX);
for (int i = 0; i < MANY_BOUNDS.length; i++) {
final RectF bounds = MANY_BOUNDS[i];
final int flags = MANY_FLAGS_ARRAY[i];
builder.addCharacterBounds(i, bounds.left, bounds.top, bounds.right, bounds.bottom,
flags);
}
builder.setMatrix(originalMatrix);
final CursorAnchorInfo info = builder.build();
assertEquals(SELECTION_START, info.getSelectionStart());
assertEquals(SELECTION_END, info.getSelectionEnd());
assertEquals(COMPOSING_TEXT_START, info.getComposingTextStart());
assertTrue(TextUtils.equals(COMPOSING_TEXT, info.getComposingText()));
assertEquals(INSERTION_MARKER_FLAGS, info.getInsertionMarkerFlags());
assertEquals(INSERTION_MARKER_HORIZONTAL, info.getInsertionMarkerHorizontal(), EPSILON);
assertEquals(INSERTION_MARKER_TOP, info.getInsertionMarkerTop(), EPSILON);
assertEquals(INSERTION_MARKER_BASELINE, info.getInsertionMarkerBaseline(), EPSILON);
assertEquals(INSERTION_MARKER_BOTOM, info.getInsertionMarkerBottom(), EPSILON);
assertEquals(TRANSFORM_MATRIX, info.getMatrix());
for (int i = 0; i < MANY_BOUNDS.length; i++) {
final RectF expectedBounds = MANY_BOUNDS[i];
assertEquals(expectedBounds, info.getCharacterBounds(i));
}
assertNull(info.getCharacterBounds(-1));
assertNull(info.getCharacterBounds(MANY_BOUNDS.length + 1));
for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) {
final int expectedFlags = MANY_FLAGS_ARRAY[i];
assertEquals(expectedFlags, info.getCharacterBoundsFlags(i));
}
assertEquals(0, info.getCharacterBoundsFlags(-1));
assertEquals(0, info.getCharacterBoundsFlags(MANY_BOUNDS.length + 1));
final CursorAnchorInfo originalInstance = builder.build();
// Make sure that the builder can reproduce the same object.
final CursorAnchorInfo info2 = builder.build();
assertEquals(SELECTION_START, info2.getSelectionStart());
assertEquals(SELECTION_END, info2.getSelectionEnd());
assertEquals(COMPOSING_TEXT_START, info2.getComposingTextStart());
assertTrue(TextUtils.equals(COMPOSING_TEXT, info2.getComposingText()));
assertEquals(INSERTION_MARKER_FLAGS, info2.getInsertionMarkerFlags());
assertEquals(INSERTION_MARKER_HORIZONTAL, info2.getInsertionMarkerHorizontal(), EPSILON);
assertEquals(INSERTION_MARKER_TOP, info2.getInsertionMarkerTop(), EPSILON);
assertEquals(INSERTION_MARKER_BASELINE, info2.getInsertionMarkerBaseline(), EPSILON);
assertEquals(INSERTION_MARKER_BOTOM, info2.getInsertionMarkerBottom(), EPSILON);
assertEquals(TRANSFORM_MATRIX, info2.getMatrix());
for (int i = 0; i < MANY_BOUNDS.length; i++) {
final RectF expectedBounds = MANY_BOUNDS[i];
assertEquals(expectedBounds, info2.getCharacterBounds(i));
}
assertNull(info2.getCharacterBounds(-1));
assertNull(info2.getCharacterBounds(MANY_BOUNDS.length + 1));
for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) {
final int expectedFlags = MANY_FLAGS_ARRAY[i];
assertEquals(expectedFlags, info2.getCharacterBoundsFlags(i));
}
assertEquals(0, info2.getCharacterBoundsFlags(-1));
assertEquals(0, info2.getCharacterBoundsFlags(MANY_BOUNDS.length + 1));
assertEquals(info, info2);
assertEquals(info.hashCode(), info2.hashCode());
assertEquals(originalMatrix, originalInstance.getMatrix());
// Make sure that object can be marshaled via {@link Parsel}.
final CursorAnchorInfo info3 = cloneViaParcel(info2);
assertEquals(SELECTION_START, info3.getSelectionStart());
assertEquals(SELECTION_END, info3.getSelectionEnd());
assertEquals(COMPOSING_TEXT_START, info3.getComposingTextStart());
assertTrue(TextUtils.equals(COMPOSING_TEXT, info3.getComposingText()));
assertEquals(INSERTION_MARKER_FLAGS, info3.getInsertionMarkerFlags());
assertEquals(INSERTION_MARKER_HORIZONTAL, info3.getInsertionMarkerHorizontal(), EPSILON);
assertEquals(INSERTION_MARKER_TOP, info3.getInsertionMarkerTop(), EPSILON);
assertEquals(INSERTION_MARKER_BASELINE, info3.getInsertionMarkerBaseline(), EPSILON);
assertEquals(INSERTION_MARKER_BOTOM, info3.getInsertionMarkerBottom(), EPSILON);
assertEquals(TRANSFORM_MATRIX, info3.getMatrix());
for (int i = 0; i < MANY_BOUNDS.length; i++) {
final RectF expectedBounds = MANY_BOUNDS[i];
assertEquals(expectedBounds, info3.getCharacterBounds(i));
}
assertNull(info3.getCharacterBounds(-1));
assertNull(info3.getCharacterBounds(MANY_BOUNDS.length + 1));
for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) {
final int expectedFlags = MANY_FLAGS_ARRAY[i];
assertEquals(expectedFlags, info3.getCharacterBoundsFlags(i));
}
assertEquals(0, info3.getCharacterBoundsFlags(-1));
assertEquals(0, info3.getCharacterBoundsFlags(MANY_BOUNDS.length + 1));
assertEquals(info.hashCode(), info3.hashCode());
final Matrix additionalParentMatrix = new Matrix();
additionalParentMatrix.setTranslate(1.0f, 2.0f);
final Matrix newMatrix = new Matrix(originalMatrix);
newMatrix.postConcat(additionalParentMatrix);
builder.reset();
final CursorAnchorInfo uninitializedInfo = builder.build();
assertEquals(-1, uninitializedInfo.getSelectionStart());
assertEquals(-1, uninitializedInfo.getSelectionEnd());
assertEquals(-1, uninitializedInfo.getComposingTextStart());
assertNull(uninitializedInfo.getComposingText());
assertEquals(0, uninitializedInfo.getInsertionMarkerFlags());
assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerHorizontal(), EPSILON);
assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerTop(), EPSILON);
assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBaseline(), EPSILON);
assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBottom(), EPSILON);
assertEquals(Matrix.IDENTITY_MATRIX, uninitializedInfo.getMatrix());
}
builder.setMatrix(newMatrix);
// An instance created by the standard Builder class.
final CursorAnchorInfo newInstanceByBuilder = builder.build();
private static void assertNotEquals(final CursorAnchorInfo reference,
final CursorAnchorInfo actual) {
assertFalse(Objects.equals(reference, actual));
}
// An instance created by an @hide method.
final CursorAnchorInfo newInstanceByMethod =
CursorAnchorInfo.createForAdditionalParentMatrix(
originalInstance, additionalParentMatrix);
@Test
public void testEquality() throws Exception {
final Matrix MATRIX1 = new Matrix();
MATRIX1.setTranslate(10.0f, 20.0f);
final Matrix MATRIX2 = new Matrix();
MATRIX2.setTranslate(110.0f, 120.0f);
final Matrix NAN_MATRIX = new Matrix();
NAN_MATRIX.setValues(new float[]{
Float.NaN, Float.NaN, Float.NaN,
Float.NaN, Float.NaN, Float.NaN,
Float.NaN, Float.NaN, Float.NaN});
final int SELECTION_START1 = 2;
final int SELECTION_END1 = 7;
final String COMPOSING_TEXT1 = "0123456789";
final int COMPOSING_TEXT_START1 = 0;
final int INSERTION_MARKER_FLAGS1 = FLAG_HAS_VISIBLE_REGION;
final float INSERTION_MARKER_HORIZONTAL1 = 10.5f;
final float INSERTION_MARKER_TOP1 = 100.1f;
final float INSERTION_MARKER_BASELINE1 = 110.4f;
final float INSERTION_MARKER_BOTOM1 = 111.0f;
final int SELECTION_START2 = 4;
final int SELECTION_END2 = 8;
final String COMPOSING_TEXT2 = "9876543210";
final int COMPOSING_TEXT_START2 = 3;
final int INSERTION_MARKER_FLAGS2 =
FLAG_HAS_VISIBLE_REGION | FLAG_HAS_INVISIBLE_REGION | FLAG_IS_RTL;
final float INSERTION_MARKER_HORIZONTAL2 = 14.5f;
final float INSERTION_MARKER_TOP2 = 200.1f;
final float INSERTION_MARKER_BASELINE2 = 210.4f;
final float INSERTION_MARKER_BOTOM2 = 211.0f;
// Default instance should be equal.
assertEquals(new Builder().build(), new Builder().build());
assertEquals(
new Builder().setSelectionRange(SELECTION_START1, SELECTION_END1).build(),
new Builder().setSelectionRange(SELECTION_START1, SELECTION_END1).build());
assertNotEquals(
new Builder().setSelectionRange(SELECTION_START1, SELECTION_END1).build(),
new Builder().setSelectionRange(SELECTION_START1, SELECTION_END2).build());
assertNotEquals(
new Builder().setSelectionRange(SELECTION_START1, SELECTION_END1).build(),
new Builder().setSelectionRange(SELECTION_START2, SELECTION_END1).build());
assertNotEquals(
new Builder().setSelectionRange(SELECTION_START1, SELECTION_END1).build(),
new Builder().setSelectionRange(SELECTION_START2, SELECTION_END2).build());
assertEquals(
new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT1).build(),
new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT1).build());
assertNotEquals(
new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT1).build(),
new Builder().setComposingText(COMPOSING_TEXT_START2, COMPOSING_TEXT1).build());
assertNotEquals(
new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT1).build(),
new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT2).build());
assertNotEquals(
new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT1).build(),
new Builder().setComposingText(COMPOSING_TEXT_START2, COMPOSING_TEXT2).build());
// For insertion marker locations, {@link Float#NaN} is treated as if it was a number.
assertEquals(
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
Float.NaN, Float.NaN, Float.NaN, Float.NaN,
INSERTION_MARKER_FLAGS1).build(),
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
Float.NaN, Float.NaN, Float.NaN, Float.NaN,
INSERTION_MARKER_FLAGS1).build());
// Check Matrix.
assertEquals(
new Builder().setMatrix(MATRIX1).build(),
new Builder().setMatrix(MATRIX1).build());
assertNotEquals(
new Builder().setMatrix(MATRIX1).build(),
new Builder().setMatrix(MATRIX2).build());
assertNotEquals(
new Builder().setMatrix(MATRIX1).build(),
new Builder().setMatrix(NAN_MATRIX).build());
// Unlike insertion marker locations, {@link Float#NaN} in the matrix is treated as just a
// NaN as usual (NaN == NaN -> false).
assertNotEquals(
new Builder().setMatrix(NAN_MATRIX).build(),
new Builder().setMatrix(NAN_MATRIX).build());
assertEquals(
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
INSERTION_MARKER_FLAGS1).build(),
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
INSERTION_MARKER_FLAGS1).build());
assertNotEquals(
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
Float.NaN, INSERTION_MARKER_TOP1,
INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
INSERTION_MARKER_FLAGS1).build(),
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
INSERTION_MARKER_FLAGS1).build());
assertNotEquals(
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
INSERTION_MARKER_FLAGS1).build(),
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
INSERTION_MARKER_HORIZONTAL2, INSERTION_MARKER_TOP1,
INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
INSERTION_MARKER_FLAGS1).build());
assertNotEquals(
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
INSERTION_MARKER_FLAGS1).build(),
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP2,
INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
INSERTION_MARKER_FLAGS1).build());
assertNotEquals(
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
INSERTION_MARKER_FLAGS1).build(),
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
INSERTION_MARKER_BASELINE2, INSERTION_MARKER_BOTOM1,
INSERTION_MARKER_FLAGS1).build());
assertNotEquals(
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
INSERTION_MARKER_FLAGS1).build(),
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
INSERTION_MARKER_HORIZONTAL2, INSERTION_MARKER_TOP1,
INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
INSERTION_MARKER_FLAGS1).build());
assertNotEquals(
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
INSERTION_MARKER_FLAGS1).build(),
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM2,
INSERTION_MARKER_FLAGS1).build());
assertNotEquals(
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
INSERTION_MARKER_FLAGS1).build(),
new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
INSERTION_MARKER_FLAGS2).build());
}
@Test
public void testMatrixIsCopied() throws Exception {
final Matrix MATRIX1 = new Matrix();
MATRIX1.setTranslate(10.0f, 20.0f);
final Matrix MATRIX2 = new Matrix();
MATRIX2.setTranslate(110.0f, 120.0f);
final Matrix MATRIX3 = new Matrix();
MATRIX3.setTranslate(210.0f, 220.0f);
final Matrix matrix = new Matrix();
final Builder builder = new Builder();
matrix.set(MATRIX1);
builder.setMatrix(matrix);
matrix.postRotate(90.0f);
final CursorAnchorInfo firstInstance = builder.build();
assertEquals(MATRIX1, firstInstance.getMatrix());
matrix.set(MATRIX2);
builder.setMatrix(matrix);
final CursorAnchorInfo secondInstance = builder.build();
assertEquals(MATRIX1, firstInstance.getMatrix());
assertEquals(MATRIX2, secondInstance.getMatrix());
matrix.set(MATRIX3);
assertEquals(MATRIX1, firstInstance.getMatrix());
assertEquals(MATRIX2, secondInstance.getMatrix());
}
@Test
public void testMatrixIsRequired() throws Exception {
final int SELECTION_START = 30;
final int SELECTION_END = 40;
final int COMPOSING_TEXT_START = 32;
final String COMPOSING_TEXT = "test";
final int INSERTION_MARKER_FLAGS = FLAG_HAS_VISIBLE_REGION;
final float INSERTION_MARKER_HORIZONTAL = 10.5f;
final float INSERTION_MARKER_TOP = 100.1f;
final float INSERTION_MARKER_BASELINE = 110.4f;
final float INSERTION_MARKER_BOTOM = 111.0f;
Matrix TRANSFORM_MATRIX = new Matrix(Matrix.IDENTITY_MATRIX);
TRANSFORM_MATRIX.setScale(10.0f, 20.0f);
final Builder builder = new Builder();
// Check twice to make sure if Builder#reset() works as expected.
for (int repeatCount = 0; repeatCount < 2; ++repeatCount) {
builder.setSelectionRange(SELECTION_START, SELECTION_END)
.setComposingText(COMPOSING_TEXT_START, COMPOSING_TEXT);
try {
// Should succeed as coordinate transformation matrix is not required if no
// positional information is specified.
builder.build();
} catch (IllegalArgumentException ex) {
assertTrue(false);
}
builder.setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP,
INSERTION_MARKER_BASELINE, INSERTION_MARKER_BOTOM, INSERTION_MARKER_FLAGS);
try {
// Coordinate transformation matrix is required if no positional information is
// specified.
builder.build();
assertTrue(false);
} catch (IllegalArgumentException ex) {
}
builder.setMatrix(TRANSFORM_MATRIX);
try {
// Should succeed as coordinate transformation matrix is required.
builder.build();
} catch (IllegalArgumentException ex) {
assertTrue(false);
}
builder.reset();
}
}
@Test
public void testBuilderAddCharacterBounds() throws Exception {
// A negative index should be rejected.
try {
new Builder().addCharacterBounds(-1, 0.0f, 0.0f, 0.0f, 0.0f, FLAG_HAS_VISIBLE_REGION);
assertTrue(false);
} catch (IllegalArgumentException ex) {
}
}
private static CursorAnchorInfo cloneViaParcel(final CursorAnchorInfo src) {
Parcel parcel = null;
try {
parcel = Parcel.obtain();
src.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
return new CursorAnchorInfo(parcel);
} finally {
if (parcel != null) {
parcel.recycle();
}
}
assertEquals(newMatrix, newInstanceByBuilder.getMatrix());
assertEquals(newMatrix, newInstanceByMethod.getMatrix());
assertEquals(newInstanceByBuilder.hashCode(), newInstanceByMethod.hashCode());
}
}