From 4e1f91d7e1fbf12373fee68ed8855979c6fd27c1 Mon Sep 17 00:00:00 2001 From: Jonatha Gabriel Date: Wed, 8 Jun 2022 03:18:48 -0300 Subject: [PATCH 1/2] Added support to true italics. True italics are enabled if a font-italic.ttf is present in ${HOME}/.termux folder, if this file not exists fallback to default behaviour of italics. --- .../app/terminal/TermuxTerminalSessionClient.java | 5 ++++- .../java/com/termux/view/TerminalRenderer.java | 14 ++++++++++++-- .../main/java/com/termux/view/TerminalView.java | 6 +++--- .../com/termux/shared/termux/TermuxConstants.java | 5 +++++ 4 files changed, 24 insertions(+), 6 deletions(-) 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..9cfa8af26a 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,10 @@ public final class TerminalRenderer { private final float[] asciiMeasures = new float[127]; - public TerminalRenderer(int textSize, Typeface typeface) { + public TerminalRenderer(int textSize, Typeface typeface, Typeface italicTypeface) { mTextSize = textSize; mTypeface = typeface; + mItalicTypeface = italicTypeface; mTextPaint.setTypeface(typeface); mTextPaint.setAntiAlias(true); @@ -226,9 +228,17 @@ 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); 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" From 4ccd3f22a9c18437b3edf98001d84e660d6d15c3 Mon Sep 17 00:00:00 2001 From: Jonatha Gabriel Date: Thu, 9 Jun 2022 00:19:13 -0300 Subject: [PATCH 2/2] Fix little bug when render italic fonts. It's very difficult to notice and explain, but it occurs when the cursor is blinking over an italic text it's "shrunken", this is more visible with slashes. --- .../com/termux/view/TerminalRenderer.java | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) 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 9cfa8af26a..01d37a560d 100644 --- a/terminal-view/src/main/java/com/termux/view/TerminalRenderer.java +++ b/terminal-view/src/main/java/com/termux/view/TerminalRenderer.java @@ -34,6 +34,15 @@ public final class TerminalRenderer { private final float[] asciiMeasures = new float[127]; + /** 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; @@ -53,6 +62,15 @@ public TerminalRenderer(int textSize, Typeface typeface, Typeface italicTypeface 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. */ @@ -170,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; @@ -188,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(); @@ -204,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); @@ -243,7 +268,7 @@ private void drawTextRun(Canvas canvas, char[] text, int[] palette, float y, int 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();