Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b5268dcc authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

Require coordinate transformation matrix if necessary

With this CL, CursorAnchorInfo.Builder#build() raises
IllegalArgumentException when an application author attempts to
instantiate CursorAnchorInfo without the coordinate
transformation matrix but with specifying some positional
parameters such as composing character rectangle.

Since any other positional members in CursorAnchorInfo are
supposed to be specified in local coordinates, the application
author must provide the coordinate transformation matrix for
such positional data.

Change-Id: I2b0fd0f146a2b95fe4fa1324837d8cfee667208c
parent 1928aabc
Loading
Loading
Loading
Loading
+18 −2
Original line number Diff line number Diff line
@@ -291,15 +291,30 @@ public final class CursorAnchorInfo implements Parcelable {
         */
        public Builder setMatrix(final Matrix matrix) {
            mMatrix.set(matrix != null ? matrix : Matrix.IDENTITY_MATRIX);
            mMatrixInitialized = true;
            return this;
        }
        private final Matrix mMatrix = new Matrix(Matrix.IDENTITY_MATRIX);
        private boolean mMatrixInitialized = false;

        /**
         * @return {@link CursorAnchorInfo} using parameters in this
         * {@link Builder}.
         * @return {@link CursorAnchorInfo} using parameters in this {@link Builder}.
         * @throws IllegalArgumentException if one or more positional parameters are specified but
         * the coordinate transformation matrix is not provided via {@link #setMatrix(Matrix)}.
         */
        public CursorAnchorInfo build() {
            if (!mMatrixInitialized) {
                // Coordinate transformation matrix is mandatory when positional parameters are
                // specified.
                if ((mCharacterRectBuilder != null && !mCharacterRectBuilder.isEmpty()) ||
                        !Float.isNaN(mInsertionMarkerHorizontal) ||
                        !Float.isNaN(mInsertionMarkerTop) ||
                        !Float.isNaN(mInsertionMarkerBaseline) ||
                        !Float.isNaN(mInsertionMarkerBottom)) {
                    throw new IllegalArgumentException("Coordinate transformation matrix is " +
                            "required when positional parameters are specified.");
                }
            }
            return new CursorAnchorInfo(this);
        }

@@ -317,6 +332,7 @@ public final class CursorAnchorInfo implements Parcelable {
            mInsertionMarkerBaseline = Float.NaN;
            mInsertionMarkerBottom = Float.NaN;
            mMatrix.set(Matrix.IDENTITY_MATRIX);
            mMatrixInitialized = false;
            if (mCharacterRectBuilder != null) {
                mCharacterRectBuilder.reset();
            }
+4 −0
Original line number Diff line number Diff line
@@ -196,6 +196,10 @@ public final class SparseRectFArray implements Parcelable {
        private float[] mCoordinates = null;
        private static int INITIAL_SIZE = 16;

        public boolean isEmpty() {
            return mCount <= 0;
        }

        /**
         * @return {@link SparseRectFArray} using parameters in this {@link SparseRectFArray}.
         */
+49 −3
Original line number Diff line number Diff line
@@ -59,9 +59,6 @@ public class CursorAnchorInfoTest extends InstrumentationTestCase {
        final float INSERTION_MARKER_TOP = 100.1f;
        final float INSERTION_MARKER_BASELINE = 110.4f;
        final float INSERTION_MARKER_BOTOM = 111.0f;
        final int CHAR_INDEX = 32;
        final char CHAR_VALUE = 'X';
        final char DEFAULT_CHAR_VALUE = '!';
        Matrix TRANSFORM_MATRIX = new Matrix(Matrix.IDENTITY_MATRIX);
        TRANSFORM_MATRIX.setScale(10.0f, 20.0f);

@@ -138,6 +135,7 @@ public class CursorAnchorInfoTest extends InstrumentationTestCase {
        assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerTop());
        assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBaseline());
        assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBottom());
        assertEquals(Matrix.IDENTITY_MATRIX, uninitializedInfo.getMatrix());
    }

    @SmallTest
@@ -168,6 +166,54 @@ public class CursorAnchorInfoTest extends InstrumentationTestCase {
        assertEquals(MATRIX2, secondInstance.getMatrix());
    }

    @SmallTest
    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 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.
                new Builder().build();
            } catch (IllegalArgumentException ex) {
                assertTrue(false);
            }

            builder.setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP,
                    INSERTION_MARKER_BASELINE, INSERTION_MARKER_BOTOM);
            try {
                // Coordinate transformation matrix is required if no positional information is
                // specified.
                new Builder().build();
            } catch (IllegalArgumentException ex) {
                assertTrue(true);
            }

            builder.setMatrix(TRANSFORM_MATRIX);
            try {
                // Should succeed as coordinate transformation matrix is required.
                new Builder().build();
            } catch (IllegalArgumentException ex) {
                assertTrue(false);
            }

            builder.reset();
        }
    }

    @SmallTest
    public void testBuilderAdd() throws Exception {
        // A negative index should be rejected.