From 96afa57d84482da608d53ae8f9f8873c20fe728f Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Fri, 29 Jun 2018 17:26:04 +0200 Subject: [PATCH] use RLE compressed fonts on Horus --- radio/src/bitmaps/480x272/CMakeLists.txt | 4 +- radio/src/fonts.h | 14 +++--- radio/src/gui/480x272/fonts.cpp | 45 +++++++++++++++++-- radio/src/gui/480x272/rle.cpp | 38 ++++++++++++++++ radio/src/gui/480x272/rle.h | 7 +++ radio/src/opentx.cpp | 5 +++ .../arm/stm32/bootloader/CMakeLists.txt | 1 + radio/src/targets/horus/CMakeLists.txt | 1 + .../targets/horus/bootloader/boot_menu.cpp | 3 ++ radio/util/img2lbm.py | 2 +- 10 files changed, 106 insertions(+), 14 deletions(-) create mode 100644 radio/src/gui/480x272/rle.cpp create mode 100644 radio/src/gui/480x272/rle.h diff --git a/radio/src/bitmaps/480x272/CMakeLists.txt b/radio/src/bitmaps/480x272/CMakeLists.txt index 26cfd2d44..34a42f37c 100644 --- a/radio/src/bitmaps/480x272/CMakeLists.txt +++ b/radio/src/bitmaps/480x272/CMakeLists.txt @@ -8,7 +8,7 @@ if(PCB STREQUAL X12S) add_bitmaps_target(x12s_slider_masks "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/slider/*.png" 480 8bits) add_bitmaps_target(x12s_layouts_masks "${RADIO_SRC_DIRECTORY}/gui/480x272/layouts/*.png" 480 8bits) add_bitmaps_target(x12s_themes_bitmaps "${RADIO_SRC_DIRECTORY}/gui/480x272/themes/*.png" 480 5/6/5) - add_bitmaps_target(x12s_fonts ${RADIO_SRC_DIRECTORY}/fonts/480x272/*.png 480 8bits) + add_bitmaps_target(x12s_fonts ${RADIO_SRC_DIRECTORY}/fonts/480x272/*.png 480 8bits rle) add_bitmaps_target(x12s_volume_masks ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/volume/*.png 480 8bits) add_bitmaps_target(x12s_bootloader_bitmaps ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/bootloader/bmp_*.png 480 5/6/5) add_bitmaps_target(x12s_bootloader_icons ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/bootloader/icon_*.png 480 8bits) @@ -23,7 +23,7 @@ else() add_bitmaps_target(x10_slider_masks "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/slider/*.png" 480 8bits) add_bitmaps_target(x10_layouts_masks "${RADIO_SRC_DIRECTORY}/gui/480x272/layouts/*.png" 480 8bits) add_bitmaps_target(x10_themes_bitmaps "${RADIO_SRC_DIRECTORY}/gui/480x272/themes/*.png" 480 5/6/5-R) - add_bitmaps_target(x10_fonts ${RADIO_SRC_DIRECTORY}/fonts/480x272/*.png 480 8bits) + add_bitmaps_target(x10_fonts ${RADIO_SRC_DIRECTORY}/fonts/480x272/*.png 480 8bits rle) add_bitmaps_target(x10_volume_masks ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/volume/*.png 480 8bits) add_bitmaps_target(x10_bootloader_bitmaps ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/bootloader/bmp_*.png 480 5/6/5-R) add_bitmaps_target(x10_bootloader_icons ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/bootloader/icon_*.png 480 8bits) diff --git a/radio/src/fonts.h b/radio/src/fonts.h index eb7725181..d102cf67e 100644 --- a/radio/src/fonts.h +++ b/radio/src/fonts.h @@ -24,17 +24,17 @@ #if defined(COLORLCD) #if !defined(BOOT) -extern const uint16_t * const fontspecsTable[16]; -extern const uint8_t * const fontsTable[16]; +#define FONT_TABLE_SIZE 16 #else -extern const uint16_t * const fontspecsTable[1]; -extern const uint8_t * const fontsTable[1]; +#define FONT_TABLE_SIZE 1 #endif -#if defined(PCBHORUS) -extern BitmapBuffer * fontCache[2]; +extern const uint16_t * const fontspecsTable[FONT_TABLE_SIZE]; +extern const uint8_t * fontsTable[FONT_TABLE_SIZE]; +extern BitmapBuffer * fontCache[2]; + void loadFontCache(); -#endif +void loadFonts(); #else diff --git a/radio/src/gui/480x272/fonts.cpp b/radio/src/gui/480x272/fonts.cpp index 75cc2b983..8a3d65112 100644 --- a/radio/src/gui/480x272/fonts.cpp +++ b/radio/src/gui/480x272/fonts.cpp @@ -19,6 +19,7 @@ */ #include "opentx.h" +#include "rle.h" #if !defined(BOOT) const uint16_t font_tinsize_specs[] = { @@ -82,17 +83,18 @@ const pm_uchar font_stdsizebold[] = { #if !defined(BOOT) const uint16_t * const fontspecsTable[16] = { - font_stdsize_specs, font_tinsize_specs, font_smlsize_specs, font_midsize_specs, font_dblsize_specs, font_xxlsize_specs, font_stdsize_specs, font_stdsize_specs, + font_stdsize_specs, font_tinsize_specs, font_smlsize_specs, font_midsize_specs, font_dblsize_specs, font_xxlsize_specs, font_stdsize_specs, font_stdsize_specs, font_stdsizebold_specs, font_tinsize_specs, font_smlsize_specs, font_midsize_specs, font_dblsize_specs, font_xxlsize_specs, font_stdsize_specs, font_stdsize_specs }; -const uint8_t * const fontsTable[16] = { - font_stdsize, font_tinsize, font_smlsize, font_midsize, font_dblsize, font_xxlsize, font_stdsize, font_stdsize, +const uint8_t * fontsTable[16] = { + font_stdsize, font_tinsize, font_smlsize, font_midsize, font_dblsize, font_xxlsize, font_stdsize, font_stdsize, font_stdsizebold, font_tinsize, font_smlsize, font_midsize, font_dblsize, font_xxlsize, font_stdsize, font_stdsize }; + #else const uint16_t * const fontspecsTable[1] = { font_stdsize_specs }; -const uint8_t * const fontsTable[1] = { font_stdsize }; +const uint8_t * fontsTable[1] = { font_stdsize }; #endif BitmapBuffer * fontCache[2] = { NULL, NULL }; @@ -117,3 +119,38 @@ void loadFontCache() fontCache[0] = createFontCache(fontsTable[0], TEXT_COLOR, TEXT_BGCOLOR); fontCache[1] = createFontCache(fontsTable[0], TEXT_INVERTED_COLOR, TEXT_INVERTED_BGCOLOR); } + + +static uint8_t* decompressFont(const uint8_t* font) +{ + uint16_t width = *((uint16_t *)font); + uint16_t height = *(((uint16_t *)font)+1); + + size_t font_size = width * height; + uint8_t* dec_buf = (uint8_t*)malloc(font_size + 4); + + // copy width / height + memcpy(dec_buf,font,4); + + rle_decode_8bit(dec_buf+4, font_size, font+4); + return dec_buf; +} + +void loadFonts() +{ + static bool fonts_loaded = false; + if (fonts_loaded) return; + +#if !defined(BOOT) + int i=0; + for (; i<9; i++) + fontsTable[i] = decompressFont(fontsTable[i]); + + for (; i<16; i++) + fontsTable[i] = fontsTable[i-9]; +#else + fontsTable[0] = decompressFont(fontsTable[0]); +#endif + + fonts_loaded = true; +} diff --git a/radio/src/gui/480x272/rle.cpp b/radio/src/gui/480x272/rle.cpp new file mode 100644 index 000000000..e4be583a5 --- /dev/null +++ b/radio/src/gui/480x272/rle.cpp @@ -0,0 +1,38 @@ +#include "rle.h" +#include "debug.h" + +#include + +int rle_decode_8bit(unsigned char* dest, unsigned int dest_size, const unsigned char* src) +{ + //unsigned char count = 0; + unsigned char prev_byte = 0; + bool prev_byte_valid = false; + + const unsigned char* dest_end = dest + dest_size; + unsigned char* d = dest; + + while(d < dest_end) { + + *d++ = *src; + if (prev_byte_valid && (*src == prev_byte)) { + + src++; + + if (d + *src > dest + dest_size) { + TRACE("rle_decode_8bit: destination overflow!\n"); + return -1; + } + + memset(d, prev_byte, *src); + d += *src++; + prev_byte_valid = false; + } + else { + prev_byte = *src++; + prev_byte_valid = true; + } + } + + return d - dest; +} diff --git a/radio/src/gui/480x272/rle.h b/radio/src/gui/480x272/rle.h new file mode 100644 index 000000000..4781216f0 --- /dev/null +++ b/radio/src/gui/480x272/rle.h @@ -0,0 +1,7 @@ +#ifndef _rle_h_ +#define _rle_h_ + +int rle_decode_8bit(unsigned char* dest, unsigned int dest_size, const unsigned char* src); + + +#endif diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index c07f955d3..de8adb602 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -2201,6 +2201,11 @@ int main() bluetoothInit(BLUETOOTH_DEFAULT_BAUDRATE); //BT is turn on for a brief period to differentiate X7 and X7S #endif +#if defined(PCBHORUS) + loadFonts(); +#endif + + #if defined(GUI) && !defined(PCBTARANIS) && !defined(PCBHORUS) // TODO remove this lcdInit(); diff --git a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt index 770e03d3a..bb55c6af4 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt @@ -93,6 +93,7 @@ else() ../../../../../targets/common/arm/stm32/sdio_sd.c ../../../../../targets/${TARGET_DIR}/haptic_driver.cpp ../../../../../gui/${GUI_DIR}/bitmapbuffer.cpp + ../../../../../gui/${GUI_DIR}/rle.cpp ../../../../../syscalls.c ) diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index 565b102b6..41782a624 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -101,6 +101,7 @@ set(GUI_SRC ${THEMES_SRC} ${LAYOUTS_SRC} ${WIDGETS_SRC} + rle.cpp ) if(DISK_CACHE) set(SRC ${SRC} disk_cache.cpp) diff --git a/radio/src/targets/horus/bootloader/boot_menu.cpp b/radio/src/targets/horus/bootloader/boot_menu.cpp index b50b9c729..23b711c34 100644 --- a/radio/src/targets/horus/bootloader/boot_menu.cpp +++ b/radio/src/targets/horus/bootloader/boot_menu.cpp @@ -40,6 +40,9 @@ void bootloaderInitScreen() lcdColorTable[BARGRAPH2_COLOR_INDEX] = RGB(73, 219, 62); // green backlightEnable(BACKLIGHT_LEVEL_MAX); + + //TODO: load/decompress bitmaps + loadFonts(); } static void bootloaderDrawTitle(unsigned int x, const char* text) diff --git a/radio/util/img2lbm.py b/radio/util/img2lbm.py index 800b9735e..692a8efd0 100755 --- a/radio/util/img2lbm.py +++ b/radio/util/img2lbm.py @@ -91,7 +91,7 @@ with open(output_filename, "w") as f: extension = os.path.splitext(output_filename)[1] out = F_writeValue(f) - if extension == ".rle": + if extension == ".rle" or ((len(sys.argv) > 5) and (sys.argv[5] == "rle")): encoder = RLE_encoder(out) else: encoder = dummy_encoder(out)