all codes are writen in Kotlin (#1452)

This commit is contained in:
lishaoxia1985 2019-12-16 02:28:34 +08:00 committed by Yair Morgenstern
parent 5d75c3d65e
commit e937ea0af1
14 changed files with 321 additions and 425 deletions

View File

@ -63,30 +63,37 @@ android {
// called every time gradle gets executed, takes the native dependencies of
// the natives configuration, and extracts them to the proper libs/ folders
// so they get packed with the APK.
task copyAndroidNatives() {
file("libs/armeabi/").mkdirs()
file("libs/armeabi-v7a/").mkdirs()
file("libs/arm64-v8a/").mkdirs()
file("libs/x86_64/").mkdirs()
file("libs/x86/").mkdirs()
configurations.natives.files.each { jar ->
def outputDir = null
if(jar.name.endsWith("natives-arm64-v8a.jar")) outputDir = file("libs/arm64-v8a")
if(jar.name.endsWith("natives-armeabi-v7a.jar")) outputDir = file("libs/armeabi-v7a")
if(jar.name.endsWith("natives-armeabi.jar")) outputDir = file("libs/armeabi")
if(jar.name.endsWith("natives-x86_64.jar")) outputDir = file("libs/x86_64")
if(jar.name.endsWith("natives-x86.jar")) outputDir = file("libs/x86")
if(outputDir != null) {
copy {
from zipTree(jar)
into outputDir
include "*.so"
task copyAndroidNatives() {
doFirst {
file("libs/armeabi/").mkdirs()
file("libs/armeabi-v7a/").mkdirs()
file("libs/arm64-v8a/").mkdirs()
file("libs/x86_64/").mkdirs()
file("libs/x86/").mkdirs()
configurations.natives.files.each { jar ->
def outputDir = null
if(jar.name.endsWith("natives-arm64-v8a.jar")) outputDir = file("libs/arm64-v8a")
if(jar.name.endsWith("natives-armeabi-v7a.jar")) outputDir = file("libs/armeabi-v7a")
if(jar.name.endsWith("natives-armeabi.jar")) outputDir = file("libs/armeabi")
if(jar.name.endsWith("natives-x86_64.jar")) outputDir = file("libs/x86_64")
if(jar.name.endsWith("natives-x86.jar")) outputDir = file("libs/x86")
if(outputDir != null) {
copy {
from zipTree(jar)
into outputDir
include "*.so"
}
}
}
}
}
tasks.whenTaskAdded { packageTask ->
if (packageTask.name.contains("package")) {
packageTask.dependsOn 'copyAndroidNatives'
}
}
task run(type: Exec) {
def path
def localProperties = project.file("../local.properties")

View File

@ -26,7 +26,6 @@
-dontwarn com.badlogic.gdx.utils.GdxBuild
-dontwarn com.badlogic.gdx.physics.box2d.utils.Box2DBuild
-dontwarn com.badlogic.gdx.jnigen.BuildTarget*
-dontwarn com.badlogic.gdx.graphics.g2d.freetype.FreetypeBuild
-keep class com.badlogic.gdx.controllers.android.AndroidControllers

View File

@ -1,22 +0,0 @@
package com.unciv.app;
import android.os.Bundle;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.unciv.UncivGame;
// If we convert this to Kotlin, the the Gradle build won't work. =(
// Stuck with Java for now
public class AndroidLauncher extends AndroidApplication {
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
String version = BuildConfig.VERSION_NAME;
config.useImmersiveMode=true;
initialize(new UncivGame(version), config);
}
}

View File

@ -0,0 +1,16 @@
package com.unciv.app
import android.os.Bundle
import com.badlogic.gdx.backends.android.AndroidApplication
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration
import com.unciv.UncivGame
class AndroidLauncher : AndroidApplication() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val config = AndroidApplicationConfiguration()
val version = BuildConfig.VERSION_NAME
config.useImmersiveMode = true
initialize(UncivGame(version), config)
}
}

View File

@ -1,78 +0,0 @@
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));
}
}

View File

