font_provider.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #include "font_provider.h"
  2. #include <inttypes.h>
  3. #include <toolbox/dir_walk.h>
  4. #include <toolbox/path.h>
  5. #include <toolbox/stream/stream.h>
  6. #include <toolbox/stream/file_stream.h>
  7. #define FONT_BASE_PATH EXT_PATH("apps_assets/totp/fonts")
  8. #define FONT_FILE_EXTENSION ".font"
  9. size_t totp_font_provider_get_fonts_count() {
  10. size_t result = 0;
  11. Storage* storage = furi_record_open(RECORD_STORAGE);
  12. FuriString* path_src = furi_string_alloc();
  13. DirWalk* dir_walk = dir_walk_alloc(storage);
  14. dir_walk_set_recursive(dir_walk, false);
  15. if(dir_walk_open(dir_walk, FONT_BASE_PATH)) {
  16. char extension[sizeof(FONT_FILE_EXTENSION)];
  17. while(dir_walk_read(dir_walk, path_src, NULL) == DirWalkOK) {
  18. path_extract_extension(path_src, &extension[0], sizeof(extension));
  19. if(strncmp(&extension[0], FONT_FILE_EXTENSION, sizeof(FONT_FILE_EXTENSION)) == 0) {
  20. result++;
  21. }
  22. }
  23. }
  24. furi_string_free(path_src);
  25. dir_walk_free(dir_walk);
  26. furi_record_close(RECORD_STORAGE);
  27. return result;
  28. }
  29. bool totp_font_provider_get_font(size_t font_index, FontInfo* font_info) {
  30. Storage* storage = furi_record_open(RECORD_STORAGE);
  31. Stream* stream = file_stream_alloc(storage);
  32. bool loaded = false;
  33. FuriString* font_path = furi_string_alloc_printf(
  34. "%s/%02" PRIu16 "%s", FONT_BASE_PATH, font_index, FONT_FILE_EXTENSION);
  35. do {
  36. if(!file_stream_open(
  37. stream, furi_string_get_cstr(font_path), FSAM_READ, FSOM_OPEN_EXISTING) ||
  38. !stream_rewind(stream)) {
  39. break;
  40. }
  41. uint8_t font_name_length;
  42. if(!stream_read(stream, &font_name_length, 1)) {
  43. break;
  44. }
  45. if(font_info->name != NULL) {
  46. free(font_info->name);
  47. }
  48. font_info->name = malloc(font_name_length + 1);
  49. furi_check(font_info->name);
  50. if(!stream_read(stream, (uint8_t*)font_info->name, font_name_length)) {
  51. break;
  52. }
  53. font_info->name[font_name_length] = '\0';
  54. if(!stream_read(stream, &font_info->height, 1) ||
  55. !stream_read(stream, &font_info->start_char, 1) ||
  56. !stream_read(stream, &font_info->end_char, 1) ||
  57. !stream_read(stream, &font_info->space_width, 1)) {
  58. break;
  59. }
  60. uint16_t bitmap_data_length;
  61. if(!stream_read(stream, (uint8_t*)&bitmap_data_length, 2)) {
  62. break;
  63. }
  64. if(font_info->data != NULL) {
  65. free(font_info->data);
  66. }
  67. font_info->data = malloc(bitmap_data_length);
  68. furi_check(font_info->data);
  69. if(!stream_read(stream, font_info->data, bitmap_data_length)) {
  70. break;
  71. }
  72. uint8_t descriptors_length;
  73. if(!stream_read(stream, &descriptors_length, 1)) {
  74. break;
  75. }
  76. if(font_info->char_info != NULL) {
  77. free(font_info->char_info);
  78. }
  79. uint16_t char_info_array_size = descriptors_length * sizeof(FontCharInfo);
  80. font_info->char_info = malloc(char_info_array_size);
  81. furi_check(font_info->char_info);
  82. if(!stream_read(stream, (uint8_t*)font_info->char_info, char_info_array_size)) {
  83. break;
  84. }
  85. loaded = true;
  86. } while(false);
  87. furi_string_free(font_path);
  88. file_stream_close(stream);
  89. stream_free(stream);
  90. furi_record_close(RECORD_STORAGE);
  91. return loaded;
  92. }