mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 10:25:06 -04:00
hud: font background
This commit is contained in:
parent
6af9876cb1
commit
034e6e8f01
@ -35,6 +35,8 @@ class Font(
|
||||
|
||||
companion object {
|
||||
const val CHAR_HEIGHT = 8
|
||||
const val CHAR_MARGIN = 1 // used for background
|
||||
const val TOTAL_CHAR_HEIGHT = CHAR_HEIGHT + 2 * CHAR_MARGIN // top and bottom
|
||||
const val HORIZONTAL_SPACING = 1
|
||||
const val VERTICAL_SPACING = 3
|
||||
}
|
||||
|
@ -23,9 +23,6 @@ import de.bixilon.minosoft.gui.rendering.gui.elements.ElementAlignments
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.ElementAlignments.Companion.getOffset
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
||||
import de.bixilon.minosoft.util.MMath.ceil
|
||||
import de.bixilon.minosoft.util.logging.Log
|
||||
import de.bixilon.minosoft.util.logging.LogLevels
|
||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
import glm_.vec2.Vec2i
|
||||
|
||||
object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
@ -42,7 +39,7 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
|
||||
fun addY(height: Int): Boolean {
|
||||
val nextY = offset.y + height
|
||||
val nextSizeY = nextY - initialOffset.y + Font.CHAR_HEIGHT // add initial height for chars
|
||||
val nextSizeY = nextY - initialOffset.y + Font.TOTAL_CHAR_HEIGHT // add initial height for chars + end margin
|
||||
if (nextSizeY >= elementMaxSize.y) {
|
||||
return true
|
||||
}
|
||||
@ -54,18 +51,15 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
}
|
||||
|
||||
fun wrap(): Boolean {
|
||||
if (addY(Font.CHAR_HEIGHT + Font.VERTICAL_SPACING)) {
|
||||
if (addY(Font.TOTAL_CHAR_HEIGHT)) {
|
||||
return true
|
||||
}
|
||||
renderInfo.currentLine++
|
||||
offset.x = initialOffset.x
|
||||
offset.x = initialOffset.x + Font.CHAR_MARGIN
|
||||
if (consumer == null) {
|
||||
// preparing phase
|
||||
renderInfo.lines += TextLineInfo()
|
||||
} else {
|
||||
if (renderInfo.currentLine >= renderInfo.lines.size) {
|
||||
Log.log(LogMessageType.OTHER, LogLevels.FATAL) { "Crash because of $text (size=$size, maxSize=$elementMaxSize)" }
|
||||
}
|
||||
alignmentXOffset = fontAlignment.getOffset(element.size.x, renderInfo.lines[renderInfo.currentLine].width)
|
||||
}
|
||||
return false
|
||||
@ -73,7 +67,7 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
|
||||
fun addX(width: Int, wrap: Boolean = true): Boolean {
|
||||
val nextX = offset.x + width
|
||||
val nextSizeX = nextX + alignmentXOffset - initialOffset.x
|
||||
val nextSizeX = nextX - initialOffset.x + Font.CHAR_MARGIN // end margin
|
||||
if (nextSizeX > elementMaxSize.x) {
|
||||
if (!wrap) {
|
||||
return true
|
||||
@ -96,7 +90,7 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
|
||||
if (size.y == 0) {
|
||||
// Add initial height of the letter for the first line
|
||||
val nextSizeY = Font.CHAR_HEIGHT
|
||||
val nextSizeY = Font.TOTAL_CHAR_HEIGHT
|
||||
if (nextSizeY > elementMaxSize.y) {
|
||||
return true
|
||||
}
|
||||
@ -106,6 +100,8 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
renderInfo.lines += TextLineInfo() // add line 0
|
||||
}
|
||||
size.y = nextSizeY
|
||||
size.x += Font.CHAR_MARGIN * 2
|
||||
offset += Font.CHAR_MARGIN
|
||||
}
|
||||
|
||||
|
||||
@ -119,7 +115,7 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
}
|
||||
|
||||
// skip spaces that are wrapped (because of a line break)
|
||||
if (offset.y != initialOffset.y && offset.x == initialOffset.x && char == ' ') {
|
||||
if (offset.y != initialOffset.y + Font.CHAR_MARGIN && offset.x == initialOffset.x + Font.CHAR_MARGIN && char == ' ') {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -128,7 +124,7 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
val charWidth = charData.calculateWidth(text)
|
||||
var width = charWidth
|
||||
|
||||
if (offset.x != initialOffset.x) {
|
||||
if (offset.x != initialOffset.x + Font.CHAR_MARGIN) {
|
||||
// add spacing between letters
|
||||
width += Font.HORIZONTAL_SPACING
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ class LineSpacerElement(
|
||||
) : SpacerElement(hudRenderer, Vec2i.EMPTY) {
|
||||
|
||||
override var size: Vec2i
|
||||
get() = Vec2i(0, (lines * Font.CHAR_HEIGHT) + ((lines + 1) * Font.VERTICAL_SPACING))
|
||||
get() = Vec2i(0, lines * Font.TOTAL_CHAR_HEIGHT)
|
||||
set(value) {
|
||||
TODO("Can not set the size of an FontSpacer! Use a normal spacer instead!")
|
||||
}
|
||||
|
@ -14,10 +14,14 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.elements.text
|
||||
|
||||
import de.bixilon.minosoft.data.text.ChatComponent
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||
import de.bixilon.minosoft.gui.rendering.font.Font
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.ChatComponentRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.TextRenderInfo
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.ElementAlignments
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.ElementAlignments.Companion.getOffset
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.InfiniteSizeElement
|
||||
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
||||
@ -29,6 +33,8 @@ open class TextElement(
|
||||
hudRenderer: HUDRenderer,
|
||||
text: Any,
|
||||
override var fontAlignment: ElementAlignments = ElementAlignments.LEFT,
|
||||
var background: Boolean = true,
|
||||
var backgroundColor: RGBColor = RenderConstants.TEXT_BACKGROUND_COLOR,
|
||||
) : LabeledElement(hudRenderer) {
|
||||
private var preparedSize = Vec2i.EMPTY
|
||||
private var renderInfo = TextRenderInfo()
|
||||
@ -91,9 +97,18 @@ open class TextElement(
|
||||
|
||||
override fun render(offset: Vec2i, z: Int, consumer: GUIVertexConsumer): Int {
|
||||
val initialOffset = offset + margin.offset
|
||||
ChatComponentRenderer.render(initialOffset, Vec2i(initialOffset), Vec2i.EMPTY, z, this, fontAlignment, renderWindow, consumer, renderInfo, textComponent)
|
||||
|
||||
ChatComponentRenderer.render(initialOffset, Vec2i(initialOffset), Vec2i.EMPTY, z + 1, this, fontAlignment, renderWindow, consumer, renderInfo, textComponent)
|
||||
renderInfo.currentLine = 0
|
||||
prepared = true
|
||||
|
||||
if (background) {
|
||||
for ((line, info) in renderInfo.lines.withIndex()) {
|
||||
val start = initialOffset + Vec2i(fontAlignment.getOffset(size.x, info.width), line * Font.TOTAL_CHAR_HEIGHT)
|
||||
consumer.addQuad(start, start + Vec2i(info.width + Font.CHAR_MARGIN, Font.TOTAL_CHAR_HEIGHT), z, renderWindow.WHITE_TEXTURE, backgroundColor)
|
||||
}
|
||||
}
|
||||
|
||||
return LAYERS
|
||||
}
|
||||
|
||||
@ -102,6 +117,6 @@ open class TextElement(
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val LAYERS = 4 // 1 layer for the text, 1 for strikethrough. * 2 for shadow
|
||||
const val LAYERS = 5 // 1 layer for the text, 1 for strikethrough, * 2 for shadow, 1 for background
|
||||
}
|
||||
}
|
||||
|
@ -14,11 +14,36 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.mesh
|
||||
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.gui.hud.atlas.TextureLike
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
|
||||
import glm_.vec2.Vec2
|
||||
import glm_.vec2.Vec2t
|
||||
|
||||
interface GUIVertexConsumer {
|
||||
|
||||
fun addVertex(position: Vec2t<*>, z: Int, texture: AbstractTexture, uv: Vec2, tint: RGBColor)
|
||||
|
||||
fun addQuad(start: Vec2t<*>, end: Vec2t<*>, z: Int, texture: AbstractTexture, uvStart: Vec2, uvEnd: Vec2, tint: RGBColor) {
|
||||
val positions = arrayOf(
|
||||
Vec2(start.x.toFloat(), start.y),
|
||||
Vec2(end.x.toFloat(), 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 Mesh.QUAD_DRAW_ODER) {
|
||||
addVertex(positions[vertexIndex], z, texture, texturePositions[textureIndex], tint)
|
||||
}
|
||||
}
|
||||
|
||||
fun addQuad(start: Vec2t<*>, end: Vec2t<*>, z: Int, texture: TextureLike, tint: RGBColor) {
|
||||
addQuad(start, end, z, texture.texture, texture.uvStart, texture.uvEnd, tint)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user