multiline labels

This commit is contained in:
MihailRis
2024-02-25 21:03:21 +03:00
parent fcc5d11814
commit d189bdc107
7 changed files with 237 additions and 93 deletions
+65 -56
View File
@@ -2,7 +2,9 @@
#include "Texture.h"
#include "Batch2D.h"
using glm::vec4;
inline constexpr uint GLYPH_SIZE = 16;
inline constexpr uint MAX_CODEPAGES = 10000; // idk ho many codepages unicode has
inline constexpr glm::vec4 SHADOW_TINT(0.0f, 0.0f, 0.0f, 1.0f);
Font::Font(std::vector<std::unique_ptr<Texture>> pages, int lineHeight, int yoffset)
: lineHeight(lineHeight), yoffset(yoffset), pages(std::move(pages)) {
@@ -16,71 +18,78 @@ int Font::getYOffset() const {
}
int Font::getLineHeight() const {
return lineHeight;
return lineHeight;
}
bool Font::isPrintableChar(int c) {
switch (c){
case ' ':
case '\t':
case '\n':
case '\f':
case '\r':
return false;
default:
return true;
}
bool Font::isPrintableChar(uint codepoint) const {
switch (codepoint){
case ' ':
case '\t':
case '\n':
case '\f':
case '\r':
return false;
default:
return true;
}
}
const int RES = 16;
int Font::calcWidth(std::wstring text, size_t length) {
return std::min(text.length(), length) * 8;
return std::min(text.length(), length) * 8;
}
void Font::draw(Batch2D* batch, std::wstring text, int x, int y) {
draw(batch, text, x, y, STYLE_NONE);
draw(batch, text, x, y, FontStyle::none);
}
void Font::draw(Batch2D* batch, std::wstring text, int x, int y, int style) {
int page = 0;
int next = 10000;
int init_x = x;
do {
for (unsigned c : text){
if (isPrintableChar(c)){
int charpage = c >> 8;
if (charpage == page){
Texture* texture = pages[charpage].get();
if (texture == nullptr){
texture = pages[0].get();
}
batch->texture(texture);
static inline void drawGlyph(Batch2D* batch, int x, int y, uint c, FontStyle style) {
switch (style){
case FontStyle::shadow:
batch->sprite(x+1, y+1, GLYPH_SIZE, GLYPH_SIZE, 16, c, SHADOW_TINT);
break;
case FontStyle::outline:
for (int oy = -1; oy <= 1; oy++){
for (int ox = -1; ox <= 1; ox++){
if (ox || oy) {
batch->sprite(x+ox, y+oy, GLYPH_SIZE, GLYPH_SIZE, 16, c, SHADOW_TINT);
}
}
}
break;
}
batch->sprite(x, y, GLYPH_SIZE, GLYPH_SIZE, 16, c, batch->color);
}
switch (style){
case STYLE_SHADOW:
batch->sprite(x+1, y+1, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f));
break;
case STYLE_OUTLINE:
for (int oy = -1; oy <= 1; oy++){
for (int ox = -1; ox <= 1; ox++){
if (ox || oy)
batch->sprite(x+ox, y+oy, RES, RES, 16, c, vec4(0.0f, 0.0f, 0.0f, 1.0f));
}
}
break;
}
void Font::draw(Batch2D* batch, std::wstring text, int x, int y, FontStyle style) {
draw(batch, std::wstring_view(text.c_str(), text.length()), x, y, style);
}
batch->sprite(x, y, RES, RES, 16, c, batch->color);
}
else if (charpage > page && charpage < next){
next = charpage;
}
}
x += 8;//getGlyphWidth(c);
}
page = next;
next = 10000;
x = init_x;
} while (page < 10000);
void Font::draw(Batch2D* batch, std::wstring_view text, int x, int y, FontStyle style) {
uint page = 0;
uint next = MAX_CODEPAGES;
int init_x = x;
do {
for (uint c : text){
if (!isPrintableChar(c)) {
x += 8;
continue;
}
int charpage = c >> 8;
if (charpage == page){
Texture* texture = pages[charpage].get();
if (texture == nullptr){
texture = pages[0].get();
}
batch->texture(texture);
drawGlyph(batch, x, y, c, style);
}
else if (charpage > page && charpage < next){
next = charpage;
}
x += 8;//getGlyphWidth(c);
}
page = next;
next = MAX_CODEPAGES;
x = init_x;
} while (page < MAX_CODEPAGES);
}