import java.util.List;
import java.util.ResourceBundle;
+import jexer.backend.ECMA48Terminal;
import jexer.backend.SwingTerminal;
import jexer.bits.CellAttributes;
import jexer.bits.GraphicsChars;
*/
private SwingTerminal terminal = null;
+ /**
+ * The ECMA48 screen.
+ */
+ private ECMA48Terminal ecmaTerminal = null;
+
/**
* The font name.
*/
*/
private TField textAdjustWidth;
+ /**
+ * The sixel palette size.
+ */
+ private TComboBox sixelPaletteSize;
+
/**
* The original font size.
*/
*/
private int oldTextAdjustWidth = 0;
+ /**
+ * The original sixel palette (number of colors) value.
+ */
+ private int oldSixelPaletteSize = 1024;
+
// ------------------------------------------------------------------------
// Constructors -----------------------------------------------------------
// ------------------------------------------------------------------------
public TFontChooserWindow(final TApplication application) {
// Register with the TApplication
- super(application, i18n.getString("windowTitle"), 0, 0, 60, 18, MODAL);
+ super(application, i18n.getString("windowTitle"), 0, 0, 60, 21, MODAL);
// Add shortcut text
newStatusBar(i18n.getString("statusBar"));
if (getScreen() instanceof SwingTerminal) {
terminal = (SwingTerminal) getScreen();
}
+ if (getScreen() instanceof ECMA48Terminal) {
+ ecmaTerminal = (ECMA48Terminal) getScreen();
+ }
addLabel(i18n.getString("fontName"), 1, 1, "ttext", false);
addLabel(i18n.getString("fontSize"), 1, 2, "ttext", false);
addLabel(i18n.getString("textAdjustY"), 1, 5, "ttext", false);
addLabel(i18n.getString("textAdjustHeight"), 1, 6, "ttext", false);
addLabel(i18n.getString("textAdjustWidth"), 1, 7, "ttext", false);
+ addLabel(i18n.getString("sixelPaletteSize"), 1, 9, "ttext", false);
- int col = 18;
+ int col = 21;
if (terminal == null) {
// Non-Swing case: we can't change anything
addLabel(i18n.getString("unavailable"), col, 1);
addLabel(i18n.getString("unavailable"), col, 5);
addLabel(i18n.getString("unavailable"), col, 6);
addLabel(i18n.getString("unavailable"), col, 7);
- } else {
+ }
+ if (ecmaTerminal == null) {
+ addLabel(i18n.getString("unavailable"), col, 9);
+ }
+ if (ecmaTerminal != null) {
+ oldSixelPaletteSize = ecmaTerminal.getSixelPaletteSize();
+
+ String [] sixelSizes = { "2", "256", "512", "1024", "2048" };
+ List<String> sizes = new ArrayList<String>();
+ sizes.addAll(Arrays.asList(sixelSizes));
+ sixelPaletteSize = addComboBox(col, 9, 10, sizes, 0, 6,
+ new TAction() {
+ public void DO() {
+ try {
+ ecmaTerminal.setSixelPaletteSize(Integer.parseInt(
+ sixelPaletteSize.getText()));
+ } catch (NumberFormatException e) {
+ // SQUASH
+ }
+ }
+ }
+ );
+ sixelPaletteSize.setText(Integer.toString(oldSixelPaletteSize));
+ }
+
+ if (terminal != null) {
oldFont = terminal.getFont();
oldFontSize = terminal.getFontSize();
oldTextAdjustX = terminal.getTextAdjustX();
terminal.setTextAdjustHeight(oldTextAdjustHeight);
terminal.setTextAdjustWidth(oldTextAdjustWidth);
}
+ if (ecmaTerminal != null) {
+ ecmaTerminal.setSixelPaletteSize(oldSixelPaletteSize);
+ }
TFontChooserWindow.this.close();
}
});
terminal.setFont(oldFont);
terminal.setFontSize(oldFontSize);
}
+ if (ecmaTerminal != null) {
+ ecmaTerminal.setSixelPaletteSize(oldSixelPaletteSize);
+ }
getApplication().closeWindow(this);
return;
}
MOUSE_SGR,
}
- /**
- * Number of colors in the sixel palette. Xterm 335 defines the max as
- * 1024.
- */
- private static final int MAX_COLOR_REGISTERS = 1024;
- // Black-and-white is possible too.
- // private static final int MAX_COLOR_REGISTERS = 2;
-
// ------------------------------------------------------------------------
// Variables --------------------------------------------------------------
// ------------------------------------------------------------------------
*/
private SixelCache sixelCache = null;
+ /**
+ * Number of colors in the sixel palette. Xterm 335 defines the max as
+ * 1024. Valid values are: 2 (black and white), 256, 512, 1024, and
+ * 2048.
+ */
+ private int sixelPaletteSize = 1024;
+
/**
* If true, then we changed System.in and need to change it back.
*/
/**
* SixelPalette is used to manage the conversion of images between 24-bit
- * RGB color and a palette of MAX_COLOR_REGISTERS colors.
+ * RGB color and a palette of sixelPaletteSize colors.
*/
private class SixelPalette {
* Map of color palette index for sixel output, from the order it was
* generated by makePalette() to rgbColors.
*/
- private int [] rgbSortedIndex = new int[MAX_COLOR_REGISTERS];
+ private int [] rgbSortedIndex = new int[sixelPaletteSize];
/**
* The color palette, organized by hue, saturation, and luminance.
int green = (color >>> 8) & 0xFF;
int blue = color & 0xFF;
- if (MAX_COLOR_REGISTERS == 2) {
+ if (sixelPaletteSize == 2) {
if (((red * red) + (green * green) + (blue * blue)) < 35568) {
// Black
return 0;
((255 - blue) * (255 - blue))) < diff) {
// White is a closer match.
- idx = MAX_COLOR_REGISTERS - 1;
+ idx = sixelPaletteSize - 1;
}
assert (idx != -1);
return idx;
}
/**
- * Dither an image to a MAX_COLOR_REGISTERS palette. The dithered
+ * Dither an image to a sixelPaletteSize palette. The dithered
* image cells will contain indexes into the palette.
*
* @param image the image to dither
imageY) & 0xFFFFFF;
int colorIdx = matchColor(oldPixel);
assert (colorIdx >= 0);
- assert (colorIdx < MAX_COLOR_REGISTERS);
+ assert (colorIdx < sixelPaletteSize);
int newPixel = rgbColors.get(colorIdx);
ditheredImage.setRGB(imageX, imageY, colorIdx);
private void makePalette() {
// Generate the sixel palette. Because we have no idea at this
// layer which image(s) will be shown, we have to use a common
- // palette with MAX_COLOR_REGISTERS colors for everything, and
+ // palette with sixelPaletteSize colors for everything, and
// map the BufferedImage colors to their nearest neighbor in RGB
// space.
- if (MAX_COLOR_REGISTERS == 2) {
+ if (sixelPaletteSize == 2) {
rgbColors.add(0);
rgbColors.add(0xFFFFFF);
rgbSortedIndex[0] = 0;
satBits = 2;
lumBits = 1;
- assert (MAX_COLOR_REGISTERS >= 256);
- assert ((MAX_COLOR_REGISTERS == 256)
- || (MAX_COLOR_REGISTERS == 512)
- || (MAX_COLOR_REGISTERS == 1024)
- || (MAX_COLOR_REGISTERS == 2048));
+ assert (sixelPaletteSize >= 256);
+ assert ((sixelPaletteSize == 256)
+ || (sixelPaletteSize == 512)
+ || (sixelPaletteSize == 1024)
+ || (sixelPaletteSize == 2048));
- switch (MAX_COLOR_REGISTERS) {
+ switch (sixelPaletteSize) {
case 512:
hueBits = 5;
satBits = 2;
}
// System.err.printf("\n</body></html>\n");
- assert (rgbColors.size() == MAX_COLOR_REGISTERS);
+ assert (rgbColors.size() == sixelPaletteSize);
/*
* We need to sort rgbColors, so that toSixel() can know where
Collections.sort(rgbColors);
HashMap<Integer, Integer> rgbColorIndices = null;
rgbColorIndices = new HashMap<Integer, Integer>();
- for (int i = 0; i < MAX_COLOR_REGISTERS; i++) {
+ for (int i = 0; i < sixelPaletteSize; i++) {
rgbColorIndices.put(rgbColors.get(i), i);
}
- for (int i = 0; i < MAX_COLOR_REGISTERS; i++) {
+ for (int i = 0; i < sixelPaletteSize; i++) {
int rawColor = rawRgbList.get(i);
rgbSortedIndex[i] = rgbColorIndices.get(rawColor);
}
if (DEBUG) {
- for (int i = 0; i < MAX_COLOR_REGISTERS; i++) {
+ for (int i = 0; i < sixelPaletteSize; i++) {
assert (rawRgbList != null);
int idx = rgbSortedIndex[i];
int rgbColor = rgbColors.get(idx);
- if ((idx != 0) && (idx != MAX_COLOR_REGISTERS - 1)) {
+ if ((idx != 0) && (idx != sixelPaletteSize - 1)) {
/*
System.err.printf("%d %06x --> %d %06x\n",
i, rawRgbList.get(i), idx, rgbColors.get(idx));
// Set the dimmest color as true black, and the brightest as true
// white.
rgbColors.set(0, 0);
- rgbColors.set(MAX_COLOR_REGISTERS - 1, 0xFFFFFF);
+ rgbColors.set(sixelPaletteSize - 1, 0xFFFFFF);
/*
System.err.printf("<html><body>\n");
public String emitPalette(final StringBuilder sb,
final boolean [] used) {
- for (int i = 0; i < MAX_COLOR_REGISTERS; i++) {
+ for (int i = 0; i < sixelPaletteSize; i++) {
if (((used != null) && (used[i] == true)) || (used == null)) {
int rgbColor = rgbColors.get(i);
sb.append(String.format("#%d;2;%d;%d;%d", i,
} else {
sixel = false;
}
+
+ // Palette size
+ int paletteSize = 1024;
+ try {
+ paletteSize = Integer.parseInt(System.getProperty(
+ "jexer.ECMA48.sixelPaletteSize", "1024"));
+ switch (paletteSize) {
+ case 2:
+ case 256:
+ case 512:
+ case 1024:
+ case 2048:
+ sixelPaletteSize = paletteSize;
+ break;
+ default:
+ // Ignore value
+ break;
+ }
+ } catch (NumberFormatException e) {
+ // SQUASH
+ }
}
// ------------------------------------------------------------------------
// Sixel output support ---------------------------------------------------
// ------------------------------------------------------------------------
+ /**
+ * Get the number of colors in the sixel palette.
+ *
+ * @return the palette size
+ */
+ public int getSixelPaletteSize() {
+ return sixelPaletteSize;
+ }
+
+ /**
+ * Set the number of colors in the sixel palette.
+ *
+ * @param paletteSize the new palette size
+ */
+ public void setSixelPaletteSize(final int paletteSize) {
+ if (paletteSize == sixelPaletteSize) {
+ return;
+ }
+
+ switch (paletteSize) {
+ case 2:
+ case 256:
+ case 512:
+ case 1024:
+ case 2048:
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported sixel palette " +
+ " size: " + paletteSize);
+ }
+
+ // Don't step on the screen refresh thread.
+ synchronized (this) {
+ sixelPaletteSize = paletteSize;
+ palette = null;
+ sixelCache = null;
+ clearPhysical();
+ }
+ }
+
/**
* Start a sixel string for display one row's worth of bitmap data.
*
// Emit the palette, but only for the colors actually used by these
// cells.
- boolean [] usedColors = new boolean[MAX_COLOR_REGISTERS];
+ 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;
int colorIdx = image.getRGB(imageX, imageY + currentRow);
assert (colorIdx >= 0);
- assert (colorIdx < MAX_COLOR_REGISTERS);
+ assert (colorIdx < sixelPaletteSize);
sixels[imageX][imageY] = colorIdx;
}
}
- for (int i = 0; i < MAX_COLOR_REGISTERS; i++) {
+ for (int i = 0; i < sixelPaletteSize; i++) {
boolean isUsed = false;
for (int imageX = 0; imageX < image.getWidth(); imageX++) {
for (int j = 0; j < 6; j++) {
sb.append((char) oldData);
}
- } // for (int i = 0; i < MAX_COLOR_REGISTERS; i++)
+ } // for (int i = 0; i < sixelPaletteSize; i++)
// Advance to the next scan line.
sb.append("-");