luat_lib_lcd.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103
  1. /*
  2. @module lcd
  3. @summary lcd驱动模块
  4. @version 1.0
  5. @date 2021.06.16
  6. */
  7. #include "luat_base.h"
  8. #include "luat_lcd.h"
  9. #include "luat_malloc.h"
  10. #include "luat_zbuff.h"
  11. #include "luat_spi.h"
  12. #define LUAT_LOG_TAG "lcd"
  13. #include "luat_log.h"
  14. #include "u8g2.h"
  15. #include "u8g2_luat_fonts.h"
  16. #include "../qrcode/qrcode.h"
  17. int8_t u8g2_font_decode_get_signed_bits(u8g2_font_decode_t *f, uint8_t cnt);
  18. uint8_t u8g2_font_decode_get_unsigned_bits(u8g2_font_decode_t *f, uint8_t cnt);
  19. enum
  20. {
  21. font_opposansm8,
  22. font_opposansm10,
  23. font_opposansm12,
  24. font_opposansm16,
  25. font_opposansm18,
  26. font_opposansm20,
  27. font_opposansm22,
  28. font_opposansm24,
  29. font_opposansm32,
  30. font_opposansm12_chinese,
  31. font_opposansm16_chinese,
  32. font_opposansm24_chinese,
  33. font_opposansm32_chinese,
  34. };
  35. extern uint32_t BACK_COLOR , FORE_COLOR ;
  36. extern const luat_lcd_opts_t lcd_opts_st7735;
  37. extern const luat_lcd_opts_t lcd_opts_st7735v;
  38. extern const luat_lcd_opts_t lcd_opts_st7735s;
  39. extern const luat_lcd_opts_t lcd_opts_st7789;
  40. extern const luat_lcd_opts_t lcd_opts_gc9a01;
  41. extern const luat_lcd_opts_t lcd_opts_gc9106l;
  42. extern const luat_lcd_opts_t lcd_opts_gc9306;
  43. extern const luat_lcd_opts_t lcd_opts_ili9341;
  44. extern const luat_lcd_opts_t lcd_opts_ili9488;
  45. extern const luat_lcd_opts_t lcd_opts_custom;
  46. static luat_lcd_conf_t *default_conf = NULL;
  47. static uint32_t lcd_str_fg_color,lcd_str_bg_color;
  48. /*
  49. lcd显示屏初始化
  50. @api lcd.init(tp, args)
  51. @string lcd类型, 当前支持st7789/st7735/st7735v/st7735s/gc9a01/gc9106l/gc9306/ili9341/custom
  52. @table 附加参数,与具体设备有关,pin_pwr为可选项,可不设置port:spi端口,例如0,1,2...如果为device方式则为"device";pin_dc:lcd数据/命令选择引脚;pin_rst:lcd复位引脚;pin_pwr:lcd背光引脚 可选项,可不设置;direction:lcd屏幕方向 0:0° 1:180° 2:270° 3:90°;w:lcd 水平分辨率;h:lcd 竖直分辨率;xoffset:x偏移(不同屏幕ic 不同屏幕方向会有差异);yoffset:y偏移(不同屏幕ic 不同屏幕方向会有差异)
  53. @userdata spi设备,当port = "device"时有效
  54. @usage
  55. -- 初始化spi0的st7789 注意:lcd初始化之前需要先初始化spi
  56. local spi_lcd = spi.deviceSetup(0,20,0,0,8,2000000,spi.MSB,1,1)
  57. log.info("lcd.init",
  58. 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))
  59. */
  60. static int l_lcd_init(lua_State* L) {
  61. size_t len = 0;
  62. luat_lcd_conf_t *conf = luat_heap_malloc(sizeof(luat_lcd_conf_t));
  63. memset(conf, 0, sizeof(luat_lcd_conf_t)); // 填充0,保证无脏数据
  64. conf->pin_pwr = 255;
  65. if (lua_type(L, 3) == LUA_TUSERDATA){
  66. conf->userdata = (luat_spi_device_t*)lua_touserdata(L, 3);
  67. conf->port = LUAT_LCD_SPI_DEVICE;
  68. }
  69. const char* tp = luaL_checklstring(L, 1, &len);
  70. if (!strcmp("st7735", tp) || !strcmp("st7735v", tp) || !strcmp("st7789", tp) || !strcmp("st7735s", tp)
  71. || !strcmp("gc9a01", tp) || !strcmp("gc9106l", tp)
  72. || !strcmp("gc9306", tp) || !strcmp("ili9341", tp) || !strcmp("ili9488", tp)
  73. || !strcmp("custom", tp)) {
  74. LLOGD("ic support: %s",tp);
  75. if (lua_gettop(L) > 1) {
  76. lua_settop(L, 2); // 丢弃多余的参数
  77. lua_pushstring(L, "port");
  78. int port = lua_gettable(L, 2);
  79. if (conf->port == LUAT_LCD_SPI_DEVICE && port ==LUA_TNUMBER) {
  80. LLOGE("port is not device but find luat_spi_device_t");
  81. goto end;
  82. }else if (conf->port != LUAT_LCD_SPI_DEVICE && LUA_TSTRING == port){
  83. LLOGE("port is device but not find luat_spi_device_t");
  84. goto end;
  85. }else if (LUA_TNUMBER == port) {
  86. conf->port = luaL_checkinteger(L, -1);
  87. }else if (LUA_TSTRING == port){
  88. conf->port = LUAT_LCD_SPI_DEVICE;
  89. }
  90. lua_pop(L, 1);
  91. lua_pushstring(L, "pin_dc");
  92. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  93. conf->pin_dc = luaL_checkinteger(L, -1);
  94. }
  95. lua_pop(L, 1);
  96. lua_pushstring(L, "pin_pwr");
  97. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  98. conf->pin_pwr = luaL_checkinteger(L, -1);
  99. }
  100. lua_pop(L, 1);
  101. lua_pushstring(L, "pin_rst");
  102. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  103. conf->pin_rst = luaL_checkinteger(L, -1);
  104. }
  105. lua_pop(L, 1);
  106. lua_pushstring(L, "direction");
  107. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  108. conf->direction = luaL_checkinteger(L, -1);
  109. }
  110. lua_pop(L, 1);
  111. lua_pushstring(L, "w");
  112. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  113. conf->w = luaL_checkinteger(L, -1);
  114. }
  115. lua_pop(L, 1);
  116. lua_pushstring(L, "h");
  117. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  118. conf->h = luaL_checkinteger(L, -1);
  119. }
  120. lua_pop(L, 1);
  121. lua_pushstring(L, "xoffset");
  122. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  123. conf->xoffset = luaL_checkinteger(L, -1);
  124. }
  125. lua_pop(L, 1);
  126. lua_pushstring(L, "yoffset");
  127. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  128. conf->yoffset = luaL_checkinteger(L, -1);
  129. }
  130. lua_pop(L, 1);
  131. }
  132. if (!strcmp("st7735", tp))
  133. conf->opts = (luat_lcd_opts_t*)&lcd_opts_st7735;
  134. else if (!strcmp("st7735v", tp))
  135. conf->opts = (luat_lcd_opts_t*)&lcd_opts_st7735v;
  136. else if (!strcmp("st7735s", tp))
  137. conf->opts = (luat_lcd_opts_t*)&lcd_opts_st7735s;
  138. else if (!strcmp("st7789", tp))
  139. conf->opts = (luat_lcd_opts_t*)&lcd_opts_st7789;
  140. else if (!strcmp("gc9a01", tp))
  141. conf->opts = (luat_lcd_opts_t*)&lcd_opts_gc9a01;
  142. else if (!strcmp("gc9106l", tp))
  143. conf->opts = (luat_lcd_opts_t*)&lcd_opts_gc9106l;
  144. else if (!strcmp("gc9306", tp))
  145. conf->opts = (luat_lcd_opts_t*)&lcd_opts_gc9306;
  146. else if (!strcmp("ili9341", tp))
  147. conf->opts = (luat_lcd_opts_t*)&lcd_opts_ili9341;
  148. else if (!strcmp("ili9488", tp))
  149. conf->opts = (luat_lcd_opts_t*)&lcd_opts_ili9488;
  150. else if (!strcmp("custom", tp)) {
  151. conf->opts = (luat_lcd_opts_t*)&lcd_opts_custom;
  152. luat_lcd_custom_t *cst = luat_heap_malloc(sizeof(luat_lcd_custom_t));
  153. // 获取initcmd/sleepcmd/wakecmd
  154. lua_pushstring(L, "sleepcmd");
  155. lua_gettable(L, 2);
  156. cst->sleepcmd = luaL_checkinteger(L, -1);
  157. lua_pop(L, 1);
  158. lua_pushstring(L, "wakecmd");
  159. lua_gettable(L, 2);
  160. cst->wakecmd = luaL_checkinteger(L, -1);
  161. lua_pop(L, 1);
  162. lua_pushstring(L, "initcmd");
  163. lua_gettable(L, 2);
  164. cst->init_cmd_count = lua_rawlen(L, -1);
  165. luat_heap_realloc(cst, sizeof(luat_lcd_custom_t) + cst->init_cmd_count * 4);
  166. for (size_t i = 1; i <= cst->init_cmd_count; i++)
  167. {
  168. lua_geti(L, -1, i);
  169. cst->initcmd[i-1] = luaL_checkinteger(L, -1);
  170. lua_pop(L, 1);
  171. }
  172. lua_pop(L, 1);
  173. }
  174. int ret = luat_lcd_init(conf);
  175. lua_pushboolean(L, ret == 0 ? 1 : 0);
  176. if (ret == 0)
  177. default_conf = conf;
  178. u8g2_SetFontMode(&(default_conf->luat_lcd_u8g2), 0);
  179. u8g2_SetFontDirection(&(default_conf->luat_lcd_u8g2), 0);
  180. // lua_pushlightuserdata(L, conf);
  181. return 1;
  182. }
  183. LLOGE("ic not support: %s",tp);
  184. end:
  185. lua_pushboolean(L, 0);
  186. luat_heap_free(conf);
  187. return 1;
  188. }
  189. /*
  190. 关闭lcd显示屏
  191. @api lcd.close()
  192. @usage
  193. -- 关闭lcd
  194. lcd.close()
  195. */
  196. static int l_lcd_close(lua_State* L) {
  197. int ret = luat_lcd_close(default_conf);
  198. lua_pushboolean(L, ret == 0 ? 1 : 0);
  199. return 1;
  200. }
  201. /*
  202. 开启lcd显示屏背光
  203. @api lcd.on()
  204. @usage
  205. -- 开启lcd显示屏背光
  206. lcd.on()
  207. */
  208. static int l_lcd_display_on(lua_State* L) {
  209. int ret = luat_lcd_display_on(default_conf);
  210. lua_pushboolean(L, ret == 0 ? 1 : 0);
  211. return 1;
  212. }
  213. /*
  214. 关闭lcd显示屏背光
  215. @api lcd.off()
  216. @usage
  217. -- 关闭lcd显示屏背光
  218. lcd.off()
  219. */
  220. static int l_lcd_display_off(lua_State* L) {
  221. int ret = luat_lcd_display_off(default_conf);
  222. lua_pushboolean(L, ret == 0 ? 1 : 0);
  223. return 1;
  224. }
  225. /*
  226. lcd睡眠
  227. @api lcd.sleep()
  228. @usage
  229. -- lcd睡眠
  230. lcd.sleep()
  231. */
  232. static int l_lcd_sleep(lua_State* L) {
  233. int ret = luat_lcd_sleep(default_conf);
  234. lua_pushboolean(L, ret == 0 ? 1 : 0);
  235. return 1;
  236. }
  237. /*
  238. lcd唤醒
  239. @api lcd.wakeup()
  240. @usage
  241. -- lcd唤醒
  242. lcd.wakeup()
  243. */
  244. static int l_lcd_wakeup(lua_State* L) {
  245. int ret = luat_lcd_wakeup(default_conf);
  246. lua_pushboolean(L, ret == 0 ? 1 : 0);
  247. return 1;
  248. }
  249. /*
  250. lcd颜色设置
  251. @api lcd.setColor(back,fore)
  252. @int 背景色
  253. @int 前景色
  254. @usage
  255. -- lcd颜色设置
  256. lcd.setColor(0xFFFF,0x0000)
  257. */
  258. static int l_lcd_set_color(lua_State* L) {
  259. uint32_t back,fore;
  260. back = (uint32_t)luaL_checkinteger(L, 1);
  261. fore = (uint32_t)luaL_checkinteger(L, 2);
  262. int ret = luat_lcd_set_color(back, fore);
  263. lua_pushboolean(L, ret == 0 ? 1 : 0);
  264. return 1;
  265. }
  266. /*
  267. lcd颜色填充
  268. @api lcd.draw(x1, y1, x2, y2,color)
  269. @int 左上边缘的X位置.
  270. @int 左上边缘的Y位置.
  271. @int 右上边缘的X位置.
  272. @int 右上边缘的Y位置.
  273. @string 字符串或zbuff对象
  274. @usage
  275. -- lcd颜色填充
  276. local buff = zbuff.create({201,1,16},0x001F)
  277. lcd.draw(20,30,220,30,buff)
  278. */
  279. static int l_lcd_draw(lua_State* L) {
  280. uint16_t x1, y1, x2, y2;
  281. int ret;
  282. // luat_color_t *color = NULL;
  283. luat_zbuff_t *buff;
  284. x1 = luaL_checkinteger(L, 1);
  285. y1 = luaL_checkinteger(L, 2);
  286. x2 = luaL_checkinteger(L, 3);
  287. y2 = luaL_checkinteger(L, 4);
  288. if (lua_isinteger(L, 5)) {
  289. // color = (luat_color_t *)luaL_checkstring(L, 5);
  290. uint32_t color = (uint32_t)luaL_checkinteger(L, 1);
  291. ret = luat_lcd_draw(default_conf, x1, y1, x2, y2, &color);
  292. }
  293. else if (lua_isuserdata(L, 5)) {
  294. buff = luaL_checkudata(L, 5, LUAT_ZBUFF_TYPE);
  295. luat_color_t *color = (luat_color_t *)buff->addr;
  296. ret = luat_lcd_draw(default_conf, x1, y1, x2, y2, color);
  297. }
  298. else if(lua_isstring(L, 5)) {
  299. luat_color_t *color = (luat_color_t *)luaL_checkstring(L, 5);
  300. ret = luat_lcd_draw(default_conf, x1, y1, x2, y2, color);
  301. }
  302. else {
  303. return 0;
  304. }
  305. // int ret = luat_lcd_draw(default_conf, x1, y1, x2, y2, color);
  306. lua_pushboolean(L, ret == 0 ? 1 : 0);
  307. return 1;
  308. }
  309. /*
  310. lcd清屏
  311. @api lcd.clear(color)
  312. @int 屏幕颜色 可选参数,默认背景色
  313. @usage
  314. -- lcd清屏
  315. lcd.clear()
  316. */
  317. static int l_lcd_clear(lua_State* L) {
  318. //size_t len = 0;
  319. uint32_t color = BACK_COLOR;
  320. if (lua_gettop(L) > 0)
  321. color = (uint32_t)luaL_checkinteger(L, 1);
  322. int ret = luat_lcd_clear(default_conf, color);
  323. lua_pushboolean(L, ret == 0 ? 1 : 0);
  324. return 1;
  325. }
  326. /*
  327. lcd颜色填充
  328. @api lcd.fill(x1, y1, x2, y2,color)
  329. @int 左上边缘的X位置.
  330. @int 左上边缘的Y位置.
  331. @int 右上边缘的X位置.
  332. @int 右上边缘的Y位置.
  333. @int 绘画颜色 可选参数,默认背景色
  334. @usage
  335. -- lcd颜色填充
  336. lcd.fill(20,30,220,30,0x0000)
  337. */
  338. static int l_lcd_draw_fill(lua_State* L) {
  339. uint16_t x1, y1, x2, y2;
  340. uint32_t color = BACK_COLOR;
  341. x1 = luaL_checkinteger(L, 1);
  342. y1 = luaL_checkinteger(L, 2);
  343. x2 = luaL_checkinteger(L, 3);
  344. y2 = luaL_checkinteger(L, 4);
  345. if (lua_gettop(L) > 4)
  346. color = (uint32_t)luaL_checkinteger(L, 5);
  347. int ret = luat_lcd_draw_fill(default_conf, x1, y1, x2, y2, color);
  348. lua_pushboolean(L, ret == 0 ? 1 : 0);
  349. return 1;
  350. }
  351. /*
  352. 画一个点.
  353. @api lcd.drawPoint(x0,y0,color)
  354. @int 点的X位置.
  355. @int 点的Y位置.
  356. @int 绘画颜色 可选参数,默认前景色
  357. @usage
  358. lcd.drawPoint(20,30,0x001F)
  359. */
  360. static int l_lcd_draw_point(lua_State* L) {
  361. uint16_t x, y;
  362. uint32_t color = FORE_COLOR;
  363. x = luaL_checkinteger(L, 1);
  364. y = luaL_checkinteger(L, 2);
  365. if (lua_gettop(L) > 2)
  366. color = (uint32_t)luaL_checkinteger(L, 3);
  367. int ret = luat_lcd_draw_point(default_conf, x, y, color);
  368. lua_pushboolean(L, ret == 0 ? 1 : 0);
  369. return 1;
  370. }
  371. /*
  372. 在两点之间画一条线.
  373. @api lcd.drawLine(x0,y0,x1,y1,color)
  374. @int 第一个点的X位置.
  375. @int 第一个点的Y位置.
  376. @int 第二个点的X位置.
  377. @int 第二个点的Y位置.
  378. @int 绘画颜色 可选参数,默认前景色
  379. @usage
  380. lcd.drawLine(20,30,220,30,0x001F)
  381. */
  382. static int l_lcd_draw_line(lua_State* L) {
  383. uint16_t x1, y1, x2, y2;
  384. uint32_t color = FORE_COLOR;
  385. x1 = luaL_checkinteger(L, 1);
  386. y1 = luaL_checkinteger(L, 2);
  387. x2 = luaL_checkinteger(L, 3);
  388. y2 = luaL_checkinteger(L, 4);
  389. if (lua_gettop(L) > 4)
  390. color = (uint32_t)luaL_checkinteger(L, 5);
  391. int ret = luat_lcd_draw_line(default_conf, x1, y1, x2, y2, color);
  392. lua_pushboolean(L, ret == 0 ? 1 : 0);
  393. return 1;
  394. }
  395. /*
  396. 从x / y位置(左上边缘)开始绘制一个框
  397. @api lcd.drawRectangle(x0,y0,x1,y1,color)
  398. @int 左上边缘的X位置.
  399. @int 左上边缘的Y位置.
  400. @int 右下边缘的X位置.
  401. @int 右下边缘的Y位置.
  402. @int 绘画颜色 可选参数,默认前景色
  403. @usage
  404. lcd.drawRectangle(20,40,220,80,0x001F)
  405. */
  406. static int l_lcd_draw_rectangle(lua_State* L) {
  407. uint16_t x1, y1, x2, y2;
  408. uint32_t color = FORE_COLOR;
  409. x1 = luaL_checkinteger(L, 1);
  410. y1 = luaL_checkinteger(L, 2);
  411. x2 = luaL_checkinteger(L, 3);
  412. y2 = luaL_checkinteger(L, 4);
  413. if (lua_gettop(L) > 4)
  414. color = (uint32_t)luaL_checkinteger(L, 5);
  415. int ret = luat_lcd_draw_rectangle(default_conf, x1, y1, x2, y2, color);
  416. lua_pushboolean(L, ret == 0 ? 1 : 0);
  417. return 1;
  418. }
  419. /*
  420. 从x / y位置(圆心)开始绘制一个圆
  421. @api lcd.drawCircle(x0,y0,r,color)
  422. @int 圆心的X位置.
  423. @int 圆心的Y位置.
  424. @int 半径.
  425. @int 绘画颜色 可选参数,默认前景色
  426. @usage
  427. lcd.drawCircle(120,120,20,0x001F)
  428. */
  429. static int l_lcd_draw_circle(lua_State* L) {
  430. uint16_t x0, y0, r;
  431. uint32_t color = FORE_COLOR;
  432. x0 = luaL_checkinteger(L, 1);
  433. y0 = luaL_checkinteger(L, 2);
  434. r = luaL_checkinteger(L, 3);
  435. if (lua_gettop(L) > 3)
  436. color = (uint32_t)luaL_checkinteger(L, 4);
  437. int ret = luat_lcd_draw_circle(default_conf, x0, y0, r, color);
  438. lua_pushboolean(L, ret == 0 ? 1 : 0);
  439. return 1;
  440. }
  441. /**
  442. 缓冲区绘制QRCode
  443. @api lcd.drawDrcode(x, y, str, version)
  444. @int x坐标
  445. @int y坐标
  446. @string 二维码的内容
  447. @int 二维码版本号
  448. @return nil 无返回值
  449. */
  450. static int l_lcd_drawDrcode(lua_State *L)
  451. {
  452. size_t len;
  453. int x = luaL_checkinteger(L, 1);
  454. int y = luaL_checkinteger(L, 2);
  455. const char* str = luaL_checklstring(L, 3, &len);
  456. int version = luaL_checkinteger(L, 4);
  457. // Create the QR code
  458. QRCode qrcode;
  459. uint8_t qrcodeData[qrcode_getBufferSize(version)];
  460. qrcode_initText(&qrcode, qrcodeData, version, ECC_LOW, str);
  461. for(int i = 0; i < qrcode.size; i++)
  462. {
  463. for (int j = 0; j < qrcode.size; j++)
  464. {
  465. qrcode_getModule(&qrcode, j, i) ? luat_lcd_draw_point(default_conf, x+j, y+i, FORE_COLOR) : luat_lcd_draw_point(default_conf, x+j, y+i, BACK_COLOR);
  466. }
  467. }
  468. return 0;
  469. }
  470. static uint8_t utf8_state;
  471. static uint16_t encoding;
  472. static uint16_t utf8_next(uint8_t b)
  473. {
  474. if ( b == 0 ) /* '\n' terminates the string to support the string list procedures */
  475. return 0x0ffff; /* end of string detected, pending UTF8 is discarded */
  476. if ( utf8_state == 0 )
  477. {
  478. if ( b >= 0xfc ) /* 6 byte sequence */
  479. {
  480. utf8_state = 5;
  481. b &= 1;
  482. }
  483. else if ( b >= 0xf8 )
  484. {
  485. utf8_state = 4;
  486. b &= 3;
  487. }
  488. else if ( b >= 0xf0 )
  489. {
  490. utf8_state = 3;
  491. b &= 7;
  492. }
  493. else if ( b >= 0xe0 )
  494. {
  495. utf8_state = 2;
  496. b &= 15;
  497. }
  498. else if ( b >= 0xc0 )
  499. {
  500. utf8_state = 1;
  501. b &= 0x01f;
  502. }
  503. else
  504. {
  505. /* do nothing, just use the value as encoding */
  506. return b;
  507. }
  508. encoding = b;
  509. return 0x0fffe;
  510. }
  511. else
  512. {
  513. utf8_state--;
  514. /* The case b < 0x080 (an illegal UTF8 encoding) is not checked here. */
  515. encoding<<=6;
  516. b &= 0x03f;
  517. encoding |= b;
  518. if ( utf8_state != 0 )
  519. return 0x0fffe; /* nothing to do yet */
  520. }
  521. return encoding;
  522. }
  523. static void u8g2_draw_hv_line(u8g2_t *u8g2, int16_t x, int16_t y, int16_t len, uint8_t dir, uint16_t color){
  524. switch(dir)
  525. {
  526. case 0:
  527. luat_lcd_draw_hline(default_conf,x,y,len,color);
  528. break;
  529. case 1:
  530. luat_lcd_draw_vline(default_conf,x,y,len,color);
  531. break;
  532. case 2:
  533. luat_lcd_draw_hline(default_conf,x-len+1,y,len,color);
  534. break;
  535. case 3:
  536. luat_lcd_draw_vline(default_conf,x,y-len+1,len,color);
  537. break;
  538. }
  539. }
  540. static void u8g2_font_decode_len(u8g2_t *u8g2, uint8_t len, uint8_t is_foreground){
  541. uint8_t cnt; /* total number of remaining pixels, which have to be drawn */
  542. uint8_t rem; /* remaining pixel to the right edge of the glyph */
  543. uint8_t current; /* number of pixels, which need to be drawn for the draw procedure */
  544. /* current is either equal to cnt or equal to rem */
  545. /* local coordinates of the glyph */
  546. uint8_t lx,ly;
  547. /* target position on the screen */
  548. int16_t x, y;
  549. u8g2_font_decode_t *decode = &(u8g2->font_decode);
  550. cnt = len;
  551. /* get the local position */
  552. lx = decode->x;
  553. ly = decode->y;
  554. for(;;){
  555. /* calculate the number of pixel to the right edge of the glyph */
  556. rem = decode->glyph_width;
  557. rem -= lx;
  558. /* calculate how many pixel to draw. This is either to the right edge */
  559. /* or lesser, if not enough pixel are left */
  560. current = rem;
  561. if ( cnt < rem )
  562. current = cnt;
  563. /* now draw the line, but apply the rotation around the glyph target position */
  564. //u8g2_font_decode_draw_pixel(u8g2, lx,ly,current, is_foreground);
  565. /* get target position */
  566. x = decode->target_x;
  567. y = decode->target_y;
  568. /* apply rotation */
  569. x = u8g2_add_vector_x(x, lx, ly, decode->dir);
  570. y = u8g2_add_vector_y(y, lx, ly, decode->dir);
  571. /* draw foreground and background (if required) */
  572. if ( current > 0 ) /* avoid drawing zero length lines, issue #4 */
  573. {
  574. if ( is_foreground )
  575. {
  576. u8g2_draw_hv_line(u8g2, x, y, current, decode->dir, lcd_str_fg_color);
  577. }
  578. else if ( decode->is_transparent == 0 )
  579. {
  580. u8g2_draw_hv_line(u8g2, x, y, current, decode->dir, lcd_str_bg_color);
  581. }
  582. }
  583. /* check, whether the end of the run length code has been reached */
  584. if ( cnt < rem )
  585. break;
  586. cnt -= rem;
  587. lx = 0;
  588. ly++;
  589. }
  590. lx += cnt;
  591. decode->x = lx;
  592. decode->y = ly;
  593. }
  594. static void u8g2_font_setup_decode(u8g2_t *u8g2, const uint8_t *glyph_data)
  595. {
  596. u8g2_font_decode_t *decode = &(u8g2->font_decode);
  597. decode->decode_ptr = glyph_data;
  598. decode->decode_bit_pos = 0;
  599. /* 8 Nov 2015, this is already done in the glyph data search procedure */
  600. /*
  601. decode->decode_ptr += 1;
  602. decode->decode_ptr += 1;
  603. */
  604. decode->glyph_width = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_char_width);
  605. decode->glyph_height = u8g2_font_decode_get_unsigned_bits(decode,u8g2->font_info.bits_per_char_height);
  606. }
  607. static int8_t u8g2_font_decode_glyph(u8g2_t *u8g2, const uint8_t *glyph_data){
  608. uint8_t a, b;
  609. int8_t x, y;
  610. int8_t d;
  611. int8_t h;
  612. u8g2_font_decode_t *decode = &(u8g2->font_decode);
  613. u8g2_font_setup_decode(u8g2, glyph_data);
  614. h = u8g2->font_decode.glyph_height;
  615. x = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_char_x);
  616. y = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_char_y);
  617. d = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_delta_x);
  618. if ( decode->glyph_width > 0 )
  619. {
  620. decode->target_x = u8g2_add_vector_x(decode->target_x, x, -(h+y), decode->dir);
  621. decode->target_y = u8g2_add_vector_y(decode->target_y, x, -(h+y), decode->dir);
  622. //u8g2_add_vector(&(decode->target_x), &(decode->target_y), x, -(h+y), decode->dir);
  623. /* reset local x/y position */
  624. decode->x = 0;
  625. decode->y = 0;
  626. /* decode glyph */
  627. for(;;){
  628. a = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_0);
  629. b = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_1);
  630. do{
  631. u8g2_font_decode_len(u8g2, a, 0);
  632. u8g2_font_decode_len(u8g2, b, 1);
  633. } while( u8g2_font_decode_get_unsigned_bits(decode, 1) != 0 );
  634. if ( decode->y >= h )
  635. break;
  636. }
  637. }
  638. return d;
  639. }
  640. const uint8_t *u8g2_font_get_glyph_data(u8g2_t *u8g2, uint16_t encoding);
  641. static int16_t u8g2_font_draw_glyph(u8g2_t *u8g2, int16_t x, int16_t y, uint16_t encoding){
  642. int16_t dx = 0;
  643. u8g2->font_decode.target_x = x;
  644. u8g2->font_decode.target_y = y;
  645. const uint8_t *glyph_data = u8g2_font_get_glyph_data(u8g2, encoding);
  646. if ( glyph_data != NULL ){
  647. dx = u8g2_font_decode_glyph(u8g2, glyph_data);
  648. }
  649. return dx;
  650. }
  651. /*
  652. 设置字体
  653. @api lcd.setFont(font)
  654. @string font
  655. @usage
  656. -- 设置为中文字体,对之后的drawStr有效,使用中文字体需在luat_conf_bsp.h.h开启#define USE_U8G2_OPPOSANSM12_CHINESE
  657. lcd.setFont(lcd.font_opposansm12)
  658. lcd.drawStr(40,10,"drawStr")
  659. sys.wait(2000)
  660. lcd.setFont(lcd.font_opposansm12_chinese)
  661. lcd.drawStr(40,40,"drawStr测试")
  662. */
  663. static int l_lcd_set_font(lua_State *L) {
  664. int font = luaL_checkinteger(L, 1);
  665. switch (font)
  666. {
  667. case font_opposansm8:
  668. LLOGI("font_opposansm8");
  669. u8g2_SetFont(&(default_conf->luat_lcd_u8g2), u8g2_font_opposansm8);
  670. lua_pushboolean(L, 1);
  671. break;
  672. case font_opposansm10:
  673. LLOGI("font_opposansm10");
  674. u8g2_SetFont(&(default_conf->luat_lcd_u8g2), u8g2_font_opposansm10);
  675. lua_pushboolean(L, 1);
  676. break;
  677. case font_opposansm12:
  678. LLOGI("font_opposansm12");
  679. u8g2_SetFont(&(default_conf->luat_lcd_u8g2), u8g2_font_opposansm12);
  680. lua_pushboolean(L, 1);
  681. break;
  682. case font_opposansm16:
  683. LLOGI("font_opposansm16");
  684. u8g2_SetFont(&(default_conf->luat_lcd_u8g2), u8g2_font_opposansm16);
  685. lua_pushboolean(L, 1);
  686. break;
  687. case font_opposansm18:
  688. LLOGI("font_opposansm18");
  689. u8g2_SetFont(&(default_conf->luat_lcd_u8g2), u8g2_font_opposansm18);
  690. lua_pushboolean(L, 1);
  691. break;
  692. case font_opposansm20:
  693. LLOGI("font_opposansm20");
  694. u8g2_SetFont(&(default_conf->luat_lcd_u8g2), u8g2_font_opposansm20);
  695. lua_pushboolean(L, 1);
  696. break;
  697. case font_opposansm22:
  698. LLOGI("font_opposansm22");
  699. u8g2_SetFont(&(default_conf->luat_lcd_u8g2), u8g2_font_opposansm22);
  700. lua_pushboolean(L, 1);
  701. break;
  702. case font_opposansm24:
  703. LLOGI("font_opposansm24");
  704. u8g2_SetFont(&(default_conf->luat_lcd_u8g2), u8g2_font_opposansm24);
  705. lua_pushboolean(L, 1);
  706. break;
  707. case font_opposansm32:
  708. LLOGI("font_opposansm32");
  709. u8g2_SetFont(&(default_conf->luat_lcd_u8g2), u8g2_font_opposansm32);
  710. lua_pushboolean(L, 1);
  711. break;
  712. #if defined USE_U8G2_OPPOSANSM12_CHINESE
  713. case font_opposansm12_chinese:
  714. LLOGI("font_opposansm12_chinese");
  715. u8g2_SetFont(&(default_conf->luat_lcd_u8g2), u8g2_font_opposansm12_chinese);
  716. lua_pushboolean(L, 1);
  717. break;
  718. #endif
  719. #if defined USE_U8G2_OPPOSANSM16_CHINESE
  720. case font_opposansm16_chinese:
  721. LLOGI("font_opposansm16_chinese");
  722. u8g2_SetFont(&(default_conf->luat_lcd_u8g2), u8g2_font_opposansm16_chinese);
  723. lua_pushboolean(L, 1);
  724. break;
  725. #endif
  726. #if defined USE_U8G2_OPPOSANSM24_CHINESE
  727. case font_opposansm24_chinese:
  728. LLOGI("font_opposansm24_chinese");
  729. u8g2_SetFont(&(default_conf->luat_lcd_u8g2), u8g2_font_opposansm24_chinese);
  730. lua_pushboolean(L, 1);
  731. break;
  732. #endif
  733. #if defined USE_U8G2_OPPOSANSM32_CHINESE
  734. case font_opposansm32_chinese:
  735. LLOGI("font_opposansm32_chinese");
  736. u8g2_SetFont(&(default_conf->luat_lcd_u8g2), u8g2_font_opposansm32_chinese);
  737. lua_pushboolean(L, 1);
  738. break;
  739. #endif
  740. default:
  741. lua_pushboolean(L, 0);
  742. LLOGI("no font");
  743. break;
  744. }
  745. return 1;
  746. }
  747. /*
  748. 显示字符串
  749. @api lcd.drawStr(x,y,str,fg_color,bg_color)
  750. @int x 横坐标
  751. @int y 竖坐标
  752. @string str 文件内容
  753. @int fg_color str颜色
  754. @int bg_color str背景颜色
  755. @usage
  756. -- 显示之前先设置为中文字体,对之后的drawStr有效,使用中文字体需在luat_conf_bsp.h.h开启#define USE_U8G2_WQY16_T_GB2312
  757. lcd.setFont(lcd.font_opposansm12)
  758. lcd.drawStr(40,10,"drawStr")
  759. sys.wait(2000)
  760. lcd.setFont(lcd.font_opposansm16_chinese)
  761. lcd.drawStr(40,40,"drawStr测试")
  762. */
  763. static int l_lcd_draw_str(lua_State* L) {
  764. int x, y;
  765. int sz;
  766. const uint8_t* data;
  767. uint32_t color = FORE_COLOR;
  768. x = luaL_checkinteger(L, 1);
  769. y = luaL_checkinteger(L, 2);
  770. data = (const uint8_t*)luaL_checklstring(L, 3, &sz);
  771. lcd_str_fg_color = (uint32_t)luaL_optinteger(L, 4,FORE_COLOR);
  772. lcd_str_bg_color = (uint32_t)luaL_optinteger(L, 5,BACK_COLOR);
  773. if (sz == 0)
  774. return 0;
  775. uint16_t e;
  776. int16_t delta, sum;
  777. utf8_state = 0;
  778. sum = 0;
  779. for(;;){
  780. e = utf8_next((uint8_t)*data);
  781. if ( e == 0x0ffff )
  782. break;
  783. data++;
  784. if ( e != 0x0fffe ){
  785. delta = u8g2_font_draw_glyph(&(default_conf->luat_lcd_u8g2), x, y, e);
  786. switch(default_conf->luat_lcd_u8g2.font_decode.dir){
  787. case 0:
  788. x += delta;
  789. break;
  790. case 1:
  791. y += delta;
  792. break;
  793. case 2:
  794. x -= delta;
  795. break;
  796. case 3:
  797. y -= delta;
  798. break;
  799. }
  800. sum += delta;
  801. }
  802. }
  803. return 0;
  804. }
  805. #ifdef LUAT_USE_GTFONT
  806. #include "GT5SLCD2E_1A.h"
  807. 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);
  808. 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);
  809. /*
  810. 使用gtfont显示gb2312字符串
  811. @api lcd.drawGtfontGb2312(str,size,x,y)
  812. @string str 显示字符串
  813. @int size 字体大小 (支持16-192号大小字体)
  814. @int x 横坐标
  815. @int y 竖坐标
  816. @usage
  817. lcd.drawGtfontGb2312("啊啊啊",32,0,0)
  818. */
  819. static int l_lcd_draw_gtfont_gb2312(lua_State *L) {
  820. unsigned char buf[128];
  821. int len;
  822. int i = 0;
  823. uint8_t strhigh,strlow ;
  824. uint16_t str;
  825. const char *fontCode = luaL_checklstring(L, 1,&len);
  826. unsigned char size = luaL_checkinteger(L, 2);
  827. int x = luaL_checkinteger(L, 3);
  828. int y = luaL_checkinteger(L, 4);
  829. while ( i < len){
  830. strhigh = *fontCode;
  831. fontCode++;
  832. strlow = *fontCode;
  833. str = (strhigh<<8)|strlow;
  834. fontCode++;
  835. get_font(buf, 1, str, size, size, size);
  836. gtfont_draw_w(buf , x ,y , size , size,luat_lcd_draw_point,default_conf,0);
  837. x+=size;
  838. i+=2;
  839. }
  840. return 0;
  841. }
  842. /*
  843. 使用gtfont灰度显示gb2312字符串
  844. @api lcd.drawGtfontGb2312Gray(str,size,gray,x,y)
  845. @string str 显示字符串
  846. @int size 字体大小 (支持16-192号大小字体)
  847. @int gray 灰度[1阶/2阶/3阶/4阶]
  848. @int x 横坐标
  849. @int y 竖坐标
  850. @usage
  851. lcd.drawGtfontGb2312Gray("啊啊啊",32,4,0,40)
  852. */
  853. static int l_lcd_draw_gtfont_gb2312_gray(lua_State* L) {
  854. unsigned char buf[2048];
  855. int len;
  856. int i = 0;
  857. uint8_t strhigh,strlow ;
  858. uint16_t str;
  859. const char *fontCode = luaL_checklstring(L, 1,&len);
  860. unsigned char size = luaL_checkinteger(L, 2);
  861. unsigned char font_g = luaL_checkinteger(L, 3);
  862. int x = luaL_checkinteger(L, 4);
  863. int y = luaL_checkinteger(L, 5);
  864. while ( i < len){
  865. strhigh = *fontCode;
  866. fontCode++;
  867. strlow = *fontCode;
  868. str = (strhigh<<8)|strlow;
  869. fontCode++;
  870. get_font(buf, 1, str, size*font_g, size*font_g, size*font_g);
  871. Gray_Process(buf,size,size,font_g);
  872. gtfont_draw_gray_hz(buf, x, y, size , size, font_g, 1,luat_lcd_draw_point,default_conf,0);
  873. x+=size;
  874. i+=2;
  875. }
  876. return 0;
  877. }
  878. #ifdef LUAT_USE_GTFONT_UTF8
  879. extern unsigned short unicodetogb2312 ( unsigned short chr);
  880. /*
  881. 使用gtfont显示UTF8字符串
  882. @api lcd.drawGtfontUtf8(str,size,x,y)
  883. @string str 显示字符串
  884. @int size 字体大小 (支持16-192号大小字体)
  885. @int x 横坐标
  886. @int y 竖坐标
  887. @usage
  888. lcd.drawGtfontUtf8("啊啊啊",32,0,0)
  889. */
  890. static int l_lcd_draw_gtfont_utf8(lua_State *L) {
  891. unsigned char buf[128];
  892. int len;
  893. int i = 0;
  894. uint8_t strhigh,strlow ;
  895. uint16_t e,str;
  896. const char *fontCode = luaL_checklstring(L, 1,&len);
  897. unsigned char size = luaL_checkinteger(L, 2);
  898. int x = luaL_checkinteger(L, 3);
  899. int y = luaL_checkinteger(L, 4);
  900. for(;;){
  901. e = utf8_next((uint8_t)*fontCode);
  902. if ( e == 0x0ffff )
  903. break;
  904. fontCode++;
  905. if ( e != 0x0fffe ){
  906. uint16_t str = unicodetogb2312(e);
  907. get_font(buf, 1, str, size, size, size);
  908. gtfont_draw_w(buf , x ,y , size , size,luat_lcd_draw_point,default_conf,0);
  909. x+=size;
  910. }
  911. }
  912. return 0;
  913. }
  914. /*
  915. 使用gtfont灰度显示UTF8字符串
  916. @api lcd.drawGtfontUtf8Gray(str,size,gray,x,y)
  917. @string str 显示字符串
  918. @int size 字体大小 (支持16-192号大小字体)
  919. @int gray 灰度[1阶/2阶/3阶/4阶]
  920. @int x 横坐标
  921. @int y 竖坐标
  922. @usage
  923. lcd.drawGtfontUtf8Gray("啊啊啊",32,4,0,40)
  924. */
  925. static int l_lcd_draw_gtfont_utf8_gray(lua_State* L) {
  926. unsigned char buf[2048];
  927. int len;
  928. int i = 0;
  929. uint8_t strhigh,strlow ;
  930. uint16_t e,str;
  931. const char *fontCode = luaL_checklstring(L, 1,&len);
  932. unsigned char size = luaL_checkinteger(L, 2);
  933. unsigned char font_g = luaL_checkinteger(L, 3);
  934. int x = luaL_checkinteger(L, 4);
  935. int y = luaL_checkinteger(L, 5);
  936. for(;;){
  937. e = utf8_next((uint8_t)*fontCode);
  938. if ( e == 0x0ffff )
  939. break;
  940. fontCode++;
  941. if ( e != 0x0fffe ){
  942. uint16_t str = unicodetogb2312(e);
  943. get_font(buf, 1, str, size*font_g, size*font_g, size*font_g);
  944. Gray_Process(buf,size,size,font_g);
  945. gtfont_draw_gray_hz(buf, x, y, size , size, font_g, 1,luat_lcd_draw_point,default_conf,0);
  946. x+=size;
  947. }
  948. }
  949. return 0;
  950. }
  951. #endif // LUAT_USE_GTFONT_UTF8
  952. #endif // LUAT_USE_GTFONT
  953. static int l_lcd_set_default(lua_State *L) {
  954. if (lua_gettop(L) == 1) {
  955. default_conf = lua_touserdata(L, 1);
  956. lua_pushboolean(L, 1);
  957. return 1;
  958. }
  959. return 1;
  960. }
  961. static int l_lcd_get_default(lua_State *L) {
  962. if (default_conf == NULL)
  963. return 0;
  964. lua_pushlightuserdata(L, default_conf);
  965. return 1;
  966. }
  967. /*
  968. 获取屏幕尺寸
  969. @api lcd.getSize()
  970. @return int 宽, 如果未初始化会返回0
  971. @return int 高, 如果未初始化会返回0
  972. @usage
  973. log.info("lcd", "size", lcd.getSize())
  974. */
  975. static int l_lcd_get_size(lua_State *L) {
  976. if (lua_gettop(L) == 1) {
  977. luat_lcd_conf_t * conf = lua_touserdata(L, 1);
  978. if (conf) {
  979. lua_pushinteger(L, conf->w);
  980. lua_pushinteger(L, conf->h);
  981. }
  982. }
  983. if (default_conf == NULL) {
  984. lua_pushinteger(L, 0);
  985. lua_pushinteger(L, 0);
  986. }
  987. else {
  988. lua_pushinteger(L, default_conf->w);
  989. lua_pushinteger(L, default_conf->h);
  990. }
  991. return 2;
  992. }
  993. #include "rotable.h"
  994. static const rotable_Reg reg_lcd[] =
  995. {
  996. { "init", l_lcd_init, 0},
  997. { "close", l_lcd_close, 0},
  998. { "on", l_lcd_display_on, 0},
  999. { "off", l_lcd_display_off, 0},
  1000. { "sleep", l_lcd_sleep, 0},
  1001. { "wakeup", l_lcd_wakeup, 0},
  1002. { "setColor", l_lcd_set_color, 0},
  1003. { "draw", l_lcd_draw, 0},
  1004. { "clear", l_lcd_clear, 0},
  1005. { "fill", l_lcd_draw_fill, 0},
  1006. { "drawPoint", l_lcd_draw_point, 0},
  1007. { "drawLine", l_lcd_draw_line, 0},
  1008. { "drawRectangle", l_lcd_draw_rectangle, 0},
  1009. { "drawCircle", l_lcd_draw_circle, 0},
  1010. { "drawDrcode", l_lcd_drawDrcode, 0},
  1011. { "drawStr", l_lcd_draw_str, 0},
  1012. { "setFont", l_lcd_set_font, 0},
  1013. { "setDefault", l_lcd_set_default, 0},
  1014. { "getDefault", l_lcd_get_default, 0},
  1015. { "getSize", l_lcd_get_size, 0},
  1016. #ifdef LUAT_USE_GTFONT
  1017. { "drawGtfontGb2312", l_lcd_draw_gtfont_gb2312, 0},
  1018. { "drawGtfontGb2312Gray", l_lcd_draw_gtfont_gb2312_gray, 0},
  1019. #ifdef LUAT_USE_GTFONT_UTF8
  1020. { "drawGtfontUtf8", l_lcd_draw_gtfont_utf8, 0},
  1021. { "drawGtfontUtf8Gray", l_lcd_draw_gtfont_utf8_gray, 0},
  1022. #endif // LUAT_USE_GTFONT_UTF8
  1023. #endif // LUAT_USE_GTFONT
  1024. { "font_opposansm8", NULL, font_opposansm8},
  1025. { "font_opposansm10", NULL, font_opposansm10},
  1026. { "font_opposansm12", NULL, font_opposansm12},
  1027. { "font_opposansm16", NULL, font_opposansm16},
  1028. { "font_opposansm18", NULL, font_opposansm18},
  1029. { "font_opposansm20", NULL, font_opposansm20},
  1030. { "font_opposansm22", NULL, font_opposansm22},
  1031. { "font_opposansm24", NULL, font_opposansm24},
  1032. { "font_opposansm32", NULL, font_opposansm32},
  1033. { "font_opposansm12_chinese", NULL, font_opposansm12_chinese},
  1034. { "font_opposansm16_chinese", NULL, font_opposansm16_chinese},
  1035. { "font_opposansm24_chinese", NULL, font_opposansm24_chinese},
  1036. { "font_opposansm32_chinese", NULL, font_opposansm32_chinese},
  1037. { NULL, NULL, 0}
  1038. };
  1039. LUAMOD_API int luaopen_lcd( lua_State *L ) {
  1040. luat_newlib(L, reg_lcd);
  1041. return 1;
  1042. }