knxdisplay/main/Fonts.cpp
2026-01-25 11:56:24 +01:00

121 lines
3.7 KiB
C++

#include "Fonts.hpp"
#include "esp_log.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <cstddef>
#if CONFIG_ESP_LVGL_ADAPTER_ENABLE_FREETYPE
#include "esp_lv_adapter.h"
#include <sys/stat.h>
#endif
namespace {
static const char* TAG = "Fonts";
static constexpr const char* kFontPath = "/sdcard/fonts/Montserrat-Medium.ttf";
static constexpr uint16_t kFontSizes[] = {14, 18, 22, 28, 36, 48};
static constexpr size_t kFontCount = sizeof(kFontSizes) / sizeof(kFontSizes[0]);
static const lv_font_t* s_fonts[kFontCount] = {nullptr};
static bool s_initialized = false;
const lv_font_t* fallbackFont(uint8_t sizeIndex) {
switch (sizeIndex) {
case 0: return &lv_font_montserrat_14;
#if LV_FONT_MONTSERRAT_18
case 1: return &lv_font_montserrat_18;
#endif
#if LV_FONT_MONTSERRAT_22
case 2: return &lv_font_montserrat_22;
#endif
#if LV_FONT_MONTSERRAT_28
case 3: return &lv_font_montserrat_28;
#endif
#if LV_FONT_MONTSERRAT_36
case 4: return &lv_font_montserrat_36;
#endif
#if LV_FONT_MONTSERRAT_48
case 5: return &lv_font_montserrat_48;
#endif
default: return &lv_font_montserrat_14;
}
}
#if CONFIG_ESP_LVGL_ADAPTER_ENABLE_FREETYPE
bool fontFileExists() {
struct stat st;
return stat(kFontPath, &st) == 0;
}
#endif
} // namespace
void Fonts::init() {
#if CONFIG_ESP_LVGL_ADAPTER_ENABLE_FREETYPE
ESP_LOGI(TAG, "FreeType enabled");
if (s_initialized) {
ESP_LOGI(TAG, "Already initialized");
return;
}
s_initialized = true;
if (!fontFileExists()) {
ESP_LOGW(TAG, "Font file not found: %s", kFontPath);
return;
}
ESP_LOGI(TAG, "Font file exists: %s", kFontPath);
// Give LVGL task time to start and release mutex
ESP_LOGI(TAG, "Waiting for LVGL task...");
vTaskDelay(pdMS_TO_TICKS(500));
// Test if LVGL lock is available
ESP_LOGI(TAG, "Testing LVGL lock...");
if (esp_lv_adapter_lock(1000) == ESP_OK) { // 1 second timeout
ESP_LOGI(TAG, "Lock acquired OK, releasing...");
esp_lv_adapter_unlock();
} else {
ESP_LOGE(TAG, "Could not acquire LVGL lock - something is holding it!");
return; // Don't try to init fonts if lock is stuck
}
for (size_t i = 0; i < kFontCount; ++i) {
ESP_LOGI(TAG, "Loading font size %u...", kFontSizes[i]);
esp_lv_adapter_ft_font_config_t cfg = {};
cfg.name = kFontPath;
cfg.size = kFontSizes[i];
cfg.style = ESP_LV_ADAPTER_FT_FONT_STYLE_NORMAL;
cfg.mem = nullptr;
cfg.mem_size = 0;
esp_lv_adapter_ft_font_handle_t handle = nullptr;
ESP_LOGI(TAG, "Calling esp_lv_adapter_ft_font_init (free heap: %lu)...",
(unsigned long)esp_get_free_heap_size());
esp_err_t ret = esp_lv_adapter_ft_font_init(&cfg, &handle);
ESP_LOGI(TAG, "esp_lv_adapter_ft_font_init returned %d", ret);
if (ret != ESP_OK || handle == nullptr) {
ESP_LOGW(TAG, "Failed to load FreeType font size %u (err=%d)", cfg.size, ret);
continue;
}
s_fonts[i] = esp_lv_adapter_ft_font_get(handle);
if (!s_fonts[i]) {
ESP_LOGW(TAG, "FreeType font handle returned null for size %u", cfg.size);
}
ESP_LOGI(TAG, "Font size %u loaded successfully", kFontSizes[i]);
}
ESP_LOGI(TAG, "Font initialization complete");
#else
ESP_LOGI(TAG, "FreeType disabled, using built-in fonts");
#endif
}
const lv_font_t* Fonts::bySizeIndex(uint8_t sizeIndex) {
#if CONFIG_ESP_LVGL_ADAPTER_ENABLE_FREETYPE
if (sizeIndex < kFontCount && s_fonts[sizeIndex]) {
return s_fonts[sizeIndex];
}
#endif
return fallbackFont(sizeIndex);
}