X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2Fbackend%2FLogicalScreen.java;h=513c599145440e8a9682ef5c764b8e5d650e9c29;hb=03ae544a1639c127ebec9a46635f2ad465713908;hp=c24703e7a23098740804f5be8f4873b27ceb1324;hpb=d36057dfab8def933a64be042b039d76708ac5ba;p=fanfix.git diff --git a/src/jexer/backend/LogicalScreen.java b/src/jexer/backend/LogicalScreen.java index c24703e..513c599 100644 --- a/src/jexer/backend/LogicalScreen.java +++ b/src/jexer/backend/LogicalScreen.java @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (C) 2017 Kevin Lamonte + * Copyright (C) 2019 Kevin Lamonte * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -134,6 +134,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. * @@ -322,11 +342,8 @@ public class LogicalScreen implements Screen { // If this happens to be the cursor position, make the position // dirty. if ((cursorX == X) && (cursorY == Y)) { - if (physical[cursorX][cursorY].getChar() == 'Q') { - physical[cursorX][cursorY].setChar('X'); - } else { - physical[cursorX][cursorY].setChar('Q'); - } + physical[cursorX][cursorY].unset(); + unsetImageRow(cursorY); } } } @@ -354,7 +371,35 @@ public class LogicalScreen implements Screen { * @param ch character + attributes to draw */ public final void putCharXY(final int x, final int y, final Cell ch) { - putCharXY(x, y, ch.getChar(), ch); + if ((x < clipLeft) + || (x >= clipRight) + || (y < clipTop) + || (y >= clipBottom) + ) { + return; + } + + int X = x + offsetX; + int Y = y + offsetY; + + // System.err.printf("putCharXY: %d, %d, %c\n", X, Y, ch); + + if ((X >= 0) && (X < width) && (Y >= 0) && (Y < height)) { + + // Do not put control characters on the display + if (!ch.isImage()) { + assert (ch.getChar() >= 0x20); + assert (ch.getChar() != 0x7F); + } + logical[X][Y].setTo(ch); + + // If this happens to be the cursor position, make the position + // dirty. + if ((cursorX == X) && (cursorY == Y)) { + physical[cursorX][cursorY].unset(); + unsetImageRow(cursorY); + } + } } /** @@ -393,11 +438,8 @@ public class LogicalScreen implements Screen { // If this happens to be the cursor position, make the position // dirty. if ((cursorX == X) && (cursorY == Y)) { - if (physical[cursorX][cursorY].getChar() == 'Q') { - physical[cursorX][cursorY].setChar('X'); - } else { - physical[cursorX][cursorY].setChar('Q'); - } + physical[cursorX][cursorY].unset(); + unsetImageRow(cursorY); } } } @@ -430,11 +472,8 @@ public class LogicalScreen implements Screen { // If this happens to be the cursor position, make the position // dirty. if ((cursorX == X) && (cursorY == Y)) { - if (physical[cursorX][cursorY].getChar() == 'Q') { - physical[cursorX][cursorY].setChar('X'); - } else { - physical[cursorX][cursorY].setChar('Q'); - } + physical[cursorX][cursorY].unset(); + unsetImageRow(cursorY); } } } @@ -545,6 +584,14 @@ public class LogicalScreen implements Screen { */ public final void setDimensions(final int width, final int height) { reallocate(width, height); + resizeToScreen(); + } + + /** + * Resize the physical screen to match the logical screen dimensions. + */ + public void resizeToScreen() { + // Subclasses are expected to override this. } /** @@ -600,7 +647,7 @@ public class LogicalScreen implements Screen { /** * Draw a box with a border and empty background. * - * @param left left column of box. 0 is the left-most row. + * @param left left column of box. 0 is the left-most column. * @param top top row of the box. 0 is the top-most row. * @param right right column of box * @param bottom bottom row of the box @@ -617,7 +664,7 @@ public class LogicalScreen implements Screen { /** * Draw a box with a border and empty background. * - * @param left left column of box. 0 is the left-most row. + * @param left left column of box. 0 is the left-most column. * @param top top row of the box. 0 is the top-most row. * @param right right column of box * @param bottom bottom row of the box @@ -702,7 +749,7 @@ public class LogicalScreen implements Screen { /** * Draw a box shadow. * - * @param left left column of box. 0 is the left-most row. + * @param left left column of box. 0 is the left-most column. * @param top top row of the box. 0 is the top-most row. * @param right right column of box * @param bottom bottom row of the box @@ -719,12 +766,10 @@ public class LogicalScreen implements Screen { // Shadows do not honor clipping but they DO honor offset. int oldClipRight = clipRight; int oldClipBottom = clipBottom; - /* - clipRight = boxWidth + 2; - clipBottom = boxHeight + 1; - */ - clipRight = width; - clipBottom = height; + // When offsetX or offsetY go negative, we need to increase the clip + // bounds. + clipRight = width - offsetX; + clipBottom = height - offsetY; for (int i = 0; i < boxHeight; i++) { putAttrXY(boxLeft + boxWidth, boxTop + 1 + i, shadowAttr); @@ -756,11 +801,8 @@ public class LogicalScreen implements Screen { && (cursorX <= width - 1) ) { // Make the current cursor position dirty - if (physical[cursorX][cursorY].getChar() == 'Q') { - physical[cursorX][cursorY].setChar('X'); - } else { - physical[cursorX][cursorY].setChar('Q'); - } + physical[cursorX][cursorY].unset(); + unsetImageRow(cursorY); } cursorVisible = visible; @@ -863,7 +905,24 @@ public class LogicalScreen implements Screen { public final void clearPhysical() { for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { - physical[col][row].reset(); + physical[col][row].unset(); + } + } + } + + /** + * Unset every image cell on one row of the physical screen, forcing + * images on that row to be redrawn. + * + * @param y row coordinate. 0 is the top-most row. + */ + public final void unsetImageRow(final int y) { + if ((y < 0) || (y >= height)) { + return; + } + for (int x = 0; x < width; x++) { + if (logical[x][y].isImage()) { + physical[x][y].unset(); } } }