mirror of
https://gitlab.com/AutumnMeowMeow/jexer
synced 2024-09-19 11:50:19 -06:00
Use terminal colors for image background
This commit is contained in:
parent
50fcfc3ea0
commit
48dd72ea1b
18 changed files with 591 additions and 63 deletions
|
@ -379,7 +379,7 @@ public class TImage extends TWidget implements EditMenuUser {
|
|||
* @param always if true, always resize the cells
|
||||
*/
|
||||
private void sizeToImage(final boolean always) {
|
||||
scaleBackColor = jexer.backend.SwingTerminal.attrToBackgroundColor(getWindow().getBackground());
|
||||
scaleBackColor = getApplication().getBackend().attrToBackgroundColor(getWindow().getBackground());
|
||||
|
||||
int textWidth = getScreen().getTextWidth();
|
||||
int textHeight = getScreen().getTextHeight();
|
||||
|
@ -437,7 +437,7 @@ public class TImage extends TWidget implements EditMenuUser {
|
|||
|
||||
if (!ImageUtils.isFullyTransparent(newImage)) {
|
||||
cell.setImage(newImage);
|
||||
cell.flattenImage(false);
|
||||
cell.flattenImage(false, getApplication().getBackend());
|
||||
}
|
||||
cells[x][y] = cell;
|
||||
}
|
||||
|
|
|
@ -1335,10 +1335,10 @@ public class TTerminalWidget extends TScrollableWidget
|
|||
Cell newCell = new Cell(cell);
|
||||
newCell.setUnderline(false);
|
||||
image = doubleFont.getImage(newCell, textWidth * 2, textHeight * 2,
|
||||
cursorBlinkVisible);
|
||||
getApplication().getBackend(), cursorBlinkVisible);
|
||||
} else {
|
||||
image = doubleFont.getImage(cell, textWidth * 2, textHeight * 2,
|
||||
cursorBlinkVisible);
|
||||
getApplication().getBackend(), cursorBlinkVisible);
|
||||
}
|
||||
|
||||
// Now that we have the double-wide glyph drawn, copy the right
|
||||
|
|
|
@ -442,10 +442,10 @@ public class TTextPicture extends TScrollableWidget
|
|||
Cell newCell = new Cell(cell);
|
||||
newCell.setUnderline(false);
|
||||
image = doubleFont.getImage(newCell, textWidth * 2, textHeight * 2,
|
||||
cursorBlinkVisible);
|
||||
getApplication().getBackend(), cursorBlinkVisible);
|
||||
} else {
|
||||
image = doubleFont.getImage(cell, textWidth * 2, textHeight * 2,
|
||||
cursorBlinkVisible);
|
||||
getApplication().getBackend(), cursorBlinkVisible);
|
||||
}
|
||||
|
||||
// Now that we have the double-wide glyph drawn, copy the right
|
||||
|
|
|
@ -30,6 +30,7 @@ package jexer.backend;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import jexer.bits.CellAttributes;
|
||||
import jexer.event.TInputEvent;
|
||||
|
||||
/**
|
||||
|
@ -146,4 +147,20 @@ public interface Backend {
|
|||
*/
|
||||
public void setMouseStyle(final String mouseStyle);
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes foreground color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the AWT Color
|
||||
*/
|
||||
public java.awt.Color attrToForegroundColor(final CellAttributes attr);
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes background color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the AWT Color
|
||||
*/
|
||||
public java.awt.Color attrToBackgroundColor(final CellAttributes attr);
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ import java.io.PrintWriter;
|
|||
import java.io.Reader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import jexer.bits.CellAttributes;
|
||||
|
||||
/**
|
||||
* This class uses an xterm/ANSI X3.64/ECMA-48 type terminal to provide a
|
||||
* screen, keyboard, and mouse to TApplication.
|
||||
|
@ -83,6 +85,7 @@ public class ECMA48Backend extends GenericBackend {
|
|||
// Create a terminal and explicitly set stdin into raw mode
|
||||
terminal = new ECMA48Terminal(this, listener, input, output,
|
||||
windowWidth, windowHeight);
|
||||
((ECMA48Terminal) terminal).setBackend(this);
|
||||
|
||||
// Keep the terminal's sessionInfo so that TApplication can see it
|
||||
sessionInfo = ((ECMA48Terminal) terminal).getSessionInfo();
|
||||
|
@ -136,6 +139,7 @@ public class ECMA48Backend extends GenericBackend {
|
|||
|
||||
// Create a terminal and explicitly set stdin into raw mode
|
||||
terminal = new ECMA48Terminal(this, listener, input, output);
|
||||
((ECMA48Terminal) terminal).setBackend(this);
|
||||
|
||||
// Keep the terminal's sessionInfo so that TApplication can see it
|
||||
sessionInfo = ((ECMA48Terminal) terminal).getSessionInfo();
|
||||
|
@ -165,6 +169,7 @@ public class ECMA48Backend extends GenericBackend {
|
|||
// Create a terminal and explicitly set stdin into raw mode
|
||||
terminal = new ECMA48Terminal(this, listener, input, reader, writer,
|
||||
setRawMode);
|
||||
((ECMA48Terminal) terminal).setBackend(this);
|
||||
|
||||
// Keep the terminal's sessionInfo so that TApplication can see it
|
||||
sessionInfo = ((ECMA48Terminal) terminal).getSessionInfo();
|
||||
|
@ -235,4 +240,24 @@ public class ECMA48Backend extends GenericBackend {
|
|||
((ECMA48Terminal) terminal).setMouseStyle(mouseStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes foreground color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the AWT Color
|
||||
*/
|
||||
public java.awt.Color attrToForegroundColor(final CellAttributes attr) {
|
||||
return ((ECMA48Terminal) terminal).attrToForegroundColor(attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes background color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the AWT Color
|
||||
*/
|
||||
public java.awt.Color attrToBackgroundColor(final CellAttributes attr) {
|
||||
return ((ECMA48Terminal) terminal).attrToBackgroundColor(attr);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ public class ECMA48Terminal extends LogicalScreen
|
|||
CSI_ENTRY,
|
||||
CSI_PARAM,
|
||||
XTVERSION,
|
||||
OSC,
|
||||
MOUSE,
|
||||
MOUSE_SGR,
|
||||
}
|
||||
|
@ -291,6 +292,11 @@ public class ECMA48Terminal extends LogicalScreen
|
|||
*/
|
||||
private StringBuilder xtversionResponse = new StringBuilder();
|
||||
|
||||
/**
|
||||
* The string being built by OSC.
|
||||
*/
|
||||
private StringBuilder oscResponse = new StringBuilder();
|
||||
|
||||
/**
|
||||
* If true, draw text glyphs underneath images on cells. This is
|
||||
* expensive.
|
||||
|
@ -342,22 +348,22 @@ public class ECMA48Terminal extends LogicalScreen
|
|||
private Object listener;
|
||||
|
||||
// Colors to map DOS colors to AWT colors.
|
||||
private static java.awt.Color MYBLACK;
|
||||
private static java.awt.Color MYRED;
|
||||
private static java.awt.Color MYGREEN;
|
||||
private static java.awt.Color MYYELLOW;
|
||||
private static java.awt.Color MYBLUE;
|
||||
private static java.awt.Color MYMAGENTA;
|
||||
private static java.awt.Color MYCYAN;
|
||||
private static java.awt.Color MYWHITE;
|
||||
private static java.awt.Color MYBOLD_BLACK;
|
||||
private static java.awt.Color MYBOLD_RED;
|
||||
private static java.awt.Color MYBOLD_GREEN;
|
||||
private static java.awt.Color MYBOLD_YELLOW;
|
||||
private static java.awt.Color MYBOLD_BLUE;
|
||||
private static java.awt.Color MYBOLD_MAGENTA;
|
||||
private static java.awt.Color MYBOLD_CYAN;
|
||||
private static java.awt.Color MYBOLD_WHITE;
|
||||
private java.awt.Color MYBLACK;
|
||||
private java.awt.Color MYRED;
|
||||
private java.awt.Color MYGREEN;
|
||||
private java.awt.Color MYYELLOW;
|
||||
private java.awt.Color MYBLUE;
|
||||
private java.awt.Color MYMAGENTA;
|
||||
private java.awt.Color MYCYAN;
|
||||
private java.awt.Color MYWHITE;
|
||||
private java.awt.Color MYBOLD_BLACK;
|
||||
private java.awt.Color MYBOLD_RED;
|
||||
private java.awt.Color MYBOLD_GREEN;
|
||||
private java.awt.Color MYBOLD_YELLOW;
|
||||
private java.awt.Color MYBOLD_BLUE;
|
||||
private java.awt.Color MYBOLD_MAGENTA;
|
||||
private java.awt.Color MYBOLD_CYAN;
|
||||
private java.awt.Color MYBOLD_WHITE;
|
||||
|
||||
/**
|
||||
* ImageCache is a least-recently-used cache that hangs on to the
|
||||
|
@ -620,6 +626,9 @@ public class ECMA48Terminal extends LogicalScreen
|
|||
// Request xterm report SGR-Pixel mouse support
|
||||
this.output.printf("%s", xtermQueryMode(1016));
|
||||
|
||||
// Request xterm report its ANSI colors
|
||||
this.output.printf("%s", xtermQueryAnsiColors());
|
||||
|
||||
this.output.flush();
|
||||
|
||||
// Query the screen size
|
||||
|
@ -730,6 +739,9 @@ public class ECMA48Terminal extends LogicalScreen
|
|||
// Request xterm report SGR-Pixel mouse support
|
||||
this.output.printf("%s", xtermQueryMode(1016));
|
||||
|
||||
// Request xterm report its ANSI colors
|
||||
this.output.printf("%s", xtermQueryAnsiColors());
|
||||
|
||||
this.output.flush();
|
||||
|
||||
// Query the screen size
|
||||
|
@ -1649,10 +1661,11 @@ public class ECMA48Terminal extends LogicalScreen
|
|||
// if imagesOverText is disabled then we will quietly
|
||||
// continue on. Otherwise render a text character
|
||||
// under the image.
|
||||
assert (backend != null);
|
||||
if (imagesOverText == true) {
|
||||
logical[x + i][y].flattenImage(true);
|
||||
logical[x + i][y].flattenImage(true, backend);
|
||||
} else {
|
||||
logical[x + i][y].flattenImage(false);
|
||||
logical[x + i][y].flattenImage(false, backend);
|
||||
}
|
||||
}
|
||||
assert (!logical[x + i][y].isTransparentImage());
|
||||
|
@ -1748,6 +1761,7 @@ public class ECMA48Terminal extends LogicalScreen
|
|||
decPrivateModeFlag = false;
|
||||
decDollarModeFlag = false;
|
||||
xtversionResponse.setLength(0);
|
||||
oscResponse.setLength(0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2275,6 +2289,162 @@ public class ECMA48Terminal extends LogicalScreen
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an OSC response.
|
||||
*
|
||||
* @param text the OSC response string
|
||||
*/
|
||||
private void oscResponse(final String text) {
|
||||
if (debugToStderr) {
|
||||
System.err.println("oscResponse(): '" + text + "'");
|
||||
}
|
||||
|
||||
String [] Ps = text.split(";");
|
||||
if (Ps.length == 0) {
|
||||
return;
|
||||
}
|
||||
if (Ps[0].equals("4")) {
|
||||
// RGB response
|
||||
if (Ps.length != 3) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
int color = Integer.parseInt(Ps[1]);
|
||||
String rgb = Ps[2];
|
||||
if (!rgb.startsWith("rgb:")) {
|
||||
return;
|
||||
}
|
||||
rgb = rgb.substring(4);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Color " + color + " is " + rgb);
|
||||
}
|
||||
String [] rgbs = rgb.split("/");
|
||||
if (rgbs.length != 3) {
|
||||
return;
|
||||
}
|
||||
int red = Integer.parseInt(rgbs[0], 16);
|
||||
int green = Integer.parseInt(rgbs[1], 16);
|
||||
int blue = Integer.parseInt(rgbs[2], 16);
|
||||
if (rgbs[0].length() == 4) {
|
||||
red = red >> 8;
|
||||
}
|
||||
if (rgbs[1].length() == 4) {
|
||||
green = green >> 8;
|
||||
}
|
||||
if (rgbs[2].length() == 4) {
|
||||
blue = blue >> 8;
|
||||
}
|
||||
if (debugToStderr) {
|
||||
System.err.printf(" RGB %02x%02x%02x\n",
|
||||
red, green, blue);
|
||||
}
|
||||
switch (color) {
|
||||
case 0:
|
||||
MYBLACK = new java.awt.Color(red, green, blue);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Set BLACK");
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
MYRED = new java.awt.Color(red, green, blue);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Set RED");
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
MYGREEN = new java.awt.Color(red, green, blue);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Set GREEN");
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
MYYELLOW = new java.awt.Color(red, green, blue);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Set YELLOW");
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
MYBLUE = new java.awt.Color(red, green, blue);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Set BLUE");
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
MYMAGENTA = new java.awt.Color(red, green, blue);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Set MAGENTA");
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
MYCYAN = new java.awt.Color(red, green, blue);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Set CYAN");
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
MYWHITE = new java.awt.Color(red, green, blue);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Set WHITE");
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
MYBOLD_BLACK = new java.awt.Color(red, green, blue);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Set BOLD BLACK");
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
MYBOLD_RED = new java.awt.Color(red, green, blue);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Set BOLD RED");
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
MYBOLD_GREEN = new java.awt.Color(red, green, blue);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Set BOLD GREEN");
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
MYBOLD_YELLOW = new java.awt.Color(red, green, blue);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Set BOLD YELLOW");
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
MYBOLD_BLUE = new java.awt.Color(red, green, blue);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Set BOLD BLUE");
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
MYBOLD_MAGENTA = new java.awt.Color(red, green, blue);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Set BOLD MAGENTA");
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
MYBOLD_CYAN = new java.awt.Color(red, green, blue);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Set BOLD CYAN");
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
MYBOLD_WHITE = new java.awt.Color(red, green, blue);
|
||||
if (debugToStderr) {
|
||||
System.err.println(" Set BOLD WHITE");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the next character of input to see if an InputEvent is
|
||||
* fully here.
|
||||
|
@ -2341,6 +2511,12 @@ public class ECMA48Terminal extends LogicalScreen
|
|||
}
|
||||
xtversionQuery = false;
|
||||
|
||||
if (ch == ']') {
|
||||
state = ParseState.OSC;
|
||||
oscResponse.setLength(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ch <= 0x1F) {
|
||||
// ALT-Control character
|
||||
events.add(controlChar(ch, true));
|
||||
|
@ -2842,6 +3018,22 @@ public class ECMA48Terminal extends LogicalScreen
|
|||
xtversionResponse.append(ch);
|
||||
return;
|
||||
|
||||
case OSC:
|
||||
if ((ch == '\\') &&
|
||||
(oscResponse.length() > 0) &&
|
||||
(oscResponse.charAt(oscResponse.length() - 1)
|
||||
== 0x1B)
|
||||
) {
|
||||
// This is ST, end of the line.
|
||||
oscResponse(oscResponse.substring(0, oscResponse.length() - 1));
|
||||
resetParser();
|
||||
return;
|
||||
}
|
||||
|
||||
// Continue collecting until we see ST.
|
||||
oscResponse.append(ch);
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -3741,6 +3933,100 @@ public class ECMA48Terminal extends LogicalScreen
|
|||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes foreground color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the AWT Color
|
||||
*/
|
||||
public java.awt.Color attrToForegroundColor(final CellAttributes attr) {
|
||||
int rgb = attr.getForeColorRGB();
|
||||
if (rgb >= 0) {
|
||||
int red = (rgb >>> 16) & 0xFF;
|
||||
int green = (rgb >>> 8) & 0xFF;
|
||||
int blue = rgb & 0xFF;
|
||||
|
||||
return new java.awt.Color(red, green, blue);
|
||||
}
|
||||
|
||||
if (attr.isBold()) {
|
||||
if (attr.getForeColor().equals(Color.BLACK)) {
|
||||
return MYBOLD_BLACK;
|
||||
} else if (attr.getForeColor().equals(Color.RED)) {
|
||||
return MYBOLD_RED;
|
||||
} else if (attr.getForeColor().equals(Color.BLUE)) {
|
||||
return MYBOLD_BLUE;
|
||||
} else if (attr.getForeColor().equals(Color.GREEN)) {
|
||||
return MYBOLD_GREEN;
|
||||
} else if (attr.getForeColor().equals(Color.YELLOW)) {
|
||||
return MYBOLD_YELLOW;
|
||||
} else if (attr.getForeColor().equals(Color.CYAN)) {
|
||||
return MYBOLD_CYAN;
|
||||
} else if (attr.getForeColor().equals(Color.MAGENTA)) {
|
||||
return MYBOLD_MAGENTA;
|
||||
} else if (attr.getForeColor().equals(Color.WHITE)) {
|
||||
return MYBOLD_WHITE;
|
||||
}
|
||||
} else {
|
||||
if (attr.getForeColor().equals(Color.BLACK)) {
|
||||
return MYBLACK;
|
||||
} else if (attr.getForeColor().equals(Color.RED)) {
|
||||
return MYRED;
|
||||
} else if (attr.getForeColor().equals(Color.BLUE)) {
|
||||
return MYBLUE;
|
||||
} else if (attr.getForeColor().equals(Color.GREEN)) {
|
||||
return MYGREEN;
|
||||
} else if (attr.getForeColor().equals(Color.YELLOW)) {
|
||||
return MYYELLOW;
|
||||
} else if (attr.getForeColor().equals(Color.CYAN)) {
|
||||
return MYCYAN;
|
||||
} else if (attr.getForeColor().equals(Color.MAGENTA)) {
|
||||
return MYMAGENTA;
|
||||
} else if (attr.getForeColor().equals(Color.WHITE)) {
|
||||
return MYWHITE;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid color: " +
|
||||
attr.getForeColor().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes background color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the AWT Color
|
||||
*/
|
||||
public java.awt.Color attrToBackgroundColor(final CellAttributes attr) {
|
||||
int rgb = attr.getBackColorRGB();
|
||||
if (rgb >= 0) {
|
||||
int red = (rgb >>> 16) & 0xFF;
|
||||
int green = (rgb >>> 8) & 0xFF;
|
||||
int blue = rgb & 0xFF;
|
||||
|
||||
return new java.awt.Color(red, green, blue);
|
||||
}
|
||||
|
||||
if (attr.getBackColor().equals(Color.BLACK)) {
|
||||
return MYBLACK;
|
||||
} else if (attr.getBackColor().equals(Color.RED)) {
|
||||
return MYRED;
|
||||
} else if (attr.getBackColor().equals(Color.BLUE)) {
|
||||
return MYBLUE;
|
||||
} else if (attr.getBackColor().equals(Color.GREEN)) {
|
||||
return MYGREEN;
|
||||
} else if (attr.getBackColor().equals(Color.YELLOW)) {
|
||||
return MYYELLOW;
|
||||
} else if (attr.getBackColor().equals(Color.CYAN)) {
|
||||
return MYCYAN;
|
||||
} else if (attr.getBackColor().equals(Color.MAGENTA)) {
|
||||
return MYMAGENTA;
|
||||
} else if (attr.getBackColor().equals(Color.WHITE)) {
|
||||
return MYWHITE;
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid color: " +
|
||||
attr.getBackColor().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a T.416 RGB parameter sequence for a custom system color.
|
||||
*
|
||||
|
@ -4269,4 +4555,17 @@ public class ECMA48Terminal extends LogicalScreen
|
|||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Request (u)xterm report the RGB values of its ANSI colors.
|
||||
*
|
||||
* @return the string to emit to xterm
|
||||
*/
|
||||
private String xtermQueryAnsiColors() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < 16; i++) {
|
||||
sb.append(String.format("\033]4;%d;?\033\\", i));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -172,12 +172,14 @@ class GlyphMakerFont {
|
|||
* @param cell the character to draw
|
||||
* @param cellWidth the width of the text cell to draw into
|
||||
* @param cellHeight the height of the text cell to draw into
|
||||
* @param backend the backend that can obtain the correct background
|
||||
* color
|
||||
* @return the glyph as an image
|
||||
*/
|
||||
public BufferedImage getImage(final Cell cell, final int cellWidth,
|
||||
final int cellHeight) {
|
||||
final int cellHeight, final Backend backend) {
|
||||
|
||||
return getImage(cell, cellWidth, cellHeight, true);
|
||||
return getImage(cell, cellWidth, cellHeight, backend, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -186,11 +188,30 @@ class GlyphMakerFont {
|
|||
* @param cell the character to draw
|
||||
* @param cellWidth the width of the text cell to draw into
|
||||
* @param cellHeight the height of the text cell to draw into
|
||||
* @return the glyph as an image
|
||||
*/
|
||||
/*
|
||||
public BufferedImage getImage(final Cell cell, final int cellWidth,
|
||||
final int cellHeight) {
|
||||
|
||||
return getImage(cell, cellWidth, cellHeight, true);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get a glyph image.
|
||||
*
|
||||
* @param cell the character to draw
|
||||
* @param cellWidth the width of the text cell to draw into
|
||||
* @param cellHeight the height of the text cell to draw into
|
||||
* @param backend the backend that can obtain the correct background
|
||||
* color
|
||||
* @param blinkVisible if true, the cell is visible if it is blinking
|
||||
* @return the glyph as an image
|
||||
*/
|
||||
public BufferedImage getImage(final Cell cell, final int cellWidth,
|
||||
final int cellHeight, final boolean blinkVisible) {
|
||||
final int cellHeight, final Backend backend,
|
||||
final boolean blinkVisible) {
|
||||
|
||||
if (gotFontDimensions == false) {
|
||||
// Lazy-load the text width/height and adjustments.
|
||||
|
@ -227,14 +248,14 @@ class GlyphMakerFont {
|
|||
}
|
||||
|
||||
// Draw the background rectangle, then the foreground character.
|
||||
gr2.setColor(SwingTerminal.attrToBackgroundColor(cellColor));
|
||||
gr2.setColor(backend.attrToBackgroundColor(cellColor));
|
||||
gr2.fillRect(0, 0, cellWidth, cellHeight);
|
||||
|
||||
// Handle blink and underline
|
||||
if (!cell.isBlink()
|
||||
|| (cell.isBlink() && blinkVisible)
|
||||
) {
|
||||
gr2.setColor(SwingTerminal.attrToForegroundColor(cellColor));
|
||||
gr2.setColor(backend.attrToForegroundColor(cellColor));
|
||||
char [] chars = Character.toChars(cell.getChar());
|
||||
gr2.drawChars(chars, 0, chars.length, textAdjustX,
|
||||
cellHeight - maxDescent + textAdjustY);
|
||||
|
@ -427,12 +448,14 @@ public class GlyphMaker {
|
|||
* @param cell the character to draw
|
||||
* @param cellWidth the width of the text cell to draw into
|
||||
* @param cellHeight the height of the text cell to draw into
|
||||
* @param backend the backend that can obtain the correct background
|
||||
* color
|
||||
* @return the glyph as an image
|
||||
*/
|
||||
public BufferedImage getImage(final Cell cell, final int cellWidth,
|
||||
final int cellHeight) {
|
||||
final int cellHeight, final Backend backend) {
|
||||
|
||||
return getImage(cell, cellWidth, cellHeight, true);
|
||||
return getImage(cell, cellWidth, cellHeight, backend, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -441,34 +464,37 @@ public class GlyphMaker {
|
|||
* @param cell the character to draw
|
||||
* @param cellWidth the width of the text cell to draw into
|
||||
* @param cellHeight the height of the text cell to draw into
|
||||
* @param backend the backend that can obtain the correct background
|
||||
* color
|
||||
* @param blinkVisible if true, the cell is visible if it is blinking
|
||||
* @return the glyph as an image
|
||||
*/
|
||||
public BufferedImage getImage(final Cell cell, final int cellWidth,
|
||||
final int cellHeight, final boolean blinkVisible) {
|
||||
final int cellHeight, final Backend backend,
|
||||
final boolean blinkVisible) {
|
||||
|
||||
int ch = cell.getChar();
|
||||
if (StringUtils.isCjk(ch)) {
|
||||
if (makerCjk.canDisplay(ch)) {
|
||||
return makerCjk.getImage(cell, cellWidth, cellHeight,
|
||||
return makerCjk.getImage(cell, cellWidth, cellHeight, backend,
|
||||
blinkVisible);
|
||||
}
|
||||
}
|
||||
if (StringUtils.isEmoji(ch)) {
|
||||
if (makerEmoji.canDisplay(ch)) {
|
||||
// System.err.println("emoji: " + String.format("0x%x", ch));
|
||||
return makerEmoji.getImage(cell, cellWidth, cellHeight,
|
||||
return makerEmoji.getImage(cell, cellWidth, cellHeight, backend,
|
||||
blinkVisible);
|
||||
}
|
||||
}
|
||||
|
||||
// When all else fails, use the default.
|
||||
if (makerMono.canDisplay(ch)) {
|
||||
return makerMono.getImage(cell, cellWidth, cellHeight,
|
||||
return makerMono.getImage(cell, cellWidth, cellHeight, backend,
|
||||
blinkVisible);
|
||||
}
|
||||
|
||||
return makerFallback.getImage(cell, cellWidth, cellHeight,
|
||||
return makerFallback.getImage(cell, cellWidth, cellHeight, backend,
|
||||
blinkVisible);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ package jexer.backend;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import jexer.bits.CellAttributes;
|
||||
import jexer.event.TInputEvent;
|
||||
|
||||
/**
|
||||
|
@ -190,4 +191,26 @@ public class HeadlessBackend extends LogicalScreen implements Backend {
|
|||
// NOP
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes foreground color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the AWT Color
|
||||
*/
|
||||
public java.awt.Color attrToForegroundColor(final CellAttributes attr) {
|
||||
// Use Swing colors.
|
||||
return SwingTerminal.attrToForegroundColor(attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes background color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the AWT Color
|
||||
*/
|
||||
public java.awt.Color attrToBackgroundColor(final CellAttributes attr) {
|
||||
// Use Swing colors.
|
||||
return SwingTerminal.attrToBackgroundColor(attr);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,6 +46,11 @@ public class LogicalScreen implements Screen {
|
|||
// Variables --------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The backend associated with this screen.
|
||||
*/
|
||||
private Backend backend;
|
||||
|
||||
/**
|
||||
* Width of the visible window.
|
||||
*/
|
||||
|
@ -1049,7 +1054,7 @@ public class LogicalScreen implements Screen {
|
|||
lastTextHeight = cellHeight;
|
||||
}
|
||||
BufferedImage image = glyphMaker.getImage(cell, cellWidth * 2,
|
||||
cellHeight);
|
||||
cellHeight, backend);
|
||||
BufferedImage leftImage = image.getSubimage(0, 0, cellWidth,
|
||||
cellHeight);
|
||||
BufferedImage rightImage = image.getSubimage(cellWidth, 0, cellWidth,
|
||||
|
@ -1295,4 +1300,22 @@ public class LogicalScreen implements Screen {
|
|||
return other;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the backend to associated with this screen.
|
||||
*
|
||||
* @param backend the backend
|
||||
*/
|
||||
public final void setBackend(final Backend backend) {
|
||||
this.backend = backend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the backend that instantiated this screen.
|
||||
*
|
||||
* @return the backend
|
||||
*/
|
||||
public final Backend getBackend() {
|
||||
return backend;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ package jexer.backend;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import jexer.bits.CellAttributes;
|
||||
import jexer.event.TCommandEvent;
|
||||
import jexer.event.TInputEvent;
|
||||
import static jexer.TCommand.*;
|
||||
|
@ -373,4 +374,26 @@ public class MultiBackend implements Backend {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes foreground color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the AWT Color
|
||||
*/
|
||||
public java.awt.Color attrToForegroundColor(final CellAttributes attr) {
|
||||
// Use Swing colors.
|
||||
return SwingTerminal.attrToForegroundColor(attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes background color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the AWT Color
|
||||
*/
|
||||
public java.awt.Color attrToBackgroundColor(final CellAttributes attr) {
|
||||
// Use Swing colors.
|
||||
return SwingTerminal.attrToBackgroundColor(attr);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,6 +44,11 @@ public class MultiScreen implements Screen {
|
|||
// Variables --------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The backend associated with this screen.
|
||||
*/
|
||||
private Backend backend;
|
||||
|
||||
/**
|
||||
* The list of screens to use.
|
||||
*/
|
||||
|
@ -947,4 +952,22 @@ public class MultiScreen implements Screen {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the backend to associated with this screen.
|
||||
*
|
||||
* @param backend the backend
|
||||
*/
|
||||
public final void setBackend(final Backend backend) {
|
||||
this.backend = backend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the backend that instantiated this screen.
|
||||
*
|
||||
* @return the backend
|
||||
*/
|
||||
public final Backend getBackend() {
|
||||
return backend;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -490,4 +490,11 @@ public interface Screen {
|
|||
*/
|
||||
public Screen snapshot();
|
||||
|
||||
/**
|
||||
* Get the backend that instantiated this screen.
|
||||
*
|
||||
* @return the backend
|
||||
*/
|
||||
public Backend getBackend();
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ package jexer.backend;
|
|||
import java.awt.Font;
|
||||
import javax.swing.JComponent;
|
||||
|
||||
import jexer.bits.CellAttributes;
|
||||
|
||||
/**
|
||||
* This class uses standard Swing calls to handle screen, keyboard, and mouse
|
||||
* I/O.
|
||||
|
@ -98,6 +100,7 @@ public class SwingBackend extends GenericBackend {
|
|||
// Create a Swing backend using a JFrame
|
||||
terminal = new SwingTerminal(this, windowWidth, windowHeight, fontSize,
|
||||
listener);
|
||||
((SwingTerminal) terminal).setBackend(this);
|
||||
|
||||
// Hang onto the session info
|
||||
this.sessionInfo = ((SwingTerminal) terminal).getSessionInfo();
|
||||
|
@ -123,6 +126,7 @@ public class SwingBackend extends GenericBackend {
|
|||
// Create a Swing backend using a JComponent
|
||||
terminal = new SwingTerminal(this, component, windowWidth, windowHeight,
|
||||
fontSize, listener);
|
||||
((SwingTerminal) terminal).setBackend(this);
|
||||
|
||||
// Hang onto the session info
|
||||
this.sessionInfo = ((SwingTerminal) terminal).getSessionInfo();
|
||||
|
@ -209,4 +213,26 @@ public class SwingBackend extends GenericBackend {
|
|||
((SwingTerminal) terminal).setMouseStyle(mouseStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes foreground color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the AWT Color
|
||||
*/
|
||||
public java.awt.Color attrToForegroundColor(final CellAttributes attr) {
|
||||
// Use Swing colors.
|
||||
return SwingTerminal.attrToForegroundColor(attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes background color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the AWT Color
|
||||
*/
|
||||
public java.awt.Color attrToBackgroundColor(final CellAttributes attr) {
|
||||
// Use Swing colors.
|
||||
return SwingTerminal.attrToBackgroundColor(attr);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1173,10 +1173,10 @@ public class SwingTerminal extends LogicalScreen
|
|||
}
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes foreground color to an Swing Color.
|
||||
* Convert a CellAttributes foreground color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the Swing Color
|
||||
* @return the AWT Color
|
||||
*/
|
||||
public static Color attrToForegroundColor(final CellAttributes attr) {
|
||||
int rgb = attr.getForeColorRGB();
|
||||
|
@ -1230,10 +1230,10 @@ public class SwingTerminal extends LogicalScreen
|
|||
}
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes background color to an Swing Color.
|
||||
* Convert a CellAttributes background color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the Swing Color
|
||||
* @return the AWT Color
|
||||
*/
|
||||
public static Color attrToBackgroundColor(final CellAttributes attr) {
|
||||
int rgb = attr.getBackColorRGB();
|
||||
|
|
|
@ -33,6 +33,7 @@ import java.util.List;
|
|||
|
||||
import jexer.TApplication;
|
||||
import jexer.TWindow;
|
||||
import jexer.bits.CellAttributes;
|
||||
import jexer.event.TCommandEvent;
|
||||
import jexer.event.TInputEvent;
|
||||
import jexer.event.TKeypressEvent;
|
||||
|
@ -608,4 +609,24 @@ public class TWindowBackend extends TWindow implements Backend {
|
|||
this.otherApplication = application;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes foreground color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the AWT Color
|
||||
*/
|
||||
public java.awt.Color attrToForegroundColor(final CellAttributes attr) {
|
||||
return getApplication().getBackend().attrToForegroundColor(attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a CellAttributes background color to an AWT Color.
|
||||
*
|
||||
* @param attr the text attributes
|
||||
* @return the AWT Color
|
||||
*/
|
||||
public java.awt.Color attrToBackgroundColor(final CellAttributes attr) {
|
||||
return getApplication().getBackend().attrToBackgroundColor(attr);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
package jexer.bits;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import jexer.backend.Backend;
|
||||
import jexer.backend.GlyphMaker;
|
||||
|
||||
/**
|
||||
|
@ -233,8 +234,10 @@ public class Cell extends CellAttributes {
|
|||
* background color, or generating the glyph and rendering over that.
|
||||
*
|
||||
* @param overGlyph if true, render over the glyph
|
||||
* @param backend the backend that can obtain the correct background
|
||||
* color
|
||||
*/
|
||||
public void flattenImage(final boolean overGlyph) {
|
||||
public void flattenImage(final boolean overGlyph, final Backend backend) {
|
||||
if (!isImage()) {
|
||||
return;
|
||||
}
|
||||
|
@ -252,15 +255,14 @@ public class Cell extends CellAttributes {
|
|||
BufferedImage newImage = new BufferedImage(textWidth,
|
||||
textHeight, BufferedImage.TYPE_INT_ARGB);
|
||||
java.awt.Graphics gr = newImage.getGraphics();
|
||||
gr.setColor(jexer.backend.SwingTerminal.
|
||||
attrToBackgroundColor(this));
|
||||
gr.setColor(backend.attrToBackgroundColor(this));
|
||||
|
||||
if (overGlyph) {
|
||||
// Render this cell to a flat image. The bad news is that we
|
||||
// won't get to use the actual terminal's font.
|
||||
GlyphMaker glyphMaker = GlyphMaker.getInstance(textHeight);
|
||||
gr.drawImage(glyphMaker.getImage(this, textWidth, textHeight),
|
||||
0, 0, null, null);
|
||||
gr.drawImage(glyphMaker.getImage(this, textWidth, textHeight,
|
||||
backend), 0, 0, null, null);
|
||||
} else {
|
||||
// Put the background color behind the pixels.
|
||||
gr.fillRect(0, 0, newImage.getWidth(),
|
||||
|
|
|
@ -267,7 +267,7 @@ public class Tackboard {
|
|||
// Blit this image over that one.
|
||||
BufferedImage oldImage = oldCell.getImage(true);
|
||||
java.awt.Graphics gr = oldImage.getGraphics();
|
||||
gr.setColor(jexer.backend.SwingTerminal.
|
||||
gr.setColor(screen.getBackend().
|
||||
attrToBackgroundColor(oldCell));
|
||||
gr.drawImage(newImage, 0, 0, null, null);
|
||||
gr.dispose();
|
||||
|
@ -279,7 +279,7 @@ public class Tackboard {
|
|||
backImage = new BufferedImage(cellWidth,
|
||||
cellHeight, BufferedImage.TYPE_INT_ARGB);
|
||||
java.awt.Graphics gr = backImage.getGraphics();
|
||||
gr.setColor(jexer.backend.SwingTerminal.
|
||||
gr.setColor(screen.getBackend().
|
||||
attrToBackgroundColor(oldCell));
|
||||
gr.fillRect(0, 0, backImage.getWidth(),
|
||||
backImage.getHeight());
|
||||
|
|
|
@ -5362,12 +5362,17 @@ public class ECMA48 implements Runnable {
|
|||
}
|
||||
|
||||
if (p[0].equals("4")) {
|
||||
for (int i = 1; i + 1 < p.length; i += 2) {
|
||||
// Set a color index value
|
||||
try {
|
||||
set88Color(Integer.parseInt(p[i]), p[i + 1]);
|
||||
} catch (NumberFormatException e) {
|
||||
// SQUASH
|
||||
if (p[1].equals("?")) {
|
||||
// Query a color index value
|
||||
// TODO AZL
|
||||
} else {
|
||||
for (int i = 1; i + 1 < p.length; i += 2) {
|
||||
// Set a color index value
|
||||
try {
|
||||
set88Color(Integer.parseInt(p[i]), p[i + 1]);
|
||||
} catch (NumberFormatException e) {
|
||||
// SQUASH
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5375,8 +5380,9 @@ public class ECMA48 implements Runnable {
|
|||
if (p[0].equals("10")) {
|
||||
if (p[1].equals("?")) {
|
||||
// Respond with foreground color.
|
||||
java.awt.Color color = SwingTerminal.attrToForegroundColor(currentState.attr);
|
||||
|
||||
java.awt.Color color = (backend != null ?
|
||||
backend.attrToForegroundColor(currentState.attr) :
|
||||
SwingTerminal.attrToForegroundColor(currentState.attr));
|
||||
writeRemote(String.format(
|
||||
"\033]10;rgb:%04x/%04x/%04x\033\\",
|
||||
color.getRed() << 8,
|
||||
|
@ -5388,8 +5394,9 @@ public class ECMA48 implements Runnable {
|
|||
if (p[0].equals("11")) {
|
||||
if (p[1].equals("?")) {
|
||||
// Respond with background color.
|
||||
java.awt.Color color = SwingTerminal.attrToBackgroundColor(currentState.attr);
|
||||
|
||||
java.awt.Color color = (backend != null ?
|
||||
backend.attrToBackgroundColor(currentState.attr) :
|
||||
SwingTerminal.attrToBackgroundColor(currentState.attr));
|
||||
writeRemote(String.format(
|
||||
"\033]11;rgb:%04x/%04x/%04x\033\\",
|
||||
color.getRed() << 8,
|
||||
|
@ -7732,7 +7739,7 @@ public class ECMA48 implements Runnable {
|
|||
|
||||
Cell cell = new Cell(ch, currentState.attr);
|
||||
BufferedImage image = glyphMaker.getImage(cell, textWidth * 2,
|
||||
textHeight);
|
||||
textHeight, backend);
|
||||
BufferedImage leftImage = image.getSubimage(0, 0, textWidth,
|
||||
textHeight);
|
||||
BufferedImage rightImage = image.getSubimage(textWidth, 0, textWidth,
|
||||
|
@ -7851,7 +7858,9 @@ public class ECMA48 implements Runnable {
|
|||
}
|
||||
SixelDecoder sixel = new SixelDecoder(sixelParseBuffer.toString(),
|
||||
sixelPalette,
|
||||
SwingTerminal.attrToBackgroundColor(currentState.attr),
|
||||
(backend != null ?
|
||||
backend.attrToBackgroundColor(currentState.attr) :
|
||||
SwingTerminal.attrToBackgroundColor(currentState.attr)),
|
||||
maybeTransparent);
|
||||
BufferedImage image = sixel.getImage();
|
||||
|
||||
|
@ -8244,14 +8253,18 @@ public class ECMA48 implements Runnable {
|
|||
// Scale the image to fit the requested dimensions.
|
||||
image = ImageUtils.scaleImage(image, displayWidth, displayHeight,
|
||||
ImageUtils.Scale.SCALE,
|
||||
SwingTerminal.attrToBackgroundColor(currentState.attr));
|
||||
(backend != null ?
|
||||
backend.attrToBackgroundColor(currentState.attr) :
|
||||
SwingTerminal.attrToBackgroundColor(currentState.attr)));
|
||||
} else if ((displayWidth != fileImageWidth)
|
||||
|| (displayHeight != fileImageHeight)
|
||||
) {
|
||||
// Scale the image to fit the requested dimensions.
|
||||
image = ImageUtils.scaleImage(image, displayWidth, displayHeight,
|
||||
ImageUtils.Scale.STRETCH,
|
||||
SwingTerminal.attrToBackgroundColor(currentState.attr));
|
||||
(backend != null ?
|
||||
backend.attrToBackgroundColor(currentState.attr) :
|
||||
SwingTerminal.attrToBackgroundColor(currentState.attr)));
|
||||
}
|
||||
|
||||
imageToCells(image, !doNotMoveCursor, maybeTransparent);
|
||||
|
@ -8436,7 +8449,7 @@ public class ECMA48 implements Runnable {
|
|||
textHeight, BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
BufferedImage textImage = glyphMaker.getImage(oldCell,
|
||||
textWidth, textHeight);
|
||||
textWidth, textHeight, backend);
|
||||
|
||||
java.awt.Graphics gr = newImage.getGraphics();
|
||||
gr.setColor(java.awt.Color.BLACK);
|
||||
|
|
Loading…
Reference in a new issue