luat_lib_lcd.c 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776
  1. /*
  2. @module lcd
  3. @summary lcd驱动模块
  4. @version 1.0
  5. @date 2021.06.16
  6. @demo lcd
  7. @tag LUAT_USE_LCD
  8. */
  9. #include "luat_base.h"
  10. #include "luat_lcd.h"
  11. #include "luat_malloc.h"
  12. #include "luat_zbuff.h"
  13. #include "luat_fs.h"
  14. #define LUAT_LOG_TAG "lcd"
  15. #include "luat_log.h"
  16. #include "u8g2.h"
  17. #include "u8g2_luat_fonts.h"
  18. #include "qrcodegen.h"
  19. int8_t u8g2_font_decode_get_signed_bits(u8g2_font_decode_t *f, uint8_t cnt);
  20. uint8_t u8g2_font_decode_get_unsigned_bits(u8g2_font_decode_t *f, uint8_t cnt);
  21. extern luat_color_t BACK_COLOR , FORE_COLOR ;
  22. extern const luat_lcd_opts_t lcd_opts_st7735;
  23. extern const luat_lcd_opts_t lcd_opts_st7735v;
  24. extern const luat_lcd_opts_t lcd_opts_st7735s;
  25. extern const luat_lcd_opts_t lcd_opts_st7789;
  26. extern const luat_lcd_opts_t lcd_opts_st7796;
  27. extern const luat_lcd_opts_t lcd_opts_gc9a01;
  28. extern const luat_lcd_opts_t lcd_opts_gc9106l;
  29. extern const luat_lcd_opts_t lcd_opts_gc9306x;
  30. extern const luat_lcd_opts_t lcd_opts_ili9341;
  31. extern const luat_lcd_opts_t lcd_opts_ili9486;
  32. extern const luat_lcd_opts_t lcd_opts_custom;
  33. typedef struct lcd_reg {
  34. const char *name;
  35. const luat_lcd_opts_t *lcd_opts;
  36. }lcd_reg_t;
  37. static const lcd_reg_t lcd_regs[] = {
  38. {"custom", &lcd_opts_custom}, //0 固定为第零个
  39. {"st7735", &lcd_opts_st7735},
  40. {"st7735v", &lcd_opts_st7735v},
  41. {"st7735s", &lcd_opts_st7735s},
  42. {"st7789", &lcd_opts_st7789},
  43. {"st7796", &lcd_opts_st7796},
  44. {"gc9a01", &lcd_opts_gc9a01},
  45. {"gc9106l", &lcd_opts_gc9106l},
  46. {"gc9306x", &lcd_opts_gc9306x},
  47. {"gc9306", &lcd_opts_gc9306x}, //gc9306是gc9306x的别名
  48. {"ili9341", &lcd_opts_ili9341},
  49. {"ili9486", &lcd_opts_ili9486},
  50. {"", NULL} // 最后一个必须是空字符串
  51. };
  52. static luat_lcd_conf_t *default_conf = NULL;
  53. // static int dft_conf_lua_ref = 0;
  54. // 所有绘图相关的函数都应该调用本函数
  55. static void lcd_auto_flush(luat_lcd_conf_t *conf) {
  56. #ifndef LUAT_USE_LCD_SDL2
  57. if (conf == NULL || conf->buff == NULL || conf->auto_flush == 0)
  58. return;
  59. #endif
  60. luat_lcd_flush(conf);
  61. }
  62. static luat_color_t lcd_str_fg_color,lcd_str_bg_color;
  63. /*
  64. lcd显示屏初始化
  65. @api lcd.init(tp, args)
  66. @string lcd类型,当前支持:<br>st7796<br>st7789<br>st7735<br>st7735v<br>st7735s<br>gc9a01<br>gc9106l<br>gc9306x<br>ili9341<br>ili9486<br>custom
  67. @table 附加参数,与具体设备有关:<br>pin_pwr(背光)为可选项,可不设置<br>port:spi端口,例如0,1,2...如果为device方式则为"device"<br>pin_dc:lcd数据/命令选择引脚<br>pin_rst:lcd复位引脚<br>pin_pwr:lcd背光引脚 可选项,可不设置<br>direction:lcd屏幕方向 0:0° 1:180° 2:270° 3:90°<br>w:lcd 水平分辨率<br>h:lcd 竖直分辨率<br>xoffset:x偏移(不同屏幕ic 不同屏幕方向会有差异)<br>yoffset:y偏移(不同屏幕ic 不同屏幕方向会有差异)
  68. @userdata spi设备,当port = "device"时有效
  69. @usage
  70. -- 初始化spi0的st7735s 注意:lcd初始化之前需要先初始化spi
  71. spi_lcd = spi.deviceSetup(0,20,0,0,8,2000000,spi.MSB,1,1)
  72. log.info("lcd.init",
  73. lcd.init("st7735s",{port = "device",pin_dc = 17, pin_pwr = 7,pin_rst = 19,direction = 2,w = 160,h = 80,xoffset = 1,yoffset = 26},spi_lcd))
  74. */
  75. static int l_lcd_init(lua_State* L) {
  76. size_t len = 0;
  77. luat_lcd_conf_t *conf = luat_heap_malloc(sizeof(luat_lcd_conf_t));
  78. if (conf == NULL) {
  79. LLOGE("out of system memory!!!");
  80. return 0;
  81. }
  82. if (default_conf != NULL) {
  83. LLOGD("lcd was inited, skip");
  84. lua_pushboolean(L, 1);
  85. return 1;
  86. }
  87. memset(conf, 0, sizeof(luat_lcd_conf_t)); // 填充0,保证无脏数据
  88. conf->pin_pwr = 255;
  89. if (lua_type(L, 3) == LUA_TUSERDATA){
  90. // 如果是SPI Device模式, 就可能出现变量为local, 从而在某个时间点被GC掉的可能性
  91. conf->lcd_spi_device = (luat_spi_device_t*)lua_touserdata(L, 3);
  92. lua_pushvalue(L, 3);
  93. // 所以, 直接引用之外, 再加上强制引用, 避免被GC
  94. // 鉴于LCD不太可能重复初始化, 引用也没什么问题
  95. conf->lcd_spi_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  96. conf->port = LUAT_LCD_SPI_DEVICE;
  97. }
  98. const char* tp = luaL_checklstring(L, 1, &len);
  99. int16_t s_index = -1;//第几个屏幕,-1表示没匹配到
  100. for(int i = 0; i < 100; i++){
  101. if (strlen(lcd_regs[i].name) == 0)
  102. break;
  103. if(strcmp(lcd_regs[i].name,tp) == 0){
  104. s_index = i;
  105. break;
  106. }
  107. }
  108. if (s_index != -1) {
  109. LLOGD("ic support: %s",tp);
  110. if (lua_gettop(L) > 1) {
  111. conf->opts = (struct luat_lcd_opts *)lcd_regs[s_index].lcd_opts;
  112. lua_settop(L, 2); // 丢弃多余的参数
  113. lua_pushstring(L, "port");
  114. int port = lua_gettable(L, 2);
  115. if (conf->port == LUAT_LCD_SPI_DEVICE && port ==LUA_TNUMBER) {
  116. LLOGE("port is not device but find luat_spi_device_t");
  117. goto end;
  118. }else if (conf->port != LUAT_LCD_SPI_DEVICE && LUA_TSTRING == port){
  119. LLOGE("port is device but not find luat_spi_device_t");
  120. goto end;
  121. }else if (LUA_TNUMBER == port) {
  122. conf->port = luaL_checkinteger(L, -1);
  123. }else if (LUA_TSTRING == port){
  124. conf->port = LUAT_LCD_SPI_DEVICE;
  125. }
  126. lua_pop(L, 1);
  127. lua_pushstring(L, "pin_dc");
  128. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  129. conf->pin_dc = luaL_checkinteger(L, -1);
  130. }
  131. lua_pop(L, 1);
  132. lua_pushstring(L, "pin_pwr");
  133. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  134. conf->pin_pwr = luaL_checkinteger(L, -1);
  135. }
  136. lua_pop(L, 1);
  137. lua_pushstring(L, "pin_rst");
  138. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  139. conf->pin_rst = luaL_checkinteger(L, -1);
  140. }
  141. lua_pop(L, 1);
  142. lua_pushstring(L, "direction");
  143. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  144. conf->direction = luaL_checkinteger(L, -1);
  145. }
  146. lua_pop(L, 1);
  147. lua_pushstring(L, "w");
  148. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  149. conf->w = luaL_checkinteger(L, -1);
  150. }
  151. lua_pop(L, 1);
  152. lua_pushstring(L, "h");
  153. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  154. conf->h = luaL_checkinteger(L, -1);
  155. }
  156. lua_pop(L, 1);
  157. conf->buffer_size = (conf->w * conf->h) * 2;
  158. lua_pushstring(L, "xoffset");
  159. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  160. conf->xoffset = luaL_checkinteger(L, -1);
  161. }
  162. lua_pop(L, 1);
  163. lua_pushstring(L, "yoffset");
  164. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  165. conf->yoffset = luaL_checkinteger(L, -1);
  166. }
  167. lua_pop(L, 1);
  168. }
  169. if (s_index == 0){
  170. luat_lcd_custom_t *cst = luat_heap_malloc(sizeof(luat_lcd_custom_t));
  171. lua_pushstring(L, "initcmd");
  172. lua_gettable(L, 2);
  173. if (lua_istable(L, -1)) {
  174. cst->init_cmd_count = lua_rawlen(L, -1);
  175. cst->initcmd = luat_heap_malloc(cst->init_cmd_count * sizeof(uint32_t));
  176. for (size_t i = 1; i <= cst->init_cmd_count; i++){
  177. lua_geti(L, -1, i);
  178. cst->initcmd[i-1] = luaL_checkinteger(L, -1);
  179. lua_pop(L, 1);
  180. }
  181. }else if(lua_isstring(L, -1)){
  182. size_t len,cmd;
  183. const char *fail_name = luaL_checklstring(L, -1, &len);
  184. FILE* fd = (FILE *)luat_fs_fopen(fail_name, "rb");
  185. cst->init_cmd_count = 0;
  186. if (fd){
  187. #define INITCMD_BUFF_SIZE 128
  188. char init_cmd_buff[INITCMD_BUFF_SIZE] ;
  189. cst->initcmd = luat_heap_malloc(sizeof(uint32_t));
  190. while (1) {
  191. memset(init_cmd_buff, 0, INITCMD_BUFF_SIZE);
  192. int readline_len = luat_fs_readline(init_cmd_buff, INITCMD_BUFF_SIZE-1, fd);
  193. if (readline_len < 1)
  194. break;
  195. if (memcmp(init_cmd_buff, "#", 1)==0){
  196. continue;
  197. }
  198. char *token = strtok(init_cmd_buff, ",");
  199. if (sscanf(token,"%x",&cmd) < 1){
  200. continue;
  201. }
  202. cst->init_cmd_count = cst->init_cmd_count + 1;
  203. cst->initcmd = luat_heap_realloc(cst->initcmd,cst->init_cmd_count * sizeof(uint32_t));
  204. cst->initcmd[cst->init_cmd_count-1]=cmd;
  205. while( token != NULL ) {
  206. token = strtok(NULL, ",");
  207. if (sscanf(token,"%x",&cmd) < 1){
  208. break;
  209. }
  210. cst->init_cmd_count = cst->init_cmd_count + 1;
  211. cst->initcmd = luat_heap_realloc(cst->initcmd,cst->init_cmd_count * sizeof(uint32_t));
  212. cst->initcmd[cst->init_cmd_count-1]=cmd;
  213. }
  214. }
  215. cst->initcmd[cst->init_cmd_count]= 0;
  216. luat_fs_fclose(fd);
  217. }else{
  218. LLOGE("init_cmd fail open error");
  219. }
  220. }
  221. lua_pop(L, 1);
  222. conf->userdata = cst;
  223. }
  224. // 默认自动flush,即使没有buff
  225. conf->auto_flush = 1;
  226. #ifdef LUAT_USE_LCD_SDL2
  227. extern const luat_lcd_opts_t lcd_opts_sdl2;
  228. conf->opts = &lcd_opts_sdl2;
  229. #endif
  230. int ret = luat_lcd_init(conf);
  231. if (ret != 0) {
  232. LLOGE("lcd init fail %d", ret);
  233. luat_heap_free(conf);
  234. lua_pushboolean(L, 0);
  235. return 0;
  236. }
  237. // 初始化OK, 配置额外的参数
  238. default_conf = conf;
  239. u8g2_SetFont(&(conf->luat_lcd_u8g2), u8g2_font_opposansm8);
  240. u8g2_SetFontMode(&(conf->luat_lcd_u8g2), 0);
  241. u8g2_SetFontDirection(&(conf->luat_lcd_u8g2), 0);
  242. lua_pushboolean(L, 1);
  243. return 1;
  244. }
  245. LLOGE("ic not support: %s",tp);
  246. end:
  247. lua_pushboolean(L, 0);
  248. luat_heap_free(conf);
  249. return 1;
  250. }
  251. /*
  252. 关闭lcd显示屏
  253. @api lcd.close()
  254. @usage
  255. -- 关闭lcd
  256. lcd.close()
  257. */
  258. static int l_lcd_close(lua_State* L) {
  259. int ret = luat_lcd_close(default_conf);
  260. lua_pushboolean(L, ret == 0 ? 1 : 0);
  261. return 1;
  262. }
  263. /*
  264. 开启lcd显示屏背光
  265. @api lcd.on()
  266. @usage
  267. -- 开启lcd显示屏背光
  268. lcd.on()
  269. */
  270. static int l_lcd_display_on(lua_State* L) {
  271. int ret = luat_lcd_display_on(default_conf);
  272. lua_pushboolean(L, ret == 0 ? 1 : 0);
  273. return 1;
  274. }
  275. /*
  276. 关闭lcd显示屏背光
  277. @api lcd.off()
  278. @usage
  279. -- 关闭lcd显示屏背光
  280. lcd.off()
  281. */
  282. static int l_lcd_display_off(lua_State* L) {
  283. int ret = luat_lcd_display_off(default_conf);
  284. lua_pushboolean(L, ret == 0 ? 1 : 0);
  285. return 1;
  286. }
  287. /*
  288. lcd睡眠
  289. @api lcd.sleep()
  290. @usage
  291. -- lcd睡眠
  292. lcd.sleep()
  293. */
  294. static int l_lcd_sleep(lua_State* L) {
  295. int ret = luat_lcd_sleep(default_conf);
  296. lua_pushboolean(L, ret == 0 ? 1 : 0);
  297. return 1;
  298. }
  299. /*
  300. lcd唤醒
  301. @api lcd.wakeup()
  302. @usage
  303. -- lcd唤醒
  304. lcd.wakeup()
  305. */
  306. static int l_lcd_wakeup(lua_State* L) {
  307. int ret = luat_lcd_wakeup(default_conf);
  308. lua_pushboolean(L, ret == 0 ? 1 : 0);
  309. return 1;
  310. }
  311. /*
  312. lcd反显
  313. @api lcd.invon()
  314. @usage
  315. -- lcd反显
  316. lcd.invon()
  317. */
  318. static int l_lcd_inv_on(lua_State* L) {
  319. int ret = luat_lcd_inv_on(default_conf);
  320. lua_pushboolean(L, ret == 0 ? 1 : 0);
  321. return 1;
  322. }
  323. /*
  324. lcd反显关闭
  325. @api lcd.invoff()
  326. @usage
  327. -- lcd反显关闭
  328. lcd.invoff()
  329. */
  330. static int l_lcd_inv_off(lua_State* L) {
  331. int ret = luat_lcd_inv_off(default_conf);
  332. lua_pushboolean(L, ret == 0 ? 1 : 0);
  333. return 1;
  334. }
  335. /*
  336. lcd命令
  337. @api lcd.cmd(cmd)
  338. @int cmd
  339. @usage
  340. -- lcd命令
  341. lcd.cmd(0x21)
  342. */
  343. static int l_lcd_write_cmd(lua_State* L) {
  344. int ret = lcd_write_cmd(default_conf,(const uint8_t)luaL_checkinteger(L, 1));
  345. lua_pushboolean(L, ret == 0 ? 1 : 0);
  346. return 1;
  347. }
  348. /*
  349. lcd数据
  350. @api lcd.data(data)
  351. @int data
  352. @usage
  353. -- lcd数据
  354. lcd.data(0x21)
  355. */
  356. static int l_lcd_write_data(lua_State* L) {
  357. int ret = lcd_write_data(default_conf,(const uint8_t)luaL_checkinteger(L, 1));
  358. lua_pushboolean(L, ret == 0 ? 1 : 0);
  359. return 1;
  360. }
  361. /*
  362. lcd颜色设置
  363. @api lcd.setColor(back,fore)
  364. @int 背景色
  365. @int 前景色
  366. @usage
  367. -- lcd颜色设置
  368. lcd.setColor(0xFFFF,0x0000)
  369. */
  370. static int l_lcd_set_color(lua_State* L) {
  371. luat_color_t back,fore;
  372. back = (luat_color_t)luaL_checkinteger(L, 1);
  373. fore = (luat_color_t)luaL_checkinteger(L, 2);
  374. int ret = luat_lcd_set_color(back, fore);
  375. lua_pushboolean(L, ret == 0 ? 1 : 0);
  376. return 1;
  377. }
  378. /*
  379. lcd颜色填充
  380. @api lcd.draw(x1, y1, x2, y2,color)
  381. @int 左上边缘的X位置.
  382. @int 左上边缘的Y位置.
  383. @int 右下边缘的X位置.
  384. @int 右下边缘的Y位置.
  385. @string 字符串或zbuff对象
  386. @usage
  387. -- lcd颜色填充
  388. local buff = zbuff.create({201,1,16},0x001F)
  389. lcd.draw(20,30,220,30,buff)
  390. */
  391. static int l_lcd_draw(lua_State* L) {
  392. uint16_t x1, y1, x2, y2;
  393. int ret;
  394. // luat_color_t *color = NULL;
  395. luat_zbuff_t *buff;
  396. x1 = luaL_checkinteger(L, 1);
  397. y1 = luaL_checkinteger(L, 2);
  398. x2 = luaL_checkinteger(L, 3);
  399. y2 = luaL_checkinteger(L, 4);
  400. if (lua_isinteger(L, 5)) {
  401. // color = (luat_color_t *)luaL_checkstring(L, 5);
  402. luat_color_t color = (uint32_t)luaL_checkinteger(L, 1);
  403. ret = luat_lcd_draw(default_conf, x1, y1, x2, y2, &color);
  404. }
  405. else if (lua_isuserdata(L, 5)) {
  406. buff = luaL_checkudata(L, 5, LUAT_ZBUFF_TYPE);
  407. luat_color_t *color = (luat_color_t *)buff->addr;
  408. ret = luat_lcd_draw(default_conf, x1, y1, x2, y2, color);
  409. }
  410. else if(lua_isstring(L, 5)) {
  411. luat_color_t *color = (luat_color_t *)luaL_checkstring(L, 5);
  412. ret = luat_lcd_draw(default_conf, x1, y1, x2, y2, color);
  413. }
  414. else {
  415. return 0;
  416. }
  417. lcd_auto_flush(default_conf);
  418. // int ret = luat_lcd_draw(default_conf, x1, y1, x2, y2, color);
  419. lua_pushboolean(L, ret == 0 ? 1 : 0);
  420. return 1;
  421. }
  422. /*
  423. lcd清屏
  424. @api lcd.clear(color)
  425. @int 屏幕颜色 可选参数,默认背景色
  426. @usage
  427. -- lcd清屏
  428. lcd.clear()
  429. */
  430. static int l_lcd_clear(lua_State* L) {
  431. //size_t len = 0;
  432. luat_color_t color = BACK_COLOR;
  433. if (lua_gettop(L) > 0)
  434. color = (uint32_t)luaL_checkinteger(L, 1);
  435. int ret = luat_lcd_clear(default_conf, color);
  436. lcd_auto_flush(default_conf);
  437. lua_pushboolean(L, ret == 0 ? 1 : 0);
  438. return 1;
  439. }
  440. /*
  441. lcd颜色填充
  442. @api lcd.fill(x1, y1, x2, y2,color)
  443. @int 左上边缘的X位置.
  444. @int 左上边缘的Y位置.
  445. @int 右下边缘的X位置.
  446. @int 右下边缘的Y位置.
  447. @int 绘画颜色 可选参数,默认背景色
  448. @usage
  449. -- lcd颜色填充
  450. lcd.fill(20,30,220,30,0x0000)
  451. */
  452. static int l_lcd_draw_fill(lua_State* L) {
  453. uint16_t x1, y1, x2, y2;
  454. luat_color_t color = BACK_COLOR;
  455. x1 = luaL_checkinteger(L, 1);
  456. y1 = luaL_checkinteger(L, 2);
  457. x2 = luaL_checkinteger(L, 3);
  458. y2 = luaL_checkinteger(L, 4);
  459. if (lua_gettop(L) > 4)
  460. color = (luat_color_t)luaL_checkinteger(L, 5);
  461. int ret = luat_lcd_draw_fill(default_conf, x1, y1, x2, y2, color);
  462. lcd_auto_flush(default_conf);
  463. lua_pushboolean(L, ret == 0 ? 1 : 0);
  464. return 1;
  465. }
  466. /*
  467. 画一个点.
  468. @api lcd.drawPoint(x0,y0,color)
  469. @int 点的X位置.
  470. @int 点的Y位置.
  471. @int 绘画颜色 可选参数,默认前景色
  472. @usage
  473. lcd.drawPoint(20,30,0x001F)
  474. */
  475. static int l_lcd_draw_point(lua_State* L) {
  476. uint16_t x, y;
  477. luat_color_t color = FORE_COLOR;
  478. x = luaL_checkinteger(L, 1);
  479. y = luaL_checkinteger(L, 2);
  480. if (lua_gettop(L) > 2)
  481. color = (luat_color_t)luaL_checkinteger(L, 3);
  482. int ret = luat_lcd_draw_point(default_conf, x, y, color);
  483. lcd_auto_flush(default_conf);
  484. lua_pushboolean(L, ret == 0 ? 1 : 0);
  485. return 1;
  486. }
  487. /*
  488. 在两点之间画一条线.
  489. @api lcd.drawLine(x0,y0,x1,y1,color)
  490. @int 第一个点的X位置.
  491. @int 第一个点的Y位置.
  492. @int 第二个点的X位置.
  493. @int 第二个点的Y位置.
  494. @int 绘画颜色 可选参数,默认前景色
  495. @usage
  496. lcd.drawLine(20,30,220,30,0x001F)
  497. */
  498. static int l_lcd_draw_line(lua_State* L) {
  499. uint16_t x1, y1, x2, y2;
  500. luat_color_t color = FORE_COLOR;
  501. x1 = luaL_checkinteger(L, 1);
  502. y1 = luaL_checkinteger(L, 2);
  503. x2 = luaL_checkinteger(L, 3);
  504. y2 = luaL_checkinteger(L, 4);
  505. if (lua_gettop(L) > 4)
  506. color = (luat_color_t)luaL_checkinteger(L, 5);
  507. int ret = luat_lcd_draw_line(default_conf, x1, y1, x2, y2, color);
  508. lcd_auto_flush(default_conf);
  509. lua_pushboolean(L, ret == 0 ? 1 : 0);
  510. return 1;
  511. }
  512. /*
  513. 从x / y位置(左上边缘)开始绘制一个框
  514. @api lcd.drawRectangle(x0,y0,x1,y1,color)
  515. @int 左上边缘的X位置.
  516. @int 左上边缘的Y位置.
  517. @int 右下边缘的X位置.
  518. @int 右下边缘的Y位置.
  519. @int 绘画颜色 可选参数,默认前景色
  520. @usage
  521. lcd.drawRectangle(20,40,220,80,0x001F)
  522. */
  523. static int l_lcd_draw_rectangle(lua_State* L) {
  524. uint16_t x1, y1, x2, y2;
  525. luat_color_t color = FORE_COLOR;
  526. x1 = luaL_checkinteger(L, 1);
  527. y1 = luaL_checkinteger(L, 2);
  528. x2 = luaL_checkinteger(L, 3);
  529. y2 = luaL_checkinteger(L, 4);
  530. if (lua_gettop(L) > 4)
  531. color = (luat_color_t)luaL_checkinteger(L, 5);
  532. int ret = luat_lcd_draw_rectangle(default_conf, x1, y1, x2, y2, color);
  533. lcd_auto_flush(default_conf);
  534. lua_pushboolean(L, ret == 0 ? 1 : 0);
  535. return 1;
  536. }
  537. /*
  538. 从x / y位置(圆心)开始绘制一个圆
  539. @api lcd.drawCircle(x0,y0,r,color)
  540. @int 圆心的X位置.
  541. @int 圆心的Y位置.
  542. @int 半径.
  543. @int 绘画颜色 可选参数,默认前景色
  544. @usage
  545. lcd.drawCircle(120,120,20,0x001F)
  546. */
  547. static int l_lcd_draw_circle(lua_State* L) {
  548. uint16_t x0, y0, r;
  549. luat_color_t color = FORE_COLOR;
  550. x0 = luaL_checkinteger(L, 1);
  551. y0 = luaL_checkinteger(L, 2);
  552. r = luaL_checkinteger(L, 3);
  553. if (lua_gettop(L) > 3)
  554. color = (luat_color_t)luaL_checkinteger(L, 4);
  555. int ret = luat_lcd_draw_circle(default_conf, x0, y0, r, color);
  556. lcd_auto_flush(default_conf);
  557. lua_pushboolean(L, ret == 0 ? 1 : 0);
  558. return 1;
  559. }
  560. /**
  561. 缓冲区绘制QRCode
  562. @api lcd.drawQrcode(x, y, str, size)
  563. @int x坐标
  564. @int y坐标
  565. @string 二维码的内容
  566. @int 显示大小 (注意:二维码生成大小与要显示内容和纠错等级有关,生成版本为1-40(对应 21x21 - 177x177)的不定大小,如果和设置大小不同会自动在指定的区域中间显示二维码,如二维码未显示请查看日志提示)
  567. @return nil 无返回值
  568. */
  569. static int l_lcd_drawQrcode(lua_State *L)
  570. {
  571. size_t len;
  572. int x = luaL_checkinteger(L, 1);
  573. int y = luaL_checkinteger(L, 2);
  574. const char* text = luaL_checklstring(L, 3, &len);
  575. int size = luaL_checkinteger(L, 4);
  576. uint8_t *qrcode = luat_heap_malloc(qrcodegen_BUFFER_LEN_MAX);
  577. uint8_t *tempBuffer = luat_heap_malloc(qrcodegen_BUFFER_LEN_MAX);
  578. if (qrcode == NULL || tempBuffer == NULL) {
  579. if (qrcode)
  580. luat_heap_free(qrcode);
  581. if (tempBuffer)
  582. luat_heap_free(tempBuffer);
  583. LLOGE("qrcode out of memory");
  584. return 0;
  585. }
  586. bool ok = qrcodegen_encodeText(text, tempBuffer, qrcode, qrcodegen_Ecc_LOW,
  587. qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
  588. if (ok){
  589. int qr_size = qrcodegen_getSize(qrcode);
  590. if (size < qr_size){
  591. LLOGE("size must be greater than qr_size %d",qr_size);
  592. goto end;
  593. }
  594. int scale = size / qr_size ;
  595. if (!scale)scale = 1;
  596. int margin = (size - qr_size * scale) / 2;
  597. luat_lcd_draw_fill(default_conf,x,y,x+size,y+size,BACK_COLOR);
  598. x+=margin;
  599. y+=margin;
  600. for (int j = 0; j < qr_size; j++) {
  601. for (int i = 0; i < qr_size; i++) {
  602. if (qrcodegen_getModule(qrcode, i, j))
  603. luat_lcd_draw_fill(default_conf,x+i*scale,y+j*scale,x+(i+1)*scale,y+(j+1)*scale,FORE_COLOR);
  604. }
  605. }
  606. }else{
  607. LLOGE("qrcodegen_encodeText false");
  608. }
  609. end:
  610. if (qrcode)
  611. luat_heap_free(qrcode);
  612. if (tempBuffer)
  613. luat_heap_free(tempBuffer);
  614. lcd_auto_flush(default_conf);
  615. return 0;
  616. }
  617. static uint8_t utf8_state;
  618. static uint16_t encoding;
  619. static uint16_t utf8_next(uint8_t b)
  620. {
  621. if ( b == 0 ) /* '\n' terminates the string to support the string list procedures */
  622. return 0x0ffff; /* end of string detected, pending UTF8 is discarded */
  623. if ( utf8_state == 0 )
  624. {
  625. if ( b >= 0xfc ) /* 6 byte sequence */
  626. {
  627. utf8_state = 5;
  628. b &= 1;
  629. }
  630. else if ( b >= 0xf8 )
  631. {
  632. utf8_state = 4;
  633. b &= 3;
  634. }
  635. else if ( b >= 0xf0 )
  636. {
  637. utf8_state = 3;
  638. b &= 7;
  639. }
  640. else if ( b >= 0xe0 )
  641. {
  642. utf8_state = 2;
  643. b &= 15;
  644. }
  645. else if ( b >= 0xc0 )
  646. {
  647. utf8_state = 1;
  648. b &= 0x01f;
  649. }
  650. else
  651. {
  652. /* do nothing, just use the value as encoding */
  653. return b;
  654. }
  655. encoding = b;
  656. return 0x0fffe;
  657. }
  658. else
  659. {
  660. utf8_state--;
  661. /* The case b < 0x080 (an illegal UTF8 encoding) is not checked here. */
  662. encoding<<=6;
  663. b &= 0x03f;
  664. encoding |= b;
  665. if ( utf8_state != 0 )
  666. return 0x0fffe; /* nothing to do yet */
  667. }
  668. return encoding;
  669. }
  670. static void u8g2_draw_hv_line(u8g2_t *u8g2, int16_t x, int16_t y, int16_t len, uint8_t dir, uint16_t color){
  671. switch(dir)
  672. {
  673. case 0:
  674. luat_lcd_draw_hline(default_conf,x,y,len,color);
  675. break;
  676. case 1:
  677. luat_lcd_draw_vline(default_conf,x,y,len,color);
  678. break;
  679. case 2:
  680. luat_lcd_draw_hline(default_conf,x-len+1,y,len,color);
  681. break;
  682. case 3:
  683. luat_lcd_draw_vline(default_conf,x,y-len+1,len,color);
  684. break;
  685. }
  686. }
  687. static void u8g2_font_decode_len(u8g2_t *u8g2, uint8_t len, uint8_t is_foreground){
  688. uint8_t cnt; /* total number of remaining pixels, which have to be drawn */
  689. uint8_t rem; /* remaining pixel to the right edge of the glyph */
  690. uint8_t current; /* number of pixels, which need to be drawn for the draw procedure */
  691. /* current is either equal to cnt or equal to rem */
  692. /* local coordinates of the glyph */
  693. uint8_t lx,ly;
  694. /* target position on the screen */
  695. int16_t x, y;
  696. u8g2_font_decode_t *decode = &(u8g2->font_decode);
  697. cnt = len;
  698. /* get the local position */
  699. lx = decode->x;
  700. ly = decode->y;
  701. for(;;){
  702. /* calculate the number of pixel to the right edge of the glyph */
  703. rem = decode->glyph_width;
  704. rem -= lx;
  705. /* calculate how many pixel to draw. This is either to the right edge */
  706. /* or lesser, if not enough pixel are left */
  707. current = rem;
  708. if ( cnt < rem )
  709. current = cnt;
  710. /* now draw the line, but apply the rotation around the glyph target position */
  711. //u8g2_font_decode_draw_pixel(u8g2, lx,ly,current, is_foreground);
  712. // printf("lx:%d,ly:%d,current:%d, is_foreground:%d \r\n",lx,ly,current, is_foreground);
  713. /* get target position */
  714. x = decode->target_x;
  715. y = decode->target_y;
  716. /* apply rotation */
  717. x = u8g2_add_vector_x(x, lx, ly, decode->dir);
  718. y = u8g2_add_vector_y(y, lx, ly, decode->dir);
  719. /* draw foreground and background (if required) */
  720. if ( current > 0 ) /* avoid drawing zero length lines, issue #4 */
  721. {
  722. if ( is_foreground )
  723. {
  724. u8g2_draw_hv_line(u8g2, x, y, current, decode->dir, lcd_str_fg_color);
  725. }
  726. // else if ( decode->is_transparent == 0 )
  727. // {
  728. // u8g2_draw_hv_line(u8g2, x, y, current, decode->dir, lcd_str_bg_color);
  729. // }
  730. }
  731. /* check, whether the end of the run length code has been reached */
  732. if ( cnt < rem )
  733. break;
  734. cnt -= rem;
  735. lx = 0;
  736. ly++;
  737. }
  738. lx += cnt;
  739. decode->x = lx;
  740. decode->y = ly;
  741. }
  742. static void u8g2_font_setup_decode(u8g2_t *u8g2, const uint8_t *glyph_data)
  743. {
  744. u8g2_font_decode_t *decode = &(u8g2->font_decode);
  745. decode->decode_ptr = glyph_data;
  746. decode->decode_bit_pos = 0;
  747. /* 8 Nov 2015, this is already done in the glyph data search procedure */
  748. /*
  749. decode->decode_ptr += 1;
  750. decode->decode_ptr += 1;
  751. */
  752. decode->glyph_width = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_char_width);
  753. decode->glyph_height = u8g2_font_decode_get_unsigned_bits(decode,u8g2->font_info.bits_per_char_height);
  754. }
  755. static int8_t u8g2_font_decode_glyph(u8g2_t *u8g2, const uint8_t *glyph_data){
  756. uint8_t a, b;
  757. int8_t x, y;
  758. int8_t d;
  759. int8_t h;
  760. u8g2_font_decode_t *decode = &(u8g2->font_decode);
  761. u8g2_font_setup_decode(u8g2, glyph_data);
  762. h = u8g2->font_decode.glyph_height;
  763. x = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_char_x);
  764. y = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_char_y);
  765. d = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_delta_x);
  766. if ( decode->glyph_width > 0 )
  767. {
  768. decode->target_x = u8g2_add_vector_x(decode->target_x, x, -(h+y), decode->dir);
  769. decode->target_y = u8g2_add_vector_y(decode->target_y, x, -(h+y), decode->dir);
  770. //u8g2_add_vector(&(decode->target_x), &(decode->target_y), x, -(h+y), decode->dir);
  771. /* reset local x/y position */
  772. decode->x = 0;
  773. decode->y = 0;
  774. /* decode glyph */
  775. for(;;){
  776. a = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_0);
  777. b = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_1);
  778. do{
  779. u8g2_font_decode_len(u8g2, a, 0);
  780. u8g2_font_decode_len(u8g2, b, 1);
  781. } while( u8g2_font_decode_get_unsigned_bits(decode, 1) != 0 );
  782. if ( decode->y >= h )
  783. break;
  784. }
  785. }
  786. return d;
  787. }
  788. const uint8_t *u8g2_font_get_glyph_data(u8g2_t *u8g2, uint16_t encoding);
  789. static int16_t u8g2_font_draw_glyph(u8g2_t *u8g2, int16_t x, int16_t y, uint16_t encoding){
  790. int16_t dx = 0;
  791. u8g2->font_decode.target_x = x;
  792. u8g2->font_decode.target_y = y;
  793. const uint8_t *glyph_data = u8g2_font_get_glyph_data(u8g2, encoding);
  794. if ( glyph_data != NULL ){
  795. dx = u8g2_font_decode_glyph(u8g2, glyph_data);
  796. }
  797. return dx;
  798. }
  799. /*
  800. 设置字体
  801. @api lcd.setFont(font)
  802. @int font lcd.font_XXX 请查阅常量表
  803. @usage
  804. -- 设置为字体,对之后的drawStr有效,调用lcd.drawStr前一定要先设置
  805. -- 若提示 "only font pointer is allow" , 则代表当前固件不含对应字体, 可使用云编译服务免费定制
  806. -- 云编译文档: https://wiki.luatos.com/develop/compile/Cloud_compilation.html
  807. -- lcd库的默认字体均以 lcd.font_ 开头
  808. lcd.setFont(lcd.font_opposansm12)
  809. lcd.drawStr(40,10,"drawStr")
  810. sys.wait(2000)
  811. lcd.setFont(lcd.font_opposansm12_chinese) -- 具体取值可参考api文档的常量表
  812. lcd.drawStr(40,40,"drawStr测试")
  813. */
  814. static int l_lcd_set_font(lua_State *L) {
  815. if (!lua_islightuserdata(L, 1)) {
  816. LLOGE("only font pointer is allow");
  817. return 0;
  818. }
  819. const uint8_t *ptr = (const uint8_t *)lua_touserdata(L, 1);
  820. if (ptr == NULL) {
  821. LLOGE("only font pointer is allow");
  822. return 0;
  823. }
  824. u8g2_SetFont(&(default_conf->luat_lcd_u8g2), ptr);
  825. lua_pushboolean(L, 1);
  826. return 1;
  827. }
  828. /*
  829. 显示字符串
  830. @api lcd.drawStr(x,y,str,fg_color)
  831. @int x 横坐标
  832. @int y 竖坐标 注意:此(x,y)为左下起始坐标
  833. @string str 文件内容
  834. @int fg_color str颜色 注意:此参数可选,如不填写则使用之前设置的颜色,绘制只会绘制字体部分,背景需要自己清除
  835. @usage
  836. -- 显示之前先设置为中文字体,对之后的drawStr有效
  837. lcd.setFont(lcd.font_opposansm12)
  838. lcd.drawStr(40,10,"drawStr")
  839. sys.wait(2000)
  840. lcd.setFont(lcd.font_opposansm16_chinese)
  841. lcd.drawStr(40,40,"drawStr测试")
  842. */
  843. static int l_lcd_draw_str(lua_State* L) {
  844. int x, y;
  845. size_t sz;
  846. const uint8_t* data;
  847. x = luaL_checkinteger(L, 1);
  848. y = luaL_checkinteger(L, 2);
  849. data = (const uint8_t*)luaL_checklstring(L, 3, &sz);
  850. lcd_str_fg_color = (luat_color_t)luaL_optinteger(L, 4,FORE_COLOR);
  851. // lcd_str_bg_color = (uint32_t)luaL_optinteger(L, 5,BACK_COLOR);
  852. if (sz == 0)
  853. return 0;
  854. uint16_t e;
  855. int16_t delta;
  856. utf8_state = 0;
  857. for(;;){
  858. e = utf8_next((uint8_t)*data);
  859. if ( e == 0x0ffff )
  860. break;
  861. data++;
  862. if ( e != 0x0fffe ){
  863. delta = u8g2_font_draw_glyph(&(default_conf->luat_lcd_u8g2), x, y, e);
  864. switch(default_conf->luat_lcd_u8g2.font_decode.dir){
  865. case 0:
  866. x += delta;
  867. break;
  868. case 1:
  869. y += delta;
  870. break;
  871. case 2:
  872. x -= delta;
  873. break;
  874. case 3:
  875. y -= delta;
  876. break;
  877. }
  878. }
  879. }
  880. lcd_auto_flush(default_conf);
  881. return 0;
  882. }
  883. #ifdef LUAT_USE_GTFONT
  884. #include "GT5SLCD2E_1A.h"
  885. extern void gtfont_draw_w(unsigned char *pBits,unsigned int x,unsigned int y,unsigned int widt,unsigned int high,int(*point)(void*),void* userdata,int mode);
  886. extern void gtfont_draw_gray_hz(unsigned char *data,unsigned short x,unsigned short y,unsigned short w ,unsigned short h,unsigned char grade, unsigned char HB_par,int(*point)(void*,uint16_t, uint16_t, uint32_t),void* userdata,int mode);
  887. /*
  888. 使用gtfont显示gb2312字符串
  889. @api lcd.drawGtfontGb2312(str,size,x,y)
  890. @string str 显示字符串
  891. @int size 字体大小 (支持16-192号大小字体)
  892. @int x 横坐标
  893. @int y 竖坐标
  894. @usage
  895. -- 注意, gtfont是额外的字体芯片硬件, 需要外挂在SPI总线才能调用本函数的
  896. lcd.drawGtfontGb2312("啊啊啊",32,0,0)
  897. */
  898. static int l_lcd_draw_gtfont_gb2312(lua_State *L) {
  899. unsigned char buf[128];
  900. size_t len;
  901. int i = 0;
  902. uint8_t strhigh,strlow ;
  903. uint16_t str;
  904. const char *fontCode = luaL_checklstring(L, 1,&len);
  905. unsigned char size = luaL_checkinteger(L, 2);
  906. int x = luaL_checkinteger(L, 3);
  907. int y = luaL_checkinteger(L, 4);
  908. while ( i < len){
  909. strhigh = *fontCode;
  910. fontCode++;
  911. strlow = *fontCode;
  912. str = (strhigh<<8)|strlow;
  913. fontCode++;
  914. int font_size = get_font(buf, 1, str, size, size, size);
  915. if(font_size != size){
  916. LLOGW("get gtfont error");
  917. return 0;
  918. }
  919. gtfont_draw_w(buf , x ,y , size , size,luat_lcd_draw_point,default_conf,0);
  920. x+=size;
  921. i+=2;
  922. }
  923. lcd_auto_flush(default_conf);
  924. return 0;
  925. }
  926. /*
  927. 使用gtfont灰度显示gb2312字符串
  928. @api lcd.drawGtfontGb2312Gray(str,size,gray,x,y)
  929. @string str 显示字符串
  930. @int size 字体大小 (支持16-192号大小字体)
  931. @int gray 灰度[1阶/2阶/3阶/4阶]
  932. @int x 横坐标
  933. @int y 竖坐标
  934. @usage
  935. -- 注意, gtfont是额外的字体芯片硬件, 需要外挂在SPI总线才能调用本函数的
  936. lcd.drawGtfontGb2312Gray("啊啊啊",32,4,0,40)
  937. */
  938. static int l_lcd_draw_gtfont_gb2312_gray(lua_State* L) {
  939. unsigned char buf[2048];
  940. size_t len;
  941. int i = 0;
  942. uint8_t strhigh,strlow ;
  943. uint16_t str;
  944. const char *fontCode = luaL_checklstring(L, 1,&len);
  945. unsigned char size = luaL_checkinteger(L, 2);
  946. unsigned char font_g = luaL_checkinteger(L, 3);
  947. int x = luaL_checkinteger(L, 4);
  948. int y = luaL_checkinteger(L, 5);
  949. while ( i < len){
  950. strhigh = *fontCode;
  951. fontCode++;
  952. strlow = *fontCode;
  953. str = (strhigh<<8)|strlow;
  954. fontCode++;
  955. int font_size = get_font(buf, 1, str, size*font_g, size*font_g, size*font_g);
  956. if(font_size != size*font_g){
  957. LLOGW("get gtfont error");
  958. return 0;
  959. }
  960. Gray_Process(buf,size,size,font_g);
  961. gtfont_draw_gray_hz(buf, x, y, size , size, font_g, 1,luat_lcd_draw_point,default_conf,0);
  962. x+=size;
  963. i+=2;
  964. }
  965. lcd_auto_flush(default_conf);
  966. return 0;
  967. }
  968. #ifdef LUAT_USE_GTFONT_UTF8
  969. extern unsigned short unicodetogb2312 ( unsigned short chr);
  970. /*
  971. 使用gtfont显示UTF8字符串
  972. @api lcd.drawGtfontUtf8(str,size,x,y)
  973. @string str 显示字符串
  974. @int size 字体大小 (支持16-192号大小字体)
  975. @int x 横坐标
  976. @int y 竖坐标
  977. @usage
  978. lcd.drawGtfontUtf8("啊啊啊",32,0,0)
  979. */
  980. static int l_lcd_draw_gtfont_utf8(lua_State *L) {
  981. unsigned char buf[128];
  982. size_t len;
  983. int i = 0;
  984. uint8_t strhigh,strlow ;
  985. uint16_t e,str;
  986. const char *fontCode = luaL_checklstring(L, 1,&len);
  987. unsigned char size = luaL_checkinteger(L, 2);
  988. int x = luaL_checkinteger(L, 3);
  989. int y = luaL_checkinteger(L, 4);
  990. for(;;){
  991. e = utf8_next((uint8_t)*fontCode);
  992. if ( e == 0x0ffff )
  993. break;
  994. fontCode++;
  995. if ( e != 0x0fffe ){
  996. uint16_t str = unicodetogb2312(e);
  997. int font_size = get_font(buf, 1, str, size, size, size);
  998. if(font_size != size){
  999. LLOGW("get gtfont error");
  1000. return 0;
  1001. }
  1002. gtfont_draw_w(buf , x ,y , size , size,luat_lcd_draw_point,default_conf,0);
  1003. x+=size;
  1004. }
  1005. }
  1006. lcd_auto_flush(default_conf);
  1007. return 0;
  1008. }
  1009. /*
  1010. 使用gtfont灰度显示UTF8字符串
  1011. @api lcd.drawGtfontUtf8Gray(str,size,gray,x,y)
  1012. @string str 显示字符串
  1013. @int size 字体大小 (支持16-192号大小字体)
  1014. @int gray 灰度[1阶/2阶/3阶/4阶]
  1015. @int x 横坐标
  1016. @int y 竖坐标
  1017. @usage
  1018. lcd.drawGtfontUtf8Gray("啊啊啊",32,4,0,40)
  1019. */
  1020. static int l_lcd_draw_gtfont_utf8_gray(lua_State* L) {
  1021. unsigned char buf[2048];
  1022. size_t len;
  1023. int i = 0;
  1024. uint8_t strhigh,strlow ;
  1025. uint16_t e,str;
  1026. const char *fontCode = luaL_checklstring(L, 1,&len);
  1027. unsigned char size = luaL_checkinteger(L, 2);
  1028. unsigned char font_g = luaL_checkinteger(L, 3);
  1029. int x = luaL_checkinteger(L, 4);
  1030. int y = luaL_checkinteger(L, 5);
  1031. for(;;){
  1032. e = utf8_next((uint8_t)*fontCode);
  1033. if ( e == 0x0ffff )
  1034. break;
  1035. fontCode++;
  1036. if ( e != 0x0fffe ){
  1037. uint16_t str = unicodetogb2312(e);
  1038. int font_size = get_font(buf, 1, str, size*font_g, size*font_g, size*font_g);
  1039. if(font_size != size*font_g){
  1040. LLOGW("get gtfont error");
  1041. return 0;
  1042. }
  1043. Gray_Process(buf,size,size,font_g);
  1044. gtfont_draw_gray_hz(buf, x, y, size , size, font_g, 1,luat_lcd_draw_point,default_conf,0);
  1045. x+=size;
  1046. }
  1047. }
  1048. lcd_auto_flush(default_conf);
  1049. return 0;
  1050. }
  1051. #endif // LUAT_USE_GTFONT_UTF8
  1052. #endif // LUAT_USE_GTFONT
  1053. static int l_lcd_set_default(lua_State *L) {
  1054. if (lua_gettop(L) == 1) {
  1055. default_conf = lua_touserdata(L, 1);
  1056. lua_pushboolean(L, 1);
  1057. return 1;
  1058. }
  1059. return 1;
  1060. }
  1061. static int l_lcd_get_default(lua_State *L) {
  1062. if (default_conf == NULL)
  1063. return 0;
  1064. lua_pushlightuserdata(L, default_conf);
  1065. return 1;
  1066. }
  1067. /*
  1068. 获取屏幕尺寸
  1069. @api lcd.getSize()
  1070. @return int 宽, 如果未初始化会返回0
  1071. @return int 高, 如果未初始化会返回0
  1072. @usage
  1073. log.info("lcd", "size", lcd.getSize())
  1074. */
  1075. static int l_lcd_get_size(lua_State *L) {
  1076. if (lua_gettop(L) == 1) {
  1077. luat_lcd_conf_t * conf = lua_touserdata(L, 1);
  1078. if (conf) {
  1079. lua_pushinteger(L, conf->w);
  1080. lua_pushinteger(L, conf->h);
  1081. return 2;
  1082. }
  1083. }
  1084. if (default_conf == NULL) {
  1085. lua_pushinteger(L, 0);
  1086. lua_pushinteger(L, 0);
  1087. }
  1088. else {
  1089. lua_pushinteger(L, default_conf->w);
  1090. lua_pushinteger(L, default_conf->h);
  1091. }
  1092. return 2;
  1093. }
  1094. /*
  1095. 绘制位图
  1096. @api lcd.drawXbm(x, y, w, h, data)
  1097. @int X坐标
  1098. @int y坐标
  1099. @int 位图宽
  1100. @int 位图高
  1101. @int 位图数据,每一位代表一个像素
  1102. @usage
  1103. -- 取模使用PCtoLCD2002软件即可 阴码 逐行 逆向
  1104. -- 在(0,0)为左上角,绘制 16x16 "今" 的位图
  1105. lcd.drawXbm(0, 0, 16,16, string.char(
  1106. 0x80,0x00,0x80,0x00,0x40,0x01,0x20,0x02,0x10,0x04,0x48,0x08,0x84,0x10,0x83,0x60,
  1107. 0x00,0x00,0xF8,0x0F,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x01,0x80,0x00
  1108. ))
  1109. */
  1110. static int l_lcd_drawxbm(lua_State *L){
  1111. int x = luaL_checkinteger(L, 1);
  1112. int y = luaL_checkinteger(L, 2);
  1113. int w = luaL_checkinteger(L, 3);
  1114. int h = luaL_checkinteger(L, 4);
  1115. size_t len = 0;
  1116. const char* data = luaL_checklstring(L, 5, &len);
  1117. uint8_t mask = 1;
  1118. if (h < 1) return 0; // 行数必须大于0
  1119. if (len*8/h < w) return 0; // 起码要填满一行
  1120. int w1 = w/8;
  1121. if (w%8)w1++;
  1122. if (len != h*w1)return 0;
  1123. luat_color_t* color_w = luat_heap_malloc(sizeof(luat_color_t) * w);
  1124. for (size_t b = 0; b < h; b++){
  1125. size_t a = 0;
  1126. while (a < w){
  1127. for (size_t c = 0; c < 8; c++){
  1128. if (*data&(mask<<c)){
  1129. color_w[a]=FORE_COLOR;
  1130. }else{
  1131. color_w[a]=BACK_COLOR;
  1132. }
  1133. a++;
  1134. if (a == w)break;
  1135. }
  1136. data++;
  1137. }
  1138. luat_lcd_draw(default_conf, x, y+b, x+w-1, y+b, color_w);
  1139. }
  1140. luat_heap_free(color_w);
  1141. lcd_auto_flush(default_conf);
  1142. lua_pushboolean(L, 1);
  1143. return 1;
  1144. }
  1145. #ifdef LUAT_USE_TJPGD
  1146. #include "tjpgd.h"
  1147. #include "tjpgdcnf.h"
  1148. #define N_BPP (3 - JD_FORMAT)
  1149. /* Session identifier for input/output functions (name, members and usage are as user defined) */
  1150. typedef struct {
  1151. FILE *fp; /* Input stream */
  1152. int x;
  1153. int y;
  1154. // int width;
  1155. // int height;
  1156. uint16_t buff[16*16]
  1157. } IODEV;
  1158. static unsigned int file_in_func (JDEC* jd, uint8_t* buff, unsigned int nbyte){
  1159. IODEV *dev = (IODEV*)jd->device; /* Device identifier for the session (5th argument of jd_prepare function) */
  1160. if (buff) {
  1161. /* Read bytes from input stream */
  1162. return luat_fs_fread(buff, 1, nbyte, dev->fp);
  1163. } else {
  1164. /* Remove bytes from input stream */
  1165. return luat_fs_fseek(dev->fp, nbyte, SEEK_CUR) ? 0 : nbyte;
  1166. }
  1167. }
  1168. static unsigned int lcd_out_func (JDEC* jd, void* bitmap, JRECT* rect){
  1169. IODEV *dev = (IODEV*)jd->device;
  1170. uint16_t* tmp = (uint16_t*)bitmap;
  1171. // rgb高低位swap
  1172. uint16_t count = (rect->right - rect->left + 1) * (rect->bottom - rect->top + 1);
  1173. for (size_t i = 0; i < count; i++)
  1174. {
  1175. dev->buff[i] = ((tmp[i] >> 8) & 0xFF)+ ((tmp[i] << 8) & 0xFF00);
  1176. }
  1177. // LLOGD("jpeg seg %dx%d %dx%d", rect->left, rect->top, rect->right, rect->bottom);
  1178. // LLOGD("jpeg seg size %d %d %d", rect->right - rect->left + 1, rect->bottom - rect->top + 1, (rect->right - rect->left + 1) * (rect->bottom - rect->top + 1));
  1179. luat_lcd_draw(default_conf, dev->x + rect->left, dev->y + rect->top,
  1180. dev->x + rect->right, dev->y + rect->bottom,
  1181. dev->buff);
  1182. return 1; /* Continue to decompress */
  1183. }
  1184. static int lcd_draw_jpeg(const char* path, int xpos, int ypos) {
  1185. JRESULT res; /* Result code of TJpgDec API */
  1186. JDEC jdec; /* Decompression object */
  1187. void *work; /* Pointer to the decompressor work area */
  1188. #if JD_FASTDECODE == 2
  1189. size_t sz_work = 3500 * 3; /* Size of work area */
  1190. #else
  1191. size_t sz_work = 3500; /* Size of work area */
  1192. #endif
  1193. IODEV devid; /* User defined device identifier */
  1194. FILE* fd = luat_fs_fopen(path, "r");
  1195. if (fd == NULL) {
  1196. LLOGW("no such file %s", path);
  1197. return -1;
  1198. }
  1199. devid.fp = fd;
  1200. work = luat_heap_malloc(sz_work);
  1201. if (work == NULL) {
  1202. LLOGE("out of memory when malloc jpeg decode workbuff");
  1203. return -3;
  1204. }
  1205. res = jd_prepare(&jdec, file_in_func, work, sz_work, &devid);
  1206. if (res != JDR_OK) {
  1207. luat_heap_free(work);
  1208. luat_fs_fclose(fd);
  1209. LLOGW("jd_prepare file %s error %d", path, res);
  1210. return -2;
  1211. }
  1212. devid.x = xpos;
  1213. devid.y = ypos;
  1214. // devid.width = jdec.width;
  1215. // devid.height = jdec.height;
  1216. res = jd_decomp(&jdec, lcd_out_func, 0);
  1217. luat_heap_free(work);
  1218. luat_fs_fclose(fd);
  1219. if (res != JDR_OK) {
  1220. LLOGW("jd_decomp file %s error %d", path, res);
  1221. return -2;
  1222. }
  1223. else {
  1224. lcd_auto_flush(default_conf);
  1225. return 0;
  1226. }
  1227. }
  1228. /*
  1229. 显示图片,当前只支持jpg,jpeg
  1230. @api lcd.showImage(x, y, file)
  1231. @int X坐标
  1232. @int y坐标
  1233. @string 文件路径
  1234. @usage
  1235. lcd.showImage(0,0,"/luadb/logo.jpg")
  1236. */
  1237. static int l_lcd_showimage(lua_State *L){
  1238. size_t size = 0;
  1239. int ret = 0;
  1240. int x = luaL_checkinteger(L, 1);
  1241. int y = luaL_checkinteger(L, 2);
  1242. const char* input_file = luaL_checklstring(L, 3, &size);
  1243. if (memcmp(input_file+size-4, ".jpg", 5) == 0 || memcmp(input_file+size-4, ".JPG", 5) == 0 || memcmp(input_file+size-5, ".jpeg", 6) == 0 || memcmp(input_file+size-5, ".JPEG", 6) == 0){
  1244. ret = lcd_draw_jpeg(input_file, x, y);
  1245. lua_pushboolean(L, ret == 0 ? 1 : 0);
  1246. } else{
  1247. LLOGE("input_file not support");
  1248. lua_pushboolean(L, 0);
  1249. }
  1250. return 1;
  1251. }
  1252. #endif
  1253. /*
  1254. 主动刷新数据到界面, 仅设置buff且禁用自动属性后使用
  1255. @api lcd.flush()
  1256. @return bool 成功返回true, 否则返回nil/false
  1257. @usgae
  1258. -- 本API与 lcd.setupBuff lcd.autoFlush 配合使用
  1259. lcd.flush()
  1260. */
  1261. static int l_lcd_flush(lua_State* L) {
  1262. luat_lcd_conf_t * conf = NULL;
  1263. if (lua_gettop(L) == 1) {
  1264. conf = lua_touserdata(L, 1);
  1265. }
  1266. else {
  1267. conf = default_conf;
  1268. }
  1269. if (conf == NULL) {
  1270. //LLOGW("lcd not init");
  1271. return 0;
  1272. }
  1273. if (conf->buff == NULL) {
  1274. //LLOGW("lcd without buff, not support flush");
  1275. return 0;
  1276. }
  1277. if (conf->auto_flush) {
  1278. //LLOGI("lcd auto flush is enable, no need for flush");
  1279. return 0;
  1280. }
  1281. luat_lcd_flush(conf);
  1282. lua_pushboolean(L, 1);
  1283. return 0;
  1284. }
  1285. /*
  1286. 设置显示缓冲区, 所需内存大小为 2×宽×高 字节. 请衡量内存需求与业务所需的刷新频次.
  1287. @api lcd.setupBuff(conf, onheap)
  1288. @userdata conf指针, 不需要传
  1289. @bool true使用heap内存, false使用vm内存, 默认使用vm内存, 不需要主动传
  1290. @return bool 是否成功
  1291. @usage
  1292. -- 初始化lcd的buff缓冲区, 可理解为FrameBuffer区域.
  1293. lcd.setupBuff()
  1294. */
  1295. static int l_lcd_setup_buff(lua_State* L) {
  1296. luat_lcd_conf_t * conf = NULL;
  1297. if (lua_gettop(L) == 1) {
  1298. conf = lua_touserdata(L, 1);
  1299. }
  1300. else {
  1301. conf = default_conf;
  1302. }
  1303. if (conf == NULL) {
  1304. LLOGW("lcd not init");
  1305. return 0;
  1306. }
  1307. if (conf->buff != NULL) {
  1308. LLOGW("lcd buff is ok");
  1309. return 0;
  1310. }
  1311. if (lua_isboolean(L, 2) && lua_toboolean(L, 2)) {
  1312. conf->buff = luat_heap_malloc(sizeof(luat_color_t) * conf->w * conf->h);
  1313. }
  1314. else {
  1315. conf->buff = lua_newuserdata(L, sizeof(luat_color_t) * conf->w * conf->h);
  1316. if (conf->buff) {
  1317. conf->buff_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  1318. }
  1319. }
  1320. if (conf->buff == NULL) {
  1321. LLOGE("lcd buff malloc fail, out of memory?");
  1322. return 0;
  1323. }
  1324. // 先设置为不需要的区间
  1325. conf->flush_y_min = conf->h;
  1326. conf->flush_y_max = 0;
  1327. // luat_lcd_clear 会将区域扩展到整个屏幕
  1328. luat_lcd_clear(default_conf, BACK_COLOR);
  1329. lua_pushboolean(L, 1);
  1330. return 1;
  1331. }
  1332. /*
  1333. 设置自动刷新, 需配合lcd.setupBuff使用
  1334. @api lcd.autoFlush(enable)
  1335. @bool 是否自动刷新,默认为true
  1336. @usage
  1337. -- 设置buff 并禁用自动更新
  1338. lcd.setupBuff()
  1339. lcd.autoFlush(false)
  1340. -- 禁止自动更新后, 需要使用 lcd.flush() 主动刷新数据到屏幕
  1341. */
  1342. static int l_lcd_auto_flush(lua_State* L) {
  1343. luat_lcd_conf_t * conf = default_conf;
  1344. if (conf == NULL) {
  1345. LLOGW("lcd not init");
  1346. return 0;
  1347. }
  1348. conf->auto_flush = lua_toboolean(L, 1);
  1349. lua_pushboolean(L, conf->auto_flush);
  1350. return 1;
  1351. }
  1352. /*
  1353. RGB565颜色生成
  1354. @api lcd.rgb565(r, g, b, swap)
  1355. @int 红色, 0x00 ~ 0xFF
  1356. @int 绿色, 0x00 ~ 0xFF
  1357. @int 蓝色, 0x00 ~ 0xFF
  1358. @bool 是否翻转, true 翻转, false 不翻转. 默认翻转
  1359. @return int 颜色值
  1360. @usage
  1361. -- 本API支持多种模式, 参数数量分别是 1, 2, 3, 4
  1362. -- 1. 单参数形式, 24bit RGB值, swap = true, 推荐
  1363. local red = lcd.rgb565(0xFF0000)
  1364. local green = lcd.rgb565(0x00FF00)
  1365. local blue = lcd.rgb565(0x0000FF)
  1366. -- 2. 两参数形式, 24bit RGB值, 增加swap的设置
  1367. local red = lcd.rgb565(0xFF0000, true)
  1368. local green = lcd.rgb565(0x00FF00, true)
  1369. local blue = lcd.rgb565(0x0000FF, true)
  1370. -- 3. 三参数形式, 红/绿/蓝, 各8bit
  1371. local red = lcd.rgb565(0xFF, 0x00, 0x00)
  1372. local green = lcd.rgb565(0x00, 0xFF, 0x00)
  1373. local blue = lcd.rgb565(0x00, 0x00, 0xFF)
  1374. -- 4. 四参数形式, 红/绿/蓝, 各8bit, 增加swap的设置
  1375. local red = lcd.rgb565(0xFF, 0x00, 0x00, true)
  1376. local green = lcd.rgb565(0x00, 0xFF, 0x00, true)
  1377. local blue = lcd.rgb565(0x00, 0x00, 0xFF, true)
  1378. */
  1379. static int l_lcd_rgb565(lua_State* L) {
  1380. uint8_t r =0,g =0,b = 0;
  1381. uint8_t swap = 0;
  1382. uint16_t dst = 0;
  1383. int top = 0 ;
  1384. uint32_t rgb = 0;
  1385. top = lua_gettop(L);
  1386. if (top == 1 || top == 2) {
  1387. rgb = luaL_checkinteger(L, 1);
  1388. r = (uint8_t)((rgb >> 16 ) & 0xFF);
  1389. g = (uint8_t)((rgb >> 8 ) & 0xFF);
  1390. b = (uint8_t)((rgb >> 0 ) & 0xFF);
  1391. swap = (lua_isboolean(L, 2) && !lua_toboolean(L, 2)) ? 0U : 1U;
  1392. }
  1393. else if (top == 3 || top == 4) {
  1394. r = (uint8_t)luaL_checkinteger(L, 1);
  1395. g = (uint8_t)luaL_checkinteger(L, 2);
  1396. b = (uint8_t)luaL_checkinteger(L, 3);
  1397. swap = (lua_isboolean(L, 4) && !lua_toboolean(L, 4)) ? 0U : 1U;
  1398. }
  1399. else {
  1400. LLOGW("unkown args count %d", top);
  1401. dst = 0;
  1402. }
  1403. dst = (uint16_t)((r&0xF8)<<8) | (uint16_t)((g&0xFC)<<3) | (uint16_t)(b>>3);
  1404. if (swap) {
  1405. dst = ((dst >> 8) & 0xFF) + ((dst & 0xFF) << 8);
  1406. }
  1407. lua_pushinteger(L, dst);
  1408. return 1;
  1409. }
  1410. #ifdef LUAT_USE_UFONT
  1411. #include "luat_ufont.h"
  1412. static const int l_lcd_draw_utf8(lua_State *L) {
  1413. size_t sz = 0;
  1414. uint32_t letter = 0;
  1415. uint32_t str_offset;
  1416. int ret = 0;
  1417. uint16_t draw_offset = 0;
  1418. int draw_x = 0;
  1419. int draw_y = 0;
  1420. luat_font_char_desc_t desc = {0};
  1421. // 左上角坐标x,y
  1422. int x = luaL_checkinteger(L, 1);
  1423. int y = luaL_checkinteger(L, 2);
  1424. // 待绘制的字符串
  1425. const char* data = (const char*)luaL_checklstring(L, 3, &sz);
  1426. // 字体指针
  1427. lv_font_t* lfont = (lv_font_t*)lua_touserdata(L, 4);
  1428. if (lfont == NULL) {
  1429. LLOGW("draw without font");
  1430. return 0;
  1431. }
  1432. luat_font_header_t* font = (luat_font_header_t*)lfont->dsc;
  1433. // 是否填充背景
  1434. bool draw_bg = lua_isboolean(L, 5) ? lua_toboolean(L, 5) : true;
  1435. // 没内容, 不需要画了
  1436. if (sz == 0) {
  1437. // 直接返回原坐标
  1438. lua_pushinteger(L, x);
  1439. return 1;
  1440. }
  1441. // 没字体, 不需要画了
  1442. if (font == NULL) {
  1443. LLOGD("NULL font, skip draw");
  1444. // 直接返回原坐标
  1445. lua_pushinteger(L, x);
  1446. return 1;
  1447. }
  1448. // 超边界了没? 超了就没必要绘制了
  1449. if (default_conf->h < y || default_conf->w < x) {
  1450. //LLOGD("draw y %d h % font->line_height %d", y, default_conf->h, font->line_height);
  1451. // 直接返回原坐标
  1452. lua_pushinteger(L, x);
  1453. return 1;
  1454. }
  1455. luat_color_t* buff = NULL;
  1456. if (draw_bg)
  1457. buff = luat_heap_malloc(font->line_height * font->line_height * 2);
  1458. // if (buff == NULL)
  1459. // return 0;
  1460. int offset = 0;
  1461. uint8_t *data_ptr = data;
  1462. uint8_t utf8_state = 0;
  1463. uint16_t utf8_tmp = 0;
  1464. uint16_t utf8_out = 0;
  1465. luat_color_t color = FORE_COLOR;
  1466. for (size_t i = 0; i < sz; i++)
  1467. {
  1468. utf8_out = luat_utf8_next(data[i], &utf8_state, &utf8_tmp);
  1469. if (utf8_out == 0x0ffff)
  1470. break; // 结束了
  1471. if (utf8_out == 0x0fffe)
  1472. continue; // 没读完一个字符,继续下一个循环
  1473. letter = (uint32_t)utf8_out;
  1474. //LLOGD("draw letter %04X", letter);
  1475. int ret = luat_font_get_bitmap(font, &desc, letter);
  1476. if (ret != 0) {
  1477. LLOGD("not such char in font");
  1478. draw_offset += font->line_height / 2; // 找不到字符, 默认跳过半个字
  1479. continue;
  1480. }
  1481. offset = 0;
  1482. // desc.data = tmp;
  1483. memset(buff, 0, font->line_height * font->line_height * 2);
  1484. draw_x = x + draw_offset;
  1485. draw_offset += desc.char_w;
  1486. if (draw_x >= 0 && draw_x + desc.char_w <= default_conf->w) {
  1487. //if (default_conf->buff == NULL) {
  1488. for (size_t j = 0; j < font->line_height; j++)
  1489. {
  1490. //LLOGD("draw char pix line %d", i);
  1491. for (size_t k = 0; k < desc.char_w; k++)
  1492. {
  1493. if ((desc.data[offset / 8] >> (7 - (offset % 8))) & 0x01) {
  1494. color = FORE_COLOR;
  1495. if (buff)
  1496. buff[offset] = FORE_COLOR;
  1497. else
  1498. luat_lcd_draw_point(default_conf, draw_x + k, y + j, FORE_COLOR);
  1499. //LLOGD("draw char pix mark %d", offset);
  1500. }
  1501. else {
  1502. if (buff)
  1503. buff[offset] = BACK_COLOR;
  1504. //LLOGD("draw char pix offset %d color %04X", offset, FORE_COLOR);
  1505. }
  1506. offset ++;
  1507. }
  1508. }
  1509. //LLOGD("luat_lcd_draw %d %d %d %d", draw_x, y, draw_x + desc.char_w, y + font->line_height);
  1510. luat_lcd_draw(default_conf, draw_x, y, draw_x + desc.char_w - 1, y + font->line_height - 1, buff);
  1511. //}
  1512. //else {
  1513. //
  1514. //}
  1515. }
  1516. }
  1517. if (buff)
  1518. luat_heap_free(buff);
  1519. lcd_auto_flush(default_conf);
  1520. lua_pushinteger(L, draw_x + desc.char_w);
  1521. return 1;
  1522. }
  1523. #endif
  1524. #include "rotable2.h"
  1525. static const rotable_Reg_t reg_lcd[] =
  1526. {
  1527. { "init", ROREG_FUNC(l_lcd_init)},
  1528. { "clear", ROREG_FUNC(l_lcd_clear)},
  1529. { "fill", ROREG_FUNC(l_lcd_draw_fill)},
  1530. { "drawPoint", ROREG_FUNC(l_lcd_draw_point)},
  1531. { "drawLine", ROREG_FUNC(l_lcd_draw_line)},
  1532. { "drawRectangle", ROREG_FUNC(l_lcd_draw_rectangle)},
  1533. { "drawCircle", ROREG_FUNC(l_lcd_draw_circle)},
  1534. { "drawQrcode", ROREG_FUNC(l_lcd_drawQrcode)},
  1535. { "drawStr", ROREG_FUNC(l_lcd_draw_str)},
  1536. { "flush", ROREG_FUNC(l_lcd_flush)},
  1537. { "setupBuff", ROREG_FUNC(l_lcd_setup_buff)},
  1538. { "autoFlush", ROREG_FUNC(l_lcd_auto_flush)},
  1539. { "setFont", ROREG_FUNC(l_lcd_set_font)},
  1540. { "setDefault", ROREG_FUNC(l_lcd_set_default)},
  1541. { "getDefault", ROREG_FUNC(l_lcd_get_default)},
  1542. { "getSize", ROREG_FUNC(l_lcd_get_size)},
  1543. { "drawXbm", ROREG_FUNC(l_lcd_drawxbm)},
  1544. { "close", ROREG_FUNC(l_lcd_close)},
  1545. { "on", ROREG_FUNC(l_lcd_display_on)},
  1546. { "off", ROREG_FUNC(l_lcd_display_off)},
  1547. { "sleep", ROREG_FUNC(l_lcd_sleep)},
  1548. { "wakeup", ROREG_FUNC(l_lcd_wakeup)},
  1549. { "invon", ROREG_FUNC(l_lcd_inv_on)},
  1550. { "invoff", ROREG_FUNC(l_lcd_inv_off)},
  1551. { "cmd", ROREG_FUNC(l_lcd_write_cmd)},
  1552. { "data", ROREG_FUNC(l_lcd_write_data)},
  1553. { "setColor", ROREG_FUNC(l_lcd_set_color)},
  1554. { "draw", ROREG_FUNC(l_lcd_draw)},
  1555. { "rgb565", ROREG_FUNC(l_lcd_rgb565)},
  1556. #ifdef LUAT_USE_UFONT
  1557. { "drawUTF8", ROREG_FUNC(l_lcd_draw_utf8)},
  1558. #endif
  1559. #ifdef LUAT_USE_TJPGD
  1560. { "showImage", ROREG_FUNC(l_lcd_showimage)},
  1561. #endif
  1562. #ifdef LUAT_USE_GTFONT
  1563. { "drawGtfontGb2312", ROREG_FUNC(l_lcd_draw_gtfont_gb2312)},
  1564. { "drawGtfontGb2312Gray", ROREG_FUNC(l_lcd_draw_gtfont_gb2312_gray)},
  1565. #ifdef LUAT_USE_GTFONT_UTF8
  1566. { "drawGtfontUtf8", ROREG_FUNC(l_lcd_draw_gtfont_utf8)},
  1567. { "drawGtfontUtf8Gray", ROREG_FUNC(l_lcd_draw_gtfont_utf8_gray)},
  1568. #endif // LUAT_USE_GTFONT_UTF8
  1569. #endif // LUAT_USE_GTFONT
  1570. // 默认只带英文8号字体
  1571. //@const font_opposansm8 font 8号字体
  1572. { "font_opposansm8", ROREG_PTR((void*)u8g2_font_opposansm8)},
  1573. #ifdef USE_U8G2_OPPOSANSM_ENGLISH
  1574. //@const font_unifont_t_symbols font 符号字体
  1575. { "font_unifont_t_symbols", ROREG_PTR((void*)u8g2_font_unifont_t_symbols)},
  1576. //@const font_open_iconic_weather_6x_t font 天气字体
  1577. { "font_open_iconic_weather_6x_t", ROREG_PTR((void*)u8g2_font_open_iconic_weather_6x_t)},
  1578. //@const font_opposansm10 font 10号字体
  1579. //@const font_opposansm12 font 12号字体
  1580. //@const font_opposansm16 font 16号字体
  1581. //@const font_opposansm18 font 18号字体
  1582. //@const font_opposansm20 font 20号字体
  1583. //@const font_opposansm22 font 22号字体
  1584. //@const font_opposansm24 font 24号字体
  1585. //@const font_opposansm32 font 32号字体
  1586. { "font_opposansm10", ROREG_PTR((void*)u8g2_font_opposansm10)},
  1587. { "font_opposansm12", ROREG_PTR((void*)u8g2_font_opposansm12)},
  1588. { "font_opposansm16", ROREG_PTR((void*)u8g2_font_opposansm16)},
  1589. { "font_opposansm18", ROREG_PTR((void*)u8g2_font_opposansm18)},
  1590. { "font_opposansm20", ROREG_PTR((void*)u8g2_font_opposansm20)},
  1591. { "font_opposansm22", ROREG_PTR((void*)u8g2_font_opposansm22)},
  1592. { "font_opposansm24", ROREG_PTR((void*)u8g2_font_opposansm24)},
  1593. { "font_opposansm32", ROREG_PTR((void*)u8g2_font_opposansm32)},
  1594. #endif
  1595. #ifdef USE_U8G2_OPPOSANSM8_CHINESE
  1596. //@const font_opposansm8_chinese font 8号中文字体
  1597. { "font_opposansm8_chinese", ROREG_PTR((void*)u8g2_font_opposansm8_chinese)},
  1598. #endif
  1599. #ifdef USE_U8G2_OPPOSANSM10_CHINESE
  1600. //@const font_opposansm10_chinese font 10号中文字体
  1601. { "font_opposansm10_chinese", ROREG_PTR((void*)u8g2_font_opposansm10_chinese)},
  1602. #endif
  1603. #ifdef USE_U8G2_OPPOSANSM12_CHINESE
  1604. //@const font_opposansm12_chinese font 12号中文字体
  1605. { "font_opposansm12_chinese", ROREG_PTR((void*)u8g2_font_opposansm12_chinese)},
  1606. #endif
  1607. #ifdef USE_U8G2_OPPOSANSM16_CHINESE
  1608. //@const font_opposansm16_chinese font 16号中文字体
  1609. { "font_opposansm16_chinese", ROREG_PTR((void*)u8g2_font_opposansm16_chinese)},
  1610. #endif
  1611. #ifdef USE_U8G2_OPPOSANSM18_CHINESE
  1612. //@const font_opposansm18_chinese font 18号中文字体
  1613. { "font_opposansm18_chinese", ROREG_PTR((void*)u8g2_font_opposansm18_chinese)},
  1614. #endif
  1615. #ifdef USE_U8G2_OPPOSANSM20_CHINESE
  1616. //@const font_opposansm20_chinese font 20号中文字体
  1617. { "font_opposansm20_chinese", ROREG_PTR((void*)u8g2_font_opposansm20_chinese)},
  1618. #endif
  1619. #ifdef USE_U8G2_OPPOSANSM22_CHINESE
  1620. //@const font_opposansm22_chinese font 22号中文字体
  1621. { "font_opposansm22_chinese", ROREG_PTR((void*)u8g2_font_opposansm22_chinese)},
  1622. #endif
  1623. #ifdef USE_U8G2_OPPOSANSM24_CHINESE
  1624. //@const font_opposansm24_chinese font 24号中文字体
  1625. { "font_opposansm24_chinese", ROREG_PTR((void*)u8g2_font_opposansm24_chinese)},
  1626. #endif
  1627. #ifdef USE_U8G2_OPPOSANSM32_CHINESE
  1628. //@const font_opposansm32_chinese font 32号中文字体
  1629. { "font_opposansm32_chinese", ROREG_PTR((void*)u8g2_font_opposansm32_chinese)},
  1630. #endif
  1631. #ifdef USE_U8G2_SARASA_ENGLISH
  1632. { "font_sarasa_m8_ascii", ROREG_PTR((void*)u8g2_font_sarasa_m8_ascii)},
  1633. { "font_sarasa_m10_ascii", ROREG_PTR((void*)u8g2_font_sarasa_m10_ascii)},
  1634. { "font_sarasa_m12_ascii", ROREG_PTR((void*)u8g2_font_sarasa_m12_ascii)},
  1635. { "font_sarasa_m14_ascii", ROREG_PTR((void*)u8g2_font_sarasa_m14_ascii)},
  1636. { "font_sarasa_m16_ascii", ROREG_PTR((void*)u8g2_font_sarasa_m16_ascii)},
  1637. { "font_sarasa_m18_ascii", ROREG_PTR((void*)u8g2_font_sarasa_m18_ascii)},
  1638. { "font_sarasa_m20_ascii", ROREG_PTR((void*)u8g2_font_sarasa_m20_ascii)},
  1639. { "font_sarasa_m22_ascii", ROREG_PTR((void*)u8g2_font_sarasa_m22_ascii)},
  1640. //再大的很少用到先不加了
  1641. #endif
  1642. #ifdef USE_U8G2_SARASA_M8_CHINESE
  1643. { "font_sarasa_m8_chinese", ROREG_PTR((void*)u8g2_font_sarasa_m8_chinese)},
  1644. #endif
  1645. #ifdef USE_U8G2_SARASA_M10_CHINESE
  1646. { "font_sarasa_m10_chinese", ROREG_PTR((void*)u8g2_font_sarasa_m10_chinese)},
  1647. #endif
  1648. #ifdef USE_U8G2_SARASA_M12_CHINESE
  1649. { "font_sarasa_m12_chinese", ROREG_PTR((void*)u8g2_font_sarasa_m12_chinese)},
  1650. #endif
  1651. #ifdef USE_U8G2_SARASA_M14_CHINESE
  1652. { "font_sarasa_m14_chinese", ROREG_PTR((void*)u8g2_font_sarasa_m14_chinese)},
  1653. #endif
  1654. #ifdef USE_U8G2_SARASA_M16_CHINESE
  1655. { "font_sarasa_m16_chinese", ROREG_PTR((void*)u8g2_font_sarasa_m16_chinese)},
  1656. #endif
  1657. #ifdef USE_U8G2_SARASA_M18_CHINESE
  1658. { "font_sarasa_m18_chinese", ROREG_PTR((void*)u8g2_font_sarasa_m18_chinese)},
  1659. #endif
  1660. #ifdef USE_U8G2_SARASA_M20_CHINESE
  1661. { "font_sarasa_m20_chinese", ROREG_PTR((void*)u8g2_font_sarasa_m20_chinese)},
  1662. #endif
  1663. #ifdef USE_U8G2_SARASA_M22_CHINESE
  1664. { "font_sarasa_m22_chinese", ROREG_PTR((void*)u8g2_font_sarasa_m22_chinese)},
  1665. #endif
  1666. #ifdef USE_U8G2_SARASA_M24_CHINESE
  1667. { "font_sarasa_m24_chinese", ROREG_PTR((void*)u8g2_font_sarasa_m24_chinese)},
  1668. #endif
  1669. #ifdef USE_U8G2_SARASA_M26_CHINESE
  1670. { "font_sarasa_m26_chinese", ROREG_PTR((void*)u8g2_font_sarasa_m26_chinese)},
  1671. #endif
  1672. #ifdef USE_U8G2_SARASA_M28_CHINESE
  1673. { "font_sarasa_m28_chinese", ROREG_PTR((void*)u8g2_font_sarasa_m28_chinese)},
  1674. #endif
  1675. {NULL, ROREG_INT(0)}
  1676. };
  1677. LUAMOD_API int luaopen_lcd( lua_State *L ) {
  1678. luat_newlib2(L, reg_lcd);
  1679. return 1;
  1680. }