mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-21 05:09:25 +07:00
can use native font and "WenQuanYimicroHei" in andriod and desktop (#1013)
* Update Other.json * Update Notifications.json * Update Other.json * Can Change Language With No "ttf" Font * update * Update AndroidLauncher.java * repair app running slowly in using no "tff" class * Can Change Language with No "ttf" Font (#772) * Update Other.json * Update Notifications.json * Update Other.json * Can Change Language With No "ttf" Font * update * Update AndroidLauncher.java * repair app running slowly in using no "tff" class * update nativefont for Desktop and IOS * Delete NativeFontIOS.java * can choose nativefont or font downloading from internet * update * update * Update Fonts.kt * Update Fonts.kt * update * update * update * update * Update build.gradle * update * update * update * can choose native font or "WenquanYiMicroHei" * update * update * update * update
This commit is contained in:

committed by
Yair Morgenstern

parent
8d3a2d6da3
commit
62a85cd14a
Binary file not shown.
@ -1,94 +0,0 @@
|
|||||||
Copyright (c) 2011, Ang<6E>lica D<>iaz (http://typereview.wordpress.com|angiecina@gmail.com),
|
|
||||||
with Reserved Font Name "Esteban"
|
|
||||||
|
|
||||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
||||||
This license is copied below, and is also available with a FAQ at:
|
|
||||||
http://scripts.sil.org/OFL
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------------------------------------------
|
|
||||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
||||||
-----------------------------------------------------------
|
|
||||||
|
|
||||||
PREAMBLE
|
|
||||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
||||||
development of collaborative font projects, to support the font creation
|
|
||||||
efforts of academic and linguistic communities, and to provide a free and
|
|
||||||
open framework in which fonts may be shared and improved in partnership
|
|
||||||
with others.
|
|
||||||
|
|
||||||
The OFL allows the licensed fonts to be used, studied, modified and
|
|
||||||
redistributed freely as long as they are not sold by themselves. The
|
|
||||||
fonts, including any derivative works, can be bundled, embedded,
|
|
||||||
redistributed and/or sold with any software provided that any reserved
|
|
||||||
names are not used by derivative works. The fonts and derivatives,
|
|
||||||
however, cannot be released under any other type of license. The
|
|
||||||
requirement for fonts to remain under this license does not apply
|
|
||||||
to any document created using the fonts or their derivatives.
|
|
||||||
|
|
||||||
DEFINITIONS
|
|
||||||
"Font Software" refers to the set of files released by the Copyright
|
|
||||||
Holder(s) under this license and clearly marked as such. This may
|
|
||||||
include source files, build scripts and documentation.
|
|
||||||
|
|
||||||
"Reserved Font Name" refers to any names specified as such after the
|
|
||||||
copyright statement(s).
|
|
||||||
|
|
||||||
"Original Version" refers to the collection of Font Software components as
|
|
||||||
distributed by the Copyright Holder(s).
|
|
||||||
|
|
||||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
||||||
or substituting -- in part or in whole -- any of the components of the
|
|
||||||
Original Version, by changing formats or by porting the Font Software to a
|
|
||||||
new environment.
|
|
||||||
|
|
||||||
"Author" refers to any designer, engineer, programmer, technical
|
|
||||||
writer or other person who contributed to the Font Software.
|
|
||||||
|
|
||||||
PERMISSION & CONDITIONS
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
||||||
redistribute, and sell modified and unmodified copies of the Font
|
|
||||||
Software, subject to the following conditions:
|
|
||||||
|
|
||||||
1) Neither the Font Software nor any of its individual components,
|
|
||||||
in Original or Modified Versions, may be sold by itself.
|
|
||||||
|
|
||||||
2) Original or Modified Versions of the Font Software may be bundled,
|
|
||||||
redistributed and/or sold with any software, provided that each copy
|
|
||||||
contains the above copyright notice and this license. These can be
|
|
||||||
included either as stand-alone text files, human-readable headers or
|
|
||||||
in the appropriate machine-readable metadata fields within text or
|
|
||||||
binary files as long as those fields can be easily viewed by the user.
|
|
||||||
|
|
||||||
3) No Modified Version of the Font Software may use the Reserved Font
|
|
||||||
Name(s) unless explicit written permission is granted by the corresponding
|
|
||||||
Copyright Holder. This restriction only applies to the primary font name as
|
|
||||||
presented to the users.
|
|
||||||
|
|
||||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
||||||
Software shall not be used to promote, endorse or advertise any
|
|
||||||
Modified Version, except to acknowledge the contribution(s) of the
|
|
||||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
||||||
permission.
|
|
||||||
|
|
||||||
5) The Font Software, modified or unmodified, in part or in whole,
|
|
||||||
must be distributed entirely under this license, and must not be
|
|
||||||
distributed under any other license. The requirement for fonts to
|
|
||||||
remain under this license does not apply to any document created
|
|
||||||
using the Font Software.
|
|
||||||
|
|
||||||
TERMINATION
|
|
||||||
This license becomes null and void if any of the above conditions are
|
|
||||||
not met.
|
|
||||||
|
|
||||||
DISCLAIMER
|
|
||||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
||||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
||||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
||||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
||||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
78
android/src/core/java/nativefont/NativeFontAndroid.java
Executable file
78
android/src/core/java/nativefont/NativeFontAndroid.java
Executable file
@ -0,0 +1,78 @@
|
|||||||
|
package core.java.nativefont;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.backends.android.AndroidApplication;
|
||||||
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
import com.badlogic.gdx.graphics.Pixmap;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by tian on 2016/10/2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class NativeFontAndroid implements NativeFontListener {
|
||||||
|
private HashMap<String, Typeface> fontFaces = new HashMap<String, Typeface>();
|
||||||
|
private AndroidApplication androidApplication = (AndroidApplication) Gdx.app;
|
||||||
|
@Override
|
||||||
|
public Pixmap getFontPixmap(String txt, NativeFontPaint vpaint) {
|
||||||
|
Paint paint = new Paint();
|
||||||
|
|
||||||
|
if (!vpaint.getTTFName().equals("")) {
|
||||||
|
// Typeface fontFace = fontFaces.get(vpaint.getTTFName());
|
||||||
|
Gdx.app.log("app",Gdx.files.internal(vpaint.getTTFName()
|
||||||
|
+ (vpaint.getTTFName().endsWith(".ttf") ? ""
|
||||||
|
: ".ttf")).file().getPath());
|
||||||
|
Typeface fontFace = Typeface.createFromAsset(androidApplication.getAssets(),vpaint.getTTFName()
|
||||||
|
+ (vpaint.getTTFName().endsWith(".ttf") ? ""
|
||||||
|
: ".ttf"));
|
||||||
|
fontFaces.put(vpaint.getTTFName(), fontFace);
|
||||||
|
paint.setTypeface(fontFace);
|
||||||
|
}
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
paint.setTextSize(vpaint.getTextSize());
|
||||||
|
Paint.FontMetrics fm = paint.getFontMetrics();
|
||||||
|
int w = (int) paint.measureText(txt);
|
||||||
|
int h = (int) (fm.descent - fm.ascent);
|
||||||
|
if (w == 0) {
|
||||||
|
w = h = vpaint.getTextSize();
|
||||||
|
}
|
||||||
|
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
|
||||||
|
Canvas canvas = new Canvas(bitmap);
|
||||||
|
// 如果是描边类型
|
||||||
|
if (vpaint.getStrokeColor() != null) {
|
||||||
|
// 绘制外层
|
||||||
|
paint.setColor(getColor(vpaint.getStrokeColor()));
|
||||||
|
paint.setStrokeWidth(vpaint.getStrokeWidth()); // 描边宽度
|
||||||
|
paint.setStyle(Paint.Style.FILL_AND_STROKE); // 描边种类
|
||||||
|
paint.setFakeBoldText(true); // 外层text采用粗体
|
||||||
|
canvas.drawText(txt, 0, -fm.ascent, paint);
|
||||||
|
paint.setFakeBoldText(false);
|
||||||
|
} else {
|
||||||
|
paint.setUnderlineText(vpaint.getUnderlineText());
|
||||||
|
paint.setStrikeThruText(vpaint.getStrikeThruText());
|
||||||
|
paint.setFakeBoldText(vpaint.getFakeBoldText());
|
||||||
|
}
|
||||||
|
// 绘制内层
|
||||||
|
paint.setStrokeWidth(0);
|
||||||
|
paint.setColor(getColor(vpaint.getColor()));
|
||||||
|
canvas.drawText(txt, 0, -fm.ascent, paint);
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
bitmap.compress(Bitmap.CompressFormat.PNG, 100, buffer);
|
||||||
|
byte[] encodedData = buffer.toByteArray();
|
||||||
|
Pixmap pixmap = new Pixmap(encodedData, 0, encodedData.length);
|
||||||
|
bitmap = null;
|
||||||
|
canvas = null;
|
||||||
|
return pixmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getColor(Color color) {
|
||||||
|
return (((((int) (color.a * 255.0f)) << 24) | (((int) (color.r * 255.0f)) << 16)) | (((int) (color.g * 255.0f)) << 8)) | ((int) (color.b * 255.0f));
|
||||||
|
}
|
||||||
|
}
|
@ -122,4 +122,4 @@ project(":core") {
|
|||||||
|
|
||||||
tasks.eclipse.doLast {
|
tasks.eclipse.doLast {
|
||||||
delete ".project"
|
delete ".project"
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ class GameSettings {
|
|||||||
var showResourcesAndImprovements: Boolean = true
|
var showResourcesAndImprovements: Boolean = true
|
||||||
var checkForDueUnits: Boolean = true
|
var checkForDueUnits: Boolean = true
|
||||||
var singleTapMove: Boolean = false
|
var singleTapMove: Boolean = false
|
||||||
|
var fontSet:String = "NativeFont(Recommended)"
|
||||||
var language: String = "English"
|
var language: String = "English"
|
||||||
var resolution: String = "1050x700"
|
var resolution: String = "1050x700"
|
||||||
var tutorialsShown = ArrayList<String>()
|
var tutorialsShown = ArrayList<String>()
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.unciv.ui
|
package com.unciv.ui
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||||
@ -11,8 +10,6 @@ import com.unciv.models.gamebasics.GameBasics
|
|||||||
import com.unciv.models.gamebasics.tr
|
import com.unciv.models.gamebasics.tr
|
||||||
import com.unciv.ui.pickerscreens.PickerScreen
|
import com.unciv.ui.pickerscreens.PickerScreen
|
||||||
import com.unciv.ui.utils.*
|
import com.unciv.ui.utils.*
|
||||||
import com.unciv.ui.worldscreen.optionstable.PopupTable
|
|
||||||
import com.unciv.ui.worldscreen.optionstable.YesNoPopupTable
|
|
||||||
|
|
||||||
|
|
||||||
class LanguageTable(val language:String,skin: Skin):Table(skin){
|
class LanguageTable(val language:String,skin: Skin):Table(skin){
|
||||||
@ -77,24 +74,7 @@ class LanguagePickerScreen: PickerScreen(){
|
|||||||
|
|
||||||
|
|
||||||
rightSideButton.onClick {
|
rightSideButton.onClick {
|
||||||
if (Fonts().containsFont(Fonts().getFontForLanguage(chosenLanguage)))
|
pickLanguage()
|
||||||
pickLanguage()
|
|
||||||
else {
|
|
||||||
val spaceSplitLang = chosenLanguage.replace("_"," ")
|
|
||||||
YesNoPopupTable("This language requires you to download fonts.\n" +
|
|
||||||
"Do you want to download fonts for $spaceSplitLang?",
|
|
||||||
{
|
|
||||||
val downloading = PopupTable(this)
|
|
||||||
downloading.add("Downloading...".toLabel())
|
|
||||||
downloading.open()
|
|
||||||
Gdx.input.inputProcessor = null // no interaction until download is over
|
|
||||||
|
|
||||||
kotlin.concurrent.thread {
|
|
||||||
Fonts().downloadFontForLanguage(chosenLanguage)
|
|
||||||
shouldPickLanguage = true
|
|
||||||
}
|
|
||||||
},this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,12 +85,4 @@ class LanguagePickerScreen: PickerScreen(){
|
|||||||
UnCivGame.Current.startNewGame()
|
UnCivGame.Current.startNewGame()
|
||||||
dispose()
|
dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
var shouldPickLanguage=false
|
|
||||||
override fun render(delta: Float) {
|
|
||||||
if(shouldPickLanguage)
|
|
||||||
pickLanguage()
|
|
||||||
super.render(delta)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,40 +1,68 @@
|
|||||||
package com.unciv.ui.utils
|
package com.unciv.ui.utils
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.Texture
|
import com.badlogic.gdx.graphics.Texture
|
||||||
import com.badlogic.gdx.graphics.g2d.BitmapFont
|
import com.badlogic.gdx.graphics.g2d.BitmapFont
|
||||||
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator
|
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator
|
||||||
import com.unciv.UnCivGame
|
import com.unciv.UnCivGame
|
||||||
import com.unciv.models.gamebasics.GameBasics
|
import com.unciv.models.gamebasics.GameBasics
|
||||||
|
import com.unciv.models.gamebasics.tr
|
||||||
|
import com.unciv.ui.worldscreen.optionstable.PopupTable
|
||||||
|
import core.java.nativefont.NativeFont
|
||||||
|
import core.java.nativefont.NativeFontPaint
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
|
import java.io.FileInputStream
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
|
import java.security.*
|
||||||
|
|
||||||
class Fonts {
|
class Fonts {
|
||||||
companion object {
|
companion object {
|
||||||
// Contains e.g. "Arial 22", fontname and size, to BitmapFont
|
|
||||||
val fontCache = HashMap<String, BitmapFont>()
|
val fontCache = HashMap<String, BitmapFont>()
|
||||||
}
|
}
|
||||||
|
fun download(link: String,fontForLanguage: String) {
|
||||||
fun getFontForLanguage(language:String): String {
|
if (!Gdx.files.local("fonts").exists())
|
||||||
if (language.contains("Chinese")) return chineseFont
|
Gdx.files.local("fonts").mkdirs()
|
||||||
else return "Arial"
|
val input = URL(link).openStream()
|
||||||
|
val output = FileOutputStream(Gdx.files.local("fonts/$fontForLanguage.ttf").file())
|
||||||
|
input.use {
|
||||||
|
output.use {
|
||||||
|
input.copyTo(output)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
fun getMD5(fontForLanguage: String):String {
|
||||||
val chineseFont = "WenQuanYiMicroHei"
|
val sb = StringBuffer("")
|
||||||
|
val md = MessageDigest.getInstance("MD5")
|
||||||
fun getCharsForFont(font: String): String {
|
if (Gdx.files.local("fonts/$fontForLanguage.ttf").exists()) {
|
||||||
|
md.update(FileInputStream(Gdx.files.local("fonts/$fontForLanguage.ttf").file()).readBytes())
|
||||||
|
val b = md.digest()
|
||||||
|
for (i in b) {
|
||||||
|
var d = i.toInt()
|
||||||
|
if (d < 0) d = i + 256
|
||||||
|
if (d < 16) sb.append("0")
|
||||||
|
sb.append(Integer.toHexString(d))
|
||||||
|
}
|
||||||
|
return sb.toString()
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
fun containsFont(): Boolean {
|
||||||
|
if (Gdx.files.local("fonts/WenQuanYiMicroHei.ttf").exists())
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
fun getCharsForFont(): String {
|
||||||
val defaultText = "ABCČĆDĐEFGHIJKLMNOPQRSŠTUVWXYZŽaäàâăbcčćçdđeéfghiîjklmnoöpqrsșštțuüvwxyzž" +
|
val defaultText = "ABCČĆDĐEFGHIJKLMNOPQRSŠTUVWXYZŽaäàâăbcčćçdđeéfghiîjklmnoöpqrsșštțuüvwxyzž" +
|
||||||
"АБВГҐДЂЕЁЄЖЗЅИІЇЙЈКЛЉМНЊОПРСТЋУЎФХЦЧЏШЩЪЫЬЭЮЯабвгґдђеёєжзѕиіїйјклљмнњопрстћуўфхцчџшщъыьэюя" +
|
"АБВГҐДЂЕЁЄЖЗЅИІЇЙЈКЛЉМНЊОПРСТЋУЎФХЦЧЏШЩЪЫЬЭЮЯабвгґдђеёєжзѕиіїйјклљмнњопрстћуўфхцчџшщъыьэюя" +
|
||||||
"ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωάßΆέΈέΉίϊΐΊόΌύΰϋΎΫΏ" +
|
"ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωάßΆέΈέΉίϊΐΊόΌύΰϋΎΫΏ" +
|
||||||
"ÀÄĂÂĎÊĚÉÈÍÎŁĹĽÔÓÖƠŘŔŚŤƯŮÚÜŻŹäâąďêęěłĺľńňôöơřŕśťưůýżźáèìíóú1234567890" +
|
"ÀÄĂÂĎÊĚÉÈÍÎŁĹĽÔÓÖƠŘŔŚŤƯŮÚÜŻŹäâąďêęěłĺľńňôöơřŕśťưůýżźáèìíóú1234567890" +
|
||||||
"‘?’'“!”(%)[#]{@}/&\\<-+÷×=>®©\$€£¥¢:;,.¡*|"
|
"‘?’'“!”(%)[#]{@}/&\\<-+÷×=>®©\$€£¥¢:;,.¡*|"
|
||||||
if (font == "Arial") return defaultText
|
|
||||||
if (font == chineseFont) {
|
|
||||||
val charSet = HashSet<Char>()
|
val charSet = HashSet<Char>()
|
||||||
charSet.addAll(defaultText.asIterable())
|
charSet.addAll(defaultText.asIterable())
|
||||||
|
|
||||||
if(Gdx.files.internal("BasicHelp/BasicHelp_Simplified_Chinese.json").exists())
|
if(Gdx.files.internal("jsons/BasicHelp/BasicHelp_Simplified_Chinese.json").exists())
|
||||||
charSet.addAll(Gdx.files.internal("BasicHelp/BasicHelp_Simplified_Chinese.json").readString().asIterable())
|
charSet.addAll(Gdx.files.internal("jsons/BasicHelp/BasicHelp_Simplified_Chinese.json").readString().asIterable())
|
||||||
if (Gdx.files.internal("jsons/Nations_Simplified_Chinese.json").exists())
|
if (Gdx.files.internal("jsons/Nations_Simplified_Chinese.json").exists())
|
||||||
charSet.addAll(Gdx.files.internal("jsons/Nations_Simplified_Chinese.json").readString().asIterable())
|
charSet.addAll(Gdx.files.internal("jsons/Nations_Simplified_Chinese.json").readString().asIterable())
|
||||||
if (Gdx.files.internal("jsons/Tutorials/Tutorials_Simplified_Chinese.json").exists())
|
if (Gdx.files.internal("jsons/Tutorials/Tutorials_Simplified_Chinese.json").exists())
|
||||||
@ -46,66 +74,41 @@ class Fonts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return charSet.joinToString()
|
return charSet.joinToString()
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
fun download(link: String, path: String) {
|
|
||||||
val input = URL(link).openStream()
|
|
||||||
val output = FileOutputStream(Gdx.files.local(path).file())
|
|
||||||
input.use {
|
|
||||||
output.use {
|
|
||||||
input.copyTo(output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun containsFont(font:String): Boolean {
|
|
||||||
if (Gdx.files.internal("skin/$font.ttf").exists())
|
|
||||||
return true
|
|
||||||
if (Gdx.files.local("fonts/$font.ttf").exists())
|
|
||||||
return true
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
fun downloadFontForLanguage(language:String){
|
|
||||||
val font = getFontForLanguage(language)
|
|
||||||
if(containsFont(language)) return
|
|
||||||
|
|
||||||
if (!Gdx.files.local("fonts").exists())
|
|
||||||
Gdx.files.local("fonts").mkdirs()
|
|
||||||
|
|
||||||
val localPath = "fonts/$font.ttf"
|
|
||||||
if (font == chineseFont)
|
|
||||||
download("https://github.com/layerssss/wqy/raw/gh-pages/fonts/WenQuanYiMicroHei.ttf", localPath)//This font is licensed under Apache2.0 or GPLv3
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getFont(size: Int): BitmapFont {
|
|
||||||
val language = UnCivGame.Current.settings.language
|
|
||||||
val fontForLanguage = getFontForLanguage(language)
|
|
||||||
val keyForFont = "$fontForLanguage $size"
|
|
||||||
if (fontCache.containsKey(keyForFont)) return fontCache[keyForFont]!!
|
|
||||||
val generator: FreeTypeFontGenerator
|
|
||||||
|
|
||||||
if (Gdx.files.internal("skin/$fontForLanguage.ttf").exists())
|
|
||||||
generator = FreeTypeFontGenerator(Gdx.files.internal("skin/$fontForLanguage.ttf"))
|
|
||||||
else {
|
|
||||||
val localPath = "fonts/$fontForLanguage.ttf"
|
|
||||||
if(!containsFont(fontForLanguage)) downloadFontForLanguage(language)
|
|
||||||
generator = FreeTypeFontGenerator(Gdx.files.local(localPath))
|
|
||||||
}
|
|
||||||
|
|
||||||
val parameter = FreeTypeFontGenerator.FreeTypeFontParameter()
|
|
||||||
parameter.size = size
|
|
||||||
parameter.minFilter = Texture.TextureFilter.Linear
|
|
||||||
parameter.magFilter = Texture.TextureFilter.Linear
|
|
||||||
|
|
||||||
parameter.characters = getCharsForFont(fontForLanguage)
|
|
||||||
|
|
||||||
val font = generator.generateFont(parameter)
|
|
||||||
generator.dispose() // don't forget to dispose to avoid memory leaks!
|
|
||||||
fontCache[keyForFont] = font
|
|
||||||
return font
|
|
||||||
}
|
}
|
||||||
|
fun getFont(size: Int): BitmapFont {
|
||||||
|
if(UnCivGame.Current.settings.fontSet=="WenQuanYiMicroHei"){
|
||||||
|
val fontForLanguage="WenQuanYiMicroHei"
|
||||||
|
val keyForFont = "$fontForLanguage $size"
|
||||||
|
if (fontCache.containsKey(keyForFont))
|
||||||
|
return fontCache[keyForFont]!!
|
||||||
|
if (getMD5(fontForLanguage)!="96574d6f2f2bbd4a3ce56979623b1952"){
|
||||||
|
Gdx.files.local("fonts/$fontForLanguage.ttf").delete()
|
||||||
|
UnCivGame.Current.settings.fontSet="NativeFont(Recommended)"
|
||||||
|
Gdx.app.postRunnable {
|
||||||
|
val downloading = PopupTable(UnCivGame.Current.worldScreen)
|
||||||
|
downloading.add("Checksum error!\nIf you want to use the font \"WenQuanYiMicroHei\", please download again.".toLabel().setFontColor(Color.RED)).row()
|
||||||
|
downloading.addButton("Close".tr()) { downloading.remove() }.row()
|
||||||
|
downloading.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val generator = FreeTypeFontGenerator(Gdx.files.local("fonts/WenQuanYiMicroHei.ttf"))
|
||||||
|
val parameter = FreeTypeFontGenerator.FreeTypeFontParameter()
|
||||||
|
parameter.size = size
|
||||||
|
parameter.minFilter = Texture.TextureFilter.Linear
|
||||||
|
parameter.magFilter = Texture.TextureFilter.Linear
|
||||||
|
parameter.characters = getCharsForFont()
|
||||||
|
val font = generator.generateFont(parameter)
|
||||||
|
fontCache[keyForFont] = font
|
||||||
|
return font
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val fontForLanguage ="Nativefont"
|
||||||
|
val keyForFont = "$fontForLanguage $size"
|
||||||
|
if (fontCache.containsKey(keyForFont))return fontCache[keyForFont]!!
|
||||||
|
val font=NativeFont(NativeFontPaint(size))
|
||||||
|
font.appendText(getCharsForFont())
|
||||||
|
fontCache[keyForFont] = font
|
||||||
|
return font
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.unciv.ui.worldscreen.optionstable
|
package com.unciv.ui.worldscreen.optionstable
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.graphics.g2d.Batch
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.*
|
import com.badlogic.gdx.scenes.scene2d.ui.*
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener
|
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener
|
||||||
@ -11,6 +11,7 @@ import com.unciv.models.gamebasics.GameBasics
|
|||||||
import com.unciv.models.gamebasics.tr
|
import com.unciv.models.gamebasics.tr
|
||||||
import com.unciv.ui.utils.*
|
import com.unciv.ui.utils.*
|
||||||
import com.unciv.ui.worldscreen.WorldScreen
|
import com.unciv.ui.worldscreen.WorldScreen
|
||||||
|
import java.io.IOException
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
class Language(val language:String){
|
class Language(val language:String){
|
||||||
@ -75,6 +76,8 @@ class WorldScreenOptionsTable(val worldScreen:WorldScreen) : PopupTable(worldScr
|
|||||||
settings.autoAssignCityProduction= !settings.autoAssignCityProduction
|
settings.autoAssignCityProduction= !settings.autoAssignCityProduction
|
||||||
update()
|
update()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addFontSelectBox(innerTable)
|
||||||
|
|
||||||
addLanguageSelectBox(innerTable)
|
addLanguageSelectBox(innerTable)
|
||||||
|
|
||||||
@ -196,6 +199,62 @@ class WorldScreenOptionsTable(val worldScreen:WorldScreen) : PopupTable(worldScr
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addFontSelectBox(innerTable: PopupTable) {
|
||||||
|
innerTable.add("Fontset".toLabel())
|
||||||
|
val FontSetSelectBox = SelectBox<String>(skin)
|
||||||
|
val FontSetArray = Array<String>()
|
||||||
|
FontSetArray.add("NativeFont(Recommended)")
|
||||||
|
FontSetArray.add("WenQuanYiMicroHei")
|
||||||
|
FontSetSelectBox.items = FontSetArray
|
||||||
|
FontSetSelectBox.selected = UnCivGame.Current.settings.fontSet
|
||||||
|
innerTable.add(FontSetSelectBox).pad(10f).row()
|
||||||
|
|
||||||
|
FontSetSelectBox.addListener(object : ChangeListener() {
|
||||||
|
override fun changed(event: ChangeEvent?, actor: Actor?) {
|
||||||
|
UnCivGame.Current.settings.fontSet = FontSetSelectBox.selected
|
||||||
|
if (FontSetSelectBox.selected == "NativeFont(Recommended)"||Fonts().containsFont()) {
|
||||||
|
selectFont()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
YesNoPopupTable("This Font requires you to download fonts.\n" +
|
||||||
|
"Do you want to download fonts(about 4.2MB)?",
|
||||||
|
{
|
||||||
|
val downloading = PopupTable(screen)
|
||||||
|
downloading.add("Downloading...\n".toLabel()).row()
|
||||||
|
downloading.add("Warning:Don't switch this game to background until download finished.".toLabel().setFontColor(Color.RED)).row()
|
||||||
|
downloading.open()
|
||||||
|
Gdx.input.inputProcessor = null
|
||||||
|
thread {
|
||||||
|
try {
|
||||||
|
Fonts().download("https://github.com/layerssss/wqy/raw/gh-pages/fonts/WenQuanYiMicroHei.ttf", "WenQuanYiMicroHei")//This font is licensed under Apache2.0 or GPLv3
|
||||||
|
Gdx.app.postRunnable {
|
||||||
|
selectFont()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e: IOException) {
|
||||||
|
Gdx.app.postRunnable {
|
||||||
|
FontSetSelectBox.selected = "NativeFont(Recommended)"
|
||||||
|
val downloading = PopupTable(UnCivGame.Current.worldScreen)
|
||||||
|
downloading.add("Download failed!\nPlease check your internet connection.".toLabel().setFontColor(Color.RED)).row()
|
||||||
|
downloading.addButton("Close".tr()) { downloading.remove() }.row()
|
||||||
|
downloading.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, UnCivGame.Current.worldScreen, {FontSetSelectBox.selected = "NativeFont(Recommended)"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun selectFont(){
|
||||||
|
UnCivGame.Current.settings.save()
|
||||||
|
CameraStageBaseScreen.resetFonts()
|
||||||
|
UnCivGame.Current.worldScreen = WorldScreen(worldScreen.viewingCiv)
|
||||||
|
UnCivGame.Current.setWorldScreen()
|
||||||
|
WorldScreenOptionsTable(UnCivGame.Current.worldScreen)
|
||||||
|
}
|
||||||
|
|
||||||
private fun addLanguageSelectBox(innerTable: PopupTable) {
|
private fun addLanguageSelectBox(innerTable: PopupTable) {
|
||||||
innerTable.add("Language".toLabel())
|
innerTable.add("Language".toLabel())
|
||||||
val languageSelectBox = SelectBox<Language>(skin)
|
val languageSelectBox = SelectBox<Language>(skin)
|
||||||
@ -209,27 +268,7 @@ class WorldScreenOptionsTable(val worldScreen:WorldScreen) : PopupTable(worldScr
|
|||||||
languageSelectBox.addListener(object : ChangeListener() {
|
languageSelectBox.addListener(object : ChangeListener() {
|
||||||
override fun changed(event: ChangeEvent?, actor: Actor?) {
|
override fun changed(event: ChangeEvent?, actor: Actor?) {
|
||||||
selectedLanguage = languageSelectBox.selected.language
|
selectedLanguage = languageSelectBox.selected.language
|
||||||
if (Fonts().containsFont(Fonts().getFontForLanguage(selectedLanguage)))
|
selectLanguage()
|
||||||
selectLanguage()
|
|
||||||
else {
|
|
||||||
val spaceSplitLang = selectedLanguage.replace("_", " ")
|
|
||||||
YesNoPopupTable("This language requires you to download fonts.\n" +
|
|
||||||
"Do you want to download fonts for $spaceSplitLang?",
|
|
||||||
{
|
|
||||||
|
|
||||||
val downloading = PopupTable(screen)
|
|
||||||
downloading.add("Downloading...".toLabel())
|
|
||||||
downloading.open()
|
|
||||||
Gdx.input.inputProcessor = null // no interaction until download is over
|
|
||||||
|
|
||||||
thread {
|
|
||||||
Fonts().downloadFontForLanguage(selectedLanguage)
|
|
||||||
// The language selection must be done on the render thread, because it requires a GL context.
|
|
||||||
// This means that we have to tell the table to create it on render.
|
|
||||||
shouldSelectLanguage = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -245,25 +284,11 @@ class WorldScreenOptionsTable(val worldScreen:WorldScreen) : PopupTable(worldScr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun selectLanguage(){
|
fun selectLanguage(){
|
||||||
UnCivGame.Current.settings.language = selectedLanguage
|
UnCivGame.Current.settings.language = selectedLanguage
|
||||||
UnCivGame.Current.settings.save()
|
UnCivGame.Current.settings.save()
|
||||||
|
|
||||||
CameraStageBaseScreen.resetFonts()
|
|
||||||
|
|
||||||
UnCivGame.Current.worldScreen = WorldScreen(worldScreen.viewingCiv)
|
UnCivGame.Current.worldScreen = WorldScreen(worldScreen.viewingCiv)
|
||||||
UnCivGame.Current.setWorldScreen()
|
UnCivGame.Current.setWorldScreen()
|
||||||
WorldScreenOptionsTable(UnCivGame.Current.worldScreen)
|
WorldScreenOptionsTable(UnCivGame.Current.worldScreen)
|
||||||
}
|
}
|
||||||
|
|
||||||
var shouldSelectLanguage = false
|
|
||||||
override fun draw(batch: Batch?, parentAlpha: Float) {
|
|
||||||
if(shouldSelectLanguage){
|
|
||||||
shouldSelectLanguage=false
|
|
||||||
selectLanguage()
|
|
||||||
}
|
|
||||||
super.draw(batch, parentAlpha)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,12 +8,12 @@ import com.unciv.ui.utils.onClick
|
|||||||
import com.unciv.ui.utils.toLabel
|
import com.unciv.ui.utils.toLabel
|
||||||
|
|
||||||
class YesNoPopupTable(question:String, action:()->Unit,
|
class YesNoPopupTable(question:String, action:()->Unit,
|
||||||
screen: CameraStageBaseScreen = UnCivGame.Current.worldScreen) : PopupTable(screen){
|
screen: CameraStageBaseScreen = UnCivGame.Current.worldScreen, restoredefault:()->Unit = {}) : PopupTable(screen){
|
||||||
init{
|
init{
|
||||||
if(!screen.hasPopupOpen) {
|
if(!screen.hasPopupOpen) {
|
||||||
screen.hasPopupOpen=true
|
screen.hasPopupOpen=true
|
||||||
add(question.toLabel()).colspan(2).row()
|
add(question.toLabel()).colspan(2).row()
|
||||||
add(TextButton("No".tr(), skin).onClick { close() })
|
add(TextButton("No".tr(), skin).onClick { close(); restoredefault() })
|
||||||
add(TextButton("Yes".tr(), skin).onClick { close(); action() })
|
add(TextButton("Yes".tr(), skin).onClick { close(); action() })
|
||||||
open()
|
open()
|
||||||
}
|
}
|
||||||
|
299
core/src/core/java/nativefont/NativeFont.java
Executable file
299
core/src/core/java/nativefont/NativeFont.java
Executable file
@ -0,0 +1,299 @@
|
|||||||
|
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<String> charSet;
|
||||||
|
private BitmapFontData data;
|
||||||
|
private HashMap<String, EmojiDate> 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<? extends NativeFontListener> claz = (Class<? extends NativeFontListener>) 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<String> cs = new Array<String>();
|
||||||
|
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, this.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<Page> pages = this.packer.getPages();
|
||||||
|
Array<TextureRegion> 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 = (TextureRegion) 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;
|
||||||
|
}
|
||||||
|
}
|
11
core/src/core/java/nativefont/NativeFontListener.java
Executable file
11
core/src/core/java/nativefont/NativeFontListener.java
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
package core.java.nativefont;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Pixmap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by tian on 2016/10/2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface NativeFontListener {
|
||||||
|
Pixmap getFontPixmap(String str, NativeFontPaint freePaint);
|
||||||
|
}
|
146
core/src/core/java/nativefont/NativeFontPaint.java
Executable file
146
core/src/core/java/nativefont/NativeFontPaint.java
Executable file
@ -0,0 +1,146 @@
|
|||||||
|
package core.java.nativefont;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by tian on 2016/10/2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class NativeFontPaint {
|
||||||
|
private int textSize = 30;// 字号
|
||||||
|
private Color color = Color.WHITE;// 颜色
|
||||||
|
private boolean isFakeBoldText = false;// 是否粗体
|
||||||
|
private boolean isUnderlineText = false;// 是否下划线
|
||||||
|
private boolean isStrikeThruText = false;// 是否删除线
|
||||||
|
private Color strokeColor = null;// 描边颜色
|
||||||
|
private int strokeWidth = 3;// 描边宽度
|
||||||
|
private String ttfName = "";
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
StringBuffer name = new StringBuffer();
|
||||||
|
name.append(ttfName).append("_").append(textSize).append("_").append(color.toIntBits())
|
||||||
|
.append("_").append(booleanToInt(isFakeBoldText)).append("_")
|
||||||
|
.append(booleanToInt(isUnderlineText));
|
||||||
|
if (strokeColor != null) {
|
||||||
|
name.append("_").append(strokeColor.toIntBits()).append("_").append(strokeWidth);
|
||||||
|
}
|
||||||
|
return name.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int booleanToInt(boolean b) {
|
||||||
|
return b == true ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NativeFontPaint() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public NativeFontPaint(String ttfName, int textSize, Color color, Color stroke, int strokeWidth,
|
||||||
|
boolean bold, boolean line, boolean thru) {
|
||||||
|
this.ttfName = ttfName;
|
||||||
|
this.textSize = textSize;
|
||||||
|
this.color = color;
|
||||||
|
this.strokeColor = stroke;
|
||||||
|
this.strokeWidth = strokeWidth;
|
||||||
|
this.isFakeBoldText = bold;
|
||||||
|
this.isUnderlineText = line;
|
||||||
|
this.isStrikeThruText = thru;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NativeFontPaint(String ttfName) {
|
||||||
|
this.ttfName = ttfName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NativeFontPaint(String ttfName, int size) {
|
||||||
|
this.ttfName = ttfName;
|
||||||
|
this.textSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NativeFontPaint(String ttfName, int size, Color color) {
|
||||||
|
this.ttfName = ttfName;
|
||||||
|
this.textSize = size;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NativeFontPaint(String ttfName, Color color) {
|
||||||
|
this.ttfName = ttfName;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NativeFontPaint(int size) {
|
||||||
|
this.textSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NativeFontPaint(Color color) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NativeFontPaint(int size, Color color) {
|
||||||
|
this.textSize = size;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTextSize() {
|
||||||
|
return textSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextSize(int textSize) {
|
||||||
|
this.textSize = textSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColor(Color color) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getFakeBoldText() {
|
||||||
|
return isFakeBoldText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFakeBoldText(boolean isFakeBoldText) {
|
||||||
|
this.isFakeBoldText = isFakeBoldText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getUnderlineText() {
|
||||||
|
return isUnderlineText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUnderlineText(boolean isUnderlineText) {
|
||||||
|
this.isUnderlineText = isUnderlineText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getStrikeThruText() {
|
||||||
|
return isStrikeThruText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStrikeThruText(boolean isStrikeThruText) {
|
||||||
|
this.isStrikeThruText = isStrikeThruText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color getStrokeColor() {
|
||||||
|
return strokeColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStrokeColor(Color strokeColor) {
|
||||||
|
this.strokeColor = strokeColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStrokeWidth() {
|
||||||
|
return strokeWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStrokeWidth(int strokeWidth) {
|
||||||
|
this.strokeWidth = strokeWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTTFName(String ttfName) {
|
||||||
|
this.ttfName = ttfName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTTFName() {
|
||||||
|
return ttfName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
128
desktop/src/core/java/nativefont/NativeFontDesktop.java
Executable file
128
desktop/src/core/java/nativefont/NativeFontDesktop.java
Executable file
@ -0,0 +1,128 @@
|
|||||||
|
package core.java.nativefont;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.graphics.Pixmap;
|
||||||
|
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.FontFormatException;
|
||||||
|
import java.awt.FontMetrics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.Shape;
|
||||||
|
import java.awt.font.GlyphVector;
|
||||||
|
import java.awt.font.TextAttribute;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.AttributedString;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
import static javax.swing.UIManager.getColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by tian on 2016/10/2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class NativeFontDesktop implements NativeFontListener {
|
||||||
|
private HashMap<String, Font> fonts = new HashMap<String, Font>();
|
||||||
|
private HashMap<String, FontMetrics> metrics = new HashMap<String, FontMetrics>();
|
||||||
|
private AttributedString as;
|
||||||
|
|
||||||
|
public Pixmap getFontPixmap(String txt, NativeFontPaint vpaint) {
|
||||||
|
Font font = getFont(vpaint);
|
||||||
|
FontMetrics fm = metrics.get(vpaint.getName());
|
||||||
|
int strWidth = fm.stringWidth(txt);
|
||||||
|
int strHeight = fm.getAscent() + fm.getDescent();
|
||||||
|
if (strWidth == 0) {
|
||||||
|
strWidth = strHeight = vpaint.getTextSize();
|
||||||
|
}
|
||||||
|
BufferedImage bi = new BufferedImage(strWidth, strHeight,
|
||||||
|
BufferedImage.TYPE_4BYTE_ABGR);
|
||||||
|
Graphics2D g = bi.createGraphics();
|
||||||
|
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||||
|
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
g.setFont(font);
|
||||||
|
if (vpaint.getStrokeColor() != null) {
|
||||||
|
// 描边
|
||||||
|
GlyphVector v = font.createGlyphVector(fm.getFontRenderContext(),
|
||||||
|
txt);
|
||||||
|
Shape shape = v.getOutline();
|
||||||
|
g.setColor(getColor(vpaint.getColor()));
|
||||||
|
g.translate(0, fm.getAscent());
|
||||||
|
g.fill(shape);
|
||||||
|
g.setStroke(new BasicStroke(vpaint.getStrokeWidth()));
|
||||||
|
g.setColor(getColor(vpaint.getStrokeColor()));
|
||||||
|
g.draw(shape);
|
||||||
|
} else if (vpaint.getUnderlineText() == true) {
|
||||||
|
// 下划线
|
||||||
|
AttributedString as = new AttributedString(txt);
|
||||||
|
as.addAttribute(TextAttribute.FONT, font);
|
||||||
|
as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
|
||||||
|
g.setColor(getColor(vpaint.getColor()));
|
||||||
|
g.drawString(as.getIterator(), 0, fm.getAscent());
|
||||||
|
} else if (vpaint.getStrikeThruText() == true) {
|
||||||
|
// 删除线
|
||||||
|
AttributedString as = new AttributedString(txt);
|
||||||
|
as.addAttribute(TextAttribute.FONT, font);
|
||||||
|
as.addAttribute(TextAttribute.STRIKETHROUGH,
|
||||||
|
TextAttribute.STRIKETHROUGH_ON);
|
||||||
|
g.setColor(getColor(vpaint.getColor()));
|
||||||
|
g.drawString(as.getIterator(), 0, fm.getAscent());
|
||||||
|
} else {
|
||||||
|
// 普通
|
||||||
|
g.setColor(getColor(vpaint.getColor()));
|
||||||
|
g.drawString(txt, 0, fm.getAscent());
|
||||||
|
}
|
||||||
|
|
||||||
|
Pixmap pixmap = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
ImageIO.write(bi, "png", buffer);
|
||||||
|
|
||||||
|
pixmap = new Pixmap(buffer.toByteArray(), 0, buffer.toByteArray().length);
|
||||||
|
buffer.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return pixmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Font getFont(NativeFontPaint vpaint) {
|
||||||
|
boolean isBolo = vpaint.getFakeBoldText() || vpaint.getStrokeColor() != null;
|
||||||
|
Font font = fonts.get(vpaint.getName());
|
||||||
|
if (font == null) {
|
||||||
|
if (vpaint.getTTFName().equals("")) {
|
||||||
|
font = new Font("", isBolo ? Font.BOLD : Font.PLAIN, vpaint.getTextSize());
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
ByteArrayInputStream in = new ByteArrayInputStream(Gdx.files.internal(vpaint.getTTFName() + (vpaint.getTTFName()
|
||||||
|
.endsWith(".ttf") ? "" : ".ttf")).readBytes());
|
||||||
|
BufferedInputStream fb = new BufferedInputStream(in);
|
||||||
|
font = Font.createFont(Font.TRUETYPE_FONT, fb).deriveFont(Font.BOLD, vpaint.getTextSize());
|
||||||
|
fb.close();
|
||||||
|
in.close();
|
||||||
|
} catch (FontFormatException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fonts.put(vpaint.getName(), font);
|
||||||
|
BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
|
||||||
|
Graphics2D g = bi.createGraphics();
|
||||||
|
g.setFont(font);
|
||||||
|
FontMetrics fm = g.getFontMetrics();
|
||||||
|
metrics.put(vpaint.getName(), fm);
|
||||||
|
}
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
5
gradle/wrapper/gradle-wrapper.properties
vendored
5
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,7 +1,6 @@
|
|||||||
#Wed Apr 24 09:17:57 IDT 2019
|
#Sat Aug 24 11:02:13 CST 2019
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
|
||||||
distributionSha256Sum=53b71812f18cdb2777e9f1b2a0f2038683907c90bdc406bc64d8b400e1fb2c3b
|
|
||||||
|
Reference in New Issue
Block a user