lv_font_gtfont.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. #include "luat_lvgl_fonts.h"
  2. #ifdef LUAT_USE_GTFONT
  3. #include "GT5SLCD2E_1A.h"
  4. extern unsigned short unicodetogb2312(unsigned short);
  5. typedef struct
  6. {
  7. int life;
  8. uint16_t code;
  9. uint16_t dot;
  10. char data[1];
  11. } gt_font_char_t;
  12. typedef struct
  13. {
  14. uint16_t i;
  15. gt_font_char_t **chars;
  16. } gt_font_cache_t;
  17. typedef struct
  18. {
  19. uint8_t sty_zh;
  20. uint8_t sty_en;
  21. uint16_t size;
  22. uint16_t bpp;
  23. uint16_t thickness;
  24. gt_font_cache_t *cache;
  25. uint16_t adv_w[94];
  26. uint16_t code;
  27. uint32_t dot;
  28. char buf[1];
  29. } gt_font_param_t;
  30. gt_font_char_t **gt_font_cache_open(gt_font_param_t *param, uint16_t code) {
  31. if (param->cache == NULL)
  32. return NULL;
  33. gt_font_char_t *cached_char = NULL;
  34. gt_font_cache_t *cache = param->cache;
  35. gt_font_char_t **chars = cache->chars;
  36. int i = 0;
  37. for (i = 0; i < cache->i && chars[i] != NULL; ++i)
  38. {
  39. if(chars[i]->life > (INT32_MIN + 1)) {
  40. chars[i]->life -= 1;
  41. }
  42. }
  43. for(i = 0; i < cache->i && chars[i] != NULL; i++) {
  44. if(chars[i]->code == code) {
  45. cached_char = chars[i];
  46. cached_char->life += 1;
  47. if(cached_char->life > 1000) cached_char->life = 1000;
  48. break;
  49. }
  50. }
  51. if (cached_char || i < cache->i) return &chars[i];
  52. i = 0;
  53. for(int j = 1; j < cache->i; j++) {
  54. if(cache->chars[j]->life < chars[i]->life) {
  55. i = j;
  56. }
  57. }
  58. chars[i]->life = 0;
  59. chars[i]->code = 0;
  60. return &chars[i];
  61. }
  62. static void gt_font_get(gt_font_param_t *param, uint16_t code) {
  63. if (param->code == code)
  64. return;
  65. gt_font_char_t *vc = NULL;
  66. gt_font_char_t **cached_char = gt_font_cache_open(param, code);
  67. if (cached_char != NULL && (vc = *cached_char) != NULL && vc->code == code) {
  68. param->code = code;
  69. param->dot = vc->dot;
  70. int size = ((param->dot + 7) / 8 * 8) * param->size * param->bpp / 8;
  71. memcpy(param->buf, vc->data, size);
  72. return;
  73. }
  74. uint8_t sty = param->sty_zh;
  75. if (code >= 0x20 && code <= 0x7e)
  76. sty = param->sty_en;
  77. memset(param->buf, 0, param->size * param->bpp * param->size * param->bpp);
  78. uint32_t dot = get_font(param->buf, sty, code, param->size * param->bpp, param->size * param->bpp, param->thickness);
  79. param->code = code;
  80. param->dot = dot / param->bpp;
  81. Gray_Process(param->buf, param->dot, param->size, param->bpp);
  82. if (cached_char != NULL) {
  83. int size = ((param->dot + 7) / 8 * 8) * param->size * param->bpp / 8;
  84. vc = lv_mem_realloc(vc, sizeof(gt_font_char_t) + size);
  85. vc->dot = param->dot;
  86. vc->code = code;
  87. vc->life = 0;
  88. memcpy(vc->data, param->buf, size);
  89. *cached_char = vc;
  90. }
  91. }
  92. int get_font_adv_w(uint8_t *buf, int width, int height, int bpp) {
  93. uint8_t *p = buf;
  94. uint16_t w = width, h = height;
  95. uint32_t i = 0, j = 0, x = 0, y = 0;
  96. uint8_t c, c_bits;
  97. uint32_t t = (w + 7) / 8 * bpp;
  98. uint32_t adv_w = 0;
  99. uint32_t cur_w = 0;
  100. for (i = 0; i < (t * h); i++) {
  101. c = *p++;
  102. for (j = 0; j < (8 / bpp); j++) {
  103. c_bits = (c >> (((8 / bpp) - 1 - j) * bpp)) & (0xff >> (8 - bpp));
  104. if (x < w && c_bits != 0) {
  105. cur_w = x;
  106. }
  107. x++;
  108. if(x >= ((w + 7) / 8 * 8)) {
  109. if (cur_w > adv_w)
  110. adv_w = cur_w;
  111. x = 0;
  112. y++;
  113. }
  114. }
  115. }
  116. return adv_w + 1;
  117. }
  118. static inline uint16_t gt_font_get_adv_w(gt_font_param_t *param, uint16_t code) {
  119. uint16_t adv_w = param->size;
  120. if (code >= 0x21 && code <= 0x7e) {
  121. int i = code - 0x21;
  122. if (param->adv_w[i] == 0xFFFF) {
  123. gt_font_get(param, code);
  124. param->adv_w[i] = get_font_adv_w(param->buf, param->dot, param->size, param->bpp);
  125. }
  126. adv_w = param->adv_w[i];
  127. } else if (code == 0x20) {
  128. adv_w = param->size / 2;
  129. }
  130. return adv_w;
  131. }
  132. bool gt_font_get_glyph_dsc(const struct _lv_font_struct *font, lv_font_glyph_dsc_t *dsc_out, uint32_t letter, uint32_t letter_next) {
  133. gt_font_param_t *param = font->dsc;
  134. uint16_t code = unicodetogb2312(letter);
  135. dsc_out->adv_w = gt_font_get_adv_w(param, code);
  136. dsc_out->box_w = ((param->code == code ? param->dot : param->size) + 7) / 8 * 8;
  137. dsc_out->box_h = param->size;
  138. dsc_out->ofs_x = 0;
  139. dsc_out->ofs_y = 0;
  140. dsc_out->bpp = param->bpp;
  141. return true;
  142. }
  143. uint8_t *gt_font_get_glyph_bitmap(const struct _lv_font_struct *font, uint32_t letter) {
  144. gt_font_param_t *param = font->dsc;
  145. uint16_t code = unicodetogb2312(letter);
  146. gt_font_get(param, code);
  147. return param->buf;
  148. }
  149. bool lv_font_is_gt(lv_font_t *font) {
  150. if (font != NULL && font->get_glyph_dsc == gt_font_get_glyph_dsc)
  151. return true;
  152. return false;
  153. }
  154. lv_font_t *lv_font_new_gt(uint8_t sty_zh, uint8_t sty_en, uint8_t size, uint8_t bpp, uint16_t thickness, uint8_t cache_size) {
  155. lv_font_t *font = NULL;
  156. do {
  157. font = lv_mem_alloc(sizeof(lv_font_t));
  158. if (!font) break;
  159. memset(font, 0, sizeof(lv_font_t));
  160. font->get_glyph_dsc = gt_font_get_glyph_dsc;
  161. font->get_glyph_bitmap = gt_font_get_glyph_bitmap;
  162. font->line_height = size;
  163. int malloc_size = size * bpp * size * bpp;
  164. gt_font_param_t *param = lv_mem_alloc(sizeof(gt_font_param_t) + malloc_size);
  165. if (!param) break;
  166. memset(param, 0, sizeof(*param));
  167. font->dsc = param;
  168. memset(param->adv_w, 0xFF, sizeof(param->adv_w));
  169. param->sty_zh = sty_zh;
  170. param->sty_en = sty_en;
  171. param->size = size;
  172. param->bpp = bpp;
  173. param->thickness = thickness;
  174. if (cache_size != 0) {
  175. gt_font_cache_t *cache = lv_mem_alloc(sizeof(gt_font_cache_t));
  176. if (!cache) break;
  177. memset(cache, 0, sizeof(*cache));
  178. param->cache = cache;
  179. cache->i = cache_size;
  180. cache->chars = lv_mem_alloc(cache_size * sizeof(gt_font_char_t *));
  181. if (!cache->chars) break;
  182. memset(cache->chars, 0, cache_size * sizeof(gt_font_char_t *));
  183. }
  184. return font;
  185. } while (0);
  186. lv_font_del_gt(font);
  187. return NULL;
  188. }
  189. void lv_font_del_gt(lv_font_t *font) {
  190. if (!font) return;
  191. if (!font->dsc) {
  192. lv_mem_free(font);
  193. return;
  194. }
  195. gt_font_param_t *param = font->dsc;
  196. if (param->cache) {
  197. gt_font_char_t **chars = param->cache->chars;
  198. for (int i = 0; i < param->cache->i; ++i) {
  199. if (chars[i]) lv_mem_free(chars[i]);
  200. }
  201. if (param->cache->chars) lv_mem_free(param->cache->chars);
  202. lv_mem_free(param->cache);
  203. }
  204. lv_mem_free(param);
  205. lv_mem_free(font);
  206. }
  207. #else
  208. bool lv_font_is_gt(lv_font_t *font) {
  209. return false;
  210. }
  211. lv_font_t *lv_font_new_gt(uint8_t sty_zh, uint8_t sty_en, uint8_t size, uint8_t bpp, uint16_t thickness, uint8_t cache_size) {
  212. return NULL;
  213. }
  214. void lv_font_del_gt(lv_font_t *font) {
  215. }
  216. #endif