diff --git a/android/build.gradle b/android/build.gradle index 161a85aeb8..d107484545 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -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") diff --git a/android/proguard-rules.pro b/android/proguard-rules.pro index b166b1e81c..3f3ade7ebc 100644 --- a/android/proguard-rules.pro +++ b/android/proguard-rules.pro @@ -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 diff --git a/android/src/com/unciv/app/AndroidLauncher.java b/android/src/com/unciv/app/AndroidLauncher.java deleted file mode 100644 index c89fe37f9b..0000000000 --- a/android/src/com/unciv/app/AndroidLauncher.java +++ /dev/null @@ -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); - } -} diff --git a/android/src/com/unciv/app/AndroidLauncher.kt b/android/src/com/unciv/app/AndroidLauncher.kt new file mode 100644 index 0000000000..86832c1e0f --- /dev/null +++ b/android/src/com/unciv/app/AndroidLauncher.kt @@ -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) + } +} \ No newline at end of file diff --git a/android/src/core/java/nativefont/NativeFontAndroid.java b/android/src/core/java/nativefont/NativeFontAndroid.java deleted file mode 100755 index 53d7a8f321..0000000000 --- a/android/src/core/java/nativefont/NativeFontAndroid.java +++ /dev/null @@ -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 fontFaces = new HashMap(); - 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)); - } -} diff --git a/android/src/core/java/nativefont/NativeFontAndroid.kt b/android/src/core/java/nativefont/NativeFontAndroid.kt new file mode 100755 index 0000000000..f695eca359 --- /dev/null +++ b/android/src/core/java/nativefont/NativeFontAndroid.kt @@ -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() + 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() + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index a7741c455c..944ba7d61d 100644 --- a/build.gradle +++ b/build.gradle @@ -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" } diff --git a/core/src/core/java/nativefont/NativeFont.kt b/core/src/core/java/nativefont/NativeFont.kt index 207191f041..744f6d32bd 100644 --- a/core/src/core/java/nativefont/NativeFont.kt +++ b/core/src/core/java/nativefont/NativeFont.kt @@ -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 @@ -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!!)) } } diff --git a/core/src/core/java/nativefont/NativeFontListener.java b/core/src/core/java/nativefont/NativeFontListener.java deleted file mode 100755 index a8de2ba29b..0000000000 --- a/core/src/core/java/nativefont/NativeFontListener.java +++ /dev/null @@ -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); -} diff --git a/core/src/core/java/nativefont/NativeFontListener.kt b/core/src/core/java/nativefont/NativeFontListener.kt new file mode 100755 index 0000000000..33b9fb29f7 --- /dev/null +++ b/core/src/core/java/nativefont/NativeFontListener.kt @@ -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 +} \ No newline at end of file diff --git a/core/src/core/java/nativefont/NativeFontPaint.java b/core/src/core/java/nativefont/NativeFontPaint.java deleted file mode 100755 index a832a20170..0000000000 --- a/core/src/core/java/nativefont/NativeFontPaint.java +++ /dev/null @@ -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; - } - -} diff --git a/core/src/core/java/nativefont/NativeFontPaint.kt b/core/src/core/java/nativefont/NativeFontPaint.kt new file mode 100755 index 0000000000..e234fa20f3 --- /dev/null +++ b/core/src/core/java/nativefont/NativeFontPaint.kt @@ -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 + } + +} \ No newline at end of file diff --git a/desktop/src/core/java/nativefont/NativeFontDesktop.java b/desktop/src/core/java/nativefont/NativeFontDesktop.java deleted file mode 100755 index 66734044c4..0000000000 --- a/desktop/src/core/java/nativefont/NativeFontDesktop.java +++ /dev/null @@ -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 fonts = new HashMap(); - private HashMap metrics = new HashMap(); - 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; - } - -} diff --git a/desktop/src/core/java/nativefont/NativeFontDesktop.kt b/desktop/src/core/java/nativefont/NativeFontDesktop.kt new file mode 100755 index 0000000000..c2608315d5 --- /dev/null +++ b/desktop/src/core/java/nativefont/NativeFontDesktop.kt @@ -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() + private val metrics = HashMap() + 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 + } +} \ No newline at end of file