@ -0,0 +1,70 @@
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.*
/**
* Created by tian on 2016/10/2.
*/
class NativeFontAndroid : NativeFontListener {
private val fontFaces = HashMap<String, Typeface>()
private val androidApplication = Gdx.app as AndroidApplication
override fun getFontPixmap(txt: String, vpaint: NativeFontPaint): Pixmap {
val paint = Paint()
if (vpaint.tTFName != "") {
Gdx.app.log("app", Gdx.files.internal(vpaint.tTFName +
if (vpaint.tTFName.endsWith(".ttf")) "" else ".ttf").file().path)
val fontFace = Typeface.createFromAsset(androidApplication.assets, vpaint.tTFName +
if (vpaint.tTFName.endsWith(".ttf")) "" else ".ttf")
fontFaces[vpaint.tTFName] = fontFace
paint.typeface = fontFace
}
paint.isAntiAlias = true
paint.textSize = vpaint.textSize.toFloat()
val fm = paint.fontMetrics
var w = paint.measureText(txt).toInt()
var h = (fm.descent - fm.ascent).toInt()
if (w == 0) {
h = vpaint.textSize
w = h
}
var bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
var canvas: Canvas? = Canvas(bitmap)
// 如果是描边类型
if (vpaint.strokeColor != null) { // 绘制外层
paint.color = getColor(vpaint.strokeColor)
paint.strokeWidth = vpaint.strokeWidth.toFloat() // 描边宽度
paint.style = Paint.Style.FILL_AND_STROKE // 描边种类
paint.isFakeBoldText = true // 外层text采用粗体
canvas!!.drawText(txt, 0f, -fm.ascent, paint)
paint.isFakeBoldText = false
} else {
paint.isUnderlineText = vpaint.underlineText
paint.isStrikeThruText = vpaint.strikeThruText
paint.isFakeBoldText = vpaint.fakeBoldText
}
// 绘制内层
paint.strokeWidth = 0f
paint.color = getColor(vpaint.color)
canvas!!.drawText(txt, 0f, -fm.ascent, paint)
val buffer = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, buffer)
val encodedData = buffer.toByteArray()
val pixmap = Pixmap(encodedData, 0, encodedData.size)
buffer.close()
bitmap.recycle()
return pixmap
}
private fun getColor(color: Color?): Int {
return (color!!.a * 255.0f).toInt() shl 24 or ((color.r * 255.0f).toInt() shl 16) or ((color.g * 255.0f).toInt() shl 8) or (color.b * 255.0f).toInt()
}
}

View File

@ -76,7 +76,8 @@ project(":desktop") {
project(":android") {
apply plugin: "android"
//apply plugin: "kotlin-android" // This seems to have problems in Gradle 4.6
apply plugin: "kotlin-android"
apply plugin: "kotlin-android-extensions"
configurations { natives }
@ -94,15 +95,6 @@ project(":android") {
natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-arm64-v8a"
natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-x86"
natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-x86_64"
// Freetype
implementation "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi-v7a"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-arm64-v8a"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86_64"
}
}
@ -128,7 +120,6 @@ project(":core") {
dependencies {
implementation "com.badlogicgames.gdx:gdx:$gdxVersion"
implementation "com.badlogicgames.gdx:gdx-box2d:$gdxVersion"
implementation "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
}

View File

@ -29,14 +29,19 @@ class NativeFont @JvmOverloads constructor(paint: NativeFontPaint = NativeFontPa
private fun createListener() {
var className = "core.java.nativefont.NativeFont"
if (Gdx.app.type == Application.ApplicationType.Desktop) {
className += "Desktop"
} else if (Gdx.app.type == Application.ApplicationType.Android) {
className += "Android"
} else if (Gdx.app.type == Application.ApplicationType.iOS) {
className += if (robovm) "IOS" else "IOSMoe"
} else if (Gdx.app.type == Application.ApplicationType.WebGL) {
className += "Html"
when (Gdx.app.type) {
Application.ApplicationType.Desktop -> {
className += "Desktop"
}
Application.ApplicationType.Android -> {
className += "Android"
}
Application.ApplicationType.iOS -> {
className += if (robovm) "IOS" else "IOSMoe"
}
Application.ApplicationType.WebGL -> {
className += "Html"
}
}
listener = try {
val claz = Gdx.app.javaClass.classLoader.loadClass(className) as Class<out NativeFontListener>
@ -163,7 +168,7 @@ class NativeFont @JvmOverloads constructor(paint: NativeFontPaint = NativeFontPa
val date = emojiSet[css]
appendEmoji(c2.toString() + "", date!!.path, date.size)
} else {
putGlyph(c2, listener!!.getFontPixmap(txt, paint))
putGlyph(c2, listener!!.getFontPixmap(txt, paint!!))
}
}

View File

@ -1,11 +0,0 @@
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);
}

View File

@ -0,0 +1,10 @@
package core.java.nativefont
import com.badlogic.gdx.graphics.Pixmap
/**
* Created by tian on 2016/10/2.
*/
interface NativeFontListener {
fun getFontPixmap(txt: String, vpaint: NativeFontPaint): Pixmap
}

View File

@ -1,146 +0,0 @@
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;
}
}

View File

@ -0,0 +1,79 @@
package core.java.nativefont
import com.badlogic.gdx.graphics.Color
/**
* Created by tian on 2016/10/2.
*/
class NativeFontPaint {
var textSize = 30 // 字号
var color = Color.WHITE // 颜色
var fakeBoldText = false // 是否粗体
var underlineText = false // 是否下划线
var strikeThruText = false // 是否删除线
var strokeColor: Color? = null // 描边颜色
var strokeWidth = 3 // 描边宽度
var tTFName = ""
val name: String
get() {
val name = StringBuffer()
name.append(tTFName).append("_").append(textSize).append("_").append(color.toIntBits())
.append("_").append(booleanToInt(fakeBoldText)).append("_")
.append(booleanToInt(underlineText))
if (strokeColor != null) {
name.append("_").append(strokeColor!!.toIntBits()).append("_").append(strokeWidth)
}
return name.toString()
}
private fun booleanToInt(b: Boolean): Int {
return if (b == true) 0 else 1
}
constructor() {}
constructor(ttfName: String, textSize: Int, color: Color, stroke: Color?, strokeWidth: Int,
bold: Boolean, line: Boolean, thru: Boolean) {
tTFName = ttfName
this.textSize = textSize
this.color = color
strokeColor = stroke
this.strokeWidth = strokeWidth
fakeBoldText = bold
underlineText = line
strikeThruText = thru
}
constructor(ttfName: String) {
tTFName = ttfName
}
constructor(ttfName: String, size: Int) {
tTFName = ttfName
textSize = size
}
constructor(ttfName: String, size: Int, color: Color) {
tTFName = ttfName
textSize = size
this.color = color
}
constructor(ttfName: String, color: Color) {
tTFName = ttfName
this.color = color
}
constructor(size: Int) {
textSize = size
}
constructor(color: Color) {
this.color = color
}
constructor(size: Int, color: Color) {
textSize = size
this.color = color
}
}

View File

@ -1,128 +0,0 @@
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;
}
}

