expose color from render state
This commit is contained in:
@@ -1,8 +1,18 @@
|
||||
package dev.jlibghostty;
|
||||
|
||||
public record RenderCell(int column, int[] codepoints, boolean selected) {
|
||||
import java.util.Optional;
|
||||
|
||||
public record RenderCell(
|
||||
int column,
|
||||
int[] codepoints,
|
||||
Optional<RenderColor> foreground,
|
||||
Optional<RenderColor> background,
|
||||
boolean selected
|
||||
) {
|
||||
public RenderCell {
|
||||
codepoints = codepoints.clone();
|
||||
foreground = foreground == null ? Optional.empty() : foreground;
|
||||
background = background == null ? Optional.empty() : background;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
16
src/main/java/dev/jlibghostty/RenderColor.java
Normal file
16
src/main/java/dev/jlibghostty/RenderColor.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package dev.jlibghostty;
|
||||
|
||||
public record RenderColor(int red, int green, int blue) {
|
||||
public RenderColor {
|
||||
red = checkChannel("red", red);
|
||||
green = checkChannel("green", green);
|
||||
blue = checkChannel("blue", blue);
|
||||
}
|
||||
|
||||
private static int checkChannel(String name, int value) {
|
||||
if (value < 0 || value > 255) {
|
||||
throw new IllegalArgumentException(name + " must be between 0 and 255");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import dev.jlibghostty.GhosttyBuildInfo;
|
||||
import dev.jlibghostty.GhosttyException;
|
||||
import dev.jlibghostty.OptimizeMode;
|
||||
import dev.jlibghostty.RenderCell;
|
||||
import dev.jlibghostty.RenderColor;
|
||||
import dev.jlibghostty.RenderRow;
|
||||
import dev.jlibghostty.SizeReportSize;
|
||||
import dev.jlibghostty.TerminalOptions;
|
||||
@@ -22,6 +23,7 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static java.lang.foreign.ValueLayout.JAVA_BYTE;
|
||||
|
||||
@@ -74,9 +76,12 @@ public final class GhosttyLibrary {
|
||||
|
||||
public static final int RENDER_STATE_ROW_CELLS_DATA_GRAPHEMES_LEN = 3;
|
||||
public static final int RENDER_STATE_ROW_CELLS_DATA_GRAPHEMES_BUF = 4;
|
||||
public static final int RENDER_STATE_ROW_CELLS_DATA_BG_COLOR = 5;
|
||||
public static final int RENDER_STATE_ROW_CELLS_DATA_FG_COLOR = 6;
|
||||
public static final int RENDER_STATE_ROW_CELLS_DATA_SELECTED = 7;
|
||||
|
||||
private static final int GHOSTTY_SUCCESS = 0;
|
||||
private static final int GHOSTTY_INVALID_VALUE = -2;
|
||||
private static final int GHOSTTY_OUT_OF_SPACE = -3;
|
||||
private static final int GHOSTTY_NO_VALUE = -4;
|
||||
|
||||
@@ -703,6 +708,8 @@ public final class GhosttyLibrary {
|
||||
result.add(new RenderCell(
|
||||
column,
|
||||
renderStateRowCellGraphemes(cells),
|
||||
renderStateRowCellColor(cells, RENDER_STATE_ROW_CELLS_DATA_FG_COLOR),
|
||||
renderStateRowCellColor(cells, RENDER_STATE_ROW_CELLS_DATA_BG_COLOR),
|
||||
renderStateRowCellsGetBoolean(cells, RENDER_STATE_ROW_CELLS_DATA_SELECTED)
|
||||
));
|
||||
column++;
|
||||
@@ -799,6 +806,24 @@ public final class GhosttyLibrary {
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<RenderColor> renderStateRowCellColor(MemorySegment cells, int key) {
|
||||
try (Arena arena = Arena.ofConfined()) {
|
||||
MemorySegment out = arena.allocate(3, 1);
|
||||
int result = (int) renderStateRowCellsGet.invoke(cells, key, out);
|
||||
if (result == GHOSTTY_INVALID_VALUE) {
|
||||
return Optional.empty();
|
||||
}
|
||||
checkResult("ghostty_render_state_row_cells_get", result);
|
||||
return Optional.of(new RenderColor(
|
||||
Byte.toUnsignedInt(out.get(JAVA_BYTE, 0)),
|
||||
Byte.toUnsignedInt(out.get(JAVA_BYTE, 1)),
|
||||
Byte.toUnsignedInt(out.get(JAVA_BYTE, 2))
|
||||
));
|
||||
} catch (Throwable t) {
|
||||
return rethrow(t);
|
||||
}
|
||||
}
|
||||
|
||||
public void kittyGraphicsPopulatePlacementIterator(MemorySegment graphics, MemorySegment iterator) {
|
||||
try (Arena arena = Arena.ofConfined()) {
|
||||
MemorySegment out = arena.allocate(C_POINTER);
|
||||
|
||||
@@ -43,6 +43,12 @@ public final class GhosttySmokeTest {
|
||||
if (!renderedHello) {
|
||||
throw new AssertionError("render state should contain written text");
|
||||
}
|
||||
renderSnapshot.renderRows().stream()
|
||||
.flatMap(row -> row.cells().stream())
|
||||
.forEach(cell -> {
|
||||
cell.foreground().ifPresent(GhosttySmokeTest::assertColor);
|
||||
cell.background().ifPresent(GhosttySmokeTest::assertColor);
|
||||
});
|
||||
TerminalSnapshot snapshot = terminal.snapshot();
|
||||
if (snapshot.columns() != 80 || snapshot.rows() != 24) {
|
||||
throw new AssertionError("unexpected terminal size: " + snapshot);
|
||||
@@ -50,4 +56,12 @@ public final class GhosttySmokeTest {
|
||||
terminal.kittyGraphics().ifPresent(KittyGraphics::placements);
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertColor(RenderColor color) {
|
||||
if (color.red() < 0 || color.red() > 255
|
||||
|| color.green() < 0 || color.green() > 255
|
||||
|| color.blue() < 0 || color.blue() > 255) {
|
||||
throw new AssertionError("invalid color: " + color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user