mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-30 21:55:31 +02:00
Bug 540737: Add 8 and 24-bit color support to terminal
Change-Id: Iab3b648fb3bfa8f43f333371bd118e90a3a182f2
This commit is contained in:
parent
d6818fbb03
commit
6d4f20edd6
12 changed files with 481 additions and 42 deletions
|
@ -40,9 +40,11 @@ import static org.eclipse.tm.terminal.model.TerminalColor.YELLOW;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.eclipse.swt.events.ControlEvent;
|
||||
import org.eclipse.swt.events.ControlListener;
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.eclipse.tm.internal.terminal.control.impl.ITerminalControlForText;
|
||||
import org.eclipse.tm.internal.terminal.control.impl.TerminalPlugin;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector;
|
||||
|
@ -859,6 +861,19 @@ public class VT100Emulator implements ControlListener {
|
|||
|
||||
while (parameterIndex < totalParameters && ansiParameters[parameterIndex].length() > 0) {
|
||||
int ansiParameter = getAnsiParameter(parameterIndex);
|
||||
if (ansiParameter == 1) {
|
||||
String parameter = ansiParameters[parameterIndex].toString();
|
||||
// Special case for ITU's T.416 foreground/background color specification
|
||||
// which uses : to separate parameters instead of ;
|
||||
if (parameter.startsWith("38:") || parameter.startsWith("48:")) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||
String[] split = parameter.split(":"); //$NON-NLS-1$
|
||||
ProcessExtendedColorsReturn retval = processExtendedColors(split, style, true);
|
||||
style = retval.style();
|
||||
parameterIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch (ansiParameter) {
|
||||
case 0:
|
||||
|
@ -974,6 +989,14 @@ public class VT100Emulator implements ControlListener {
|
|||
style = style.setBackground(text.getDefaultStyle());
|
||||
break;
|
||||
|
||||
case 38: // Foreground color defined by sequence
|
||||
case 48: // Background color defined by sequence
|
||||
CharSequence[] params = Arrays.copyOfRange(ansiParameters, parameterIndex, ansiParameters.length);
|
||||
ProcessExtendedColorsReturn retval = processExtendedColors(params, style, false);
|
||||
parameterIndex += retval.consumed() - 1;
|
||||
style = retval.style();
|
||||
break;
|
||||
|
||||
default:
|
||||
Logger.log("Unsupported graphics rendition parameter: " + ansiParameter); //$NON-NLS-1$
|
||||
break;
|
||||
|
@ -984,6 +1007,110 @@ public class VT100Emulator implements ControlListener {
|
|||
text.setStyle(style);
|
||||
}
|
||||
|
||||
private interface ProcessExtendedColorsReturn {
|
||||
/**
|
||||
* @return the new style
|
||||
*/
|
||||
TerminalStyle style();
|
||||
|
||||
/**
|
||||
* @return number of parameters consumed
|
||||
*/
|
||||
int consumed();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param params array of parameters, starting with 38 or 48 being the command
|
||||
* @param colorspace if a colorspace may be included (ITU T.416 mode)
|
||||
*/
|
||||
private ProcessExtendedColorsReturn processExtendedColors(CharSequence[] paramStrings, TerminalStyle style,
|
||||
boolean colorspace) {
|
||||
int params[] = new int[paramStrings.length];
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
try {
|
||||
int parseInt = Integer.parseInt(paramStrings[i].toString());
|
||||
int inMagnitude = parseInt % 256;
|
||||
int inRange = inMagnitude < 0 ? inMagnitude + 256 : inMagnitude;
|
||||
params[i] = inRange;
|
||||
} catch (NumberFormatException ex) {
|
||||
params[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
boolean foreground = params[0] == 38;
|
||||
int consumed = 1;
|
||||
if (params.length > 1) {
|
||||
int colorDepth = params[1];
|
||||
switch (colorDepth) {
|
||||
case 2: // 24-bit RGB color
|
||||
int r = 0, g = 0, b = 0;
|
||||
if (colorspace) {
|
||||
if (params.length < 6) {
|
||||
Logger.log(
|
||||
"Not enough parameters for 24-bit color depth, expected 5, one for color space and one for each of RGB"); //$NON-NLS-1$
|
||||
}
|
||||
} else {
|
||||
if (params.length < 5) {
|
||||
Logger.log("Not enough parameters for 24-bit color depth, expected 3, one for each of RGB"); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
int start = colorspace ? 3 : 2;
|
||||
if (params.length > start + 0) {
|
||||
r = params[start + 0];
|
||||
}
|
||||
if (params.length > start + 1) {
|
||||
g = params[start + 1];
|
||||
}
|
||||
if (params.length > start + 2) {
|
||||
b = params[start + 2];
|
||||
}
|
||||
|
||||
RGB rgb = new RGB(r, g, b);
|
||||
if (foreground) {
|
||||
style = style.setForeground(rgb);
|
||||
} else {
|
||||
style = style.setBackground(rgb);
|
||||
}
|
||||
consumed = Math.min(6, params.length);
|
||||
break;
|
||||
case 5: // 8-bit color table lookup
|
||||
int index = 0;
|
||||
if (params.length < 3) {
|
||||
Logger.log("Missing parameter for 8-bit color depth"); //$NON-NLS-1$
|
||||
} else {
|
||||
index = params[2];
|
||||
}
|
||||
if (foreground) {
|
||||
style = style.setForeground(index);
|
||||
} else {
|
||||
style = style.setBackground(index);
|
||||
}
|
||||
consumed = Math.min(3, params.length);
|
||||
break;
|
||||
default:
|
||||
Logger.log("Unsupported color depth " + colorDepth + " for: " + params[0]); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
|
||||
} else {
|
||||
Logger.log("Missing color depth for " + params[0]); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
TerminalStyle finalStyle = style;
|
||||
int finalConsumed = consumed;
|
||||
return new ProcessExtendedColorsReturn() {
|
||||
@Override
|
||||
public TerminalStyle style() {
|
||||
return finalStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int consumed() {
|
||||
return finalConsumed;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This method responds to an ANSI Device Status Report (DSR) command from
|
||||
* the remote endpoint requesting the ready status or the cursor position.
|
||||
|
@ -1096,7 +1223,7 @@ public class VT100Emulator implements ControlListener {
|
|||
* most recent escape sequence.
|
||||
*
|
||||
* @return The <i>parameterIndex</i>th numeric ANSI parameter or -1 if the
|
||||
* index is out of range.
|
||||
* index is out of range or 1 if parse failed (1 is also a legitimate value)
|
||||
*/
|
||||
private int getAnsiParameter(int parameterIndex) {
|
||||
if (parameterIndex < 0 || parameterIndex >= ansiParameters.length) {
|
||||
|
@ -1109,6 +1236,7 @@ public class VT100Emulator implements ControlListener {
|
|||
if (parameter.length() == 0)
|
||||
return 1;
|
||||
|
||||
// return 1 on failed parseInt
|
||||
int parameterValue = 1;
|
||||
|
||||
// Don't trust the remote endpoint to send well formed numeric
|
||||
|
|
|
@ -74,6 +74,16 @@ public class StyleMap {
|
|||
|
||||
public RGB getForegrondRGB(TerminalStyle style) {
|
||||
style = defaultIfNull(style);
|
||||
RGB foregroundRGB;
|
||||
if (style.isReverse()) {
|
||||
foregroundRGB = style.getBackgroundRGB();
|
||||
} else {
|
||||
foregroundRGB = style.getForegroundRGB();
|
||||
}
|
||||
if (foregroundRGB != null) {
|
||||
return foregroundRGB;
|
||||
}
|
||||
|
||||
TerminalColor color;
|
||||
if (style.isReverse()) {
|
||||
color = style.getBackgroundTerminalColor();
|
||||
|
@ -91,6 +101,16 @@ public class StyleMap {
|
|||
|
||||
public RGB getBackgroundRGB(TerminalStyle style) {
|
||||
style = defaultIfNull(style);
|
||||
RGB backgroundRGB;
|
||||
if (style.isReverse()) {
|
||||
backgroundRGB = style.getForegroundRGB();
|
||||
} else {
|
||||
backgroundRGB = style.getBackgroundRGB();
|
||||
}
|
||||
if (backgroundRGB != null) {
|
||||
return backgroundRGB;
|
||||
}
|
||||
|
||||
TerminalColor color;
|
||||
if (style.isReverse()) {
|
||||
color = style.getForegroundTerminalColor();
|
||||
|
|
|
@ -20,6 +20,15 @@ import org.eclipse.swt.widgets.Display;
|
|||
* the colors with well known names defined by the ANSI Escape Sequences, plus other colors needed
|
||||
* to render a display (such as Background color).
|
||||
*
|
||||
* Rather than name all the colors when using ANSI 8-bit indexed colors, the indexed colors
|
||||
* can be accessed via the {@link #getIndexedRGBColor(int)} or {@link #getIndexedRGBColor(int)}
|
||||
* (use {@link #isIndexedTerminalColor(int)} to determine which one is appropriate.
|
||||
*
|
||||
* The {@link TerminalStyle} supports any arbitrary color by using {@link RGB} defined colors.
|
||||
* This class provides the connection between the names exposed to the user in preferences
|
||||
* and their use in the terminal, along with how colors change when other attributes (such as
|
||||
* bright and invertColors) are applied to them.
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public enum TerminalColor {
|
||||
|
@ -158,11 +167,37 @@ public enum TerminalColor {
|
|||
}
|
||||
|
||||
/**
|
||||
* FOR TEST ONLY.
|
||||
* Query for whether the 8-bit color index will return a named color, in which case
|
||||
* {@link #getIndexedTerminalColor(int)} must be called to get the named color. Use
|
||||
* {@link #convertColor(boolean, boolean)} if this method returns false.
|
||||
*
|
||||
* @noreference This enum method is not intended to be referenced by clients.
|
||||
* @param index 8-bit index.
|
||||
* @return true for named colors, false for RGB colors
|
||||
*/
|
||||
public static TerminalColor getForTest(int c) {
|
||||
return TerminalColor.values()[c % TerminalColor.values().length];
|
||||
public static boolean isIndexedTerminalColor(int index) {
|
||||
Assert.isLegal(index >= 0 && index < 256, "Invalid 8-bit table index out of range 0-255"); //$NON-NLS-1$
|
||||
return index < table8bitIndexedTerminalColors.length && index >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the named color for the given 8-bit index.
|
||||
*
|
||||
* @param index 8-bit index in 0-15 range.
|
||||
* @return named color
|
||||
*/
|
||||
public static TerminalColor getIndexedTerminalColor(int index) {
|
||||
Assert.isLegal(isIndexedTerminalColor(index), "Invalid table index used for ANSI Color"); //$NON-NLS-1$
|
||||
return table8bitIndexedTerminalColors[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the RGB color for the given 8-bit index.
|
||||
*
|
||||
* @param index 8-bit index in 16-255 range.
|
||||
* @return RGB color
|
||||
*/
|
||||
public static RGB getIndexedRGBColor(int index) {
|
||||
Assert.isLegal(index >= 16 && index < 256, "Invalid table index used for RGB Color"); //$NON-NLS-1$
|
||||
return table8bitIndexedRGB[index - 16];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ import java.util.Collections;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.core.runtime.Assert;
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
import org.eclipse.tm.internal.terminal.control.impl.TerminalPlugin;
|
||||
import org.eclipse.tm.internal.terminal.provisional.api.Logger;
|
||||
|
||||
|
@ -29,6 +31,8 @@ import org.eclipse.tm.internal.terminal.provisional.api.Logger;
|
|||
public class TerminalStyle {
|
||||
private final TerminalColor fForegroundTerminalColor;
|
||||
private final TerminalColor fBackgroundTerminalColor;
|
||||
private final RGB fForegroundRGB;
|
||||
private final RGB fBackgroundRGB;
|
||||
private final boolean fBold;
|
||||
private final boolean fBlink;
|
||||
private final boolean fUnderline;
|
||||
|
@ -50,10 +54,16 @@ public class TerminalStyle {
|
|||
}
|
||||
});
|
||||
|
||||
private TerminalStyle(TerminalColor foregroundTerminalColor, TerminalColor backgroundTerminalColor, boolean bold,
|
||||
boolean blink, boolean underline, boolean reverse) {
|
||||
private TerminalStyle(TerminalColor foregroundTerminalColor, TerminalColor backgroundTerminalColor,
|
||||
RGB foregroundRGB, RGB backgroundRGB, boolean bold, boolean blink, boolean underline, boolean reverse) {
|
||||
Assert.isLegal(foregroundTerminalColor == null || foregroundRGB == null,
|
||||
"Only one of ANSI or RGB colors can be specified as a foreground color"); //$NON-NLS-1$
|
||||
Assert.isLegal(backgroundTerminalColor == null || backgroundRGB == null,
|
||||
"Only one of ANSI or RGB colors can be specified as a background color"); //$NON-NLS-1$
|
||||
fForegroundTerminalColor = foregroundTerminalColor;
|
||||
fBackgroundTerminalColor = backgroundTerminalColor;
|
||||
fForegroundRGB = foregroundRGB;
|
||||
fBackgroundRGB = backgroundRGB;
|
||||
fBold = bold;
|
||||
fBlink = blink;
|
||||
fUnderline = underline;
|
||||
|
@ -61,51 +71,105 @@ public class TerminalStyle {
|
|||
}
|
||||
|
||||
public static TerminalStyle getStyle(TerminalColor foregroundTerminalColor, TerminalColor backgroundTerminalColor,
|
||||
boolean bold, boolean blink, boolean underline, boolean reverse) {
|
||||
TerminalStyle style = new TerminalStyle(foregroundTerminalColor, backgroundTerminalColor, bold, blink,
|
||||
underline, reverse);
|
||||
RGB foregroundRGB, RGB backgroundRGB, boolean bold, boolean blink, boolean underline, boolean reverse) {
|
||||
TerminalStyle style = new TerminalStyle(foregroundTerminalColor, backgroundTerminalColor, foregroundRGB,
|
||||
backgroundRGB, bold, blink, underline, reverse);
|
||||
// If set had a computeIfAbsent we would use a set, instead just store 1-2-1 mapping
|
||||
return fgStyles.computeIfAbsent(style, (s) -> style);
|
||||
}
|
||||
|
||||
public static TerminalStyle getStyle(TerminalColor foregroundTerminalColor, TerminalColor backgroundTerminalColor,
|
||||
boolean bold, boolean blink, boolean underline, boolean reverse) {
|
||||
return getStyle(foregroundTerminalColor, backgroundTerminalColor, null, null, bold, blink, underline, reverse);
|
||||
}
|
||||
|
||||
public static TerminalStyle getStyle(RGB foregroundRGB, RGB backgroundRGB, boolean bold, boolean blink,
|
||||
boolean underline, boolean reverse) {
|
||||
return getStyle(null, null, foregroundRGB, backgroundRGB, bold, blink, underline, reverse);
|
||||
}
|
||||
|
||||
public static TerminalStyle getDefaultStyle() {
|
||||
return getStyle(TerminalColor.FOREGROUND, TerminalColor.BACKGROUND);
|
||||
}
|
||||
|
||||
public static TerminalStyle getStyle(TerminalColor foregroundTerminalColor, TerminalColor backgroundTerminalColor) {
|
||||
return getStyle(foregroundTerminalColor, backgroundTerminalColor, false, false, false, false);
|
||||
return getStyle(foregroundTerminalColor, backgroundTerminalColor, null, null, false, false, false, false);
|
||||
}
|
||||
|
||||
public TerminalStyle setForeground(TerminalColor foregroundTerminalColor) {
|
||||
return getStyle(foregroundTerminalColor, fBackgroundTerminalColor, fBold, fBlink, fUnderline, fReverse);
|
||||
return getStyle(foregroundTerminalColor, fBackgroundTerminalColor, null, fBackgroundRGB, fBold, fBlink,
|
||||
fUnderline, fReverse);
|
||||
}
|
||||
|
||||
public TerminalStyle setBackground(TerminalColor backgroundTerminalColor) {
|
||||
return getStyle(fForegroundTerminalColor, backgroundTerminalColor, fBold, fBlink, fUnderline, fReverse);
|
||||
return getStyle(fForegroundTerminalColor, backgroundTerminalColor, fForegroundRGB, null, fBold, fBlink,
|
||||
fUnderline, fReverse);
|
||||
}
|
||||
|
||||
public TerminalStyle setForeground(RGB foregroundRGB) {
|
||||
return getStyle(null, fBackgroundTerminalColor, foregroundRGB, fBackgroundRGB, fBold, fBlink, fUnderline,
|
||||
fReverse);
|
||||
}
|
||||
|
||||
public TerminalStyle setBackground(RGB backgroundRGB) {
|
||||
return getStyle(fForegroundTerminalColor, null, fForegroundRGB, backgroundRGB, fBold, fBlink, fUnderline,
|
||||
fReverse);
|
||||
}
|
||||
|
||||
public TerminalStyle setForeground(TerminalStyle other) {
|
||||
return getStyle(other.fForegroundTerminalColor, fBackgroundTerminalColor, fBold, fBlink, fUnderline, fReverse);
|
||||
return getStyle(other.fForegroundTerminalColor, fBackgroundTerminalColor, other.fForegroundRGB, fBackgroundRGB,
|
||||
fBold, fBlink, fUnderline, fReverse);
|
||||
}
|
||||
|
||||
public TerminalStyle setBackground(TerminalStyle other) {
|
||||
return getStyle(fForegroundTerminalColor, other.fBackgroundTerminalColor, fBold, fBlink, fUnderline, fReverse);
|
||||
return getStyle(fForegroundTerminalColor, other.fBackgroundTerminalColor, fForegroundRGB, other.fBackgroundRGB,
|
||||
fBold, fBlink, fUnderline, fReverse);
|
||||
}
|
||||
|
||||
public TerminalStyle setForeground(int eightBitindexedColor) {
|
||||
boolean isIndexTerminalColor = TerminalColor.isIndexedTerminalColor(eightBitindexedColor);
|
||||
if (isIndexTerminalColor) {
|
||||
TerminalColor foregroundTerminalColor = TerminalColor.getIndexedTerminalColor(eightBitindexedColor);
|
||||
return getStyle(foregroundTerminalColor, fBackgroundTerminalColor, null, fBackgroundRGB, fBold, fBlink,
|
||||
fUnderline, fReverse);
|
||||
} else {
|
||||
RGB foregroundRGB = TerminalColor.getIndexedRGBColor(eightBitindexedColor);
|
||||
return getStyle(null, fBackgroundTerminalColor, foregroundRGB, fBackgroundRGB, fBold, fBlink, fUnderline,
|
||||
fReverse);
|
||||
}
|
||||
}
|
||||
|
||||
public TerminalStyle setBackground(int eightBitindexedColor) {
|
||||
boolean isIndexTerminalColor = TerminalColor.isIndexedTerminalColor(eightBitindexedColor);
|
||||
if (isIndexTerminalColor) {
|
||||
TerminalColor backgroundTerminalColor = TerminalColor.getIndexedTerminalColor(eightBitindexedColor);
|
||||
return getStyle(fForegroundTerminalColor, backgroundTerminalColor, fForegroundRGB, null, fBold, fBlink,
|
||||
fUnderline, fReverse);
|
||||
} else {
|
||||
RGB backgroundRGB = TerminalColor.getIndexedRGBColor(eightBitindexedColor);
|
||||
return getStyle(fForegroundTerminalColor, null, fForegroundRGB, backgroundRGB, fBold, fBlink, fUnderline,
|
||||
fReverse);
|
||||
}
|
||||
}
|
||||
|
||||
public TerminalStyle setBold(boolean bold) {
|
||||
return getStyle(fForegroundTerminalColor, fBackgroundTerminalColor, bold, fBlink, fUnderline, fReverse);
|
||||
return getStyle(fForegroundTerminalColor, fBackgroundTerminalColor, fForegroundRGB, fBackgroundRGB, bold,
|
||||
fBlink, fUnderline, fReverse);
|
||||
}
|
||||
|
||||
public TerminalStyle setBlink(boolean blink) {
|
||||
return getStyle(fForegroundTerminalColor, fBackgroundTerminalColor, fBold, blink, fUnderline, fReverse);
|
||||
return getStyle(fForegroundTerminalColor, fBackgroundTerminalColor, fForegroundRGB, fBackgroundRGB, fBold,
|
||||
blink, fUnderline, fReverse);
|
||||
}
|
||||
|
||||
public TerminalStyle setUnderline(boolean underline) {
|
||||
return getStyle(fForegroundTerminalColor, fBackgroundTerminalColor, fBold, fBlink, underline, fReverse);
|
||||
return getStyle(fForegroundTerminalColor, fBackgroundTerminalColor, fForegroundRGB, fBackgroundRGB, fBold,
|
||||
fBlink, underline, fReverse);
|
||||
}
|
||||
|
||||
public TerminalStyle setReverse(boolean reverse) {
|
||||
return getStyle(fForegroundTerminalColor, fBackgroundTerminalColor, fBold, fBlink, fUnderline, reverse);
|
||||
return getStyle(fForegroundTerminalColor, fBackgroundTerminalColor, fForegroundRGB, fBackgroundRGB, fBold,
|
||||
fBlink, fUnderline, reverse);
|
||||
}
|
||||
|
||||
public TerminalColor getForegroundTerminalColor() {
|
||||
|
@ -116,6 +180,14 @@ public class TerminalStyle {
|
|||
return fBackgroundTerminalColor;
|
||||
}
|
||||
|
||||
public RGB getForegroundRGB() {
|
||||
return fForegroundRGB;
|
||||
}
|
||||
|
||||
public RGB getBackgroundRGB() {
|
||||
return fBackgroundRGB;
|
||||
}
|
||||
|
||||
public boolean isBlink() {
|
||||
return fBlink;
|
||||
}
|
||||
|
@ -137,9 +209,11 @@ public class TerminalStyle {
|
|||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((fBackgroundTerminalColor == null) ? 0 : fBackgroundTerminalColor.hashCode());
|
||||
result = prime * result + ((fBackgroundRGB == null) ? 0 : fBackgroundRGB.hashCode());
|
||||
result = prime * result + (fBlink ? 1231 : 1237);
|
||||
result = prime * result + (fBold ? 1231 : 1237);
|
||||
result = prime * result + ((fForegroundTerminalColor == null) ? 0 : fForegroundTerminalColor.hashCode());
|
||||
result = prime * result + ((fForegroundRGB == null) ? 0 : fForegroundRGB.hashCode());
|
||||
result = prime * result + (fReverse ? 1231 : 1237);
|
||||
result = prime * result + (fUnderline ? 1231 : 1237);
|
||||
return result;
|
||||
|
@ -156,12 +230,22 @@ public class TerminalStyle {
|
|||
TerminalStyle other = (TerminalStyle) obj;
|
||||
if (fBackgroundTerminalColor != other.fBackgroundTerminalColor)
|
||||
return false;
|
||||
if (fBackgroundRGB == null) {
|
||||
if (other.fBackgroundRGB != null)
|
||||
return false;
|
||||
} else if (!fBackgroundRGB.equals(other.fBackgroundRGB))
|
||||
return false;
|
||||
if (fBlink != other.fBlink)
|
||||
return false;
|
||||
if (fBold != other.fBold)
|
||||
return false;
|
||||
if (fForegroundTerminalColor != other.fForegroundTerminalColor)
|
||||
return false;
|
||||
if (fForegroundRGB == null) {
|
||||
if (other.fForegroundRGB != null)
|
||||
return false;
|
||||
} else if (!fForegroundRGB.equals(other.fForegroundRGB))
|
||||
return false;
|
||||
if (fReverse != other.fReverse)
|
||||
return false;
|
||||
if (fUnderline != other.fUnderline)
|
||||
|
@ -173,9 +257,17 @@ public class TerminalStyle {
|
|||
public String toString() {
|
||||
StringBuffer result = new StringBuffer();
|
||||
result.append("Style(foreground="); //$NON-NLS-1$
|
||||
result.append(fForegroundTerminalColor);
|
||||
if (fForegroundTerminalColor != null) {
|
||||
result.append(fForegroundTerminalColor);
|
||||
} else {
|
||||
result.append(fForegroundRGB);
|
||||
}
|
||||
result.append(", background="); //$NON-NLS-1$
|
||||
result.append(fBackgroundTerminalColor);
|
||||
if (fForegroundTerminalColor != null) {
|
||||
result.append(fBackgroundTerminalColor);
|
||||
} else {
|
||||
result.append(fBackgroundRGB);
|
||||
}
|
||||
if (fBlink)
|
||||
result.append(", blink"); //$NON-NLS-1$
|
||||
if (fBold)
|
||||
|
|
|
@ -14,7 +14,6 @@ package org.eclipse.tm.internal.terminal.model;
|
|||
import org.eclipse.tm.terminal.model.ITerminalTextData;
|
||||
import org.eclipse.tm.terminal.model.ITerminalTextDataReadOnly;
|
||||
import org.eclipse.tm.terminal.model.LineSegment;
|
||||
import org.eclipse.tm.terminal.model.TerminalColor;
|
||||
import org.eclipse.tm.terminal.model.TerminalStyle;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
@ -338,13 +337,13 @@ abstract public class AbstractITerminalTextDataTest extends TestCase {
|
|||
for (int line = 0; line < term.getHeight(); line++) {
|
||||
for (int column = 0; column < term.getWidth(); column++) {
|
||||
char c = (char) ('a' + column + line);
|
||||
term.setChar(line, column, c, style.setForeground(TerminalColor.getForTest(c)));
|
||||
term.setChar(line, column, c, style.setForeground(c));
|
||||
}
|
||||
}
|
||||
for (int line = 0; line < term.getHeight(); line++) {
|
||||
for (int column = 0; column < term.getWidth(); column++) {
|
||||
char c = (char) ('a' + column + line);
|
||||
assertSame(style.setForeground(TerminalColor.getForTest(c)), term.getStyle(line, column));
|
||||
assertSame(style.setForeground(c), term.getStyle(line, column));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ package org.eclipse.tm.internal.terminal.model;
|
|||
import org.eclipse.tm.terminal.model.ITerminalTextData;
|
||||
import org.eclipse.tm.terminal.model.ITerminalTextDataReadOnly;
|
||||
import org.eclipse.tm.terminal.model.ITerminalTextDataSnapshot;
|
||||
import org.eclipse.tm.terminal.model.TerminalColor;
|
||||
import org.eclipse.tm.terminal.model.TerminalStyle;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
@ -322,7 +321,7 @@ public class TerminalTextDataSnapshotTest extends TestCase {
|
|||
for (int line = 0; line < term.getHeight(); line++) {
|
||||
for (int column = 0; column < term.getWidth(); column++) {
|
||||
char c = (char) ('a' + column + line);
|
||||
term.setChar(line, column, c, style.setForeground(TerminalColor.getForTest(c)));
|
||||
term.setChar(line, column, c, style.setForeground(c));
|
||||
}
|
||||
}
|
||||
ITerminalTextDataSnapshot snapshot = term.makeSnapshot();
|
||||
|
@ -331,7 +330,7 @@ public class TerminalTextDataSnapshotTest extends TestCase {
|
|||
for (int line = 0; line < term.getHeight(); line++) {
|
||||
for (int column = 0; column < term.getWidth(); column++) {
|
||||
char c = (char) ('a' + column + line);
|
||||
assertSame(style.setForeground(TerminalColor.getForTest(c)), snapshot.getStyle(line, column));
|
||||
assertSame(style.setForeground(c), snapshot.getStyle(line, column));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ import java.util.ArrayList;
|
|||
|
||||
import org.eclipse.tm.terminal.model.ITerminalTextData;
|
||||
import org.eclipse.tm.terminal.model.LineSegment;
|
||||
import org.eclipse.tm.terminal.model.TerminalColor;
|
||||
import org.eclipse.tm.terminal.model.TerminalStyle;
|
||||
|
||||
public class TerminalTextDataWindowTest extends AbstractITerminalTextDataTest {
|
||||
|
@ -214,7 +213,7 @@ public class TerminalTextDataWindowTest extends AbstractITerminalTextDataTest {
|
|||
for (int line = 0; line < term.getHeight(); line++) {
|
||||
for (int column = 0; column < term.getWidth(); column++) {
|
||||
char c = (char) ('a' + column + line);
|
||||
term.setChar(line, column, c, style.setForeground(TerminalColor.getForTest(c)));
|
||||
term.setChar(line, column, c, style.setForeground(c));
|
||||
}
|
||||
}
|
||||
for (int line = 0; line < term.getHeight(); line++) {
|
||||
|
@ -222,7 +221,7 @@ public class TerminalTextDataWindowTest extends AbstractITerminalTextDataTest {
|
|||
char c = (char) ('a' + column + line);
|
||||
TerminalStyle s = null;
|
||||
if (line >= fOffset && line < fOffset + fSize)
|
||||
s = style.setForeground(TerminalColor.getForTest(c));
|
||||
s = style.setForeground(c);
|
||||
assertSame(s, term.getStyle(line, column));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ package org.eclipse.tm.internal.terminal.model;
|
|||
|
||||
import org.eclipse.tm.terminal.model.ITerminalTextData;
|
||||
import org.eclipse.tm.terminal.model.ITerminalTextDataReadOnly;
|
||||
import org.eclipse.tm.terminal.model.TerminalColor;
|
||||
import org.eclipse.tm.terminal.model.TerminalStyle;
|
||||
|
||||
public class TerminalTextTestHelper {
|
||||
|
@ -66,7 +65,7 @@ public class TerminalTextTestHelper {
|
|||
term.setDimensions(s.length(), 1);
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
term.setChar(i, 0, c, style.setForeground(TerminalColor.getForTest(c)));
|
||||
term.setChar(i, 0, c, style.setForeground(c));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,7 +104,7 @@ public class TerminalTextTestHelper {
|
|||
yy++;
|
||||
xx = column;
|
||||
} else {
|
||||
term.setChar(yy, xx, c, style.setForeground(TerminalColor.getForTest(c)));
|
||||
term.setChar(yy, xx, c, style.setForeground(c));
|
||||
xx++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,6 +97,8 @@ public class TerminalTextUITest {
|
|||
addDataReader(composite, reader);
|
||||
reader = new DataReader("Fast", fTerminalModel, new FastDataSource(), status);
|
||||
addDataReader(composite, reader);
|
||||
reader = new DataReader("Colors", fTerminalModel, new VT100DataSource(), status);
|
||||
addDataReader(composite, reader);
|
||||
reader = new DataReader("Random", fTerminalModel, new RandomDataSource(), status);
|
||||
addDataReader(composite, reader);
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.tm.internal.terminal.test.ui;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -40,18 +41,111 @@ final class VT100DataSource implements IDataSource {
|
|||
volatile int fAvailable;
|
||||
volatile int fRead;
|
||||
private final String fFile;
|
||||
private final String fANSIEscapeColors;
|
||||
|
||||
VT100DataSource(String file) {
|
||||
fFile = file;
|
||||
fANSIEscapeColors = null;
|
||||
}
|
||||
|
||||
VT100DataSource() {
|
||||
fFile = null;
|
||||
StringBuffer input = new StringBuffer();
|
||||
input.append(" 8-bit ");
|
||||
for (int i = 0; i < 255; i++) {
|
||||
input.append("\033[38:5:");
|
||||
input.append(i);
|
||||
input.append("m");
|
||||
input.append(String.format(" %3s ", i));
|
||||
input.append("\033[0m");
|
||||
if ((i + 1) % 6 == 4) {
|
||||
input.append("\n");
|
||||
}
|
||||
}
|
||||
input.append("\n");
|
||||
input.append(" 8-bit ");
|
||||
for (int i = 0; i < 255; i++) {
|
||||
input.append("\033[48:5:");
|
||||
input.append(i);
|
||||
input.append("m");
|
||||
input.append(String.format(" %3s ", i));
|
||||
input.append("\033[0m");
|
||||
if ((i + 1) % 6 == 4) {
|
||||
input.append("\n");
|
||||
}
|
||||
}
|
||||
input.append("\n");
|
||||
|
||||
input.append("\n");
|
||||
input.append(" 24-bit (RGB incremented by 15)");
|
||||
int count = 0;
|
||||
for (int r = 0; r < 255; r += 15) {
|
||||
for (int g = 0; g < 255; g += 15) {
|
||||
count = 0;
|
||||
for (int b = 0; b < 255; b += 15) {
|
||||
if (count++ % 5 == 0) {
|
||||
input.append("\n");
|
||||
}
|
||||
input.append("\033[38:2:3:");
|
||||
input.append(r);
|
||||
input.append(":");
|
||||
input.append(g);
|
||||
input.append(":");
|
||||
input.append(b);
|
||||
input.append(":");
|
||||
input.append("m");
|
||||
input.append(String.format(" (%02x%02x%02x) ", r, g, b));
|
||||
input.append("\033[0m");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
input.append("\n");
|
||||
input.append(" 24-bit (RGB incremented by 15)");
|
||||
count = 0;
|
||||
for (int r = 0; r < 255; r += 15) {
|
||||
for (int g = 0; g < 255; g += 15) {
|
||||
count = 0;
|
||||
for (int b = 0; b < 255; b += 15) {
|
||||
if (count++ % 5 == 0) {
|
||||
input.append("\n");
|
||||
}
|
||||
input.append("\033[48:2:3:");
|
||||
input.append(r);
|
||||
input.append(":");
|
||||
input.append(g);
|
||||
input.append(":");
|
||||
input.append(b);
|
||||
input.append(":");
|
||||
input.append("m");
|
||||
input.append(String.format(" (%02x%02x%02x) ", r, g, b));
|
||||
input.append("\033[0m");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input.append("\n");
|
||||
|
||||
fANSIEscapeColors = input.toString();
|
||||
}
|
||||
|
||||
class InfiniteFileInputStream extends InputStream {
|
||||
public InfiniteFileInputStream() {
|
||||
try {
|
||||
fInputStream = new FileInputStream(fFile);
|
||||
} catch (FileNotFoundException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
startInputStream();
|
||||
|
||||
}
|
||||
|
||||
private void startInputStream() {
|
||||
if (fFile == null) {
|
||||
fInputStream = new ByteArrayInputStream(fANSIEscapeColors.getBytes(StandardCharsets.ISO_8859_1));
|
||||
} else {
|
||||
try {
|
||||
fInputStream = new FileInputStream(fFile);
|
||||
} catch (FileNotFoundException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,7 +174,7 @@ final class VT100DataSource implements IDataSource {
|
|||
int n = fInputStream.read(b, off, len);
|
||||
if (n <= 0) {
|
||||
fInputStream.close();
|
||||
fInputStream = new FileInputStream(fFile);
|
||||
startInputStream();
|
||||
n = fInputStream.read(b, off, len);
|
||||
}
|
||||
fAvailable -= n;
|
||||
|
|
|
@ -13,9 +13,9 @@ package org.eclipse.tm.terminal.model;
|
|||
import junit.framework.TestCase;
|
||||
|
||||
public class StyleTest extends TestCase {
|
||||
final TerminalColor c1 = TerminalColor.getForTest(1);
|
||||
final TerminalColor c2 = TerminalColor.getForTest(2);
|
||||
final TerminalColor c3 = TerminalColor.getForTest(3);
|
||||
final TerminalColor c1 = TerminalColor.getIndexedTerminalColor(1);
|
||||
final TerminalColor c2 = TerminalColor.getIndexedTerminalColor(2);
|
||||
final TerminalColor c3 = TerminalColor.getIndexedTerminalColor(3);
|
||||
|
||||
public void testGetStyle() {
|
||||
TerminalStyle s1 = TerminalStyle.getStyle(c1, c2, true, false, true, false);
|
||||
|
|
|
@ -17,6 +17,7 @@ import static org.eclipse.tm.terminal.model.TerminalColor.WHITE;
|
|||
import static org.eclipse.tm.terminal.model.TerminalColor.YELLOW;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.junit.AfterClass;
|
||||
|
@ -79,4 +80,75 @@ public class TerminalColorUITest {
|
|||
assertEquals(WHITE.convertColor(false, true), BLACK.convertColor(true, true));
|
||||
assertNotEquals(WHITE.convertColor(false, true), BLACK.convertColor(false, true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexesResolveToStandardColors() {
|
||||
// check explicit colors
|
||||
assertEquals(TerminalColor.BLACK.convertColor(false, false),
|
||||
TerminalColor.getIndexedTerminalColor(0).convertColor(false, false));
|
||||
assertEquals(TerminalColor.RED.convertColor(false, false),
|
||||
TerminalColor.getIndexedTerminalColor(1).convertColor(false, false));
|
||||
|
||||
// Now check all colors
|
||||
for (int i = 0; i < 8; i++) {
|
||||
assertEquals(TerminalColor.values()[i].convertColor(false, false),
|
||||
TerminalColor.getIndexedTerminalColor(i).convertColor(false, false));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexesResolveToBrightColors() {
|
||||
// check explicit colors
|
||||
assertEquals(TerminalColor.BLACK.convertColor(false, true),
|
||||
TerminalColor.getIndexedTerminalColor(8).convertColor(false, false));
|
||||
assertEquals(TerminalColor.RED.convertColor(false, true),
|
||||
TerminalColor.getIndexedTerminalColor(9).convertColor(false, false));
|
||||
|
||||
// Now check all colors
|
||||
for (int i = 0; i < 8; i++) {
|
||||
assertEquals(TerminalColor.values()[i].convertColor(false, true),
|
||||
TerminalColor.getIndexedTerminalColor(i + 8).convertColor(false, false));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexesInRange() {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
assertNotNull(TerminalColor.getIndexedTerminalColor(i));
|
||||
}
|
||||
for (int i = 16; i < 256; i++) {
|
||||
assertNotNull(TerminalColor.getIndexedRGBColor(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testIndexesOutOfRange_m1TerminalColor() {
|
||||
assertNotNull(TerminalColor.getIndexedTerminalColor(-1));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testIndexesOutOfRange_m1RGBColor() {
|
||||
assertNotNull(TerminalColor.getIndexedRGBColor(-1));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testIndexesOutOfRange_16() {
|
||||
assertNotNull(TerminalColor.getIndexedTerminalColor(16));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testIndexesOutOfRange_15() {
|
||||
assertNotNull(TerminalColor.getIndexedRGBColor(15));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testIndexesOutOfRange_256TerminalColor() {
|
||||
assertNotNull(TerminalColor.getIndexedTerminalColor(256));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testIndexesOutOfRange_256RGBColor() {
|
||||
assertNotNull(TerminalColor.getIndexedRGBColor(256));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue