X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2Fbackend%2FLogicalScreen.java;h=4e4aecca7a349eb999b83a9ef4bc71c229ff650a;hb=12b90437b5f22c2ae6e9b9b14c3b62b60f6143e5;hp=24ba4aff9f12afeec1b8b0609baf4e733d3a0524;hpb=9696a8f6da9a0d204740420d6d8571176ab81944;p=fanfix.git diff --git a/src/jexer/backend/LogicalScreen.java b/src/jexer/backend/LogicalScreen.java index 24ba4af..4e4aecc 100644 --- a/src/jexer/backend/LogicalScreen.java +++ b/src/jexer/backend/LogicalScreen.java @@ -28,9 +28,13 @@ */ package jexer.backend; +import java.awt.image.BufferedImage; + +import jexer.backend.GlyphMaker; import jexer.bits.Cell; import jexer.bits.CellAttributes; import jexer.bits.GraphicsChars; +import jexer.bits.StringUtils; /** * A logical screen composed of a 2D array of Cells. @@ -113,6 +117,17 @@ public class LogicalScreen implements Screen { */ protected int cursorY; + /** + * The last used height of a character cell in pixels, only used for + * full-width chars. + */ + private int lastTextHeight = -1; + + /** + * The glyph drawer for full-width chars. + */ + private GlyphMaker glyphMaker = null; + // ------------------------------------------------------------------------ // Constructors ----------------------------------------------------------- // ------------------------------------------------------------------------ @@ -134,6 +149,26 @@ public class LogicalScreen implements Screen { // Screen ----------------------------------------------------------------- // ------------------------------------------------------------------------ + /** + * Get the width of a character cell in pixels. + * + * @return the width in pixels of a character cell + */ + public int getTextWidth() { + // Default width is 16 pixels. + return 16; + } + + /** + * Get the height of a character cell in pixels. + * + * @return the height in pixels of a character cell + */ + public int getTextHeight() { + // Default height is 20 pixels. + return 20; + } + /** * Set drawing offset for x. * @@ -334,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++) { @@ -359,6 +394,11 @@ public class LogicalScreen implements Screen { return; } + if ((StringUtils.width(ch.getChar()) == 2) && (!ch.isImage())) { + putFullwidthCharXY(x, y, ch); + return; + } + int X = x + offsetX; int Y = y + offsetY; @@ -390,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) @@ -401,6 +441,11 @@ public class LogicalScreen implements Screen { return; } + if (StringUtils.width(ch) == 2) { + putFullwidthCharXY(x, y, ch, attr); + return; + } + int X = x + offsetX; int Y = y + offsetY; @@ -431,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) @@ -441,6 +485,11 @@ public class LogicalScreen implements Screen { return; } + if (StringUtils.width(ch) == 2) { + putFullwidthCharXY(x, y, ch); + return; + } + int X = x + offsetX; int Y = y + offsetY; @@ -470,10 +519,11 @@ 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++; + i += StringUtils.width(ch); if (i == width) { break; } @@ -491,10 +541,11 @@ 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++; + i += StringUtils.width(ch); if (i == width) { break; } @@ -511,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); @@ -528,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); @@ -752,11 +803,30 @@ public class LogicalScreen implements Screen { clipBottom = height - offsetY; for (int i = 0; i < boxHeight; i++) { - putAttrXY(boxLeft + boxWidth, boxTop + 1 + i, shadowAttr); - putAttrXY(boxLeft + boxWidth + 1, boxTop + 1 + i, shadowAttr); + Cell cell = getCharXY(offsetX + boxLeft + boxWidth, + offsetY + boxTop + 1 + i); + if (cell.getWidth() == Cell.Width.SINGLE) { + putAttrXY(boxLeft + boxWidth, boxTop + 1 + i, shadowAttr); + } else { + putCharXY(boxLeft + boxWidth, boxTop + 1 + i, ' ', shadowAttr); + } + cell = getCharXY(offsetX + boxLeft + boxWidth + 1, + offsetY + boxTop + 1 + i); + if (cell.getWidth() == Cell.Width.SINGLE) { + putAttrXY(boxLeft + boxWidth + 1, boxTop + 1 + i, shadowAttr); + } else { + putCharXY(boxLeft + boxWidth + 1, boxTop + 1 + i, ' ', + shadowAttr); + } } for (int i = 0; i < boxWidth; i++) { - putAttrXY(boxLeft + 2 + i, boxTop + boxHeight, shadowAttr); + Cell cell = getCharXY(offsetX + boxLeft + 2 + i, + offsetY + boxTop + boxHeight); + if (cell.getWidth() == Cell.Width.SINGLE) { + putAttrXY(boxLeft + 2 + i, boxTop + boxHeight, shadowAttr); + } else { + putCharXY(boxLeft + 2 + i, boxTop + boxHeight, ' ', shadowAttr); + } } clipRight = oldClipRight; clipBottom = oldClipBottom; @@ -907,4 +977,69 @@ public class LogicalScreen implements Screen { } } + /** + * Render one fullwidth cell. + * + * @param x column coordinate. 0 is the left-most column. + * @param y row coordinate. 0 is the top-most row. + * @param cell the cell to draw + */ + public final void putFullwidthCharXY(final int x, final int y, + final Cell cell) { + + int cellWidth = getTextWidth(); + int cellHeight = getTextHeight(); + + if (lastTextHeight != cellHeight) { + glyphMaker = GlyphMaker.getInstance(cellHeight); + lastTextHeight = cellHeight; + } + BufferedImage image = glyphMaker.getImage(cell, cellWidth * 2, + cellHeight); + BufferedImage leftImage = image.getSubimage(0, 0, cellWidth, + cellHeight); + BufferedImage rightImage = image.getSubimage(cellWidth, 0, cellWidth, + cellHeight); + + Cell left = new Cell(cell); + left.setImage(leftImage); + left.setWidth(Cell.Width.LEFT); + putCharXY(x, y, left); + + Cell right = new Cell(cell); + right.setImage(rightImage); + right.setWidth(Cell.Width.RIGHT); + putCharXY(x + 1, y, right); + } + + /** + * Render one fullwidth character with attributes. + * + * @param x column coordinate. 0 is the left-most column. + * @param y row coordinate. 0 is the top-most row. + * @param ch character to draw + * @param attr attributes to use (bold, foreColor, backColor) + */ + public final void putFullwidthCharXY(final int x, final int y, + final int ch, final CellAttributes attr) { + + Cell cell = new Cell(ch, attr); + putFullwidthCharXY(x, y, cell); + } + + /** + * Render one fullwidth character with attributes. + * + * @param x column coordinate. 0 is the left-most column. + * @param y row coordinate. 0 is the top-most row. + * @param ch character to draw + */ + public final void putFullwidthCharXY(final int x, final int y, + final int ch) { + + Cell cell = new Cell(ch); + cell.setAttr(getAttrXY(x, y)); + putFullwidthCharXY(x, y, cell); + } + }