View File

@ -0,0 +1,104 @@
package core.java.nativefont
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Pixmap
import java.awt.*
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.*
import javax.imageio.ImageIO
import javax.swing.UIManager
class NativeFontDesktop : NativeFontListener {
private val fonts = HashMap<String, Font?>()
private val metrics = HashMap<String, FontMetrics>()
override fun getFontPixmap(txt: String, vpaint: NativeFontPaint): Pixmap {
val font = getFont(vpaint)
val fm = metrics[vpaint.name]
var strWidth = fm!!.stringWidth(txt)
var strHeight = fm.ascent + fm.descent
if (strWidth == 0) {
strHeight = vpaint.textSize
strWidth = strHeight
}
val bi = BufferedImage(strWidth, strHeight, BufferedImage.TYPE_4BYTE_ABGR)
val g = bi.createGraphics()
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
g.font = font
when {
vpaint.strokeColor != null -> { // 描边
val v = font!!.createGlyphVector(fm.fontRenderContext, txt)
val shape = v.outline
g.color = UIManager.getColor(vpaint.color)
g.translate(0, fm.ascent)
g.fill(shape)
g.stroke = BasicStroke(vpaint.strokeWidth.toFloat())
g.color = UIManager.getColor(vpaint.strokeColor)
g.draw(shape)
}
vpaint.underlineText -> { // 下划线
val `as` = AttributedString(txt)
`as`.addAttribute(TextAttribute.FONT, font)
`as`.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON)
g.color = UIManager.getColor(vpaint.color)
g.drawString(`as`.iterator, 0, fm.ascent)
}
vpaint.strikeThruText -> { // 删除线
val `as` = AttributedString(txt)
`as`.addAttribute(TextAttribute.FONT, font)
`as`.addAttribute(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON)
g.color = UIManager.getColor(vpaint.color)
g.drawString(`as`.iterator, 0, fm.ascent)
}
else -> { // 普通
g.color = UIManager.getColor(vpaint.color)
g.drawString(txt, 0, fm.ascent)
}
}
lateinit var pixmap: Pixmap
try {
val buffer = ByteArrayOutputStream()
ImageIO.write(bi, "png", buffer)
pixmap = Pixmap(buffer.toByteArray(), 0, buffer.toByteArray().size)
buffer.close()
} catch (e: IOException) {
e.printStackTrace()
}
return pixmap
}
private fun getFont(vpaint: NativeFontPaint): Font? {
val isBolo = vpaint.fakeBoldText || vpaint.strokeColor != null
var font = fonts[vpaint.name]
if (font == null) {
if (vpaint.tTFName == "") {
font = Font("", if (isBolo) Font.BOLD else Font.PLAIN, vpaint.textSize)
} else {
try {
val `in` = ByteArrayInputStream(Gdx.files.internal(vpaint.tTFName +
if (vpaint.tTFName.endsWith(".ttf")) "" else ".ttf").readBytes())
val fb = BufferedInputStream(`in`)
font = Font.createFont(Font.TRUETYPE_FONT, fb).deriveFont(Font.BOLD, vpaint.textSize.toFloat())
fb.close()
`in`.close()
} catch (e: FontFormatException) {
e.printStackTrace()
} catch (e: IOException) {
e.printStackTrace()
}
}
fonts[vpaint.name] = font
val bi = BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR)
val g = bi.createGraphics()
g.font = font
val fm = g.fontMetrics
metrics[vpaint.name] = fm
}
return font
}
}