Skip to content

Commit 3309595

Browse files
committed
Kotlinize yourself
1 parent 8921bf7 commit 3309595

File tree

1 file changed

+39
-58
lines changed
  • common/src/main/kotlin/com/lambda/graphics/renderer/gui/font

1 file changed

+39
-58
lines changed

common/src/main/kotlin/com/lambda/graphics/renderer/gui/font/FontRenderer.kt

Lines changed: 39 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.lambda.graphics.renderer.gui.font
22

3-
import com.lambda.graphics.buffer.vao.IRenderContext
43
import com.lambda.graphics.buffer.vao.vertex.VertexAttrib
54
import com.lambda.graphics.buffer.vao.vertex.VertexMode
65
import com.lambda.graphics.renderer.Renderer
@@ -25,19 +24,15 @@ class FontRenderer(
2524
* @param text The text to parse.
2625
* @return A list of triples containing the emoji text, start index, and end index.
2726
*/
28-
fun parseEmojis(text: String): List<Pair<GlyphInfo, IntRange>> {
29-
val result = mutableListOf<Pair<GlyphInfo, IntRange>>()
30-
val matches = emojiRegex.findAll(text)
31-
32-
for (match in matches) {
33-
val emojiKey = match.value.substring(1, match.value.length - 1)
34-
val charInfo = emojis[emojiKey] ?: continue
35-
result.add(charInfo to match.range)
27+
fun parseEmojis(text: String) =
28+
mutableListOf<Pair<GlyphInfo, IntRange>>().apply {
29+
emojiRegex.findAll(text).forEach { match ->
30+
val emojiKey = match.value.substring(1, match.value.length - 1)
31+
val charInfo = emojis[emojiKey] ?: return@forEach
32+
add(charInfo to match.range)
33+
}
3634
}
3735

38-
return result
39-
}
40-
4136
/**
4237
* Builds the vertex array for rendering the text.
4338
*/
@@ -49,7 +44,13 @@ class FontRenderer(
4944
shadow: Boolean = true
5045
) = vao.use {
5146
iterateText(text, scale, shadow, color) { char, pos1, pos2, color ->
52-
putChar(position, pos1, pos2, color, char)
47+
grow(4)
48+
putQuad(
49+
vec2(pos1.x + position.x, pos1.y + position.y).vec2(char.uv1.x, char.uv1.y).color(color).end(),
50+
vec2(pos1.x + position.x, pos2.y + position.y).vec2(char.uv1.x, char.uv2.y).color(color).end(),
51+
vec2(pos2.x + position.x, pos2.y + position.y).vec2(char.uv2.x, char.uv2.y).color(color).end(),
52+
vec2(pos2.x + position.x, pos1.y + position.y).vec2(char.uv2.x, char.uv1.y).color(color).end()
53+
)
5354
}
5455
}
5556

@@ -89,8 +90,8 @@ class FontRenderer(
8990
block: (GlyphInfo, Vec2d, Vec2d, Color) -> Unit
9091
) {
9192
val actualScale = getScaleFactor(scale)
92-
val scaledShadowShift = shadowShift * actualScale
9393
val scaledGap = gap * actualScale
94+
9495
val shadowColor = getShadowColor(color)
9596
val emojiColor = Color.WHITE.setAlpha(color.a)
9697

@@ -99,59 +100,39 @@ class FontRenderer(
99100

100101
val emojis = parseEmojis(text)
101102

102-
var index = 0
103-
while (index < text.length) {
104-
run { // Because continue is not allowed in lambda
105-
emojis
106-
.firstOrNull { index in it.second }
107-
?.let { emoji ->
108-
val scaledSize = emoji.first.size * actualScale
109-
val pos1 = Vec2d(posX, posY)
110-
val pos2 = pos1 + scaledSize
111-
112-
block(emoji.first, pos1, pos2, emojiColor)
103+
repeat(text.length) { index ->
104+
fun draw(info: GlyphInfo, color: Color, offset: Double = 0.0) {
105+
val scaledSize = info.size * actualScale
106+
val pos1 = Vec2d(posX, posY) + offset * actualScale
107+
val pos2 = pos1 + scaledSize
113108

114-
posX += scaledSize.x + scaledGap
115-
index = emoji.second.last
116-
return@run
117-
}
109+
block(info, pos1, pos2, color)
110+
if (offset == 0.0) posX += scaledSize.x + scaledGap
111+
}
118112

119-
val char = text[index]
120-
val glyph = font[char] ?: return@run
113+
// Check if there's an emoji
114+
emojis.firstOrNull { index in it.second }?.let { emoji ->
115+
// Replace first emoji char by an emoji glyph and skip the other ones
116+
if (index == emoji.second.first) {
117+
draw(emoji.first, emojiColor)
118+
}
121119

122-
val scaledSize = glyph.size * actualScale
123-
val pos1 = Vec2d(posX, posY)
124-
val pos2 = pos1 + scaledSize
120+
return@repeat
121+
}
125122

126-
if (shadow && FontSettings.shadow) {
127-
val shadowPos1 = pos1 + scaledShadowShift
128-
val shadowPos2 = shadowPos1 + scaledSize
129-
block(glyph, shadowPos1, shadowPos2, shadowColor)
123+
// Render chars
124+
font[text[index]]?.let { info ->
125+
// Draw a shadow before
126+
if (shadow && FontSettings.shadow && shadowShift > 0.0) {
127+
draw(info, shadowColor, shadowShift)
130128
}
131129

132-
block(glyph, pos1, pos2, color)
133-
134-
posX += scaledSize.x + scaledGap
130+
// Draw actual char over the shadow
131+
draw(info, color)
135132
}
136-
137-
index++
138133
}
139134
}
140135

141-
private fun IRenderContext.putChar(pos: Vec2d, lt: Vec2d, rb: Vec2d, color: Color, ci: GlyphInfo) {
142-
val x = pos.x
143-
val y = pos.y
144-
145-
grow(4)
146-
147-
putQuad(
148-
vec2(lt.x + x, lt.y + y).vec2(ci.uv1.x, ci.uv1.y).color(color).end(),
149-
vec2(lt.x + x, rb.y + y).vec2(ci.uv1.x, ci.uv2.y).color(color).end(),
150-
vec2(rb.x + x, rb.y + y).vec2(ci.uv2.x, ci.uv2.y).color(color).end(),
151-
vec2(rb.x + x, lt.y + y).vec2(ci.uv2.x, ci.uv1.y).color(color).end()
152-
)
153-
}
154-
155136
private fun getScaleFactor(scale: Double) = scaleMultiplier * scale * 0.12
156137

157138
private fun getShadowColor(color: Color): Color {
@@ -176,7 +157,7 @@ class FontRenderer(
176157
companion object {
177158
private val shader = Shader("renderer/font")
178159

179-
private val shadowShift get() = FontSettings.shadowShift * 4.0
160+
private val shadowShift get() = FontSettings.shadowShift * 5.0
180161
private val baselineOffset get() = FontSettings.baselineOffset * 2.0f - 10f
181162
private val gap get() = FontSettings.gapSetting * 0.5f - 0.8f
182163
}

0 commit comments

Comments
 (0)