luat_lib_fonts.c 10 KB

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