@@ -41,7 +41,7 @@ private const val MAX_BATCH = 1024
4141private val EMPTY_ROW = floatArrayOf(0f , 0f , 0f , 0f )
4242private val NO_UV = floatArrayOf(- 1f , - 1f , 1f , 1f )
4343
44- @Suppress(" UnstableApiUsage" )
44+ @Suppress(" UnstableApiUsage" , " INVISIBLE_MEMBER " , " INVISIBLE_REFERENCE " )
4545class GLRendererImpl (private val nsvg : NanoSvgApi , private val stb : StbApi ) : Renderer {
4646
4747 private val buffer = BufferUtils .createFloatBuffer(MAX_BATCH * STRIDE )
@@ -428,6 +428,12 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
428428 org.lwjgl.opengl.GL30 .glBindVertexArray(vao)
429429 } else prevVao = 0
430430 glUseProgram(program)
431+
432+ if (popFlushNeeded) {
433+ glUniformMatrix3fv(uTransform, false , transformBuffer)
434+ popFlushNeeded = false
435+ }
436+
431437 glActiveTexture(GL_TEXTURE0 )
432438 glBindTexture(GL_TEXTURE_2D , curTex)
433439
@@ -591,7 +597,7 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
591597 if (count >= MAX_BATCH ) {
592598 flush()
593599 }
594- val glyph = fAtlas.glyphs[c] ? : continue
600+ val glyph = fAtlas.get(c)
595601 buffer.put(penX + glyph.xOff * scaleFactor).put(penY + glyph.yOff * scaleFactor)
596602 .put(glyph.width * scaleFactor).put(glyph.height * scaleFactor)
597603 buffer.put(EMPTY_ROW ) // zero radii
@@ -696,23 +702,12 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
696702 }
697703
698704 override fun pop () {
699- val prevProg = glGetInteger(GL_CURRENT_PROGRAM )
700- if (popFlushNeeded) {
701- glUseProgram(program)
702- transformBuffer.clear()
703- transformBuffer.put(transform).flip()
704- glUniformMatrix3fv(uTransform, false , transformBuffer)
705- glUseProgram(prevProg)
706- flush()
707- popFlushNeeded = false
708- }
709705 if (transform.isIdentity()) return
706+ flush()
710707 if (transformStack.isEmpty()) {
711708 loadIdentity()
712709 } else transform = transformStack.removeLast()
713- glUseProgram(program)
714- glUniformMatrix3fv(uTransform, false , transformBuffer)
715- glUseProgram(prevProg)
710+ popFlushNeeded = true
716711 }
717712
718713 override fun translate (x : Float , y : Float ) {
@@ -890,7 +885,7 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
890885 }
891886
892887 private inner class FontAtlas (data : ByteBuffer , val renderedSize : Float ) {
893- val glyphs = HashMap < Char , Glyph >()
888+ private val glyphs: Array < FloatArray >
894889 val ascent: Float
895890 val descent: Float
896891 val lineGap: Float
@@ -957,15 +952,14 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
957952 val sy = slotY
958953
959954
960- for (i in 0 .. < 95 ) {
961- val c = (i + 32 ).toChar()
962- val g = stb.font_GetPackedGlyph(packed, i)
955+ glyphs = Array (95 ) {
956+ val g = stb.font_GetPackedGlyph(packed, it)
963957 val x0 = stb.glyph_x0(g)
964958 val y0 = stb.glyph_y0(g)
965959 val x1 = stb.glyph_x1(g)
966960 val y1 = stb.glyph_y1(g)
967961
968- val glyph = Glyph (
962+ floatArrayOf (
969963 (sx + x0) / ATLAS_SIZE .toFloat(),
970964 (sy + y0) / ATLAS_SIZE .toFloat(),
971965 (x1 - x0) / ATLAS_SIZE .toFloat(),
@@ -976,7 +970,6 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
976970 (y1 - y0).toFloat(),
977971 stb.glyph_xadvance(g)
978972 )
979- glyphs[c] = glyph
980973 }
981974 stb.free(packed)
982975 stb.free(range)
@@ -1013,50 +1006,41 @@ class GLRendererImpl(private val nsvg: NanoSvgApi, private val stb: StbApi) : Re
10131006// var height = 0f
10141007 val scaleFactor = fontSize / this .renderedSize
10151008 for (c in text) {
1016- val g = glyphs[c] ? : continue
1017- width + = g.xAdvance * scaleFactor
1009+ width + = get(c).xAdvance * scaleFactor
10181010// height = maxOf(height, g.height + g.offsetY)
10191011 }
10201012 return Vec2 .of(width, fontSize)
10211013 }
1022- }
10231014
1024- @JvmInline
1025- @Suppress(" INVISIBLE_MEMBER" , " INVISIBLE_REFERENCE" )
1026- private value class Glyph (val data : FloatArray ) {
1015+ @Suppress(" DEPRECATION" )
10271016 @kotlin.internal.InlineOnly
1028- inline val u get() = data[0 ]
1017+ inline fun get (char : Char ) = glyphs[(char.toInt() - 32 ) /* .coerceIn(0, glyphs.size - 1) */ ]
1018+ }
10291019
1030- @kotlin.internal.InlineOnly
1031- inline val v get() = data[ 1 ]
1020+ @kotlin.internal.InlineOnly
1021+ inline val FloatArray .u get() = this [ 0 ]
10321022
1033- @kotlin.internal.InlineOnly
1034- inline val uw get() = data[ 2 ]
1023+ @kotlin.internal.InlineOnly
1024+ inline val FloatArray .v get() = this [ 1 ]
10351025
1036- @kotlin.internal.InlineOnly
1037- inline val vh get() = data[ 3 ]
1026+ @kotlin.internal.InlineOnly
1027+ inline val FloatArray .uw get() = this [ 2 ]
10381028
1039- @kotlin.internal.InlineOnly
1040- inline val xOff get() = data[ 4 ]
1029+ @kotlin.internal.InlineOnly
1030+ inline val FloatArray .vh get() = this [ 3 ]
10411031
1042- @kotlin.internal.InlineOnly
1043- inline val yOff get() = data[ 5 ]
1032+ @kotlin.internal.InlineOnly
1033+ inline val FloatArray .xOff get() = this [ 4 ]
10441034
1045- @kotlin.internal.InlineOnly
1046- inline val width get() = data[ 6 ]
1035+ @kotlin.internal.InlineOnly
1036+ inline val FloatArray .yOff get() = this [ 5 ]
10471037
1048- @kotlin.internal.InlineOnly
1049- inline val height get() = data[ 7 ]
1038+ @kotlin.internal.InlineOnly
1039+ inline val FloatArray .width get() = this [ 6 ]
10501040
1051- @kotlin.internal.InlineOnly
1052- inline val xAdvance get() = data[8 ]
1053-
1054- constructor (
1055- uvX: Float , uvY: Float , uvW: Float , uvH: Float ,
1056- offsetX: Float , offsetY: Float ,
1057- width: Float , height: Float ,
1058- advanceX: Float
1059- ) : this (floatArrayOf(uvX, uvY, uvW, uvH, offsetX, offsetY, width, height, advanceX))
1041+ @kotlin.internal.InlineOnly
1042+ inline val FloatArray .height get() = this [7 ]
10601043
1061- }
1044+ @kotlin.internal.InlineOnly
1045+ inline val FloatArray .xAdvance get() = this [8 ]
10621046}
0 commit comments