luat_ufont.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #include "luat_base.h"
  2. #include "luat_ufont.h"
  3. #define LUAT_LOG_TAG "fonts"
  4. #include "luat_log.h"
  5. extern const uint16_t luat_font_map_gb2312_data[];
  6. static int binsearch(const uint16_t *sortedSeq, int seqLength, uint16_t keyData) {
  7. int low = 0, mid, high = seqLength - 1;
  8. while (low <= high) {
  9. mid = (low + high)>>1;//右移1位等于是/2,奇数,无论奇偶,有个值就行
  10. if (keyData < sortedSeq[mid]) {
  11. high = mid - 1;//是mid-1,因为mid已经比较过了
  12. }
  13. else if (keyData > sortedSeq[mid]) {
  14. low = mid + 1;
  15. }
  16. else {
  17. return mid;
  18. }
  19. }
  20. return -1;
  21. }
  22. int luat_font_get_bitmap(luat_font_header_t *font, luat_font_char_desc_t *dsc_out, uint32_t letter) {
  23. if (font == NULL) {
  24. LLOGW("font is NULL");
  25. return -1;
  26. }
  27. if (dsc_out == NULL) {
  28. LLOGW("dsc_out is NULL");
  29. return -2;
  30. }
  31. // 暂时只支持内存访问模式, 就先拦截掉其他的吧
  32. //LLOGD("font search letter %04X", letter);
  33. //LLOGD("font access_mode %02X", font->access_mode);
  34. //LLOGD("font font_data_count %02X", font->font_data_count);
  35. if (font->access_mode != 0x01) {
  36. LLOGW("only ram access mode is supported, for now");
  37. return -3;
  38. }
  39. int data_count = font->font_data_count;
  40. luat_font_data_t* font_data = ((luat_font_desc_t*)font)->datas;
  41. // 准备2个指针数组, 把map和bitmap的位置先指出来
  42. // uint8_t *map_ptr[4] = {0};
  43. // uint8_t *bitmap_ptr = NULL;
  44. // size_t map_data_count = 0;
  45. // for (size_t i = 0; i < data_count; i++)
  46. // {
  47. // if (font_data->map_type == 0x0001) {
  48. // // 仅map_type == 1 时自带映射数据
  49. // map_data_count += font_data->unicode_size * font_data->count;
  50. // }
  51. // }
  52. // bitmap_ptr = ((uint8_t*)font + sizeof(luat_font_header_t) + sizeof(luat_font_data_t) * data_count + map_data_count);
  53. // 根据unicode的范围, 看看letter在哪个
  54. int map_offset = 0;
  55. for (size_t i = 0; i < data_count; i++)
  56. {
  57. // 暂时只支持2字节的unicode map
  58. //LLOGD("font_data->unicode_min %04X", font_data->unicode_min);
  59. //LLOGD("font_data->unicode_max %04X", font_data->unicode_max);
  60. //LLOGD("font_data->map_type %04X", font_data->map_type);
  61. if (font_data->unicode_min <= letter && font_data->unicode_max >= letter) {
  62. // 范围以内, 开始找索引值
  63. if (font_data->map_type == 0x01) {
  64. LLOGD("map_type 0x01 not support yet");
  65. return -12;
  66. }
  67. // 英文字符
  68. else if (font_data->map_type == 0x02) {
  69. // letter必然在 32 ~ 127 之间, 直接索引到点阵数据就行
  70. //dsc_out->data = bitmap_ptr + (font_data->bitmap_size * (letter - 32));
  71. dsc_out->len = font_data->bitmap_size;
  72. dsc_out->char_w = font_data->char_w_bit;
  73. dsc_out->data = font_data->bitmap_data + (font_data->bitmap_size * (letter - 32));
  74. return 0;
  75. }
  76. else if (font_data->map_type == 0x03) {
  77. map_offset = binsearch(luat_font_map_gb2312_data, font_data->count, (uint16_t)letter);
  78. if (map_offset < 0) {
  79. LLOGD("font map-data NOT match %04X", letter);
  80. return -11;
  81. }
  82. // else {
  83. // LLOGD("font gb2312 %04X %04X", letter, map_offset);
  84. // }
  85. dsc_out->len = font_data->bitmap_size;
  86. dsc_out->char_w = font_data->char_w_bit;
  87. dsc_out->data = font_data->bitmap_data + (map_offset * ((font->line_height * font->line_height + 7) / 8));
  88. return 0;
  89. }
  90. else {
  91. LLOGD("map_type 0x%02X not support yet", font_data->map_type);
  92. return -33;
  93. }
  94. }
  95. // bitmap_ptr += font_data->count * font_data->bitmap_size;
  96. font_data ++;
  97. }
  98. //LLOGW("not such unicode in font %p %04X", font, letter);
  99. // 找不到
  100. return -32;
  101. }
  102. uint16_t luat_utf8_next(uint8_t b, uint8_t *utf8_state, uint16_t *encoding)
  103. {
  104. if ( b == 0 ) /* '\n' terminates the string to support the string list procedures */
  105. return 0x0ffff; /* end of string detected, pending UTF8 is discarded */
  106. if ( *utf8_state == 0 )
  107. {
  108. if ( b >= 0xfc ) /* 6 byte sequence */
  109. {
  110. *utf8_state = 5;
  111. b &= 1;
  112. }
  113. else if ( b >= 0xf8 )
  114. {
  115. *utf8_state = 4;
  116. b &= 3;
  117. }
  118. else if ( b >= 0xf0 )
  119. {
  120. *utf8_state = 3;
  121. b &= 7;
  122. }
  123. else if ( b >= 0xe0 )
  124. {
  125. *utf8_state = 2;
  126. b &= 15;
  127. }
  128. else if ( b >= 0xc0 )
  129. {
  130. *utf8_state = 1;
  131. b &= 0x01f;
  132. }
  133. else
  134. {
  135. /* do nothing, just use the value as encoding */
  136. return b;
  137. }
  138. *encoding = b;
  139. return 0x0fffe;
  140. }
  141. else
  142. {
  143. *utf8_state = *utf8_state - 1;
  144. /* The case b < 0x080 (an illegal UTF8 encoding) is not checked here. */
  145. *encoding= (*encoding) << 6;
  146. b &= 0x03f;
  147. *encoding = (*encoding) | b;
  148. if ( *utf8_state != 0 )
  149. return 0x0fffe; /* nothing to do yet */
  150. }
  151. return *encoding;
  152. }