multiline labels
This commit is contained in:
+65
-56
@@ -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);
|
||||
}
|
||||
|
||||
+15
-13
@@ -9,25 +9,27 @@
|
||||
class Texture;
|
||||
class Batch2D;
|
||||
|
||||
const uint STYLE_NONE = 0;
|
||||
const uint STYLE_SHADOW = 1;
|
||||
const uint STYLE_OUTLINE = 2;
|
||||
enum class FontStyle {
|
||||
none,
|
||||
shadow,
|
||||
outline
|
||||
};
|
||||
|
||||
class Font {
|
||||
int lineHeight;
|
||||
int lineHeight;
|
||||
int yoffset;
|
||||
public:
|
||||
std::vector<std::unique_ptr<Texture>> pages;
|
||||
Font(std::vector<std::unique_ptr<Texture>> pages, int lineHeight, int yoffset);
|
||||
~Font();
|
||||
std::vector<std::unique_ptr<Texture>> pages;
|
||||
Font(std::vector<std::unique_ptr<Texture>> pages, int lineHeight, int yoffset);
|
||||
~Font();
|
||||
|
||||
int getLineHeight() const;
|
||||
int getLineHeight() const;
|
||||
int getYOffset() const;
|
||||
int calcWidth(std::wstring text, size_t length=-1);
|
||||
// int getGlyphWidth(char c);
|
||||
bool isPrintableChar(int c);
|
||||
void draw(Batch2D* batch, std::wstring text, int x, int y);
|
||||
void draw(Batch2D* batch, std::wstring text, int x, int y, int style);
|
||||
int calcWidth(std::wstring text, size_t length=-1);
|
||||
bool isPrintableChar(uint codepoint) const;
|
||||
void draw(Batch2D* batch, std::wstring text, int x, int y);
|
||||
void draw(Batch2D* batch, std::wstring text, int x, int y, FontStyle style);
|
||||
void draw(Batch2D* batch, std::wstring_view text, int x, int y, FontStyle style);
|
||||
};
|
||||
|
||||
#endif /* GRAPHICS_FONT_H_ */
|
||||
|
||||
Reference in New Issue
Block a user