Skip to content

Commit 004c8de

Browse files
committed
Bitmap Fonts: Add rotation support.
* Fix bug with word-wrap ignoring \n * Fix bug with word-wrap miscalculating word size
1 parent 3639b46 commit 004c8de

File tree

3 files changed

+61
-21
lines changed

3 files changed

+61
-21
lines changed

libraries/bitmap_fonts/bitmap_fonts.cpp

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ namespace bitmap {
4242
return text_width;
4343
}
4444

45-
void character(const font_t *font, rect_func rectangle, const char c, const int32_t x, const int32_t y, const uint8_t scale, unicode_sorta::codepage_t codepage) {
45+
void character(const font_t *font, rect_func rectangle, const char c, const int32_t x, const int32_t y, const uint8_t scale, int32_t rotation, unicode_sorta::codepage_t codepage) {
4646
if(c < 32 || c > 127 + 64) { // + 64 char remappings defined in unicode_sorta.hpp
4747
return;
4848
}
@@ -89,7 +89,8 @@ namespace bitmap {
8989
uint8_t accent_offset = char_index < 65 ? offset_upper : offset_lower;
9090

9191
// Offset our y position to account for our column canvas being 32 pixels
92-
int y_offset = y - (8 * scale);
92+
// this gives us 8 "pixels" of headroom above the letters for diacritic marks
93+
int font_offset = (8 * scale);
9394

9495
// Iterate through each horizontal column of font (and accent) data
9596
for(uint8_t cx = 0; cx < font->widths[char_index]; cx++) {
@@ -98,6 +99,8 @@ namespace bitmap {
9899
// We shift the char down 8 pixels to make room for an accent above.
99100
uint32_t data = *d << 8;
100101

102+
int32_t o_x = cx * scale;
103+
101104
// For fonts that are taller than 8 pixels (up to 16) they need two bytes
102105
if(two_bytes_per_column) {
103106
d++;
@@ -113,7 +116,28 @@ namespace bitmap {
113116
// Draw the 32 pixel column
114117
for(uint8_t cy = 0; cy < 32; cy++) {
115118
if((1U << cy) & data) {
116-
rectangle(x + (cx * scale), y_offset + (cy * scale), scale, scale);
119+
int32_t o_y = cy * scale;
120+
int32_t px = 0;
121+
int32_t py = 0;
122+
switch (rotation) {
123+
case 0:
124+
px = x + o_x;
125+
py = y - font_offset + o_y;
126+
break;
127+
case 90:
128+
px = x + font_offset - o_y;
129+
py = y + o_x;
130+
break;
131+
case 180:
132+
px = x - o_x;
133+
py = y + font_offset - o_y;
134+
break;
135+
case 270:
136+
px = x - font_offset + o_y;
137+
py = y - o_x;
138+
break;
139+
}
140+
rectangle(px, py, scale, scale);
117141
}
118142
}
119143

@@ -123,8 +147,9 @@ namespace bitmap {
123147
}
124148
}
125149

126-
void text(const font_t *font, rect_func rectangle, const std::string_view &t, const int32_t x, const int32_t y, const int32_t wrap, const uint8_t scale, const uint8_t letter_spacing, bool fixed_width) {
127-
uint32_t co = 0, lo = 0; // character and line (if wrapping) offset
150+
void text(const font_t *font, rect_func rectangle, const std::string_view &t, const int32_t x, const int32_t y, const int32_t wrap, const uint8_t scale, const uint8_t letter_spacing, bool fixed_width, int32_t rotation) {
151+
uint32_t char_offset = 0;
152+
uint32_t line_offset = 0; // line (if wrapping) offset
128153
unicode_sorta::codepage_t codepage = unicode_sorta::PAGE_195;
129154

130155
size_t i = 0;
@@ -153,37 +178,52 @@ namespace bitmap {
153178
continue;
154179
}
155180
word_width += measure_character(font, t[j], scale, codepage, fixed_width);
181+
word_width += letter_spacing * scale;
156182
codepage = unicode_sorta::PAGE_195;
157183
}
158184

159185
// if this word would exceed the wrap limit then
160186
// move to the next line
161-
if(co != 0 && co + word_width > (uint32_t)wrap) {
162-
co = 0;
163-
lo += (font->height + 1) * scale;
187+
if(char_offset != 0 && char_offset + word_width > (uint32_t)wrap) {
188+
char_offset = 0;
189+
line_offset += (font->height + 1) * scale;
164190
}
165191

166192
// draw word
167-
for(size_t j = i; j < next_break; j++) {
193+
for(size_t j = i; j < std::min(next_break + 1, t.length()); j++) {
168194
if (t[j] == unicode_sorta::PAGE_194_START) {
169195
codepage = unicode_sorta::PAGE_194;
170196
continue;
171197
} else if (t[j] == unicode_sorta::PAGE_195_START) {
172198
continue;
173199
}
174-
if (t[j] == '\n') {
175-
lo += (font->height + 1) * scale;
176-
co = 0;
200+
if (t[j] == '\n') { // Linebreak
201+
line_offset += (font->height + 1) * scale;
202+
char_offset = 0;
203+
} else if (t[j] == ' ') { // Space
204+
char_offset += font->widths[0] * scale;
177205
} else {
178-
character(font, rectangle, t[j], x + co, y + lo, scale, codepage);
179-
co += measure_character(font, t[j], scale, codepage, fixed_width);
180-
co += letter_spacing * scale;
206+
switch(rotation) {
207+
case 0:
208+
character(font, rectangle, t[j], x + char_offset, y + line_offset, scale, rotation, codepage);
209+
break;
210+
case 90:
211+
character(font, rectangle, t[j], x - line_offset, y + char_offset, scale, rotation, codepage);
212+
break;
213+
case 180:
214+
character(font, rectangle, t[j], x - char_offset, y - line_offset, scale, rotation, codepage);
215+
break;
216+
case 270:
217+
character(font, rectangle, t[j], x + line_offset, y - char_offset, scale, rotation, codepage);
218+
break;
219+
}
220+
char_offset += measure_character(font, t[j], scale, codepage, fixed_width);
221+
char_offset += letter_spacing * scale;
181222
}
182223
codepage = unicode_sorta::PAGE_195;
183224
}
184225

185-
// move character offset to end of word and add a space
186-
co += font->widths[0] * scale;
226+
// move character offset
187227
i = next_break += 1;
188228
}
189229
}

libraries/bitmap_fonts/bitmap_fonts.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ namespace bitmap {
2222
int32_t measure_character(const font_t *font, const char c, const uint8_t scale, unicode_sorta::codepage_t codepage = unicode_sorta::PAGE_195, bool fixed_width = false);
2323
int32_t measure_text(const font_t *font, const std::string_view &t, const uint8_t scale = 2, const uint8_t letter_spacing = 1, bool fixed_width = false);
2424

25-
void character(const font_t *font, rect_func rectangle, const char c, const int32_t x, const int32_t y, const uint8_t scale = 2, unicode_sorta::codepage_t codepage = unicode_sorta::PAGE_195);
26-
void text(const font_t *font, rect_func rectangle, const std::string_view &t, const int32_t x, const int32_t y, const int32_t wrap, const uint8_t scale = 2, const uint8_t letter_spacing = 1, bool fixed_width = false);
25+
void character(const font_t *font, rect_func rectangle, const char c, const int32_t x, const int32_t y, const uint8_t scale = 2, int32_t rotation = 0, unicode_sorta::codepage_t codepage = unicode_sorta::PAGE_195);
26+
void text(const font_t *font, rect_func rectangle, const std::string_view &t, const int32_t x, const int32_t y, const int32_t wrap, const uint8_t scale = 2, const uint8_t letter_spacing = 1, bool fixed_width = false, int32_t rotation = 0);
2727
}

libraries/pico_graphics/pico_graphics.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ namespace pimoroni {
132132
if (bitmap_font) {
133133
bitmap::character(bitmap_font, [this](int32_t x, int32_t y, int32_t w, int32_t h) {
134134
rectangle(Rect(x, y, w, h));
135-
}, c, p.x, p.y, std::max(1.0f, s));
135+
}, c, p.x, p.y, std::max(1.0f, s), int32_t(a) % 360);
136136
return;
137137
}
138138

@@ -148,7 +148,7 @@ namespace pimoroni {
148148
if (bitmap_font) {
149149
bitmap::text(bitmap_font, [this](int32_t x, int32_t y, int32_t w, int32_t h) {
150150
rectangle(Rect(x, y, w, h));
151-
}, t, p.x, p.y, wrap, std::max(1.0f, s), letter_spacing, fixed_width);
151+
}, t, p.x, p.y, wrap, std::max(1.0f, s), letter_spacing, fixed_width, int32_t(a) % 360);
152152
return;
153153
}
154154

0 commit comments

Comments
 (0)