From a492c565d0f5313ede50e86d0143eade82302e42 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Thu, 8 Jul 2021 12:17:26 -0400 Subject: [PATCH] v0.9.4: refactored code relating to font generators --- .../java/com/watabou/noosa/RenderedText.java | 2 +- .../com/watabou/utils/PlatformSupport.java | 103 +++++++++++++- .../android/AndroidPlatformSupport.java | 130 ++---------------- .../desktop/DesktopPlatformSupport.java | 116 ++-------------- .../ios/IOSPlatformSupport.java | 109 +-------------- 5 files changed, 123 insertions(+), 337 deletions(-) diff --git a/SPD-classes/src/main/java/com/watabou/noosa/RenderedText.java b/SPD-classes/src/main/java/com/watabou/noosa/RenderedText.java index cf1b6f624..27678d037 100644 --- a/SPD-classes/src/main/java/com/watabou/noosa/RenderedText.java +++ b/SPD-classes/src/main/java/com/watabou/noosa/RenderedText.java @@ -89,7 +89,7 @@ public class RenderedText extends Image { visible = true; } - font = Game.platform.getFont(size, text); + font = Game.platform.getFont(size, text, true, true); if (font != null){ GlyphLayout glyphs = new GlyphLayout( font, text); diff --git a/SPD-classes/src/main/java/com/watabou/utils/PlatformSupport.java b/SPD-classes/src/main/java/com/watabou/utils/PlatformSupport.java index b28015469..d8afd4519 100644 --- a/SPD-classes/src/main/java/com/watabou/utils/PlatformSupport.java +++ b/SPD-classes/src/main/java/com/watabou/utils/PlatformSupport.java @@ -22,7 +22,13 @@ package com.watabou.utils; import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.PixmapPacker; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; +import com.watabou.noosa.Game; + +import java.util.HashMap; public abstract class PlatformSupport { @@ -47,15 +53,102 @@ public abstract class PlatformSupport { } //TODO should consider spinning this into its own class, rather than platform support getting ever bigger + protected static HashMap> fonts; + + protected int pageSize; + protected PixmapPacker packer; + protected boolean systemfont; public abstract void setupFontGenerators(int pageSize, boolean systemFont ); - public abstract void resetGenerators(); + protected abstract FreeTypeFontGenerator getGeneratorForString( String input ); - public abstract void reloadGenerators(); - - public abstract BitmapFont getFont(int size, String text); - public abstract String[] splitforTextBlock( String text, boolean multiline ); + public void resetGenerators(){ + resetGenerators( true ); + } + + public void resetGenerators( boolean setupAfter ){ + if (fonts != null) { + for (FreeTypeFontGenerator generator : fonts.keySet()) { + for (BitmapFont f : fonts.get(generator).values()) { + f.dispose(); + } + fonts.get(generator).clear(); + generator.dispose(); + } + fonts.clear(); + if (packer != null) { + for (PixmapPacker.Page p : packer.getPages()) { + p.getTexture().dispose(); + } + packer.dispose(); + } + fonts = null; + } + if (setupAfter) setupFontGenerators(pageSize, systemfont); + } + + public void reloadGenerators(){ + if (packer != null) { + for (FreeTypeFontGenerator generator : fonts.keySet()) { + for (BitmapFont f : fonts.get(generator).values()) { + f.dispose(); + } + fonts.get(generator).clear(); + } + if (packer != null) { + for (PixmapPacker.Page p : packer.getPages()) { + p.getTexture().dispose(); + } + packer.dispose(); + } + packer = new PixmapPacker(pageSize, pageSize, Pixmap.Format.RGBA8888, 1, false); + } + } + + //flipped is needed because Shattered's graphics are y-down, while GDX graphics are y-up. + //this is very confusing, I know. + public BitmapFont getFont(int size, String text, boolean flipped, boolean border) { + FreeTypeFontGenerator generator = getGeneratorForString(text); + + if (generator == null){ + return null; + } + + int key = size; + if (border) key += Short.MAX_VALUE; //surely we'll never have a size above 32k + if (flipped) key = -key; + if (!fonts.get(generator).containsKey(key)) { + FreeTypeFontGenerator.FreeTypeFontParameter parameters = new FreeTypeFontGenerator.FreeTypeFontParameter(); + parameters.size = size; + parameters.flip = flipped; + if (border) { + parameters.borderWidth = parameters.size / 10f; + } + if (size >= 20){ + parameters.renderCount = 2; + } else { + parameters.renderCount = 3; + } + parameters.hinting = FreeTypeFontGenerator.Hinting.None; + parameters.spaceX = -(int) parameters.borderWidth; + parameters.incremental = true; + parameters.characters = "�"; + parameters.packer = packer; + + try { + BitmapFont font = generator.generateFont(parameters); + font.getData().missingGlyph = font.getData().getGlyph('�'); + fonts.get(generator).put(key, font); + } catch ( Exception e ){ + Game.reportException(e); + return null; + } + } + + return fonts.get(generator).get(key); + } + } diff --git a/android/src/main/java/com/shatteredpixel/shatteredpixeldungeon/android/AndroidPlatformSupport.java b/android/src/main/java/com/shatteredpixel/shatteredpixeldungeon/android/AndroidPlatformSupport.java index 6276c8cd8..1ddf773f2 100644 --- a/android/src/main/java/com/shatteredpixel/shatteredpixeldungeon/android/AndroidPlatformSupport.java +++ b/android/src/main/java/com/shatteredpixel/shatteredpixeldungeon/android/AndroidPlatformSupport.java @@ -178,27 +178,14 @@ public class AndroidPlatformSupport extends PlatformSupport { /* FONT SUPPORT */ - private int pageSize; - private PixmapPacker packer; - private boolean systemfont; - //droid sans / roboto, or a custom pixel font, for use with Latin and Cyrillic languages private static FreeTypeFontGenerator basicFontGenerator; - private static HashMap basicFonts = new HashMap<>(); - //droid sans / nanum gothic / noto sans, for use with Korean private static FreeTypeFontGenerator KRFontGenerator; - private static HashMap KRFonts = new HashMap<>(); - //droid sans / noto sans, for use with Simplified Chinese private static FreeTypeFontGenerator SCFontGenerator; - private static HashMap SCFonts = new HashMap<>(); - //droid sans / noto sans, for use with Japanese private static FreeTypeFontGenerator JPFontGenerator; - private static HashMap JPFonts = new HashMap<>(); - - private static HashMap> fonts; //special logic for handling korean android 6.0 font oddities private static boolean koreanAndroid6OTF = false; @@ -211,23 +198,8 @@ public class AndroidPlatformSupport extends PlatformSupport { } this.pageSize = pageSize; this.systemfont = systemfont; - - if (fonts != null){ - for (FreeTypeFontGenerator generator : fonts.keySet()){ - for (BitmapFont f : fonts.get(generator).values()){ - f.dispose(); - } - fonts.get(generator).clear(); - generator.dispose(); - } - fonts.clear(); - if (packer != null){ - for (PixmapPacker.Page p : packer.getPages()){ - p.getTexture().dispose(); - } - packer.dispose(); - } - } + + resetGenerators(false); fonts = new HashMap<>(); basicFontGenerator = KRFontGenerator = SCFontGenerator = JPFontGenerator = null; @@ -294,62 +266,21 @@ public class AndroidPlatformSupport extends PlatformSupport { } - if (basicFontGenerator != null) fonts.put(basicFontGenerator, basicFonts); - if (KRFontGenerator != null) fonts.put(KRFontGenerator, KRFonts); - if (SCFontGenerator != null) fonts.put(SCFontGenerator, SCFonts); - if (JPFontGenerator != null) fonts.put(JPFontGenerator, JPFonts); + if (basicFontGenerator != null) fonts.put(basicFontGenerator, new HashMap<>()); + if (KRFontGenerator != null) fonts.put(KRFontGenerator, new HashMap<>()); + if (SCFontGenerator != null) fonts.put(SCFontGenerator, new HashMap<>()); + if (JPFontGenerator != null) fonts.put(JPFontGenerator, new HashMap<>()); //would be nice to use RGBA4444 to save memory, but this causes problems on some gpus =S packer = new PixmapPacker(pageSize, pageSize, Pixmap.Format.RGBA8888, 1, false); } - - @Override - public void resetGenerators() { - if (fonts != null) { - for (FreeTypeFontGenerator generator : fonts.keySet()) { - for (BitmapFont f : fonts.get(generator).values()) { - f.dispose(); - } - fonts.get(generator).clear(); - generator.dispose(); - } - fonts.clear(); - if (packer != null) { - for (PixmapPacker.Page p : packer.getPages()) { - p.getTexture().dispose(); - } - packer.dispose(); - } - fonts = null; - } - setupFontGenerators(pageSize, systemfont); - } - - @Override - //FIXME it would be really nice to keep the local texture data and just re-send it to the GPU - public void reloadGenerators() { - if (packer != null) { - for (FreeTypeFontGenerator generator : fonts.keySet()) { - for (BitmapFont f : fonts.get(generator).values()) { - f.dispose(); - } - fonts.get(generator).clear(); - } - if (packer != null) { - for (PixmapPacker.Page p : packer.getPages()) { - p.getTexture().dispose(); - } - packer.dispose(); - } - packer = new PixmapPacker(pageSize, pageSize, Pixmap.Format.RGBA8888, 1, false); - } - } private static Pattern KRMatcher = Pattern.compile("\\p{InHangul_Syllables}"); private static Pattern SCMatcher = Pattern.compile("\\p{InCJK_Unified_Ideographs}|\\p{InCJK_Symbols_and_Punctuation}|\\p{InHalfwidth_and_Fullwidth_Forms}"); private static Pattern JPMatcher = Pattern.compile("\\p{InHiragana}|\\p{InKatakana}"); - - private static FreeTypeFontGenerator getGeneratorForString( String input ){ + + @Override + protected FreeTypeFontGenerator getGeneratorForString( String input ){ if (KRMatcher.matcher(input).find()){ return KRFontGenerator; } else if (SCMatcher.matcher(input).find()){ @@ -361,49 +292,6 @@ public class AndroidPlatformSupport extends PlatformSupport { } } - @Override - public BitmapFont getFont(int size, String text) { - FreeTypeFontGenerator generator = getGeneratorForString(text); - - if (generator == null){ - return null; - } - - if (!fonts.get(generator).containsKey(size)) { - FreeTypeFontGenerator.FreeTypeFontParameter parameters = new FreeTypeFontGenerator.FreeTypeFontParameter(); - parameters.size = size; - parameters.flip = true; - parameters.borderWidth = parameters.size / 10f; - if (size >= 20){ - parameters.renderCount = 2; - } else { - parameters.renderCount = 3; - } - parameters.hinting = FreeTypeFontGenerator.Hinting.None; - parameters.spaceX = -(int) parameters.borderWidth; - parameters.incremental = true; - if (generator == basicFontGenerator){ - //if we're using latin/cyrillic, we can safely pre-generate some common letters - //(we define common as >4% frequency in english) - parameters.characters = "�etaoinshrdl"; - } else { - parameters.characters = "�"; - } - parameters.packer = packer; - - try { - BitmapFont font = generator.generateFont(parameters); - font.getData().missingGlyph = font.getData().getGlyph('�'); - fonts.get(generator).put(size, font); - } catch ( Exception e ){ - Game.reportException(e); - return null; - } - } - - return fonts.get(generator).get(size); - } - //splits on newlines, underscores, and chinese/japaneses characters private Pattern regularsplitter = Pattern.compile( "(?<=\n)|(?=\n)|(?<=_)|(?=_)|" + diff --git a/desktop/src/main/java/com/shatteredpixel/shatteredpixeldungeon/desktop/DesktopPlatformSupport.java b/desktop/src/main/java/com/shatteredpixel/shatteredpixeldungeon/desktop/DesktopPlatformSupport.java index affbe7a71..c3dc73ba2 100644 --- a/desktop/src/main/java/com/shatteredpixel/shatteredpixeldungeon/desktop/DesktopPlatformSupport.java +++ b/desktop/src/main/java/com/shatteredpixel/shatteredpixeldungeon/desktop/DesktopPlatformSupport.java @@ -80,20 +80,13 @@ public class DesktopPlatformSupport extends PlatformSupport { callback.onSelect(true, result.replace("\r\n", "").replace("\n", "")); } } - - private int pageSize; - private PixmapPacker packer; - private boolean systemfont; + + /* FONT SUPPORT */ //custom pixel font, for use with Latin and Cyrillic languages private static FreeTypeFontGenerator basicFontGenerator; - private static HashMap basicFonts = new HashMap<>(); - //droid sans fallback, for asian fonts private static FreeTypeFontGenerator asianFontGenerator; - private static HashMap asianFonts = new HashMap<>(); - - private static HashMap> fonts; @Override public void setupFontGenerators(int pageSize, boolean systemfont) { @@ -103,23 +96,8 @@ public class DesktopPlatformSupport extends PlatformSupport { } this.pageSize = pageSize; this.systemfont = systemfont; - - if (fonts != null){ - for (FreeTypeFontGenerator generator : fonts.keySet()){ - for (BitmapFont f : fonts.get(generator).values()){ - f.dispose(); - } - fonts.get(generator).clear(); - generator.dispose(); - } - fonts.clear(); - if (packer != null){ - for (PixmapPacker.Page p : packer.getPages()){ - p.getTexture().dispose(); - } - packer.dispose(); - } - } + + resetGenerators(false); fonts = new HashMap<>(); if (systemfont) { @@ -129,49 +107,18 @@ public class DesktopPlatformSupport extends PlatformSupport { asianFontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/droid_sans.ttf")); } - fonts.put(basicFontGenerator, basicFonts); - fonts.put(asianFontGenerator, asianFonts); + fonts.put(basicFontGenerator, new HashMap<>()); + fonts.put(asianFontGenerator, new HashMap<>()); packer = new PixmapPacker(pageSize, pageSize, Pixmap.Format.RGBA8888, 1, false); } - @Override - public void resetGenerators() { - if (fonts != null) { - for (FreeTypeFontGenerator generator : fonts.keySet()) { - for (BitmapFont f : fonts.get(generator).values()) { - f.dispose(); - } - fonts.get(generator).clear(); - generator.dispose(); - } - fonts.clear(); - if (packer != null) { - for (PixmapPacker.Page p : packer.getPages()) { - p.getTexture().dispose(); - } - packer.dispose(); - } - fonts = null; - } - setupFontGenerators(pageSize, systemfont); - } - - @Override - public void reloadGenerators() { - if (packer != null) { - for (PixmapPacker.Page p : packer.getPages()) { - p.getTexture().dispose(); - p.updateTexture(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest, false); - } - } - } - private static Pattern asianMatcher = Pattern.compile("\\p{InHangul_Syllables}|" + "\\p{InCJK_Unified_Ideographs}|\\p{InCJK_Symbols_and_Punctuation}|\\p{InHalfwidth_and_Fullwidth_Forms}|" + "\\p{InHiragana}|\\p{InKatakana}"); - - private static FreeTypeFontGenerator getGeneratorForString( String input ){ + + @Override + protected FreeTypeFontGenerator getGeneratorForString( String input ){ if (asianMatcher.matcher(input).find()){ return asianFontGenerator; } else { @@ -179,50 +126,6 @@ public class DesktopPlatformSupport extends PlatformSupport { } } - - @Override - public BitmapFont getFont(int size, String text) { - FreeTypeFontGenerator generator = getGeneratorForString(text); - - if (generator == null){ - return null; - } - - if (!fonts.get(generator).containsKey(size)) { - FreeTypeFontGenerator.FreeTypeFontParameter parameters = new FreeTypeFontGenerator.FreeTypeFontParameter(); - parameters.size = size; - parameters.flip = true; - parameters.borderWidth = parameters.size / 10f; - if (size >= 20){ - parameters.renderCount = 2; - } else { - parameters.renderCount = 3; - } - parameters.hinting = FreeTypeFontGenerator.Hinting.None; - parameters.spaceX = -(int) parameters.borderWidth; - parameters.incremental = true; - if (generator == basicFontGenerator){ - //if we're using latin/cyrillic, we can safely pre-generate some common letters - //(we define common as >4% frequency in english) - parameters.characters = "�etaoinshrdl"; - } else { - parameters.characters = "�"; - } - parameters.packer = packer; - - try { - BitmapFont font = generator.generateFont(parameters); - font.getData().missingGlyph = font.getData().getGlyph('�'); - fonts.get(generator).put(size, font); - } catch ( Exception e ){ - Game.reportException(e); - return null; - } - } - - return fonts.get(generator).get(size); - } - //splits on newlines, underscores, and chinese/japaneses characters private Pattern regularsplitter = Pattern.compile( "(?<=\n)|(?=\n)|(?<=_)|(?=_)|" + @@ -247,5 +150,4 @@ public class DesktopPlatformSupport extends PlatformSupport { return regularsplitter.split(text); } } - } diff --git a/ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSPlatformSupport.java b/ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSPlatformSupport.java index f01e53976..dde2be7b2 100644 --- a/ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSPlatformSupport.java +++ b/ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSPlatformSupport.java @@ -66,19 +66,12 @@ public class IOSPlatformSupport extends PlatformSupport { AudioServices.playSystemSound(1520); } - private int pageSize; - private PixmapPacker packer; - private boolean systemfont; + /* FONT SUPPORT */ //custom pixel font, for use with Latin and Cyrillic languages private static FreeTypeFontGenerator basicFontGenerator; - private static HashMap basicFonts = new HashMap<>(); - //droid sans fallback, for asian fonts private static FreeTypeFontGenerator asianFontGenerator; - private static HashMap asianFonts = new HashMap<>(); - - private static HashMap> fonts; @Override public void setupFontGenerators(int pageSize, boolean systemfont) { @@ -89,22 +82,7 @@ public class IOSPlatformSupport extends PlatformSupport { this.pageSize = pageSize; this.systemfont = systemfont; - if (fonts != null){ - for (FreeTypeFontGenerator generator : fonts.keySet()){ - for (BitmapFont f : fonts.get(generator).values()){ - f.dispose(); - } - fonts.get(generator).clear(); - generator.dispose(); - } - fonts.clear(); - if (packer != null){ - for (PixmapPacker.Page p : packer.getPages()){ - p.getTexture().dispose(); - } - packer.dispose(); - } - } + resetGenerators(false); fonts = new HashMap<>(); if (systemfont) { @@ -114,49 +92,18 @@ public class IOSPlatformSupport extends PlatformSupport { asianFontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/droid_sans.ttf")); } - fonts.put(basicFontGenerator, basicFonts); - fonts.put(asianFontGenerator, asianFonts); + fonts.put(basicFontGenerator, new HashMap<>()); + fonts.put(asianFontGenerator, new HashMap<>()); packer = new PixmapPacker(pageSize, pageSize, Pixmap.Format.RGBA8888, 1, false); } - @Override - public void resetGenerators() { - if (fonts != null) { - for (FreeTypeFontGenerator generator : fonts.keySet()) { - for (BitmapFont f : fonts.get(generator).values()) { - f.dispose(); - } - fonts.get(generator).clear(); - generator.dispose(); - } - fonts.clear(); - if (packer != null) { - for (PixmapPacker.Page p : packer.getPages()) { - p.getTexture().dispose(); - } - packer.dispose(); - } - fonts = null; - } - setupFontGenerators(pageSize, systemfont); - } - - @Override - public void reloadGenerators() { - if (packer != null) { - for (PixmapPacker.Page p : packer.getPages()) { - p.getTexture().dispose(); - p.updateTexture(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest, false); - } - } - } - private static Pattern asianMatcher = Pattern.compile("\\p{InHangul_Syllables}|" + "\\p{InCJK_Unified_Ideographs}|\\p{InCJK_Symbols_and_Punctuation}|\\p{InHalfwidth_and_Fullwidth_Forms}|" + "\\p{InHiragana}|\\p{InKatakana}"); - private static FreeTypeFontGenerator getGeneratorForString( String input ){ + @Override + protected FreeTypeFontGenerator getGeneratorForString( String input ){ if (asianMatcher.matcher(input).find()){ return asianFontGenerator; } else { @@ -164,50 +111,6 @@ public class IOSPlatformSupport extends PlatformSupport { } } - - @Override - public BitmapFont getFont(int size, String text) { - FreeTypeFontGenerator generator = getGeneratorForString(text); - - if (generator == null){ - return null; - } - - if (!fonts.get(generator).containsKey(size)) { - FreeTypeFontGenerator.FreeTypeFontParameter parameters = new FreeTypeFontGenerator.FreeTypeFontParameter(); - parameters.size = size; - parameters.flip = true; - parameters.borderWidth = parameters.size / 10f; - if (size >= 20){ - parameters.renderCount = 2; - } else { - parameters.renderCount = 3; - } - parameters.hinting = FreeTypeFontGenerator.Hinting.None; - parameters.spaceX = -(int) parameters.borderWidth; - parameters.incremental = true; - if (generator == basicFontGenerator){ - //if we're using latin/cyrillic, we can safely pre-generate some common letters - //(we define common as >4% frequency in english) - parameters.characters = "�etaoinshrdl"; - } else { - parameters.characters = "�"; - } - parameters.packer = packer; - - try { - BitmapFont font = generator.generateFont(parameters); - font.getData().missingGlyph = font.getData().getGlyph('�'); - fonts.get(generator).put(size, font); - } catch ( Exception e ){ - Game.reportException(e); - return null; - } - } - - return fonts.get(generator).get(size); - } - //splits on newlines, underscores, and chinese/japaneses characters private Pattern regularsplitter = Pattern.compile( "(?<=\n)|(?=\n)|(?<=_)|(?=_)|" +