com.duy.pascal.ui.editor.view.LineUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.duy.pascal.ui.editor.view.LineUtils.java

Source

/*
 *  Copyright (c) 2017 Tran Le Duy
 *
 * 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 com.duy.pascal.ui.editor.view;

import android.support.annotation.NonNull;
import android.support.v4.util.Pair;
import android.text.Layout;
import android.text.TextUtils;
import android.widget.EditText;
import android.widget.ScrollView;

import com.duy.pascal.ui.utils.DLog;

public class LineUtils {
    private static final String TAG = "LineUtils";
    private boolean[] toCountLinesArray;
    private int[] realLines;

    /**
     * @param editable - edit text
     * @param line   - current line
     * @param col    - column index at current line
     * @return the index at (line:col)
     */
    public static int getIndexFromLineCol(Layout editable, int line, int col) {
        int index = editable.getLineStart(line);
        index += col;
        return Math.min(index, editable.getText().length());
    }

    public static int getYAtLine(ScrollView scrollView, int lineCount, int line) {
        if (lineCount == 0)
            return 0;
        return scrollView.getChildAt(0).getHeight() / lineCount * line;
    }

    public static int getFirstVisibleLine(@NonNull ScrollView scrollView, int childHeight, int lineCount)
            throws ArithmeticException {
        if (childHeight == 0)
            return 0;
        int line = (scrollView.getScrollY() * lineCount) / childHeight;
        if (line < 0)
            line = 0;
        return line;
    }

    public static int getLastVisibleLine(@NonNull ScrollView scrollView, int childHeight, int lineCount) {
        if (childHeight == 0)
            return 0;
        int line = (scrollView.getScrollY() * lineCount) / childHeight;
        if (line > lineCount)
            line = lineCount;
        return line;
    }

    /**
     * Gets the lineInfo from the index of the letter in the text
     */
    public static int getLineFromIndex(int index, int lineCount, Layout layout) {
        int line;
        int currentIndex = 0;

        for (line = 0; line < lineCount; line++) {
            currentIndex += layout.getLineEnd(line) - layout.getLineStart(line);
            if (currentIndex > index) {
                break;
            }
        }
        return line;
    }

    /**
     * Gets the line from the index of the letter in the text
     * <p>
     * 1  2  3  |
     * ^  ^  ^  ^
     * 0  1  2  cursor at 4, return (line;col) = (0;4), line start at 0, column start at 0
     */
    @NonNull
    public static Pair<Integer, Integer> getLineColFromIndex(int cursorIndex, int length, int lineCount,
            Layout layout) {
        int line;
        int currentIndex = 0, oldIndex = 0;

        line = 0;
        while (line < lineCount) {
            oldIndex = currentIndex;
            currentIndex += layout.getLineEnd(line) - layout.getLineStart(line);
            if (currentIndex > cursorIndex) {
                break;
            }
            if (line < lineCount - 1) {
                line++;
            } else {
                break;
            }
        }
        Pair<Integer, Integer> result = new Pair<>(line, cursorIndex - oldIndex);
        DLog.d(TAG, "getLineColFromIndex() returned: " + result);
        return result;

    }

    public static int getStartIndexAtLine(EditText editable, int line) {
        Layout layout = editable.getLayout();
        if (layout != null) {
            return layout.getLineStart(line);
        }
        return 0;
    }

    public boolean[] getGoodLines() {
        return toCountLinesArray;
    }

    public int[] getRealLines() {
        return realLines;
    }

    public void updateHasNewLineArray(int lineCount, Layout layout, String text) {
        boolean[] hasNewLineArray = new boolean[lineCount];
        toCountLinesArray = new boolean[lineCount];
        realLines = new int[lineCount];
        if (TextUtils.isEmpty(text)) {
            toCountLinesArray[0] = false;
            realLines[0] = 0;
            return;
        }

        if (lineCount == 0)
            return;

        int i;

        // for every lineInfo on the edittext
        for (i = 0; i < lineCount; i++) {
            // check if this lineInfo contains "\n"
            if (layout.getLineEnd(i) == 0) {
                hasNewLineArray[i] = false;
            } else {
                hasNewLineArray[i] = text.charAt(layout.getLineEnd(i) - 1) == '\n';
            }
            // if true
            if (hasNewLineArray[i]) {
                int j = i - 1;
                while (j >= 0 && !hasNewLineArray[j]) {
                    j--;
                }
                toCountLinesArray[j + 1] = true;

            }
        }

        toCountLinesArray[lineCount - 1] = true;

        int realLine = 0;
        for (i = 0; i < toCountLinesArray.length; i++) {
            realLines[i] = realLine;
            if (toCountLinesArray[i]) {
                realLine++;
            }
        }
    }

    public int firstReadLine() {
        return realLines[0];
    }

    public int lastReadLine() {
        return realLines[realLines.length - 1];
    }

    public int fakeLineFromRealLine(int realLine) {
        int i;
        int fakeLine = 0;
        for (i = 0; i < realLines.length; i++) {
            if (realLine == realLines[i]) {
                fakeLine = i;
                break;
            }
        }
        return fakeLine;
    }
}