mirror of
https://github.com/fankes/termux-app.git
synced 2025-09-06 18:55:31 +08:00
Reformat code project-wide (getting rid of tabs)
This commit is contained in:
@@ -4,229 +4,229 @@ import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A row in a terminal, composed of a fixed number of cells.
|
||||
*
|
||||
* <p/>
|
||||
* The text in the row is stored in a char[] array, {@link #mText}, for quick access during rendering.
|
||||
*/
|
||||
public final class TerminalRow {
|
||||
|
||||
private static final float SPARE_CAPACITY_FACTOR = 1.5f;
|
||||
private static final float SPARE_CAPACITY_FACTOR = 1.5f;
|
||||
|
||||
/** The number of columns in this terminal row. */
|
||||
private final int mColumns;
|
||||
/** The text filling this terminal row. */
|
||||
public char[] mText;
|
||||
/** The number of java char:s used in {@link #mText}. */
|
||||
private short mSpaceUsed;
|
||||
/** If this row has been line wrapped due to text output at the end of line. */
|
||||
boolean mLineWrap;
|
||||
/** The style bits of each cell in the row. See {@link TextStyle}. */
|
||||
final int[] mStyle;
|
||||
/** The number of columns in this terminal row. */
|
||||
private final int mColumns;
|
||||
/** The text filling this terminal row. */
|
||||
public char[] mText;
|
||||
/** The number of java char:s used in {@link #mText}. */
|
||||
private short mSpaceUsed;
|
||||
/** If this row has been line wrapped due to text output at the end of line. */
|
||||
boolean mLineWrap;
|
||||
/** The style bits of each cell in the row. See {@link TextStyle}. */
|
||||
final int[] mStyle;
|
||||
|
||||
/** Construct a blank row (containing only whitespace, ' ') with a specified style. */
|
||||
public TerminalRow(int columns, int style) {
|
||||
mColumns = columns;
|
||||
mText = new char[(int) (SPARE_CAPACITY_FACTOR * columns)];
|
||||
mStyle = new int[columns];
|
||||
clear(style);
|
||||
}
|
||||
/** Construct a blank row (containing only whitespace, ' ') with a specified style. */
|
||||
public TerminalRow(int columns, int style) {
|
||||
mColumns = columns;
|
||||
mText = new char[(int) (SPARE_CAPACITY_FACTOR * columns)];
|
||||
mStyle = new int[columns];
|
||||
clear(style);
|
||||
}
|
||||
|
||||
/** NOTE: The sourceX2 is exclusive. */
|
||||
public void copyInterval(TerminalRow line, int sourceX1, int sourceX2, int destinationX) {
|
||||
final int x1 = line.findStartOfColumn(sourceX1);
|
||||
final int x2 = line.findStartOfColumn(sourceX2);
|
||||
boolean startingFromSecondHalfOfWideChar = (sourceX1 > 0 && line.wideDisplayCharacterStartingAt(sourceX1 - 1));
|
||||
final char[] sourceChars = (this == line) ? Arrays.copyOf(line.mText, line.mText.length) : line.mText;
|
||||
int latestNonCombiningWidth = 0;
|
||||
for (int i = x1; i < x2; i++) {
|
||||
char sourceChar = sourceChars[i];
|
||||
int codePoint = Character.isHighSurrogate(sourceChar) ? Character.toCodePoint(sourceChar, sourceChars[++i]) : sourceChar;
|
||||
if (startingFromSecondHalfOfWideChar) {
|
||||
// Just treat copying second half of wide char as copying whitespace.
|
||||
codePoint = ' ';
|
||||
startingFromSecondHalfOfWideChar = false;
|
||||
}
|
||||
int w = WcWidth.width(codePoint);
|
||||
if (w > 0) {
|
||||
destinationX += latestNonCombiningWidth;
|
||||
sourceX1 += latestNonCombiningWidth;
|
||||
latestNonCombiningWidth = w;
|
||||
}
|
||||
setChar(destinationX, codePoint, line.getStyle(sourceX1));
|
||||
}
|
||||
}
|
||||
/** NOTE: The sourceX2 is exclusive. */
|
||||
public void copyInterval(TerminalRow line, int sourceX1, int sourceX2, int destinationX) {
|
||||
final int x1 = line.findStartOfColumn(sourceX1);
|
||||
final int x2 = line.findStartOfColumn(sourceX2);
|
||||
boolean startingFromSecondHalfOfWideChar = (sourceX1 > 0 && line.wideDisplayCharacterStartingAt(sourceX1 - 1));
|
||||
final char[] sourceChars = (this == line) ? Arrays.copyOf(line.mText, line.mText.length) : line.mText;
|
||||
int latestNonCombiningWidth = 0;
|
||||
for (int i = x1; i < x2; i++) {
|
||||
char sourceChar = sourceChars[i];
|
||||
int codePoint = Character.isHighSurrogate(sourceChar) ? Character.toCodePoint(sourceChar, sourceChars[++i]) : sourceChar;
|
||||
if (startingFromSecondHalfOfWideChar) {
|
||||
// Just treat copying second half of wide char as copying whitespace.
|
||||
codePoint = ' ';
|
||||
startingFromSecondHalfOfWideChar = false;
|
||||
}
|
||||
int w = WcWidth.width(codePoint);
|
||||
if (w > 0) {
|
||||
destinationX += latestNonCombiningWidth;
|
||||
sourceX1 += latestNonCombiningWidth;
|
||||
latestNonCombiningWidth = w;
|
||||
}
|
||||
setChar(destinationX, codePoint, line.getStyle(sourceX1));
|
||||
}
|
||||
}
|
||||
|
||||
public int getSpaceUsed() {
|
||||
return mSpaceUsed;
|
||||
}
|
||||
public int getSpaceUsed() {
|
||||
return mSpaceUsed;
|
||||
}
|
||||
|
||||
/** Note that the column may end of second half of wide character. */
|
||||
public int findStartOfColumn(int column) {
|
||||
if (column == mColumns) return getSpaceUsed();
|
||||
/** Note that the column may end of second half of wide character. */
|
||||
public int findStartOfColumn(int column) {
|
||||
if (column == mColumns) return getSpaceUsed();
|
||||
|
||||
int currentColumn = 0;
|
||||
int currentCharIndex = 0;
|
||||
while (true) { // 0<2 1 < 2
|
||||
int newCharIndex = currentCharIndex;
|
||||
char c = mText[newCharIndex++]; // cci=1, cci=2
|
||||
boolean isHigh = Character.isHighSurrogate(c);
|
||||
int codePoint = isHigh ? Character.toCodePoint(c, mText[newCharIndex++]) : c;
|
||||
int wcwidth = WcWidth.width(codePoint); // 1, 2
|
||||
if (wcwidth > 0) {
|
||||
currentColumn += wcwidth;
|
||||
if (currentColumn == column) {
|
||||
while (newCharIndex < mSpaceUsed) {
|
||||
// Skip combining chars.
|
||||
if (Character.isHighSurrogate(mText[newCharIndex])) {
|
||||
if (WcWidth.width(Character.toCodePoint(mText[newCharIndex], mText[newCharIndex + 1])) <= 0) {
|
||||
newCharIndex += 2;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (WcWidth.width(mText[newCharIndex]) <= 0) {
|
||||
newCharIndex++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return newCharIndex;
|
||||
} else if (currentColumn > column) {
|
||||
// Wide column going past end.
|
||||
return currentCharIndex;
|
||||
}
|
||||
}
|
||||
currentCharIndex = newCharIndex;
|
||||
}
|
||||
}
|
||||
int currentColumn = 0;
|
||||
int currentCharIndex = 0;
|
||||
while (true) { // 0<2 1 < 2
|
||||
int newCharIndex = currentCharIndex;
|
||||
char c = mText[newCharIndex++]; // cci=1, cci=2
|
||||
boolean isHigh = Character.isHighSurrogate(c);
|
||||
int codePoint = isHigh ? Character.toCodePoint(c, mText[newCharIndex++]) : c;
|
||||
int wcwidth = WcWidth.width(codePoint); // 1, 2
|
||||
if (wcwidth > 0) {
|
||||
currentColumn += wcwidth;
|
||||
if (currentColumn == column) {
|
||||
while (newCharIndex < mSpaceUsed) {
|
||||
// Skip combining chars.
|
||||
if (Character.isHighSurrogate(mText[newCharIndex])) {
|
||||
if (WcWidth.width(Character.toCodePoint(mText[newCharIndex], mText[newCharIndex + 1])) <= 0) {
|
||||
newCharIndex += 2;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (WcWidth.width(mText[newCharIndex]) <= 0) {
|
||||
newCharIndex++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return newCharIndex;
|
||||
} else if (currentColumn > column) {
|
||||
// Wide column going past end.
|
||||
return currentCharIndex;
|
||||
}
|
||||
}
|
||||
currentCharIndex = newCharIndex;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean wideDisplayCharacterStartingAt(int column) {
|
||||
for (int currentCharIndex = 0, currentColumn = 0; currentCharIndex < mSpaceUsed;) {
|
||||
char c = mText[currentCharIndex++];
|
||||
int codePoint = Character.isHighSurrogate(c) ? Character.toCodePoint(c, mText[currentCharIndex++]) : c;
|
||||
int wcwidth = WcWidth.width(codePoint);
|
||||
if (wcwidth > 0) {
|
||||
if (currentColumn == column && wcwidth == 2) return true;
|
||||
currentColumn += wcwidth;
|
||||
if (currentColumn > column) return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private boolean wideDisplayCharacterStartingAt(int column) {
|
||||
for (int currentCharIndex = 0, currentColumn = 0; currentCharIndex < mSpaceUsed; ) {
|
||||
char c = mText[currentCharIndex++];
|
||||
int codePoint = Character.isHighSurrogate(c) ? Character.toCodePoint(c, mText[currentCharIndex++]) : c;
|
||||
int wcwidth = WcWidth.width(codePoint);
|
||||
if (wcwidth > 0) {
|
||||
if (currentColumn == column && wcwidth == 2) return true;
|
||||
currentColumn += wcwidth;
|
||||
if (currentColumn > column) return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void clear(int style) {
|
||||
Arrays.fill(mText, ' ');
|
||||
Arrays.fill(mStyle, style);
|
||||
mSpaceUsed = (short) mColumns;
|
||||
}
|
||||
public void clear(int style) {
|
||||
Arrays.fill(mText, ' ');
|
||||
Arrays.fill(mStyle, style);
|
||||
mSpaceUsed = (short) mColumns;
|
||||
}
|
||||
|
||||
// https://github.com/steven676/Android-Terminal-Emulator/commit/9a47042620bec87617f0b4f5d50568535668fe26
|
||||
public void setChar(int columnToSet, int codePoint, int style) {
|
||||
mStyle[columnToSet] = style;
|
||||
// https://github.com/steven676/Android-Terminal-Emulator/commit/9a47042620bec87617f0b4f5d50568535668fe26
|
||||
public void setChar(int columnToSet, int codePoint, int style) {
|
||||
mStyle[columnToSet] = style;
|
||||
|
||||
final int newCodePointDisplayWidth = WcWidth.width(codePoint);
|
||||
final boolean newIsCombining = newCodePointDisplayWidth <= 0;
|
||||
final int newCodePointDisplayWidth = WcWidth.width(codePoint);
|
||||
final boolean newIsCombining = newCodePointDisplayWidth <= 0;
|
||||
|
||||
boolean wasExtraColForWideChar = (columnToSet > 0) && wideDisplayCharacterStartingAt(columnToSet - 1);
|
||||
boolean wasExtraColForWideChar = (columnToSet > 0) && wideDisplayCharacterStartingAt(columnToSet - 1);
|
||||
|
||||
if (newIsCombining) {
|
||||
// When standing at second half of wide character and inserting combining:
|
||||
if (wasExtraColForWideChar) columnToSet--;
|
||||
} else {
|
||||
// Check if we are overwriting the second half of a wide character starting at the previous column:
|
||||
if (wasExtraColForWideChar) setChar(columnToSet - 1, ' ', style);
|
||||
// Check if we are overwriting the first half of a wide character starting at the next column:
|
||||
boolean overwritingWideCharInNextColumn = newCodePointDisplayWidth == 2 && wideDisplayCharacterStartingAt(columnToSet + 1);
|
||||
if (overwritingWideCharInNextColumn) setChar(columnToSet + 1, ' ', style);
|
||||
}
|
||||
if (newIsCombining) {
|
||||
// When standing at second half of wide character and inserting combining:
|
||||
if (wasExtraColForWideChar) columnToSet--;
|
||||
} else {
|
||||
// Check if we are overwriting the second half of a wide character starting at the previous column:
|
||||
if (wasExtraColForWideChar) setChar(columnToSet - 1, ' ', style);
|
||||
// Check if we are overwriting the first half of a wide character starting at the next column:
|
||||
boolean overwritingWideCharInNextColumn = newCodePointDisplayWidth == 2 && wideDisplayCharacterStartingAt(columnToSet + 1);
|
||||
if (overwritingWideCharInNextColumn) setChar(columnToSet + 1, ' ', style);
|
||||
}
|
||||
|
||||
char[] text = mText;
|
||||
final int oldStartOfColumnIndex = findStartOfColumn(columnToSet);
|
||||
final int oldCodePointDisplayWidth = WcWidth.width(text, oldStartOfColumnIndex);
|
||||
char[] text = mText;
|
||||
final int oldStartOfColumnIndex = findStartOfColumn(columnToSet);
|
||||
final int oldCodePointDisplayWidth = WcWidth.width(text, oldStartOfColumnIndex);
|
||||
|
||||
// Get the number of elements in the mText array this column uses now
|
||||
int oldCharactersUsedForColumn;
|
||||
if (columnToSet + oldCodePointDisplayWidth < mColumns) {
|
||||
oldCharactersUsedForColumn = findStartOfColumn(columnToSet + oldCodePointDisplayWidth) - oldStartOfColumnIndex;
|
||||
} else {
|
||||
// Last character.
|
||||
oldCharactersUsedForColumn = mSpaceUsed - oldStartOfColumnIndex;
|
||||
}
|
||||
// Get the number of elements in the mText array this column uses now
|
||||
int oldCharactersUsedForColumn;
|
||||
if (columnToSet + oldCodePointDisplayWidth < mColumns) {
|
||||
oldCharactersUsedForColumn = findStartOfColumn(columnToSet + oldCodePointDisplayWidth) - oldStartOfColumnIndex;
|
||||
} else {
|
||||
// Last character.
|
||||
oldCharactersUsedForColumn = mSpaceUsed - oldStartOfColumnIndex;
|
||||
}
|
||||
|
||||
// Find how many chars this column will need
|
||||
int newCharactersUsedForColumn = Character.charCount(codePoint);
|
||||
if (newIsCombining) {
|
||||
// Combining characters are added to the contents of the column instead of overwriting them, so that they
|
||||
// modify the existing contents.
|
||||
// FIXME: Put a limit of combining characters.
|
||||
// FIXME: Unassigned characters also get width=0.
|
||||
newCharactersUsedForColumn += oldCharactersUsedForColumn;
|
||||
}
|
||||
// Find how many chars this column will need
|
||||
int newCharactersUsedForColumn = Character.charCount(codePoint);
|
||||
if (newIsCombining) {
|
||||
// Combining characters are added to the contents of the column instead of overwriting them, so that they
|
||||
// modify the existing contents.
|
||||
// FIXME: Put a limit of combining characters.
|
||||
// FIXME: Unassigned characters also get width=0.
|
||||
newCharactersUsedForColumn += oldCharactersUsedForColumn;
|
||||
}
|
||||
|
||||
int oldNextColumnIndex = oldStartOfColumnIndex + oldCharactersUsedForColumn;
|
||||
int newNextColumnIndex = oldStartOfColumnIndex + newCharactersUsedForColumn;
|
||||
int oldNextColumnIndex = oldStartOfColumnIndex + oldCharactersUsedForColumn;
|
||||
int newNextColumnIndex = oldStartOfColumnIndex + newCharactersUsedForColumn;
|
||||
|
||||
final int javaCharDifference = newCharactersUsedForColumn - oldCharactersUsedForColumn;
|
||||
if (javaCharDifference > 0) {
|
||||
// Shift the rest of the line right.
|
||||
int oldCharactersAfterColumn = mSpaceUsed - oldNextColumnIndex;
|
||||
if (mSpaceUsed + javaCharDifference > text.length) {
|
||||
// We need to grow the array
|
||||
char[] newText = new char[text.length + mColumns];
|
||||
System.arraycopy(text, 0, newText, 0, oldStartOfColumnIndex + oldCharactersUsedForColumn);
|
||||
System.arraycopy(text, oldNextColumnIndex, newText, newNextColumnIndex, oldCharactersAfterColumn);
|
||||
mText = text = newText;
|
||||
} else {
|
||||
System.arraycopy(text, oldNextColumnIndex, text, newNextColumnIndex, oldCharactersAfterColumn);
|
||||
}
|
||||
} else if (javaCharDifference < 0) {
|
||||
// Shift the rest of the line left.
|
||||
System.arraycopy(text, oldNextColumnIndex, text, newNextColumnIndex, mSpaceUsed - oldNextColumnIndex);
|
||||
}
|
||||
mSpaceUsed += javaCharDifference;
|
||||
final int javaCharDifference = newCharactersUsedForColumn - oldCharactersUsedForColumn;
|
||||
if (javaCharDifference > 0) {
|
||||
// Shift the rest of the line right.
|
||||
int oldCharactersAfterColumn = mSpaceUsed - oldNextColumnIndex;
|
||||
if (mSpaceUsed + javaCharDifference > text.length) {
|
||||
// We need to grow the array
|
||||
char[] newText = new char[text.length + mColumns];
|
||||
System.arraycopy(text, 0, newText, 0, oldStartOfColumnIndex + oldCharactersUsedForColumn);
|
||||
System.arraycopy(text, oldNextColumnIndex, newText, newNextColumnIndex, oldCharactersAfterColumn);
|
||||
mText = text = newText;
|
||||
} else {
|
||||
System.arraycopy(text, oldNextColumnIndex, text, newNextColumnIndex, oldCharactersAfterColumn);
|
||||
}
|
||||
} else if (javaCharDifference < 0) {
|
||||
// Shift the rest of the line left.
|
||||
System.arraycopy(text, oldNextColumnIndex, text, newNextColumnIndex, mSpaceUsed - oldNextColumnIndex);
|
||||
}
|
||||
mSpaceUsed += javaCharDifference;
|
||||
|
||||
// Store char. A combining character is stored at the end of the existing contents so that it modifies them:
|
||||
//noinspection ResultOfMethodCallIgnored - since we already now how many java chars is used.
|
||||
Character.toChars(codePoint, text, oldStartOfColumnIndex + (newIsCombining ? oldCharactersUsedForColumn : 0));
|
||||
// Store char. A combining character is stored at the end of the existing contents so that it modifies them:
|
||||
//noinspection ResultOfMethodCallIgnored - since we already now how many java chars is used.
|
||||
Character.toChars(codePoint, text, oldStartOfColumnIndex + (newIsCombining ? oldCharactersUsedForColumn : 0));
|
||||
|
||||
if (oldCodePointDisplayWidth == 2 && newCodePointDisplayWidth == 1) {
|
||||
// Replace second half of wide char with a space. Which mean that we actually add a ' ' java character.
|
||||
if (mSpaceUsed + 1 > text.length) {
|
||||
char[] newText = new char[text.length + mColumns];
|
||||
System.arraycopy(text, 0, newText, 0, newNextColumnIndex);
|
||||
System.arraycopy(text, newNextColumnIndex, newText, newNextColumnIndex + 1, mSpaceUsed - newNextColumnIndex);
|
||||
mText = text = newText;
|
||||
} else {
|
||||
System.arraycopy(text, newNextColumnIndex, text, newNextColumnIndex + 1, mSpaceUsed - newNextColumnIndex);
|
||||
}
|
||||
text[newNextColumnIndex] = ' ';
|
||||
if (oldCodePointDisplayWidth == 2 && newCodePointDisplayWidth == 1) {
|
||||
// Replace second half of wide char with a space. Which mean that we actually add a ' ' java character.
|
||||
if (mSpaceUsed + 1 > text.length) {
|
||||
char[] newText = new char[text.length + mColumns];
|
||||
System.arraycopy(text, 0, newText, 0, newNextColumnIndex);
|
||||
System.arraycopy(text, newNextColumnIndex, newText, newNextColumnIndex + 1, mSpaceUsed - newNextColumnIndex);
|
||||
mText = text = newText;
|
||||
} else {
|
||||
System.arraycopy(text, newNextColumnIndex, text, newNextColumnIndex + 1, mSpaceUsed - newNextColumnIndex);
|
||||
}
|
||||
text[newNextColumnIndex] = ' ';
|
||||
|
||||
++mSpaceUsed;
|
||||
} else if (oldCodePointDisplayWidth == 1 && newCodePointDisplayWidth == 2) {
|
||||
if (columnToSet == mColumns - 1) {
|
||||
throw new IllegalArgumentException("Cannot put wide character in last column");
|
||||
} else if (columnToSet == mColumns - 2) {
|
||||
// Truncate the line to the second part of this wide char:
|
||||
mSpaceUsed = (short) newNextColumnIndex;
|
||||
} else {
|
||||
// Overwrite the contents of the next column, which mean we actually remove java characters. Due to the
|
||||
// check at the beginning of this method we know that we are not overwriting a wide char.
|
||||
int newNextNextColumnIndex = newNextColumnIndex + (Character.isHighSurrogate(mText[newNextColumnIndex]) ? 2 : 1);
|
||||
int nextLen = newNextNextColumnIndex - newNextColumnIndex;
|
||||
++mSpaceUsed;
|
||||
} else if (oldCodePointDisplayWidth == 1 && newCodePointDisplayWidth == 2) {
|
||||
if (columnToSet == mColumns - 1) {
|
||||
throw new IllegalArgumentException("Cannot put wide character in last column");
|
||||
} else if (columnToSet == mColumns - 2) {
|
||||
// Truncate the line to the second part of this wide char:
|
||||
mSpaceUsed = (short) newNextColumnIndex;
|
||||
} else {
|
||||
// Overwrite the contents of the next column, which mean we actually remove java characters. Due to the
|
||||
// check at the beginning of this method we know that we are not overwriting a wide char.
|
||||
int newNextNextColumnIndex = newNextColumnIndex + (Character.isHighSurrogate(mText[newNextColumnIndex]) ? 2 : 1);
|
||||
int nextLen = newNextNextColumnIndex - newNextColumnIndex;
|
||||
|
||||
// Shift the array leftwards.
|
||||
System.arraycopy(text, newNextNextColumnIndex, text, newNextColumnIndex, mSpaceUsed - newNextNextColumnIndex);
|
||||
mSpaceUsed -= nextLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Shift the array leftwards.
|
||||
System.arraycopy(text, newNextNextColumnIndex, text, newNextColumnIndex, mSpaceUsed - newNextNextColumnIndex);
|
||||
mSpaceUsed -= nextLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean isBlank() {
|
||||
for (int charIndex = 0, charLen = getSpaceUsed(); charIndex < charLen; charIndex++)
|
||||
if (mText[charIndex] != ' ') return false;
|
||||
return true;
|
||||
}
|
||||
boolean isBlank() {
|
||||
for (int charIndex = 0, charLen = getSpaceUsed(); charIndex < charLen; charIndex++)
|
||||
if (mText[charIndex] != ' ') return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public final int getStyle(int column) {
|
||||
return mStyle[column];
|
||||
}
|
||||
public final int getStyle(int column) {
|
||||
return mStyle[column];
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user