diff --git a/core/src/com/unciv/UncivGame.kt b/core/src/com/unciv/UncivGame.kt index 95f572f222..dfc5811136 100644 --- a/core/src/com/unciv/UncivGame.kt +++ b/core/src/com/unciv/UncivGame.kt @@ -39,7 +39,6 @@ class UncivGame(val version: String) : Game() { override fun create() { Current = this - if(Gdx.app.type!= Application.ApplicationType.Desktop) viewEntireMapForDebug=false Gdx.input.setCatchKey(Input.Keys.BACK, true) diff --git a/core/src/com/unciv/models/gamebasics/GameBasics.kt b/core/src/com/unciv/models/gamebasics/GameBasics.kt index c217622674..524406df8c 100644 --- a/core/src/com/unciv/models/gamebasics/GameBasics.kt +++ b/core/src/com/unciv/models/gamebasics/GameBasics.kt @@ -38,6 +38,8 @@ object GameBasics { } init { + + val gameBasicsStartTime = System.currentTimeMillis() val techColumns = getFromJson(Array::class.java, "Techs") for (techColumn in techColumns) { for (tech in techColumn.techs) { @@ -77,11 +79,14 @@ object GameBasics { Difficulties += createHashmap(getFromJson(Array::class.java, "Difficulties")) + val gameBasicsLoadTime = System.currentTimeMillis() - gameBasicsStartTime + println("Loading game basics - "+gameBasicsLoadTime+"ms") // Apparently you can't iterate over the files in a directory when running out of a .jar... // https://www.badlogicgames.com/forum/viewtopic.php?f=11&t=27250 // which means we need to list everything manually =/ + val translationStart = System.currentTimeMillis() val translationFileNames = listOf("Buildings","Diplomacy,Trade,Nations", "NewGame,SaveGame,LoadGame,Options", "Notifications","Other","Policies","Techs", "Terrains,Resources,Improvements","Units,Promotions") @@ -92,6 +97,8 @@ object GameBasics { Translations.add(file.readString(Charsets.UTF_8.name())) } } + val translationFilesTime = System.currentTimeMillis() - translationStart + println("Loading translation files - "+translationFilesTime+"ms") } } diff --git a/core/src/com/unciv/ui/utils/CameraStageBaseScreen.kt b/core/src/com/unciv/ui/utils/CameraStageBaseScreen.kt index 0c0cffaac9..dffa431851 100644 --- a/core/src/com/unciv/ui/utils/CameraStageBaseScreen.kt +++ b/core/src/com/unciv/ui/utils/CameraStageBaseScreen.kt @@ -62,6 +62,8 @@ open class CameraStageBaseScreen : Screen { } fun resetFonts(){ + val startTime = System.currentTimeMillis() + skin.get(TextButton.TextButtonStyle::class.java).font = Fonts().getFont(45).apply { data.setScale(20/45f) } skin.get(CheckBox.CheckBoxStyle::class.java).font= Fonts().getFont(45).apply { data.setScale(20/45f) } skin.get(Label.LabelStyle::class.java).apply { @@ -72,6 +74,10 @@ open class CameraStageBaseScreen : Screen { skin.get(SelectBox.SelectBoxStyle::class.java).font = Fonts().getFont(45).apply { data.setScale(20/45f) } skin.get(SelectBox.SelectBoxStyle::class.java).listStyle.font = Fonts().getFont(45).apply { data.setScale(20/45f) } skin.get(CheckBox.CheckBoxStyle::class.java).fontColor= Color.WHITE + + + val resetFontsTime = System.currentTimeMillis() - startTime + println("Resetting fonts - "+resetFontsTime+"ms") } internal var batch: Batch = SpriteBatch() } diff --git a/core/src/com/unciv/ui/utils/Fonts.kt b/core/src/com/unciv/ui/utils/Fonts.kt index 9bd1a065db..c9babbe104 100644 --- a/core/src/com/unciv/ui/utils/Fonts.kt +++ b/core/src/com/unciv/ui/utils/Fonts.kt @@ -17,6 +17,8 @@ class Fonts { fun getCharactersForFont(language:String=""): String { if (characterSetCache.containsKey(language)) return characterSetCache[language]!! + val startTime = System.currentTimeMillis() + val defaultText = "AÀÁBCČĆDĐEÈÉFGHIÌÍÏJKLMNOÒÓÖPQRSŠTUÙÚÜVWXYZŽaäàâăbcčćçdđeéèfghiìîjklmnoòöpqrsșštțuùüvwxyzž" + "АБВГҐДЂЕЁЄЖЗЅИІЇЙЈКЛЉМНЊОПРСТЋУЎФХЦЧЏШЩЪЫЬЭЮЯабвгґдђеёєжзѕиіїйјклљмнњопрстћуўфхцчџшщъыьэюя" + // Russian "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωάßΆέΈέΉίϊΐΊόΌύΰϋΎΫΏ" + // Greek @@ -43,6 +45,10 @@ class Fonts { } val characterSetString = charSet.joinToString("") characterSetCache[language]=characterSetString + + val totalTime = System.currentTimeMillis() - startTime + println("Loading characters for font - "+totalTime+"ms") + return characterSetString } @@ -55,7 +61,11 @@ class Fonts { val font=NativeFont(NativeFontPaint(size)) val charsForFont = getCharactersForFont(if(isUniqueFont) language else "") + + font.appendText(charsForFont) + + fontCache[keyForFont] = font return font } diff --git a/core/src/core/java/nativefont/NativeFont.java b/core/src/core/java/nativefont/NativeFont.java deleted file mode 100755 index 5652593638..0000000000 --- a/core/src/core/java/nativefont/NativeFont.java +++ /dev/null @@ -1,299 +0,0 @@ -package core.java.nativefont; - -import com.badlogic.gdx.Application; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Color; -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.PixmapPacker; -import com.badlogic.gdx.graphics.g2d.PixmapPacker.Page; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.GdxRuntimeException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; - -/** - * Created by tian on 2016/10/2. - */ - -public class NativeFont extends BitmapFont { - private static NativeFontListener listener; - private static boolean robovm; - - private Set charSet; - private BitmapFontData data; - private HashMap emojiSet; - private Texture.TextureFilter magFilter; - private Texture.TextureFilter minFilter; - private PixmapPacker packer; - private int pageWidth; - private NativeFontPaint paint; - private int size; - - public class EmojiDate { - public String path; - public int size; - - public EmojiDate(String path, int size) { - this.path = path; - this.size = size; - } - } - - - public NativeFont() { - this(new NativeFontPaint()); - } - - public NativeFont(NativeFontPaint paint) { - super(new BitmapFontData(), new TextureRegion(), false); - this.pageWidth = 512; - this.paint = new NativeFontPaint(); - this.charSet = new HashSet(); - this.packer = null; - this.minFilter = Texture.TextureFilter.Linear; - this.magFilter = Texture.TextureFilter.Linear; - this.emojiSet = new HashMap(); - updataSize(paint.getTextSize()); - if (listener == null) createListener(); - this.paint = paint; - } - - private void createListener() { - String className = "core.java.nativefont.NativeFont"; - if (Gdx.app.getType() == Application.ApplicationType.Desktop) { - className += "Desktop"; - } else if (Gdx.app.getType() == Application.ApplicationType.Android) { - className += "Android"; - } else if (Gdx.app.getType() == Application.ApplicationType.iOS) { - if (robovm) - className += "IOS"; - else - className += "IOSMoe"; - }else if (Gdx.app.getType() == Application.ApplicationType.WebGL){ - className += "Html"; - } - try { - Class claz = (Class) Gdx.app.getClass().getClassLoader().loadClass(className); - listener = claz.newInstance(); - } catch (Exception e) { - throw new GdxRuntimeException("Class Not Found:" + e.getMessage()); - } - } - - public void updataSize(int newSize) { - this.data = getData(); - this.size = Math.max(newSize, this.size); - this.data.down = (float) (-this.size); - this.data.ascent = (float) (-this.size); - this.data.capHeight = (float) this.size; - this.data.lineHeight = (float) this.size; - } - - public NativeFont setTextColor(Color color) { - this.paint.setColor(color); - return this; - } - - public NativeFont setStrokeColor(Color color) { - this.paint.setStrokeColor(color); - return this; - } - - public NativeFont setStrokeWidth(int width) { - this.paint.setStrokeWidth(width); - return this; - } - - public NativeFont setSize(int size) { - this.paint.setTextSize(size); - return this; - } - - public NativeFont setBold(boolean istrue) { - this.paint.setFakeBoldText(istrue); - return this; - } - - public NativeFont setUnderline(boolean istrue) { - this.paint.setUnderlineText(istrue); - return this; - } - - public NativeFont setStrikeThru(boolean istrue) { - this.paint.setStrikeThruText(istrue); - return this; - } - - public NativeFont setPaint(NativeFontPaint paint) { - this.paint = paint; - return this; - } - - public NativeFont addEmojiPath(String emojiKey, String imgPath, int size) { - this.emojiSet.put(emojiKey, new EmojiDate(imgPath, size)); - return this; - } - - public NativeFont appendEmoji(String txt, String imgname, int size) { - Pixmap pixmap = new Pixmap(Gdx.files.internal(imgname)); - // Pixmap.setFilter(Pixmap.Filter.BiLinear); - Pixmap pixmap2 = new Pixmap(size, size, Pixmap.Format.RGBA8888); - pixmap2.setFilter(Pixmap.Filter.BiLinear); - pixmap2.drawPixmap(pixmap, 0, 0, pixmap.getWidth(), pixmap.getHeight(), 0, 0, size, size); - pixmap.dispose(); - appendEmoji(txt, pixmap2); - return this; - } - - public NativeFont appendEmoji(String txt, Pixmap pixmap) { - if (this.charSet.add(txt)) { - if (this.packer == null) { - this.packer = new PixmapPacker(this.pageWidth, this.pageWidth, Pixmap.Format.RGBA8888, 2, false); - } - putGlyph(txt.charAt(0), pixmap); - updataSize(pixmap.getHeight()); - upData(); - } - return this; - } - - public NativeFont createText(String characters) { - if (!(characters == null || characters.length() == 0)) { - create(characters, true); - end(); - } - return this; - } - - public NativeFont appendText(String characters) { - if (!(characters == null || characters.length() == 0)) { - create(characters, false); - } - return this; - } - - private void create(String characters, boolean haveMinPageSize) { - char c; - characters = characters.replaceAll("[\\t\\n\\x0B\\f\\r]", ""); - Array cs = new Array(); - for (char c2 : characters.toCharArray()) { - if (this.charSet.add((String.valueOf(c2)))) { - cs.add((String.valueOf(c2))); - } - } - if (haveMinPageSize) { - this.pageWidth = (this.paint.getTextSize() + 2) * ((int) (Math.sqrt((double) cs.size) + 1.0d)); - } - if (this.packer == null) { - this.packer = new PixmapPacker(this.pageWidth, this.pageWidth, Pixmap.Format.RGBA8888, 2, false); - } - - char c2; - for (int i = 0; i < cs.size; i++) { - String txt = cs.get(i); - c2 = txt.charAt(0); - String css = String.valueOf(c2); - if (this.emojiSet.get(css) != null) { - this.charSet.remove(css); - EmojiDate date = this.emojiSet.get(css); - appendEmoji(c2 + "", date.path, date.size); - } else { - putGlyph(c2, listener.getFontPixmap(txt, this.paint)); - } - } - - updataSize(this.size); - upData(); - if (getRegions().size == 1) { - setOwnsTexture(true); - } else { - setOwnsTexture(false); - } - } - - private void putGlyph(char c, Pixmap pixmap) { - Rectangle rect = this.packer.pack(String.valueOf(c), pixmap); - pixmap.dispose(); - int pIndex = this.packer.getPageIndex((String.valueOf(c))); - Glyph glyph = new Glyph(); - glyph.id = c; - glyph.page = pIndex; - glyph.srcX = (int) rect.x; - glyph.srcY = (int) rect.y; - glyph.width = (int) rect.width; - glyph.height = (int) rect.height; - glyph.xadvance = glyph.width; - this.data.setGlyph(c, glyph); - } - - private void upData() { - Glyph spaceGlyph = this.data.getGlyph(' '); - if (spaceGlyph == null) { - spaceGlyph = new Glyph(); - Glyph xadvanceGlyph = this.data.getGlyph('l'); - if (xadvanceGlyph == null) { - xadvanceGlyph = this.data.getFirstGlyph(); - } - spaceGlyph.xadvance = xadvanceGlyph.xadvance; - spaceGlyph.id = 32; - this.data.setGlyph(32, spaceGlyph); - } - this.data.spaceXadvance = (float) (spaceGlyph.xadvance + spaceGlyph.width); - - Array pages = this.packer.getPages(); - Array regions = getRegions(); - int regSize = regions.size - 1; - for (int i = 0; i < pages.size; i++) { - Page p = pages.get(i); - if (i > regSize) { - p.updateTexture(this.minFilter, this.magFilter, false); - regions.add(new TextureRegion(p.getTexture())); - } else { - if (p.updateTexture(this.minFilter, this.magFilter, false)) { - regions.set(i, new TextureRegion(p.getTexture())); - } - } - } - - for (Glyph[] page : this.data.glyphs) { - if (page == null) continue; - - for (Glyph glyph : page) { - if (glyph != null) { - TextureRegion region = getRegions().get(glyph.page); - if (region == null) { - throw new IllegalArgumentException("BitmapFont texture region array cannot contain null elements."); - } - this.data.setGlyphRegion(glyph, region); - } - } - } - } - - public NativeFont end() { - this.paint = null; - this.charSet.clear(); - this.charSet = null; - this.packer.dispose(); - this.packer = null; - return this; - } - - public void dispose() { - end(); - super.dispose(); - } - - public static void setRobovm() { - robovm = true; - } - - public static NativeFontListener getListener() { - return listener; - } -} diff --git a/core/src/core/java/nativefont/NativeFont.kt b/core/src/core/java/nativefont/NativeFont.kt new file mode 100644 index 0000000000..207191f041 --- /dev/null +++ b/core/src/core/java/nativefont/NativeFont.kt @@ -0,0 +1,272 @@ +package core.java.nativefont + +import com.badlogic.gdx.Application +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.graphics.Pixmap +import com.badlogic.gdx.graphics.Texture.TextureFilter +import com.badlogic.gdx.graphics.g2d.BitmapFont +import com.badlogic.gdx.graphics.g2d.PixmapPacker +import com.badlogic.gdx.graphics.g2d.TextureRegion +import com.badlogic.gdx.utils.Array +import com.badlogic.gdx.utils.GdxRuntimeException +import java.util.* + +/** + * Created by tian on 2016/10/2. + */ +class NativeFont @JvmOverloads constructor(paint: NativeFontPaint = NativeFontPaint()) : BitmapFont(BitmapFontData(), TextureRegion(), false) { + private var charSet: MutableSet? + private val emojiSet: HashMap + private val magFilter: TextureFilter + private val minFilter: TextureFilter + private var packer: PixmapPacker? + private var pageWidth = 512 + private var paint: NativeFontPaint? + private var size = 0 + + inner class EmojiDate(var path: String, var size: Int) + + private fun createListener() { + var className = "core.java.nativefont.NativeFont" + if (Gdx.app.type == Application.ApplicationType.Desktop) { + className += "Desktop" + } else if (Gdx.app.type == Application.ApplicationType.Android) { + className += "Android" + } else if (Gdx.app.type == Application.ApplicationType.iOS) { + className += if (robovm) "IOS" else "IOSMoe" + } else if (Gdx.app.type == Application.ApplicationType.WebGL) { + className += "Html" + } + listener = try { + val claz = Gdx.app.javaClass.classLoader.loadClass(className) as Class + claz.newInstance() + } catch (e: Exception) { + throw GdxRuntimeException("Class Not Found:" + e.message) + } + } + + fun updataSize(newSize: Int) { + size = Math.max(newSize, size) + this.data.down = (-size).toFloat() + this.data.ascent = (-size).toFloat() + this.data.capHeight = size.toFloat() + this.data.lineHeight = size.toFloat() + } + + fun setTextColor(color: Color?): NativeFont { + paint!!.color = color + return this + } + + fun setStrokeColor(color: Color?): NativeFont { + paint!!.strokeColor = color + return this + } + + fun setStrokeWidth(width: Int): NativeFont { + paint!!.strokeWidth = width + return this + } + + fun setSize(size: Int): NativeFont { + paint!!.textSize = size + return this + } + + fun setBold(istrue: Boolean): NativeFont { + paint!!.fakeBoldText = istrue + return this + } + + fun setUnderline(istrue: Boolean): NativeFont { + paint!!.underlineText = istrue + return this + } + + fun setStrikeThru(istrue: Boolean): NativeFont { + paint!!.strikeThruText = istrue + return this + } + + fun setPaint(paint: NativeFontPaint?): NativeFont { + this.paint = paint + return this + } + + fun addEmojiPath(emojiKey: String?, imgPath: String, size: Int): NativeFont { + emojiSet[emojiKey] = EmojiDate(imgPath, size) + return this + } + + fun appendEmoji(txt: String, imgname: String?, size: Int): NativeFont { + val pixmap = Pixmap(Gdx.files.internal(imgname)) + // Pixmap.setFilter(Pixmap.Filter.BiLinear); + val pixmap2 = Pixmap(size, size, Pixmap.Format.RGBA8888) + pixmap2.filter = Pixmap.Filter.BiLinear + pixmap2.drawPixmap(pixmap, 0, 0, pixmap.width, pixmap.height, 0, 0, size, size) + pixmap.dispose() + appendEmoji(txt, pixmap2) + return this + } + + fun appendEmoji(txt: String, pixmap: Pixmap): NativeFont { + if (charSet!!.add(txt)) { + if (packer == null) { + packer = PixmapPacker(pageWidth, pageWidth, Pixmap.Format.RGBA8888, 2, false) + } + putGlyph(txt[0], pixmap) + updataSize(pixmap.height) + upData() + } + return this + } + + fun createText(characters: String?): NativeFont { + if (!(characters == null || characters.length == 0)) { + create(characters, true) + end() + } + return this + } + + fun appendText(characters: String?): NativeFont { + if (!(characters == null || characters.length == 0)) { + create(characters, false) + } + return this + } + + private fun create(characters: String, haveMinPageSize: Boolean) { + var characters = characters + characters = characters.replace("[\\t\\n\\x0B\\f\\r]".toRegex(), "") + val arrayOfCharsAsStrings = Array() + for (c2 in characters.toCharArray()) { + if (charSet!!.add(c2.toString())) { + arrayOfCharsAsStrings.add(c2.toString()) + } + } + if (haveMinPageSize) { + pageWidth = (paint!!.textSize + 2) * (Math.sqrt(arrayOfCharsAsStrings.size.toDouble()) + 1.0).toInt() + } + if (packer == null) { + packer = PixmapPacker(pageWidth, pageWidth, Pixmap.Format.RGBA8888, 2, false) + } + + val putGlyphStartTime = System.currentTimeMillis() + for (i in 0 until arrayOfCharsAsStrings.size) { + val txt = arrayOfCharsAsStrings[i] + val c2 = txt[0] + val css = c2.toString() + if (emojiSet[css] != null) { + charSet!!.remove(css) + val date = emojiSet[css] + appendEmoji(c2.toString() + "", date!!.path, date.size) + } else { + putGlyph(c2, listener!!.getFontPixmap(txt, paint)) + } + } + + val putGlyphTime = System.currentTimeMillis() - putGlyphStartTime + println("Putting glyphs - "+putGlyphTime+"ms") + + updataSize(size) + upData() + + if (regions.size == 1) { + setOwnsTexture(true) + } else { + setOwnsTexture(false) + } + } + + private fun putGlyph(c: Char, pixmap: Pixmap) { + val rect = packer!!.pack(c.toString(), pixmap) + pixmap.dispose() + val pIndex = packer!!.getPageIndex(c.toString()) + val glyph = Glyph() + glyph.id = c.toInt() + glyph.page = pIndex + glyph.srcX = rect.x.toInt() + glyph.srcY = rect.y.toInt() + glyph.width = rect.width.toInt() + glyph.height = rect.height.toInt() + glyph.xadvance = glyph.width + this.data!!.setGlyph(c.toInt(), glyph) + } + + private fun upData() { + var spaceGlyph = this.data!!.getGlyph(' ') + if (spaceGlyph == null) { + spaceGlyph = Glyph() + var xadvanceGlyph = this.data!!.getGlyph('l') + if (xadvanceGlyph == null) { + xadvanceGlyph = this.data!!.firstGlyph + } + spaceGlyph.xadvance = xadvanceGlyph!!.xadvance + spaceGlyph.id = 32 + this.data!!.setGlyph(32, spaceGlyph) + } + this.data!!.spaceXadvance = (spaceGlyph.xadvance + spaceGlyph.width).toFloat() + val pages = packer!!.pages + val regions = regions + val regSize = regions.size - 1 + for (i in 0 until pages.size) { + val p = pages[i] + if (i > regSize) { + p.updateTexture(minFilter, magFilter, false) + regions.add(TextureRegion(p.texture)) + } else { + if (p.updateTexture(minFilter, magFilter, false)) { + regions[i] = TextureRegion(p.texture) + } + } + } + for (page in this.data!!.glyphs) { + if (page == null) continue + for (glyph in page) { + if (glyph != null) { + val region = getRegions()[glyph.page] + ?: throw IllegalArgumentException("BitmapFont texture region array cannot contain null elements.") + this.data!!.setGlyphRegion(glyph, region) + } + } + } + } + + fun end(): NativeFont { + paint = null + charSet!!.clear() + charSet = null + packer!!.dispose() + packer = null + return this + } + + override fun dispose() { + end() + super.dispose() + } + + companion object { + var listener: NativeFontListener? = null + private set + private var robovm = false + fun setRobovm() { + robovm = true + } + + } + + init { + this.paint = NativeFontPaint() + charSet = HashSet() + packer = null + minFilter = TextureFilter.Linear + magFilter = TextureFilter.Linear + emojiSet = HashMap() + updataSize(paint.textSize) + if (listener == null) createListener() + this.paint = paint + } +} \ No newline at end of file diff --git a/desktop/src/com/unciv/app/desktop/DesktopLauncher.kt b/desktop/src/com/unciv/app/desktop/DesktopLauncher.kt index daea62acca..79dee54b6c 100644 --- a/desktop/src/com/unciv/app/desktop/DesktopLauncher.kt +++ b/desktop/src/com/unciv/app/desktop/DesktopLauncher.kt @@ -32,6 +32,8 @@ internal object DesktopLauncher { } private fun packImages() { + val startTime = System.currentTimeMillis() + val settings = TexturePacker.Settings() // Apparently some chipsets, like NVIDIA Tegra 3 graphics chipset (used in Asus TF700T tablet), // don't support non-power-of-two texture sizes - kudos @yuroller! @@ -46,6 +48,9 @@ internal object DesktopLauncher { settings.filterMag = Texture.TextureFilter.MipMapLinearLinear settings.filterMin = Texture.TextureFilter.MipMapLinearLinear TexturePacker.process(settings, "../Images", ".", "game") + + val texturePackingTime = System.currentTimeMillis() - startTime + println("Packing textures - "+texturePackingTime+"ms") } private fun tryActivateDiscord(game: UncivGame) {