Reland CursorAnchorInfo#createForAdditionalParentMatrix()
This logically relands the CL [1], which added an @hide method CursorAnchorInfo#createForAdditionalParentMatrix(). The corresponding change was once removed in [2]. This is a preparation to reland a change that supports InputMethodManager#reportActivityView() again. [1] Ic7f9057623ffc61ec7a6121735dc39adecf4649d [2] I0a05453eeed863db5bfe4b965ab4bcbad67f2783 Bug: 224424149 Test: CursorAnchorInfoTest Change-Id: I0a411453c7c26795d28e913a96be8eb8fa3684d7
This commit is contained in:
@@ -415,7 +415,7 @@ public final class CursorAnchorInfo implements Parcelable {
|
||||
"required when positional parameters are specified.");
|
||||
}
|
||||
}
|
||||
return new CursorAnchorInfo(this);
|
||||
return CursorAnchorInfo.create(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -440,31 +440,93 @@ 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;
|
||||
mEditorBoundsInfo = builder.mEditorBoundsInfo;
|
||||
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, builder.mEditorBoundsInfo, 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,
|
||||
@Nullable EditorBoundsInfo editorBoundsInfo,
|
||||
@NonNull float[] matrixValues) {
|
||||
mSelectionStart = selectionStart;
|
||||
mSelectionEnd = selectionEnd;
|
||||
mComposingTextStart = composingTextStart;
|
||||
mComposingText = composingText;
|
||||
mInsertionMarkerFlags = insertionMarkerFlags;
|
||||
mInsertionMarkerHorizontal = insertionMarkerHorizontal;
|
||||
mInsertionMarkerTop = insertionMarkerTop;
|
||||
mInsertionMarkerBaseline = insertionMarkerBaseline;
|
||||
mInsertionMarkerBottom = insertionMarkerBottom;
|
||||
mCharacterBoundsArray = characterBoundsArray;
|
||||
mEditorBoundsInfo = editorBoundsInfo;
|
||||
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(mMatrixValues);
|
||||
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,
|
||||
original.mEditorBoundsInfo, 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.view.inputmethod;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import android.graphics.Matrix;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class CursorAnchorInfoTest {
|
||||
@Test
|
||||
public void testCreateForAdditionalParentMatrix() {
|
||||
final Matrix originalMatrix = new Matrix();
|
||||
originalMatrix.setTranslate(10.0f, 20.0f);
|
||||
final CursorAnchorInfo.Builder builder = new CursorAnchorInfo.Builder();
|
||||
builder.setMatrix(originalMatrix);
|
||||
|
||||
final CursorAnchorInfo originalInstance = builder.build();
|
||||
|
||||
assertEquals(originalMatrix, originalInstance.getMatrix());
|
||||
|
||||
final Matrix additionalParentMatrix = new Matrix();
|
||||
additionalParentMatrix.setTranslate(1.0f, 2.0f);
|
||||
|
||||
final Matrix newMatrix = new Matrix(originalMatrix);
|
||||
newMatrix.postConcat(additionalParentMatrix);
|
||||
|
||||
builder.reset();
|
||||
builder.setMatrix(newMatrix);
|
||||
// An instance created by the standard Builder class.
|
||||
final CursorAnchorInfo newInstanceByBuilder = builder.build();
|
||||
|
||||
// An instance created by an @hide method.
|
||||
final CursorAnchorInfo newInstanceByMethod =
|
||||
CursorAnchorInfo.createForAdditionalParentMatrix(
|
||||
originalInstance, additionalParentMatrix);
|
||||
|
||||
assertEquals(newMatrix, newInstanceByBuilder.getMatrix());
|
||||
assertEquals(newMatrix, newInstanceByMethod.getMatrix());
|
||||
assertEquals(newInstanceByBuilder.hashCode(), newInstanceByMethod.hashCode());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user