package speiger.src.coreengine.rendering.gui.renderer.provider; import java.awt.image.BufferedImage; import java.util.List; import com.google.gson.JsonObject; import speiger.src.collections.ints.maps.impl.hash.Int2ObjectOpenHashMap; import speiger.src.collections.ints.maps.interfaces.Int2ObjectMap; import speiger.src.collections.ints.utils.maps.Int2ObjectMaps; import speiger.src.collections.objects.misc.pairs.ObjectObjectPair; import speiger.src.coreengine.assets.AssetLocation; import speiger.src.coreengine.assets.AssetManager; import speiger.src.coreengine.assets.IAsset; import speiger.src.coreengine.math.vector.ints.Vec2i; import speiger.src.coreengine.rendering.gui.helper.FontBuilder; import speiger.src.coreengine.rendering.gui.helper.FontBuilder.WrittenChar; import speiger.src.coreengine.rendering.gui.renderer.IFontRenderer.CharInstance; import speiger.src.coreengine.rendering.textures.base.ITexture; import speiger.src.coreengine.rendering.textures.base.TextureManager; import speiger.src.coreengine.utils.helpers.JsonUtil; public class BitmapFontProvider implements IFontProvider { FontInfo info; ITexture texture; Int2ObjectMap[] instances; float space; public BitmapFontProvider(FontInfo info, ITexture texture, Int2ObjectMap[] instances) { this.info = info; this.texture = texture; this.instances = instances; if(instances[0].containsKey(' ')) space = instances[0].get(' ').getXAdvance(); else if(instances[1].containsKey(' ')) space = instances[1].get(' ').getXAdvance(); } @Override public void destroy() { if(texture != null) { texture.destroy(); texture = null; } } @Override public ITexture getTexture() { return texture; } @Override public boolean isCharacterValid(int codepoint) { return instances[0].containsKey(codepoint) || instances[1].containsKey(codepoint); } @Override public CharInstance getCharacter(int codepoint, boolean bold) { Int2ObjectMap map = instances[bold ? 1 : 0]; return (map.isEmpty() ? instances[bold ? 0 : 1] : map).get(codepoint); } @Override public float height() { return info.fontHeight; } @Override public float baseLine() { return info.fontBase; } @Override public float getSpaceWidth() { return space; } @Override public float getTabWidth() { return space * info.tabs; } public static IFontProvider load(JsonObject object, float desiredSize, AssetManager manager) { FontInfo info = new FontInfo(object.getAsJsonObject("info")); float multiplier = info.setDesiredHeight(desiredSize); Int2ObjectMap[] maps = new Int2ObjectMap[]{new Int2ObjectOpenHashMap(), new Int2ObjectOpenHashMap()}; JsonUtil.iterate(object.get("chars"), T -> { CharInstance instance = info.create(T); instance.scale(multiplier); maps[instance.isBold() ? 1 : 0].put(instance.getCharacter(), instance); }); if(maps[0].isEmpty()) maps[0] = Int2ObjectMaps.empty(); if(maps[1].isEmpty()) maps[1] = Int2ObjectMaps.empty(); return new BitmapFontProvider(info, ITexture.simple(AssetLocation.of(object.get("file").getAsString())), maps); } public static IFontProvider create(JsonObject object, float desiredSize, AssetManager manager) { try(IAsset asset = TextureManager.INSTANCE.getManager().getAsset(AssetLocation.of(object.get("file").getAsString()))) { JsonObject info = object.getAsJsonObject("info"); int tabs = JsonUtil.getOrDefault(info, "tabs", 4); boolean literal = JsonUtil.getOrDefault(info, "literal", false); boolean plain = JsonUtil.getOrDefault(info, "plain", true); boolean bold = JsonUtil.getOrDefault(info, "bold", true); if(!plain && !bold) throw new IllegalStateException("You need a plain or bold font at the very least"); int flags = (literal ? FontBuilder.LITERAL : 0) | (plain ? FontBuilder.PLAIN : 0) | (bold ? FontBuilder.BOLD : 0); ObjectObjectPair, List> written = FontBuilder.createBitmapFont(asset.getStream(), info.get("charset").getAsString(), flags, info.get("size").getAsFloat()); BufferedImage image = written.getKey().getValue(); Vec2i size = written.getKey().getKey(); FontInfo fontInfo = new FontInfo(image.getWidth(), image.getHeight(), size.getY(), size.getX(), tabs); float mulitplier = fontInfo.setDesiredHeight(desiredSize); Int2ObjectMap[] maps = new Int2ObjectMap[]{new Int2ObjectOpenHashMap(), new Int2ObjectOpenHashMap()}; for(WrittenChar entry : written.getValue()) { CharInstance instance = entry.create(fontInfo.textureWidth, fontInfo.textureHeight); instance.scale(mulitplier); maps[instance.isBold() ? 1 : 0].put(instance.getCharacter(), instance); } if(maps[0].isEmpty()) maps[0] = Int2ObjectMaps.empty(); if(maps[1].isEmpty()) maps[1] = Int2ObjectMaps.empty(); return new BitmapFontProvider(fontInfo, ITexture.direct(image), maps); } catch(Exception e) { e.printStackTrace(); } return null; } }