From 8eb8a2368ad028340126c247cfaa84c9dd4f09ea Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sat, 3 Feb 2024 11:35:11 +0100 Subject: [PATCH] remove unused code --- .../keyboard/internal/MatrixUtils.java | 151 ------------ .../keyboard/internal/SmoothingUtils.java | 89 ------- .../latin/utils/CursorAnchorInfoUtils.java | 232 ------------------ 3 files changed, 472 deletions(-) delete mode 100644 app/src/main/java/helium314/keyboard/keyboard/internal/MatrixUtils.java delete mode 100644 app/src/main/java/helium314/keyboard/keyboard/internal/SmoothingUtils.java delete mode 100644 app/src/main/java/helium314/keyboard/latin/utils/CursorAnchorInfoUtils.java diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/MatrixUtils.java b/app/src/main/java/helium314/keyboard/keyboard/internal/MatrixUtils.java deleted file mode 100644 index f05b8079..00000000 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/MatrixUtils.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * modified - * SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only - */ - -package helium314.keyboard.keyboard.internal; - -import helium314.keyboard.latin.utils.Log; - -import java.util.Arrays; -import java.util.Locale; - -/** - * Utilities for matrix operations. Don't instantiate objects inside this class to prevent - * unexpected performance regressions. - */ -public class MatrixUtils { - static final String TAG = MatrixUtils.class.getSimpleName(); - - public static class MatrixOperationFailedException extends Exception { - private static final long serialVersionUID = 4384485606788583829L; - - public MatrixOperationFailedException(String msg) { - super(msg); - Log.d(TAG, msg); - } - } - - /** - * A utility function to inverse matrix. - * Find a pivot and swap the row of squareMatrix0 and squareMatrix1 - */ - private static void findPivotAndSwapRow(final int row, final float[][] squareMatrix0, - final float[][] squareMatrix1, final int size) { - int ip = row; - float pivot = Math.abs(squareMatrix0[row][row]); - for (int i = row + 1; i < size; ++i) { - if (pivot < Math.abs(squareMatrix0[i][row])) { - ip = i; - pivot = Math.abs(squareMatrix0[i][row]); - } - } - if (ip != row) { - for (int j = 0; j < size; ++j) { - final float temp0 = squareMatrix0[ip][j]; - squareMatrix0[ip][j] = squareMatrix0[row][j]; - squareMatrix0[row][j] = temp0; - final float temp1 = squareMatrix1[ip][j]; - squareMatrix1[ip][j] = squareMatrix1[row][j]; - squareMatrix1[row][j] = temp1; - } - } - } - - /** - * A utility function to inverse matrix. This function calculates answer for each row by - * sweeping method of Gauss Jordan elimination - */ - private static void sweep(final int row, final float[][] squareMatrix0, - final float[][] squareMatrix1, final int size) throws MatrixOperationFailedException { - final float pivot = squareMatrix0[row][row]; - if (pivot == 0) { - throw new MatrixOperationFailedException("Inverse failed. Invalid pivot"); - } - for (int j = 0; j < size; ++j) { - squareMatrix0[row][j] /= pivot; - squareMatrix1[row][j] /= pivot; - } - for (int i = 0; i < size; i++) { - final float sweepTargetValue = squareMatrix0[i][row]; - if (i != row) { - for (int j = row; j < size; ++j) { - squareMatrix0[i][j] -= sweepTargetValue * squareMatrix0[row][j]; - } - for (int j = 0; j < size; ++j) { - squareMatrix1[i][j] -= sweepTargetValue * squareMatrix1[row][j]; - } - } - } - } - - /** - * A function to inverse matrix. - * The inverse matrix of squareMatrix will be output to inverseMatrix. Please notice that - * the value of squareMatrix is modified in this function and can't be resuable. - */ - public static void inverse(final float[][] squareMatrix, - final float[][] inverseMatrix) throws MatrixOperationFailedException { - final int size = squareMatrix.length; - if (squareMatrix[0].length != size || inverseMatrix.length != size - || inverseMatrix[0].length != size) { - throw new MatrixOperationFailedException( - "--- invalid length. column should be 2 times larger than row."); - } - for (int i = 0; i < size; ++i) { - Arrays.fill(inverseMatrix[i], 0.0f); - inverseMatrix[i][i] = 1.0f; - } - for (int i = 0; i < size; ++i) { - findPivotAndSwapRow(i, squareMatrix, inverseMatrix, size); - sweep(i, squareMatrix, inverseMatrix, size); - } - } - - /** - * A matrix operation to multiply m0 and m1. - */ - public static void multiply(final float[][] m0, final float[][] m1, - final float[][] retval) throws MatrixOperationFailedException { - if (m0[0].length != m1.length) { - throw new MatrixOperationFailedException( - "--- invalid length for multiply " + m0[0].length + ", " + m1.length); - } - final int m0h = m0.length; - final int m0w = m0[0].length; - final int m1w = m1[0].length; - if (retval.length != m0h || retval[0].length != m1w) { - throw new MatrixOperationFailedException( - "--- invalid length of retval " + retval.length + ", " + retval[0].length); - } - - for (int i = 0; i < m0h; i++) { - Arrays.fill(retval[i], 0); - for (int j = 0; j < m1w; j++) { - for (int k = 0; k < m0w; k++) { - retval[i][j] += m0[i][k] * m1[k][j]; - } - } - } - } - - /** - * A utility function to dump the specified matrix in a readable way - */ - public static void dump(final String title, final float[][] a) { - final int column = a[0].length; - final int row = a.length; - Log.d(TAG, "Dump matrix: " + title); - Log.d(TAG, "/*---------------------"); - final StringBuilder sb = new StringBuilder(); - for (float[] floats : a) { - sb.setLength(0); - for (int j = 0; j < column; ++j) { - sb.append(String.format(Locale.ROOT, "%4f", floats[j])).append(' '); - } - Log.d(TAG, sb.toString()); - } - Log.d(TAG, "---------------------*/"); - } -} diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/SmoothingUtils.java b/app/src/main/java/helium314/keyboard/keyboard/internal/SmoothingUtils.java deleted file mode 100644 index ff87454b..00000000 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/SmoothingUtils.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * modified - * SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only - */ - -package helium314.keyboard.keyboard.internal; - -import helium314.keyboard.keyboard.internal.MatrixUtils.MatrixOperationFailedException; -import helium314.keyboard.latin.utils.Log; - -import java.util.Arrays; - -/** - * Utilities to smooth coordinates. Currently, we calculate 3d least squares formula by using - * Lagrangian smoothing - */ -// todo: unused, what could this be used for? maybe just remove (then also remove MatrixUtils) -public class SmoothingUtils { - private static final String TAG = SmoothingUtils.class.getSimpleName(); - private static final boolean DEBUG = false; - - private SmoothingUtils() { - // not allowed to instantiate publicly - } - - /** - * Find a most likely 3d least squares formula for specified coordinates. - * "retval" should be a 1x4 size matrix. - */ - public static void get3DParameters(final float[] xs, final float[] ys, - final float[][] retval) throws MatrixOperationFailedException { - final int COEFF_COUNT = 4; // Coefficient count for 3d smoothing - if (retval.length != COEFF_COUNT || retval[0].length != 1) { - Log.d(TAG, "--- invalid length of 3d retval " + retval.length + ", " - + retval[0].length); - return; - } - final int N = xs.length; - // TODO: Never isntantiate the matrix - final float[][] m0 = new float[COEFF_COUNT][COEFF_COUNT]; - final float[][] m0Inv = new float[COEFF_COUNT][COEFF_COUNT]; - final float[][] m1 = new float[COEFF_COUNT][N]; - final float[][] m2 = new float[N][1]; - - // m0 - for (int i = 0; i < COEFF_COUNT; ++i) { - Arrays.fill(m0[i], 0); - for (int j = 0; j < COEFF_COUNT; ++j) { - final int pow = i + j; - for (float x : xs) { - m0[i][j] += (float) Math.pow(x, pow); - } - } - } - // m0Inv - MatrixUtils.inverse(m0, m0Inv); - if (DEBUG) { - MatrixUtils.dump("m0-1", m0Inv); - } - - // m1 - for (int i = 0; i < COEFF_COUNT; ++i) { - for (int j = 0; j < N; ++j) { - m1[i][j] = (i == 0) ? 1.0f : m1[i - 1][j] * xs[j]; - } - } - - // m2 - for (int i = 0; i < N; ++i) { - m2[i][0] = ys[i]; - } - - final float[][] m0Invxm1 = new float[COEFF_COUNT][N]; - if (DEBUG) { - MatrixUtils.dump("a0", m0Inv); - MatrixUtils.dump("a1", m1); - } - MatrixUtils.multiply(m0Inv, m1, m0Invxm1); - if (DEBUG) { - MatrixUtils.dump("a2", m0Invxm1); - MatrixUtils.dump("a3", m2); - } - MatrixUtils.multiply(m0Invxm1, m2, retval); - if (DEBUG) { - MatrixUtils.dump("result", retval); - } - } -} diff --git a/app/src/main/java/helium314/keyboard/latin/utils/CursorAnchorInfoUtils.java b/app/src/main/java/helium314/keyboard/latin/utils/CursorAnchorInfoUtils.java deleted file mode 100644 index 735e48e1..00000000 --- a/app/src/main/java/helium314/keyboard/latin/utils/CursorAnchorInfoUtils.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * modified - * SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only - */ - -package helium314.keyboard.latin.utils; - -import android.graphics.Matrix; -import android.graphics.Rect; -import android.inputmethodservice.ExtractEditText; -import android.inputmethodservice.InputMethodService; -import android.text.Layout; -import android.text.Spannable; -import android.text.Spanned; -import android.view.View; -import android.view.ViewParent; -import android.view.inputmethod.CursorAnchorInfo; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -// todo: remove this? or is there anything it could be useful for? -/** - * This class allows input methods to extract {@link CursorAnchorInfo} directly from the given - * {@link TextView}. This is useful and even necessary to support full-screen mode where the default - * {@link InputMethodService#onUpdateCursorAnchorInfo(CursorAnchorInfo)} event callback must be - * ignored because it reports the character locations of the target application rather than - * characters on {@link ExtractEditText}. - */ -public final class CursorAnchorInfoUtils { - private CursorAnchorInfoUtils() { - // This helper class is not instantiable. - } - - private static boolean isPositionVisible(final View view, final float positionX, - final float positionY) { - final float[] position = new float[] { positionX, positionY }; - View currentView = view; - - while (currentView != null) { - if (currentView != view) { - // Local scroll is already taken into account in positionX/Y - position[0] -= currentView.getScrollX(); - position[1] -= currentView.getScrollY(); - } - - if (position[0] < 0 || position[1] < 0 || - position[0] > currentView.getWidth() || position[1] > currentView.getHeight()) { - return false; - } - - if (!currentView.getMatrix().isIdentity()) { - currentView.getMatrix().mapPoints(position); - } - - position[0] += currentView.getLeft(); - position[1] += currentView.getTop(); - - final ViewParent parent = currentView.getParent(); - if (parent instanceof View) { - currentView = (View) parent; - } else { - // We've reached the ViewRoot, stop iterating - currentView = null; - } - } - - // We've been able to walk up the view hierarchy and the position was never clipped - return true; - } - - /** - * Returns {@link CursorAnchorInfo} from the given {@link TextView}. - * @param textView the target text view from which {@link CursorAnchorInfo} is to be extracted. - * @return the {@link CursorAnchorInfo} object based on the current layout. {@code null} if it - * is not feasible. - */ - @Nullable - private static CursorAnchorInfo extractFromTextViewInternal(@NonNull final TextView textView) { - final Layout layout = textView.getLayout(); - if (layout == null) { - return null; - } - - final CursorAnchorInfo.Builder builder = new CursorAnchorInfo.Builder(); - - final int selectionStart = textView.getSelectionStart(); - builder.setSelectionRange(selectionStart, textView.getSelectionEnd()); - - // Construct transformation matrix from view local coordinates to screen coordinates. - final Matrix viewToScreenMatrix = new Matrix(textView.getMatrix()); - final int[] viewOriginInScreen = new int[2]; - textView.getLocationOnScreen(viewOriginInScreen); - viewToScreenMatrix.postTranslate(viewOriginInScreen[0], viewOriginInScreen[1]); - builder.setMatrix(viewToScreenMatrix); - - if (layout.getLineCount() == 0) { - return null; - } - final Rect lineBoundsWithoutOffset = new Rect(); - final Rect lineBoundsWithOffset = new Rect(); - layout.getLineBounds(0, lineBoundsWithoutOffset); - textView.getLineBounds(0, lineBoundsWithOffset); - final float viewportToContentHorizontalOffset = lineBoundsWithOffset.left - - lineBoundsWithoutOffset.left - textView.getScrollX(); - final float viewportToContentVerticalOffset = lineBoundsWithOffset.top - - lineBoundsWithoutOffset.top - textView.getScrollY(); - - final CharSequence text = textView.getText(); - if (text instanceof Spannable) { - // Here we assume that the composing text is marked as SPAN_COMPOSING flag. This is not - // necessarily true, but basically works. - int composingTextStart = text.length(); - int composingTextEnd = 0; - final Spannable spannable = (Spannable) text; - final Object[] spans = spannable.getSpans(0, text.length(), Object.class); - for (Object span : spans) { - final int spanFlag = spannable.getSpanFlags(span); - if ((spanFlag & Spanned.SPAN_COMPOSING) != 0) { - composingTextStart = Math.min(composingTextStart, - spannable.getSpanStart(span)); - composingTextEnd = Math.max(composingTextEnd, spannable.getSpanEnd(span)); - } - } - - final boolean hasComposingText = - (0 <= composingTextStart) && (composingTextStart < composingTextEnd); - if (hasComposingText) { - final CharSequence composingText = text.subSequence(composingTextStart, - composingTextEnd); - builder.setComposingText(composingTextStart, composingText); - - final int minLine = layout.getLineForOffset(composingTextStart); - final int maxLine = layout.getLineForOffset(composingTextEnd - 1); - for (int line = minLine; line <= maxLine; ++line) { - final int lineStart = layout.getLineStart(line); - final int lineEnd = layout.getLineEnd(line); - final int offsetStart = Math.max(lineStart, composingTextStart); - final int offsetEnd = Math.min(lineEnd, composingTextEnd); - final boolean ltrLine = - layout.getParagraphDirection(line) == Layout.DIR_LEFT_TO_RIGHT; - final float[] widths = new float[offsetEnd - offsetStart]; - layout.getPaint().getTextWidths(text, offsetStart, offsetEnd, widths); - final float top = layout.getLineTop(line); - final float bottom = layout.getLineBottom(line); - for (int offset = offsetStart; offset < offsetEnd; ++offset) { - final float charWidth = widths[offset - offsetStart]; - final boolean isRtl = layout.isRtlCharAt(offset); - final float primary = layout.getPrimaryHorizontal(offset); - final float secondary = layout.getSecondaryHorizontal(offset); - // TODO: This doesn't work perfectly for text with custom styles and TAB - // chars. - final float left; - final float right; - if (ltrLine) { - if (isRtl) { - left = secondary - charWidth; - right = secondary; - } else { - left = primary; - right = primary + charWidth; - } - } else { - if (!isRtl) { - left = secondary; - right = secondary + charWidth; - } else { - left = primary - charWidth; - right = primary; - } - } - // TODO: Check top-right and bottom-left as well. - final float localLeft = left + viewportToContentHorizontalOffset; - final float localRight = right + viewportToContentHorizontalOffset; - final float localTop = top + viewportToContentVerticalOffset; - final float localBottom = bottom + viewportToContentVerticalOffset; - final boolean isTopLeftVisible = isPositionVisible(textView, - localLeft, localTop); - final boolean isBottomRightVisible = - isPositionVisible(textView, localRight, localBottom); - int characterBoundsFlags = 0; - if (isTopLeftVisible || isBottomRightVisible) { - characterBoundsFlags |= CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION; - } - if (!isTopLeftVisible || !isTopLeftVisible) { - characterBoundsFlags |= CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION; - } - if (isRtl) { - characterBoundsFlags |= CursorAnchorInfo.FLAG_IS_RTL; - } - // Here offset is the index in Java chars. - builder.addCharacterBounds(offset, localLeft, localTop, localRight, - localBottom, characterBoundsFlags); - } - } - } - } - - // Treat selectionStart as the insertion point. - if (0 <= selectionStart) { - final int offset = selectionStart; - final int line = layout.getLineForOffset(offset); - final float insertionMarkerX = layout.getPrimaryHorizontal(offset) - + viewportToContentHorizontalOffset; - final float insertionMarkerTop = layout.getLineTop(line) - + viewportToContentVerticalOffset; - final float insertionMarkerBaseline = layout.getLineBaseline(line) - + viewportToContentVerticalOffset; - final float insertionMarkerBottom = layout.getLineBottom(line) - + viewportToContentVerticalOffset; - final boolean isTopVisible = - isPositionVisible(textView, insertionMarkerX, insertionMarkerTop); - final boolean isBottomVisible = - isPositionVisible(textView, insertionMarkerX, insertionMarkerBottom); - int insertionMarkerFlags = 0; - if (isTopVisible || isBottomVisible) { - insertionMarkerFlags |= CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION; - } - if (!isTopVisible || !isBottomVisible) { - insertionMarkerFlags |= CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION; - } - if (layout.isRtlCharAt(offset)) { - insertionMarkerFlags |= CursorAnchorInfo.FLAG_IS_RTL; - } - builder.setInsertionMarkerLocation(insertionMarkerX, insertionMarkerTop, - insertionMarkerBaseline, insertionMarkerBottom, insertionMarkerFlags); - } - return builder.build(); - } -}