luat_lib_fonts.c 8.6 KB

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