#35 fix demo
[fanfix.git] / src / jexer / backend / LogicalScreen.java
index 24ba4aff9f12afeec1b8b0609baf4e733d3a0524..558fdc4812c1e553b1434e0b1d6c173dc4ef0469 100644 (file)
  */
 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.
      *
@@ -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;
 
@@ -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;
 
@@ -441,6 +486,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;
 
@@ -473,7 +523,7 @@ public class LogicalScreen implements Screen {
         for (int j = 0; j < str.length(); j++) {
             char ch = str.charAt(j);
             putCharXY(i, y, ch, attr);
-            i++;
+            i += StringUtils.width(ch);
             if (i == width) {
                 break;
             }
@@ -494,7 +544,7 @@ public class LogicalScreen implements Screen {
         for (int j = 0; j < str.length(); j++) {
             char ch = str.charAt(j);
             putCharXY(i, y, ch);
-            i++;
+            i += StringUtils.width(ch);
             if (i == width) {
                 break;
             }
@@ -907,4 +957,73 @@ 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);
+        // Blank out the char itself, so that shadows do not leave artifacts.
+        left.setChar(' ');
+        putCharXY(x, y, left);
+
+        Cell right = new Cell(cell);
+        right.setImage(rightImage);
+        right.setWidth(Cell.Width.RIGHT);
+        // Blank out the char itself, so that shadows do not leave artifacts.
+        right.setChar(' ');
+        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 char 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 char ch) {
+
+        Cell cell = new Cell(ch);
+        cell.setAttr(getAttrXY(x, y));
+        putFullwidthCharXY(x, y, cell);
+    }
+
 }