#35 emoji font wip

This commit is contained in:
Kevin Lamonte 2019-08-11 22:14:42 -05:00
parent bfa37f3b2e
commit 218d18dbda
10 changed files with 82 additions and 81 deletions

3
.gitignore vendored
View file

@ -30,3 +30,6 @@ misc/**
pmd.bash
pmd-results.html
examples/*.sh
# Fonts for testing
fonts/**

View file

@ -1501,7 +1501,7 @@ public abstract class TWidget implements Comparable<TWidget> {
* @param ch character to draw
* @param attr attributes to use (bold, foreColor, backColor)
*/
protected final void putAll(final char ch, final CellAttributes attr) {
protected final void putAll(final int ch, final CellAttributes attr) {
getScreen().putAll(ch, attr);
}
@ -1524,7 +1524,7 @@ public abstract class TWidget implements Comparable<TWidget> {
* @param ch character to draw
* @param attr attributes to use (bold, foreColor, backColor)
*/
protected final void putCharXY(final int x, final int y, final char ch,
protected final void putCharXY(final int x, final int y, final int ch,
final CellAttributes attr) {
getScreen().putCharXY(x, y, ch, attr);
@ -1537,7 +1537,7 @@ public abstract class TWidget implements Comparable<TWidget> {
* @param y row coordinate. 0 is the top-most row.
* @param ch character to draw
*/
protected final void putCharXY(final int x, final int y, final char ch) {
protected final void putCharXY(final int x, final int y, final int ch) {
getScreen().putCharXY(x, y, ch);
}
@ -1577,7 +1577,7 @@ public abstract class TWidget implements Comparable<TWidget> {
* @param attr attributes to use (bold, foreColor, backColor)
*/
protected final void vLineXY(final int x, final int y, final int n,
final char ch, final CellAttributes attr) {
final int ch, final CellAttributes attr) {
getScreen().vLineXY(x, y, n, ch, attr);
}
@ -1592,7 +1592,7 @@ public abstract class TWidget implements Comparable<TWidget> {
* @param attr attributes to use (bold, foreColor, backColor)
*/
protected final void hLineXY(final int x, final int y, final int n,
final char ch, final CellAttributes attr) {
final int ch, final CellAttributes attr) {
getScreen().hLineXY(x, y, n, ch, attr);
}

View file

@ -185,6 +185,11 @@ class GlyphMakerFont {
getFontDimensions();
}
if (DEBUG && !font.canDisplay(cell.getChar())) {
System.err.println("font " + font + " has no glyph for " +
String.format("0x%x", cell.getChar()));
}
BufferedImage image = null;
if (cell.isBlink() && !blinkVisible) {
image = glyphCacheBlink.get(cell);
@ -218,9 +223,8 @@ class GlyphMakerFont {
|| (cell.isBlink() && blinkVisible)
) {
gr2.setColor(SwingTerminal.attrToForegroundColor(cellColor));
char [] chars = new char[1];
chars[0] = cell.getChar();
gr2.drawChars(chars, 0, 1, textAdjustX,
char [] chars = Character.toChars(cell.getChar());
gr2.drawChars(chars, 0, chars.length, textAdjustX,
cellHeight - maxDescent + textAdjustY);
if (cell.isUnderline()) {
@ -299,19 +303,14 @@ public class GlyphMaker {
private static final String MONO = "terminus-ttf-4.39/TerminusTTF-Bold-4.39.ttf";
/**
* The CJKhk font resource filename.
* The CJK font resource filename.
*/
// private static final String CJKhk = "NotoSansMonoCJKhk-Regular.otf";
private static final String cjkFontFilename = "NotoSansMonoCJKtc-Regular.otf";
/**
* The CJKkr font resource filename.
* The emoji font resource filename.
*/
// private static final String CJKkr = "NotoSansMonoCJKkr-Regular.otf";
/**
* The CJKtc font resource filename.
*/
private static final String CJKtc = "NotoSansMonoCJKtc-Regular.otf";
private static final String emojiFontFilename = "OpenSansEmoji.ttf";
// ------------------------------------------------------------------------
// Variables --------------------------------------------------------------
@ -333,19 +332,14 @@ public class GlyphMaker {
private GlyphMakerFont makerMono;
/**
* The instance that has the CJKhk font.
* The instance that has the CJK font.
*/
// private GlyphMakerFont makerCJKhk;
private GlyphMakerFont makerCjk;
/**
* The instance that has the CJKkr font.
* The instance that has the emoji font.
*/
// private GlyphMakerFont makerCJKkr;
/**
* The instance that has the CJKtc font.
*/
private GlyphMakerFont makerCJKtc;
private GlyphMakerFont makerEmoji;
// ------------------------------------------------------------------------
// Constructors -----------------------------------------------------------
@ -357,11 +351,15 @@ public class GlyphMaker {
* @param fontSize the size of these fonts in pixels
*/
private GlyphMaker(final int fontSize) {
assert (fontSize > 3);
makerMono = new GlyphMakerFont(MONO, fontSize);
// makerCJKhk = new GlyphMakerFont(CJKhk, fontSize);
// makerCJKkr = new GlyphMakerFont(CJKkr, fontSize);
makerCJKtc = new GlyphMakerFont(CJKtc, fontSize);
String fontFilename = null;
fontFilename = System.getProperty("jexer.cjkFont.filename",
cjkFontFilename);
makerCjk = new GlyphMakerFont(fontFilename, fontSize);
fontFilename = System.getProperty("jexer.emojiFont.filename",
emojiFontFilename);
makerEmoji = new GlyphMakerFont(fontFilename, fontSize);
}
// ------------------------------------------------------------------------
@ -411,17 +409,12 @@ public class GlyphMaker {
public BufferedImage getImage(final Cell cell, final int cellWidth,
final int cellHeight, final boolean blinkVisible) {
char ch = cell.getChar();
/*
if ((ch >= 0x4e00) && (ch <= 0x9fff)) {
return makerCJKhk.getImage(cell, cellWidth, cellHeight, blinkVisible);
}
if ((ch >= 0x4e00) && (ch <= 0x9fff)) {
return makerCJKkr.getImage(cell, cellWidth, cellHeight, blinkVisible);
}
*/
int ch = cell.getChar();
if ((ch >= 0x2e80) && (ch <= 0x9fff)) {
return makerCJKtc.getImage(cell, cellWidth, cellHeight, blinkVisible);
return makerCjk.getImage(cell, cellWidth, cellHeight, blinkVisible);
}
if ((ch >= 0x1f004) && (ch <= 0x1f9c0)) {
return makerEmoji.getImage(cell, cellWidth, cellHeight, blinkVisible);
}
// When all else fails, use the default.

View file

@ -369,7 +369,7 @@ public class LogicalScreen implements Screen {
* @param ch character to draw
* @param attr attributes to use (bold, foreColor, backColor)
*/
public final void putAll(final char ch, final CellAttributes attr) {
public final void putAll(final int ch, final CellAttributes attr) {
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
@ -430,7 +430,7 @@ public class LogicalScreen implements Screen {
* @param ch character to draw
* @param attr attributes to use (bold, foreColor, backColor)
*/
public final void putCharXY(final int x, final int y, final char ch,
public final void putCharXY(final int x, final int y, final int ch,
final CellAttributes attr) {
if ((x < clipLeft)
@ -476,8 +476,7 @@ public class LogicalScreen implements Screen {
* @param y row coordinate. 0 is the top-most row.
* @param ch character to draw
*/
public final void putCharXY(final int x, final int y, final char ch) {
public final void putCharXY(final int x, final int y, final int ch) {
if ((x < clipLeft)
|| (x >= clipRight)
|| (y < clipTop)
@ -520,8 +519,9 @@ public class LogicalScreen implements Screen {
final CellAttributes attr) {
int i = x;
for (int j = 0; j < str.length(); j++) {
char ch = str.charAt(j);
for (int j = 0; j < str.length();) {
int ch = str.codePointAt(j);
j += Character.charCount(ch);
putCharXY(i, y, ch, attr);
i += StringUtils.width(ch);
if (i == width) {
@ -541,8 +541,9 @@ public class LogicalScreen implements Screen {
public final void putStringXY(final int x, final int y, final String str) {
int i = x;
for (int j = 0; j < str.length(); j++) {
char ch = str.charAt(j);
for (int j = 0; j < str.length();) {
int ch = str.codePointAt(j);
j += Character.charCount(ch);
putCharXY(i, y, ch);
i += StringUtils.width(ch);
if (i == width) {
@ -561,7 +562,7 @@ public class LogicalScreen implements Screen {
* @param attr attributes to use (bold, foreColor, backColor)
*/
public final void vLineXY(final int x, final int y, final int n,
final char ch, final CellAttributes attr) {
final int ch, final CellAttributes attr) {
for (int i = y; i < y + n; i++) {
putCharXY(x, i, ch, attr);
@ -578,7 +579,7 @@ public class LogicalScreen implements Screen {
* @param attr attributes to use (bold, foreColor, backColor)
*/
public final void hLineXY(final int x, final int y, final int n,
final char ch, final CellAttributes attr) {
final int ch, final CellAttributes attr) {
for (int i = x; i < x + n; i++) {
putCharXY(i, y, ch, attr);
@ -1005,7 +1006,7 @@ public class LogicalScreen implements Screen {
* @param attr attributes to use (bold, foreColor, backColor)
*/
public final void putFullwidthCharXY(final int x, final int y,
final char ch, final CellAttributes attr) {
final int ch, final CellAttributes attr) {
Cell cell = new Cell(ch, attr);
putFullwidthCharXY(x, y, cell);
@ -1019,7 +1020,7 @@ public class LogicalScreen implements Screen {
* @param ch character to draw
*/
public final void putFullwidthCharXY(final int x, final int y,
final char ch) {
final int ch) {
Cell cell = new Cell(ch);
cell.setAttr(getAttrXY(x, y));

View file

@ -241,7 +241,7 @@ public class MultiScreen implements Screen {
* @param ch character to draw
* @param attr attributes to use (bold, foreColor, backColor)
*/
public void putAll(final char ch, final CellAttributes attr) {
public void putAll(final int ch, final CellAttributes attr) {
for (Screen screen: screens) {
screen.putAll(ch, attr);
}
@ -268,7 +268,7 @@ public class MultiScreen implements Screen {
* @param ch character to draw
* @param attr attributes to use (bold, foreColor, backColor)
*/
public void putCharXY(final int x, final int y, final char ch,
public void putCharXY(final int x, final int y, final int ch,
final CellAttributes attr) {
for (Screen screen: screens) {
@ -283,7 +283,7 @@ public class MultiScreen implements Screen {
* @param y row coordinate. 0 is the top-most row.
* @param ch character to draw
*/
public void putCharXY(final int x, final int y, final char ch) {
public void putCharXY(final int x, final int y, final int ch) {
for (Screen screen: screens) {
screen.putCharXY(x, y, ch);
}
@ -329,7 +329,7 @@ public class MultiScreen implements Screen {
* @param attr attributes to use (bold, foreColor, backColor)
*/
public void vLineXY(final int x, final int y, final int n,
final char ch, final CellAttributes attr) {
final int ch, final CellAttributes attr) {
for (Screen screen: screens) {
screen.vLineXY(x, y, n, ch, attr);
@ -346,7 +346,7 @@ public class MultiScreen implements Screen {
* @param attr attributes to use (bold, foreColor, backColor)
*/
public void hLineXY(final int x, final int y, final int n,
final char ch, final CellAttributes attr) {
final int ch, final CellAttributes attr) {
for (Screen screen: screens) {
screen.hLineXY(x, y, n, ch, attr);

View file

@ -159,7 +159,7 @@ public interface Screen {
* @param ch character to draw
* @param attr attributes to use (bold, foreColor, backColor)
*/
public void putAll(final char ch, final CellAttributes attr);
public void putAll(final int ch, final CellAttributes attr);
/**
* Render one character with attributes.
@ -178,7 +178,7 @@ public interface Screen {
* @param ch character to draw
* @param attr attributes to use (bold, foreColor, backColor)
*/
public void putCharXY(final int x, final int y, final char ch,
public void putCharXY(final int x, final int y, final int ch,
final CellAttributes attr);
/**
@ -188,7 +188,7 @@ public interface Screen {
* @param y row coordinate. 0 is the top-most row.
* @param ch character to draw
*/
public void putCharXY(final int x, final int y, final char ch);
public void putCharXY(final int x, final int y, final int ch);
/**
* Render a string. Does not wrap if the string exceeds the line.
@ -221,7 +221,7 @@ public interface Screen {
* @param attr attributes to use (bold, foreColor, backColor)
*/
public void vLineXY(final int x, final int y, final int n,
final char ch, final CellAttributes attr);
final int ch, final CellAttributes attr);
/**
* Draw a horizontal line from (x, y) to (x + n, y).
@ -233,7 +233,7 @@ public interface Screen {
* @param attr attributes to use (bold, foreColor, backColor)
*/
public void hLineXY(final int x, final int y, final int n,
final char ch, final CellAttributes attr);
final int ch, final CellAttributes attr);
/**
* Change the width. Everything on-screen will be destroyed and must be

View file

@ -1229,9 +1229,8 @@ public class SwingTerminal extends LogicalScreen
|| (cell.isBlink() && cursorBlinkVisible)
) {
gr2.setColor(attrToForegroundColor(cellColor));
char [] chars = new char[1];
chars[0] = cell.getChar();
gr2.drawChars(chars, 0, 1, gr2x + textAdjustX,
char [] chars = Character.toChars(cell.getChar());
gr2.drawChars(chars, 0, chars.length, gr2x + textAdjustX,
gr2y + textHeight - maxDescent + textAdjustY);
if (cell.isUnderline()) {

View file

@ -73,7 +73,7 @@ public final class Cell extends CellAttributes {
/**
* The character at this cell.
*/
private char ch = ' ';
private int ch = ' ';
/**
* The display width of this cell.
@ -129,7 +129,7 @@ public final class Cell extends CellAttributes {
* @param ch character to set to
* @see #reset()
*/
public Cell(final char ch) {
public Cell(final int ch) {
this.ch = ch;
}
@ -148,7 +148,7 @@ public final class Cell extends CellAttributes {
* @param ch character to set to
* @param attr attributes to use
*/
public Cell(final char ch, final CellAttributes attr) {
public Cell(final int ch, final CellAttributes attr) {
super(attr);
this.ch = ch;
}
@ -263,7 +263,7 @@ public final class Cell extends CellAttributes {
*
* @return cell character
*/
public char getChar() {
public int getChar() {
return ch;
}
@ -272,7 +272,7 @@ public final class Cell extends CellAttributes {
*
* @param ch new cell character
*/
public void setChar(final char ch) {
public void setChar(final int ch) {
this.ch = ch;
}

View file

@ -43,7 +43,7 @@ public class MnemonicString {
/**
* Keyboard shortcut to activate this item.
*/
private char shortcut;
private int shortcut;
/**
* Location of the highlighted character.
@ -74,23 +74,25 @@ public class MnemonicString {
public MnemonicString(final String label) {
// Setup the menu shortcut
String newLabel = "";
StringBuilder newLabel = new StringBuilder();
boolean foundAmp = false;
boolean foundShortcut = false;
int scanShortcutIdx = 0;
int scanScreenShortcutIdx = 0;
for (int i = 0; i < label.length(); i++) {
char c = label.charAt(i);
for (int i = 0; i < label.length();) {
int c = label.codePointAt(i);
i += Character.charCount(c);
if (c == '&') {
if (foundAmp) {
newLabel += '&';
newLabel.append('&');
scanShortcutIdx++;
scanScreenShortcutIdx++;
} else {
foundAmp = true;
}
} else {
newLabel += c;
newLabel.append(Character.toChars(c));
if (foundAmp) {
if (!foundShortcut) {
shortcut = c;
@ -105,7 +107,7 @@ public class MnemonicString {
}
}
}
this.rawLabel = newLabel;
this.rawLabel = newLabel.toString();
}
// ------------------------------------------------------------------------
@ -117,7 +119,7 @@ public class MnemonicString {
*
* @return the highlighted character
*/
public char getShortcut() {
public int getShortcut() {
return shortcut;
}

View file

@ -449,7 +449,8 @@ public class StringUtils {
|| ((ch >= 0xffe0) && (ch <= 0xffe6))
|| ((ch >= 0x20000) && (ch <= 0x2fffd))
|| ((ch >= 0x30000) && (ch <= 0x3fffd))
// TODO: emoji / twemoji
// emoji
|| ((ch >= 0x1f004) && (ch <= 0x1f9c0))
)
) {
return 2;
@ -466,8 +467,10 @@ public class StringUtils {
*/
public static int width(final String str) {
int n = 0;
for (int i = 0; i < str.length(); i++) {
n += width(str.charAt(i));
for (int i = 0; i < str.length();) {
int ch = str.codePointAt(i);
n += width(ch);
i += Character.charCount(ch);
}
return n;
}