mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 02:15:34 -04:00
refactor font rendering more
This commit is contained in:
parent
761ea0a582
commit
d9c74a71d7
@ -57,6 +57,7 @@ class BaseComponent : ChatComponent {
|
||||
json["strikethrough"]?.toBoolean()?.let { formatting[FormattingCodes.STRIKETHROUGH] = it }
|
||||
json["obfuscated"]?.toBoolean()?.let { formatting[FormattingCodes.OBFUSCATED] = it }
|
||||
|
||||
val font = json["font"]?.toResourceLocation() ?: parent?.font
|
||||
val clickEvent = json["clickEvent", "click_event"]?.toJsonObject()?.let { click -> ClickEvents.build(click, restricted) } ?: parent?.clickEvent
|
||||
val hoverEvent = json["hoverEvent", "hover_event"]?.toJsonObject()?.let { hover -> HoverEvents.build(hover, restricted) } ?: parent?.hoverEvent
|
||||
|
||||
@ -66,6 +67,7 @@ class BaseComponent : ChatComponent {
|
||||
message = text,
|
||||
color = color,
|
||||
formatting = formatting,
|
||||
font = font,
|
||||
clickEvent = clickEvent,
|
||||
hoverEvent = hoverEvent,
|
||||
)
|
||||
|
@ -50,15 +50,15 @@ object LegacyComponentReader {
|
||||
}
|
||||
if (text.isNotEmpty()) {
|
||||
// an url follows, push the previous part
|
||||
this += TextComponent(text, sequence.color, sequence.formatting.copy(), parent?.clickEvent, parent?.hoverEvent)
|
||||
this += TextComponent(text, sequence.color, sequence.formatting.copy(), null, parent?.clickEvent, parent?.hoverEvent)
|
||||
text.clear()
|
||||
}
|
||||
|
||||
this += TextComponent(part, sequence.color, sequence.formatting.copy(), parent?.clickEvent ?: event, parent?.hoverEvent)
|
||||
this += TextComponent(part, sequence.color, sequence.formatting.copy(), null, parent?.clickEvent ?: event, parent?.hoverEvent)
|
||||
}
|
||||
if (text.isNotEmpty()) {
|
||||
// data that was not pushed yet
|
||||
this += TextComponent(text, sequence.color, sequence.formatting.copy(), parent?.clickEvent, parent?.hoverEvent)
|
||||
this += TextComponent(text, sequence.color, sequence.formatting.copy(), null, parent?.clickEvent, parent?.hoverEvent)
|
||||
}
|
||||
|
||||
sequence.reset() // clear it up again for next usage
|
||||
|
@ -14,6 +14,7 @@ package de.bixilon.minosoft.data.text
|
||||
|
||||
import de.bixilon.kutil.json.MutableJsonObject
|
||||
import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager
|
||||
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
|
||||
import de.bixilon.minosoft.data.text.events.click.ClickEvent
|
||||
import de.bixilon.minosoft.data.text.events.hover.HoverEvent
|
||||
import de.bixilon.minosoft.data.text.formatting.FormattingCodes
|
||||
@ -37,6 +38,7 @@ open class TextComponent(
|
||||
message: Any? = "",
|
||||
override var color: RGBColor? = null,
|
||||
override val formatting: TextFormatting = TextFormatting(),
|
||||
var font: ResourceLocation? = null,
|
||||
var clickEvent: ClickEvent? = null,
|
||||
var hoverEvent: HoverEvent? = null,
|
||||
) : ChatComponent, TextStyle {
|
||||
@ -224,7 +226,7 @@ open class TextComponent(
|
||||
}
|
||||
|
||||
override fun copy(): ChatComponent {
|
||||
return TextComponent(message, color, formatting.copy(), clickEvent, hoverEvent)
|
||||
return TextComponent(message, color, formatting.copy(), font, clickEvent, hoverEvent)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
|
@ -14,13 +14,7 @@
|
||||
package de.bixilon.minosoft.gui.rendering.font
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.kutil.math.simple.FloatMath.ceil
|
||||
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||
import de.bixilon.minosoft.gui.rendering.font.types.font.Font
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
|
||||
@Deprecated("renderer")
|
||||
@ -31,106 +25,4 @@ class CharData(
|
||||
val scaledWidth: Int,
|
||||
var uvStart: Vec2,
|
||||
var uvEnd: Vec2,
|
||||
) {
|
||||
|
||||
fun postInit() {
|
||||
if (texture == null) {
|
||||
return
|
||||
}
|
||||
uvStart = uvStart * texture.textureArrayUV
|
||||
uvEnd = uvEnd * texture.textureArrayUV
|
||||
}
|
||||
|
||||
fun render(position: Vec2i, color: RGBColor, shadow: Boolean, italic: Boolean, bold: Boolean, strikethrough: Boolean, underlined: Boolean, consumer: GUIVertexConsumer, options: GUIVertexOptions?, scale: Float) {
|
||||
if (shadow) {
|
||||
_render(position, color, true, italic, bold, strikethrough, underlined, consumer, options, scale)
|
||||
}
|
||||
_render(position, color, false, italic, bold, strikethrough, underlined, consumer, options, scale)
|
||||
}
|
||||
|
||||
private fun GUIVertexConsumer.addQuad(start: Vec2, end: Vec2, texture: AbstractTexture, uvStart: Vec2, uvEnd: Vec2, italic: Boolean, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
val italicOffset = if (italic) (end.y - start.y) / Font.CHAR_HEIGHT.toFloat() * ITALIC_OFFSET else 0.0f
|
||||
|
||||
val positions = arrayOf(
|
||||
Vec2(start.x + italicOffset, start.y),
|
||||
Vec2(end.x + italicOffset, start.y),
|
||||
end,
|
||||
Vec2(start.x, end.y),
|
||||
)
|
||||
val texturePositions = arrayOf(
|
||||
Vec2(uvEnd.x, uvStart.y),
|
||||
uvStart,
|
||||
Vec2(uvStart.x, uvEnd.y),
|
||||
uvEnd,
|
||||
)
|
||||
|
||||
for ((vertexIndex, textureIndex) in this.order) {
|
||||
addVertex(positions[vertexIndex], texture, texturePositions[textureIndex], tint, options)
|
||||
}
|
||||
}
|
||||
|
||||
private fun _render(position: Vec2i, color: RGBColor, shadow: Boolean, italic: Boolean, bold: Boolean, strikethrough: Boolean, underlined: Boolean, vertexConsumer: GUIVertexConsumer, options: GUIVertexOptions?, scale: Float) {
|
||||
if (texture == null) {
|
||||
return
|
||||
}
|
||||
var color = color
|
||||
|
||||
var shadowOffset = 0.0f
|
||||
if (shadow) {
|
||||
shadowOffset = SHADOW_OFFSET
|
||||
color *= 0.25f
|
||||
}
|
||||
|
||||
var boldOffset = 0.0f
|
||||
|
||||
if (bold) {
|
||||
boldOffset = BOLD_OFFSET * scale
|
||||
}
|
||||
val charHeight = Font.CHAR_HEIGHT * scale
|
||||
val horizontalSpacing = Font.HORIZONTAL_SPACING * scale
|
||||
val verticalSpacing = Font.VERTICAL_SPACING * scale
|
||||
|
||||
|
||||
val startPosition = Vec2(position) + (shadowOffset * scale)
|
||||
val endPosition = startPosition + (Vec2(scaledWidth * scale, charHeight))
|
||||
|
||||
|
||||
|
||||
vertexConsumer.addQuad(startPosition, endPosition, texture, uvStart, uvEnd, italic, color, options)
|
||||
|
||||
if (bold) {
|
||||
vertexConsumer.addQuad(startPosition + Vec2(boldOffset, 0.0f), endPosition + Vec2(boldOffset, 0.0f), texture, uvStart, uvEnd, italic, color, options)
|
||||
}
|
||||
val whiteTexture = context.textureManager.whiteTexture
|
||||
|
||||
if (strikethrough) {
|
||||
vertexConsumer.addQuad(startPosition + Vec2(-horizontalSpacing, charHeight / 2.0f - scale / 2), Vec2(endPosition.x + horizontalSpacing, startPosition.y + charHeight / 2.0f + scale / 2), whiteTexture.texture, whiteTexture.uvStart, whiteTexture.uvEnd, italic, color, options)
|
||||
}
|
||||
|
||||
if (underlined) {
|
||||
vertexConsumer.addQuad(startPosition + Vec2(-horizontalSpacing, charHeight), Vec2(endPosition.x + boldOffset + horizontalSpacing, startPosition.y + charHeight + verticalSpacing / 2.0f), whiteTexture.texture, whiteTexture.uvStart, whiteTexture.uvEnd, italic, color, options)
|
||||
}
|
||||
|
||||
// ToDo: Obfuscated
|
||||
}
|
||||
|
||||
fun calculateWidth(scale: Float, shadow: Boolean): Int {
|
||||
var width = scaledWidth.toFloat()
|
||||
if (shadow) {
|
||||
width += SHADOW_OFFSET
|
||||
}
|
||||
|
||||
return (width * scale).ceil
|
||||
}
|
||||
|
||||
fun render3d(consumer: WorldGUIConsumer, color: RGBColor, shadow: Boolean, italic: Boolean, bold: Boolean, strikethrough: Boolean, underlined: Boolean, scale: Float): Float {
|
||||
render(Vec2i(0, 0), color, shadow, italic, bold, strikethrough, underlined, consumer, null, scale)
|
||||
return scaledWidth.toFloat()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ITALIC_OFFSET = 2.5f
|
||||
const val SHADOW_OFFSET = 1.0f
|
||||
const val BOLD_OFFSET = 0.5f
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.font
|
||||
import de.bixilon.kotlinglm.mat4x4.Mat4
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.component.ChatComponentRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMeshCache
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
||||
@ -26,6 +27,7 @@ import de.bixilon.minosoft.gui.rendering.world.mesh.SingleWorldMesh
|
||||
|
||||
|
||||
class WorldGUIConsumer(val mesh: SingleWorldMesh, val transform: Mat4, val light: Int) : GUIVertexConsumer {
|
||||
override val context: RenderContext get() = mesh.context
|
||||
override val order: Array<Pair<Int, Int>> get() = mesh.order
|
||||
|
||||
override fun addVertex(position: Vec2, texture: ShaderIdentifiable, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
|
@ -16,18 +16,31 @@ package de.bixilon.minosoft.gui.rendering.font.manager
|
||||
import de.bixilon.kutil.latch.AbstractLatch
|
||||
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||
import de.bixilon.minosoft.gui.rendering.font.loader.DefaultFontIndices
|
||||
import de.bixilon.minosoft.gui.rendering.font.loader.FontLoader
|
||||
import de.bixilon.minosoft.gui.rendering.font.types.FontType
|
||||
import de.bixilon.minosoft.gui.rendering.font.types.PostInitFontType
|
||||
import de.bixilon.minosoft.gui.rendering.font.types.font.EmptyFont
|
||||
import de.bixilon.minosoft.gui.rendering.font.types.font.Font
|
||||
|
||||
class FontManager {
|
||||
val default: FontType
|
||||
class FontManager(
|
||||
val default: FontType,
|
||||
) {
|
||||
|
||||
fun postInit(latch: AbstractLatch)
|
||||
fun postInit(latch: AbstractLatch) {
|
||||
if (default is PostInitFontType) {
|
||||
default.postInit(latch)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
operator fun get(font: ResourceLocation): Font?
|
||||
operator fun get(font: ResourceLocation?): Font? = null
|
||||
|
||||
companion object {
|
||||
fun create(context: RenderContext, latch: AbstractLatch): FontManager {}
|
||||
fun create(context: RenderContext, latch: AbstractLatch): FontManager {
|
||||
val font = FontLoader.load(context, DefaultFontIndices.DEFAULT, latch)
|
||||
|
||||
return FontManager(font ?: EmptyFont)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.font.renderer.code
|
||||
|
||||
/**
|
||||
* Font that is shifted vertically
|
||||
* See the great explanation of @Suragch at https://stackoverflow.com/questions/27631736/meaning-of-top-ascent-baseline-descent-bottom-and-leading-in-androids-font
|
||||
*/
|
||||
interface AscentedCodePointRenderer : CodePointRenderer {
|
||||
val descent: Float
|
||||
val ascent: Float
|
||||
}
|
@ -16,12 +16,20 @@ package de.bixilon.minosoft.gui.rendering.font.renderer.code
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.minosoft.data.text.formatting.TextFormatting
|
||||
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.font.WorldGUIConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
|
||||
|
||||
interface CodePointRenderer {
|
||||
|
||||
fun calculateWidth(scale: Float, shadow: Boolean): Float
|
||||
|
||||
fun render(position: Vec2, color: RGBColor, formatting: TextFormatting, consumer: GUIVertexConsumer, options: GUIVertexOptions?, scale: Float)
|
||||
fun render(position: Vec2, color: RGBColor, shadow: Boolean, formatting: TextFormatting, consumer: GUIVertexConsumer, options: GUIVertexOptions?, scale: Float)
|
||||
|
||||
fun render3d(consumer: WorldGUIConsumer, color: RGBColor, shadow: Boolean, formatting: TextFormatting, scale: Float): Float {
|
||||
render(Vec2.EMPTY, color, shadow, formatting, consumer, null, scale)
|
||||
|
||||
return calculateWidth(scale, shadow)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.font.renderer.code
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.minosoft.data.text.formatting.FormattingCodes
|
||||
import de.bixilon.minosoft.data.text.formatting.TextFormatting
|
||||
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FontProperties
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FormattingProperties.BOLD_OFFSET
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FormattingProperties.ITALIC_OFFSET
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FormattingProperties.SHADOW_COLOR
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FormattingProperties.SHADOW_OFFSET
|
||||
import de.bixilon.minosoft.gui.rendering.font.types.font.Font
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
|
||||
interface RasterizedCodePointRenderer : CodePointRenderer {
|
||||
val texture: AbstractTexture
|
||||
|
||||
val uvStart: Vec2
|
||||
val uvEnd: Vec2
|
||||
|
||||
val width: Float
|
||||
|
||||
|
||||
override fun calculateWidth(scale: Float, shadow: Boolean): Float {
|
||||
var width = width
|
||||
if (shadow) {
|
||||
width += SHADOW_OFFSET
|
||||
}
|
||||
|
||||
return width * scale
|
||||
}
|
||||
|
||||
override fun render(position: Vec2, color: RGBColor, shadow: Boolean, formatting: TextFormatting, consumer: GUIVertexConsumer, options: GUIVertexOptions?, scale: Float) {
|
||||
if (shadow) {
|
||||
render(position + (SHADOW_OFFSET * scale), color * SHADOW_COLOR, formatting, consumer, options, scale)
|
||||
}
|
||||
render(position, color, formatting, consumer, options, scale)
|
||||
}
|
||||
|
||||
fun calculateStart(base: Vec2, scale: Float): Vec2 {
|
||||
val position = Vec2(base)
|
||||
position.y += (FontProperties.CHAR_SPACING_TOP * scale)
|
||||
|
||||
return position
|
||||
}
|
||||
|
||||
fun calculateEnd(start: Vec2, scale: Float): Vec2 {
|
||||
val position = Vec2(start)
|
||||
position.y += (FontProperties.CHAR_BASE_HEIGHT * scale)
|
||||
position.x += width * scale
|
||||
|
||||
return position
|
||||
}
|
||||
|
||||
private fun render(position: Vec2, color: RGBColor, formatting: TextFormatting, consumer: GUIVertexConsumer, options: GUIVertexOptions?, scale: Float) {
|
||||
var boldOffset = 0.0f
|
||||
|
||||
val bold = FormattingCodes.BOLD in formatting
|
||||
val italic = FormattingCodes.ITALIC in formatting
|
||||
|
||||
if (bold) {
|
||||
boldOffset = BOLD_OFFSET * scale
|
||||
}
|
||||
val charHeight = FontProperties.CHAR_BASE_HEIGHT * scale
|
||||
val horizontalSpacing = Font.HORIZONTAL_SPACING * scale
|
||||
val verticalSpacing = Font.VERTICAL_SPACING * scale
|
||||
|
||||
|
||||
val startPosition = calculateStart(position, scale)
|
||||
val endPosition = calculateEnd(startPosition, scale)
|
||||
|
||||
|
||||
|
||||
consumer.addQuad(startPosition, endPosition, texture, uvStart, uvEnd, italic, color, options)
|
||||
|
||||
if (FormattingCodes.BOLD in formatting) {
|
||||
consumer.addQuad(startPosition + Vec2(boldOffset, 0.0f), endPosition + Vec2(boldOffset, 0.0f), texture, uvStart, uvEnd, italic, color, options)
|
||||
}
|
||||
val whiteTexture = consumer.context.textureManager.whiteTexture
|
||||
|
||||
if (FormattingCodes.STRIKETHROUGH in formatting) {
|
||||
consumer.addQuad(startPosition + Vec2(-horizontalSpacing, charHeight / 2.0f - scale / 2), Vec2(endPosition.x + horizontalSpacing, startPosition.y + charHeight / 2.0f + scale / 2), whiteTexture.texture, whiteTexture.uvStart, whiteTexture.uvEnd, italic, color, options)
|
||||
}
|
||||
|
||||
if (FormattingCodes.UNDERLINED in formatting) {
|
||||
consumer.addQuad(startPosition + Vec2(-horizontalSpacing, charHeight), Vec2(endPosition.x + boldOffset + horizontalSpacing, startPosition.y + charHeight + verticalSpacing / 2.0f), whiteTexture.texture, whiteTexture.uvStart, whiteTexture.uvEnd, italic, color, options)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun GUIVertexConsumer.addQuad(start: Vec2, end: Vec2, texture: AbstractTexture, uvStart: Vec2, uvEnd: Vec2, italic: Boolean, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
val topOffset = if (italic) (end.y - start.y) / FontProperties.CHAR_BASE_HEIGHT * ITALIC_OFFSET else 0.0f
|
||||
|
||||
val positions = arrayOf(
|
||||
Vec2(start.x + topOffset, start.y),
|
||||
Vec2(end.x + topOffset, start.y),
|
||||
end,
|
||||
Vec2(start.x, end.y),
|
||||
)
|
||||
val texturePositions = arrayOf(
|
||||
Vec2(uvEnd.x, uvStart.y),
|
||||
uvStart,
|
||||
Vec2(uvStart.x, uvEnd.y),
|
||||
uvEnd,
|
||||
)
|
||||
|
||||
for ((vertexIndex, textureIndex) in this.order) {
|
||||
addVertex(positions[vertexIndex], texture, texturePositions[textureIndex], tint, options)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -13,6 +13,7 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.font.renderer.component
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.minosoft.data.text.BaseComponent
|
||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||
@ -24,7 +25,7 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
||||
|
||||
object BaseComponentRenderer : ChatComponentRenderer<BaseComponent> {
|
||||
|
||||
override fun render(initialOffset: Vec2i, offset: Vec2i, size: Vec2i, element: Element, context: RenderContext, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, renderInfo: TextRenderInfo, text: BaseComponent): Boolean {
|
||||
override fun render(initialOffset: Vec2, offset: Vec2, size: Vec2, element: Element, context: RenderContext, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, renderInfo: TextRenderInfo, text: BaseComponent): Boolean {
|
||||
for (part in text.parts) {
|
||||
if (ChatComponentRenderer.render(initialOffset, offset, size, element, context, consumer, options, renderInfo, part)) {
|
||||
return true
|
||||
|
@ -14,6 +14,7 @@
|
||||
package de.bixilon.minosoft.gui.rendering.font.renderer.component
|
||||
|
||||
import de.bixilon.kotlinglm.mat4x4.Mat4
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.data.text.BaseComponent
|
||||
@ -35,7 +36,7 @@ interface ChatComponentRenderer<T : ChatComponent> {
|
||||
/**
|
||||
* Returns true if the text exceeded the maximum size
|
||||
*/
|
||||
fun render(initialOffset: Vec2i, offset: Vec2i, size: Vec2i, element: Element, context: RenderContext, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, renderInfo: TextRenderInfo, text: T): Boolean
|
||||
fun render(initialOffset: Vec2, offset: Vec2, size: Vec2, element: Element, context: RenderContext, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, renderInfo: TextRenderInfo, text: T): Boolean
|
||||
|
||||
fun render3dFlat(context: RenderContext, offset: Vec2i, scale: Float, maxSize: Vec2i, consumer: WorldGUIConsumer, text: T, light: Int)
|
||||
|
||||
@ -44,7 +45,7 @@ interface ChatComponentRenderer<T : ChatComponent> {
|
||||
companion object : ChatComponentRenderer<ChatComponent> {
|
||||
const val TEXT_BLOCK_RESOLUTION = 128
|
||||
|
||||
override fun render(initialOffset: Vec2i, offset: Vec2i, size: Vec2i, element: Element, context: RenderContext, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, renderInfo: TextRenderInfo, text: ChatComponent): Boolean {
|
||||
override fun render(initialOffset: Vec2, offset: Vec2, size: Vec2, element: Element, context: RenderContext, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, renderInfo: TextRenderInfo, text: ChatComponent): Boolean {
|
||||
return when (text) {
|
||||
is BaseComponent -> BaseComponentRenderer.render(initialOffset, offset, size, element, context, consumer, options, renderInfo, text)
|
||||
is TextComponent -> TextComponentRenderer.render(initialOffset, offset, size, element, context, consumer, options, renderInfo, text)
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.font.renderer.component
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.minosoft.data.text.TextComponent
|
||||
import de.bixilon.minosoft.data.text.formatting.FormattingCodes
|
||||
@ -29,22 +30,20 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
||||
|
||||
object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
|
||||
override fun render(initialOffset: Vec2i, offset: Vec2i, size: Vec2i, element: Element, context: RenderContext, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, renderInfo: TextRenderInfo, text: TextComponent): Boolean {
|
||||
override fun render(initialOffset: Vec2, offset: Vec2, size: Vec2, element: Element, context: RenderContext, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, renderInfo: TextRenderInfo, text: TextComponent): Boolean {
|
||||
if (text.message.isEmpty()) {
|
||||
return false
|
||||
}
|
||||
val font = context.font[text.font]
|
||||
val elementMaxSize = element.maxSize
|
||||
val elementSize = element.size
|
||||
val color = text.color ?: ChatColors.WHITE
|
||||
val shadow = renderInfo.shadow
|
||||
val italic: Boolean = text.formatting.contains(FormattingCodes.ITALIC)
|
||||
val bold: Boolean = text.formatting.contains(FormattingCodes.BOLD)
|
||||
val strikethrough: Boolean = text.formatting.contains(FormattingCodes.STRIKETHROUGH)
|
||||
val underlined: Boolean = text.formatting.contains(FormattingCodes.UNDERLINED)
|
||||
|
||||
// ToDo: Only 1 quad for the underline and the strikethrough
|
||||
|
||||
var alignmentXOffset = 0
|
||||
var alignmentXOffset = 0.0f
|
||||
var currentLineText = ""
|
||||
if (size.x > elementMaxSize.x || size.y > elementMaxSize.y) {
|
||||
// The size is already bigger/equals the maximum size
|
||||
@ -65,15 +64,15 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
|
||||
fun applyOffset() {
|
||||
val lastLine = renderInfo.lines.getOrNull(renderInfo.lineIndex)
|
||||
if (consumer == null && offset.x == initialOffset.x + renderInfo.charMargin && (lastLine == null || lastLine.width != 0)) {
|
||||
if (consumer == null && offset.x == initialOffset.x + renderInfo.charMargin && (lastLine == null || lastLine.width != 0.0f)) {
|
||||
// preparing phase
|
||||
renderInfo.lines += TextLineInfo()
|
||||
} else {
|
||||
alignmentXOffset = renderInfo.fontAlignment.getOffset(elementSize.x, renderInfo.currentLine.width)
|
||||
alignmentXOffset = renderInfo.fontAlignment.getOffset(elementSize.x.toFloat(), renderInfo.currentLine.width)
|
||||
}
|
||||
}
|
||||
|
||||
fun addY(height: Int): Boolean {
|
||||
fun addY(height: Float): Boolean {
|
||||
val nextY = offset.y + height
|
||||
val nextSizeY = nextY - initialOffset.y + renderInfo.charHeight // add initial height for chars + end margin
|
||||
if (nextSizeY > elementMaxSize.y) {
|
||||
@ -97,7 +96,7 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
return false
|
||||
}
|
||||
|
||||
fun addX(width: Int, wrap: Boolean = true): Boolean {
|
||||
fun addX(width: Float, wrap: Boolean = true): Boolean {
|
||||
val nextX = offset.x + width
|
||||
val nextSizeX = nextX - initialOffset.x - renderInfo.charMargin // end margin
|
||||
if (nextSizeX > elementMaxSize.x) {
|
||||
@ -121,7 +120,7 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
}
|
||||
|
||||
|
||||
if (size.y == 0) {
|
||||
if (size.y == 0.0f) {
|
||||
// Add initial height of the letter for the first line
|
||||
val nextSizeY = renderInfo.charHeight
|
||||
if (nextSizeY > elementMaxSize.y) {
|
||||
@ -147,7 +146,7 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
continue
|
||||
}
|
||||
|
||||
val charData = context.font[char] ?: continue
|
||||
val charData = font?.get(char) ?: context.font.default[char] ?: continue
|
||||
|
||||
val charWidth = charData.calculateWidth(renderInfo.scale, renderInfo.shadow)
|
||||
var width = charWidth
|
||||
@ -168,7 +167,7 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
return true
|
||||
}
|
||||
|
||||
val letterOffset = Vec2i(offset.x + alignmentXOffset, offset.y)
|
||||
val letterOffset = Vec2(offset.x + alignmentXOffset, offset.y)
|
||||
|
||||
// remove width from the offset again
|
||||
letterOffset.x -= charWidth
|
||||
@ -178,7 +177,7 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
// ToDo: Remove Font.HORIZONTAL_SPACING
|
||||
}
|
||||
|
||||
consumer?.let { charData.render(letterOffset, color, shadow, italic, bold, strikethrough, underlined, it, options, renderInfo.scale) }
|
||||
consumer?.let { charData.render(letterOffset, color, shadow, text.formatting, it, options, renderInfo.scale) }
|
||||
|
||||
if (consumer == null) {
|
||||
currentLineText += char.toChar()
|
||||
@ -207,18 +206,16 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
|
||||
override fun render3dFlat(context: RenderContext, offset: Vec2i, scale: Float, maxSize: Vec2i, consumer: WorldGUIConsumer, text: TextComponent, light: Int) {
|
||||
val color = text.color ?: ChatColors.BLACK
|
||||
val italic = text.formatting.contains(FormattingCodes.ITALIC)
|
||||
val bold = text.formatting.contains(FormattingCodes.BOLD)
|
||||
val strikethrough = text.formatting.contains(FormattingCodes.STRIKETHROUGH)
|
||||
val underlined = text.formatting.contains(FormattingCodes.UNDERLINED)
|
||||
|
||||
val font = context.font[text.font]
|
||||
|
||||
for (char in text.message.codePoints()) {
|
||||
val data = context.font[char] ?: continue
|
||||
val expectedWidth = ((data.width + Font.HORIZONTAL_SPACING) * scale).toInt()
|
||||
val data = font?.get(char) ?: context.font.default[char] ?: continue
|
||||
val expectedWidth = ((data.calculateWidth(scale, false) + Font.HORIZONTAL_SPACING) * scale).toInt()
|
||||
if (maxSize.x - offset.x < expectedWidth) { // ToDo
|
||||
return
|
||||
}
|
||||
val width = ((data.render3d(consumer, color, shadow = false, italic = italic, bold = bold, strikethrough = strikethrough, underlined = underlined, scale = scale) + Font.HORIZONTAL_SPACING) * scale).toInt()
|
||||
val width = ((data.render3d(consumer, color, shadow = false, text.formatting, scale = scale) + Font.HORIZONTAL_SPACING) * scale).toInt()
|
||||
offset.x += width
|
||||
consumer.offset((width / ChatComponentRenderer.TEXT_BLOCK_RESOLUTION.toFloat()))
|
||||
}
|
||||
|
@ -17,5 +17,5 @@ import de.bixilon.minosoft.data.text.BaseComponent
|
||||
|
||||
data class TextLineInfo(
|
||||
val text: BaseComponent = BaseComponent(),
|
||||
var width: Int = 0,
|
||||
var width: Float = 0.0f,
|
||||
)
|
||||
|
@ -21,7 +21,7 @@ import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
|
||||
class TextRenderInfo(
|
||||
val fontAlignment: HorizontalAlignments,
|
||||
val charHeight: Int,
|
||||
val charHeight: Float,
|
||||
val charMargin: Int,
|
||||
val scale: Float,
|
||||
val shadow: Boolean,
|
||||
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.font.renderer.properties
|
||||
|
||||
object FontProperties {
|
||||
const val MAX_CHAR_WIDTH = 16 // maximum width that a char can have
|
||||
const val CHAR_BASE_HEIGHT = 8 // base height of every char, it is allowed to take up the spacing if needed
|
||||
const val CHAR_SPACING_TOP = 1
|
||||
const val CHAR_SPACING_BOTTOM = 2 // larger to not break underlined text
|
||||
|
||||
const val LINE_HEIGHT = CHAR_SPACING_TOP + CHAR_BASE_HEIGHT + CHAR_SPACING_BOTTOM
|
||||
}
|
@ -11,10 +11,13 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.font.renderer
|
||||
package de.bixilon.minosoft.gui.rendering.font.renderer.properties
|
||||
|
||||
object FontProperties {
|
||||
const val MAX_CHAR_WIDTH = 16 // maximum width that a char can have
|
||||
const val CHAR_HEIGHT = 12 // height every char has
|
||||
const val CHAR_SPACING = 1 // spacing every char has around itself
|
||||
object FormattingProperties {
|
||||
const val ITALIC_OFFSET = 2.5f
|
||||
const val SHADOW_OFFSET = 1.0f
|
||||
const val BOLD_OFFSET = 0.5f
|
||||
|
||||
|
||||
const val SHADOW_COLOR = 0.25f
|
||||
}
|
@ -14,16 +14,20 @@
|
||||
package de.bixilon.minosoft.gui.rendering.font.types.bitmap
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.code.CodePointRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.code.AscentedCodePointRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.code.RasterizedCodePointRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
|
||||
class BitmapCodeRenderer(
|
||||
val texture: AbstractTexture,
|
||||
var uvStart: Vec2,
|
||||
var uvEnd: Vec2,
|
||||
val width: Float,
|
||||
) : CodePointRenderer {
|
||||
|
||||
override val texture: AbstractTexture,
|
||||
override var uvStart: Vec2,
|
||||
override var uvEnd: Vec2,
|
||||
override val width: Float,
|
||||
) : RasterizedCodePointRenderer, AscentedCodePointRenderer {
|
||||
override val ascent: Float
|
||||
get() = 1.0f
|
||||
override val descent: Float
|
||||
get() = 1.0f
|
||||
|
||||
fun updateArray() {
|
||||
uvStart = uvStart * texture.textureArrayUV
|
||||
|
@ -16,8 +16,8 @@ package de.bixilon.minosoft.gui.rendering.font.types.empty
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.minosoft.data.text.formatting.TextFormatting
|
||||
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.FontProperties.MAX_CHAR_WIDTH
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.code.CodePointRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FontProperties.MAX_CHAR_WIDTH
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
||||
|
||||
@ -31,5 +31,5 @@ class EmptyCodeRenderer(
|
||||
}
|
||||
|
||||
override fun calculateWidth(scale: Float, shadow: Boolean): Float = width * scale
|
||||
override fun render(position: Vec2, color: RGBColor, formatting: TextFormatting, consumer: GUIVertexConsumer, options: GUIVertexOptions?, scale: Float) = Unit
|
||||
override fun render(position: Vec2, color: RGBColor, shadow: Boolean, formatting: TextFormatting, consumer: GUIVertexConsumer, options: GUIVertexOptions?, scale: Float) = Unit
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ class EmptyFontType(
|
||||
fun load(data: JsonObject): Int2ObjectOpenHashMap<EmptyCodeRenderer>? {
|
||||
val advances = data["advances"]?.toJsonObject() ?: return null
|
||||
|
||||
val spaces = Int2ObjectOpenHashMap<EmptyCodeRenderer>(advances.size, 0.0f)
|
||||
val spaces = Int2ObjectOpenHashMap<EmptyCodeRenderer>(advances.size, 0.01f)
|
||||
for ((char, spacing) in advances) {
|
||||
val codePoint = char.codePointAt(0)
|
||||
|
||||
|
@ -14,15 +14,15 @@
|
||||
package de.bixilon.minosoft.gui.rendering.font.types.unicode.legacy
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.code.CodePointRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.code.RasterizedCodePointRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
|
||||
class LegacyUnicodeCodeRenderer(
|
||||
val texture: AbstractTexture,
|
||||
var uvStart: Vec2,
|
||||
var uvEnd: Vec2,
|
||||
val width: Float,
|
||||
) : CodePointRenderer {
|
||||
override val texture: AbstractTexture,
|
||||
override var uvStart: Vec2,
|
||||
override var uvEnd: Vec2,
|
||||
override val width: Float,
|
||||
) : RasterizedCodePointRenderer {
|
||||
|
||||
|
||||
fun updateArray() {
|
||||
|
@ -21,8 +21,8 @@ import de.bixilon.minosoft.assets.AssetsManager
|
||||
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
|
||||
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.FontProperties
|
||||
import de.bixilon.minosoft.gui.rendering.font.types.FontType
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FontProperties
|
||||
import de.bixilon.minosoft.gui.rendering.font.types.PostInitFontType
|
||||
import de.bixilon.minosoft.gui.rendering.font.types.factory.FontTypeFactory
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.StaticTextureArray
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
@ -32,7 +32,7 @@ import java.io.InputStream
|
||||
|
||||
class LegacyUnicodeFontType(
|
||||
val chars: Array<LegacyUnicodeCodeRenderer?>,
|
||||
) : FontType {
|
||||
) : PostInitFontType {
|
||||
|
||||
override fun postInit(latch: AbstractLatch) {
|
||||
for (char in chars) {
|
||||
@ -51,7 +51,7 @@ class LegacyUnicodeFontType(
|
||||
private const val CHAR_ROW = 0x0F
|
||||
private const val CHAR_SIZE = 0x0F
|
||||
private const val PIXEL = 1.0f / (CHAR_SIZE * CHAR_ROW)
|
||||
private const val WIDTH_SCALE = FontProperties.CHAR_HEIGHT / CHAR_SIZE.toFloat()
|
||||
private const val WIDTH_SCALE = FontProperties.CHAR_BASE_HEIGHT / CHAR_SIZE.toFloat()
|
||||
|
||||
override fun build(context: RenderContext, data: Map<String, Any>): LegacyUnicodeFontType? {
|
||||
val assets = context.connection.assetsManager
|
||||
|
@ -67,7 +67,7 @@ abstract class Element(val guiRenderer: GUIRenderer, initialCacheSize: Int = 100
|
||||
}
|
||||
|
||||
@Deprecated("Warning: Should not be directly accessed!")
|
||||
open val cache = GUIMeshCache(guiRenderer.halfSize, context.renderSystem.primitiveMeshOrder, initialCacheSize)
|
||||
open val cache = GUIMeshCache(guiRenderer.halfSize, context.renderSystem.primitiveMeshOrder, context, initialCacheSize)
|
||||
|
||||
private var previousMaxSize = Vec2i.EMPTY
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.gui.elements
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
|
||||
enum class HorizontalAlignments {
|
||||
@ -22,6 +23,14 @@ enum class HorizontalAlignments {
|
||||
;
|
||||
|
||||
companion object {
|
||||
fun HorizontalAlignments.getOffset(width: Float, childWidth: Float): Float {
|
||||
return when (this) {
|
||||
LEFT -> 0.0f
|
||||
RIGHT -> width - childWidth
|
||||
CENTER -> (width - childWidth) / 2
|
||||
}
|
||||
}
|
||||
|
||||
fun HorizontalAlignments.getOffset(width: Int, childWidth: Int): Int {
|
||||
return when (this) {
|
||||
LEFT -> 0
|
||||
@ -33,5 +42,9 @@ enum class HorizontalAlignments {
|
||||
fun HorizontalAlignments.getOffset(size: Vec2i, childSize: Vec2i): Vec2i {
|
||||
return Vec2i(getOffset(size.x, childSize.x), 0)
|
||||
}
|
||||
|
||||
fun HorizontalAlignments.getOffset(size: Vec2, childSize: Vec2): Vec2 {
|
||||
return Vec2(getOffset(size.x, childSize.x), 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.gui.elements.text
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.kutil.cast.CastUtil.unsafeNull
|
||||
import de.bixilon.kutil.primitive.BooleanUtil.decide
|
||||
@ -36,6 +37,7 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
||||
import de.bixilon.minosoft.gui.rendering.system.window.CursorShapes
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec4.Vec4iUtil.offset
|
||||
import de.bixilon.minosoft.util.KUtil.charCount
|
||||
@ -118,12 +120,12 @@ open class TextElement(
|
||||
if (!emptyMessage) {
|
||||
val renderInfo = TextRenderInfo(
|
||||
fontAlignment = fontAlignment,
|
||||
charHeight = charHeight,
|
||||
charHeight = charHeight.toFloat(),
|
||||
charMargin = charMargin,
|
||||
scale = scale,
|
||||
shadow = shadow,
|
||||
)
|
||||
ChatComponentRenderer.render(Vec2i.EMPTY, Vec2i.EMPTY, prefSize, InfiniteSizeElement(guiRenderer), context, null, null, renderInfo, value)
|
||||
ChatComponentRenderer.render(Vec2.EMPTY, Vec2.EMPTY, Vec2(prefSize), InfiniteSizeElement(guiRenderer), context, null, null, renderInfo, value)
|
||||
}
|
||||
_prefSize = prefSize
|
||||
}
|
||||
@ -151,13 +153,13 @@ open class TextElement(
|
||||
val size = Vec2i.EMPTY
|
||||
val renderInfo = TextRenderInfo(
|
||||
fontAlignment = fontAlignment,
|
||||
charHeight = charHeight,
|
||||
charHeight = charHeight.toFloat(),
|
||||
charMargin = charMargin,
|
||||
scale = scale,
|
||||
shadow = shadow,
|
||||
)
|
||||
if (!emptyMessage) {
|
||||
ChatComponentRenderer.render(Vec2i.EMPTY, Vec2i.EMPTY, size, this, context, null, null, renderInfo, chatComponent)
|
||||
ChatComponentRenderer.render(Vec2.EMPTY, Vec2.EMPTY, Vec2(size), this, context, null, null, renderInfo, chatComponent)
|
||||
renderInfo.lineIndex = 0
|
||||
}
|
||||
if (renderInfo.lines.size > 1 && size.y > Font.CHAR_HEIGHT) {
|
||||
@ -180,7 +182,7 @@ open class TextElement(
|
||||
|
||||
if (background) {
|
||||
for ((line, info) in renderInfo.lines.withIndex()) {
|
||||
val start = initialOffset + Vec2i(fontAlignment.getOffset(size.x, info.width), line * charHeight)
|
||||
val start = initialOffset + Vec2i(fontAlignment.getOffset(size.x.toFloat(), info.width), line * charHeight)
|
||||
consumer.addQuad(start, start + Vec2i(info.width + charMargin, charHeight), context.textureManager.whiteTexture, backgroundColor, options)
|
||||
}
|
||||
}
|
||||
@ -190,7 +192,7 @@ open class TextElement(
|
||||
vertices *= 2
|
||||
}
|
||||
consumer.ensureSize(vertices)
|
||||
ChatComponentRenderer.render(initialOffset, Vec2i(initialOffset), Vec2i.EMPTY, this, context, consumer, options, renderInfo, chatComponent)
|
||||
ChatComponentRenderer.render(Vec2(initialOffset), Vec2(initialOffset), Vec2.EMPTY, this, context, consumer, options, renderInfo, chatComponent)
|
||||
renderInfo.lineIndex = 0
|
||||
}
|
||||
|
||||
@ -262,10 +264,10 @@ open class TextElement(
|
||||
charToCheck++
|
||||
}
|
||||
val text = line.text.getTextAt(charToCheck)
|
||||
offset.x -= line0.width // ToDo: Not 100% correct
|
||||
offset.x -= line0.width.toInt() // ToDo: Not 100% correct
|
||||
|
||||
|
||||
offset.x += fontAlignment.getOffset(size.x, line.width)
|
||||
offset.x += fontAlignment.getOffset(size.x, line.width.toInt())
|
||||
return Pair(text, offset)
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ class MarkTextElement(
|
||||
val preMark = TextElement(guiRenderer, message.substring(0, markStartPosition), scale = scale, parent = _parent)
|
||||
val mark = TextElement(guiRenderer, message.substring(markStartPosition, markEndPosition), scale = scale, parent = _parent)
|
||||
val markOffset = Vec2i(preMark.renderInfo.lines.lastOrNull()?.width ?: 0, preMark.size.y)
|
||||
if (markOffset.y > 0 && (preMark.renderInfo.lines.lastOrNull()?.width ?: 0) <= (renderInfo.lines.lastOrNull()?.width ?: 0)) {
|
||||
if (markOffset.y > 0 && (preMark.renderInfo.lines.lastOrNull()?.width ?: 0.0f) <= (renderInfo.lines.lastOrNull()?.width ?: 0.0f)) {
|
||||
markOffset.y -= (Font.TOTAL_CHAR_HEIGHT * scale).toInt()
|
||||
}
|
||||
|
||||
|
@ -344,8 +344,8 @@ open class TextInputElement(
|
||||
continue
|
||||
}
|
||||
val charDelta = position.x - line.width
|
||||
val width = guiRenderer.context.font[value.codePointAtOrNull(pointer) ?: break]?.width ?: break
|
||||
if (charDelta != 0 && charDelta >= width / 2) {
|
||||
val width = guiRenderer.context.font.default[value.codePointAtOrNull(pointer) ?: break]?.calculateWidth(1.0f, true) ?: break
|
||||
if (charDelta != 0.0f && charDelta >= width / 2) {
|
||||
pointer++
|
||||
}
|
||||
break
|
||||
|
@ -18,12 +18,14 @@ import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.kutil.collections.primitive.floats.AbstractFloatList
|
||||
import de.bixilon.kutil.collections.primitive.floats.HeapArrayFloatList
|
||||
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.ShaderIdentifiable
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
|
||||
|
||||
class GUIMeshCache(
|
||||
var halfSize: Vec2,
|
||||
override val order: Array<Pair<Int, Int>>,
|
||||
override val context: RenderContext,
|
||||
initialCacheSize: Int = 1000,
|
||||
var data: AbstractFloatList = HeapArrayFloatList(initialCacheSize),
|
||||
) : GUIVertexConsumer {
|
||||
|
@ -16,10 +16,12 @@ package de.bixilon.minosoft.gui.rendering.gui.mesh
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||
import de.bixilon.minosoft.gui.rendering.gui.atlas.TextureLike
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.ShaderIdentifiable
|
||||
|
||||
interface GUIVertexConsumer {
|
||||
val context: RenderContext
|
||||
val order: Array<Pair<Int, Int>>
|
||||
|
||||
fun addVertex(position: Vec2, texture: ShaderIdentifiable, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?)
|
||||
|
Loading…
x
Reference in New Issue
Block a user