horizontal text

This commit is contained in:
Jorijn van der Graaf 2025-11-26 04:13:02 +01:00
commit 476764be46
2 changed files with 58 additions and 3 deletions

View file

@ -34,7 +34,7 @@ TextElement::TextElement(std::int_fast32_t anchorX, std::int_fast32_t anchorY, s
}
void TextElement::RenderText(const std::string_view text, float size, Pixel_BU8_GU8_RU8_AU8 color, Font& font, TextAlignment alignment, TextOverflowMode overflowMode) {
void TextElement::RenderText(const std::string_view text, float size, Pixel_BU8_GU8_RU8_AU8 color, Font& font, TextAlignment alignment, VerticalTextAlignment verticalAlignment, TextOverflowMode overflowMode) {
// Calculate the actual size needed for the text
float scale = stbtt_ScaleForPixelHeight(&font.font, size);
int baseline = (int)(font.ascent * scale);
@ -70,6 +70,22 @@ void TextElement::RenderText(const std::string_view text, float size, Pixel_BU8_
// Now process each line
std::uint_fast32_t lineHeight = (font.ascent - font.descent) * scale;
std::uint_fast32_t maxLineWidth = scaled.width;
std::uint_fast32_t totalTextHeight = lines.size() * lineHeight;
// Calculate vertical offset based on vertical alignment
std::int_fast32_t verticalOffset = 0;
switch (verticalAlignment) {
case VerticalTextAlignment::Top:
verticalOffset = 0;
break;
case VerticalTextAlignment::Middle:
verticalOffset = (scaled.height - totalTextHeight) / 2;
break;
case VerticalTextAlignment::Bottom:
verticalOffset = scaled.height - totalTextHeight;
break;
}
std::uint_fast32_t currentLineStartY = 0;
for (std::size_t lineIndex = 0; lineIndex < lines.size(); ++lineIndex) {
@ -101,7 +117,7 @@ void TextElement::RenderText(const std::string_view text, float size, Pixel_BU8_
// Render the line
int x = startX;
int startY = currentLineStartY + baseline + (lineIndex * lineHeight);
int startY = verticalOffset + currentLineStartY + baseline + (lineIndex * lineHeight);
for (std::size_t i = 0; i < line.size(); ++i) {
int codepoint = line[i];
@ -248,6 +264,39 @@ void TextElement::RenderText(const std::string_view text, float size, Pixel_BU8_
if (!currentLine.empty()) {
RenderWrappedLine(currentLine, scale, baseline, currentLineStartY, color, font, alignment);
}
// Apply vertical alignment to the entire wrapped text
std::uint_fast32_t totalTextHeight = (currentLineStartY + lineHeight); // Total height including last line
// Calculate vertical offset based on vertical alignment
std::int_fast32_t verticalOffset = 0;
switch (verticalAlignment) {
case VerticalTextAlignment::Top:
verticalOffset = 0;
break;
case VerticalTextAlignment::Middle:
verticalOffset = (scaled.height - totalTextHeight) / 2;
break;
case VerticalTextAlignment::Bottom:
verticalOffset = scaled.height - totalTextHeight;
break;
}
// Shift all rendered content vertically
if (verticalOffset != 0) {
for (std::uint_fast32_t y = 0; y < scaled.height; ++y) {
for (std::uint_fast32_t x = 0; x < scaled.width; ++x) {
std::uint_fast32_t index = y * scaled.width + x;
if (index < bufferScaled.size()) {
// Move the pixel vertically
std::uint_fast32_t newIndex = (y + verticalOffset) * scaled.width + x;
if (newIndex < bufferScaled.size()) {
bufferScaled[newIndex] = bufferScaled[index];
}
}
}
}
}
}
}

View file

@ -30,6 +30,12 @@ export namespace Crafter {
Right
};
enum class VerticalTextAlignment {
Top,
Middle,
Bottom
};
enum class TextOverflowMode {
Clip, // Clip text that overflows
Wrap // Wrap text to multiple lines
@ -40,6 +46,6 @@ export namespace Crafter {
void RenderWrappedLine(const std::string_view line, float scale, int baseline, std::uint_fast32_t startY, Pixel_BU8_GU8_RU8_AU8 color, Font& font, TextAlignment alignment);
public:
TextElement(std::int_fast32_t anchorX = FractionalToMapped(0.5), std::int_fast32_t anchorY = FractionalToMapped(0.5), std::uint_fast32_t relativeWidth = FractionalToMapped(1), std::uint_fast32_t relativeHeight = FractionalToMapped(1), std::int_fast32_t anchorOffsetX = FractionalToMapped(0.5), std::int_fast32_t anchorOffsetY = FractionalToMapped(0.5), std::int_fast32_t z = 0, bool ignoreScaling = false);
void RenderText(const std::string_view text, float size, Pixel_BU8_GU8_RU8_AU8 pixel, Font& font, TextAlignment alignment = TextAlignment::Left, TextOverflowMode overflowMode = TextOverflowMode::Clip);
void RenderText(const std::string_view text, float size, Pixel_BU8_GU8_RU8_AU8 pixel, Font& font, TextAlignment alignment = TextAlignment::Left, VerticalTextAlignment verticalAlignment = VerticalTextAlignment::Top, TextOverflowMode overflowMode = TextOverflowMode::Clip);
};
}