diff --git a/app/src/main/java/com/termux/app/terminal/TermuxTerminalSessionClient.java b/app/src/main/java/com/termux/app/terminal/TermuxTerminalSessionClient.java index 070872d7d0..2959f6fd89 100644 --- a/app/src/main/java/com/termux/app/terminal/TermuxTerminalSessionClient.java +++ b/app/src/main/java/com/termux/app/terminal/TermuxTerminalSessionClient.java @@ -495,6 +495,7 @@ public void checkForFontAndColors() { try { File colorsFile = TermuxConstants.TERMUX_COLOR_PROPERTIES_FILE; File fontFile = TermuxConstants.TERMUX_FONT_FILE; + File italicFontFile = TermuxConstants.TERMUX_ITALIC_FONT_FILE; final Properties props = new Properties(); if (colorsFile.isFile()) { @@ -511,7 +512,9 @@ public void checkForFontAndColors() { updateBackgroundColor(); final Typeface newTypeface = (fontFile.exists() && fontFile.length() > 0) ? Typeface.createFromFile(fontFile) : Typeface.MONOSPACE; - mActivity.getTerminalView().setTypeface(newTypeface); + final Typeface newItalicTypeface = (italicFontFile.exists() && italicFontFile.length() > 0) ? Typeface.createFromFile(italicFontFile) : newTypeface; + + mActivity.getTerminalView().setTypeface(newTypeface, newItalicTypeface); } catch (Exception e) { Logger.logStackTraceWithMessage(LOG_TAG, "Error in checkForFontAndColors()", e); } diff --git a/terminal-view/src/main/java/com/termux/view/TerminalRenderer.java b/terminal-view/src/main/java/com/termux/view/TerminalRenderer.java index 307e422694..01d37a560d 100644 --- a/terminal-view/src/main/java/com/termux/view/TerminalRenderer.java +++ b/terminal-view/src/main/java/com/termux/view/TerminalRenderer.java @@ -20,6 +20,7 @@ public final class TerminalRenderer { final int mTextSize; final Typeface mTypeface; + final Typeface mItalicTypeface; private final Paint mTextPaint = new Paint(); /** The width of a single mono spaced character obtained by {@link Paint#measureText(String)} on a single 'X'. */ @@ -33,9 +34,19 @@ public final class TerminalRenderer { private final float[] asciiMeasures = new float[127]; - public TerminalRenderer(int textSize, Typeface typeface) { + /** The width of a single mono spaced character obtained by {@link Paint#measureText(String)} on a single 'X'. */ + final float mItalicFontWidth; + /** The {@link Paint#getFontSpacing()}. See http://www.fampennings.nl/maarten/android/08numgrid/font.png */ + final int mItalicFontLineSpacing; + /** The {@link Paint#ascent()}. See http://www.fampennings.nl/maarten/android/08numgrid/font.png */ + private final int mItalicFontAscent; + /** The {@link #mFontLineSpacing} + {@link #mFontAscent}. */ + final int mItalicFontLineSpacingAndAscent; + + public TerminalRenderer(int textSize, Typeface typeface, Typeface italicTypeface) { mTextSize = textSize; mTypeface = typeface; + mItalicTypeface = italicTypeface; mTextPaint.setTypeface(typeface); mTextPaint.setAntiAlias(true); @@ -51,6 +62,15 @@ public TerminalRenderer(int textSize, Typeface typeface) { sb.setCharAt(0, (char) i); asciiMeasures[i] = mTextPaint.measureText(sb, 0, 1); } + + mTextPaint.setTypeface(italicTypeface); + mTextPaint.setAntiAlias(true); + mTextPaint.setTextSize(textSize); + + mItalicFontLineSpacing = (int) Math.ceil(mTextPaint.getFontSpacing()); + mItalicFontAscent = (int) Math.ceil(mTextPaint.ascent()); + mItalicFontLineSpacingAndAscent = mItalicFontLineSpacing + mItalicFontAscent; + mItalicFontWidth = mTextPaint.measureText("X"); } /** Render the terminal to a canvas with at a specified row scroll, and an optional rectangular selection. */ @@ -168,6 +188,11 @@ private void drawTextRun(Canvas canvas, char[] text, int[] palette, float y, int final boolean strikeThrough = (effect & TextStyle.CHARACTER_ATTRIBUTE_STRIKETHROUGH) != 0; final boolean dim = (effect & TextStyle.CHARACTER_ATTRIBUTE_DIM) != 0; + final float fontWidth = italic ? mItalicFontWidth : mFontWidth; + final int fontLineSpacing = italic ? mItalicFontLineSpacing : mFontLineSpacing; + final int fontAscent = italic ? mItalicFontAscent : mFontAscent; + final int fontLineSpacingAndAscent = italic ? mItalicFontLineSpacingAndAscent : mFontLineSpacingAndAscent; + if ((foreColor & 0xff000000) != 0xff000000) { // Let bold have bright colors if applicable (one of the first 8): if (bold && foreColor >= 0 && foreColor < 8) foreColor += 8; @@ -186,10 +211,10 @@ private void drawTextRun(Canvas canvas, char[] text, int[] palette, float y, int backColor = tmp; } - float left = startColumn * mFontWidth; - float right = left + runWidthColumns * mFontWidth; + float left = startColumn * fontWidth; + float right = left + runWidthColumns * fontWidth; - mes = mes / mFontWidth; + mes = mes / fontWidth; boolean savedMatrix = false; if (Math.abs(mes - runWidthColumns) > 0.01) { canvas.save(); @@ -202,12 +227,14 @@ private void drawTextRun(Canvas canvas, char[] text, int[] palette, float y, int if (backColor != palette[TextStyle.COLOR_INDEX_BACKGROUND]) { // Only draw non-default background. mTextPaint.setColor(backColor); - canvas.drawRect(left, y - mFontLineSpacingAndAscent + mFontAscent, right, y, mTextPaint); + canvas.drawRect(left, y - fontLineSpacingAndAscent + fontAscent, right, y, mTextPaint); } if (cursor != 0) { mTextPaint.setColor(cursor); - float cursorHeight = mFontLineSpacingAndAscent - mFontAscent; + // fontLineSpacingAndAscent - fontAscent isn't equals to + // fontLineSpacing? + float cursorHeight = fontLineSpacing; if (cursorStyle == TerminalEmulator.TERMINAL_CURSOR_STYLE_UNDERLINE) cursorHeight /= 4.; else if (cursorStyle == TerminalEmulator.TERMINAL_CURSOR_STYLE_BAR) right -= ((right - left) * 3) / 4.; canvas.drawRect(left, y - cursorHeight, right, y, mTextPaint); @@ -226,14 +253,22 @@ private void drawTextRun(Canvas canvas, char[] text, int[] palette, float y, int foreColor = 0xFF000000 + (red << 16) + (green << 8) + blue; } + mTextPaint.setTypeface(mTypeface); + if (italic) + mTextPaint.setTypeface(mItalicTypeface); + mTextPaint.setFakeBoldText(bold); mTextPaint.setUnderlineText(underline); - mTextPaint.setTextSkewX(italic ? -0.35f : 0.f); + + mTextPaint.setTextSkewX(0.f); + if (italic && mItalicTypeface.equals(mTypeface)) + mTextPaint.setTextSkewX(-0.35f); + mTextPaint.setStrikeThruText(strikeThrough); mTextPaint.setColor(foreColor); // The text alignment is the default Paint.Align.LEFT. - canvas.drawText(text, startCharIndex, runWidthChars, left, y - mFontLineSpacingAndAscent, mTextPaint); + canvas.drawText(text, startCharIndex, runWidthChars, left, y - fontLineSpacingAndAscent, mTextPaint); } if (savedMatrix) canvas.restore(); diff --git a/terminal-view/src/main/java/com/termux/view/TerminalView.java b/terminal-view/src/main/java/com/termux/view/TerminalView.java index 2bed7cabd4..76fde78d9f 100644 --- a/terminal-view/src/main/java/com/termux/view/TerminalView.java +++ b/terminal-view/src/main/java/com/termux/view/TerminalView.java @@ -452,12 +452,12 @@ public void onScreenUpdated() { * @param textSize the new font size, in density-independent pixels. */ public void setTextSize(int textSize) { - mRenderer = new TerminalRenderer(textSize, mRenderer == null ? Typeface.MONOSPACE : mRenderer.mTypeface); + mRenderer = new TerminalRenderer(textSize, mRenderer == null ? Typeface.MONOSPACE : mRenderer.mTypeface, mRenderer == null ? Typeface.MONOSPACE : mRenderer.mItalicTypeface); updateSize(); } - public void setTypeface(Typeface newTypeface) { - mRenderer = new TerminalRenderer(mRenderer.mTextSize, newTypeface); + public void setTypeface(Typeface newTypeface, Typeface newItalicTypeface) { + mRenderer = new TerminalRenderer(mRenderer.mTextSize, newTypeface, newItalicTypeface); updateSize(); invalidate(); } diff --git a/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java b/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java index 75c91b6c18..6b68ebbb21 100644 --- a/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java +++ b/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java @@ -762,6 +762,11 @@ public final class TermuxConstants { /** Termux app and Termux:Styling font.ttf file */ public static final File TERMUX_FONT_FILE = new File(TERMUX_FONT_FILE_PATH); + /** Termux app only font-italic.ttf file path */ + public static final String TERMUX_ITALIC_FONT_FILE_PATH = TERMUX_DATA_HOME_DIR_PATH + "/font-italic.ttf"; // Default: "/data/data/com.termux/files/home/.termux/font-italic.ttf" + /** Termux app only font-italic.ttf file */ + public static final File TERMUX_ITALIC_FONT_FILE = new File(TERMUX_ITALIC_FONT_FILE_PATH); + /** Termux app and plugins crash log file path */ public static final String TERMUX_CRASH_LOG_FILE_PATH = TERMUX_HOME_DIR_PATH + "/crash_log.md"; // Default: "/data/data/com.termux/files/home/crash_log.md"