From a2d86eac6d119ee605fd164855e8ff69a46b1539 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 13 Nov 2020 11:03:37 +1100 Subject: [PATCH] AP_OSD: allow for loading fonts from sdcard user can put fontN.bin on their sdcard and it will replace the font in romfs. This makes for easy font development, and allows for multiple languages This replaces #15668 --- libraries/AP_OSD/AP_OSD_Backend.cpp | 23 +++++++++++++++++++++++ libraries/AP_OSD/AP_OSD_Backend.h | 4 ++++ libraries/AP_OSD/AP_OSD_MAX7456.cpp | 28 +++++++++++++++------------- libraries/AP_OSD/AP_OSD_SITL.cpp | 16 ++++------------ libraries/AP_OSD/AP_OSD_Screen.cpp | 14 ++++++-------- 5 files changed, 52 insertions(+), 33 deletions(-) diff --git a/libraries/AP_OSD/AP_OSD_Backend.cpp b/libraries/AP_OSD/AP_OSD_Backend.cpp index 4137c84e86..3715cae280 100644 --- a/libraries/AP_OSD/AP_OSD_Backend.cpp +++ b/libraries/AP_OSD/AP_OSD_Backend.cpp @@ -51,3 +51,26 @@ void AP_OSD_Backend::write(uint8_t x, uint8_t y, bool blink, const char *fmt, .. va_end(ap); #endif } + +/* + load a font from sdcard or ROMFS + */ +FileData *AP_OSD_Backend::load_font_data(uint8_t font_num) +{ + FileData *fd; + + // first try from microSD + char fontname[] = "font0.bin"; + fontname[4] = font_num + '0'; + + fd = AP::FS().load_file(fontname); + if (fd == nullptr) { + char fontname_romfs[] = "@ROMFS/font0.bin"; + fontname_romfs[7+4] = font_num + '0'; + fd = AP::FS().load_file(fontname_romfs); + } + if (fd == nullptr) { + GCS_SEND_TEXT(MAV_SEVERITY_ERROR, "OSD: Failed to load font %u", font_num); + } + return fd; +} diff --git a/libraries/AP_OSD/AP_OSD_Backend.h b/libraries/AP_OSD/AP_OSD_Backend.h index afc3913e66..4fe7cd4696 100644 --- a/libraries/AP_OSD/AP_OSD_Backend.h +++ b/libraries/AP_OSD/AP_OSD_Backend.h @@ -18,6 +18,7 @@ #include #include +#include class AP_OSD_Backend @@ -72,6 +73,9 @@ protected: return (_osd.options & option) != 0; } + // load a font from sdcard or ROMFS + FileData *load_font_data(uint8_t font_num); + int8_t blink_phase; enum vid_format { diff --git a/libraries/AP_OSD/AP_OSD_MAX7456.cpp b/libraries/AP_OSD/AP_OSD_MAX7456.cpp index 3ee3ca036f..c4677aa7a1 100644 --- a/libraries/AP_OSD/AP_OSD_MAX7456.cpp +++ b/libraries/AP_OSD/AP_OSD_MAX7456.cpp @@ -22,7 +22,8 @@ #include #include #include -#include +#include +#include #include @@ -157,13 +158,19 @@ bool AP_OSD_MAX7456::init() bool AP_OSD_MAX7456::update_font() { - uint32_t font_size; uint8_t updated_chars = 0; - char fontname[] = "font0.bin"; last_font = get_font_num(); - fontname[4] = last_font + '0'; - const uint8_t *font_data = AP_ROMFS::find_decompress(fontname, font_size); - if (font_data == nullptr || font_size != NVM_RAM_SIZE * 256) { + FileData *fd = load_font_data(last_font); + + if (fd == nullptr) { + return false; + } + + const uint8_t *font_data = fd->data; + uint32_t font_size = fd->length; + if (font_size != NVM_RAM_SIZE * 256) { + GCS_SEND_TEXT(MAV_SEVERITY_ERROR, "AP_OSD: bad font size %u\n", unsigned(font_size)); + delete fd; return false; } @@ -173,18 +180,13 @@ bool AP_OSD_MAX7456::update_font() if (!check_font_char(chr, chr_font_data)) { //update char inside max7456 NVM if (!update_font_char(chr, chr_font_data)) { - hal.console->printf("AP_OSD: error during font char update\n"); - AP_ROMFS::free(font_data); + delete fd; return false; } updated_chars++; } } - if (updated_chars > 0) { - hal.console->printf("AP_OSD: updated %d symbols.\n", updated_chars); - } - hal.console->printf("AP_OSD: osd font is up to date.\n"); - AP_ROMFS::free(font_data); + delete fd; return true; } diff --git a/libraries/AP_OSD/AP_OSD_SITL.cpp b/libraries/AP_OSD/AP_OSD_SITL.cpp index 59ccb88bb8..07762fef03 100644 --- a/libraries/AP_OSD/AP_OSD_SITL.cpp +++ b/libraries/AP_OSD/AP_OSD_SITL.cpp @@ -43,21 +43,13 @@ extern const AP_HAL::HAL &hal; */ void AP_OSD_SITL::load_font(void) { - uint32_t font_size; - char fontname[] = "font0.bin"; last_font = get_font_num(); - fontname[4] = last_font + '0'; - const uint8_t *font_data = AP_ROMFS::find_decompress(fontname, font_size); - if (font_data == nullptr && last_font != 0) { - last_font = 0; - fontname[4] = last_font + '0'; - font_data = AP_ROMFS::find_decompress(fontname, font_size); - } - if (font_data == nullptr || font_size != 54 * 256) { + FileData *fd = load_font_data(last_font); + if (fd == nullptr || fd->length != 54 * 256) { AP_HAL::panic("Bad font file"); } for (uint16_t i=0; i<256; i++) { - const uint8_t *c = &font_data[i*54]; + const uint8_t *c = &fd->data[i*54]; // each pixel is 4 bytes, RGBA sf::Uint8 *pixels = new sf::Uint8[char_width * char_height * 4]; if (!font[i].create(char_width, char_height)) { @@ -97,7 +89,7 @@ void AP_OSD_SITL::load_font(void) } font[i].update(pixels); } - AP_ROMFS::free(font_data); + delete fd; } void AP_OSD_SITL::write(uint8_t x, uint8_t y, const char* text) diff --git a/libraries/AP_OSD/AP_OSD_Screen.cpp b/libraries/AP_OSD/AP_OSD_Screen.cpp index c4e1c5d5b0..47beff5f71 100644 --- a/libraries/AP_OSD/AP_OSD_Screen.cpp +++ b/libraries/AP_OSD/AP_OSD_Screen.cpp @@ -1777,17 +1777,15 @@ void AP_OSD_Screen::draw_callsign(uint8_t x, uint8_t y) #if HAVE_FILESYSTEM_SUPPORT if (!callsign_data.load_attempted) { callsign_data.load_attempted = true; - int fd = AP::FS().open("callsign.txt", O_RDONLY); - if (fd != -1) { - char s[20] {}; - int32_t len = AP::FS().read(fd, s, sizeof(s)-1); + FileData *fd = AP::FS().load_file("callsign.txt"); + if (fd != nullptr) { + uint32_t len = fd->length; // trim off whitespace - while (len > 0 && isspace(s[len-1])) { - s[len-1] = 0; + while (len > 0 && isspace(fd->data[len-1])) { len--; } - AP::FS().close(fd); - callsign_data.str = strdup(s); + callsign_data.str = strndup((const char *)fd->data, len); + delete fd; } } if (callsign_data.str != nullptr) {