diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Ext.kt index 103f10939..f3fdb5aac 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Ext.kt @@ -12,6 +12,7 @@ import net.minecraft.network.chat.Component import net.minecraft.util.FormattedCharSequence import org.joml.Matrix4f import org.joml.Vector3f +import ru.dbotthepony.mc.otm.core.FloatSupplier import ru.dbotthepony.mc.otm.core.math.IAngle import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.core.math.Vector @@ -77,12 +78,12 @@ private fun Font.drawInBatch( text: Any, x: Float, y: Float, color: Int, drawShadow: Boolean, matrix4f: Matrix4f, buffer: MultiBufferSource, displayMode: Font.DisplayMode, effectColor: Int, packedLightCoords: Int, gravity: RenderGravity, - rounding: GravityRounding + rounding: GravityRounding, width: FloatSupplier ): Int { if (text is String) return drawInBatch( text, - gravity.x(x, this, text, rounding = rounding), + gravity.x(x, width, rounding = rounding), gravity.y(y, lineHeight.toFloat(), rounding = rounding), color, drawShadow, @@ -94,7 +95,7 @@ private fun Font.drawInBatch( else if (text is Component) return drawInBatch( text, - gravity.x(x, this, text, rounding = rounding), + gravity.x(x, width, rounding = rounding), gravity.y(y, lineHeight.toFloat(), rounding = rounding), color, drawShadow, @@ -106,7 +107,7 @@ private fun Font.drawInBatch( else if (text is FormattedCharSequence) return drawInBatch( text, - gravity.x(x, this, text, rounding = rounding), + gravity.x(x, width, rounding = rounding), gravity.y(y, lineHeight.toFloat(), rounding = rounding), color, drawShadow, @@ -126,6 +127,48 @@ private val outlinePositions = listOf( 0 to -1, ) +private class CachedTextWidth0(val font: Font, val text: Component) : FloatSupplier { + private var computed = false + private var width = 0f + + override fun getAsFloat(): Float { + if (!computed) { + width = font.width(text).toFloat() + computed = true + } + + return width + } +} + +private class CachedTextWidth1(val font: Font, val text: String) : FloatSupplier { + private var computed = false + private var width = 0f + + override fun getAsFloat(): Float { + if (!computed) { + width = font.width(text).toFloat() + computed = true + } + + return width + } +} + +private class CachedTextWidth2(val font: Font, val text: FormattedCharSequence) : FloatSupplier { + private var computed = false + private var width = 0f + + override fun getAsFloat(): Float { + if (!computed) { + width = font.width(text).toFloat() + computed = true + } + + return width + } +} + private fun Font.drawInternal( poseStack: PoseStack, text: Any, @@ -164,6 +207,15 @@ private fun Font.drawInternal( inv = 1f } + val cache = if (text is Component) + CachedTextWidth0(this, text) + else if (text is String) + CachedTextWidth1(this, text) + else if (text is FormattedCharSequence) + CachedTextWidth2(this, text) + else + throw IllegalArgumentException(text::class.qualifiedName) + if (customShadow) { if (shadowZ != 0f) { poseStack.translate(0f, 0f, shadowZ) @@ -180,7 +232,7 @@ private fun Font.drawInternal( displayMode, effectColor, packedLightCoords, - gravity, rounding) + gravity, rounding, cache) if (shadowZ != 0f) { poseStack.translate(0f, 0f, -shadowZ) @@ -204,7 +256,7 @@ private fun Font.drawInternal( displayMode, effectColor, packedLightCoords, - gravity, rounding) + gravity, rounding, cache) } if (outlineZ != 0f) { @@ -223,7 +275,7 @@ private fun Font.drawInternal( displayMode, effectColor, packedLightCoords, - gravity, rounding) + gravity, rounding, cache) if (scale != 1f) { poseStack.popPose() @@ -252,7 +304,7 @@ fun Font.draw( shadowColor: RGBAColor = RGBAColor.BLACK, shadowX: Float = 1f, shadowY: Float = 1f, - shadowZ: Float = -0.1f, + shadowZ: Float = 0.1f, customShadow: Boolean = false, rounding: GravityRounding = if (scale == 1f) GravityRounding.DEFAULT else GravityRounding.NO, drawOutline: Boolean = false, @@ -300,7 +352,7 @@ fun Font.draw( shadowColor: RGBAColor = RGBAColor.BLACK, shadowX: Float = 1f, shadowY: Float = 1f, - shadowZ: Float = -0.1f, + shadowZ: Float = 0.1f, customShadow: Boolean = false, rounding: GravityRounding = if (scale == 1f) GravityRounding.DEFAULT else GravityRounding.NO, drawOutline: Boolean = false,