Added really unfinished text decoration support

This commit is contained in:
2023-07-15 23:42:24 -07:00
parent a1d43b4ab6
commit 6e85b61200
5 changed files with 94 additions and 17 deletions

View File

@ -85,20 +85,20 @@
</choices> </choices>
<if key="interview" value="help-her-out"> <if key="interview" value="help-her-out">
<title> <text>
<string lang="en"><font style="italics">"Of course", I tell the Newspaper Girl. "I'd love to be interviewed. This is about my Prom campaign, right?"</font></string> <string lang="en"><font style="italics">"Of course", I tell the Newspaper Girl. "I'd love to be interviewed. This is about my Prom campaign, right?"</font></string>
</title> </text>
<title> <text>
<string lang="en"><font style="italics">"Oh, yes!" Newspaper Girl grins. "You're the star, Ethereality. What else will it be about?"</font></string> <string lang="en"><font style="italics">"Oh, yes!" Newspaper Girl grins. "You're the star, Ethereality. What else will it be about?"</font></string>
</title> </text>
</if> </if>
<if key="interview" value="dont"> <if key="interview" value="dont">
<title> <text>
<string lang="en"><font style="italics">"Sorry", I say, offering a slight smile. It'll feel consolatory enough. "It's Prom Day."</font></string> <string lang="en"><font style="italics">"Sorry", I say, offering a slight smile. It'll feel consolatory enough. "It's Prom Day."</font></string>
</title> </text>
<title> <text>
<string lang="en"><font style="italics">"Oh, yes!" Newspaper Girl says. "I'm so sorry, of course you're busy. You're going to shine, Eth!"</font></string> <string lang="en"><font style="italics">"Oh, yes!" Newspaper Girl says. "I'm so sorry, of course you're busy. You're going to shine, Eth!"</font></string>
</title> </text>
</if> </if>
<text> <text>
@ -119,7 +119,7 @@
</text> </text>
<text> <text>
<string lang="en">It's my day. Today is Prom Day. <font style="strike">(Wasn't yesterday?)</font> 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.</string> <string lang="en">It's my day. Today is Prom Day. <font decoration="strikethrough">(Wasn't yesterday?)</font> 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.</string>
</text> </text>
<text> <text>
@ -129,6 +129,5 @@
<text> <text>
<string lang="en">Thank god for that.</string> <string lang="en">Thank god for that.</string>
</text> </text>
</events> </events>
</vnscene> </vnscene>

View File

