import jexer.bits.Cell;
import jexer.bits.CellAttributes;
import jexer.bits.Color;
+import jexer.bits.StringUtils;
import jexer.event.TCommandEvent;
import jexer.event.TInputEvent;
import jexer.event.TKeypressEvent;
*/
private boolean sixel = true;
+ /**
+ * If true, use a single shared palette for sixel.
+ */
+ private boolean sixelSharedPalette = true;
+
/**
* The sixel palette handler.
*/
*/
private ImageCache jexerCache = null;
- /**
- * Base64 encoder used by iTerm2 and Jexer images.
- */
- private java.util.Base64.Encoder base64 = null;
-
/**
* If true, then we changed System.in and need to change it back.
*/
// Enable mouse reporting and metaSendsEscape
this.output.printf("%s%s", mouse(true), xtermMetaSendsEscape(true));
- this.output.flush();
// Request xterm use the sixel settings we want
this.output.printf("%s", xtermSetSixelSettings());
+ this.output.flush();
+
// Query the screen size
sessionInfo.queryWindowSize();
setDimensions(sessionInfo.getWindowWidth(),
// Enable mouse reporting and metaSendsEscape
this.output.printf("%s%s", mouse(true), xtermMetaSendsEscape(true));
- this.output.flush();
// Request xterm use the sixel settings we want
this.output.printf("%s", xtermSetSixelSettings());
+ this.output.flush();
+
// Query the screen size
sessionInfo.queryWindowSize();
setDimensions(sessionInfo.getWindowWidth(),
// SQUASH
}
+ // Shared palette
+ if (System.getProperty("jexer.ECMA48.sixelSharedPalette",
+ "true").equals("false")) {
+ sixelSharedPalette = false;
+ } else {
+ sixelSharedPalette = true;
+ }
+
// Default to not supporting iTerm2 images.
if (System.getProperty("jexer.ECMA48.iTerm2Images",
"false").equals("true")) {
}
jexerImages = true;
}
+ if (x.equals("1337")) {
+ // Terminal reports iTerm2 images support
+ if (debugToStderr) {
+ System.err.println("Device Attributes: iTerm2 images");
+ }
+ iterm2Images = true;
+ }
}
if (jexerImages == false) {
// Terminal does not support Jexer images, disable
* - enable sixel scrolling
*
* - disable private color registers (so that we can use one common
- * palette)
+ * palette) if sixelSharedPalette is set
*
* @return the string to emit to xterm
*/
private String xtermSetSixelSettings() {
- return "\033[?80h\033[?1070l";
+ if (sixelSharedPalette == true) {
+ return "\033[?80h\033[?1070l";
+ } else {
+ return "\033[?80h\033[?1070h";
+ }
}
/**
if (palette == null) {
palette = new SixelPalette();
- // TODO: make this an option (shared palette or not)
- palette.emitPalette(sb, null);
+ if (sixelSharedPalette == true) {
+ palette.emitPalette(sb, null);
+ }
}
return sb.toString();
if (y == height - 1) {
// We are on the bottom row. If scrolling mode is enabled
// (default), then VT320/xterm will scroll the entire screen if
- // we draw any pixels here.
-
- // TODO: support sixel scrolling mode disabled as an option.
+ // we draw any pixels here. Do not draw the image, bail out
+ // instead.
sb.append(normal());
sb.append(gotoXY(x, y));
for (int j = 0; j < cells.size(); j++) {
// Dither the image. It is ok to lose the original here.
if (palette == null) {
palette = new SixelPalette();
- // TODO: make this an option (shared palette or not)
- palette.emitPalette(sb, null);
+ if (sixelSharedPalette == true) {
+ palette.emitPalette(sb, null);
+ }
}
image = palette.ditherImage(image);
int rasterHeight = 0;
int rasterWidth = image.getWidth();
- /*
-
- // TODO: make this an option (shared palette or not)
-
- // Emit the palette, but only for the colors actually used by these
- // cells.
- boolean [] usedColors = new boolean[sixelPaletteSize];
- for (int imageX = 0; imageX < image.getWidth(); imageX++) {
- for (int imageY = 0; imageY < image.getHeight(); imageY++) {
- usedColors[image.getRGB(imageX, imageY)] = true;
+ if (sixelSharedPalette == false) {
+ // Emit the palette, but only for the colors actually used by
+ // these cells.
+ boolean [] usedColors = new boolean[sixelPaletteSize];
+ for (int imageX = 0; imageX < image.getWidth(); imageX++) {
+ for (int imageY = 0; imageY < image.getHeight(); imageY++) {
+ usedColors[image.getRGB(imageX, imageY)] = true;
+ }
}
+ palette.emitPalette(sb, usedColors);
}
- palette.emitPalette(sb, usedColors);
- */
// Render the entire row of cells.
for (int currentRow = 0; currentRow < fullHeight; currentRow += 6) {
if (iterm2Cache == null) {
iterm2Cache = new ImageCache(height * 10);
- base64 = java.util.Base64.getEncoder();
}
// Save and get rows to/from the cache that do NOT have inverted
return "";
}
- // iTerm2 does not advance the cursor automatically, so place it
- // myself.
sb.append("\033]1337;File=");
/*
sb.append(String.format("width=$d;height=1;preserveAspectRatio=1;",
getTextHeight())));
*/
sb.append("inline=1:");
- sb.append(base64.encodeToString(pngOutputStream.toByteArray()));
+ sb.append(StringUtils.toBase64(pngOutputStream.toByteArray()));
sb.append("\007");
if (saveInCache) {
if (jexerCache == null) {
jexerCache = new ImageCache(height * 10);
- base64 = java.util.Base64.getEncoder();
}
// Save and get rows to/from the cache that do NOT have inverted
}
sb.append("\033]444;1;0;");
- sb.append(base64.encodeToString(pngOutputStream.toByteArray()));
+ sb.append(StringUtils.toBase64(pngOutputStream.toByteArray()));
sb.append("\007");
} else if (jexerImageOption == JexerImageOption.JPG) {
}
sb.append("\033]444;2;0;");
- sb.append(base64.encodeToString(jpgOutputStream.toByteArray()));
+ sb.append(StringUtils.toBase64(jpgOutputStream.toByteArray()));
sb.append("\007");
} else if (jexerImageOption == JexerImageOption.RGB) {
bytes[(py * stride * 3) + (px * 3) + 2] = (byte) ( rgb & 0xFF);
}
}
- sb.append(base64.encodeToString(bytes));
+ sb.append(StringUtils.toBase64(bytes));
sb.append("\007");
}