diff --git a/assets/games/liminal/scenes/prologue/ScenePrologue4.xml b/assets/games/liminal/scenes/prologue/ScenePrologue4.xml
index bf010fc9..792c217c 100644
--- a/assets/games/liminal/scenes/prologue/ScenePrologue4.xml
+++ b/assets/games/liminal/scenes/prologue/ScenePrologue4.xml
@@ -85,20 +85,20 @@
-
+
"Of course", I tell the Newspaper Girl. "I'd love to be interviewed. This is about my Prom campaign, right?"
-
-
+
+
"Oh, yes!" Newspaper Girl grins. "You're the star, Ethereality. What else will it be about?"
-
+
-
+
"Sorry", I say, offering a slight smile. It'll feel consolatory enough. "It's Prom Day."
-
-
+
+
"Oh, yes!" Newspaper Girl says. "I'm so sorry, of course you're busy. You're going to shine, Eth!"
-
+
@@ -119,7 +119,7 @@
- It's my day. Today is Prom Day. (Wasn't yesterday?) I am pristine and they know it. They have seen my face on my campaign posters, seen what I would look like with a crown on my head.
+ It's my day. Today is Prom Day. (Wasn't yesterday?) I am pristine and they know it. They have seen my face on my campaign posters, seen what I would look like with a crown on my head.
@@ -129,6 +129,5 @@
Thank god for that.
-
\ No newline at end of file
diff --git a/src/dawn/scene/components/ui/text/UILabel.cpp b/src/dawn/scene/components/ui/text/UILabel.cpp
index 2d8dd0ac..d32827e8 100644
--- a/src/dawn/scene/components/ui/text/UILabel.cpp
+++ b/src/dawn/scene/components/ui/text/UILabel.cpp
@@ -35,11 +35,12 @@ std::vector UILabel::getUIRenderPasses() {
auto canvas = this->getCanvas();
auto shader = getGame()->renderManager.fontShader;
- glm::mat4 model = transform->getWorldTransform();
// Translate
+ glm::mat4 model = transform->getWorldTransform();
model = glm::translate(model, glm::vec3(this->textOffset, 0.0f));
struct ShaderPassItem item;
+
item.shader = shader;
item.mesh = &this->mesh;
item.matrixValues[shader->paramModel] = model;
@@ -76,10 +77,20 @@ std::vector UILabel::getUIRenderPasses() {
item.textureSlots[it->second] = &it->first->texture;
item.textureValues[param] = it->second;
+
++it;
}
- return { item };
+ std::vector items;
+ items.push_back(item);
+
+ if(this->hasDecorations) {
+ struct ShaderPassItem itemDecorations = item;
+ itemDecorations.mesh = &this->meshDecorations;
+ items.push_back(itemDecorations);
+ }
+
+ return items;
}
float_t UILabel::getContentWidth() {
@@ -114,6 +125,7 @@ void UILabel::rebufferQuads(const std::vector newTexts) {
glm::vec2 position(0, 0);
int32_t partIndex = 0;
std::vector> vertices;
+ std::vector> decorations;
struct FontShaderBufferData fontData;
quadCountTotal = 0;
quadCount = -1;
@@ -124,6 +136,7 @@ void UILabel::rebufferQuads(const std::vector newTexts) {
// Reset
lines.clear();
textureMap.clear();
+ hasDecorations = false;
// Determine font dimensions.
auto itText = newTexts.begin();
@@ -188,6 +201,7 @@ void UILabel::rebufferQuads(const std::vector newTexts) {
glm::vec4 uvs(0, 0, 1, 1);
glm::vec4 vert(0, 0, 0, 0);
vertices.push_back(std::make_pair(vert, uvs));
+ decorations.push_back(std::make_pair(vert, uvs));
fontData.quadMappings[quadCountTotal].value = partIndex;
quadCountTotal++;
@@ -256,7 +270,10 @@ void UILabel::rebufferQuads(const std::vector newTexts) {
// Basically this rewinds everything we've done to the last space char,
// changes it to a newline, and then moves the position along.
int32_t diff = i - lastSpaceCharacter;
- for(int32_t k = 0; k < diff; k++) vertices.pop_back();
+ for(int32_t k = 0; k < diff; k++) {
+ vertices.pop_back();
+ decorations.pop_back();
+ }
text.text[lastSpaceCharacter] = '\n';
i = lastSpaceCharacter;
lastSpaceCharacter = -1;
@@ -279,9 +296,27 @@ void UILabel::rebufferQuads(const std::vector newTexts) {
vert.y = position.y + charInfo.bitmapPosition.y;
vert.w = vert.x + charInfo.bitmapSize.x;
vert.z = vert.y + charInfo.bitmapSize.y;
-
vertices.push_back(std::make_pair(vert, uvs));
+ // Decorations
+ if(text.style.decorations != 0) {
+ auto charInfo2 = realText.texture->getCharacterData('-');
+ uvs.y = charInfo2.textureY / wh.y;
+ uvs.w = charInfo2.bitmapSize.x / wh.x;
+ uvs.z = uvs.y + (charInfo2.bitmapSize.y / wh.y);
+ vert.x = position.x + charInfo2.bitmapPosition.x;
+ vert.y = position.y + charInfo2.bitmapPosition.y;
+ vert.w = vert.x + charInfo.advanceX;
+ vert.z = vert.y + charInfo2.bitmapSize.y;
+ decorations.push_back(std::make_pair(vert, uvs));
+ hasDecorations = true;
+ // TODO: Finish
+ } else {
+ uvs = glm::vec4(0, 0, 1, 1);
+ vert = glm::vec4(0, 0, 0, 0);
+ decorations.push_back(std::make_pair(vert, uvs));
+ }
+
// Move the current position along.
position.x += charInfo.advanceX;
position.y += charInfo.advanceY;
@@ -320,9 +355,18 @@ void UILabel::rebufferQuads(const std::vector newTexts) {
QUAD_VERTICE_COUNT * vertices.size(),
QUAD_INDICE_COUNT * vertices.size()
);
+
+ if(hasDecorations) {
+ assertTrue(vertices.size() == decorations.size());
+ this->meshDecorations.createBuffers(
+ QUAD_VERTICE_COUNT * decorations.size(),
+ QUAD_INDICE_COUNT * decorations.size()
+ );
+ }
}
- // Now buffer the quads.
+
+ // Now buffer the quads. Can be optimized probably.
int32_t j = 0;
auto itQuad = vertices.begin();
while(itQuad != vertices.end()) {
@@ -335,10 +379,29 @@ void UILabel::rebufferQuads(const std::vector newTexts) {
0.0f,
j * QUAD_VERTICE_COUNT, j * QUAD_INDICE_COUNT
);
- j++;
+ ++j;
++itQuad;
}
+ // Now buffer decorations
+ if(hasDecorations) {
+ j = 0;
+ itQuad = decorations.begin();
+ while(itQuad != decorations.end()) {
+ auto vert = itQuad->first;
+ auto uvs = itQuad->second;
+
+ QuadMesh::bufferQuadMeshWithZ(&this->meshDecorations,
+ glm::vec2(vert.x, vert.y), glm::vec2(uvs.x, uvs.y),
+ glm::vec2(vert.w, vert.z), glm::vec2(uvs.w, uvs.z),
+ 0.0f,
+ j * QUAD_VERTICE_COUNT, j * QUAD_INDICE_COUNT
+ );
+ ++j;
+ ++itQuad;
+ }
+ }
+
// Buffer data
shaderBuffer.buffer(&fontData);
diff --git a/src/dawn/scene/components/ui/text/UILabel.hpp b/src/dawn/scene/components/ui/text/UILabel.hpp
index 1d937099..1db2a1dc 100644
--- a/src/dawn/scene/components/ui/text/UILabel.hpp
+++ b/src/dawn/scene/components/ui/text/UILabel.hpp
@@ -15,6 +15,7 @@ namespace Dawn {
struct UILabelStyle {
struct Color color = COLOR_WHITE;
flag_t style = 0;
+ flag_t decorations = 0;
uint32_t size = 16;
TrueTypeAsset *font = nullptr;
};
@@ -45,9 +46,11 @@ namespace Dawn {
class UILabel : public UIComponentRenderable {
private:
Mesh mesh;
+ Mesh meshDecorations;
FontShaderBuffer shaderBuffer;
std::map textureMap;
bool_t ignoreAlignmentUpdate = false;
+ bool_t hasDecorations = false;
public:
int32_t quadStart = 0;
diff --git a/src/dawn/scene/components/ui/text/UIRichTextLabel.cpp b/src/dawn/scene/components/ui/text/UIRichTextLabel.cpp
index 8cddc32b..275d9819 100644
--- a/src/dawn/scene/components/ui/text/UIRichTextLabel.cpp
+++ b/src/dawn/scene/components/ui/text/UIRichTextLabel.cpp
@@ -63,6 +63,15 @@ void UIRichTextLabel::onStart() {
style.style = current.style;
}
+ if(node->attributes.contains("decoration")) {
+ std::string s = node->attributes["decoration"];
+ style.decorations = 0;
+ if(s.find("underline") != std::string::npos) style.decorations |= TRUE_TYPE_DECORATION_UNDERLINE;
+ if(s.find("strikethrough") != std::string::npos) style.decorations |= TRUE_TYPE_DECORATION_STRIKETHROUGH;
+ } else {
+ style.decorations = current.decorations;
+ }
+
if(node->attributes.contains("color")) {
style.color = Color::fromString(node->attributes["color"]);
} else {
diff --git a/src/dawnshared/display/font/truetype/TrueTypeShared.hpp b/src/dawnshared/display/font/truetype/TrueTypeShared.hpp
index d680c8be..1079a20a 100644
--- a/src/dawnshared/display/font/truetype/TrueTypeShared.hpp
+++ b/src/dawnshared/display/font/truetype/TrueTypeShared.hpp
@@ -10,4 +10,7 @@
#define TRUE_TYPE_CHAR_END 0xFF
#define TRUE_TYPE_VARIANT_BOLD FLAG_DEFINE(0)
-#define TRUE_TYPE_VARIANT_ITALICS FLAG_DEFINE(1)
\ No newline at end of file
+#define TRUE_TYPE_VARIANT_ITALICS FLAG_DEFINE(1)
+
+#define TRUE_TYPE_DECORATION_STRIKETHROUGH FLAG_DEFINE(0)
+#define TRUE_TYPE_DECORATION_UNDERLINE FLAG_DEFINE(1)
\ No newline at end of file