From bc77340569cb284b7a9668e0d8a353801252db27 Mon Sep 17 00:00:00 2001
From: Dominic Masters <dominic@domsplace.com>
Date: Mon, 9 Oct 2023 17:55:46 -0500
Subject: [PATCH] Added text alignment support.
---
src/dawn/scene/components/ui/text/UILabel.cpp | 53 +++++++++++++++++++
src/dawn/scene/components/ui/text/UILabel.hpp | 2 +
.../shader/ShaderParameterBufferTypes.hpp | 7 +++
.../display/shader/shaders/FontShader.cpp | 5 +-
.../display/shader/shaders/FontShader.hpp | 1 +
5 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/src/dawn/scene/components/ui/text/UILabel.cpp b/src/dawn/scene/components/ui/text/UILabel.cpp
index 6f9107ab..a9a3bc93 100644
--- a/src/dawn/scene/components/ui/text/UILabel.cpp
+++ b/src/dawn/scene/components/ui/text/UILabel.cpp
@@ -22,12 +22,65 @@ void UILabel::onStart() {
this->shaderBuffer.init();
useEvent([&]{
+ // TODO: I believe I only need to rebuffer here if maxWidth is not -1
this->rebufferQuads(this->texts);
}, eventAlignmentUpdated);
useEffect([&]{
this->rebufferQuads(this->texts);
}, lineHeight);
+
+ useEvent([&]{
+ this->updateTextAlignments();
+ }, eventTextChanged);
+
+ useEffect([&]{
+ this->updateTextAlignments();
+ }, this->textAlign);
+}
+
+void UILabel::updateTextAlignments() {
+ struct FontShaderBufferData data;
+
+ switch(this->textAlign) {
+ case UI_LABEL_TEXT_ALIGN_LEFT: {
+ auto itLine = lines.begin();
+ int32_t i = 0;
+ while(itLine != lines.end()) {
+ data.linePositions[i] = glm::vec2(0, 0);
+ ++itLine;
+ }
+ break;
+ }
+
+ case UI_LABEL_TEXT_ALIGN_RIGHT: {
+ float_t widthBased = this->getWidth();
+ auto itLine = lines.begin();
+ int32_t i = 0;
+ while(itLine != lines.end()) {
+ data.linePositions[i] = glm::vec2(widthBased - itLine->width, 0);
+ ++itLine;
+ }
+ break;
+ }
+
+ case UI_LABEL_TEXT_ALIGN_CENTER: {
+ float_t widthBased = this->getWidth();
+ auto itLine = lines.begin();
+ int32_t i = 0;
+ while(itLine != lines.end()) {
+ float_t x = (widthBased - itLine->width) / 2.0f;
+ data.linePositions[i] = glm::vec2(x, 0);
+ ++itLine;
+ }
+ break;
+ }
+
+ default:
+ assertUnreachable("UILabel::updateTextAlignments: TextAlign invalid");
+ }
+
+ this->shaderBuffer.buffer(&data, &data.linePositions);
}
std::vector<struct ShaderPassItem> UILabel::getUIRenderPasses() {
diff --git a/src/dawn/scene/components/ui/text/UILabel.hpp b/src/dawn/scene/components/ui/text/UILabel.hpp
index 0e881fcc..8ca3a0bd 100644
--- a/src/dawn/scene/components/ui/text/UILabel.hpp
+++ b/src/dawn/scene/components/ui/text/UILabel.hpp
@@ -59,6 +59,8 @@ namespace Dawn {
bool_t ignoreAlignmentUpdate = false;
bool_t hasDecorations = false;
+ void updateTextAlignments();
+
public:
int32_t quadStart = 0;
int32_t quadCount = -1;
diff --git a/src/dawnopengl/display/shader/ShaderParameterBufferTypes.hpp b/src/dawnopengl/display/shader/ShaderParameterBufferTypes.hpp
index 1d200a68..0f5e9b1b 100644
--- a/src/dawnopengl/display/shader/ShaderParameterBufferTypes.hpp
+++ b/src/dawnopengl/display/shader/ShaderParameterBufferTypes.hpp
@@ -43,5 +43,12 @@
#define SHADER_PARAMETER_BUFFER_MAT4(name) \
glm::mat4 name;
+// VEC2
+#define SHADER_PARAMETER_BUFFER_VEC2(name) \
+ glm::vec2 name;
+
+#define SHADER_PARAMETER_BUFFER_VEC2_ARRAY(name, size) \
+ glm::vec2 name[size];
+
// EOF Fix
#define NOTHING "Fixes an error with EOF"
\ No newline at end of file
diff --git a/src/dawnopengl/display/shader/shaders/FontShader.cpp b/src/dawnopengl/display/shader/shaders/FontShader.cpp
index 12b59379..7ef2dc0f 100644
--- a/src/dawnopengl/display/shader/shaders/FontShader.cpp
+++ b/src/dawnopengl/display/shader/shaders/FontShader.cpp
@@ -28,6 +28,7 @@ void FontShader::compile() {
"layout (shared) uniform ub_Font {\n"
"vec4 u_FontColors[" MACRO_STRINGIFY(FONT_SHADER_PARTS_MAX) "];\n"
"int u_FontTextures[" MACRO_STRINGIFY(FONT_SHADER_PARTS_MAX) "];\n"
+ "vec2 u_FontLinePositions[" MACRO_STRINGIFY(FONT_SHADER_PARTS_MAX) "];\n"
"int u_FontQuadMappings[" MACRO_STRINGIFY(FONT_SHADER_QUADS_MAX) "];\n"
"};\n"
@@ -37,10 +38,12 @@ void FontShader::compile() {
"flat out int o_TextIndex;\n"
"void main() {\n"
- "gl_Position = u_Projection * u_View * u_Model * vec4(aPos.xy, 0, 1.0);\n"
"o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);\n"
"int quadIndex = gl_VertexID / " MACRO_STRINGIFY(QUAD_VERTICE_COUNT) ";\n"
"int partIndex = u_FontQuadMappings[quadIndex];\n"
+ "gl_Position = u_Projection * u_View * u_Model * (\n"
+ "vec4(aPos.xy, 0, 1.0) + vec4(u_FontLinePositions[partIndex], 0, 0)\n"
+ ");\n"
"o_VertColor = u_FontColors[partIndex];\n"
"o_TextIndex = u_FontTextures[partIndex];\n"
"}",
diff --git a/src/dawnopengl/display/shader/shaders/FontShader.hpp b/src/dawnopengl/display/shader/shaders/FontShader.hpp
index 66eb90b0..0bcd5b4e 100644
--- a/src/dawnopengl/display/shader/shaders/FontShader.hpp
+++ b/src/dawnopengl/display/shader/shaders/FontShader.hpp
@@ -15,6 +15,7 @@ namespace Dawn {
SHADER_PARAMETER_BUFFER_DEFINE(FontShaderBuffer, \
SHADER_PARAMETER_BUFFER_COLOR_ARRAY(colors, FONT_SHADER_PARTS_MAX);
SHADER_PARAMETER_BUFFER_INTEGER_ARRAY(textures, FONT_SHADER_PARTS_MAX);
+ SHADER_PARAMETER_BUFFER_VEC2_ARRAY(linePositions, FONT_SHADER_PARTS_MAX);
SHADER_PARAMETER_BUFFER_INTEGER_ARRAY(quadMappings, FONT_SHADER_QUADS_MAX);
);