From c4abd85c54e5c930a8a587ca7f99b635c4401a17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Mon, 28 Jun 2021 08:59:05 +0200 Subject: [PATCH] feat: add support for font family --- file-browser/src/main.c | 2 +- lib-gui/include/font.h | 76 ++++++++++++++++++++++++----------------- lib-gui/src/font.c | 46 +++++++++++++++++++++++-- lib-gui/src/renderer.c | 3 +- text-viewer/src/main.c | 2 +- 5 files changed, 92 insertions(+), 37 deletions(-) diff --git a/file-browser/src/main.c b/file-browser/src/main.c index ff1e087d3da21e8da1f01d0f599bedea05bb12d7..0f6a7ecf9e293eb9791f5f5bf4e9181e086da644 100644 --- a/file-browser/src/main.c +++ b/file-browser/src/main.c @@ -81,7 +81,7 @@ int main(int argc, char *argv[]) { mzapo_pheripherals_t pheripherals = mzapo_pheripherals_create(&ledstrip, &rgb_leds, &display, &knobs); - font_t font = font_create(font_rom8x16); + font_t font = font_family_create(font_wTahoma_22, &fontFamily_wTahoma); font.char_spacing = 2; file_browser_t file_browser = file_browser_create(pheripherals, &logger, font); diff --git a/lib-gui/include/font.h b/lib-gui/include/font.h index f824878fa57b4a62153ea6a1911f2841a9d96fd0..15dd1840d225a637115447b61d2691df66bf4851 100644 --- a/lib-gui/include/font.h +++ b/lib-gui/include/font.h @@ -1,8 +1,8 @@ #ifndef __FONT_H__ #define __FONT_H__ -#include #include +#include typedef uint16_t font_bits_t; @@ -30,11 +30,18 @@ struct font_descriptor_t { uint32_t default_char; - font_descriptor_t* font_next_part; + font_descriptor_t *font_next_part; }; +typedef struct { + font_descriptor_t **descriptors; + uint16_t descriptors_count; +} font_family_t; + typedef struct { font_descriptor_t font; + font_family_t *family; + uint16_t size; uint16_t line_spacing; @@ -50,67 +57,72 @@ typedef coords_t size2d_t; /** * @brief Create font from given descriptor - * - * @param descriptor - * @return font_t + * + * @param descriptor + * @return font_t */ font_t font_create(font_descriptor_t descriptor); +font_t font_family_create(font_descriptor_t def, font_family_t *family); +font_descriptor_t *font_family_get_descriptor(font_t *font); uint32_t font_get_real_char(char *text, uint16_t *bytes); - /** - * @brief Get text dimensions for given font - * - * @param font - * @param text - * @return size2d_t + * @brief Get text dimensions for given font + * + * @param font + * @param text + * @return size2d_t */ size2d_t font_measure_text(font_t *font, char *text); /** * @brief Get font character for font from char - * - * @param font - * @param c - * @return font_character_t + * + * @param font + * @param c + * @return font_character_t */ font_character_t font_get_character(font_t *font, uint32_t c); /** - * @brief Get whether font contains font character - * - * @param font - * @param c - * @return true character is in font + * @brief Get whether font contains font character + * + * @param font + * @param c + * @return true character is in font * @return false character is not in font */ bool font_contains_character(font_t *font, uint32_t c); /** * @brief Fit text with ellipsis to get how many characters can be shown - * - * @param font - * @param size - * @param text - * @param ellipsis + * + * @param font + * @param size + * @param text + * @param ellipsis * @return uint16_t number of characters that can be fit */ -uint16_t font_fit_ellipsis(font_t *font, size2d_t size, char *text, char *ellipsis); +uint16_t font_fit_ellipsis(font_t *font, size2d_t size, char *text, + char *ellipsis); /** - * @brief Fit cut text without any ellipsis to get how many characters can be shown - * - * @param font - * @param size - * @param text - * @return uint16_t + * @brief Fit cut text without any ellipsis to get how many characters can be + * shown + * + * @param font + * @param size + * @param text + * @return uint16_t */ uint16_t font_fit_cut(font_t *font, size2d_t size, char *text); extern font_descriptor_t font_rom8x16; extern font_descriptor_t font_winFreeSystem14x16; extern font_descriptor_t font_wTahoma_40; +extern font_descriptor_t font_wTahoma_22; +extern font_family_t fontFamily_wTahoma; #endif // __FONT_H__ diff --git a/lib-gui/src/font.c b/lib-gui/src/font.c index f74b30cfdfc4961b39609e299501f271f8de6353..d5ba0ec387b39323a804d068c4000ff34256d678 100644 --- a/lib-gui/src/font.c +++ b/lib-gui/src/font.c @@ -1,9 +1,38 @@ #include "font.h" #include #include + static bool font_descriptor_contains_character(font_descriptor_t **descriptor, uint32_t c); + +static int32_t absolute(int32_t a) { + return a < 0 ? -a : a; +} + +font_descriptor_t *font_family_get_descriptor(font_t *font) { + if (font->family == NULL) { + return &font->font; + } + + + int32_t nearest = font->family->descriptors[0]->height, nearest_index = 0; + for (int i = 1; i < font->family->descriptors_count; i++) { + font_descriptor_t *descriptor = font->family->descriptors[i]; + + int32_t diff = absolute(descriptor->height - font->size); + int32_t nearest_diff = absolute(nearest - font->size); + + if (diff < nearest_diff) { + nearest_index = i; + nearest = descriptor->height; + } + } + + printf("%d\r\n", nearest_index); + return font->family->descriptors[nearest_index]; +} + uint32_t font_get_real_char(char *text, uint16_t *bytes) { *bytes = 1; uint8_t first_byte_offset = 0; @@ -59,6 +88,19 @@ font_t font_create(font_descriptor_t descriptor) { .size = descriptor.height, .char_spacing = 0, .line_spacing = 0, + .family = NULL, + }; + + return font; +} + +font_t font_family_create(font_descriptor_t def, font_family_t *family) { + font_t font = { + .font = def, + .size = family->descriptors[0]->height, + .char_spacing = 0, + .line_spacing = 0, + .family = family, }; return font; @@ -82,7 +124,7 @@ size2d_t font_measure_text(font_t *font, char *text) { } font_character_t font_get_character(font_t *font, uint32_t c) { - font_descriptor_t *descriptor = &font->font; + font_descriptor_t *descriptor = font_family_get_descriptor(font); if (!font_descriptor_contains_character(&descriptor, c)) { return font_get_character(font, font->font.default_char); @@ -124,7 +166,7 @@ static bool font_descriptor_contains_character(font_descriptor_t **descriptor, } bool font_contains_character(font_t *font, uint32_t c){ - font_descriptor_t *descriptor = &font->font; + font_descriptor_t *descriptor = font_family_get_descriptor(font); return font_descriptor_contains_character(&descriptor, c); } diff --git a/lib-gui/src/renderer.c b/lib-gui/src/renderer.c index fd80f3235d7d82b5ecedae80b89cffc260102d18..0ee6e381d401f35f36614d16ce49cb123e74b43a 100644 --- a/lib-gui/src/renderer.c +++ b/lib-gui/src/renderer.c @@ -99,7 +99,8 @@ static coords_t renderer_get_char_xy(int64_t x, int64_t y, uint64_t downscale_i, size2d_t renderer_write_char(renderer_t *renderer, uint16_t bx, uint16_t by, font_t *font, uint32_t c, display_pixel_t color) { - double scale = (double)font->size / font->font.height; + font_descriptor_t *descriptor = font_family_get_descriptor(font); + double scale = (double)font->size / descriptor->height; double downscale = 1 / scale; uint64_t convert = 100000; diff --git a/text-viewer/src/main.c b/text-viewer/src/main.c index 96c465a5ec4e52694692210cdc1a3c526c3434c1..cdebd203020051d140690a498f215b053c224505 100644 --- a/text-viewer/src/main.c +++ b/text-viewer/src/main.c @@ -65,7 +65,7 @@ int main(int argc, char *argv[]) { mzapo_pheripherals_t pheripherals = mzapo_pheripherals_create(&ledstrip, &rgb_leds, &display, &knobs); - font_t font = font_create(font_wTahoma_40); + font_t font = font_family_create(font_wTahoma_22, &fontFamily_wTahoma); font.size = 20; font.char_spacing = 2;