diff --git a/Core/Inc/graphics.h b/Core/Inc/graphics/display.h similarity index 71% rename from Core/Inc/graphics.h rename to Core/Inc/graphics/display.h index e972f5b..41edf3d 100644 --- a/Core/Inc/graphics.h +++ b/Core/Inc/graphics/display.h @@ -1,12 +1,14 @@ -#ifndef GRAPHICS_H -#define GRAPHICS_H +#ifndef DISPLAY_H +#define DISPLAY_H #include "main.h" #define DISPLAY_WIDTH 240 #define DISPLAY_HEIGHT 320 -typedef uint16_t Pixel_t; +typedef uint16_t rgb565_pixel_t; + + #define PIXEL_RED(p) (((p) >> 11) & 0x1F) #define PIXEL_GREEN(p) (((p) >> 5) & 0x3F) @@ -16,7 +18,7 @@ typedef uint16_t Pixel_t; (((r & 0x1F) << 11) | ((g & 0x3F) << 5) | (b & 0x1F)) -extern volatile Pixel_t framebuffer[DISPLAY_HEIGHT * DISPLAY_WIDTH]; +extern volatile rgb565_pixel_t framebuffer[DISPLAY_HEIGHT * DISPLAY_WIDTH]; extern volatile uint32_t times_changed; diff --git a/Core/Inc/graphics/font.h b/Core/Inc/graphics/font.h new file mode 100644 index 0000000..f34e98c --- /dev/null +++ b/Core/Inc/graphics/font.h @@ -0,0 +1,13 @@ +#ifndef FONT_H +#define FONT_H + +#include "stdint.h" +#include "display.h" +#include "lvgl.h" + + +uint16_t draw_character(rgb565_pixel_t *framebuffer, const lv_font_t *font, const uint16_t x_loc, const uint16_t y_loc, const uint8_t character, rgb565_pixel_t color); + +void draw_string(rgb565_pixel_t *framebuffer, const lv_font_t *font, const uint16_t x_loc, const uint16_t y_loc, const uint8_t *string, rgb565_pixel_t color); + +#endif \ No newline at end of file diff --git a/Core/Inc/graphics/lvgl/lvgl.h b/Core/Inc/graphics/lvgl/lvgl.h new file mode 100644 index 0000000..54738ef --- /dev/null +++ b/Core/Inc/graphics/lvgl/lvgl.h @@ -0,0 +1,223 @@ +/** + * I want to use bitmap fonts generated with lv_font_conv. + * This generates a .h bitmap font header from a .TTF file, but it's + * designed to be used with the full LVGL library. + * This compatibility layer is here so that we can drop + * a font .h file into the project and use it without modification. + * + * This layer includes a lot of code from lv_font_fmt_txt.h to define how + * a bitmapped font is expressed. + */ + +#ifndef LVGL_H +#define LVGL_H + +#include "stdint.h" +#include "stdbool.h" + +/* Dummy Defines */ +#define LV_ATTRIBUTE_LARGE_CONST +#define LV_FONT_SUBPX_NONE 0 +#define NULL 0 +#define LVGL_VERSION_MAJOR 7 +#define LV_VERSION_CHECK(X,Y,Z) 0 + +/* Struct Definitions */ + +typedef struct _lv_font_t lv_font_t; +typedef struct _lv_font_fmt_txt_glyph_dsc_t lv_font_fmt_txt_glyph_dsc_t; +typedef struct _lv_draw_buf_t lv_draw_buf_t; + +struct _lv_font_t { + bool (*get_glyph_dsc)(const lv_font_t * font, lv_font_fmt_txt_glyph_dsc_t * dsc_out, uint32_t unicode_letter); /* Function pointer for glyph descriptor */ + const void * (*get_glyph_bitmap)(lv_font_fmt_txt_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf); /* Function pointer for glyph bitmap */ + uint16_t line_height; /* The maximum line height required by the font */ + int16_t base_line; /* Baseline measured from the bottom of the line */ + uint8_t subpx; /* Subpixel rendering type */ + int16_t underline_position; /* Underline position */ + int16_t underline_thickness; /* Underline thickness */ + const void * dsc; /* The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ + const void * fallback; /* Fallback font (if any) */ + void * user_data; /* Custom user data */ +}; + +/** A simple mapping of kern values from pairs*/ +typedef struct { + /*To get a kern value of two code points: + 1. Get the `glyph_id_left` and `glyph_id_right` from `lv_font_fmt_txt_cmap_t + 2. for(i = 0; i < pair_cnt * 2; i += 2) + if(glyph_ids[i] == glyph_id_left && + glyph_ids[i+1] == glyph_id_right) + return values[i / 2]; + */ + const void * glyph_ids; + const int8_t * values; + uint32_t pair_cnt : 30; + uint32_t glyph_ids_size : 2; /**< 0: `glyph_ids` is stored as `uint8_t`; 1: as `uint16_t` */ +} lv_font_fmt_txt_kern_pair_t; + +/** This describes a glyph.*/ +struct _lv_font_fmt_txt_glyph_dsc_t { +#if LV_FONT_FMT_TXT_LARGE == 0 + uint32_t bitmap_index : 20; /**< Start index of the bitmap. A font can be max 1 MB.*/ + uint32_t adv_w : 12; /**< Draw the next glyph after this width. 8.4 format (real_value * 16 is stored).*/ + uint8_t box_w; /**< Width of the glyph's bounding box*/ + uint8_t box_h; /**< Height of the glyph's bounding box*/ + int8_t ofs_x; /**< x offset of the bounding box*/ + int8_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/ +#else + uint32_t bitmap_index; /**< Start index of the bitmap. A font can be max 4 GB.*/ + uint32_t adv_w; /**< Draw the next glyph after this width. 28.4 format (real_value * 16 is stored).*/ + uint16_t box_w; /**< Width of the glyph's bounding box*/ + uint16_t box_h; /**< Height of the glyph's bounding box*/ + int16_t ofs_x; /**< x offset of the bounding box*/ + int16_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/ +#endif +}; + +/** Format of font character map.*/ +typedef enum { + LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL, + LV_FONT_FMT_TXT_CMAP_SPARSE_FULL, + LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY, + LV_FONT_FMT_TXT_CMAP_SPARSE_TINY, +} lv_font_fmt_txt_cmap_type_t; + +/** + * Map codepoints to a `glyph_dsc`s + * Several formats are supported to optimize memory usage + * See https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md + */ +typedef struct { + /** First Unicode character for this range*/ + uint32_t range_start; + + /** Number of Unicode characters related to this range. + * Last Unicode character = range_start + range_length - 1*/ + uint16_t range_length; + + /** First glyph ID (array index of `glyph_dsc`) for this range*/ + uint16_t glyph_id_start; + + /* + According the specification there are 4 formats: + https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md + + For simplicity introduce "relative code point": + rcp = codepoint - range_start + + and a search function: + search a "value" in an "array" and returns the index of "value". + + Format 0 tiny + unicode_list == NULL && glyph_id_ofs_list == NULL + glyph_id = glyph_id_start + rcp + + Format 0 full + unicode_list == NULL && glyph_id_ofs_list != NULL + glyph_id = glyph_id_start + glyph_id_ofs_list[rcp] + + Sparse tiny + unicode_list != NULL && glyph_id_ofs_list == NULL + glyph_id = glyph_id_start + search(unicode_list, rcp) + + Sparse full + unicode_list != NULL && glyph_id_ofs_list != NULL + glyph_id = glyph_id_start + glyph_id_ofs_list[search(unicode_list, rcp)] + */ + + const uint16_t * unicode_list; + + /** if(type == LV_FONT_FMT_TXT_CMAP_FORMAT0_...) it's `uint8_t *` + * if(type == LV_FONT_FMT_TXT_CMAP_SPARSE_...) it's `uint16_t *` + */ + const void * glyph_id_ofs_list; + + /** Length of `unicode_list` and/or `glyph_id_ofs_list`*/ + uint16_t list_length; + + /** Type of this character map*/ + lv_font_fmt_txt_cmap_type_t type; +} lv_font_fmt_txt_cmap_t; + +/** Bitmap formats*/ +typedef enum { + LV_FONT_FMT_TXT_PLAIN = 0, + LV_FONT_FMT_TXT_COMPRESSED = 1, + LV_FONT_FMT_TXT_COMPRESSED_NO_PREFILTER = 2, +} lv_font_fmt_txt_bitmap_format_t; + +/** Describe store for additional data for fonts */ +typedef struct { + /** The bitmaps of all glyphs */ + const uint8_t * glyph_bitmap; + + /** Describe the glyphs */ + const lv_font_fmt_txt_glyph_dsc_t * glyph_dsc; + + /** Map the glyphs to Unicode characters. + *Array of `lv_font_cmap_fmt_txt_t` variables */ + const lv_font_fmt_txt_cmap_t * cmaps; + + /** + * Store kerning values. + * Can be `lv_font_fmt_txt_kern_pair_t * or `lv_font_kern_classes_fmt_txt_t *` + * depending on `kern_classes` + */ + const void * kern_dsc; + + /** Scale kern values in 12.4 format */ + uint16_t kern_scale; + + /** Number of cmap tables */ + uint16_t cmap_num : 9; + + /** Bit per pixel: 1, 2, 3, 4, 8 */ + uint16_t bpp : 4; + + /** Type of `kern_dsc` */ + uint16_t kern_classes : 1; + + /** + * storage format of the bitmap + * from `lv_font_fmt_txt_bitmap_format_t` + */ + uint16_t bitmap_format : 2; + + /** + * Bytes to which each line is padded. + * 0: means no align and padding + * 1: e.g. with bpp=4 lines are aligned to 1 byte, so there can be a 4 bits of padding + * 4, 8, 16, 32, 64: each line is padded to the given byte boundaries + */ + uint8_t stride; +} lv_font_fmt_txt_dsc_t; + +struct _lv_draw_buf_t { + uint32_t data_size; /**< Total buf size in bytes */ + uint8_t * data; +}; + +/********************** +* GLOBAL PROTOTYPES +**********************/ + +/** + * Used as `get_glyph_bitmap` callback in lvgl's native font format if the font is uncompressed. + * @param g_dsc the glyph descriptor including which font to use, which supply the glyph_index and format. + * @param draw_buf a draw buffer that can be used to store the bitmap of the glyph, it's OK not to use it. + * @return pointer to an A8 bitmap (not necessarily bitmap_out) or NULL if `unicode_letter` not found + */ +const void * lv_font_get_bitmap_fmt_txt(lv_font_fmt_txt_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf); + +/** + * Used as `get_glyph_dsc` callback in lvgl's native font format if the font is uncompressed. + * @param font pointer to font + * @param dsc_out store the result descriptor here + * @param unicode_letter a UNICODE letter code + * @return true: descriptor is successfully loaded into `dsc_out`. + * false: the letter was not found, no data is loaded to `dsc_out` + */ +bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_fmt_txt_glyph_dsc_t * dsc_out, uint32_t unicode_letter); + +#endif \ No newline at end of file diff --git a/Core/Inc/graphics/roboto_bold_font.h b/Core/Inc/graphics/roboto_bold_font.h new file mode 100644 index 0000000..4ea6ccf --- /dev/null +++ b/Core/Inc/graphics/roboto_bold_font.h @@ -0,0 +1,597 @@ +/******************************************************************************* + * Size: 16 px + * Bpp: 1 + * Opts: --font Roboto-Bold.ttf --bpp 1 --size 16 --format lvgl --no-compress -o roboto_bold_font.h --range 0x20-0x7E + ******************************************************************************/ + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif + +#ifndef ROBOTO_BOLD_FONT +#define ROBOTO_BOLD_FONT 1 +#endif + +#if ROBOTO_BOLD_FONT + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ + 0x0, + + /* U+0021 "!" */ + 0xff, 0xff, 0xf, + + /* U+0022 "\"" */ + 0xff, 0xff, + + /* U+0023 "#" */ + 0x1a, 0xd, 0x4, 0x8f, 0xf7, 0xf8, 0xb0, 0xd1, + 0xfe, 0xff, 0x12, 0x9, 0x5, 0x80, + + /* U+0024 "$" */ + 0x8, 0x8, 0x3c, 0x7e, 0x67, 0x63, 0x60, 0x38, + 0xe, 0x3, 0x63, 0x67, 0x7f, 0x3e, 0x8, 0x8, + + /* U+0025 "%" */ + 0x70, 0x1f, 0x3, 0x64, 0x6d, 0x8f, 0xa0, 0xe8, + 0x3, 0xf0, 0x7f, 0x16, 0x64, 0xcc, 0x1f, 0x81, + 0xe0, + + /* U+0026 "&" */ + 0x3c, 0x1f, 0x86, 0x61, 0x98, 0x7c, 0xe, 0x7, + 0x9b, 0x76, 0xcf, 0xb1, 0xcf, 0xf0, 0xf6, + + /* U+0027 "'" */ + 0xff, + + /* U+0028 "(" */ + 0x13, 0x66, 0xcc, 0xcc, 0xcc, 0xcc, 0x66, 0x33, + 0x0, + + /* U+0029 ")" */ + 0x8c, 0x66, 0x23, 0x33, 0x33, 0x33, 0x66, 0xcc, + 0x0, + + /* U+002A "*" */ + 0x18, 0x18, 0xdb, 0x7e, 0x3c, 0x6c, 0x66, + + /* U+002B "+" */ + 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, + 0x18, 0x18, + + /* U+002C "," */ + 0x6d, 0xb4, + + /* U+002D "-" */ + 0xff, + + /* U+002E "." */ + 0xf0, + + /* U+002F "/" */ + 0xc, 0x21, 0x86, 0x10, 0xc3, 0x8, 0x61, 0x84, + 0x30, 0xc0, + + /* U+0030 "0" */ + 0x3c, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, + 0xc3, 0xe7, 0x7e, 0x3c, + + /* U+0031 "1" */ + 0xb, 0xff, 0x31, 0x8c, 0x63, 0x18, 0xc6, 0x30, + + /* U+0032 "2" */ + 0x3c, 0x7e, 0xc6, 0xc6, 0x6, 0xc, 0x1c, 0x18, + 0x30, 0x60, 0xff, 0xff, + + /* U+0033 "3" */ + 0x3c, 0x7f, 0x63, 0x3, 0x1f, 0x1e, 0x1f, 0x3, + 0x63, 0x63, 0x7e, 0x3c, + + /* U+0034 "4" */ + 0x6, 0x7, 0x7, 0x83, 0xc3, 0x61, 0x31, 0x99, + 0xff, 0xff, 0x83, 0x1, 0x80, 0xc0, + + /* U+0035 "5" */ + 0xff, 0xff, 0x6, 0xf, 0xdf, 0xd3, 0x83, 0x7, + 0x8f, 0xf3, 0xc0, + + /* U+0036 "6" */ + 0xc, 0x3c, 0x70, 0x60, 0xdc, 0xfe, 0xc7, 0xc3, + 0xc3, 0xe7, 0x7e, 0x3c, + + /* U+0037 "7" */ + 0xff, 0xff, 0x7, 0x6, 0x6, 0xc, 0xc, 0x18, + 0x18, 0x38, 0x30, 0x70, + + /* U+0038 "8" */ + 0x3c, 0xff, 0xc3, 0xc3, 0xe7, 0x3c, 0x7e, 0xc3, + 0xc3, 0xe7, 0x7e, 0x3c, + + /* U+0039 "9" */ + 0x3c, 0x7e, 0xe7, 0xc3, 0xc3, 0xe3, 0x7f, 0x3b, + 0x6, 0xe, 0x3c, 0x30, + + /* U+003A ":" */ + 0xf0, 0x3, 0xc0, + + /* U+003B ";" */ + 0xf0, 0xf, 0xf8, + + /* U+003C "<" */ + 0x2, 0x3d, 0xf7, 0x8f, 0x7, 0xc3, 0x81, + + /* U+003D "=" */ + 0xff, 0xfc, 0x7, 0xff, 0xe0, + + /* U+003E ">" */ + 0x81, 0xe1, 0xf0, 0x71, 0xff, 0x38, 0x40, + + /* U+003F "?" */ + 0x3e, 0x7f, 0x63, 0x3, 0x3, 0xe, 0x1c, 0x18, + 0x18, 0x0, 0x18, 0x18, + + /* U+0040 "@" */ + 0xf, 0x80, 0xff, 0xe, 0x1c, 0xce, 0x66, 0xf9, + 0xe6, 0x4f, 0x66, 0x7b, 0x33, 0xd9, 0x9e, 0xcd, + 0xf7, 0xbc, 0xdd, 0xc7, 0x0, 0x1f, 0xc0, 0x7c, + 0x0, + + /* U+0041 "A" */ + 0xe, 0x1, 0xc0, 0x78, 0xf, 0x81, 0xb0, 0x76, + 0xc, 0xe1, 0x8c, 0x7f, 0x8f, 0xf9, 0x83, 0x70, + 0x60, + + /* U+0042 "B" */ + 0xfc, 0xff, 0xc3, 0xc3, 0xc3, 0xfe, 0xff, 0xc3, + 0xc3, 0xc3, 0xfe, 0xfc, + + /* U+0043 "C" */ + 0x1e, 0x3f, 0x98, 0xf8, 0x3c, 0x6, 0x3, 0x1, + 0x80, 0xc1, 0xb1, 0xdf, 0xc7, 0xc0, + + /* U+0044 "D" */ + 0xfc, 0x7f, 0x30, 0xd8, 0x3c, 0x1e, 0xf, 0x7, + 0x83, 0xc1, 0xe1, 0xbf, 0x9f, 0x80, + + /* U+0045 "E" */ + 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xfe, 0xfe, 0xc0, + 0xc0, 0xc0, 0xff, 0xff, + + /* U+0046 "F" */ + 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xfe, 0xfe, 0xc0, + 0xc0, 0xc0, 0xc0, 0xc0, + + /* U+0047 "G" */ + 0x3e, 0x3f, 0x98, 0xf8, 0x3c, 0x6, 0x3, 0x1f, + 0x8f, 0xc1, 0xb0, 0xdf, 0xe7, 0xc0, + + /* U+0048 "H" */ + 0xc1, 0xe0, 0xf0, 0x78, 0x3c, 0x1f, 0xff, 0xff, + 0x83, 0xc1, 0xe0, 0xf0, 0x78, 0x30, + + /* U+0049 "I" */ + 0xff, 0xff, 0xff, + + /* U+004A "J" */ + 0x6, 0xc, 0x18, 0x30, 0x60, 0xc1, 0x83, 0xc7, + 0x8d, 0xf1, 0xc0, + + /* U+004B "K" */ + 0xc3, 0x63, 0xb3, 0x9b, 0x8d, 0x87, 0xc3, 0xf1, + 0xf8, 0xce, 0x63, 0x31, 0xd8, 0x70, + + /* U+004C "L" */ + 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, + 0xc0, 0xc0, 0xff, 0xff, + + /* U+004D "M" */ + 0xe0, 0x7e, 0x7, 0xf0, 0xff, 0xf, 0xd9, 0xbd, + 0x9b, 0xd9, 0xbc, 0xf3, 0xcf, 0x3c, 0xf3, 0xc6, + 0x3c, 0x63, + + /* U+004E "N" */ + 0xc1, 0xf0, 0xfc, 0x7e, 0x3f, 0x9e, 0xcf, 0x37, + 0x9f, 0xc7, 0xe3, 0xf0, 0xf8, 0x30, + + /* U+004F "O" */ + 0x1e, 0x1f, 0xe6, 0x1b, 0x3, 0xc0, 0xf0, 0x3c, + 0xf, 0x3, 0xc0, 0xd8, 0x67, 0xf8, 0x78, + + /* U+0050 "P" */ + 0xfe, 0x7f, 0xb0, 0xf8, 0x3c, 0x1e, 0x1f, 0xfd, + 0xfc, 0xc0, 0x60, 0x30, 0x18, 0x0, + + /* U+0051 "Q" */ + 0x1e, 0x1f, 0xe6, 0x1b, 0x3, 0xc0, 0xf0, 0x3c, + 0xf, 0x3, 0xc0, 0xd8, 0x67, 0xf8, 0x7e, 0x1, + 0xc0, 0x20, + + /* U+0052 "R" */ + 0xfc, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe, 0xfc, + 0xce, 0xc6, 0xc7, 0xc3, + + /* U+0053 "S" */ + 0x1e, 0x1f, 0x98, 0xec, 0x37, 0x1, 0xe0, 0x3c, + 0x7, 0x61, 0xb0, 0xdf, 0xe3, 0xc0, + + /* U+0054 "T" */ + 0xff, 0xff, 0xf0, 0xc0, 0x30, 0xc, 0x3, 0x0, + 0xc0, 0x30, 0xc, 0x3, 0x0, 0xc0, 0x30, + + /* U+0055 "U" */ + 0xc1, 0xe0, 0xf0, 0x78, 0x3c, 0x1e, 0xf, 0x7, + 0x83, 0xc1, 0xf1, 0xdf, 0xc7, 0xc0, + + /* U+0056 "V" */ + 0xe0, 0xd8, 0x76, 0x1d, 0xc6, 0x31, 0x8c, 0xe3, + 0x30, 0x6c, 0x1f, 0x7, 0x81, 0xe0, 0x38, + + /* U+0057 "W" */ + 0x63, 0x19, 0x8c, 0x66, 0x31, 0x99, 0xe6, 0x77, + 0xb8, 0xde, 0xc3, 0x7b, 0xd, 0x2c, 0x3c, 0xf0, + 0xf3, 0xc1, 0xce, 0x6, 0x18, + + /* U+0058 "X" */ + 0x61, 0xdc, 0xe3, 0x38, 0xfc, 0x1e, 0x7, 0x81, + 0xe0, 0x78, 0x3f, 0xc, 0xe7, 0x1b, 0x87, + + /* U+0059 "Y" */ + 0xe1, 0xd8, 0x67, 0x38, 0xcc, 0x3f, 0x7, 0x81, + 0xe0, 0x30, 0xc, 0x3, 0x0, 0xc0, 0x30, + + /* U+005A "Z" */ + 0xff, 0xff, 0xc1, 0xc0, 0xe0, 0xe0, 0xe0, 0x70, + 0x70, 0x70, 0x38, 0x3f, 0xff, 0xf0, + + /* U+005B "[" */ + 0xff, 0x6d, 0xb6, 0xdb, 0x6d, 0xb7, 0xe0, + + /* U+005C "\\" */ + 0xe0, 0xc1, 0x83, 0x83, 0x6, 0xe, 0xc, 0x18, + 0x38, 0x30, 0x70, 0x60, + + /* U+005D "]" */ + 0xfd, 0xb6, 0xdb, 0x6d, 0xb6, 0xdf, 0xe0, + + /* U+005E "^" */ + 0x38, 0x70, 0xa3, 0x66, 0xc8, 0x80, + + /* U+005F "_" */ + 0xff, 0xfc, + + /* U+0060 "`" */ + 0x63, + + /* U+0061 "a" */ + 0x7d, 0xff, 0x1b, 0xff, 0xf8, 0xf1, 0xff, 0x76, + + /* U+0062 "b" */ + 0xc1, 0x83, 0x7, 0xef, 0xd8, 0xf1, 0xe3, 0xc7, + 0x8f, 0xf7, 0xe0, + + /* U+0063 "c" */ + 0x3c, 0x7e, 0xe6, 0xc0, 0xc0, 0xc0, 0xe6, 0x7e, + 0x3c, + + /* U+0064 "d" */ + 0x6, 0xc, 0x1b, 0xb7, 0xfc, 0xf1, 0xe3, 0xc7, + 0x8d, 0xf9, 0xf0, + + /* U+0065 "e" */ + 0x3c, 0x7e, 0xe3, 0xff, 0xff, 0xc0, 0xe2, 0x7f, + 0x3e, + + /* U+0066 "f" */ + 0x1c, 0xf3, 0x3f, 0xfc, 0xc3, 0xc, 0x30, 0xc3, + 0xc, + + /* U+0067 "g" */ + 0x3b, 0x7f, 0xe3, 0xc3, 0xc3, 0xc3, 0xe3, 0x7f, + 0x3b, 0x47, 0x7e, 0x3c, + + /* U+0068 "h" */ + 0xc1, 0x83, 0x6, 0xef, 0xf8, 0xf1, 0xe3, 0xc7, + 0x8f, 0x1e, 0x30, + + /* U+0069 "i" */ + 0xf3, 0xff, 0xff, + + /* U+006A "j" */ + 0x33, 0x3, 0x33, 0x33, 0x33, 0x33, 0x3f, 0xe0, + + /* U+006B "k" */ + 0xc0, 0xc0, 0xc0, 0xce, 0xdc, 0xd8, 0xf0, 0xf8, + 0xf8, 0xcc, 0xce, 0xc6, + + /* U+006C "l" */ + 0xff, 0xff, 0xff, + + /* U+006D "m" */ + 0xdc, 0xef, 0xff, 0xc6, 0x3c, 0x63, 0xc6, 0x3c, + 0x63, 0xc6, 0x3c, 0x63, 0xc6, 0x30, + + /* U+006E "n" */ + 0xdd, 0xff, 0x1e, 0x3c, 0x78, 0xf1, 0xe3, 0xc6, + + /* U+006F "o" */ + 0x3c, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xe7, 0x7e, + 0x3c, + + /* U+0070 "p" */ + 0xfd, 0xfb, 0x3e, 0x3c, 0x78, 0xf3, 0xfe, 0xf9, + 0x83, 0x6, 0x0, + + /* U+0071 "q" */ + 0x7e, 0xff, 0x9e, 0x3c, 0x78, 0xf1, 0xbf, 0x3e, + 0xc, 0x18, 0x30, + + /* U+0072 "r" */ + 0xdf, 0xf1, 0x8c, 0x63, 0x18, 0xc0, + + /* U+0073 "s" */ + 0x3c, 0xff, 0x9b, 0x3, 0xc0, 0xf1, 0xff, 0x3c, + + /* U+0074 "t" */ + 0x63, 0x3f, 0xf6, 0x31, 0x8c, 0x63, 0xce, + + /* U+0075 "u" */ + 0xc7, 0x8f, 0x1e, 0x3c, 0x78, 0xf1, 0xff, 0x76, + + /* U+0076 "v" */ + 0x63, 0x31, 0x9d, 0xce, 0xe3, 0x61, 0xb0, 0xf8, + 0x38, 0x1c, 0x0, + + /* U+0077 "w" */ + 0xcc, 0x79, 0xdf, 0x3b, 0x6f, 0x67, 0xac, 0xf7, + 0x9c, 0xe3, 0x9c, 0x31, 0x80, + + /* U+0078 "x" */ + 0x67, 0x66, 0x3e, 0x3c, 0x1c, 0x3c, 0x3e, 0x66, + 0xe7, + + /* U+0079 "y" */ + 0xe3, 0x67, 0x66, 0x76, 0x3e, 0x3c, 0x3c, 0x1c, + 0x18, 0x18, 0x70, 0x70, + + /* U+007A "z" */ + 0xff, 0xfc, 0x30, 0xe3, 0x8e, 0x1c, 0x7f, 0xfe, + + /* U+007B "{" */ + 0x0, 0xcc, 0x63, 0x18, 0xce, 0xe7, 0x8c, 0x63, + 0x18, 0xc3, 0x8, + + /* U+007C "|" */ + 0xff, 0xff, 0xff, 0xf0, + + /* U+007D "}" */ + 0x6, 0x18, 0xc6, 0x31, 0x8e, 0x3b, 0x98, 0xc6, + 0x31, 0x98, 0x80, + + /* U+007E "~" */ + 0x71, 0xfc, 0xb3, 0xd8, 0xc0 +}; + + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { + {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, + {.bitmap_index = 0, .adv_w = 64, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1, .adv_w = 69, .box_w = 2, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 4, .adv_w = 82, .box_w = 4, .box_h = 4, .ofs_x = 1, .ofs_y = 8}, + {.bitmap_index = 6, .adv_w = 152, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 20, .adv_w = 147, .box_w = 8, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 36, .adv_w = 189, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 53, .adv_w = 168, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 68, .adv_w = 41, .box_w = 2, .box_h = 4, .ofs_x = 1, .ofs_y = 8}, + {.bitmap_index = 69, .adv_w = 90, .box_w = 4, .box_h = 17, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 78, .adv_w = 90, .box_w = 4, .box_h = 17, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 87, .adv_w = 116, .box_w = 8, .box_h = 7, .ofs_x = 0, .ofs_y = 5}, + {.bitmap_index = 94, .adv_w = 140, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 104, .adv_w = 63, .box_w = 3, .box_h = 5, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 106, .adv_w = 101, .box_w = 4, .box_h = 2, .ofs_x = 1, .ofs_y = 4}, + {.bitmap_index = 107, .adv_w = 74, .box_w = 2, .box_h = 2, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 108, .adv_w = 95, .box_w = 6, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 118, .adv_w = 147, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 130, .adv_w = 147, .box_w = 5, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 138, .adv_w = 147, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 150, .adv_w = 147, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 162, .adv_w = 147, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 176, .adv_w = 147, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 187, .adv_w = 147, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 199, .adv_w = 147, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 211, .adv_w = 147, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 223, .adv_w = 147, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 235, .adv_w = 72, .box_w = 2, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 238, .adv_w = 67, .box_w = 2, .box_h = 11, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 241, .adv_w = 131, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 248, .adv_w = 147, .box_w = 7, .box_h = 5, .ofs_x = 1, .ofs_y = 3}, + {.bitmap_index = 253, .adv_w = 132, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 260, .adv_w = 127, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 272, .adv_w = 230, .box_w = 13, .box_h = 15, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 297, .adv_w = 172, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 314, .adv_w = 163, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 326, .adv_w = 168, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 340, .adv_w = 166, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 354, .adv_w = 144, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 366, .adv_w = 141, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 378, .adv_w = 175, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 392, .adv_w = 181, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 406, .adv_w = 75, .box_w = 2, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 409, .adv_w = 143, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 420, .adv_w = 163, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 434, .adv_w = 139, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 446, .adv_w = 224, .box_w = 12, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 464, .adv_w = 181, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 478, .adv_w = 177, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 493, .adv_w = 165, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 507, .adv_w = 177, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 525, .adv_w = 164, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 537, .adv_w = 158, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 551, .adv_w = 159, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 566, .adv_w = 169, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 580, .adv_w = 167, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 595, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 616, .adv_w = 163, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 631, .adv_w = 159, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 646, .adv_w = 155, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 660, .adv_w = 71, .box_w = 3, .box_h = 17, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 667, .adv_w = 108, .box_w = 7, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 679, .adv_w = 71, .box_w = 3, .box_h = 17, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 686, .adv_w = 112, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 6}, + {.bitmap_index = 692, .adv_w = 114, .box_w = 7, .box_h = 2, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 694, .adv_w = 85, .box_w = 4, .box_h = 2, .ofs_x = 0, .ofs_y = 10}, + {.bitmap_index = 695, .adv_w = 137, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 703, .adv_w = 144, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 714, .adv_w = 133, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 723, .adv_w = 144, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 734, .adv_w = 138, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 743, .adv_w = 92, .box_w = 6, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 752, .adv_w = 146, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 764, .adv_w = 143, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 775, .adv_w = 68, .box_w = 2, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 778, .adv_w = 67, .box_w = 4, .box_h = 15, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 786, .adv_w = 137, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 798, .adv_w = 68, .box_w = 2, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 801, .adv_w = 222, .box_w = 12, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 815, .adv_w = 144, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 823, .adv_w = 145, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 832, .adv_w = 144, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 843, .adv_w = 144, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 854, .adv_w = 94, .box_w = 5, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 860, .adv_w = 132, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 868, .adv_w = 87, .box_w = 5, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 875, .adv_w = 143, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 883, .adv_w = 130, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 894, .adv_w = 188, .box_w = 11, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 907, .adv_w = 130, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 916, .adv_w = 129, .box_w = 8, .box_h = 12, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 928, .adv_w = 130, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 936, .adv_w = 84, .box_w = 5, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 947, .adv_w = 65, .box_w = 2, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 951, .adv_w = 84, .box_w = 5, .box_h = 17, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 962, .adv_w = 166, .box_w = 9, .box_h = 4, .ofs_x = 1, .ofs_y = 3} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + + + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 32, .range_length = 95, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + } +}; + +/*----------------- + * KERNING + *----------------*/ + + +/*Pair left and right glyphs for kerning*/ +static const uint8_t kern_pair_glyph_ids[] = +{ + 3, 3, + 3, 8, + 8, 3, + 8, 8, + 13, 3, + 13, 8, + 15, 3, + 15, 8, + 16, 16 +}; + +/* Kerning between the respective left and right glyphs + * 4.4 format which needs to scaled with `kern_scale`*/ +static const int8_t kern_pair_values[] = +{ + -7, -7, -7, -7, -31, -31, -31, -31, + -30 +}; + +/*Collect the kern pair's data in one place*/ +static const lv_font_fmt_txt_kern_pair_t kern_pairs = +{ + .glyph_ids = kern_pair_glyph_ids, + .values = kern_pair_values, + .pair_cnt = 9, + .glyph_ids_size = 0 +}; + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LVGL_VERSION_MAJOR == 8 +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_glyph_cache_t cache; +#endif + +#if LVGL_VERSION_MAJOR >= 8 +static const lv_font_fmt_txt_dsc_t font_dsc = { +#else +static lv_font_fmt_txt_dsc_t font_dsc = { +#endif + .glyph_bitmap = glyph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = &kern_pairs, + .kern_scale = 16, + .cmap_num = 1, + .bpp = 1, + .kern_classes = 0, + .bitmap_format = 0, +#if LVGL_VERSION_MAJOR == 8 + .cache = &cache +#endif +}; + + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LVGL_VERSION_MAJOR >= 8 +const lv_font_t roboto_bold_font = { +#else +lv_font_t roboto_bold_font = { +#endif + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 18, /*The maximum line height required by the font*/ + .base_line = 4, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif +#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 + .underline_position = -1, + .underline_thickness = 1, +#endif + .dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +#if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9 + .fallback = NULL, +#endif + .user_data = NULL, +}; + + + +#endif /*#if ROBOTO_BOLD_FONT*/ + diff --git a/Core/Inc/graphics/roboto_font.h b/Core/Inc/graphics/roboto_font.h new file mode 100644 index 0000000..4ddf5bb --- /dev/null +++ b/Core/Inc/graphics/roboto_font.h @@ -0,0 +1,560 @@ +/******************************************************************************* + * Size: 16 px + * Bpp: 1 + * Opts: --font RobotoMono-Regular.ttf --bpp 1 --size 16 --format lvgl --no-compress -o roboto_font.h --range 0x20-0x7E + ******************************************************************************/ + + #ifdef LV_LVGL_H_INCLUDE_SIMPLE + #include "lvgl.h" + #else + #include "lvgl/lvgl.h" + #endif + + #ifndef ROBOTO_FONT + #define ROBOTO_FONT 1 + #endif + + #if ROBOTO_FONT + + /*----------------- + * BITMAPS + *----------------*/ + + /*Store the image of the glyphs*/ + static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ + 0x0, + + /* U+0021 "!" */ + 0xff, 0x30, + + /* U+0022 "\"" */ + 0x99, 0x99, + + /* U+0023 "#" */ + 0x9, 0x9, 0x4, 0x8f, 0xf1, 0x20, 0x90, 0x48, + 0x48, 0xff, 0x12, 0x9, 0x4, 0x80, + + /* U+0024 "$" */ + 0x10, 0x20, 0xf3, 0x34, 0x28, 0x18, 0xc, 0x4, + 0x6, 0xe, 0x37, 0xc2, 0x4, 0x0, + + /* U+0025 "%" */ + 0x60, 0x48, 0x24, 0x92, 0xc6, 0x40, 0x40, 0x20, + 0x26, 0x14, 0x92, 0x41, 0x20, 0x60, + + /* U+0026 "&" */ + 0x38, 0x4c, 0x44, 0x4c, 0x7c, 0x30, 0x70, 0xd9, + 0x8d, 0x87, 0xc6, 0x7f, + + /* U+0027 "'" */ + 0xf0, + + /* U+0028 "(" */ + 0x32, 0x44, 0x88, 0x88, 0x88, 0x88, 0x44, 0x62, + 0x0, + + /* U+0029 ")" */ + 0xc4, 0x22, 0x11, 0x11, 0x11, 0x11, 0x22, 0x24, + 0x0, + + /* U+002A "*" */ + 0x10, 0x22, 0x4f, 0xf1, 0x5, 0x1b, 0x22, + + /* U+002B "+" */ + 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10, + + /* U+002C "," */ + 0x55, 0x0, + + /* U+002D "-" */ + 0xfc, + + /* U+002E "." */ + 0xf0, + + /* U+002F "/" */ + 0x4, 0x20, 0x86, 0x10, 0x43, 0x8, 0x21, 0x84, + 0x10, 0x80, + + /* U+0030 "0" */ + 0x38, 0x8a, 0xc, 0x18, 0x73, 0x6c, 0xf1, 0x83, + 0x5, 0x11, 0xc0, + + /* U+0031 "1" */ + 0x17, 0xd1, 0x11, 0x11, 0x11, 0x11, + + /* U+0032 "2" */ + 0x3c, 0x46, 0x82, 0x82, 0x2, 0x4, 0xc, 0x18, + 0x30, 0x60, 0x40, 0xff, + + /* U+0033 "3" */ + 0x7d, 0x8f, 0x8, 0x10, 0x67, 0x81, 0x81, 0x3, + 0x85, 0x11, 0xc0, + + /* U+0034 "4" */ + 0x4, 0xc, 0x1c, 0x14, 0x34, 0x24, 0x44, 0xc4, + 0xff, 0x4, 0x4, 0x4, + + /* U+0035 "5" */ + 0x7e, 0x81, 0x2, 0x7, 0xc8, 0xc0, 0x81, 0x3, + 0x85, 0x99, 0xe0, + + /* U+0036 "6" */ + 0x1c, 0x41, 0x4, 0xb, 0x98, 0xa0, 0xc1, 0x83, + 0x5, 0x11, 0xc0, + + /* U+0037 "7" */ + 0xff, 0x3, 0x2, 0x6, 0x4, 0xc, 0x8, 0x8, + 0x18, 0x10, 0x30, 0x20, + + /* U+0038 "8" */ + 0x7d, 0x8e, 0xc, 0x1c, 0x6f, 0xb1, 0xc1, 0x83, + 0x5, 0x11, 0xc0, + + /* U+0039 "9" */ + 0x38, 0x8a, 0xc, 0x18, 0x30, 0x51, 0x9d, 0x2, + 0x8, 0x23, 0x80, + + /* U+003A ":" */ + 0xf0, 0x3, 0xc0, + + /* U+003B ";" */ + 0xf0, 0x1, 0x5c, + + /* U+003C "<" */ + 0x6, 0x3d, 0xc6, 0xe, 0x7, 0x81, 0x80, + + /* U+003D "=" */ + 0xfe, 0x0, 0x0, 0xf, 0xe0, + + /* U+003E ">" */ + 0x81, 0xc0, 0xf0, 0x31, 0xee, 0x30, 0x0, + + /* U+003F "?" */ + 0x3c, 0xc5, 0x8, 0x10, 0x61, 0x86, 0xc, 0x0, + 0x0, 0x60, 0xc0, + + /* U+0040 "@" */ + 0x1e, 0x11, 0x93, 0x7a, 0x99, 0x4d, 0x26, 0x93, + 0x4b, 0x9b, 0x20, 0x18, 0x7, 0x80, + + /* U+0041 "A" */ + 0x18, 0x18, 0x18, 0x3c, 0x2c, 0x24, 0x64, 0x66, + 0x7e, 0xc2, 0xc3, 0x81, + + /* U+0042 "B" */ + 0xf9, 0xe, 0xc, 0x18, 0x7f, 0xa1, 0xc1, 0x83, + 0x6, 0x17, 0xc0, + + /* U+0043 "C" */ + 0x3c, 0x8e, 0xc, 0x18, 0x10, 0x20, 0x40, 0x83, + 0x5, 0x19, 0xe0, + + /* U+0044 "D" */ + 0xf9, 0x1a, 0x14, 0x18, 0x30, 0x60, 0xc1, 0x83, + 0xa, 0x37, 0xc0, + + /* U+0045 "E" */ + 0xfd, 0x2, 0x4, 0x8, 0x1f, 0xa0, 0x40, 0x81, + 0x2, 0x7, 0xf0, + + /* U+0046 "F" */ + 0xff, 0x2, 0x4, 0x8, 0x10, 0x3f, 0x40, 0x81, + 0x2, 0x4, 0x0, + + /* U+0047 "G" */ + 0x3c, 0x62, 0x41, 0x80, 0x80, 0x80, 0x8f, 0x81, + 0x81, 0x41, 0x63, 0x3e, + + /* U+0048 "H" */ + 0x83, 0x6, 0xc, 0x18, 0x3f, 0xe0, 0xc1, 0x83, + 0x6, 0xc, 0x10, + + /* U+0049 "I" */ + 0xfe, 0x20, 0x40, 0x81, 0x2, 0x4, 0x8, 0x10, + 0x20, 0x47, 0xf0, + + /* U+004A "J" */ + 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x81, 0x3, + 0x85, 0x11, 0xc0, + + /* U+004B "K" */ + 0x87, 0x1a, 0x24, 0xcb, 0x1c, 0x3c, 0x4c, 0x89, + 0x1a, 0x1c, 0x30, + + /* U+004C "L" */ + 0x81, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x81, + 0x2, 0x7, 0xf0, + + /* U+004D "M" */ + 0xc7, 0x8f, 0x1f, 0x7a, 0xb5, 0x6e, 0xc9, 0x93, + 0x6, 0xc, 0x10, + + /* U+004E "N" */ + 0x83, 0x87, 0xf, 0x1b, 0x36, 0x66, 0xcd, 0x8f, + 0xe, 0x1c, 0x10, + + /* U+004F "O" */ + 0x3c, 0x42, 0x42, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x42, 0x42, 0x3c, + + /* U+0050 "P" */ + 0xf9, 0xa, 0xc, 0x18, 0x30, 0xbe, 0x40, 0x81, + 0x2, 0x4, 0x0, + + /* U+0051 "Q" */ + 0x3c, 0x42, 0x42, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x43, 0x42, 0x3e, 0x3, 0x1, + + /* U+0052 "R" */ + 0xf9, 0xa, 0xc, 0x18, 0x30, 0xff, 0x46, 0x8d, + 0xa, 0x1c, 0x10, + + /* U+0053 "S" */ + 0x38, 0x8a, 0xc, 0xc, 0xe, 0x7, 0x3, 0x3, + 0x7, 0x1b, 0xc0, + + /* U+0054 "T" */ + 0xff, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 0x8, 0x8, 0x8, 0x8, + + /* U+0055 "U" */ + 0x83, 0x6, 0xc, 0x18, 0x30, 0x60, 0xc1, 0x83, + 0x5, 0x11, 0xc0, + + /* U+0056 "V" */ + 0x83, 0xc3, 0xc2, 0x46, 0x46, 0x64, 0x24, 0x2c, + 0x28, 0x38, 0x18, 0x18, + + /* U+0057 "W" */ + 0x99, 0x99, 0x99, 0x99, 0x9b, 0xeb, 0xee, 0xe6, + 0x66, 0x66, 0x66, 0x66, + + /* U+0058 "X" */ + 0xc3, 0x42, 0x66, 0x2c, 0x3c, 0x18, 0x18, 0x3c, + 0x24, 0x66, 0x42, 0xc3, + + /* U+0059 "Y" */ + 0x41, 0x31, 0x88, 0x86, 0x41, 0x40, 0xa0, 0x60, + 0x10, 0x8, 0x4, 0x2, 0x1, 0x0, + + /* U+005A "Z" */ + 0xfe, 0xc, 0x10, 0x60, 0x83, 0xc, 0x10, 0x60, + 0x83, 0x7, 0xf0, + + /* U+005B "[" */ + 0xf2, 0x49, 0x24, 0x92, 0x49, 0x27, + + /* U+005C "\\" */ + 0x83, 0x4, 0x10, 0x60, 0x82, 0x4, 0x10, 0x60, + 0x82, 0xc, + + /* U+005D "]" */ + 0xe4, 0x92, 0x49, 0x24, 0x92, 0x4f, + + /* U+005E "^" */ + 0x20, 0xc3, 0x14, 0x5b, 0x28, 0xc0, + + /* U+005F "_" */ + 0xfe, + + /* U+0060 "`" */ + 0x44, + + /* U+0061 "a" */ + 0x3c, 0x8e, 0x8, 0x17, 0xf8, 0x60, 0xc3, 0x7a, + + /* U+0062 "b" */ + 0x81, 0x2, 0x7, 0xcc, 0x50, 0x60, 0xc1, 0x83, + 0x7, 0x17, 0xc0, + + /* U+0063 "c" */ + 0x3c, 0x46, 0x82, 0x80, 0x80, 0x80, 0x82, 0x46, + 0x3c, + + /* U+0064 "d" */ + 0x2, 0x4, 0x9, 0xf4, 0x70, 0x60, 0xc1, 0x83, + 0x5, 0x19, 0xf0, + + /* U+0065 "e" */ + 0x3c, 0x66, 0xc2, 0xc2, 0xff, 0xc0, 0xc0, 0x62, + 0x3c, + + /* U+0066 "f" */ + 0xf, 0x18, 0x10, 0x10, 0xfe, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, + + /* U+0067 "g" */ + 0x3e, 0x8e, 0xc, 0x18, 0x30, 0x60, 0xa3, 0x3e, + 0x7, 0x13, 0xc0, + + /* U+0068 "h" */ + 0x81, 0x2, 0x5, 0xec, 0x70, 0x60, 0xc1, 0x83, + 0x6, 0xc, 0x10, + + /* U+0069 "i" */ + 0x30, 0x60, 0x7, 0x81, 0x2, 0x4, 0x8, 0x10, + 0x20, 0x47, 0xf0, + + /* U+006A "j" */ + 0x8, 0x40, 0xf0, 0x84, 0x21, 0x8, 0x42, 0x10, + 0x8d, 0xc0, + + /* U+006B "k" */ + 0x81, 0x2, 0x4, 0x69, 0x96, 0x38, 0x78, 0x91, + 0x32, 0x34, 0x30, + + /* U+006C "l" */ + 0xf0, 0x20, 0x40, 0x81, 0x2, 0x4, 0x8, 0x10, + 0x20, 0x47, 0xf0, + + /* U+006D "m" */ + 0xff, 0x44, 0x62, 0x31, 0x18, 0x8c, 0x46, 0x23, + 0x11, 0x88, 0x80, + + /* U+006E "n" */ + 0xbd, 0x8e, 0xc, 0x18, 0x30, 0x60, 0xc1, 0x82, + + /* U+006F "o" */ + 0x38, 0x8a, 0xc, 0x18, 0x30, 0x60, 0xa2, 0x38, + + /* U+0070 "p" */ + 0xf9, 0x8a, 0xc, 0x18, 0x30, 0x60, 0xe2, 0xf9, + 0x2, 0x4, 0x0, + + /* U+0071 "q" */ + 0x3e, 0x8e, 0xc, 0x18, 0x30, 0x60, 0xa3, 0x3e, + 0x4, 0x8, 0x10, + + /* U+0072 "r" */ + 0xbe, 0x21, 0x8, 0x42, 0x10, 0x80, + + /* U+0073 "s" */ + 0x3c, 0x8f, 0xb, 0x3, 0xc0, 0xf0, 0xe3, 0x7c, + + /* U+0074 "t" */ + 0x20, 0x43, 0xf9, 0x2, 0x4, 0x8, 0x10, 0x20, + 0x40, 0x78, + + /* U+0075 "u" */ + 0x83, 0x6, 0xc, 0x18, 0x30, 0x60, 0xe3, 0x7a, + + /* U+0076 "v" */ + 0x83, 0xc2, 0x46, 0x64, 0x64, 0x2c, 0x38, 0x18, + 0x18, + + /* U+0077 "w" */ + 0xc8, 0xa6, 0x53, 0x29, 0xb5, 0x53, 0x98, 0xcc, + 0x66, 0x23, 0x0, + + /* U+0078 "x" */ + 0xc2, 0x66, 0x2c, 0x38, 0x18, 0x38, 0x24, 0x66, + 0xc3, + + /* U+0079 "y" */ + 0x83, 0xc2, 0x46, 0x66, 0x64, 0x2c, 0x38, 0x18, + 0x10, 0x10, 0x20, 0xe0, + + /* U+007A "z" */ + 0xfe, 0xc, 0x30, 0xc1, 0x6, 0x18, 0x60, 0xfe, + + /* U+007B "{" */ + 0x19, 0x88, 0x42, 0x10, 0x98, 0x61, 0x8, 0x42, + 0x10, 0x43, + + /* U+007C "|" */ + 0xff, 0xfe, + + /* U+007D "}" */ + 0xc1, 0x82, 0x8, 0x20, 0x83, 0x7, 0x30, 0x82, + 0x8, 0x20, 0x84, 0x30, + + /* U+007E "~" */ + 0x70, 0xc4, 0x61, 0xc0 + }; + + + /*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + + static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { + {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, + {.bitmap_index = 0, .adv_w = 154, .box_w = 1, .box_h = 1, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1, .adv_w = 154, .box_w = 1, .box_h = 12, .ofs_x = 4, .ofs_y = 0}, + {.bitmap_index = 3, .adv_w = 154, .box_w = 4, .box_h = 4, .ofs_x = 3, .ofs_y = 8}, + {.bitmap_index = 5, .adv_w = 154, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 19, .adv_w = 154, .box_w = 7, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 33, .adv_w = 154, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 47, .adv_w = 154, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 59, .adv_w = 154, .box_w = 1, .box_h = 4, .ofs_x = 4, .ofs_y = 8}, + {.bitmap_index = 60, .adv_w = 154, .box_w = 4, .box_h = 17, .ofs_x = 3, .ofs_y = -4}, + {.bitmap_index = 69, .adv_w = 154, .box_w = 4, .box_h = 17, .ofs_x = 2, .ofs_y = -4}, + {.bitmap_index = 78, .adv_w = 154, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 4}, + {.bitmap_index = 85, .adv_w = 154, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 93, .adv_w = 154, .box_w = 2, .box_h = 5, .ofs_x = 2, .ofs_y = -3}, + {.bitmap_index = 95, .adv_w = 154, .box_w = 6, .box_h = 1, .ofs_x = 2, .ofs_y = 5}, + {.bitmap_index = 96, .adv_w = 154, .box_w = 2, .box_h = 2, .ofs_x = 4, .ofs_y = 0}, + {.bitmap_index = 97, .adv_w = 154, .box_w = 6, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 107, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 118, .adv_w = 154, .box_w = 4, .box_h = 12, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 124, .adv_w = 154, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 136, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 147, .adv_w = 154, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 159, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 170, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 181, .adv_w = 154, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 193, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 204, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 215, .adv_w = 154, .box_w = 2, .box_h = 9, .ofs_x = 4, .ofs_y = 0}, + {.bitmap_index = 218, .adv_w = 154, .box_w = 2, .box_h = 12, .ofs_x = 4, .ofs_y = -3}, + {.bitmap_index = 221, .adv_w = 154, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 228, .adv_w = 154, .box_w = 7, .box_h = 5, .ofs_x = 1, .ofs_y = 3}, + {.bitmap_index = 233, .adv_w = 154, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 240, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 251, .adv_w = 154, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 265, .adv_w = 154, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 277, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 288, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 299, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 310, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 321, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 332, .adv_w = 154, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 344, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 355, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 366, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 377, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 388, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 399, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 410, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 421, .adv_w = 154, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 433, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 444, .adv_w = 154, .box_w = 8, .box_h = 14, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 458, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 469, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 480, .adv_w = 154, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 492, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 503, .adv_w = 154, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 515, .adv_w = 154, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 527, .adv_w = 154, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 539, .adv_w = 154, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 553, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 564, .adv_w = 154, .box_w = 3, .box_h = 16, .ofs_x = 3, .ofs_y = -2}, + {.bitmap_index = 570, .adv_w = 154, .box_w = 6, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 580, .adv_w = 154, .box_w = 3, .box_h = 16, .ofs_x = 3, .ofs_y = -2}, + {.bitmap_index = 586, .adv_w = 154, .box_w = 6, .box_h = 7, .ofs_x = 2, .ofs_y = 6}, + {.bitmap_index = 592, .adv_w = 154, .box_w = 7, .box_h = 1, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 593, .adv_w = 154, .box_w = 3, .box_h = 2, .ofs_x = 3, .ofs_y = 10}, + {.bitmap_index = 594, .adv_w = 154, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 602, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 613, .adv_w = 154, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 622, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 633, .adv_w = 154, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 642, .adv_w = 154, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 655, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 666, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 677, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 688, .adv_w = 154, .box_w = 5, .box_h = 15, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 698, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 709, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 720, .adv_w = 154, .box_w = 9, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 731, .adv_w = 154, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 739, .adv_w = 154, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 747, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 758, .adv_w = 154, .box_w = 7, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 769, .adv_w = 154, .box_w = 5, .box_h = 9, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 775, .adv_w = 154, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 783, .adv_w = 154, .box_w = 7, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 793, .adv_w = 154, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 801, .adv_w = 154, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 810, .adv_w = 154, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 821, .adv_w = 154, .box_w = 8, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 830, .adv_w = 154, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 842, .adv_w = 154, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 850, .adv_w = 154, .box_w = 5, .box_h = 16, .ofs_x = 3, .ofs_y = -3}, + {.bitmap_index = 860, .adv_w = 154, .box_w = 1, .box_h = 15, .ofs_x = 4, .ofs_y = -3}, + {.bitmap_index = 862, .adv_w = 154, .box_w = 6, .box_h = 16, .ofs_x = 2, .ofs_y = -3}, + {.bitmap_index = 874, .adv_w = 154, .box_w = 9, .box_h = 3, .ofs_x = 1, .ofs_y = 3} + }; + + /*--------------------- + * CHARACTER MAPPING + *--------------------*/ + + + + /*Collect the unicode lists and glyph_id offsets*/ + static const lv_font_fmt_txt_cmap_t cmaps[] = + { + { + .range_start = 32, .range_length = 95, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + } + }; + + + + /*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + + #if LVGL_VERSION_MAJOR == 8 + /*Store all the custom data of the font*/ + static lv_font_fmt_txt_glyph_cache_t cache; + #endif + + #if LVGL_VERSION_MAJOR >= 8 + static const lv_font_fmt_txt_dsc_t font_dsc = { + #else + static lv_font_fmt_txt_dsc_t font_dsc = { + #endif + .glyph_bitmap = glyph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = NULL, + .kern_scale = 0, + .cmap_num = 1, + .bpp = 1, + .kern_classes = 0, + .bitmap_format = 0, + #if LVGL_VERSION_MAJOR == 8 + .cache = &cache + #endif + }; + + + + /*----------------- + * PUBLIC FONT + *----------------*/ + + /*Initialize a public general font descriptor*/ + #if LVGL_VERSION_MAJOR >= 8 + const lv_font_t roboto_font = { + #else + lv_font_t roboto_font = { + #endif + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 18, /*The maximum line height required by the font*/ + .base_line = 4, /*Baseline measured from the bottom of the line*/ + #if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, + #endif + #if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 + .underline_position = -1, + .underline_thickness = 1, + #endif + .dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ + #if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9 + .fallback = NULL, + #endif + .user_data = NULL, + }; + + + + #endif /*#if ROBOTO_FONT*/ + + \ No newline at end of file diff --git a/Core/Src/graphics/font.c b/Core/Src/graphics/font.c new file mode 100644 index 0000000..8dd1929 --- /dev/null +++ b/Core/Src/graphics/font.c @@ -0,0 +1,148 @@ +#include "font.h" +#include "display.h" +#include "lvgl.h" +#include "stdbool.h" +#include + +static uint16_t find_glyph_id_in_cmap(const lv_font_fmt_txt_cmap_t * cmap, uint32_t character) +{ + uint16_t cmap_last_character = cmap->range_start + cmap->range_length - 1; + bool character_exists_in_cmap = character >= cmap->range_start && character <= cmap_last_character; + if (character_exists_in_cmap) + { + uint16_t glyph_id = cmap->glyph_id_start - cmap->range_start + character; + return glyph_id; + } + + return 0; +} + +bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_fmt_txt_glyph_dsc_t * dsc_out, uint32_t character) +{ + lv_font_fmt_txt_dsc_t *font_dsc = (lv_font_fmt_txt_dsc_t *) font->dsc; + for (uint16_t i = 0; i < font_dsc->cmap_num; i++) + { + uint16_t glyph_id = find_glyph_id_in_cmap(font_dsc->cmaps + i, character); + + if (glyph_id == 0) continue; + + *dsc_out = font_dsc->glyph_dsc[glyph_id]; + return true; + } + return false; +} + +const void * lv_font_get_bitmap_fmt_txt(lv_font_fmt_txt_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf) +{ + +} + +/** + * @brief Draws a single character to the framebuffer using the specified font. + * + * This function renders a character glyph from an LVGL font to the framebuffer at the + * specified location. The character is drawn in the provided color using a 1-bit bitmap + * format where set bits are drawn as colored pixels and unset bits are left transparent. + * + * @param framebuffer Pointer to the framebuffer array where the character will be drawn. + * Must be large enough to accommodate the character at the specified + * location (typically DISPLAY_HEIGHT * DISPLAY_WIDTH pixels). + * @param font Pointer to the LVGL font structure containing glyph data and metrics. + * The font must be a valid LVGL formatted text font (lv_font_fmt_txt_dsc_t). + * @param x_loc X coordinate (horizontal position) where the top-left of the character + * bounding box will be drawn. Must be within framebuffer bounds. + * @param y_loc Y coordinate (vertical position) where the top-left of the character + * bounding box will be drawn. Must be within framebuffer bounds. + * @param character The ASCII character code (0-255) to be drawn. + * @param color The RGB565 color value to use when drawing the character pixels. + * Pixels corresponding to set bits in the glyph bitmap will be drawn + * in this color. + * + * @return The advance width of the drawn glyph in pixels (lower 16 bits of glyph_dsc.adv_w). + * This value can be used to calculate the x position for the next character when + * drawing text. Returns 0 if the character glyph was not found in the font. + * + * @note The function performs no bounds checking. Ensure x_loc and y_loc are within + * the framebuffer dimensions to prevent buffer overruns. + * @note The glyph bitmap is stored in a packed 1-bit format where each bit represents + * one pixel (1 = draw pixel, 0 = skip pixel). + * @note If the character is not found in the font's character map, the function returns + * 0 without drawing anything. + */ +uint16_t draw_character(rgb565_pixel_t *framebuffer, const lv_font_t *font, const uint16_t x_loc, const uint16_t y_loc, const uint8_t character, rgb565_pixel_t color) +{ + const lv_font_fmt_txt_dsc_t *font_dsc = (lv_font_fmt_txt_dsc_t *)font->dsc; + lv_font_fmt_txt_glyph_dsc_t glyph_dsc; + bool glyph_found = lv_font_get_glyph_dsc_fmt_txt(font, &glyph_dsc, character); + if (!glyph_found) return 0; + + const uint16_t glyph_width = glyph_dsc.box_w; + const uint16_t glyph_height = glyph_dsc.box_h; + const int8_t glyph_ofs_x = glyph_dsc.ofs_x; + const int8_t glyph_ofs_y = glyph_dsc.ofs_y; + const uint32_t num_bitmap_bits = glyph_height * glyph_width; + + for (uint32_t bitmap_pixel_index = 0; bitmap_pixel_index < num_bitmap_bits; bitmap_pixel_index++) + { + const uint8_t current_bit_in_byte = bitmap_pixel_index % 8; + const uint16_t bitmap_byte_index = glyph_dsc.bitmap_index + (bitmap_pixel_index / 8); + const uint32_t fb_pixel_x = x_loc + (bitmap_pixel_index % glyph_width) + glyph_ofs_x; + const uint32_t line_top = y_loc + font->base_line - glyph_height; + const uint32_t fb_pixel_y = line_top + (bitmap_pixel_index / glyph_width) - glyph_ofs_y; + const uint32_t fb_pixel_index = (fb_pixel_y * DISPLAY_WIDTH) + fb_pixel_x; + + const bool bit_on = font_dsc->glyph_bitmap[bitmap_byte_index] & (0x80 >> current_bit_in_byte); + if (bit_on) + { + framebuffer[fb_pixel_index] = color; + } + } + + return (glyph_dsc.adv_w & 0x0000FFFF); +} + +/** + * @brief Draws a null-terminated string to the framebuffer using the specified font. + * + * This function renders a complete string of characters to the framebuffer by iteratively + * calling draw_character() for each character in the string. Characters are drawn horizontally + * from left to right, with each character's advance width determining the spacing for the + * next character. All characters are drawn on the same baseline (y_loc remains constant). + * + * @param framebuffer Pointer to the framebuffer array where the string will be drawn. + * Must be large enough to accommodate the entire string at the specified + * location (typically DISPLAY_HEIGHT * DISPLAY_WIDTH pixels). + * @param font Pointer to the LVGL font structure containing glyph data and metrics. + * The font must be a valid LVGL formatted text font (lv_font_fmt_txt_dsc_t). + * @param x_loc X coordinate (horizontal position) where the first character's top-left + * bounding box will be drawn. Must be within framebuffer bounds. + * @param y_loc Y coordinate (vertical position) where all characters' top-left bounding + * boxes will be drawn. Must be within framebuffer bounds. + * @param string Pointer to a null-terminated C string (array of uint8_t) containing + * the characters to be drawn. The function will stop drawing when it + * encounters a null terminator ('\0'). + * @param color The RGB565 color value to use when drawing all character pixels. + * Pixels corresponding to set bits in each glyph bitmap will be drawn + * in this color. + * + * @note The function performs no bounds checking. Ensure x_loc and y_loc are within + * the framebuffer dimensions, and that the entire string will fit within the + * framebuffer bounds to prevent buffer overruns. + * @note Characters not found in the font (draw_character returns 0) will be skipped + * without advancing the x position, which may cause subsequent characters to + * overlap with missing characters. + * @note The string must be null-terminated. The function will continue drawing until + * it encounters a '\0' character. + * @note All characters in the string are drawn on the same horizontal baseline (y_loc + * remains constant for all characters). + */ +void draw_string(rgb565_pixel_t *framebuffer, const lv_font_t *font, const uint16_t x_loc, const uint16_t y_loc, const uint8_t *string, rgb565_pixel_t color) +{ + uint32_t current_x = x_loc << 4; + + for (const uint8_t *char_ptr = string; *char_ptr != '\0'; char_ptr++) + { + uint16_t advance_width = draw_character(framebuffer, font, current_x >> 4, y_loc, *char_ptr, color); + current_x += advance_width; + } +} diff --git a/Core/Src/graphics.c b/Core/Src/graphics/graphics.c similarity index 81% rename from Core/Src/graphics.c rename to Core/Src/graphics/graphics.c index e91abf3..98f8bd1 100644 --- a/Core/Src/graphics.c +++ b/Core/Src/graphics/graphics.c @@ -1,8 +1,8 @@ -#include "graphics.h" +#include "display.h" #include "stm32f4xx_hal_ltdc.h" __attribute__((section(".sdram"))) -volatile Pixel_t framebuffer[DISPLAY_HEIGHT * DISPLAY_WIDTH]; +volatile rgb565_pixel_t framebuffer[DISPLAY_HEIGHT * DISPLAY_WIDTH]; __attribute__((section(".sdram"))) volatile uint32_t times_changed; diff --git a/Core/Src/main.c b/Core/Src/main.c index 19711f9..daa22e8 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -25,7 +25,9 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ -#include "graphics.h" +#include "display.h" +#include "font.h" +#include "roboto_bold_font.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -865,8 +867,10 @@ void StartDefaultTask(void const * argument) for(;;) { DisplayTest(0xffff); + draw_string(framebuffer, &roboto_bold_font, 25, 25, "Divide Voltage!", 0x0000); osDelay(500); DisplayTest(0x0000); + draw_string(framebuffer, &roboto_bold_font, 25, 25, "Divide Voltage!", 0xf800); osDelay(500); } /* USER CODE END 5 */ diff --git a/STM32Make.make b/STM32Make.make index 992d871..580f2fc 100644 --- a/STM32Make.make +++ b/STM32Make.make @@ -76,7 +76,8 @@ endif # C sources C_SOURCES = \ Core/Src/freertos.c \ -Core/Src/graphics.c \ +Core/Src/graphics/font.c \ +Core/Src/graphics/graphics.c \ Core/Src/main.c \ Core/Src/stm32f4xx_hal_msp.c \ Core/Src/stm32f4xx_hal_timebase_tim.c \ @@ -223,6 +224,8 @@ AS_INCLUDES = \ # C includes C_INCLUDES = \ -ICore/Inc \ +-ICore/Inc/graphics \ +-ICore/Inc/graphics/lvgl \ -IDrivers/CMSIS/Device/ST/STM32F4xx/Include \ -IDrivers/CMSIS/Include \ -IDrivers/STM32F4xx_HAL_Driver/Inc \