luat_lib_fonts.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*
  2. @module fonts
  3. @summary 字体库
  4. @version 1.0
  5. @date 2022.07.11
  6. */
  7. #include "luat_base.h"
  8. #include "luat_malloc.h"
  9. #include "luat_fs.h"
  10. #define LUAT_LOG_TAG "fonts"
  11. #include "luat_log.h"
  12. #include "u8g2.h"
  13. #include "u8g2_luat_fonts.h"
  14. typedef struct u8g2_font
  15. {
  16. const char* name;
  17. const uint8_t* font;
  18. }u8g2_font_t;
  19. static const u8g2_font_t u8g2_fonts[] = {
  20. #ifdef USE_U8G2_OPPOSANSM_ENGLISH
  21. {.name="unifont_t_symbols", .font=u8g2_font_unifont_t_symbols},
  22. {.name="open_iconic_weather_6x_t", .font=u8g2_font_open_iconic_weather_6x_t},
  23. {.name="opposansm8", .font=u8g2_font_opposansm8},
  24. {.name="opposansm10", .font=u8g2_font_opposansm10},
  25. {.name="opposansm12", .font=u8g2_font_opposansm12},
  26. {.name="opposansm16", .font=u8g2_font_opposansm16},
  27. {.name="opposansm20", .font=u8g2_font_opposansm20},
  28. {.name="opposansm24", .font=u8g2_font_opposansm24},
  29. {.name="opposansm32", .font=u8g2_font_opposansm32},
  30. #endif
  31. #ifdef USE_U8G2_OPPOSANSM8_CHINESE
  32. {.name="opposansm8_chinese", .font=u8g2_font_opposansm8_chinese},
  33. #endif
  34. #ifdef USE_U8G2_OPPOSANSM10_CHINESE
  35. {.name="opposansm10_chinese", .font=u8g2_font_opposansm10_chinese},
  36. #endif
  37. #ifdef USE_U8G2_OPPOSANSM12_CHINESE
  38. {.name="opposansm12_chinese", .font=u8g2_font_opposansm12_chinese},
  39. #endif
  40. #ifdef USE_U8G2_OPPOSANSM16_CHINESE
  41. {.name="opposansm16_chinese", .font=u8g2_font_opposansm16_chinese},
  42. #endif
  43. #ifdef USE_U8G2_OPPOSANSM18_CHINESE
  44. {.name="opposansm18_chinese", .font=u8g2_font_opposansm18_chinese},
  45. #endif
  46. #ifdef USE_U8G2_OPPOSANSM20_CHINESE
  47. {.name="opposansm20_chinese", .font=u8g2_font_opposansm20_chinese},
  48. #endif
  49. #ifdef USE_U8G2_OPPOSANSM22_CHINESE
  50. {.name="opposansm22_chinese", .font=u8g2_font_opposansm22_chinese},
  51. #endif
  52. #ifdef USE_U8G2_OPPOSANSM24_CHINESE
  53. {.name="opposansm24_chinese", .font=u8g2_font_opposansm24_chinese},
  54. #endif
  55. #ifdef USE_U8G2_OPPOSANSM32_CHINESE
  56. {.name="opposansm32_chinese", .font=u8g2_font_opposansm32_chinese},
  57. #endif
  58. #ifdef LUAT_FONTS_CUSTOM_U8G2
  59. LUAT_FONTS_CUSTOM_U8G2
  60. #endif
  61. {.name="", .font=NULL},
  62. };
  63. /*
  64. 获取u8g2字体
  65. @api fonts.u8g2_get(name)
  66. @string 字体名称, 例如opposansm8_chinese unifont_t_symbols
  67. @return userdata 若字体存放,返回字体指针, 否则返回nil
  68. @usage
  69. oppo_8 = fonts.u8g2_get("opposansm8_chinese")
  70. if oppo_8 then
  71. u8g2.SetFont(oppo_8)
  72. else
  73. log.warn("fonts", "no such font opposansm8_chinese")
  74. end
  75. */
  76. static int l_fonts_u8g2_get(lua_State *L) {
  77. const char* name = luaL_checkstring(L, 1);
  78. const u8g2_font_t *font = u8g2_fonts;
  79. while (font->font != NULL) {
  80. if (!strcmp(name, font->name)) {
  81. lua_pushlightuserdata(L, font->font);
  82. return 1;
  83. }
  84. font ++;
  85. }
  86. return 0;
  87. }
  88. /*
  89. 从文件加载u8g2字体
  90. @api fonts.u8g2_load(path)
  91. @string 字体路径, 例如 /luadb/abc.bin
  92. @return userdata 若字体存放,返回字体指针, 否则返回nil
  93. @usage
  94. -- API新增于2022-07-11
  95. -- 提醒: 若文件位于/luadb下, 不需要占用内存
  96. -- 若文件处于其他路径, 例如tf/sd卡, spi flash, 会自动加载到内存, 消耗lua vm的内存空间
  97. -- 加载后请适当引用, 不必反复加载同一个字体文件
  98. oppo12 = fonts.u8g2_load("/luadb/oppo12.bin")
  99. if oppo12 then
  100. u8g2.SetFont(oppo12)
  101. else
  102. log.warn("fonts", "no such font file oppo12.bin")
  103. end
  104. */
  105. static int l_fonts_u8g2_load(lua_State *L) {
  106. char* ptr = NULL;
  107. // 从文件加载
  108. const char* path = luaL_checkstring(L, 1);
  109. size_t flen = luat_fs_fsize(path);
  110. if (flen < 16) {
  111. LLOGE("not a good font file %s", path);
  112. return 0;
  113. }
  114. FILE* fd = luat_fs_fopen(path, "rb");
  115. if (fd == NULL) {
  116. LLOGE("no such file %s", path);
  117. return 0;
  118. }
  119. #ifdef LUAT_USE_FS_VFS
  120. //LLOGD("try mmap");
  121. ptr = (char*)luat_vfs_mmap(fd);
  122. if (ptr != NULL) {
  123. LLOGD("load by mmap %s %p", path, ptr);
  124. lua_pushlightuserdata(L, ptr);
  125. luat_fs_fclose(fd);
  126. return 1;
  127. }
  128. #endif
  129. ptr = lua_newuserdata(L, flen);
  130. if (ptr == NULL) {
  131. luat_fs_fclose(fd);
  132. LLOGE("no engouh memory for font %s", path);
  133. return 0;
  134. }
  135. char buff[256];
  136. int len = 0;
  137. int count = 0;
  138. while (count < flen)
  139. {
  140. len = luat_fs_fread(buff, 256, 1, fd);
  141. if (len < 0)
  142. break;
  143. if (len > 0) {
  144. memcpy(ptr + count, buff, len);
  145. count += len;
  146. }
  147. }
  148. luat_fs_fclose(fd);
  149. lua_pushlightuserdata(L, ptr);
  150. return 1;
  151. }
  152. /*
  153. 返回固件支持的u8g2字体列表
  154. @api fonts.u8g2_list()
  155. @return table 字体列表
  156. @usage
  157. -- API新增于2022-07-12
  158. if fonts.u8g2_list then
  159. log.info("fonts", "u8g2", json.encode(fonts.u8g2_list()))
  160. end
  161. */
  162. static int l_fonts_u8g2_list(lua_State *L) {
  163. const u8g2_font_t *font = u8g2_fonts;
  164. lua_createtable(L, 10, 0);
  165. int index = 1;
  166. while (font->font != NULL) {
  167. lua_pushinteger(L, index);
  168. lua_pushstring(L, font->name);
  169. lua_settable(L, -3);
  170. index ++;
  171. font ++;
  172. }
  173. return 1;
  174. }
  175. //----------------------------------------------
  176. // LVGL 相关
  177. //----------------------------------------------
  178. #ifdef LUAT_USE_LVGL
  179. #include "lvgl.h"
  180. #include "lv_font/lv_font.h"
  181. typedef struct lv_font_reg
  182. {
  183. const char* name;
  184. lv_font_t* font;
  185. }lv_font_reg_t;
  186. static const lv_font_reg_t lv_regs[] = {
  187. #ifdef LV_FONT_MONTSERRAT_14
  188. {.name="montserrat_14", .font=&lv_font_montserrat_14},
  189. #endif
  190. #ifdef LV_FONT_OPPOSANS_M_8
  191. {.name="opposans_m_8", .font=&lv_font_opposans_m_8},
  192. #endif
  193. #ifdef LV_FONT_OPPOSANS_M_10
  194. {.name="opposans_m_10", .font=&lv_font_opposans_m_10},
  195. #endif
  196. #ifdef LV_FONT_OPPOSANS_M_12
  197. {.name="opposans_m_12", .font=&lv_font_opposans_m_12},
  198. #endif
  199. #ifdef LV_FONT_OPPOSANS_M_14
  200. {.name="opposans_m_14", .font=&lv_font_opposans_m_14},
  201. #endif
  202. #ifdef LV_FONT_OPPOSANS_M_16
  203. {.name="opposans_m_16", .font=&lv_font_opposans_m_16},
  204. #endif
  205. #ifdef LV_FONT_OPPOSANS_M_18
  206. {.name="opposans_m_18", .font=&lv_font_opposans_m_18},
  207. #endif
  208. #ifdef LV_FONT_OPPOSANS_M_20
  209. {.name="opposans_m_20", .font=&lv_font_opposans_m_20},
  210. #endif
  211. #ifdef LV_FONT_OPPOSANS_M_22
  212. {.name="opposans_m_22", .font=&lv_font_opposans_m_22},
  213. #endif
  214. #ifdef USE_LVGL_SIMSUN_42
  215. {.name="simsun_42", .font=&lv_font_simsun_42},
  216. #endif
  217. #ifdef USE_LVGL_SIMSUN_48
  218. {.name="simsun_48", &lv_font_simsun_48},
  219. #endif
  220. #ifdef LUAT_FONTS_CUSTOM_LVGL
  221. LUAT_FONTS_CUSTOM_LVGL
  222. #endif
  223. {.name="", .font=NULL},
  224. };
  225. static int l_fonts_lvgl_get(lua_State *L) {
  226. const char* name = luaL_checkstring(L, 1);
  227. const lv_font_reg_t *font = lv_regs;
  228. while (font->font != NULL) {
  229. if (!strcmp(name, font->name)) {
  230. lua_pushlightuserdata(L, font->font);
  231. return 1;
  232. }
  233. font ++;
  234. }
  235. return 0;
  236. }
  237. static int l_fonts_lvgl_list(lua_State *L) {
  238. const lv_font_reg_t *font = lv_regs;
  239. lua_createtable(L, 10, 0);
  240. int index = 1;
  241. while (font->font != NULL) {
  242. lua_pushinteger(L, index);
  243. lua_pushstring(L, font->name);
  244. lua_settable(L, -3);
  245. index ++;
  246. }
  247. return 1;
  248. }
  249. #endif
  250. #include "rotable2.h"
  251. static const rotable_Reg_t reg_fonts[] =
  252. {
  253. { "u8g2_get" , ROREG_FUNC(l_fonts_u8g2_get)},
  254. { "u8g2_load" , ROREG_FUNC(l_fonts_u8g2_load)},
  255. { "u8g2_list" , ROREG_FUNC(l_fonts_u8g2_list)},
  256. #ifdef LUAT_USE_LVGL
  257. { "lvgl_get" , ROREG_FUNC(l_fonts_lvgl_get)},
  258. { "lvgl_list" , ROREG_FUNC(l_fonts_lvgl_list)},
  259. #endif
  260. { NULL, ROREG_INT(0)},
  261. };
  262. LUAMOD_API int luaopen_fonts( lua_State *L ) {
  263. luat_newlib2(L, reg_fonts);
  264. return 1;
  265. }