hud: font background

This commit is contained in:
Bixilon 2021-09-10 22:37:28 +02:00
parent 6af9876cb1
commit 034e6e8f01
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
5 changed files with 54 additions and 16 deletions

View File

@ -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
}

View File

@ -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
}

View File

@ -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!")
}

View File

@ -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
}
}

View File

@ -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)
}
}