Skip to content

Commit

Permalink
PicoGraphics: Fixed-width bitmap font support.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gadgetoid committed May 15, 2023
1 parent 00d1617 commit fba7b53
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 133 deletions.
16 changes: 10 additions & 6 deletions libraries/bitmap_fonts/bitmap_fonts.cpp
@@ -1,11 +1,15 @@
#include "bitmap_fonts.hpp"

namespace bitmap {
int32_t measure_character(const font_t *font, const char c, const uint8_t scale, unicode_sorta::codepage_t codepage) {
int32_t measure_character(const font_t *font, const char c, const uint8_t scale, unicode_sorta::codepage_t codepage, bool fixed_width) {
if(c < 32 || c > 127 + 64) { // + 64 char remappings defined in unicode_sorta.hpp
return 0;
}

if(fixed_width) {
return font->max_width * scale;
}

uint8_t char_index = c;

if(char_index > 127) {
Expand All @@ -21,7 +25,7 @@ namespace bitmap {
return font->widths[char_index] * scale;
}

int32_t measure_text(const font_t *font, const std::string_view &t, const uint8_t scale, const uint8_t letter_spacing) {
int32_t measure_text(const font_t *font, const std::string_view &t, const uint8_t scale, const uint8_t letter_spacing, bool fixed_width) {
int32_t text_width = 0;
unicode_sorta::codepage_t codepage = unicode_sorta::PAGE_195;
for(auto c : t) {
Expand All @@ -31,7 +35,7 @@ namespace bitmap {
} else if (c == unicode_sorta::PAGE_195_START) {
continue;
}
text_width += measure_character(font, c, scale, codepage);
text_width += measure_character(font, c, scale, codepage, fixed_width);
text_width += letter_spacing * scale;
codepage = unicode_sorta::PAGE_195; // Reset back to default
}
Expand Down Expand Up @@ -119,7 +123,7 @@ namespace bitmap {
}
}

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) {
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) {
uint32_t co = 0, lo = 0; // character and line (if wrapping) offset
unicode_sorta::codepage_t codepage = unicode_sorta::PAGE_195;

Expand Down Expand Up @@ -148,7 +152,7 @@ namespace bitmap {
} else if (t[j] == unicode_sorta::PAGE_195_START) {
continue;
}
word_width += measure_character(font, t[j], scale, codepage);
word_width += measure_character(font, t[j], scale, codepage, fixed_width);
codepage = unicode_sorta::PAGE_195;
}

Expand All @@ -172,7 +176,7 @@ namespace bitmap {
co = 0;
} else {
character(font, rectangle, t[j], x + co, y + lo, scale, codepage);
co += measure_character(font, t[j], scale, codepage);
co += measure_character(font, t[j], scale, codepage, fixed_width);
co += letter_spacing * scale;
}
codepage = unicode_sorta::PAGE_195;
Expand Down
6 changes: 3 additions & 3 deletions libraries/bitmap_fonts/bitmap_fonts.hpp
Expand Up @@ -19,9 +19,9 @@ namespace bitmap {

typedef std::function<void(int32_t x, int32_t y, int32_t w, int32_t h)> rect_func;

int32_t measure_character(const font_t *font, const char c, const uint8_t scale, unicode_sorta::codepage_t codepage = unicode_sorta::PAGE_195);
int32_t measure_text(const font_t *font, const std::string_view &t, const uint8_t scale = 2, const uint8_t letter_spacing = 1);
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);
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);

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);
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);
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);
}
228 changes: 114 additions & 114 deletions libraries/bitmap_fonts/font8_data.hpp
Expand Up @@ -4,7 +4,7 @@

const bitmap::font_t font8 {
.height = 8,
.max_width = 6,
.max_width = 5,
.widths = {
3, 1, 3, 5, 4, 4, 4, 1, 3, 3, 3, 3, 2, 3, 2, 4,
4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 1, 2, 3, 3, 3, 4,
Expand All @@ -17,123 +17,123 @@ const bitmap::font_t font8 {
5, 4, 4, 5, 4, 4, 4, 4, 3
},
.data = {
0x00,0x00,0x00,0x00,0x00,0x00, //
0x5f,0x00,0x00,0x00,0x00,0x00, // !
0x03,0x00,0x03,0x00,0x00,0x00, // "
0x28,0x7c,0x28,0x7c,0x28,0x00, // #
0x24,0x7a,0x2f,0x12,0x00,0x00, // $
0x66,0x10,0x08,0x66,0x00,0x00, // %
0x36,0x49,0x49,0x7c,0x00,0x00, // &
0x03,0x00,0x00,0x00,0x00,0x00, // '
0x1c,0x22,0x41,0x00,0x00,0x00, // (
0x41,0x22,0x1c,0x00,0x00,0x00, // )
0x54,0x38,0x54,0x00,0x00,0x00, // *
0x10,0x38,0x10,0x00,0x00,0x00, // +
0x80,0x60,0x00,0x00,0x00,0x00, // ,
0x10,0x10,0x10,0x00,0x00,0x00, // -
0x60,0x60,0x00,0x00,0x00,0x00, // .
0x60,0x18,0x06,0x01,0x00,0x00, // /
0x3e,0x41,0x41,0x3e,0x00,0x00, // 0
0x42,0x7f,0x40,0x00,0x00,0x00, // 1
0x62,0x51,0x49,0x46,0x00,0x00, // 2
0x21,0x49,0x4d,0x33,0x00,0x00, // 3
0x18,0x16,0x11,0x7f,0x00,0x00, // 4
0x4f,0x49,0x49,0x31,0x00,0x00, // 5
0x3c,0x4a,0x49,0x30,0x00,0x00, // 6
0x01,0x61,0x19,0x07,0x00,0x00, // 7
0x36,0x49,0x49,0x36,0x00,0x00, // 8
0x06,0x49,0x29,0x1e,0x00,0x00, // 9
0x33,0x00,0x00,0x00,0x00,0x00, // :
0x80,0x6c,0x00,0x00,0x00,0x00, // ;
0x10,0x28,0x44,0x00,0x00,0x00, // <
0x28,0x28,0x28,0x00,0x00,0x00, // =
0x44,0x28,0x10,0x00,0x00,0x00, // >
0x02,0x51,0x09,0x06,0x00,0x00, // ?
0x3e,0x49,0x55,0x5e,0x00,0x00, // @
0x7e,0x09,0x09,0x7e,0x00,0x00, // A
0x7f,0x49,0x49,0x36,0x00,0x00, // B
0x3e,0x41,0x41,0x22,0x00,0x00, // C
0x7f,0x41,0x41,0x3e,0x00,0x00, // D
0x7f,0x49,0x49,0x41,0x00,0x00, // E
0x7f,0x09,0x09,0x01,0x00,0x00, // F
0x3e,0x41,0x49,0x79,0x00,0x00, // G
0x7f,0x08,0x08,0x7f,0x00,0x00, // H
0x41,0x7f,0x41,0x00,0x00,0x00, // I
0x30,0x40,0x40,0x3f,0x00,0x00, // J
0x7f,0x08,0x14,0x63,0x00,0x00, // K
0x7f,0x40,0x40,0x40,0x00,0x00, // L
0x7f,0x02,0x04,0x02,0x7f,0x00, // M
0x7f,0x02,0x04,0x7f,0x00,0x00, // N
0x3e,0x41,0x41,0x3e,0x00,0x00, // O
0x7f,0x09,0x09,0x06,0x00,0x00, // P
0x3e,0x41,0x21,0x5e,0x00,0x00, // Q
0x7f,0x09,0x19,0x66,0x00,0x00, // R
0x46,0x49,0x49,0x31,0x00,0x00, // S
0x01,0x01,0x7f,0x01,0x01,0x00, // T
0x3f,0x40,0x40,0x3f,0x00,0x00, // U
0x7f,0x40,0x20,0x1f,0x00,0x00, // V
0x3f,0x40,0x20,0x40,0x3f,0x00, // W
0x77,0x08,0x08,0x77,0x00,0x00, // X
0x47,0x48,0x48,0x3f,0x00,0x00, // Y
0x71,0x49,0x45,0x43,0x00,0x00, // Z
0x7f,0x41,0x00,0x00,0x00,0x00, // [
0x01,0x06,0x18,0x60,0x00,0x00, // "\"
0x41,0x7f,0x00,0x00,0x00,0x00, // ]
0x04,0x02,0x04,0x00,0x00,0x00, // ^
0x40,0x40,0x40,0x00,0x00,0x00, // _
0x01,0x01,0x00,0x00,0x00,0x00, // `
0x20,0x54,0x54,0x78,0x00,0x00, // a
0x7f,0x44,0x44,0x38,0x00,0x00, // b
0x38,0x44,0x44,0x28,0x00,0x00, // c
0x38,0x44,0x44,0x7f,0x00,0x00, // d
0x38,0x54,0x54,0x58,0x00,0x00, // e
0x7e,0x09,0x09,0x02,0x00,0x00, // f
0x18,0xa4,0xa4,0x7c,0x00,0x00, // g
0x7f,0x04,0x04,0x78,0x00,0x00, // h
0x04,0x7d,0x40,0x00,0x00,0x00, // i
0x60,0x80,0x80,0x7d,0x00,0x00, // j
0x7f,0x10,0x28,0x44,0x00,0x00, // k
0x01,0x7f,0x40,0x00,0x00,0x00, // l
0x7c,0x04,0x78,0x04,0x78,0x00, // m
0x7c,0x04,0x04,0x78,0x00,0x00, // n
0x38,0x44,0x44,0x38,0x00,0x00, // o
0xfc,0x24,0x24,0x18,0x00,0x00, // p
0x18,0x24,0x24,0xfc,0x00,0x00, // q
0x7c,0x08,0x04,0x04,0x00,0x00, // r
0x48,0x54,0x54,0x24,0x00,0x00, // s
0x3e,0x44,0x44,0x20,0x00,0x00, // t
0x3c,0x40,0x40,0x7c,0x00,0x00, // u
0x7c,0x40,0x20,0x1c,0x00,0x00, // v
0x3c,0x40,0x20,0x40,0x3c,0x00, // w
0x6c,0x10,0x10,0x6c,0x00,0x00, // x
0x1c,0xa0,0xa0,0x7c,0x00,0x00, // y
0x64,0x54,0x4c,0x00,0x00,0x00, // z
0x08,0x3e,0x41,0x00,0x00,0x00, // {
0x7f,0x00,0x00,0x00,0x00,0x00, // |
0x41,0x3e,0x08,0x00,0x00,0x00, // }
0x08,0x04,0x08,0x04,0x00,0x00, // ~
0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00, //
0x5f,0x00,0x00,0x00,0x00, // !
0x03,0x00,0x03,0x00,0x00, // "
0x28,0x7c,0x28,0x7c,0x28, // #
0x24,0x7a,0x2f,0x12,0x00, // $
0x66,0x10,0x08,0x66,0x00, // %
0x36,0x49,0x49,0x7c,0x00, // &
0x03,0x00,0x00,0x00,0x00, // '
0x1c,0x22,0x41,0x00,0x00, // (
0x41,0x22,0x1c,0x00,0x00, // )
0x54,0x38,0x54,0x00,0x00, // *
0x10,0x38,0x10,0x00,0x00, // +
0x80,0x60,0x00,0x00,0x00, // ,
0x10,0x10,0x10,0x00,0x00, // -
0x60,0x60,0x00,0x00,0x00, // .
0x60,0x18,0x06,0x01,0x00, // /
0x3e,0x41,0x41,0x3e,0x00, // 0
0x42,0x7f,0x40,0x00,0x00, // 1
0x62,0x51,0x49,0x46,0x00, // 2
0x21,0x49,0x4d,0x33,0x00, // 3
0x18,0x16,0x11,0x7f,0x00, // 4
0x4f,0x49,0x49,0x31,0x00, // 5
0x3c,0x4a,0x49,0x30,0x00, // 6
0x01,0x61,0x19,0x07,0x00, // 7
0x36,0x49,0x49,0x36,0x00, // 8
0x06,0x49,0x29,0x1e,0x00, // 9
0x33,0x00,0x00,0x00,0x00, // :
0x80,0x6c,0x00,0x00,0x00, // ;
0x10,0x28,0x44,0x00,0x00, // <
0x28,0x28,0x28,0x00,0x00, // =
0x44,0x28,0x10,0x00,0x00, // >
0x02,0x51,0x09,0x06,0x00, // ?
0x3e,0x49,0x55,0x5e,0x00, // @
0x7e,0x09,0x09,0x7e,0x00, // A
0x7f,0x49,0x49,0x36,0x00, // B
0x3e,0x41,0x41,0x22,0x00, // C
0x7f,0x41,0x41,0x3e,0x00, // D
0x7f,0x49,0x49,0x41,0x00, // E
0x7f,0x09,0x09,0x01,0x00, // F
0x3e,0x41,0x49,0x79,0x00, // G
0x7f,0x08,0x08,0x7f,0x00, // H
0x41,0x7f,0x41,0x00,0x00, // I
0x30,0x40,0x40,0x3f,0x00, // J
0x7f,0x08,0x14,0x63,0x00, // K
0x7f,0x40,0x40,0x40,0x00, // L
0x7f,0x02,0x04,0x02,0x7f, // M
0x7f,0x02,0x04,0x7f,0x00, // N
0x3e,0x41,0x41,0x3e,0x00, // O
0x7f,0x09,0x09,0x06,0x00, // P
0x3e,0x41,0x21,0x5e,0x00, // Q
0x7f,0x09,0x19,0x66,0x00, // R
0x46,0x49,0x49,0x31,0x00, // S
0x01,0x01,0x7f,0x01,0x01, // T
0x3f,0x40,0x40,0x3f,0x00, // U
0x7f,0x40,0x20,0x1f,0x00, // V
0x3f,0x40,0x20,0x40,0x3f, // W
0x77,0x08,0x08,0x77,0x00, // X
0x47,0x48,0x48,0x3f,0x00, // Y
0x71,0x49,0x45,0x43,0x00, // Z
0x7f,0x41,0x00,0x00,0x00, // [
0x01,0x06,0x18,0x60,0x00, // "\"
0x41,0x7f,0x00,0x00,0x00, // ]
0x04,0x02,0x04,0x00,0x00, // ^
0x40,0x40,0x40,0x00,0x00, // _
0x01,0x01,0x00,0x00,0x00, // `
0x20,0x54,0x54,0x78,0x00, // a
0x7f,0x44,0x44,0x38,0x00, // b
0x38,0x44,0x44,0x28,0x00, // c
0x38,0x44,0x44,0x7f,0x00, // d
0x38,0x54,0x54,0x58,0x00, // e
0x7e,0x09,0x09,0x02,0x00, // f
0x18,0xa4,0xa4,0x7c,0x00, // g
0x7f,0x04,0x04,0x78,0x00, // h
0x04,0x7d,0x40,0x00,0x00, // i
0x60,0x80,0x80,0x7d,0x00, // j
0x7f,0x10,0x28,0x44,0x00, // k
0x01,0x7f,0x40,0x00,0x00, // l
0x7c,0x04,0x78,0x04,0x78, // m
0x7c,0x04,0x04,0x78,0x00, // n
0x38,0x44,0x44,0x38,0x00, // o
0xfc,0x24,0x24,0x18,0x00, // p
0x18,0x24,0x24,0xfc,0x00, // q
0x7c,0x08,0x04,0x04,0x00, // r
0x48,0x54,0x54,0x24,0x00, // s
0x3e,0x44,0x44,0x20,0x00, // t
0x3c,0x40,0x40,0x7c,0x00, // u
0x7c,0x40,0x20,0x1c,0x00, // v
0x3c,0x40,0x20,0x40,0x3c, // w
0x6c,0x10,0x10,0x6c,0x00, // x
0x1c,0xa0,0xa0,0x7c,0x00, // y
0x64,0x54,0x4c,0x00,0x00, // z
0x08,0x3e,0x41,0x00,0x00, // {
0x7f,0x00,0x00,0x00,0x00, // |
0x41,0x3e,0x08,0x00,0x00, // }
0x08,0x04,0x08,0x04,0x00, // ~
0x00,0x00,0x00,0x00,0x00,
// Extra
0x7e,0x09,0x7f,0x49,0x49,0x00, // Æ
0x7e,0x24,0x24,0x18,0x00,0x00, // Þ
0x7e,0x09,0x49,0x36,0x00,0x00, // ß
0x20,0x54,0x78,0x54,0x58,0x00, // æ
0x7f,0x24,0x24,0x18,0x00,0x00, // þ
0x08,0x7e,0x49,0x41,0x00,0x00, // £
0x47,0x48,0x48,0x3f,0x00,0x00, // ¥
0x38,0x44,0x44,0x28,0x00,0x00, // ©
0x02,0x05,0x02,0x00,0x00,0x00, // °
0x7e,0x09,0x7f,0x49,0x49, // Æ
0x7e,0x24,0x24,0x18,0x00, // Þ
0x7e,0x09,0x49,0x36,0x00, // ß
0x20,0x54,0x78,0x54,0x58, // æ
0x7f,0x24,0x24,0x18,0x00, // þ
0x08,0x7e,0x49,0x41,0x00, // £
0x47,0x48,0x48,0x3f,0x00, // ¥
0x38,0x44,0x44,0x28,0x00, // ©
0x02,0x05,0x02,0x00,0x00, // °
// Accents + Offsets
// All chars are shifted 8px down into a 32 pixel canvas for combining with accents.
// Accent shift values (the first two numbers in each line below) move the accent down to meet them.
// These are the shift values for lower and UPPER case letters respectively.
6,4, 0x00,0x00,0x01,0x02,0x00,0x00, // Grave
6,4, 0x00,0x00,0x02,0x01,0x00,0x00, // Acute
6,4, 0x00,0x02,0x01,0x02,0x00,0x00, // Circumflex
6,4, 0x00,0x01,0x02,0x01,0x02,0x00, // Tilde
6,4, 0x00,0x01,0x00,0x01,0x00,0x00, // Diaresis
6,4, 0x00,0x02,0x05,0x02,0x00,0x00, // Ring Above
6,4, 0x00,0x80,0x40,0x00,0x00,0x00, // Stroke
9,9, 0x00,0x00,0xa0,0x40,0x00,0x00 // Cedilla
6,4, 0x00,0x00,0x01,0x02,0x00, // Grave
6,4, 0x00,0x00,0x02,0x01,0x00, // Acute
6,4, 0x00,0x02,0x01,0x02,0x00, // Circumflex
6,4, 0x00,0x01,0x02,0x01,0x02, // Tilde
6,4, 0x00,0x01,0x00,0x01,0x00, // Diaresis
6,4, 0x00,0x02,0x05,0x02,0x00, // Ring Above
6,4, 0x00,0x80,0x40,0x00,0x00, // Stroke
9,9, 0x00,0x00,0xa0,0x40,0x00 // Cedilla
}
};
8 changes: 4 additions & 4 deletions libraries/pico_graphics/pico_graphics.cpp
Expand Up @@ -144,11 +144,11 @@ namespace pimoroni {
}
}

