diff --git a/forge-gui-mobile/src/forge/Forge.java b/forge-gui-mobile/src/forge/Forge.java index 6978b2983f3..9b9d08c36be 100644 --- a/forge-gui-mobile/src/forge/Forge.java +++ b/forge-gui-mobile/src/forge/Forge.java @@ -79,7 +79,10 @@ public class Forge implements ApplicationListener { public void run() { FModel.initialize(splashScreen.getProgressBar()); - splashScreen.getProgressBar().setDescription("Finishing startup..."); + splashScreen.getProgressBar().setDescription("Loading fonts"); + FSkinFont.preloadAll(); + + splashScreen.getProgressBar().setDescription("Finishing startup"); Gdx.app.postRunnable(new Runnable() { @Override diff --git a/forge-gui-mobile/src/forge/GuiMobile.java b/forge-gui-mobile/src/forge/GuiMobile.java index e8396600d73..5c5325d02d7 100644 --- a/forge-gui-mobile/src/forge/GuiMobile.java +++ b/forge-gui-mobile/src/forge/GuiMobile.java @@ -46,7 +46,6 @@ import forge.sound.IAudioClip; import forge.toolbox.FOptionPane; import forge.toolbox.GuiChoose; import forge.util.ITriggerEvent; -import forge.util.ThreadUtil; import forge.util.WaitCallback; import forge.util.WaitRunnable; import forge.util.gui.SGuiChoose; @@ -79,7 +78,7 @@ public class GuiMobile implements IGuiBase { @Override public boolean isGuiThread() { - return !ThreadUtil.isGameThread(); + return Thread.currentThread().getName().startsWith("LWJGL"); } @Override diff --git a/forge-gui-mobile/src/forge/assets/FSkinFont.java b/forge-gui-mobile/src/forge/assets/FSkinFont.java index c52ebc901ec..014d00c392c 100644 --- a/forge-gui-mobile/src/forge/assets/FSkinFont.java +++ b/forge-gui-mobile/src/forge/assets/FSkinFont.java @@ -8,21 +8,22 @@ import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.BitmapFont.BitmapFontData; import com.badlogic.gdx.graphics.g2d.PixmapPacker; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; import com.badlogic.gdx.graphics.glutils.PixmapTextureData; import com.badlogic.gdx.utils.Array; +import forge.FThreads; import forge.util.Utils; public class FSkinFont { public static final int MIN_FONT_SIZE = Math.round(8 / Utils.MAX_RATIO); + public static final int MAX_FONT_SIZE = Math.round(72 / Utils.MAX_RATIO); private static final String TTF_FILE = "font1.ttf"; private static final Map fonts = new HashMap(); - private static final int FONT_PAGE_SIZE = 256; - private static final int MAX_FONT_SIZE = 72; //don't generate fonts larger than this, use scaling instead public static FSkinFont get(final int size0) { FSkinFont skinFont = fonts.get(size0); @@ -43,6 +44,13 @@ public class FSkinFont { } } + //pre-load all supported font sizes + public static void preloadAll() { + for (int size = MIN_FONT_SIZE; size <= MAX_FONT_SIZE; size++) { + get(size); + } + } + public static void updateAll() { for (FSkinFont skinFont : fonts.values()) { skinFont.updateFont(); @@ -66,70 +74,76 @@ public class FSkinFont { } private void updateFont() { - float scale = 1; int fontSize = (int)Utils.scaleMax(size); - try { - if (fontSize > MAX_FONT_SIZE) { //scale if larger than max font size - scale = (float)fontSize / (float)MAX_FONT_SIZE; - fontSize = MAX_FONT_SIZE; - } - String fontName = "f" + fontSize; - FileHandle fontFile = Gdx.files.absolute(FSkin.getFontDir() + fontName + ".fnt"); - if (fontFile.exists()) { - font = new BitmapFont(fontFile); - } - else { - FileHandle ttfFile = Gdx.files.absolute(FSkin.getDir() + TTF_FILE); - font = generateFont(ttfFile, fontName, fontSize); - } + String fontName = "f" + fontSize; + FileHandle fontFile = Gdx.files.absolute(FSkin.getFontDir() + fontName + ".fnt"); + if (fontFile.exists()) { + final BitmapFontData data = new BitmapFontData(fontFile, false); + FThreads.invokeInEdtNowOrLater(new Runnable() { + @Override + public void run() { //font must be initialized on UI thread + font = new BitmapFont(data, (TextureRegion)null, true); + } + }); } - catch (Exception e) { - e.printStackTrace(); - } - if (font == null) { - font = new BitmapFont(); //use scaled default font as fallback - scale = (float)fontSize / 15; //default font has size 15 - } - font.setUseIntegerPositions(true); //prevent parts of text getting cut off at times - if (scale != 1) { - font.setScale(scale); + else { + FileHandle ttfFile = Gdx.files.absolute(FSkin.getDir() + TTF_FILE); + generateFont(ttfFile, fontName, fontSize); } } - private BitmapFont generateFont(FileHandle ttfFile, String fontName, int fontSize) { - if (!ttfFile.exists()) { return null; } + private void generateFont(final FileHandle ttfFile, final String fontName, final int fontSize) { + if (!ttfFile.exists()) { return; } - FreeTypeFontGenerator generator = new FreeTypeFontGenerator(ttfFile); + final FreeTypeFontGenerator generator = new FreeTypeFontGenerator(ttfFile); - PixmapPacker packer = new PixmapPacker(FONT_PAGE_SIZE, FONT_PAGE_SIZE, Pixmap.Format.RGBA8888, 2, false); - FreeTypeFontGenerator.FreeTypeBitmapFontData fontData = generator.generateData(fontSize, FreeTypeFontGenerator.DEFAULT_CHARS, false, packer); - Array pages = packer.getPages(); - TextureRegion[] texRegions = new TextureRegion[pages.size]; - for (int i=0; i= 28) { + pageSize = 256; + } + else { + pageSize = 128; } - BitmapFont font = new BitmapFont(fontData, texRegions, false); + //only generate images for characters that could be used by Forge + String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890\"!?'.,;:()[]{}<>|/@\\^$-%+=#_&*"; - //create .fnt and .png files for font - FileHandle fontFile = Gdx.files.absolute(FSkin.getFontDir() + fontName + ".fnt"); - FileHandle pixmapDir = Gdx.files.absolute(FSkin.getFontDir()); - BitmapFontWriter.setOutputFormat(BitmapFontWriter.OutputFormat.Text); + final PixmapPacker packer = new PixmapPacker(pageSize, pageSize, Pixmap.Format.RGBA8888, 2, false); + final FreeTypeFontGenerator.FreeTypeBitmapFontData fontData = generator.generateData(fontSize, chars, false, packer); + final Array pages = packer.getPages(); - String[] pageRefs = BitmapFontWriter.writePixmaps(packer.getPages(), pixmapDir, fontName); - BitmapFontWriter.writeFont(font.getData(), pageRefs, fontFile, new BitmapFontWriter.FontInfo(fontName, fontSize), 1, 1); + //finish generating font on UI thread + FThreads.invokeInEdtNowOrLater(new Runnable() { + @Override + public void run() { + TextureRegion[] textureRegions = new TextureRegion[pages.size]; + for (int i = 0; i < pages.size; i++) { + PixmapPacker.Page p = pages.get(i); + Texture texture = new Texture(new PixmapTextureData(p.getPixmap(), p.getPixmap().getFormat(), false, false)) { + @Override + public void dispose() { + super.dispose(); + getTextureData().consumePixmap().dispose(); + } + }; + texture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest); + textureRegions[i] = new TextureRegion(texture); + } - generator.dispose(); - packer.dispose(); - return font; + font = new BitmapFont(fontData, textureRegions, true); + + //create .fnt and .png files for font + FileHandle fontFile = Gdx.files.absolute(FSkin.getFontDir() + fontName + ".fnt"); + FileHandle pixmapDir = Gdx.files.absolute(FSkin.getFontDir()); + BitmapFontWriter.setOutputFormat(BitmapFontWriter.OutputFormat.Text); + + String[] pageRefs = BitmapFontWriter.writePixmaps(packer.getPages(), pixmapDir, fontName); + BitmapFontWriter.writeFont(font.getData(), pageRefs, fontFile, new BitmapFontWriter.FontInfo(fontName, fontSize), 1, 1); + + generator.dispose(); + packer.dispose(); + } + }); } }