diff --git a/CMakeLists.txt b/CMakeLists.txt index d928fe9..3c00c2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,11 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) # For lsp set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g") +set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") + +set(CMAKE_C_FLAGS_DEBUG "-O0 -g") +set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG") set(NAME st7735_driver) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 842eadb..f904236 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,6 +3,7 @@ add_library(${NAME} STATIC "core/lcd_base.c" "core/lucida_console_10pt.c" "core/m3x6_16pt.c" + "core/m5x7_16pt.c" "st7735/lcd_st7735.c" ) diff --git a/src/core/m3x6_16pt.h b/src/core/m3x6_16pt.h index 9d34aaa..6c767b7 100644 --- a/src/core/m3x6_16pt.h +++ b/src/core/m3x6_16pt.h @@ -2,6 +2,10 @@ // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 +// This is a rasterized version of the m3x6 font. +// The m3x6 font is created by Daniel Linssen and is free to use with attribution. +// The original TTF font can be found at https://managore.itch.io/m3x6 + #ifndef M3X6_16PT_H_ #define M3X6_16PT_H_ diff --git a/src/core/m5x7_16pt.c b/src/core/m5x7_16pt.c new file mode 100644 index 0000000..4ebb17d --- /dev/null +++ b/src/core/m5x7_16pt.c @@ -0,0 +1,1165 @@ +// Copyright (c) 2025 Douglas Reis. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This is a rasterized version of the m5x7 font. +// The m5x7 font is created by Daniel Linssen and is free to use with +// attribution. The original TTF font can be found at +// https://managore.itch.io/m5x7 + +#include "m5x7_16pt.h" +// Character bitmaps for m5x7_16pt +const unsigned char m5x7_16ptBitmaps[] = { + // @32 ' ' (5 pixels wide) + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + + // @33 '!' (2 pixels wide) + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x00, // + 0x01, // # + 0x00, // + 0x00, // + + // @34 '"' (4 pixels wide) + 0x05, // # # + 0x05, // # # + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + + // @35 '#' (6 pixels wide) + 0x00, // + 0x0a, // # # + 0x1f, // ##### + 0x0a, // # # + 0x0a, // # # + 0x1f, // ##### + 0x0a, // # # + 0x00, // + 0x00, // + + // @36 '$' (6 pixels wide) + 0x04, // # + 0x1e, // #### + 0x05, // # # + 0x0e, // ### + 0x14, // # # + 0x0f, // #### + 0x04, // # + 0x00, // + 0x00, // + + // @37 '%' (6 pixels wide) + 0x13, // ## # + 0x13, // ## # + 0x08, // # + 0x04, // # + 0x02, // # + 0x19, // # ## + 0x19, // # ## + 0x00, // + 0x00, // + + // @38 '&' (7 pixels wide) + 0x04, // # + 0x0a, // # # + 0x0a, // # # + 0x06, // ## + 0x11, // # # + 0x11, // # # + 0x2e, // ### # + 0x00, // + 0x00, // + + // @39 ''' (2 pixels wide) + 0x01, // # + 0x01, // # + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + + // @40 '(' (3 pixels wide) + 0x02, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x02, // # + 0x00, // + + // @41 ')' (3 pixels wide) + 0x01, // # + 0x02, // # + 0x02, // # + 0x02, // # + 0x02, // # + 0x02, // # + 0x02, // # + 0x01, // # + 0x00, // + + // @42 '*' (4 pixels wide) + 0x05, // # # + 0x02, // # + 0x05, // # # + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + + // @43 '+' (6 pixels wide) + 0x00, // + 0x04, // # + 0x04, // # + 0x1f, // ##### + 0x04, // # + 0x04, // # + 0x00, // + 0x00, // + 0x00, // + + // @44 ',' (3 pixels wide) + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x02, // # + 0x01, // # + 0x00, // + + // @45 '-' (6 pixels wide) + 0x00, // + 0x00, // + 0x00, // + 0x1f, // ##### + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + + // @46 '.' (2 pixels wide) + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x01, // # + 0x00, // + 0x00, // + + // @47 '/' (4 pixels wide) + 0x04, // # + 0x04, // # + 0x02, // # + 0x02, // # + 0x02, // # + 0x01, // # + 0x01, // # + 0x00, // + 0x00, // + + // @48 '0' (6 pixels wide) + 0x0e, // ### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x0e, // ### + 0x00, // + 0x00, // + + // @49 '1' (6 pixels wide) + 0x04, // # + 0x06, // ## + 0x04, // # + 0x04, // # + 0x04, // # + 0x04, // # + 0x1f, // ##### + 0x00, // + 0x00, // + + // @50 '2' (6 pixels wide) + 0x0e, // ### + 0x11, // # # + 0x10, // # + 0x08, // # + 0x04, // # + 0x02, // # + 0x1f, // ##### + 0x00, // + 0x00, // + + // @51 '3' (6 pixels wide) + 0x0e, // ### + 0x11, // # # + 0x10, // # + 0x0c, // ## + 0x10, // # + 0x11, // # # + 0x0e, // ### + 0x00, // + 0x00, // + + // @52 '4' (6 pixels wide) + 0x08, // # + 0x0c, // ## + 0x0a, // # # + 0x09, // # # + 0x1f, // ##### + 0x08, // # + 0x08, // # + 0x00, // + 0x00, // + + // @53 '5' (6 pixels wide) + 0x1f, // ##### + 0x01, // # + 0x0f, // #### + 0x10, // # + 0x10, // # + 0x10, // # + 0x0f, // #### + 0x00, // + 0x00, // + + // @54 '6' (6 pixels wide) + 0x0e, // ### + 0x01, // # + 0x0f, // #### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x0e, // ### + 0x00, // + 0x00, // + + // @55 '7' (6 pixels wide) + 0x1f, // ##### + 0x10, // # + 0x10, // # + 0x08, // # + 0x08, // # + 0x04, // # + 0x04, // # + 0x00, // + 0x00, // + + // @56 '8' (6 pixels wide) + 0x0e, // ### + 0x11, // # # + 0x11, // # # + 0x0e, // ### + 0x11, // # # + 0x11, // # # + 0x0e, // ### + 0x00, // + 0x00, // + + // @57 '9' (6 pixels wide) + 0x0e, // ### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x1e, // #### + 0x10, // # + 0x0e, // ### + 0x00, // + 0x00, // + + // @58 ':' (2 pixels wide) + 0x00, // + 0x00, // + 0x00, // + 0x01, // # + 0x00, // + 0x00, // + 0x01, // # + 0x00, // + 0x00, // + + // @59 ';' (3 pixels wide) + 0x00, // + 0x00, // + 0x00, // + 0x02, // # + 0x00, // + 0x00, // + 0x02, // # + 0x01, // # + 0x00, // + + // @60 '<' (4 pixels wide) + 0x00, // + 0x04, // # + 0x02, // # + 0x01, // # + 0x02, // # + 0x04, // # + 0x00, // + 0x00, // + 0x00, // + + // @61 '=' (5 pixels wide) + 0x00, // + 0x00, // + 0x0f, // #### + 0x00, // + 0x0f, // #### + 0x00, // + 0x00, // + 0x00, // + 0x00, // + + // @62 '>' (4 pixels wide) + 0x00, // + 0x01, // # + 0x02, // # + 0x04, // # + 0x02, // # + 0x01, // # + 0x00, // + 0x00, // + 0x00, // + + // @63 '?' (6 pixels wide) + 0x0e, // ### + 0x11, // # # + 0x10, // # + 0x08, // # + 0x04, // # + 0x00, // + 0x04, // # + 0x00, // + 0x00, // + + // @64 '@' (6 pixels wide) + 0x0e, // ### + 0x11, // # # + 0x1d, // # ### + 0x15, // # # # + 0x1d, // # ### + 0x01, // # + 0x1e, // #### + 0x00, // + 0x00, // + + // @65 'A' (6 pixels wide) + 0x0e, // ### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x1f, // ##### + 0x11, // # # + 0x11, // # # + 0x00, // + 0x00, // + + // @66 'B' (6 pixels wide) + 0x0f, // #### + 0x11, // # # + 0x0f, // #### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x0f, // #### + 0x00, // + 0x00, // + + // @67 'C' (6 pixels wide) + 0x1c, // ### + 0x02, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x1e, // #### + 0x00, // + 0x00, // + + // @68 'D' (6 pixels wide) + 0x07, // ### + 0x09, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x0f, // #### + 0x00, // + 0x00, // + + // @69 'E' (6 pixels wide) + 0x1e, // #### + 0x01, // # + 0x0f, // #### + 0x01, // # + 0x01, // # + 0x01, // # + 0x1e, // #### + 0x00, // + 0x00, // + + // @70 'F' (6 pixels wide) + 0x1e, // #### + 0x01, // # + 0x0f, // #### + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x00, // + 0x00, // + + // @71 'G' (6 pixels wide) + 0x0e, // ### + 0x11, // # # + 0x01, // # + 0x1d, // # ### + 0x11, // # # + 0x11, // # # + 0x0e, // ### + 0x00, // + 0x00, // + + // @72 'H' (6 pixels wide) + 0x11, // # # + 0x11, // # # + 0x1f, // ##### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x00, // + 0x00, // + + // @73 'I' (6 pixels wide) + 0x1f, // ##### + 0x04, // # + 0x04, // # + 0x04, // # + 0x04, // # + 0x04, // # + 0x1f, // ##### + 0x00, // + 0x00, // + + // @74 'J' (6 pixels wide) + 0x1f, // ##### + 0x10, // # + 0x10, // # + 0x10, // # + 0x10, // # + 0x08, // # + 0x07, // ### + 0x00, // + 0x00, // + + // @75 'K' (6 pixels wide) + 0x11, // # # + 0x11, // # # + 0x09, // # # + 0x07, // ### + 0x09, // # # + 0x11, // # # + 0x11, // # # + 0x00, // + 0x00, // + + // @76 'L' (6 pixels wide) + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x1e, // #### + 0x00, // + 0x00, // + + // @77 'M' (8 pixels wide) + 0x36, // ## ## + 0x49, // # # # + 0x49, // # # # + 0x49, // # # # + 0x49, // # # # + 0x49, // # # # + 0x41, // # # + 0x00, // + 0x00, // + + // @78 'N' (6 pixels wide) + 0x07, // ### + 0x09, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x00, // + 0x00, // + + // @79 'O' (6 pixels wide) + 0x0e, // ### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x0e, // ### + 0x00, // + 0x00, // + + // @80 'P' (6 pixels wide) + 0x0f, // #### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x0f, // #### + 0x01, // # + 0x01, // # + 0x00, // + 0x00, // + + // @81 'Q' (6 pixels wide) + 0x0e, // ### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x15, // # # # + 0x09, // # # + 0x16, // ## # + 0x00, // + 0x00, // + + // @82 'R' (6 pixels wide) + 0x0f, // #### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x0f, // #### + 0x11, // # # + 0x11, // # # + 0x00, // + 0x00, // + + // @83 'S' (6 pixels wide) + 0x1e, // #### + 0x01, // # + 0x01, // # + 0x0e, // ### + 0x10, // # + 0x10, // # + 0x0f, // #### + 0x00, // + 0x00, // + + // @84 'T' (6 pixels wide) + 0x1f, // ##### + 0x04, // # + 0x04, // # + 0x04, // # + 0x04, // # + 0x04, // # + 0x04, // # + 0x00, // + 0x00, // + + // @85 'U' (6 pixels wide) + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x0e, // ### + 0x00, // + 0x00, // + + // @86 'V' (6 pixels wide) + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x0a, // # # + 0x04, // # + 0x00, // + 0x00, // + + // @87 'W' (8 pixels wide) + 0x41, // # # + 0x41, // # # + 0x49, // # # # + 0x49, // # # # + 0x49, // # # # + 0x49, // # # # + 0x36, // ## ## + 0x00, // + 0x00, // + + // @88 'X' (6 pixels wide) + 0x11, // # # + 0x11, // # # + 0x0a, // # # + 0x04, // # + 0x0a, // # # + 0x11, // # # + 0x11, // # # + 0x00, // + 0x00, // + + // @89 'Y' (6 pixels wide) + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x0a, // # # + 0x04, // # + 0x04, // # + 0x04, // # + 0x00, // + 0x00, // + + // @90 'Z' (6 pixels wide) + 0x1f, // ##### + 0x10, // # + 0x08, // # + 0x04, // # + 0x02, // # + 0x01, // # + 0x1f, // ##### + 0x00, // + 0x00, // + + // @91 '[' (3 pixels wide) + 0x03, // ## + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x03, // ## + 0x00, // + + // @92 '\' (4 pixels wide) + 0x01, // # + 0x01, // # + 0x02, // # + 0x02, // # + 0x02, // # + 0x04, // # + 0x04, // # + 0x00, // + 0x00, // + + // @93 ']' (3 pixels wide) + 0x03, // ## + 0x02, // # + 0x02, // # + 0x02, // # + 0x02, // # + 0x02, // # + 0x02, // # + 0x03, // ## + 0x00, // + + // @94 '^' (6 pixels wide) + 0x04, // # + 0x0a, // # # + 0x11, // # # + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + + // @95 '_' (6 pixels wide) + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x1f, // ##### + 0x00, // + 0x00, // + + // @96 '`' (3 pixels wide) + 0x01, // # + 0x02, // # + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + 0x00, // + + // @97 'a' (6 pixels wide) + 0x00, // + 0x00, // + 0x0e, // ### + 0x10, // # + 0x1e, // #### + 0x11, // # # + 0x1e, // #### + 0x00, // + 0x00, // + + // @98 'b' (6 pixels wide) + 0x01, // # + 0x01, // # + 0x0f, // #### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x0f, // #### + 0x00, // + 0x00, // + + // @99 'c' (5 pixels wide) + 0x00, // + 0x00, // + 0x0e, // ### + 0x01, // # + 0x01, // # + 0x01, // # + 0x0e, // ### + 0x00, // + 0x00, // + + // @100 'd' (6 pixels wide) + 0x10, // # + 0x10, // # + 0x1e, // #### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x1e, // #### + 0x00, // + 0x00, // + + // @101 'e' (6 pixels wide) + 0x00, // + 0x00, // + 0x0e, // ### + 0x11, // # # + 0x1f, // ##### + 0x01, // # + 0x0e, // ### + 0x00, // + 0x00, // + + // @102 'f' (5 pixels wide) + 0x0c, // ## + 0x02, // # + 0x0f, // #### + 0x02, // # + 0x02, // # + 0x02, // # + 0x02, // # + 0x00, // + 0x00, // + + // @103 'g' (6 pixels wide) + 0x00, // + 0x00, // + 0x0e, // ### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x1e, // #### + 0x10, // # + 0x0e, // ### + + // @104 'h' (6 pixels wide) + 0x01, // # + 0x01, // # + 0x0f, // #### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x00, // + 0x00, // + + // @105 'i' (3 pixels wide) + 0x02, // # + 0x00, // + 0x03, // ## + 0x02, // # + 0x02, // # + 0x02, // # + 0x02, // # + 0x00, // + 0x00, // + + // @106 'j' (4 pixels wide) + 0x04, // # + 0x00, // + 0x06, // ## + 0x04, // # + 0x04, // # + 0x04, // # + 0x04, // # + 0x04, // # + 0x03, // ## + + // @107 'k' (5 pixels wide) + 0x01, // # + 0x01, // # + 0x09, // # # + 0x05, // # # + 0x03, // ## + 0x05, // # # + 0x09, // # # + 0x00, // + 0x00, // + + // @108 'l' (3 pixels wide) + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x02, // # + 0x00, // + 0x00, // + + // @109 'm' (8 pixels wide) + 0x00, // + 0x00, // + 0x3d, // # #### + 0x4b, // ## # # + 0x49, // # # # + 0x49, // # # # + 0x49, // # # # + 0x00, // + 0x00, // + + // @110 'n' (6 pixels wide) + 0x00, // + 0x00, // + 0x0d, // # ## + 0x13, // ## # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x00, // + 0x00, // + + // @111 'o' (6 pixels wide) + 0x00, // + 0x00, // + 0x0e, // ### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x0e, // ### + 0x00, // + 0x00, // + + // @112 'p' (6 pixels wide) + 0x00, // + 0x00, // + 0x0f, // #### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x0f, // #### + 0x01, // # + 0x01, // # + + // @113 'q' (6 pixels wide) + 0x00, // + 0x00, // + 0x1e, // #### + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x1e, // #### + 0x10, // # + 0x10, // # + + // @114 'r' (5 pixels wide) + 0x00, // + 0x00, // + 0x0d, // # ## + 0x03, // ## + 0x01, // # + 0x01, // # + 0x01, // # + 0x00, // + 0x00, // + + // @115 's' (6 pixels wide) + 0x00, // + 0x00, // + 0x1e, // #### + 0x01, // # + 0x0e, // ### + 0x10, // # + 0x0f, // #### + 0x00, // + 0x00, // + + // @116 't' (5 pixels wide) + 0x02, // # + 0x02, // # + 0x0f, // #### + 0x02, // # + 0x02, // # + 0x02, // # + 0x0c, // ## + 0x00, // + 0x00, // + + // @117 'u' (6 pixels wide) + 0x00, // + 0x00, // + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x19, // # ## + 0x16, // ## # + 0x00, // + 0x00, // + + // @118 'v' (6 pixels wide) + 0x00, // + 0x00, // + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x0a, // # # + 0x04, // # + 0x00, // + 0x00, // + + // @119 'w' (8 pixels wide) + 0x00, // + 0x00, // + 0x41, // # # + 0x49, // # # # + 0x49, // # # # + 0x49, // # # # + 0x36, // ## ## + 0x00, // + 0x00, // + + // @120 'x' (6 pixels wide) + 0x00, // + 0x00, // + 0x11, // # # + 0x0a, // # # + 0x04, // # + 0x0a, // # # + 0x11, // # # + 0x00, // + 0x00, // + + // @121 'y' (6 pixels wide) + 0x00, // + 0x00, // + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x11, // # # + 0x1e, // #### + 0x10, // # + 0x0e, // ### + + // @122 'z' (6 pixels wide) + 0x00, // + 0x00, // + 0x1f, // ##### + 0x08, // # + 0x04, // # + 0x02, // # + 0x1f, // ##### + 0x00, // + 0x00, // + + // @123 '{' (4 pixels wide) + 0x06, // ## + 0x02, // # + 0x02, // # + 0x03, // ## + 0x02, // # + 0x02, // # + 0x02, // # + 0x06, // ## + 0x00, // + + // @124 '|' (2 pixels wide) + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x01, // # + 0x00, // + 0x00, // + + // @125 '}' (4 pixels wide) + 0x03, // ## + 0x02, // # + 0x02, // # + 0x06, // ## + 0x02, // # + 0x02, // # + 0x02, // # + 0x03, // ## + 0x00, // + + // @126 '~' (6 pixels wide) + 0x00, // + 0x00, // + 0x02, // # + 0x15, // # # # + 0x08, // # + 0x00, // + 0x00, // + 0x00, // + 0x00, // +}; + +// Character descriptors for 16pt +const FontCharInfo m5x7_16ptDescriptors[] = { + {5, 0}, // ' ' + {2, 9}, // '!' + {4, 18}, // '"' + {6, 27}, // '#' + {6, 36}, // '$' + {6, 45}, // '%' + {7, 54}, // '&' + {2, 63}, // ''' + {3, 72}, // '(' + {3, 81}, // ')' + {4, 90}, // '*' + {6, 99}, // '+' + {3, 108}, // ',' + {6, 117}, // '-' + {2, 126}, // '.' + {4, 135}, // '/' + {6, 144}, // '0' + {6, 153}, // '1' + {6, 162}, // '2' + {6, 171}, // '3' + {6, 180}, // '4' + {6, 189}, // '5' + {6, 198}, // '6' + {6, 207}, // '7' + {6, 216}, // '8' + {6, 225}, // '9' + {2, 234}, // ':' + {3, 243}, // ';' + {4, 252}, // '<' + {5, 261}, // '=' + {4, 270}, // '>' + {6, 279}, // '?' + {6, 288}, // '@' + {6, 297}, // 'A' + {6, 306}, // 'B' + {6, 315}, // 'C' + {6, 324}, // 'D' + {6, 333}, // 'E' + {6, 342}, // 'F' + {6, 351}, // 'G' + {6, 360}, // 'H' + {6, 369}, // 'I' + {6, 378}, // 'J' + {6, 387}, // 'K' + {6, 396}, // 'L' + {8, 405}, // 'M' + {6, 414}, // 'N' + {6, 423}, // 'O' + {6, 432}, // 'P' + {6, 441}, // 'Q' + {6, 450}, // 'R' + {6, 459}, // 'S' + {6, 468}, // 'T' + {6, 477}, // 'U' + {6, 486}, // 'V' + {8, 495}, // 'W' + {6, 504}, // 'X' + {6, 513}, // 'Y' + {6, 522}, // 'Z' + {3, 531}, // '[' + {4, 540}, // '\' + {3, 549}, // ']' + {6, 558}, // '^' + {6, 567}, // '_' + {3, 576}, // '`' + {6, 585}, // 'a' + {6, 594}, // 'b' + {5, 603}, // 'c' + {6, 612}, // 'd' + {6, 621}, // 'e' + {5, 630}, // 'f' + {6, 639}, // 'g' + {6, 648}, // 'h' + {3, 657}, // 'i' + {4, 666}, // 'j' + {5, 675}, // 'k' + {3, 684}, // 'l' + {8, 693}, // 'm' + {6, 702}, // 'n' + {6, 711}, // 'o' + {6, 720}, // 'p' + {6, 729}, // 'q' + {5, 738}, // 'r' + {6, 747}, // 's' + {5, 756}, // 't' + {6, 765}, // 'u' + {6, 774}, // 'v' + {8, 783}, // 'w' + {6, 792}, // 'x' + {6, 801}, // 'y' + {6, 810}, // 'z' + {4, 819}, // '{' + {2, 828}, // '|' + {4, 837}, // '}' + {6, 846}, // '~' +}; + +// Font information for 16pt +const Font m5x7_16ptFont = { + 9, // Character height + ' ', // Start character + '~', // End character + m5x7_16ptDescriptors, // Character descriptor array + m5x7_16ptBitmaps, // Character bitmap array +}; diff --git a/src/core/m5x7_16pt.h b/src/core/m5x7_16pt.h new file mode 100644 index 0000000..d6aed2c --- /dev/null +++ b/src/core/m5x7_16pt.h @@ -0,0 +1,21 @@ +// Copyright (c) 2025 Douglas Reis. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This is a rasterized version of the m5x7 font. +// The m5x7 font is created by Daniel Linssen and is free to use with +// attribution. The original TTF font can be found at +// https://managore.itch.io/m5x7 + +#ifndef M5X7_16PT_H_ +#define M5X7_16PT_H_ + +#include + +#include "font.h" + +extern const unsigned char m5x7_16ptBitmaps[]; +extern const Font m5x7_16ptFont; +extern const FontCharInfo m5x7_16ptDescriptors[]; + +#endif /* M5X7_16PT_H_ */ diff --git a/tests/golden_files/test_font_m5x7_16pt.png b/tests/golden_files/test_font_m5x7_16pt.png new file mode 100644 index 0000000..6b32627 Binary files /dev/null and b/tests/golden_files/test_font_m5x7_16pt.png differ diff --git a/tests/main.cc b/tests/main.cc index 2d1c43e..92a08de 100644 --- a/tests/main.cc +++ b/tests/main.cc @@ -69,9 +69,9 @@ class DisplayTest : public testing::Test { #define GET_GOLDEN_FILE() \ std::format("./tests/golden_files/test_{}.png", testing::UnitTest::GetInstance()->current_test_info()->name()) - template - T rotate_left(T& v) { - v = v << 8 | v >> (32 - 8); + template + T rotate_left(T &v) { + v = v << 8 | v >> (32 - 8); return v; } std::string make_temp_filename() { @@ -191,7 +191,7 @@ TEST_F(st7735SimTest, draw_rectangles) { Result res = lcd_st7735_clean(&ctx_); EXPECT_EQ(res.code, 0); size_t increment = 20; - uint32_t rgb = 0x0000FF; + uint32_t rgb = 0x0000FF; { LCD_rectangle rec{.origin = {.x = 0, .y = 0}, .width = DisplayWidth, .height = 10}; @@ -282,6 +282,58 @@ TEST_F(st7735SimTest, draw_text) { compare_img(filename, GET_GOLDEN_FILE()); } +#include +#include +TEST_F(st7735SimTest, font_m5x7_16pt) { + Result res = lcd_st7735_clean(&ctx_); + EXPECT_EQ(res.code, 0); + + std::string ascii = ""; + for (int i = 32; i <= 126; ++i) { + if (std::isprint(static_cast(i))) { + ascii += static_cast(i); + } + } + size_t font_h(0), rows(0), columns(0), ascii_index(0); + uint32_t bg(0xff), fg(0x00); + LCD_Point pos{.x = 0, .y = 0}; + + auto set_font = [&](const Font *font) { + res = lcd_st7735_set_font(&ctx_, font); + EXPECT_EQ(res.code, 0); + font_h = ctx_.parent.font->height; + rows = DisplayHeight / ctx_.parent.font->height; + columns = DisplayWidth / (ctx_.parent.font->descriptor_table->width + 1); + ascii_index = 0; + }; + + auto draw_text = [&]() { + res = lcd_st7735_set_font_colors(&ctx_, bg, fg); + EXPECT_EQ(res.code, 0); + std::string print = ascii.substr(ascii_index, columns); + res = lcd_st7735_puts(&ctx_, pos, print.c_str()); + EXPECT_EQ(res.code, print.size()); + ascii_index += columns; + pos.y += font_h; + bg = bg << 8 | bg >> (32 - 8); // Rotate left + fg = bg ^ 0xffffff; + }; + + set_font(&m5x7_16ptFont); + do { + draw_text(); + } while (ascii_index < ascii.size()); + + set_font(&m3x6_16ptFont); + do { + draw_text(); + } while (pos.y < DisplayHeight - font_h && ascii_index < ascii.size()); + + std::string filename = make_temp_filename(); + mock_.simulator.png(filename); + compare_img(filename, GET_GOLDEN_FILE()); +} + int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS();