Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add true italic font support #4141

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand All @@ -511,7 +512,8 @@ 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().setTypefaces(newTypeface, newItalicTypeface);
} catch (Exception e) {
Logger.logStackTraceWithMessage(LOG_TAG, "Error in checkForFontAndColors()", e);
}
Expand Down
55 changes: 46 additions & 9 deletions terminal-view/src/main/java/com/termux/view/TerminalRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -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'. */
Expand All @@ -31,15 +32,33 @@ public final class TerminalRenderer {
/** The {@link #mFontLineSpacing} + {@link #mFontAscent}. */
final int mFontLineSpacingAndAscent;


/** The width of a single mono spaced italic 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;

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.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");

mTextPaint.setTypeface(typeface);
typeface.getStyle();

mFontLineSpacing = (int) Math.ceil(mTextPaint.getFontSpacing());
mFontAscent = (int) Math.ceil(mTextPaint.ascent());
Expand Down Expand Up @@ -168,6 +187,24 @@ 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;
final int fontAscent;
final int fontLineSpacingAndAscent;

if (italic) {
fontWidth = mItalicFontWidth;
fontAscent = mItalicFontAscent;
fontLineSpacingAndAscent = mItalicFontLineSpacingAndAscent;

mTextPaint.setTypeface(mItalicTypeface);
} else {
fontWidth = mFontWidth;
fontAscent = mFontAscent;
fontLineSpacingAndAscent = mFontLineSpacingAndAscent;

mTextPaint.setTypeface(mTypeface);
}

if ((foreColor & 0xff000000) != 0xff000000) {
// Let bold have bright colors if applicable (one of the first 8):
if (bold && foreColor >= 0 && foreColor < 8) foreColor += 8;
Expand All @@ -186,10 +223,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();
Expand All @@ -202,12 +239,12 @@ 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;
float cursorHeight = fontLineSpacingAndAscent - fontAscent;
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);
Expand All @@ -228,12 +265,12 @@ private void drawTextRun(Canvas canvas, char[] text, int[] palette, float y, int

mTextPaint.setFakeBoldText(bold);
mTextPaint.setUnderlineText(underline);
mTextPaint.setTextSkewX(italic ? -0.35f : 0.f);
mTextPaint.setTextSkewX(italic && mItalicTypeface == mTypeface ? -0.35f : 0.f);
mTextPaint.setStrikeThruText(strikeThrough);
mTextPaint.setColor(foreColor);

// The text alignment is the default Paint.Align.LEFT.
canvas.drawTextRun(text, startCharIndex, runWidthChars, startCharIndex, runWidthChars, left, y - mFontLineSpacingAndAscent, false, mTextPaint);
canvas.drawTextRun(text, startCharIndex, runWidthChars, startCharIndex, runWidthChars, left, y - fontLineSpacingAndAscent, false, mTextPaint);
}

if (savedMatrix) canvas.restore();
Expand Down
6 changes: 3 additions & 3 deletions terminal-view/src/main/java/com/termux/view/TerminalView.java
Original file line number Diff line number Diff line change
Expand Up @@ -512,12 +512,12 @@ public void onContextMenuClosed(Menu menu) {
* @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 setTypefaces(Typeface newTypeface, Typeface newItalicTypeFace) {
mRenderer = new TerminalRenderer(mRenderer.mTextSize, newTypeface, newItalicTypeFace);
updateSize();
invalidate();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,10 @@ 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 and Termux:Styling font-italic.ttf file path */
public static final String TERMUX_ITALIC_FONT_FILE_PATH = TERMUX_DATA_HOME_DIR_PATH + "/font-italic.ttf";
/** Termux app and Termux:Styling 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"
Expand Down