kopia lustrzana https://github.com/pimoroni/pimoroni-pico
89 wiersze
2.4 KiB
C++
89 wiersze
2.4 KiB
C++
#include "bitmap_fonts.hpp"
|
|
#include "common/unicode_sorta.hpp"
|
|
|
|
namespace bitmap {
|
|
int32_t measure_character(const font_t *font, const char c, const uint8_t scale) {
|
|
if(c < 32 || c > 127 + 64) { // + 64 char remappings defined in unicode_sorta.hpp
|
|
return 0;
|
|
}
|
|
|
|
uint8_t char_index = c;
|
|
|
|
if(char_index > 127) {
|
|
char_index = char_base[c - 128];
|
|
}
|
|
|
|
char_index -= 32;
|
|
|
|
return font->widths[char_index] * scale;
|
|
}
|
|
|
|
int32_t measure_text(const font_t *font, const std::string &t, const uint8_t scale) {
|
|
int32_t text_width = 0;
|
|
for(auto c : t) {
|
|
text_width += measure_character(font, c, scale);
|
|
}
|
|
return text_width;
|
|
}
|
|
|
|
void character(const font_t *font, rect_func rectangle, const char c, const int32_t x, const int32_t y, const uint8_t scale) {
|
|
if(c < 32 || c > 127 + 64) { // + 64 char remappings defined in unicode_sorta.hpp
|
|
return;
|
|
}
|
|
|
|
uint8_t char_index = c;
|
|
|
|
if(char_index > 127) {
|
|
char_index = char_base[c - 128];
|
|
}
|
|
|
|
char_index -= 32;
|
|
|
|
const uint8_t *d = &font->data[char_index * font->max_width];
|
|
for(uint8_t cx = 0; cx < font->widths[char_index]; cx++) {
|
|
for(uint8_t cy = 0; cy < font->height; cy++) {
|
|
if((1U << cy) & *d) {
|
|
rectangle(x + (cx * scale), y + (cy * scale), scale, scale);
|
|
}
|
|
}
|
|
|
|
d++;
|
|
}
|
|
}
|
|
|
|
void text(const font_t *font, rect_func rectangle, const std::string &t, const int32_t x, const int32_t y, const int32_t wrap, const uint8_t scale) {
|
|
uint32_t co = 0, lo = 0; // character and line (if wrapping) offset
|
|
|
|
size_t i = 0;
|
|
while(i < t.length()) {
|
|
// find length of current word
|
|
size_t next_space = t.find(' ', i + 1);
|
|
|
|
if(next_space == std::string::npos) {
|
|
next_space = t.length();
|
|
}
|
|
|
|
uint16_t word_width = 0;
|
|
for(size_t j = i; j < next_space; j++) {
|
|
word_width += measure_character(font, t[j], scale);
|
|
}
|
|
|
|
// if this word would exceed the wrap limit then
|
|
// move to the next line
|
|
if(co != 0 && co + word_width > (uint32_t)wrap) {
|
|
co = 0;
|
|
lo += (font->height + 1) * scale;
|
|
}
|
|
|
|
// draw word
|
|
for(size_t j = i; j < next_space; j++) {
|
|
character(font, rectangle, t[j], x + co, y + lo, scale);
|
|
co += measure_character(font, t[j], scale);
|
|
}
|
|
|
|
// move character offset to end of word and add a space
|
|
co += font->widths[0] * scale;
|
|
i = next_space + 1;
|
|
}
|
|
}
|
|
} |