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:
parent
8d3a2d6da3
commit
62a85cd14a
14 changed files with 807 additions and 239 deletions
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));
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ class GameSettings {
|
|||
var showResourcesAndImprovements: Boolean = true
|
||||
var checkForDueUnits: Boolean = true
|
||||
var singleTapMove: Boolean = false
|
||||
var fontSet:String = "NativeFont(Recommended)"
|
||||
var language: String = "English"
|
||||
var resolution: String = "1050x700"
|
||||
var tutorialsShown = ArrayList<String>()
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.unciv.ui
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||
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.ui.pickerscreens.PickerScreen
|
||||
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){
|
||||
|
@ -77,24 +74,7 @@ class LanguagePickerScreen: PickerScreen(){
|
|||
|
||||
|
||||
rightSideButton.onClick {
|
||||
if (Fonts().containsFont(Fonts().getFontForLanguage(chosenLanguage)))
|
||||
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()
|
||||
dispose()
|
||||
}
|
||||
|
||||
var shouldPickLanguage=false
|
||||
override fun render(delta: Float) {
|
||||
if(shouldPickLanguage)
|
||||
pickLanguage()
|
||||
super.render(delta)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,40 +1,68 @@
|
|||
package com.unciv.ui.utils
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.Texture
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont
|
||||
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator
|
||||
import com.unciv.UnCivGame
|
||||
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.FileInputStream
|
||||
import java.net.URL
|
||||
import java.security.*
|
||||
|
||||
class Fonts {
|
||||
companion object {
|
||||
// Contains e.g. "Arial 22", fontname and size, to BitmapFont
|
||||
val fontCache = HashMap<String, BitmapFont>()
|
||||
}
|
||||
|
||||
fun getFontForLanguage(language:String): String {
|
||||
if (language.contains("Chinese")) return chineseFont
|
||||
else return "Arial"
|
||||
fun download(link: String,fontForLanguage: String) {
|
||||
if (!Gdx.files.local("fonts").exists())
|
||||
Gdx.files.local("fonts").mkdirs()
|
||||
val input = URL(link).openStream()
|
||||
val output = FileOutputStream(Gdx.files.local("fonts/$fontForLanguage.ttf").file())
|
||||
input.use {
|
||||
output.use {
|
||||
input.copyTo(output)
|
||||
}
|
||||
|
||||
val chineseFont = "WenQuanYiMicroHei"
|
||||
|
||||
fun getCharsForFont(font: String): String {
|
||||
}
|
||||
}
|
||||
fun getMD5(fontForLanguage: String):String {
|
||||
val sb = StringBuffer("")
|
||||
val md = MessageDigest.getInstance("MD5")
|
||||
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ž" +
|
||||
"АБВГҐДЂЕЁЄЖЗЅИІЇЙЈКЛЉМНЊОПРСТЋУЎФХЦЧЏШЩЪЫЬЭЮЯабвгґдђеёєжзѕиіїйјклљмнњопрстћуўфхцчџшщъыьэюя" +
|
||||
"ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωάßΆέΈέΉίϊΐΊόΌύΰϋΎΫΏ" +
|
||||
"ÀÄĂÂĎÊĚÉÈÍÎŁĹĽÔÓÖƠŘŔŚŤƯŮÚÜŻŹäâąďêęěłĺľńňôöơřŕśťưůýżźáèìíóú1234567890" +
|
||||
"‘?’'“!”(%)[#]{@}/&\\<-+÷×=>®©\$€£¥¢:;,.¡*|"
|
||||
if (font == "Arial") return defaultText
|
||||
if (font == chineseFont) {
|
||||
val charSet = HashSet<Char>()
|
||||
charSet.addAll(defaultText.asIterable())
|
||||
|
||||
if(Gdx.files.internal("BasicHelp/BasicHelp_Simplified_Chinese.json").exists())
|
||||
charSet.addAll(Gdx.files.internal("BasicHelp/BasicHelp_Simplified_Chinese.json").readString().asIterable())
|
||||
if(Gdx.files.internal("jsons/BasicHelp/BasicHelp_Simplified_Chinese.json").exists())
|
||||
charSet.addAll(Gdx.files.internal("jsons/BasicHelp/BasicHelp_Simplified_Chinese.json").readString().asIterable())
|
||||
if (Gdx.files.internal("jsons/Nations_Simplified_Chinese.json").exists())
|
||||
charSet.addAll(Gdx.files.internal("jsons/Nations_Simplified_Chinese.json").readString().asIterable())
|
||||
if (Gdx.files.internal("jsons/Tutorials/Tutorials_Simplified_Chinese.json").exists())
|
||||
|
@ -47,64 +75,39 @@ class Fonts {
|
|||
}
|
||||
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)
|
||||
if(UnCivGame.Current.settings.fontSet=="WenQuanYiMicroHei"){
|
||||
val fontForLanguage="WenQuanYiMicroHei"
|
||||
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))
|
||||
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(fontForLanguage)
|
||||
|
||||
parameter.characters = getCharsForFont()
|
||||
val font = generator.generateFont(parameter)
|
||||
generator.dispose() // don't forget to dispose to avoid memory leaks!
|
||||
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
|
||||
|
||||
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.ui.*
|
||||
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.ui.utils.*
|
||||
import com.unciv.ui.worldscreen.WorldScreen
|
||||
import java.io.IOException
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
class Language(val language:String){
|
||||
|
@ -76,6 +77,8 @@ class WorldScreenOptionsTable(val worldScreen:WorldScreen) : PopupTable(worldScr
|
|||
update()
|
||||
}
|
||||
|
||||
addFontSelectBox(innerTable)
|
||||
|
||||
addLanguageSelectBox(innerTable)
|
||||
|
||||
addResolutionSelectBox(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) {
|
||||
innerTable.add("Language".toLabel())
|
||||
val languageSelectBox = SelectBox<Language>(skin)
|
||||
|
@ -209,27 +268,7 @@ class WorldScreenOptionsTable(val worldScreen:WorldScreen) : PopupTable(worldScr
|
|||
languageSelectBox.addListener(object : ChangeListener() {
|
||||
override fun changed(event: ChangeEvent?, actor: Actor?) {
|
||||
selectedLanguage = languageSelectBox.selected.language
|
||||
if (Fonts().containsFont(Fonts().getFontForLanguage(selectedLanguage)))
|
||||
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(){
|
||||
UnCivGame.Current.settings.language = selectedLanguage
|
||||
UnCivGame.Current.settings.save()
|
||||
|
||||
CameraStageBaseScreen.resetFonts()
|
||||
|
||||
UnCivGame.Current.worldScreen = WorldScreen(worldScreen.viewingCiv)
|
||||
UnCivGame.Current.setWorldScreen()
|
||||
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
|
||||
|
||||
class YesNoPopupTable(question:String, action:()->Unit,
|
||||
screen: CameraStageBaseScreen = UnCivGame.Current.worldScreen) : PopupTable(screen){
|
||||
screen: CameraStageBaseScreen = UnCivGame.Current.worldScreen, restoredefault:()->Unit = {}) : PopupTable(screen){
|
||||
init{
|
||||
if(!screen.hasPopupOpen) {
|
||||
screen.hasPopupOpen=true
|
||||
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() })
|
||||
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
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
|
||||
distributionSha256Sum=53b71812f18cdb2777e9f1b2a0f2038683907c90bdc406bc64d8b400e1fb2c3b
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
|
||||
|
|
Loading…
Reference in a new issue