Skip to content

Instantly share code, notes, and snippets.

@UserUNP
Created June 9, 2025 18:10
Show Gist options
  • Save UserUNP/845b6b1c461a8d043891e80400fb4f93 to your computer and use it in GitHub Desktop.
Save UserUNP/845b6b1c461a8d043891e80400fb4f93 to your computer and use it in GitHub Desktop.
// requires jdk 24 with --enable-preview
import java.awt.image.DirectColorModel;
import java.awt.image.ColorModel;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import org.jetbrains.annotations.NotNull;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.TextColor;
public class Renderer {
private static final String PIXEL_STR = "⏹ ";
private static final int CHAR_PIXELS = 5;
private static final int LINE_WIDTH = CHAR_PIXELS * 2;
private static final float CHAR_LENGTH = CHAR_PIXELS / 40f;
private final ColorModel rgb;
public Renderer(ColorModel rgb) {
this.rgb = rgb;
}
public Renderer(int[] bitMasks) {
this(new DirectColorModel(32, bitMasks[0], bitMasks[1], bitMasks[2]));
}
public Surface surface(Supplier supplier) {
return new Surface(supplier);
}
public int getColor(int pixel) {
return rgb.getRGB(pixel);
}
public boolean renderNextField(Surface surface) {
while (!surface.next()) {}
return surface.unloaded;
}
public class Surface {
private volatile MemorySegment pixels;
private volatile boolean unloaded;
private int width, height;
private int fixedWidth, fixedHeight, x, y;
private final SurfaceField[] fields = new SurfaceField[4];
public Surface(Supplier supplier) {
fields[0] = new SurfaceField(supplier, 0, 1);
fields[1] = new SurfaceField(supplier, 1, 1);
fields[2] = new SurfaceField(supplier, 0, 0);
fields[3] = new SurfaceField(supplier, 1, 0);
}
public int width() {
return width;
}
public int height() {
return height;
}
public int fieldsCount() {
return fields.length;
}
public void update(@NotNull MemorySegment pixelsPtr, int width, int height) {
long byteSize = (long) width * height * 4;
if (byteSize > Integer.MAX_VALUE) throw new RuntimeException("Surface too large");
if (pixelsPtr.isNative()) pixels = pixelsPtr.reinterpret(byteSize);
else pixels = pixelsPtr;
this.width = width;
this.height = height;
fixedWidth = width % 2 == 0 ? width : width + 1;
fixedHeight = height % 2 == 0 ? height : height + 1;
for (SurfaceField field : fields) field.update(fixedWidth / 2, fixedHeight / 2);
x = y = 0;
unloaded = false;
}
public void stop() {
unloaded = true;
pixels = null;
}
private boolean next() {
if (unloaded || pixels == null) return true;
if (y >= fixedHeight) x = y = 0;
int color = (x < width && y < height) ? (getColor(pixels.getAtIndex(ValueLayout.JAVA_INT, y * width + x))) : 0;
boolean fieldFinished = fields[(y % 2) * 2 + (x % 2)].next(color);
if (++x >= fixedWidth) {
x = 0;
y++;
}
return fieldFinished;
}
}
@FunctionalInterface
public interface Supplier {
Entity get(float x, float y);
}
public interface Entity {
void update(int lineWidth);
void render(Component text);
}
static class SurfaceField {
int index, offX, offY;
final Entity entity;
final IntArrayList pixmap = new IntArrayList();
SurfaceField(Supplier supplier, int offX, int offY) {
this.offX = offX;
this.offY = offY;
entity = supplier.get(offX * CHAR_LENGTH / 2, offY * CHAR_LENGTH / 2);
}
boolean next(int color) {
boolean reset = index >= pixmap.size();
if (reset) {
entity.render(pixmap.intStream()
.mapToObj(c -> Component.text(PIXEL_STR, TextColor.color(c)))
.collect(Component::text, TextComponent.Builder::append, TextComponent.Builder::append)
.build());
index = 0;
}
if (index < pixmap.size()) pixmap.set(index++, color);
return reset;
}
void update(int width, int height) {
int newSize = width * height;
pixmap.size(newSize);
pixmap.trim();
entity.update(width * LINE_WIDTH);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment