From ccac202e26f4f0104c01c98af62db6d6822c2463 Mon Sep 17 00:00:00 2001 From: Jonathan Williamson Date: Thu, 21 Oct 2021 18:39:18 +0100 Subject: [PATCH] new text api with measurement function --- examples/audio/audio.cpp | 4 +- examples/shapes/shapes.cpp | 44 ++-- examples/sprites/sprites.cpp | 2 +- examples/text/text.cpp | 35 +-- libraries/assets.cpp | 398 +++++++++++++++++------------------ libraries/hardware.cpp | 12 +- libraries/picosystem.cmake | 1 + libraries/picosystem.cpp | 6 + libraries/picosystem.hpp | 50 +++-- libraries/primitives.cpp | 63 ------ libraries/state.cpp | 9 + libraries/text.cpp | 216 +++++++++++++++++++ libraries/utility.cpp | 37 +++- 13 files changed, 548 insertions(+), 329 deletions(-) create mode 100644 libraries/text.cpp diff --git a/examples/audio/audio.cpp b/examples/audio/audio.cpp index a7e819e..5eb46d7 100644 --- a/examples/audio/audio.cpp +++ b/examples/audio/audio.cpp @@ -136,10 +136,10 @@ void draw_dial(std::string name, int32_t x, int32_t y) { fcircle(dotx + x + 30, doty + y + 20, 3); // centre dial label and value - uint32_t lw = text_width(d->name); + uint32_t lw = 60; //text_width(d->name); text(d->name, x + 30 - (lw / 2), y + 60 - 22); std::string unit_label = str(d->value) + d->unit; - lw = text_width(unit_label); + lw = 20;//text_width(unit_label); text(unit_label, x + 30 - (lw / 2), y + 60 - 12); // if this is the active dial then highlight it diff --git a/examples/shapes/shapes.cpp b/examples/shapes/shapes.cpp index 163e5f5..247aaf8 100644 --- a/examples/shapes/shapes.cpp +++ b/examples/shapes/shapes.cpp @@ -10,14 +10,14 @@ struct shape_t { color_t p; }; -std::array shapes; +std::array shapes; void reset() { for(auto &s : shapes) { - s.x = std::rand() % 120; - s.y = std::rand() % 120; - s.w = std::rand() % 20; - s.h = std::rand() % 20; + s.x = std::rand() % SCREEN->w; + s.y = std::rand() % SCREEN->h; + s.w = std::rand() % 40; + s.h = std::rand() % 40; s.r = std::rand() % 360; s.p = hsv((std::rand() % 100) / 100.0f, 1.0f, 1.0f); } @@ -39,6 +39,7 @@ void init() { int32_t view = -1; + void update(uint32_t tick) { move(); @@ -53,8 +54,9 @@ void update(uint32_t tick) { } void label(std::string s) { - pen(0, 0, 0, 8); - frect(0, 11, 120, 15); + blend(ALPHA); + pen(1, 2, 3, 8); + frect(0, 11, SCREEN->w, 15); pen(0, 0, 0); text(s + ":", 3, 16); pen(15, 15, 15); @@ -62,9 +64,12 @@ void label(std::string s) { } void draw(uint32_t tick) { + uint32_t start = time_us(); pen(0, 0, 0); clear(); + blend(COPY); + switch(view) { case 0: { for(auto &s : shapes) {pen(s.p); frect(s.x, s.y, s.w, s.h);} @@ -78,7 +83,7 @@ void draw(uint32_t tick) { uint32_t i = 0; for(auto &s : shapes) { pen(s.p); - text(char((i++ % 96) + 32), s.x, s.y); + text(std::string(1, char((i++ % 96) + 32)), s.x, s.y); } label("Text"); } break; @@ -88,6 +93,7 @@ void draw(uint32_t tick) { label("Ellipses"); } break; case 4: { + blend(MASK); uint32_t i = 0; for(auto &s : shapes) {sprite(i++, s.x, s.y);} label("Sprites"); @@ -142,19 +148,25 @@ void draw(uint32_t tick) { } break; } + blend(ALPHA); + // draw title pen(15, 15, 15); - frect(0, 0, 120, 11); + frect(0, 0, SCREEN->w, 11); pen(0, 0, 0); text("Shapes Test", 2, 2); - pen(0, 0, 0, 8); - frect(0, 60, 120, 60); + // draw stats + pen(1, 2, 3, 8); + frect(0, SCREEN->h - 74, 80, 74); pen(15, 15, 15); - text("fps: " + str(stats.fps), 10, 70); - text("draw us: " + str(stats.draw_us), 10, 80); - text("update us: " + str(stats.update_us), 10, 90); - text("tick us: " + str(stats.tick_us), 10, 100); - text("idle: " + str(stats.idle) + "%", 10, 110); + cursor(2, SCREEN->h - 70); + text("shapes: " + str(shapes.size())); + text("fps: " + str(stats.fps)); + text("draw us: " + str(stats.draw_us)); + text("update us: " + str(stats.update_us)); + text("tick us: " + str(stats.tick_us)); + text("idle: " + str(stats.idle) + "%"); + text("flip us: " + str(stats.flip_us)); } \ No newline at end of file diff --git a/examples/sprites/sprites.cpp b/examples/sprites/sprites.cpp index 1cbe10f..4d9fd3e 100644 --- a/examples/sprites/sprites.cpp +++ b/examples/sprites/sprites.cpp @@ -120,7 +120,7 @@ void draw(uint32_t tick) { alpha(15); // centre name of weapon at bottom of screen - int label_width = text_width(weapons[selected].name); + int label_width = 40;//text_width(weapons[selected].name); pen(8, 11, 11); frect(60 - label_width / 2 - 3, 104 - 3, label_width + 6, 13); pen(0, 0, 0); diff --git a/examples/text/text.cpp b/examples/text/text.cpp index 909b971..960f6c3 100644 --- a/examples/text/text.cpp +++ b/examples/text/text.cpp @@ -5,40 +5,49 @@ using namespace picosystem; uint32_t wrap_width; void init() { + //int32_t w = -1, int32_t h = 8, int32_t s = 1, + // uint8_t *data = nullptr + // font(4, 6, 1); } void update(uint32_t tick) { - wrap_width = (fsin(time() / 1000.0f) * 40.0f) + 76; + wrap_width = (fsin(time() / 1000.0f) * 20.0f) + 96; } void draw(uint32_t tick) { - pen(0, 0, 0); + pen(0, 0, 0, 2); clear(); // draw title pen(15, 15, 15); frect(0, 0, 120, 11); pen(0, 0, 0); - text("Word Wrap Test", 2, 2); + text("Word wrap test", 2, 2); pen(15, 15, 15); text("Wrap at " + str(wrap_width) + " pixels:", 2, 15); // define a long message to word wrap - std::string message = "\ -THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG. \ -The Quick Brown Fox Jumped Over The Lazy Dog. \ -1234567890 ?><,.;'# []{}-=_+ \\|"; + std::string message = "\\rgbcccWe are just an advanced breed of \\rgbc0cmonkeys\\rgbccc on a minor planet of a \\rgbcc0very average star\\rgbccc. But we can \\rgb0ccunderstand\\rgbccc the Universe. That makes us something very special.\ + \n\ + \n\t\\rgbfff- Stephen Hawking"; + + int32_t w, h; + + uint32_t s = time_us(); + measure(message, w, h, wrap_width); + pen(0, 0, 0); + text(str(time_us() - s), 100, 2); - // given the message, and a width in pixels, the wrap() method will insert - // newline characters where needed (modifying the original string) - wrap(message, wrap_width); + // draw measured rectangle for text + pen(4, 4, 4, 4); + frect(2, 28, w, h); // draw wrapped text pen(8, 8, 8); - text(message, 2, 28); + text(message, 2, 28, wrap_width); - // draw green box to show wrap width + // draw green line to show wrap width pen(0, 12, 0); - rect(1, 27, wrap_width + 2, 92); + vline(wrap_width + 2, 27, 92); } \ No newline at end of file diff --git a/libraries/assets.cpp b/libraries/assets.cpp index 99c545d..559ad48 100644 --- a/libraries/assets.cpp +++ b/libraries/assets.cpp @@ -42,205 +42,205 @@ namespace picosystem { }; #ifndef NO_FONT - #ifdef PIXEL_DOUBLE - const uint8_t _default_font[96][9] = { - {0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {1, 0x80, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00}, - {3, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {3, 0xa0, 0xe0, 0xa0, 0xe0, 0xa0, 0x00, 0x00, 0x00}, - {3, 0x40, 0xe0, 0xc0, 0x60, 0xe0, 0x40, 0x00, 0x00}, - {3, 0xa0, 0x20, 0x40, 0x80, 0xa0, 0x00, 0x00, 0x00}, - {3, 0x60, 0x80, 0xe0, 0xc0, 0x60, 0x00, 0x00, 0x00}, - {2, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {2, 0x40, 0x80, 0x80, 0x80, 0x40, 0x00, 0x00, 0x00}, - {2, 0x80, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00}, - {3, 0x40, 0xe0, 0x40, 0xa0, 0x00, 0x00, 0x00, 0x00}, - {3, 0x00, 0x40, 0xe0, 0x40, 0x00, 0x00, 0x00, 0x00}, - {1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00}, - {3, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00}, - {1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00}, - {3, 0x20, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00}, - {3, 0x60, 0xa0, 0xa0, 0xa0, 0xc0, 0x00, 0x00, 0x00}, - {3, 0x40, 0xc0, 0x40, 0x40, 0xe0, 0x00, 0x00, 0x00}, - {3, 0xc0, 0x20, 0xe0, 0x80, 0xe0, 0x00, 0x00, 0x00}, - {3, 0xc0, 0x20, 0x60, 0x20, 0xe0, 0x00, 0x00, 0x00}, - {3, 0x80, 0xa0, 0xe0, 0x20, 0x20, 0x00, 0x00, 0x00}, - {3, 0xe0, 0x80, 0xe0, 0x20, 0xc0, 0x00, 0x00, 0x00}, - {3, 0x60, 0x80, 0xe0, 0xa0, 0xc0, 0x00, 0x00, 0x00}, - {3, 0xe0, 0x20, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00}, - {3, 0x60, 0xa0, 0xe0, 0xa0, 0xc0, 0x00, 0x00, 0x00}, - {3, 0x60, 0xa0, 0xe0, 0x20, 0xc0, 0x00, 0x00, 0x00}, - {1, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00}, - {1, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00}, - {2, 0x00, 0x40, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00}, - {3, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00}, - {2, 0x00, 0x80, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00}, - {3, 0xe0, 0x20, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00}, - {3, 0x60, 0xe0, 0xe0, 0x80, 0x60, 0x00, 0x00, 0x00}, - {3, 0x60, 0xa0, 0xe0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, - {3, 0xc0, 0xa0, 0xe0, 0xa0, 0xe0, 0x00, 0x00, 0x00}, - {3, 0x60, 0x80, 0x80, 0x80, 0x60, 0x00, 0x00, 0x00}, - {3, 0xc0, 0xa0, 0xa0, 0xa0, 0xe0, 0x00, 0x00, 0x00}, - {3, 0x60, 0x80, 0xc0, 0x80, 0xe0, 0x00, 0x00, 0x00}, - {3, 0x60, 0x80, 0xe0, 0x80, 0x80, 0x00, 0x00, 0x00}, - {3, 0x60, 0x80, 0x80, 0xa0, 0xe0, 0x00, 0x00, 0x00}, - {3, 0xa0, 0xa0, 0xe0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, - {3, 0xe0, 0x40, 0x40, 0x40, 0xe0, 0x00, 0x00, 0x00}, - {3, 0x60, 0x20, 0x20, 0x20, 0xc0, 0x00, 0x00, 0x00}, - {3, 0xa0, 0xa0, 0xc0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, - {3, 0x80, 0x80, 0x80, 0x80, 0xe0, 0x00, 0x00, 0x00}, - {3, 0xe0, 0xe0, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, - {3, 0xc0, 0xa0, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, - {3, 0x60, 0xa0, 0xa0, 0xa0, 0xc0, 0x00, 0x00, 0x00}, - {3, 0xc0, 0xa0, 0xe0, 0x80, 0x80, 0x00, 0x00, 0x00}, - {3, 0x60, 0xa0, 0xa0, 0xc0, 0x60, 0x00, 0x00, 0x00}, - {3, 0xc0, 0xa0, 0xc0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, - {3, 0x60, 0x80, 0x40, 0x20, 0xc0, 0x00, 0x00, 0x00}, - {3, 0xe0, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00}, - {3, 0xa0, 0xa0, 0xa0, 0xa0, 0xc0, 0x00, 0x00, 0x00}, - {3, 0xa0, 0xa0, 0xa0, 0xa0, 0x40, 0x00, 0x00, 0x00}, - {3, 0xa0, 0xa0, 0xa0, 0xe0, 0xe0, 0x00, 0x00, 0x00}, - {3, 0xa0, 0xa0, 0x40, 0xa0, 0xa0, 0x00, 0x00, 0x00}, - {3, 0xa0, 0xa0, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00}, - {3, 0xe0, 0x20, 0x40, 0x80, 0xe0, 0x00, 0x00, 0x00}, - {2, 0xc0, 0x80, 0x80, 0x80, 0xc0, 0x00, 0x00, 0x00}, - {3, 0x80, 0x80, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00}, - {2, 0xc0, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00, 0x00}, - {3, 0x00, 0x40, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00}, - {3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00}, - {2, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}, - {3, 0x00, 0x60, 0xa0, 0xa0, 0x60, 0x00, 0x00, 0x00}, - {3, 0x80, 0xc0, 0xa0, 0xa0, 0xc0, 0x00, 0x00, 0x00}, - {3, 0x00, 0x60, 0x80, 0x80, 0x60, 0x00, 0x00, 0x00}, - {3, 0x20, 0x60, 0xa0, 0xa0, 0x60, 0x00, 0x00, 0x00}, - {3, 0x00, 0x60, 0xa0, 0xc0, 0x60, 0x00, 0x00, 0x00}, - {2, 0x40, 0x80, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00}, - {3, 0x00, 0x60, 0xa0, 0xa0, 0x60, 0x20, 0x40, 0x00}, - {3, 0x80, 0xc0, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, - {1, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00}, - {2, 0x40, 0x00, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00}, - {3, 0x80, 0xa0, 0xc0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, - {2, 0x80, 0x80, 0x80, 0x80, 0x40, 0x00, 0x00, 0x00}, - {3, 0x00, 0xe0, 0xe0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, - {3, 0x00, 0xc0, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, - {3, 0x00, 0x60, 0xa0, 0xa0, 0xc0, 0x00, 0x00, 0x00}, - {3, 0x00, 0xc0, 0xa0, 0xa0, 0xc0, 0x80, 0x80, 0x00}, - {3, 0x00, 0x60, 0xa0, 0xa0, 0x60, 0x20, 0x20, 0x00}, - {2, 0x00, 0x40, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00}, - {3, 0x00, 0x60, 0x80, 0x20, 0xc0, 0x00, 0x00, 0x00}, - {2, 0x80, 0xc0, 0x80, 0x80, 0x40, 0x00, 0x00, 0x00}, - {3, 0x00, 0xa0, 0xa0, 0xa0, 0xc0, 0x00, 0x00, 0x00}, - {3, 0x00, 0xa0, 0xa0, 0xa0, 0x40, 0x00, 0x00, 0x00}, - {3, 0x00, 0xa0, 0xa0, 0xe0, 0xe0, 0x00, 0x00, 0x00}, - {3, 0x00, 0xa0, 0x40, 0xa0, 0xa0, 0x00, 0x00, 0x00}, - {3, 0x00, 0xa0, 0xa0, 0xa0, 0x60, 0x20, 0x40, 0x00}, - {3, 0x00, 0xe0, 0x20, 0x80, 0xe0, 0x00, 0x00, 0x00}, - {3, 0x60, 0x40, 0xc0, 0x40, 0x60, 0x00, 0x00, 0x00}, - {1, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00}, - {3, 0xc0, 0x40, 0x60, 0x40, 0xc0, 0x00, 0x00, 0x00}, - {3, 0x00, 0x20, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00}, - {0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, -}; - #else - const uint8_t _default_font[96][9] = { - {1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {1, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x00}, - {5, 0x90, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {6, 0x00, 0x48, 0xfc, 0x48, 0x48, 0xfc, 0x48, 0x00}, - {5, 0x00, 0x20, 0x78, 0xa0, 0x70, 0x28, 0xf0, 0x20}, - {6, 0x00, 0x84, 0x08, 0x10, 0x20, 0x40, 0x84, 0x00}, - {6, 0x00, 0x70, 0x88, 0x70, 0x94, 0x88, 0x74, 0x00}, - {1, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00}, - {2, 0x00, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x00}, - {2, 0x00, 0x80, 0x40, 0x40, 0x40, 0x40, 0x80, 0x00}, - {5, 0x00, 0x20, 0x20, 0xf8, 0x20, 0x50, 0x88, 0x00}, - {5, 0x00, 0x00, 0x20, 0x20, 0xf8, 0x20, 0x20, 0x00}, - {1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80}, - {5, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00}, - {1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00}, - {6, 0x00, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00}, - {5, 0x70, 0x88, 0x98, 0xa8, 0xc8, 0x88, 0x70, 0x00}, - {3, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x40, 0xe0, 0x00}, - {4, 0x60, 0x90, 0x10, 0x60, 0x80, 0x80, 0xf0, 0x00}, - {4, 0x60, 0x90, 0x10, 0x20, 0x10, 0x90, 0x60, 0x00}, - {4, 0x80, 0x80, 0xa0, 0xa0, 0xf0, 0x20, 0x20, 0x00}, - {4, 0xf0, 0x80, 0x80, 0xe0, 0x10, 0x90, 0x60, 0x00}, - {4, 0x30, 0x40, 0x80, 0xe0, 0x90, 0x90, 0x60, 0x00}, - {4, 0xf0, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x00}, - {4, 0x60, 0x90, 0x90, 0x60, 0x90, 0x90, 0x60, 0x00}, - {4, 0x60, 0x90, 0x90, 0x70, 0x10, 0x90, 0x60, 0x00}, - {1, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00}, - {1, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00}, - {3, 0x00, 0x00, 0x20, 0x40, 0x80, 0x40, 0x20, 0x00}, - {5, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00}, - {3, 0x00, 0x00, 0x80, 0x40, 0x20, 0x40, 0x80, 0x00}, - {5, 0x00, 0x70, 0x88, 0x08, 0x30, 0x20, 0x00, 0x20}, - {5, 0x00, 0x70, 0x88, 0xb8, 0xb8, 0x80, 0x70, 0x00}, - {5, 0x70, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88, 0x00}, - {5, 0xf0, 0x88, 0x88, 0xf0, 0x88, 0x88, 0xf0, 0x00}, - {5, 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70, 0x00}, - {5, 0xf0, 0x88, 0x88, 0x88, 0x88, 0x88, 0xf0, 0x00}, - {5, 0xf8, 0x80, 0x80, 0xf8, 0x80, 0x80, 0xf8, 0x00}, - {5, 0xf8, 0x80, 0x80, 0xf8, 0x80, 0x80, 0x80, 0x00}, - {5, 0x70, 0x88, 0x88, 0x80, 0x98, 0x88, 0x78, 0x00}, - {5, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88, 0x88, 0x00}, - {5, 0xf8, 0x20, 0x20, 0x20, 0x20, 0x20, 0xf8, 0x00}, - {5, 0x78, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60, 0x00}, - {5, 0x88, 0x88, 0x90, 0xe0, 0x90, 0x88, 0x88, 0x00}, - {5, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xf8, 0x00}, - {5, 0x88, 0xd8, 0xa8, 0x88, 0x88, 0x88, 0x88, 0x00}, - {5, 0x88, 0xc8, 0xa8, 0x98, 0x88, 0x88, 0x88, 0x00}, - {5, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00}, - {5, 0xf0, 0x88, 0x88, 0x88, 0xf0, 0x80, 0x80, 0x00}, - {5, 0x70, 0x88, 0x88, 0x88, 0xa8, 0x98, 0x70, 0x00}, - {5, 0xf0, 0x88, 0x88, 0x88, 0xf0, 0x88, 0x88, 0x00}, - {5, 0x70, 0x88, 0x80, 0x70, 0x08, 0x88, 0x70, 0x00}, - {5, 0xf8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00}, - {5, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00}, - {5, 0x88, 0x88, 0x88, 0x88, 0x88, 0x50, 0x20, 0x00}, - {5, 0x88, 0x88, 0x88, 0x88, 0xa8, 0xd8, 0x88, 0x00}, - {5, 0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88, 0x00}, - {5, 0x88, 0x88, 0x88, 0x50, 0x20, 0x20, 0x20, 0x00}, - {5, 0xf8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xf8, 0x00}, - {3, 0xe0, 0x80, 0x80, 0x80, 0x80, 0x80, 0xe0, 0x00}, - {6, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00}, - {3, 0xe0, 0x20, 0x20, 0x20, 0x20, 0x20, 0xe0, 0x00}, - {5, 0x00, 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00}, - {8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}, - {2, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}, - {5, 0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0xf8, 0x00}, - {5, 0x00, 0x80, 0xf0, 0x88, 0x88, 0x88, 0xf0, 0x00}, - {4, 0x00, 0x00, 0x70, 0x80, 0x80, 0x80, 0x70, 0x00}, - {5, 0x00, 0x08, 0x78, 0x88, 0x88, 0x88, 0x78, 0x00}, - {5, 0x00, 0x00, 0x70, 0x88, 0xf8, 0x80, 0x78, 0x00}, - {4, 0x00, 0x30, 0x40, 0xf0, 0x40, 0x40, 0x40, 0x00}, - {5, 0x00, 0x00, 0x78, 0x88, 0x88, 0x78, 0x08, 0x70}, - {5, 0x00, 0x80, 0xf0, 0x88, 0x88, 0x88, 0x88, 0x00}, - {2, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x40, 0x00}, - {4, 0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x90, 0x60}, - {4, 0x00, 0x80, 0x90, 0xa0, 0xc0, 0xa0, 0x90, 0x00}, - {2, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40, 0x00}, - {5, 0x00, 0x00, 0xd0, 0xa8, 0x88, 0x88, 0x88, 0x00}, - {5, 0x00, 0x00, 0xb0, 0xc8, 0x88, 0x88, 0x88, 0x00}, - {5, 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70, 0x00}, - {5, 0x00, 0x00, 0xf0, 0x88, 0x88, 0x88, 0xf0, 0x80}, - {5, 0x00, 0x00, 0x78, 0x88, 0x88, 0x88, 0x78, 0x08}, - {5, 0x00, 0x00, 0xf0, 0x88, 0x80, 0x80, 0x80, 0x00}, - {4, 0x00, 0x00, 0x70, 0x80, 0x60, 0x10, 0xe0, 0x00}, - {3, 0x00, 0x40, 0xe0, 0x40, 0x40, 0x40, 0x20, 0x00}, - {5, 0x00, 0x00, 0x88, 0x88, 0x88, 0x98, 0x68, 0x00}, - {5, 0x00, 0x00, 0x88, 0x88, 0x88, 0x50, 0x20, 0x00}, - {5, 0x00, 0x00, 0x88, 0x88, 0x88, 0xa8, 0x58, 0x00}, - {5, 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 0x00}, - {5, 0x00, 0x00, 0x88, 0x88, 0x88, 0x78, 0x08, 0x70}, - {5, 0x00, 0x00, 0xf8, 0x10, 0x20, 0x40, 0xf8, 0x00}, - {3, 0x20, 0x40, 0x40, 0x80, 0x40, 0x40, 0x20, 0x00}, - {1, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}, - {3, 0x80, 0x40, 0x40, 0x20, 0x40, 0x40, 0x80, 0x00}, - {6, 0x00, 0x00, 0x64, 0x98, 0x00, 0x00, 0x00, 0x00}, - {0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - }; - #endif + #ifdef PIXEL_DOUBLE + const uint8_t _default_font[96][9] = { + {1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {1, 0x80, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00}, + {3, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {3, 0xa0, 0xe0, 0xa0, 0xe0, 0xa0, 0x00, 0x00, 0x00}, + {3, 0x40, 0xe0, 0xc0, 0x60, 0xe0, 0x40, 0x00, 0x00}, + {3, 0xa0, 0x20, 0x40, 0x80, 0xa0, 0x00, 0x00, 0x00}, + {3, 0x60, 0x80, 0xe0, 0xc0, 0x60, 0x00, 0x00, 0x00}, + {2, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {2, 0x40, 0x80, 0x80, 0x80, 0x40, 0x00, 0x00, 0x00}, + {2, 0x80, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00}, + {3, 0x40, 0xe0, 0x40, 0xa0, 0x00, 0x00, 0x00, 0x00}, + {3, 0x00, 0x40, 0xe0, 0x40, 0x00, 0x00, 0x00, 0x00}, + {1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00}, + {3, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00}, + {1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00}, + {3, 0x20, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00}, + {3, 0x60, 0xa0, 0xa0, 0xa0, 0xc0, 0x00, 0x00, 0x00}, + {3, 0x40, 0xc0, 0x40, 0x40, 0xe0, 0x00, 0x00, 0x00}, + {3, 0xc0, 0x20, 0xe0, 0x80, 0xe0, 0x00, 0x00, 0x00}, + {3, 0xc0, 0x20, 0x60, 0x20, 0xe0, 0x00, 0x00, 0x00}, + {3, 0x80, 0xa0, 0xe0, 0x20, 0x20, 0x00, 0x00, 0x00}, + {3, 0xe0, 0x80, 0xe0, 0x20, 0xc0, 0x00, 0x00, 0x00}, + {3, 0x60, 0x80, 0xe0, 0xa0, 0xc0, 0x00, 0x00, 0x00}, + {3, 0xe0, 0x20, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00}, + {3, 0x60, 0xa0, 0xe0, 0xa0, 0xc0, 0x00, 0x00, 0x00}, + {3, 0x60, 0xa0, 0xe0, 0x20, 0xc0, 0x00, 0x00, 0x00}, + {1, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00}, + {1, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00}, + {2, 0x00, 0x40, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00}, + {3, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00}, + {2, 0x00, 0x80, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00}, + {3, 0xe0, 0x20, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00}, + {3, 0x60, 0xe0, 0xe0, 0x80, 0x60, 0x00, 0x00, 0x00}, + {3, 0x60, 0xa0, 0xe0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, + {3, 0xc0, 0xa0, 0xe0, 0xa0, 0xe0, 0x00, 0x00, 0x00}, + {3, 0x60, 0x80, 0x80, 0x80, 0x60, 0x00, 0x00, 0x00}, + {3, 0xc0, 0xa0, 0xa0, 0xa0, 0xe0, 0x00, 0x00, 0x00}, + {3, 0x60, 0x80, 0xc0, 0x80, 0xe0, 0x00, 0x00, 0x00}, + {3, 0x60, 0x80, 0xe0, 0x80, 0x80, 0x00, 0x00, 0x00}, + {3, 0x60, 0x80, 0x80, 0xa0, 0xe0, 0x00, 0x00, 0x00}, + {3, 0xa0, 0xa0, 0xe0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, + {3, 0xe0, 0x40, 0x40, 0x40, 0xe0, 0x00, 0x00, 0x00}, + {3, 0x60, 0x20, 0x20, 0x20, 0xc0, 0x00, 0x00, 0x00}, + {3, 0xa0, 0xa0, 0xc0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, + {3, 0x80, 0x80, 0x80, 0x80, 0xe0, 0x00, 0x00, 0x00}, + {3, 0xe0, 0xe0, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, + {3, 0xc0, 0xa0, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, + {3, 0x60, 0xa0, 0xa0, 0xa0, 0xc0, 0x00, 0x00, 0x00}, + {3, 0xc0, 0xa0, 0xe0, 0x80, 0x80, 0x00, 0x00, 0x00}, + {3, 0x60, 0xa0, 0xa0, 0xc0, 0x60, 0x00, 0x00, 0x00}, + {3, 0xc0, 0xa0, 0xc0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, + {3, 0x60, 0x80, 0x40, 0x20, 0xc0, 0x00, 0x00, 0x00}, + {3, 0xe0, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00}, + {3, 0xa0, 0xa0, 0xa0, 0xa0, 0xc0, 0x00, 0x00, 0x00}, + {3, 0xa0, 0xa0, 0xa0, 0xa0, 0x40, 0x00, 0x00, 0x00}, + {3, 0xa0, 0xa0, 0xa0, 0xe0, 0xe0, 0x00, 0x00, 0x00}, + {3, 0xa0, 0xa0, 0x40, 0xa0, 0xa0, 0x00, 0x00, 0x00}, + {3, 0xa0, 0xa0, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00}, + {3, 0xe0, 0x20, 0x40, 0x80, 0xe0, 0x00, 0x00, 0x00}, + {2, 0xc0, 0x80, 0x80, 0x80, 0xc0, 0x00, 0x00, 0x00}, + {3, 0x80, 0x80, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00}, + {2, 0xc0, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00, 0x00}, + {3, 0x00, 0x40, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00}, + {3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00}, + {2, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}, + {3, 0x00, 0x60, 0xa0, 0xa0, 0x60, 0x00, 0x00, 0x00}, + {3, 0x80, 0xc0, 0xa0, 0xa0, 0xc0, 0x00, 0x00, 0x00}, + {3, 0x00, 0x60, 0x80, 0x80, 0x60, 0x00, 0x00, 0x00}, + {3, 0x20, 0x60, 0xa0, 0xa0, 0x60, 0x00, 0x00, 0x00}, + {3, 0x00, 0x60, 0xa0, 0xc0, 0x60, 0x00, 0x00, 0x00}, + {2, 0x40, 0x80, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00}, + {3, 0x00, 0x60, 0xa0, 0xa0, 0x60, 0x20, 0x40, 0x00}, + {3, 0x80, 0xc0, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, + {1, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00}, + {2, 0x40, 0x00, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00}, + {3, 0x80, 0xa0, 0xc0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, + {2, 0x80, 0x80, 0x80, 0x80, 0x40, 0x00, 0x00, 0x00}, + {3, 0x00, 0xe0, 0xe0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, + {3, 0x00, 0xc0, 0xa0, 0xa0, 0xa0, 0x00, 0x00, 0x00}, + {3, 0x00, 0x60, 0xa0, 0xa0, 0xc0, 0x00, 0x00, 0x00}, + {3, 0x00, 0xc0, 0xa0, 0xa0, 0xc0, 0x80, 0x80, 0x00}, + {3, 0x00, 0x60, 0xa0, 0xa0, 0x60, 0x20, 0x20, 0x00}, + {2, 0x00, 0x40, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00}, + {3, 0x00, 0x60, 0x80, 0x20, 0xc0, 0x00, 0x00, 0x00}, + {2, 0x80, 0xc0, 0x80, 0x80, 0x40, 0x00, 0x00, 0x00}, + {3, 0x00, 0xa0, 0xa0, 0xa0, 0xc0, 0x00, 0x00, 0x00}, + {3, 0x00, 0xa0, 0xa0, 0xa0, 0x40, 0x00, 0x00, 0x00}, + {3, 0x00, 0xa0, 0xa0, 0xe0, 0xe0, 0x00, 0x00, 0x00}, + {3, 0x00, 0xa0, 0x40, 0xa0, 0xa0, 0x00, 0x00, 0x00}, + {3, 0x00, 0xa0, 0xa0, 0xa0, 0x60, 0x20, 0x40, 0x00}, + {3, 0x00, 0xe0, 0x20, 0x80, 0xe0, 0x00, 0x00, 0x00}, + {3, 0x60, 0x40, 0xc0, 0x40, 0x60, 0x00, 0x00, 0x00}, + {1, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00}, + {3, 0xc0, 0x40, 0x60, 0x40, 0xc0, 0x00, 0x00, 0x00}, + {3, 0x00, 0x20, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00}, + {0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + }; + #else + const uint8_t _default_font[96][9] = { + {1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {1, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x00}, + {5, 0x90, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {6, 0x00, 0x48, 0xfc, 0x48, 0x48, 0xfc, 0x48, 0x00}, + {5, 0x00, 0x20, 0x78, 0xa0, 0x70, 0x28, 0xf0, 0x20}, + {6, 0x00, 0x84, 0x08, 0x10, 0x20, 0x40, 0x84, 0x00}, + {6, 0x00, 0x70, 0x88, 0x70, 0x94, 0x88, 0x74, 0x00}, + {1, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00}, + {2, 0x00, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x00}, + {2, 0x00, 0x80, 0x40, 0x40, 0x40, 0x40, 0x80, 0x00}, + {5, 0x00, 0x20, 0x20, 0xf8, 0x20, 0x50, 0x88, 0x00}, + {5, 0x00, 0x00, 0x20, 0x20, 0xf8, 0x20, 0x20, 0x00}, + {1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80}, + {5, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00}, + {1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00}, + {6, 0x00, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00}, + {5, 0x70, 0x88, 0x98, 0xa8, 0xc8, 0x88, 0x70, 0x00}, + {3, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x40, 0xe0, 0x00}, + {4, 0x60, 0x90, 0x10, 0x60, 0x80, 0x80, 0xf0, 0x00}, + {4, 0x60, 0x90, 0x10, 0x20, 0x10, 0x90, 0x60, 0x00}, + {4, 0x80, 0x80, 0xa0, 0xa0, 0xf0, 0x20, 0x20, 0x00}, + {4, 0xf0, 0x80, 0x80, 0xe0, 0x10, 0x90, 0x60, 0x00}, + {4, 0x30, 0x40, 0x80, 0xe0, 0x90, 0x90, 0x60, 0x00}, + {4, 0xf0, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x00}, + {4, 0x60, 0x90, 0x90, 0x60, 0x90, 0x90, 0x60, 0x00}, + {4, 0x60, 0x90, 0x90, 0x70, 0x10, 0x90, 0x60, 0x00}, + {1, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00}, + {1, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00}, + {3, 0x00, 0x00, 0x20, 0x40, 0x80, 0x40, 0x20, 0x00}, + {5, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00}, + {3, 0x00, 0x00, 0x80, 0x40, 0x20, 0x40, 0x80, 0x00}, + {5, 0x00, 0x70, 0x88, 0x08, 0x30, 0x20, 0x00, 0x20}, + {5, 0x00, 0x70, 0x88, 0xb8, 0xb8, 0x80, 0x70, 0x00}, + {5, 0x70, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88, 0x00}, + {5, 0xf0, 0x88, 0x88, 0xf0, 0x88, 0x88, 0xf0, 0x00}, + {5, 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70, 0x00}, + {5, 0xf0, 0x88, 0x88, 0x88, 0x88, 0x88, 0xf0, 0x00}, + {5, 0xf8, 0x80, 0x80, 0xf8, 0x80, 0x80, 0xf8, 0x00}, + {5, 0xf8, 0x80, 0x80, 0xf8, 0x80, 0x80, 0x80, 0x00}, + {5, 0x70, 0x88, 0x88, 0x80, 0x98, 0x88, 0x78, 0x00}, + {5, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88, 0x88, 0x00}, + {5, 0xf8, 0x20, 0x20, 0x20, 0x20, 0x20, 0xf8, 0x00}, + {5, 0x78, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60, 0x00}, + {5, 0x88, 0x88, 0x90, 0xe0, 0x90, 0x88, 0x88, 0x00}, + {5, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xf8, 0x00}, + {5, 0x88, 0xd8, 0xa8, 0x88, 0x88, 0x88, 0x88, 0x00}, + {5, 0x88, 0xc8, 0xa8, 0x98, 0x88, 0x88, 0x88, 0x00}, + {5, 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00}, + {5, 0xf0, 0x88, 0x88, 0x88, 0xf0, 0x80, 0x80, 0x00}, + {5, 0x70, 0x88, 0x88, 0x88, 0xa8, 0x98, 0x70, 0x00}, + {5, 0xf0, 0x88, 0x88, 0x88, 0xf0, 0x88, 0x88, 0x00}, + {5, 0x70, 0x88, 0x80, 0x70, 0x08, 0x88, 0x70, 0x00}, + {5, 0xf8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00}, + {5, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00}, + {5, 0x88, 0x88, 0x88, 0x88, 0x88, 0x50, 0x20, 0x00}, + {5, 0x88, 0x88, 0x88, 0x88, 0xa8, 0xd8, 0x88, 0x00}, + {5, 0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88, 0x00}, + {5, 0x88, 0x88, 0x88, 0x50, 0x20, 0x20, 0x20, 0x00}, + {5, 0xf8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xf8, 0x00}, + {3, 0xe0, 0x80, 0x80, 0x80, 0x80, 0x80, 0xe0, 0x00}, + {6, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00}, + {3, 0xe0, 0x20, 0x20, 0x20, 0x20, 0x20, 0xe0, 0x00}, + {5, 0x00, 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00}, + {8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}, + {2, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}, + {5, 0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0xf8, 0x00}, + {5, 0x00, 0x80, 0xf0, 0x88, 0x88, 0x88, 0xf0, 0x00}, + {4, 0x00, 0x00, 0x70, 0x80, 0x80, 0x80, 0x70, 0x00}, + {5, 0x00, 0x08, 0x78, 0x88, 0x88, 0x88, 0x78, 0x00}, + {5, 0x00, 0x00, 0x70, 0x88, 0xf8, 0x80, 0x78, 0x00}, + {4, 0x00, 0x30, 0x40, 0xf0, 0x40, 0x40, 0x40, 0x00}, + {5, 0x00, 0x00, 0x78, 0x88, 0x88, 0x78, 0x08, 0x70}, + {5, 0x00, 0x80, 0xf0, 0x88, 0x88, 0x88, 0x88, 0x00}, + {2, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x40, 0x00}, + {4, 0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x90, 0x60}, + {4, 0x00, 0x80, 0x90, 0xa0, 0xc0, 0xa0, 0x90, 0x00}, + {2, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40, 0x00}, + {5, 0x00, 0x00, 0xd0, 0xa8, 0x88, 0x88, 0x88, 0x00}, + {5, 0x00, 0x00, 0xb0, 0xc8, 0x88, 0x88, 0x88, 0x00}, + {5, 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70, 0x00}, + {5, 0x00, 0x00, 0xf0, 0x88, 0x88, 0x88, 0xf0, 0x80}, + {5, 0x00, 0x00, 0x78, 0x88, 0x88, 0x88, 0x78, 0x08}, + {5, 0x00, 0x00, 0xf0, 0x88, 0x80, 0x80, 0x80, 0x00}, + {4, 0x00, 0x00, 0x70, 0x80, 0x60, 0x10, 0xe0, 0x00}, + {3, 0x00, 0x40, 0xe0, 0x40, 0x40, 0x40, 0x20, 0x00}, + {5, 0x00, 0x00, 0x88, 0x88, 0x88, 0x98, 0x68, 0x00}, + {5, 0x00, 0x00, 0x88, 0x88, 0x88, 0x50, 0x20, 0x00}, + {5, 0x00, 0x00, 0x88, 0x88, 0x88, 0xa8, 0x58, 0x00}, + {5, 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 0x00}, + {5, 0x00, 0x00, 0x88, 0x88, 0x88, 0x78, 0x08, 0x70}, + {5, 0x00, 0x00, 0xf8, 0x10, 0x20, 0x40, 0xf8, 0x00}, + {3, 0x20, 0x40, 0x40, 0x80, 0x40, 0x40, 0x20, 0x00}, + {1, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}, + {3, 0x80, 0x40, 0x40, 0x20, 0x40, 0x40, 0x80, 0x00}, + {6, 0x00, 0x00, 0x64, 0x98, 0x00, 0x00, 0x00, 0x00}, + {0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + }; + #endif #endif // https://github.com/32blit/32blit-sdk/blob/master/assets/s4m_ur4i-dingbads.png diff --git a/libraries/hardware.cpp b/libraries/hardware.cpp index f97028f..c2484c5 100644 --- a/libraries/hardware.cpp +++ b/libraries/hardware.cpp @@ -94,10 +94,6 @@ namespace picosystem { sleep_ms(d); } - void sleep_us(uint32_t d) { - ::sleep_us(d); - } - uint32_t battery() { // convert to 0..1 range for battery between 2.8v and 4.1v float c = (_battery_voltage() - 2.8f) / 1.3f; @@ -347,11 +343,11 @@ namespace picosystem { FRMCTR1 = 0xB1, FRMCTR2 = 0xB2, GMCTRP1 = 0xE0, GMCTRN1 = 0xE1, INVOFF = 0x20, SLPOUT = 0x11, DISPON = 0x29, GAMSET = 0x26, DISPOFF = 0x28, RAMWR = 0x2C, INVON = 0x21, CASET = 0x2A, - RASET = 0x2B + RASET = 0x2B, STE = 0x44 }; _screen_command(SWRESET); - sleep_ms(150); + sleep_ms(5); _screen_command(MADCTL, 1, "\x04"); _screen_command(TEON, 1, "\x00"); _screen_command(FRMCTR2, 5, "\x0C\x0C\x00\x33\x33"); @@ -365,13 +361,13 @@ namespace picosystem { _screen_command(VRHS, 1, "\x12"); _screen_command(VDVS, 1, "\x20"); _screen_command(PWRCTRL1, 2, "\xA4\xA1"); - _screen_command(FRCTRL2, 1, "\x15"); + _screen_command(FRCTRL2, 1, "\x1E"); _screen_command(GMCTRP1, 14, "\xD0\x04\x0D\x11\x13\x2B\x3F\x54\x4C\x18\x0D\x0B\x1F\x23"); _screen_command(GMCTRN1, 14, "\xD0\x04\x0C\x11\x13\x2C\x3F\x44\x51\x2F\x1F\x1F\x20\x23"); _screen_command(INVON); + sleep_ms(115); _screen_command(SLPOUT); _screen_command(DISPON); - sleep_ms(100); _screen_command(CASET, 4, "\x00\x00\x00\xef"); _screen_command(RASET, 4, "\x00\x00\x00\xef"); _screen_command(RAMWR); diff --git a/libraries/picosystem.cmake b/libraries/picosystem.cmake index dfaad1d..854c791 100644 --- a/libraries/picosystem.cmake +++ b/libraries/picosystem.cmake @@ -9,6 +9,7 @@ target_sources(picosystem INTERFACE ${CMAKE_CURRENT_LIST_DIR}/audio.cpp ${CMAKE_CURRENT_LIST_DIR}/state.cpp ${CMAKE_CURRENT_LIST_DIR}/primitives.cpp + ${CMAKE_CURRENT_LIST_DIR}/text.cpp ${CMAKE_CURRENT_LIST_DIR}/utility.cpp ${CMAKE_CURRENT_LIST_DIR}/hardware.cpp ${CMAKE_CURRENT_LIST_DIR}/assets.cpp diff --git a/libraries/picosystem.cpp b/libraries/picosystem.cpp index 01d09c1..b4a3cdc 100644 --- a/libraries/picosystem.cpp +++ b/libraries/picosystem.cpp @@ -14,6 +14,9 @@ namespace picosystem { uint8_t _a = 15; int32_t _tx = 0, _ty = 0; + int32_t _tlh = 8, _tls = 1; + int32_t _tlw = -1; + int32_t _camx = 0, _camy = 0; uint32_t _io = 0, _lio = 0; blend_func_t _bf = ALPHA; @@ -101,6 +104,7 @@ int main() { uint32_t tick = 0; uint32_t last_frame_ms = 0; + uint32_t start_flip = 0; _io = _gpio_get(); @@ -121,6 +125,7 @@ int main() { uint32_t wait_us = 0; uint32_t start_wait_flip_us = time_us(); while(_is_flipping()) {} + stats.flip_us = time_us() - start_flip; wait_us += time_us() - start_wait_flip_us; // call user render function to draw world @@ -135,6 +140,7 @@ int main() { wait_us += time_us() - start_wait_vsync_us; // flip the framebuffer to the screen + start_flip = time_us(); _flip(); tick++; diff --git a/libraries/picosystem.hpp b/libraries/picosystem.hpp index a4b2378..cb50389 100644 --- a/libraries/picosystem.hpp +++ b/libraries/picosystem.hpp @@ -26,6 +26,7 @@ namespace picosystem { uint32_t tick_us; // last full tick time in microseconds uint32_t update_us; // last update() call time in microseconds uint32_t draw_us; // last draw() call time in microseconds + uint32_t flip_us; // last flip time in microseconds }; extern stat_t stats; @@ -52,18 +53,20 @@ namespace picosystem { color_t* dest, uint32_t count); // drawing state - extern color_t _pen; // pen - extern uint8_t _a; // global alpha - extern int32_t _cx, _cy, _cw, _ch; // clip rect - extern int32_t _tx, _ty; // text cursor position - extern uint32_t _io, _lio; // io state and last io state - extern int32_t _camx, _camy; // camera - extern blend_func_t _bf; // blend function - extern buffer_t * SCREEN; // framebuffer - extern buffer_t *_dt; // drawing target - extern buffer_t * SPRITESHEET; // inbuilt spritesheet - extern buffer_t *_ss; // sprite sheet - extern uint8_t *_font; // font data + extern color_t _pen; // pen + extern uint8_t _a; // global alpha + extern int32_t _cx, _cy, _cw, _ch; // clip rect + extern int32_t _tx, _ty; // text cursor position + extern int32_t _tlh, _tls; // text letter height and spacing + extern int32_t _tlw; // text letter width (-1: variable) + extern uint32_t _io, _lio; // io state and last io state + extern int32_t _camx, _camy; // camera + extern blend_func_t _bf; // blend function + extern buffer_t * SCREEN; // framebuffer + extern buffer_t *_dt; // drawing target + extern buffer_t * SPRITESHEET; // inbuilt spritesheet + extern buffer_t *_ss; // sprite sheet + extern uint8_t *_font; // font data // audio state extern voice_t _v; // current voice @@ -91,6 +94,9 @@ namespace picosystem { void spritesheet(buffer_t *ss); void cursor(); void cursor(int32_t x, int32_t y); + void font( + int32_t w = -1, int32_t h = 8, int32_t s = 1, + uint8_t *data = nullptr); // primitives void clear(); @@ -124,8 +130,13 @@ namespace picosystem { int32_t dw, int32_t dh); void text(const char &c, int32_t x, int32_t y); void text(const char &c); - void text(const std::string &t, int32_t x, int32_t y); - void text(const std::string &t); + void text( + const std::string &t, + int32_t x, int32_t y, + int32_t wrap = -1); + void text( + const std::string &t, + int32_t wrap = -1); // blend functions void COPY( @@ -148,6 +159,7 @@ namespace picosystem { // utility std::string str(float v, uint8_t precision = 2); std::string str(int32_t v); + std::string str(std::size_t v); std::string str(uint32_t v); color_t rgb(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 15); color_t hsv(float h, float s, float v, float a = 1.0f); @@ -160,7 +172,6 @@ namespace picosystem { uint32_t time(); uint32_t time_us(); void sleep(uint32_t d); - void sleep_us(uint32_t d); bool intersects( int32_t x, int32_t y, int32_t w, int32_t h, int32_t cx, int32_t cy, int32_t cw, int32_t ch); @@ -173,8 +184,11 @@ namespace picosystem { bool contains( int32_t x, int32_t y, int32_t w, int32_t h, int32_t cx, int32_t cy, int32_t cw, int32_t ch); - void wrap(std::string &t, std::size_t chars); - uint32_t text_width(std::string &t); + uint32_t wrap(std::string &t, uint32_t w); + void measure( + const std::string &t, + int32_t &w, int32_t &h, + int32_t wrap = -1); std::vector split(const std::string& t, char d = '\n'); float fsin(float v); float fcos(float v); @@ -275,4 +289,4 @@ namespace picosystem { As8 = 7458, Bb8 = 7458, B8 = 7902, }; -} \ No newline at end of file +} diff --git a/libraries/primitives.cpp b/libraries/primitives.cpp index 09ca094..ecb4780 100644 --- a/libraries/primitives.cpp +++ b/libraries/primitives.cpp @@ -387,69 +387,6 @@ namespace picosystem { blit(_ss, sx * 8, sy * 8, cx * 8, cy * 8, x, y, dw, dh); } - // draws a character at the current cursor position - void text(const char &c) { - if(!intersects(_tx, _ty, 8, 8, _cx, _cy, _cw, _ch)) { - return; - } - - const uint8_t *p = &_font[(c - 32) * 9]; - - uint8_t w = *p++; - - for(int32_t y = _ty; y < _ty + 8; y++) { - color_t *dest = _dt->p(_tx, y); - uint8_t pr = *p; - if(pr && y >= _cy && y < _cy + _ch) { - for(uint8_t x = _tx; x < _tx + w; x++) { - if(x >= _cx && x < _cx + _cw && pr & 0x80) { - _bf(&_pen, 0, 0, dest, 1); - } - pr <<= 1; dest++; - } - } - p++; - } - - _tx += w + 1; - } - - void text(const char &c, int32_t x, int32_t y) { - _camera_offset(x, y); - - _tx = x; - _ty = y; - - text(c); - } - - void text(const std::string &t, int32_t x, int32_t y) { - _camera_offset(x, y); - - _tx = x; - _ty = y; - - text(t); - } - - void text(const std::string &t) { - int32_t _stx = _tx; - - for(auto &c : t) { - // newline - if(c == 10) { - // set cursor to start of next line - _ty += 8; - _tx = _stx; - } else { - text(c); - } - } - - // set cursor to start of next line - _ty += 8; - _tx = _stx; - } void _logo() { const uint8_t *s = _picosystem_logo; diff --git a/libraries/state.cpp b/libraries/state.cpp index b45d023..aa4b64e 100644 --- a/libraries/state.cpp +++ b/libraries/state.cpp @@ -88,4 +88,13 @@ namespace picosystem { _ss = ss; } + void font(int32_t w, int32_t h, int32_t s, uint8_t *data) { + _tlw = w; + _tlh = h; + _tls = s; + if(data) { + _font = data; + } + } + } \ No newline at end of file diff --git a/libraries/text.cpp b/libraries/text.cpp new file mode 100644 index 0000000..7d54d9d --- /dev/null +++ b/libraries/text.cpp @@ -0,0 +1,216 @@ + +#include "picosystem.hpp" + +namespace picosystem { + + uint32_t _char_width(char c) { + return _tlw == -1 ? _font[(c - 32) * 9] : _tlw; + } + + // draws a character at the current cursor position + void text(const char &c) { + if(!intersects(_tx, _ty, 8, 8, _cx, _cy, _cw, _ch)) { + return; + } + + const uint8_t *p = &_font[(c - 32) * 9]; + + uint8_t w = *p++; + + // centre glyph if in fixed with mode + uint8_t xo = 0; + if(_tlw != -1) { + xo = (_tlw - w) >> 1; + } + + for(int32_t y = _ty; y < _ty + 8; y++) { + color_t *dest = _dt->p(_tx + xo, y); + uint8_t pr = *p; + if(pr && y >= _cy && y < _cy + _ch) { + for(uint8_t x = _tx + xo; x < _tx + xo + w; x++) { + if(x >= _cx && x < _cx + _cw && pr & 0x80) { + _bf(&_pen, 0, 0, dest, 1); + } + pr <<= 1; dest++; + } + } + p++; + } + + _tx += _char_width(c) + _tls; + } + + bool _matches(const std::string &t, const std::string &m, std::size_t &i) { + std::size_t j = 0; + while(j < m.size()) { + if(t[i + j] != m[j]) { + return false; + } + j++; + } + + // consume characters if a match + i += m.size(); + return true; + } + + void _skip_escape_code(const std::string &t, std::size_t &i) { + i++; + if(_matches(t, "rgba", i)) { + i += 3; + } else if(_matches(t, "rgb", i)) { + i += 2; + } + } + + // search for end of the next word (including any e) + uint32_t _next_word_length(const std::string &t, std::size_t i) { + // search through until we find a non word character to break on + uint32_t l = 0; + while(true) { + char c = t[i]; + if(c <= 32) { + break; + } + + if(c == '\\') { + _skip_escape_code(t, i); + } else { + l += _char_width(c) + _tls; + i++; + } + } + return l; + } + + uint8_t _hex_to_int(char c) { + if(c >= '0' && c <= '9') return c - '0'; + if(c >= 'A' && c <= 'F') return (c - 'A') + 10; + if(c >= 'a' && c <= 'f') return (c - 'a') + 10; + return 0; + } + + void _parse_escape_code(const std::string &t, std::size_t &i) { + i++; + if(_matches(t, "rgba", i) ){ + uint8_t r = _hex_to_int(t[i++]); + uint8_t g = _hex_to_int(t[i++]); + uint8_t b = _hex_to_int(t[i++]); + uint8_t a = _hex_to_int(t[i]); + pen(r, g, b, a); + } else if (_matches(t, "rgb", i) ){ + uint8_t r = _hex_to_int(t[i++]); + uint8_t g = _hex_to_int(t[i++]); + uint8_t b = _hex_to_int(t[i]); + pen(r, g, b); + } + } + + void measure(const std::string &t, int32_t &w, int32_t &h, int32_t wrap) { + w = 0; h = 0; + + // save cursor position for wrapping new lines + int32_t tx = 0, ty = 0; + bool in_word = false; + + for(std::size_t i = 0; i < t.size(); i++) { + char c = t[i]; + + switch(c) { + case '\n': { + tx = 0; + ty += _tlh; + }break; + + case ' ': { + tx += _font[0]; + }break; + + case '\t': { + tx += _font[0] * 10; // four spaces + }break; + + case '\\': { + // special code - read ahead and do something... + _parse_escape_code(t, i); + }break; + } + + if(c > 32 && c != '\\') { + // check length to end of word + if(!in_word) { + uint32_t nwl = _next_word_length(t, i); + if(wrap != -1 && tx + nwl > wrap) { + tx = 0; + ty += _tlh; + } + } + + tx += _char_width(c) + _tls; + w = std::max(w, tx); + } + + in_word = c > 32 && c != '\\'; + } + + // set cursor to start of next line + h = ty + _tlh; + } + + void text(const std::string &t, int32_t wrap) { + // save cursor position for wrapping new lines + int32_t _stx = _tx; + int32_t _wtx = _tx + wrap; + bool in_word = false; + + for(std::size_t i = 0; i < t.size(); i++) { + char c = t[i]; + + switch(c) { + case '\n': { + _tx = _stx; + _ty += _tlh; + }break; + + case ' ': { + _tx += _font[0]; + }break; + + case '\t': { + _tx += _font[0] * 10; // four spaces + }break; + + case '\\': { + // special code - read ahead and do something... + _parse_escape_code(t, i); + }break; + } + + if(c > 32 && c != '\\') { + // check length to end of word + if(!in_word) { + uint32_t nwl = _next_word_length(t, i); + if(wrap != -1 && _tx + nwl > _wtx) { + _tx = _stx; + _ty += _tlh; + } + } + + text(c); + } + + in_word = c > 32 && c != '\\'; + } + + // set cursor to start of next line + _ty += _tlh; + _tx = _stx; + } + + void text(const std::string &t, int32_t x, int32_t y, int32_t wrap) { + _camera_offset(x, y); + _tx = x; _ty = y; + text(t, wrap); + } + +} \ No newline at end of file diff --git a/libraries/utility.cpp b/libraries/utility.cpp index f105d07..e4c1b0c 100644 --- a/libraries/utility.cpp +++ b/libraries/utility.cpp @@ -19,6 +19,10 @@ namespace picosystem { return b; } + std::string str(std::size_t v) { + return str(int32_t(v)); + } + std::string str(uint32_t v) { static char b[32]; snprintf(b, 32, "%lu", v); @@ -103,13 +107,19 @@ namespace picosystem { int32_t cx, int32_t cy, int32_t cw, int32_t ch) { return x >= cx && y >= cy && x + w <= cx + cw && y + h <= cy + ch; } - +/* uint32_t text_width(std::string &t) { // add up length of characters uint32_t l = 0; - for(auto c : t) { - l += _font[(c - 32) * 9] + 1; + if(_tlw == -1) { + for(auto c : t) { + l += _font[(c - 32) * 9]; + } + }else{ + l = t.size() * _tlw; } + // add letter spacing + l += _tls * (t.size() - 1); return l; } @@ -131,14 +141,21 @@ namespace picosystem { // add up length of characters uint32_t l = 0; while(i < n) { - l += _font[(t[i] - 32) * 9] + 1; + if(_tlw == -1) { + l += _font[(t[i] - 32) * 9] + _tls; + }else{ + l += _tlw + _tls; + } i++; }; + // remove last letter spacing + l -= _tls; + return l; } - void wrap(std::string &t, std::size_t w) { + uint32_t wrap(std::string &t, uint32_t w) { std::size_t i = 0, si = 0, ll = 0; while(true) { @@ -152,14 +169,16 @@ namespace picosystem { // if we would overflow the line then replace space with a newline t[si] = '\n'; // next line starts with current word - ll = wl + 2; - }else{ - ll += wl + 2; // 2 == space length, should be a configurable? + ll = 0; } + ll += wl + (_tlw == -1 ? _font[(t[i] - 32) * 9] : _tlw) + _tls; // 2 == space length, should be a configurable? + si = i; } - } + + return 0; + }*/ std::vector split(const std::string& t, char d) { std::vector l;