@ -35,11 +35,12 @@ std::vector<struct ShaderPassItem> UILabel::getUIRenderPasses() {
auto canvas = this->getCanvas(); auto canvas = this->getCanvas();
auto shader = getGame()->renderManager.fontShader; auto shader = getGame()->renderManager.fontShader;
glm::mat4 model = transform->getWorldTransform();
// Translate // Translate
glm::mat4 model = transform->getWorldTransform();
model = glm::translate(model, glm::vec3(this->textOffset, 0.0f)); model = glm::translate(model, glm::vec3(this->textOffset, 0.0f));
struct ShaderPassItem item; struct ShaderPassItem item;
item.shader = shader; item.shader = shader;
item.mesh = &this->mesh; item.mesh = &this->mesh;
item.matrixValues[shader->paramModel] = model; item.matrixValues[shader->paramModel] = model;
@ -76,10 +77,20 @@ std::vector<struct ShaderPassItem> UILabel::getUIRenderPasses() {
item.textureSlots[it->second] = &it->first->texture; item.textureSlots[it->second] = &it->first->texture;
item.textureValues[param] = it->second; item.textureValues[param] = it->second;
++it; ++it;
} }
return { item }; std::vector<struct ShaderPassItem> 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() { float_t UILabel::getContentWidth() {
@ -114,6 +125,7 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
glm::vec2 position(0, 0); glm::vec2 position(0, 0);
int32_t partIndex = 0; int32_t partIndex = 0;
std::vector<std::pair<glm::vec4, glm::vec4>> vertices; std::vector<std::pair<glm::vec4, glm::vec4>> vertices;
std::vector<std::pair<glm::vec4, glm::vec4>> decorations;
struct FontShaderBufferData fontData; struct FontShaderBufferData fontData;
quadCountTotal = 0; quadCountTotal = 0;
quadCount = -1; quadCount = -1;
@ -124,6 +136,7 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
// Reset // Reset
lines.clear(); lines.clear();
textureMap.clear(); textureMap.clear();
hasDecorations = false;
// Determine font dimensions. // Determine font dimensions.
auto itText = newTexts.begin(); auto itText = newTexts.begin();
@ -188,6 +201,7 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
glm::vec4 uvs(0, 0, 1, 1); glm::vec4 uvs(0, 0, 1, 1);
glm::vec4 vert(0, 0, 0, 0); glm::vec4 vert(0, 0, 0, 0);
vertices.push_back(std::make_pair(vert, uvs)); vertices.push_back(std::make_pair(vert, uvs));
decorations.push_back(std::make_pair(vert, uvs));
fontData.quadMappings[quadCountTotal].value = partIndex; fontData.quadMappings[quadCountTotal].value = partIndex;
quadCountTotal++; quadCountTotal++;
@ -256,7 +270,10 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
// Basically this rewinds everything we've done to the last space char, // Basically this rewinds everything we've done to the last space char,
// changes it to a newline, and then moves the position along. // changes it to a newline, and then moves the position along.
int32_t diff = i - lastSpaceCharacter; 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'; text.text[lastSpaceCharacter] = '\n';
i = lastSpaceCharacter; i = lastSpaceCharacter;
lastSpaceCharacter = -1; lastSpaceCharacter = -1;
@ -279,9 +296,27 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
vert.y = position.y + charInfo.bitmapPosition.y; vert.y = position.y + charInfo.bitmapPosition.y;
vert.w = vert.x + charInfo.bitmapSize.x; vert.w = vert.x + charInfo.bitmapSize.x;
vert.z = vert.y + charInfo.bitmapSize.y; vert.z = vert.y + charInfo.bitmapSize.y;
vertices.push_back(std::make_pair(vert, uvs)); 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. // Move the current position along.
position.x += charInfo.advanceX; position.x += charInfo.advanceX;
position.y += charInfo.advanceY; position.y += charInfo.advanceY;
@ -320,9 +355,18 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
QUAD_VERTICE_COUNT * vertices.size(), QUAD_VERTICE_COUNT * vertices.size(),
QUAD_INDICE_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; int32_t j = 0;
auto itQuad = vertices.begin(); auto itQuad = vertices.begin();
while(itQuad != vertices.end()) { while(itQuad != vertices.end()) {
@ -335,10 +379,29 @@ void UILabel::rebufferQuads(const std::vector<struct UILabelText> newTexts) {
0.0f, 0.0f,
j * QUAD_VERTICE_COUNT, j * QUAD_INDICE_COUNT j * QUAD_VERTICE_COUNT, j * QUAD_INDICE_COUNT
); );
j++; ++j;
++itQuad; ++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 // Buffer data
shaderBuffer.buffer(&fontData); shaderBuffer.buffer(&fontData);

View File

@ -15,6 +15,7 @@ namespace Dawn {
struct UILabelStyle { struct UILabelStyle {
struct Color color = COLOR_WHITE; struct Color color = COLOR_WHITE;
flag_t style = 0; flag_t style = 0;
flag_t decorations = 0;
uint32_t size = 16; uint32_t size = 16;
TrueTypeAsset *font = nullptr; TrueTypeAsset *font = nullptr;
}; };
@ -45,9 +46,11 @@ namespace Dawn {
class UILabel : public UIComponentRenderable { class UILabel : public UIComponentRenderable {
private: private:
Mesh mesh; Mesh mesh;
Mesh meshDecorations;
FontShaderBuffer shaderBuffer; FontShaderBuffer shaderBuffer;
std::map<TrueTypeFaceTexture*, int32_t> textureMap; std::map<TrueTypeFaceTexture*, int32_t> textureMap;
bool_t ignoreAlignmentUpdate = false; bool_t ignoreAlignmentUpdate = false;
bool_t hasDecorations = false;
public: public:
int32_t quadStart = 0; int32_t quadStart = 0;

View File

@ -63,6 +63,15 @@ void UIRichTextLabel::onStart() {
style.style = current.style; 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")) { if(node->attributes.contains("color")) {
style.color = Color::fromString(node->attributes["color"]); style.color = Color::fromString(node->attributes["color"]);
} else { } else {

View File

@ -11,3 +11,6 @@
#define TRUE_TYPE_VARIANT_BOLD FLAG_DEFINE(0) #define TRUE_TYPE_VARIANT_BOLD FLAG_DEFINE(0)
#define TRUE_TYPE_VARIANT_ITALICS FLAG_DEFINE(1) #define TRUE_TYPE_VARIANT_ITALICS FLAG_DEFINE(1)
#define TRUE_TYPE_DECORATION_STRIKETHROUGH FLAG_DEFINE(0)
#define TRUE_TYPE_DECORATION_UNDERLINE FLAG_DEFINE(1)