use vanilla font system for terminal

This commit is contained in:
cvrunmin 2023-07-20 21:58:41 +08:00
parent cf466874ef
commit abf5c4b3de
5 changed files with 79 additions and 68 deletions

View File

@ -59,7 +59,7 @@ private PrintoutRenderer() {
}
public static void drawText(PoseStack transform, MultiBufferSource bufferSource, int x, int y, int start, int light, TextBuffer[] text, TextBuffer[] colours) {
var buffer = bufferSource.getBuffer(RenderTypes.PRINTOUT_TEXT);
var buffer = bufferSource.getBuffer(RenderTypes.PRINTOUT_FULLTEXT);
var emitter = FixedWidthFontRenderer.toVertexConsumer(transform, buffer);
for (var line = 0; line < LINES_PER_PAGE && line < text.length; line++) {
FixedWidthFontRenderer.drawString(emitter,
@ -70,7 +70,7 @@ public static void drawText(PoseStack transform, MultiBufferSource bufferSource,
}
public static void drawText(PoseStack transform, MultiBufferSource bufferSource, int x, int y, int start, int light, String[] text, String[] colours) {
var buffer = bufferSource.getBuffer(RenderTypes.PRINTOUT_TEXT);
var buffer = bufferSource.getBuffer(RenderTypes.PRINTOUT_FULLTEXT);
var emitter = FixedWidthFontRenderer.toVertexConsumer(transform, buffer);
for (var line = 0; line < LINES_PER_PAGE && line < text.length; line++) {
FixedWidthFontRenderer.drawString(emitter,

View File

@ -29,7 +29,10 @@
public class DynamicFontTexture extends AbstractTexture {
public static final ResourceLocation DEFAULT_NAME = new ResourceLocation(ComputerCraftAPI.MOD_ID, "dyn_term_font");
private static final int MINIMUM_SIZE = 512;
public static final ResourceLocation TERMINAL_FONT_DEFINATION = new ResourceLocation(ComputerCraftAPI.MOD_ID, "terminal_font");
private static final int MINIMUM_SIZE = 256;
private int currentSize;
private TextureSlotNode rootNode;
@ -97,7 +100,7 @@ public int getCurrentSize() {
public RegisteredGlyph getGlyph(int codepoint){
return glyphs.computeIfAbsent(codepoint, cp -> {
var fontSet = Minecraft.getInstance().font.getFontSet(Minecraft.UNIFORM_FONT);
var fontSet = Minecraft.getInstance().font.getFontSet(TERMINAL_FONT_DEFINATION);
var glyphInfo = fontSet.getGlyphInfo(cp, false);
if(glyphInfo != SpecialGlyphs.MISSING){
var glyph = registerGlyph(glyphInfo);
@ -118,9 +121,7 @@ void registeredGlyph(int codepoint, GlyphInfo glyphInfo){
private RegisteredGlyph registerGlyph(GlyphInfo glyphInfo) {
var regGlyphWrapper = new RegisteredGlyph[]{ null };
glyphInfo.bake(sheetGlyphInfo -> {
var offsetX = ((int) glyphInfo.getAdvance());
offsetX = offsetX + sheetGlyphInfo.getPixelWidth() <= 16 ? offsetX : 0;
var wrapper = new SheetGlyphInfoWrapper(sheetGlyphInfo, Optional.of(offsetX));
var wrapper = new SheetGlyphInfoWrapper(sheetGlyphInfo, Optional.empty());
var assignedNode = rootNode.insert(wrapper);
if (assignedNode == null) {
resize(currentSize * 2);
@ -130,8 +131,8 @@ private RegisteredGlyph registerGlyph(GlyphInfo glyphInfo) {
return null;
}
bind();
sheetGlyphInfo.upload(assignedNode.x + offsetX / 2, assignedNode.y);
regGlyphWrapper[0] = new RegisteredGlyph(assignedNode.x, assignedNode.y, assignedNode.x + sheetGlyphInfo.getPixelWidth() + offsetX, assignedNode.y + sheetGlyphInfo.getPixelHeight());
sheetGlyphInfo.upload(assignedNode.x, assignedNode.y);
regGlyphWrapper[0] = new RegisteredGlyph(assignedNode.x, assignedNode.y, assignedNode.x + sheetGlyphInfo.getPixelWidth(), assignedNode.y + sheetGlyphInfo.getPixelHeight());
return null;
});
return regGlyphWrapper[0];

View File

@ -1,25 +1,16 @@
package dan200.computercraft.client.render.text;
import com.mojang.blaze3d.font.GlyphInfo;
import com.mojang.blaze3d.font.SheetGlyphInfo;
import com.mojang.blaze3d.platform.NativeImage;
import dan200.computercraft.core.terminal.TextBuffer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.font.glyphs.BakedGlyph;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ReloadableResourceManager;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.server.packs.resources.SimplePreparableReloadListener;
import net.minecraft.util.profiling.ProfilerFiller;
import org.joml.Vector4f;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.function.Function;
public class TerminalFont {
public static final ResourceLocation ANSI_TERM_FONT = new ResourceLocation("computercraft", "textures/gui/term_font.png");
public static final int FONT_HEIGHT = 9;
public static final int FONT_WIDTH = 6;
static final float WIDTH = 256.0f;
private DynamicFontTexture fullTexture;
@Nullable
@ -33,20 +24,27 @@ public static TerminalFont getInstance(){
}
private TerminalFont(){
this.fullTexture = new DynamicFontTexture(512);
Minecraft.getInstance().getTextureManager().register(DynamicFontTexture.DEFAULT_NAME, this.fullTexture);
try (var stream = Minecraft.getInstance().getResourceManager().open(ANSI_TERM_FONT)){
var image = NativeImage.read(stream);
var scale = image.getWidth() / WIDTH;
for (int i = 1; i < 256; i++) {
var column = i % 16;
var row = i / 16;
var xStart = 1 + column * (FONT_WIDTH + 2);
var yStart = 1 + row * (FONT_HEIGHT + 2);
fullTexture.registeredGlyph(i, new ANSITerminalGlyphInfo(image, (int) (xStart * scale), (int) (yStart * scale), (int) (FONT_WIDTH * scale), (int) (FONT_HEIGHT * scale)));
prepareFontTexture();
((ReloadableResourceManager) Minecraft.getInstance().getResourceManager()).registerReloadListener(new SimplePreparableReloadListener<Void>() {
@Override
protected Void prepare(ResourceManager resourceManager, ProfilerFiller profilerFiller) {
return null;
}
} catch (IOException e) {
throw new RuntimeException(e);
@Override
protected void apply(Void unused, ResourceManager resourceManager, ProfilerFiller profilerFiller) {
TerminalFont.this.fullTexture.close();
prepareFontTexture();
}
});
}
private void prepareFontTexture() {
this.fullTexture = new DynamicFontTexture(256);
Minecraft.getInstance().getTextureManager().register(DynamicFontTexture.DEFAULT_NAME, this.fullTexture);
// preload codepoint 0x01-0xff
for (int i = 1; i < 256; i++) {
this.fullTexture.getGlyph(i);
}
}
@ -81,37 +79,4 @@ public void preloadCharacterFont(TextBuffer[] textBuffers){
preloadCharacterFont(textBuffer);
}
}
record ANSITerminalGlyphInfo(NativeImage image, int offsetX, int offsetY, int width, int height) implements GlyphInfo{
public float getAdvance() {
return 0;
}
public BakedGlyph bake(Function<SheetGlyphInfo, BakedGlyph> function) {
return function.apply(new SheetGlyphInfo() {
@Override
public int getPixelWidth() {
return ANSITerminalGlyphInfo.this.width;
}
@Override
public int getPixelHeight() {
return ANSITerminalGlyphInfo.this.height;
}
@Override
public void upload(int xOffset, int yOffset) {
ANSITerminalGlyphInfo.this.image.upload(0, xOffset, yOffset, ANSITerminalGlyphInfo.this.offsetX, ANSITerminalGlyphInfo.this.offsetY, width, height, false, false);
}
@Override
public boolean isColored() {
return true;
}
@Override
public float getOversample() {
return 1;
}
});
}
}
}

View File

@ -0,0 +1,45 @@
{
"providers": [
{
"type": "bitmap",
"file": "computercraft:font/terminal_ansi.png",
"ascent": 8,
"height": 9,
"chars": [
"\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000a\u000b\u000c\u000d\u000e\u000f\u0000\u0000\u0000\u0000\u0000",
"\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f\u0000\u0000\u0000\u0000\u0000",
"\u0020\u0021\u0022\u0023\u0024\u0025\u0026\u0027\u0028\u0029\u002a\u002b\u002c\u002d\u002e\u002f\u0000\u0000\u0000\u0000\u0000",
"\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u003a\u003b\u003c\u003d\u003e\u003f\u0000\u0000\u0000\u0000\u0000",
"\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f\u0000\u0000\u0000\u0000\u0000",
"\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057\u0058\u0059\u005a\u005b\u005c\u005d\u005e\u005f\u0000\u0000\u0000\u0000\u0000",
"\u0060\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068\u0069\u006a\u006b\u006c\u006d\u006e\u006f\u0000\u0000\u0000\u0000\u0000",
"\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077\u0078\u0079\u007a\u007b\u007c\u007d\u007e\u007f\u0000\u0000\u0000\u0000\u0000",
"\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f\u0000\u0000\u0000\u0000\u0000",
"\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f\u0000\u0000\u0000\u0000\u0000",
"\u00a0\u00a1\u00a2\u00a3\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ad\u00ae\u00af\u0000\u0000\u0000\u0000\u0000",
"\u00b0\u00b1\u00b2\u00b3\u00b4\u00b5\u00b6\u00b7\u00b8\u00b9\u00ba\u00bb\u00bc\u00bd\u00be\u00bf\u0000\u0000\u0000\u0000\u0000",
"\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf\u0000\u0000\u0000\u0000\u0000",
"\u00d0\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9\u00da\u00db\u00dc\u00dd\u00de\u00df\u0000\u0000\u0000\u0000\u0000",
"\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed\u00ee\u00ef\u0000\u0000\u0000\u0000\u0000",
"\u00f0\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u00fe\u00ff\u0000\u0000\u0000\u0000\u0000",
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
]
},
{
"type": "legacy_unicode",
"sizes": "minecraft:font/glyph_sizes.bin",
"template": "minecraft:font/unicode_page_%s.png"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB