diff --git a/src/main/java/com/github/tommyettinger/textra/Font.java b/src/main/java/com/github/tommyettinger/textra/Font.java index 1440c049..bcf22104 100644 --- a/src/main/java/com/github/tommyettinger/textra/Font.java +++ b/src/main/java/com/github/tommyettinger/textra/Font.java @@ -80,6 +80,35 @@ */ public class Font implements Disposable { + /** + * A {@link DistanceFieldType} that should be {@link DistanceFieldType#STANDARD} for most fonts, and can be + * {@link DistanceFieldType#SDF}, {@link DistanceFieldType#MSDF}, or {@link DistanceFieldType#SDF_OUTLINE} if you + * know you have a font made to be used with one of those rendering techniques. See {@link #distanceFieldCrispness} + * for one way to configure SDF and MSDF fonts, and {@link #resizeDistanceField(int, int)} for a convenience method + * to handle window-resizing sharply. + */ + public DistanceFieldType getDistanceField() { + return distanceField; + } + + public void setDistanceField(DistanceFieldType distanceField) { + this.distanceField = distanceField; + if (distanceField == DistanceFieldType.MSDF) { + shader = new ShaderProgram(vertexShader, msdfFragmentShader); + if (!shader.isCompiled()) + Gdx.app.error("textratypist", "MSDF shader failed to compile: " + shader.getLog()); + } else if (distanceField == DistanceFieldType.SDF) { + shader = new ShaderProgram(vertexShader, sdfFragmentShader); + if (!shader.isCompiled()) + Gdx.app.error("textratypist", "SDF shader failed to compile: " + shader.getLog()); + } else if (distanceField == DistanceFieldType.SDF_OUTLINE) { + shader = new ShaderProgram(vertexShader, sdfBlackOutlineFragmentShader); + if (!shader.isCompiled()) + Gdx.app.error("textratypist", "SDF_OUTLINE shader failed to compile: " + shader.getLog()); + } else shader = null; + + } + /** * Describes the region of a glyph in a larger TextureRegion, carrying a little more info about the offsets that * apply to where the glyph is rendered. @@ -418,14 +447,7 @@ public enum DistanceFieldType { * drawn from a TextureAtlas that the font shares with other images. */ public Array parents; - /** - * A {@link DistanceFieldType} that should be {@link DistanceFieldType#STANDARD} for most fonts, and can be - * {@link DistanceFieldType#SDF}, {@link DistanceFieldType#MSDF}, or {@link DistanceFieldType#SDF_OUTLINE} if you - * know you have a font made to be used with one of those rendering techniques. See {@link #distanceFieldCrispness} - * for one way to configure SDF and MSDF fonts, and {@link #resizeDistanceField(int, int)} for a convenience method - * to handle window-resizing sharply. - */ - public DistanceFieldType distanceField; + private DistanceFieldType distanceField; /** * If true, this is a fixed-width (monospace) font; if false, this is probably a variable-width font. This affects * some rendering decisions Font makes, such as whether subscript chars should take up half-width (for variable @@ -1167,7 +1189,7 @@ public Font(String fntName, String textureName, DistanceFieldType distanceField) * @param toCopy another Font to copy */ public Font(Font toCopy) { - distanceField = toCopy.distanceField; + this.distanceField = toCopy.distanceField; isMono = toCopy.isMono; actualCrispness = toCopy.actualCrispness; distanceFieldCrispness = toCopy.distanceFieldCrispness; @@ -1315,20 +1337,7 @@ public Font(String fntName, DistanceFieldType distanceField, */ public Font(String fntName, DistanceFieldType distanceField, float xAdjust, float yAdjust, float widthAdjust, float heightAdjust, boolean makeGridGlyphs) { - this.distanceField = distanceField; - if (distanceField == DistanceFieldType.MSDF) { - shader = new ShaderProgram(vertexShader, msdfFragmentShader); - if (!shader.isCompiled()) - Gdx.app.error("textratypist", "MSDF shader failed to compile: " + shader.getLog()); - } else if (distanceField == DistanceFieldType.SDF) { - shader = new ShaderProgram(vertexShader, sdfFragmentShader); - if (!shader.isCompiled()) - Gdx.app.error("textratypist", "SDF shader failed to compile: " + shader.getLog()); - } else if (distanceField == DistanceFieldType.SDF_OUTLINE) { - shader = new ShaderProgram(vertexShader, sdfBlackOutlineFragmentShader); - if (!shader.isCompiled()) - Gdx.app.error("textratypist", "SDF_OUTLINE shader failed to compile: " + shader.getLog()); - } + this.setDistanceField(distanceField); loadFNT(fntName, xAdjust, yAdjust, widthAdjust, heightAdjust, makeGridGlyphs); } @@ -1398,20 +1407,7 @@ public Font(String fntName, String textureName, DistanceFieldType distanceField, */ public Font(String fntName, String textureName, DistanceFieldType distanceField, float xAdjust, float yAdjust, float widthAdjust, float heightAdjust, boolean makeGridGlyphs) { - this.distanceField = distanceField; - if (distanceField == DistanceFieldType.MSDF) { - shader = new ShaderProgram(vertexShader, msdfFragmentShader); - if (!shader.isCompiled()) - Gdx.app.error("textratypist", "MSDF shader failed to compile: " + shader.getLog()); - } else if (distanceField == DistanceFieldType.SDF) { - shader = new ShaderProgram(vertexShader, sdfFragmentShader); - if (!shader.isCompiled()) - Gdx.app.error("textratypist", "SDF shader failed to compile: " + shader.getLog()); - } else if (distanceField == DistanceFieldType.SDF_OUTLINE) { - shader = new ShaderProgram(vertexShader, sdfBlackOutlineFragmentShader); - if (!shader.isCompiled()) - Gdx.app.error("textratypist", "SDF_OUTLINE shader failed to compile: " + shader.getLog()); - } + this.setDistanceField(distanceField); FileHandle textureHandle; if ((textureHandle = Gdx.files.internal(textureName)).exists() || (textureHandle = Gdx.files.local(textureName)).exists()) { @@ -1490,20 +1486,7 @@ public Font(String fntName, TextureRegion textureRegion, DistanceFieldType dista */ public Font(String fntName, TextureRegion textureRegion, DistanceFieldType distanceField, float xAdjust, float yAdjust, float widthAdjust, float heightAdjust, boolean makeGridGlyphs) { - this.distanceField = distanceField; - if (distanceField == DistanceFieldType.MSDF) { - shader = new ShaderProgram(vertexShader, msdfFragmentShader); - if (!shader.isCompiled()) - Gdx.app.error("textratypist", "MSDF shader failed to compile: " + shader.getLog()); - } else if (distanceField == DistanceFieldType.SDF) { - shader = new ShaderProgram(vertexShader, sdfFragmentShader); - if (!shader.isCompiled()) - Gdx.app.error("textratypist", "SDF shader failed to compile: " + shader.getLog()); - } else if (distanceField == DistanceFieldType.SDF_OUTLINE) { - shader = new ShaderProgram(vertexShader, sdfBlackOutlineFragmentShader); - if (!shader.isCompiled()) - Gdx.app.error("textratypist", "SDF_OUTLINE shader failed to compile: " + shader.getLog()); - } + this.setDistanceField(distanceField); this.parents = Array.with(textureRegion); if (distanceField != DistanceFieldType.STANDARD) { textureRegion.getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear); @@ -1574,20 +1557,7 @@ public Font(String fntName, Array textureRegions, DistanceFieldTy */ public Font(String fntName, Array textureRegions, DistanceFieldType distanceField, float xAdjust, float yAdjust, float widthAdjust, float heightAdjust, boolean makeGridGlyphs) { - this.distanceField = distanceField; - if (distanceField == DistanceFieldType.MSDF) { - shader = new ShaderProgram(vertexShader, msdfFragmentShader); - if (!shader.isCompiled()) - Gdx.app.error("textratypist", "MSDF shader failed to compile: " + shader.getLog()); - } else if (distanceField == DistanceFieldType.SDF) { - shader = new ShaderProgram(vertexShader, sdfFragmentShader); - if (!shader.isCompiled()) - Gdx.app.error("textratypist", "SDF shader failed to compile: " + shader.getLog()); - } else if (distanceField == DistanceFieldType.SDF_OUTLINE) { - shader = new ShaderProgram(vertexShader, sdfBlackOutlineFragmentShader); - if (!shader.isCompiled()) - Gdx.app.error("textratypist", "SDF_OUTLINE shader failed to compile: " + shader.getLog()); - } + this.setDistanceField(distanceField); this.parents = textureRegions; if (distanceField != DistanceFieldType.STANDARD && textureRegions != null) { for (TextureRegion parent : textureRegions) @@ -1654,20 +1624,7 @@ public Font(BitmapFont bmFont, DistanceFieldType distanceField, */ public Font(BitmapFont bmFont, DistanceFieldType distanceField, float xAdjust, float yAdjust, float widthAdjust, float heightAdjust, boolean makeGridGlyphs) { - this.distanceField = distanceField; - if (distanceField == DistanceFieldType.MSDF) { - shader = new ShaderProgram(vertexShader, msdfFragmentShader); - if (!shader.isCompiled()) - Gdx.app.error("textratypist", "MSDF shader failed to compile: " + shader.getLog()); - } else if (distanceField == DistanceFieldType.SDF) { - shader = new ShaderProgram(vertexShader, sdfFragmentShader); - if (!shader.isCompiled()) - Gdx.app.error("textratypist", "SDF shader failed to compile: " + shader.getLog()); - } else if (distanceField == DistanceFieldType.SDF_OUTLINE) { - shader = new ShaderProgram(vertexShader, sdfBlackOutlineFragmentShader); - if (!shader.isCompiled()) - Gdx.app.error("textratypist", "SDF_OUTLINE shader failed to compile: " + shader.getLog()); - } + this.setDistanceField(distanceField); this.parents = bmFont.getRegions(); if (distanceField != DistanceFieldType.STANDARD && parents != null) { for (TextureRegion parent : parents) @@ -1808,7 +1765,7 @@ public Font(BitmapFont bmFont, DistanceFieldType distanceField, * @param ignoredSadConsoleFlag the value is ignored here; the presence of this parameter says to load a SadConsole .font file */ public Font(String prefix, String fntName, boolean ignoredSadConsoleFlag) { - this.distanceField = DistanceFieldType.STANDARD; + this.setDistanceField(DistanceFieldType.STANDARD); loadSad(prefix == null ? "" : prefix, fntName); } @@ -1864,7 +1821,7 @@ protected void loadFNT(String fntName, float xAdjust, float yAdjust, float width if ((textureHandle = Gdx.files.internal(textureName)).exists() || (textureHandle = Gdx.files.local(textureName)).exists()) { parents.add(new TextureRegion(new Texture(textureHandle))); - if (distanceField != DistanceFieldType.STANDARD) + if (getDistanceField() != DistanceFieldType.STANDARD) parents.peek().getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear); } else { throw new RuntimeException("Missing texture file: " + textureName); @@ -2686,14 +2643,14 @@ public int atlasLookup(String name) { * @param batch the Batch to instruct to use the appropriate shader for this font; should usually be a SpriteBatch */ public void enableShader(Batch batch) { - if (distanceField == DistanceFieldType.MSDF) { + if (getDistanceField() == DistanceFieldType.MSDF) { if (batch.getShader() != shader) { batch.setShader(shader); shader.setUniformf("u_weight", 0f); // shader.setUniformf("u_smoothing", 2f * distanceFieldCrispness); shader.setUniformf("u_smoothing", 7f * actualCrispness * Math.max(cellHeight / originalCellHeight, cellWidth / originalCellWidth)); } - } else if (distanceField == DistanceFieldType.SDF || distanceField == DistanceFieldType.SDF_OUTLINE) { + } else if (getDistanceField() == DistanceFieldType.SDF || getDistanceField() == DistanceFieldType.SDF_OUTLINE) { if (batch.getShader() != shader) { batch.setShader(shader); final float scale = Math.max(cellHeight / originalCellHeight, cellWidth / originalCellWidth) * 0.5f + 0.125f; @@ -6310,7 +6267,7 @@ public void removeStoredState(String name) { * @param height the new window height; usually a parameter in {@link com.badlogic.gdx.ApplicationListener#resize(int, int)} */ public void resizeDistanceField(int width, int height) { - if (distanceField == DistanceFieldType.MSDF) { + if (getDistanceField() == DistanceFieldType.MSDF) { if (Gdx.graphics.getBackBufferWidth() == 0 || Gdx.graphics.getBackBufferHeight() == 0) { actualCrispness = distanceFieldCrispness; } else { @@ -6318,7 +6275,7 @@ public void resizeDistanceField(int width, int height) { Math.max((float) width / Gdx.graphics.getBackBufferWidth(), (float) height / Gdx.graphics.getBackBufferHeight()) * 1.9f - 2.15f + cellHeight * 0.01f); } - } else if (distanceField == DistanceFieldType.SDF || distanceField == DistanceFieldType.SDF_OUTLINE) { + } else if (getDistanceField() == DistanceFieldType.SDF || getDistanceField() == DistanceFieldType.SDF_OUTLINE) { if (Gdx.graphics.getBackBufferWidth() == 0 || Gdx.graphics.getBackBufferHeight() == 0) { actualCrispness = distanceFieldCrispness; } else { @@ -6494,7 +6451,7 @@ public String toString() { public String debugString() { return "Font{" + - "distanceField=" + distanceField + + "distanceField=" + getDistanceField() + ", isMono=" + isMono + ", kerning=" + kerning + ", actualCrispness=" + actualCrispness + diff --git a/src/main/java/com/github/tommyettinger/textra/KnownFonts.java b/src/main/java/com/github/tommyettinger/textra/KnownFonts.java index dac5aff4..06b4c1ed 100644 --- a/src/main/java/com/github/tommyettinger/textra/KnownFonts.java +++ b/src/main/java/com/github/tommyettinger/textra/KnownFonts.java @@ -582,7 +582,7 @@ public static Font getGentiumSDF() { if (instance.gentiumSDF == null) { try { instance.gentiumSDF = new Font(instance.prefix + "Gentium-sdf.fnt", - instance.prefix + "Gentium-sdf.png", SDF, 4f, -45f, 0f, 0f, true) + instance.prefix + "Gentium-sdf.png", SDF, 4f, -45f, 0f, 0f, false) .scaleTo(50, 45).adjustLineHeight(0.625f).setFancyLinePosition(0f, 1.1f) .setLineMetrics(0.05f, 1f, 0f, -0.5f).setInlineImageMetrics(0f, -42f, 8f) .setCrispness(1.5f).setName("Gentium (SDF)"); @@ -726,7 +726,7 @@ public static Font getGoNotoUniversalSDF() { if (instance.goNotoUniversalSDF == null) { try { instance.goNotoUniversalSDF = new Font(instance.prefix + "GoNotoUniversal-sdf.fnt", - instance.prefix + "GoNotoUniversal-sdf.png", SDF, 0f, -16f, 0f, 0f, true) + instance.prefix + "GoNotoUniversal-sdf.png", SDF, 0f, -16f, 0f, 0f, false) .scaleTo(43.25f, 34).adjustLineHeight(0.625f) .setCrispness(1.8f).setFancyLinePosition(0f, 1.15f) .setLineMetrics(0.25f, 0.85f, 0.2f, -0.5f).setInlineImageMetrics(0f, -28f, 16f) @@ -1026,7 +1026,7 @@ public static Font getIosevkaSDF() { // NOTE: If the .fnt file is changed, the manual adjustment to '_' (id=95) will be lost. yoffset was changed to 4. // This should be OK now that this uses the box-drawing underline. instance.iosevkaSDF = new Font(instance.prefix + "Iosevka-sdf.fnt", - instance.prefix + "Iosevka-sdf.png", SDF, 2f, 0f, -2f, -2f, true) + instance.prefix + "Iosevka-sdf.png", SDF, 2f, 0f, -2f, -2f, false) .setLineMetrics(0.25f, -0.125f, 0f, -0.4f).setInlineImageMetrics(8f, 12f, 12f) .setCrispness(0.75f).scaleTo(12, 26).fitCell(10, 25, false) .setName("Iosevka (SDF)"); @@ -1159,7 +1159,7 @@ public static Font getIosevkaSlabSDF() { // NOTE: If the .fnt file is changed, the manual adjustment to '_' (id=95) will be lost. yoffset was changed to 4. // This might be OK now that this uses the box-drawing underline. instance.iosevkaSlabSDF = new Font(instance.prefix + "Iosevka-Slab-sdf.fnt", - instance.prefix + "Iosevka-Slab-sdf.png", SDF, 2f, 0f, -2f, -2f, true) + instance.prefix + "Iosevka-Slab-sdf.png", SDF, 2f, 0f, -2f, -2f, false) .setLineMetrics(0.25f, -0.125f, 0f, -0.4f).setInlineImageMetrics(8f, 12f, 12f) .setCrispness(0.75f).scaleTo(12, 26).fitCell(10, 25, false) .setName("Iosevka Slab (SDF)"); diff --git a/src/main/java/com/github/tommyettinger/textra/TextraLabel.java b/src/main/java/com/github/tommyettinger/textra/TextraLabel.java index 35381385..65bcf42c 100644 --- a/src/main/java/com/github/tommyettinger/textra/TextraLabel.java +++ b/src/main/java/com/github/tommyettinger/textra/TextraLabel.java @@ -316,7 +316,7 @@ public void draw(Batch batch, float parentAlpha) { if (layout.lines.isEmpty() || parentAlpha <= 0f) return; // we only change the shader or batch color if we actually are drawing something. - boolean resetShader = font.distanceField != Font.DistanceFieldType.STANDARD && batch.getShader() != font.shader; + boolean resetShader = font.getDistanceField() != Font.DistanceFieldType.STANDARD && batch.getShader() != font.shader; if (resetShader) font.enableShader(batch); batch.getColor().set(getColor()).a *= parentAlpha; diff --git a/src/main/java/com/github/tommyettinger/textra/TypingLabel.java b/src/main/java/com/github/tommyettinger/textra/TypingLabel.java index b435f7a6..89fd8388 100644 --- a/src/main/java/com/github/tommyettinger/textra/TypingLabel.java +++ b/src/main/java/com/github/tommyettinger/textra/TypingLabel.java @@ -905,7 +905,7 @@ public void draw(Batch batch, float parentAlpha) { // baseY += workingLayout.lines.first().height * 0.25f; int o = 0, s = 0, r = 0, gi = 0; - boolean resetShader = font.distanceField != Font.DistanceFieldType.STANDARD && batch.getShader() != font.shader; + boolean resetShader = font.getDistanceField() != Font.DistanceFieldType.STANDARD && batch.getShader() != font.shader; if (resetShader) font.enableShader(batch); batch.getColor().set(getColor()).a *= parentAlpha; diff --git a/src/test/java/com/github/tommyettinger/textra/DebugPreviewGenerator.java b/src/test/java/com/github/tommyettinger/textra/DebugPreviewGenerator.java index abf2e5cf..e43f2a0d 100644 --- a/src/test/java/com/github/tommyettinger/textra/DebugPreviewGenerator.java +++ b/src/test/java/com/github/tommyettinger/textra/DebugPreviewGenerator.java @@ -8,7 +8,6 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.glutils.ShaderProgram; import com.badlogic.gdx.utils.Align; -import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ScreenUtils; import com.badlogic.gdx.utils.TimeUtils; import com.badlogic.gdx.utils.viewport.StretchViewport; @@ -124,7 +123,7 @@ public void create() { // font.markup("[%300][#44DD22]digital[%]\n[#66EE55]just numeric things \n" // , layout); font.markup("[_]Font[ ] [~]name[ ] ([%?error]error[%] [%?warn]warn[%] [%?note]note[%] [*]bold[ ] [/]oblique[ ]): " + font.name + - (font.distanceField != Font.DistanceFieldType.MSDF ? + (font.getDistanceField() != Font.DistanceFieldType.MSDF ? ",\n[@Main]Do I... [@G]Do I..." + ",\n[@Main]line up... [@G]line up..." + ",\n[@Main]with Gentium? [@G]with Gentium?[@Main]" : "") + @@ -141,7 +140,7 @@ public void create() { ",\nwidthAdjust: " + font.widthAdjust + ", heightAdjust: " + font.heightAdjust + "\n" + - (font.distanceField != Font.DistanceFieldType.MSDF ? emojiSupport : distanceField), layout); + (font.getDistanceField() != Font.DistanceFieldType.MSDF ? emojiSupport : distanceField), layout); // System.out.println(layout); ScreenUtils.clear(0.75f, 0.75f, 0.75f, 1f); @@ -180,7 +179,7 @@ public void create() { ",\nwidthAdjust: " + font.widthAdjust + ", heightAdjust: " + font.heightAdjust + "\n" + - (font.distanceField != Font.DistanceFieldType.MSDF ? emojiSupport : distanceField), layout.clear()); + (font.getDistanceField() != Font.DistanceFieldType.MSDF ? emojiSupport : distanceField), layout.clear()); // System.out.println(layout); Gdx.app.exit(); diff --git a/src/test/java/com/github/tommyettinger/textra/PreviewGenerator.java b/src/test/java/com/github/tommyettinger/textra/PreviewGenerator.java index 49535f2c..e8845566 100644 --- a/src/test/java/com/github/tommyettinger/textra/PreviewGenerator.java +++ b/src/test/java/com/github/tommyettinger/textra/PreviewGenerator.java @@ -8,10 +8,8 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.glutils.ShaderProgram; import com.badlogic.gdx.utils.Align; -import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ScreenUtils; import com.badlogic.gdx.utils.TimeUtils; -import com.badlogic.gdx.utils.viewport.ScreenViewport; import com.badlogic.gdx.utils.viewport.StretchViewport; import com.badlogic.gdx.utils.viewport.Viewport; @@ -59,8 +57,15 @@ public void create() { // with useIntegerPositions(false), it seems fine? // Font[] fonts = {KnownFonts.getCozette().useIntegerPositions(true)}; // Font[] fonts = {KnownFonts.getGentiumSDF()}; - Font[] fonts = KnownFonts.getAll(); - fnt = fonts[13]; + Font[] all = KnownFonts.getAll(), sdf = KnownFonts.getAllSDF(); + for(Font f : sdf) { + f.setDistanceField(Font.DistanceFieldType.SDF_OUTLINE); + f.name = f.name.replace("(SDF)", "(SDF_OUTLINE)"); + } + Font[] fonts = new Font[all.length + sdf.length]; + System.arraycopy(all, 0, fonts, 0, all.length); + System.arraycopy(sdf, 0, fonts, all.length, sdf.length); + fnt = fonts[1]; // fnt = fonts[fonts.length - 1]; Gdx.files.local("out/").mkdirs(); int index = 0; @@ -105,7 +110,7 @@ public void create() { layout.setEllipsis(" and so on and so forth..."); // font.markup("[%300][#44DD22]digital[%]\n[#66EE55]just numeric things \n" // , layout); - font.markup(text + (font.distanceField != Font.DistanceFieldType.MSDF ? emojiSupport : distanceField), layout); + font.markup(text + (font.getDistanceField() != Font.DistanceFieldType.MSDF ? emojiSupport : distanceField), layout); // font.markup("I wanna thank you all for coming here tonight..." // + "\n[#22BB22FF]Hello, [~]World[~]Universe[.]$[=]$[^]$[^]!" // + "\nThe [RED]MAW[] of the [/][CYAN]wendigo[/] (wendigo)[] [*]appears[*]!" @@ -141,7 +146,7 @@ public void create() { } // System.out.println(layout); startTime = TimeUtils.millis(); - fnt.markup(text + (fnt.distanceField != Font.DistanceFieldType.MSDF ? emojiSupport : distanceField), layout.clear()); + fnt.markup(text + (fnt.getDistanceField() != Font.DistanceFieldType.MSDF ? emojiSupport : distanceField), layout.clear()); Gdx.app.exit(); }