void PicoGraphics::text(const std::string_view &t, const Point &p, int32_t wrap, float s, float a, uint8_t letter_spacing) {
void PicoGraphics::text(const std::string_view &t, const Point &p, int32_t wrap, float s, float a, uint8_t letter_spacing, bool fixed_width) {
if (bitmap_font) {
bitmap::text(bitmap_font, [this](int32_t x, int32_t y, int32_t w, int32_t h) {
rectangle(Rect(x, y, w, h));
}, t, p.x, p.y, wrap, std::max(1.0f, s), letter_spacing);
}, t, p.x, p.y, wrap, std::max(1.0f, s), letter_spacing, fixed_width);
return;
}

Expand All @@ -166,8 +166,8 @@ namespace pimoroni {
}
}

int32_t PicoGraphics::measure_text(const std::string_view &t, float s, uint8_t letter_spacing) {
if (bitmap_font) return bitmap::measure_text(bitmap_font, t, std::max(1.0f, s), letter_spacing);
int32_t PicoGraphics::measure_text(const std::string_view &t, float s, uint8_t letter_spacing, bool fixed_width) {
if (bitmap_font) return bitmap::measure_text(bitmap_font, t, std::max(1.0f, s), letter_spacing, fixed_width);
if (hershey_font) return hershey::measure_text(hershey_font, t, s);
return 0;
}
Expand Down
4 changes: 2 additions & 2 deletions libraries/pico_graphics/pico_graphics.hpp
Expand Up @@ -286,8 +286,8 @@ namespace pimoroni {
void rectangle(const Rect &r);
void circle(const Point &p, int32_t r);
void character(const char c, const Point &p, float s = 2.0f, float a = 0.0f);
void text(const std::string_view &t, const Point &p, int32_t wrap, float s = 2.0f, float a = 0.0f, uint8_t letter_spacing = 1);
int32_t measure_text(const std::string_view &t, float s = 2.0f, uint8_t letter_spacing = 1);
void text(const std::string_view &t, const Point &p, int32_t wrap, float s = 2.0f, float a = 0.0f, uint8_t letter_spacing = 1, bool fixed_width = false);
int32_t measure_text(const std::string_view &t, float s = 2.0f, uint8_t letter_spacing = 1, bool fixed_width = false);
void polygon(const std::vector<Point> &points);
void triangle(Point p1, Point p2, Point p3);
void line(Point p1, Point p2);
Expand Down

0 comments on commit fba7b53

Please sign in to comment.