@@ -7,8 +7,8 @@ import com.lambda.util.math.Vec2d
77import java.awt.Color
88import java.awt.Graphics2D
99import java.awt.image.BufferedImage
10+ import java.io.File
1011import java.net.URL
11- import java.nio.file.Files
1212import java.util.zip.ZipFile
1313import javax.imageio.ImageIO
1414import kotlin.math.ceil
@@ -19,52 +19,63 @@ class EmojiGlyphs(zipUrl: String) {
1919 private val emojiMap = mutableMapOf<String , CharInfo >()
2020 private val fontTexture: MipmapTexture
2121
22- init {
23- val file = Files .createTempFile(" emoji" , " .zip" ).toFile()
24- val url = URL (zipUrl)
25- file.writeBytes(url.readBytes())
26-
27- ZipFile (file).use { zip ->
28- // someone please refactor this
29- val first = ImageIO .read(zip.getInputStream(zip.entries().nextElement()))
30-
31- val size = zip.entries().asSequence().count()
32- val dimensions = Vec2d (first.width.toDouble(), first.height.toDouble())
33- val texelSize = 1.0 / size
34- val width = first.width * ceil(sqrt(size.toDouble())).toInt()
35- val height = first.height * ceil(sqrt(size.toDouble())).toInt()
36-
37- val image = BufferedImage (width, height, BufferedImage .TYPE_INT_ARGB )
38- val graphics = image.graphics as Graphics2D
39- graphics.background = Color (0 , 0 , 0 , 0 )
40-
41- var x = 0
42- var y = 0
43-
44- val time = measureTimeMillis {
45- zip.entries().asSequence().forEach { entry ->
46- val name = entry.name.substringAfterLast(" /" ).substringBeforeLast(" ." )
47- val emoji = ImageIO .read(zip.getInputStream(entry))
48-
49- if (x + emoji.width >= width) {
50- y + = emoji.height
51- x = 0
52- }
22+ private val image: BufferedImage
23+ private val graphics: Graphics2D
5324
54- graphics.drawImage(emoji, x, y, null )
25+ init {
26+ var x = 0
27+ var y = 0
5528
56- val uv1 = Vec2d (x.toDouble(), y.toDouble()) * texelSize
57- val uv2 = Vec2d (x, y).plus(dimensions) * texelSize
58- emojiMap[name] = CharInfo (dimensions, uv1 * - 1.0 , uv2 * - 1.0 )
29+ val time = measureTimeMillis {
30+ val file = File .createTempFile( " emoji " , " .zip " )
31+ file.deleteOnExit( )
5932
60- x + = emoji.width
33+ file.outputStream().use { output ->
34+ URL (zipUrl).openStream().use { input ->
35+ input.copyTo(output)
6136 }
6237 }
6338
64- fontTexture = MipmapTexture (image)
39+ ZipFile (file).use { zip ->
40+ val firstImage = ImageIO .read(zip.getInputStream(zip.entries().nextElement()))
41+
42+ val length = zip.size().toDouble()
43+ val squaredLength = ceil(sqrt(length)).toInt()
44+
45+ val texelSize = 1.0 / length
46+ val width = firstImage.width
47+ val height = firstImage.height
48+
49+ image = BufferedImage (width * squaredLength, height * squaredLength, BufferedImage .TYPE_INT_ARGB )
50+ graphics = image.graphics as Graphics2D
51+ graphics.color = Color (0 , 0 , 0 , 0 )
52+
53+ zip.entries().asSequence()
54+ .forEach { entry ->
55+ val name = entry.name.substringAfterLast(" /" ).substringBeforeLast(" ." )
56+ val emoji = ImageIO .read(zip.getInputStream(entry))
57+
58+ if (x + emoji.width >= image.width) {
59+ y + = emoji.height
60+ x = 0
61+ }
6562
66- LOG .info(" Loaded $size emojis in $time ms" )
63+ graphics.drawImage(emoji, x, y, null )
64+
65+ val size = Vec2d (emoji.width, emoji.height)
66+ val uv1 = Vec2d (- x, - y) * texelSize
67+ val uv2 = Vec2d (- x, - y).minus(size) * texelSize
68+
69+ emojiMap[name] = CharInfo (size, uv1, uv2)
70+
71+ x + = emoji.width
72+ }
73+ }
74+
75+ fontTexture = MipmapTexture (image)
6776 }
77+
78+ LOG .info(" Loaded ${emojiMap.size} emojis in $time ms" )
6879 }
6980
7081 fun bind () {
@@ -78,6 +89,6 @@ class EmojiGlyphs(zipUrl: String) {
7889 emojiMap[emoji]
7990
8091 companion object {
81- private const val GL_TEXTURE_SLOT = 1
92+ private const val GL_TEXTURE_SLOT = 1 // TODO: Texture slot borrowing
8293 }
8394}
0 commit comments