font.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * File : font.c
  3. * This file is part of RT-Thread GUI Engine
  4. * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2009-10-16 Bernard first version
  23. * 2013-08-31 Bernard remove the default font setting.
  24. * (which set by theme)
  25. */
  26. #include <rtgui/font.h>
  27. #include <rtgui/dc.h>
  28. static rtgui_list_t _rtgui_font_list;
  29. static struct rtgui_font *rtgui_default_font;
  30. extern struct rtgui_font rtgui_font_asc16;
  31. extern struct rtgui_font rtgui_font_arial16;
  32. extern struct rtgui_font rtgui_font_asc12;
  33. extern struct rtgui_font rtgui_font_arial12;
  34. #ifdef RTGUI_USING_FONTHZ
  35. extern struct rtgui_font rtgui_font_hz16;
  36. extern struct rtgui_font rtgui_font_hz12;
  37. #endif
  38. void rtgui_font_system_init()
  39. {
  40. rtgui_list_init(&(_rtgui_font_list));
  41. /* set default font to NULL */
  42. rtgui_default_font = RT_NULL;
  43. #ifdef RTGUI_USING_FONT16
  44. rtgui_font_system_add_font(&rtgui_font_asc16);
  45. #ifdef RTGUI_USING_FONTHZ
  46. rtgui_font_system_add_font(&rtgui_font_hz16);
  47. #endif
  48. #endif
  49. #ifdef RTGUI_USING_FONT12
  50. rtgui_font_system_add_font(&rtgui_font_asc12);
  51. #ifdef RTGUI_USING_FONTHZ
  52. rtgui_font_system_add_font(&rtgui_font_hz12);
  53. #endif
  54. #endif
  55. }
  56. void rtgui_font_system_add_font(struct rtgui_font *font)
  57. {
  58. rtgui_list_init(&(font->list));
  59. rtgui_list_append(&_rtgui_font_list, &(font->list));
  60. /* init font */
  61. if (font->engine->font_init != RT_NULL)
  62. font->engine->font_init(font);
  63. /* first refer, load it */
  64. if (font->engine->font_load != RT_NULL)
  65. font->engine->font_load(font);
  66. }
  67. RTM_EXPORT(rtgui_font_system_add_font);
  68. void rtgui_font_system_remove_font(struct rtgui_font *font)
  69. {
  70. rtgui_list_remove(&_rtgui_font_list, &(font->list));
  71. }
  72. RTM_EXPORT(rtgui_font_system_remove_font);
  73. struct rtgui_font *rtgui_font_default()
  74. {
  75. return rtgui_default_font;
  76. }
  77. void rtgui_font_set_defaut(struct rtgui_font *font)
  78. {
  79. // rt_kprintf("set font size to %d\n", font->height);
  80. rtgui_default_font = font;
  81. }
  82. struct rtgui_font *rtgui_font_refer(const char *family, rt_uint16_t height)
  83. {
  84. /* search font */
  85. struct rtgui_list_node *node;
  86. struct rtgui_font *font;
  87. rtgui_list_foreach(node, &_rtgui_font_list)
  88. {
  89. font = rtgui_list_entry(node, struct rtgui_font, list);
  90. if ((rt_strncmp(font->family, family, RTGUI_NAME_MAX) == 0) &&
  91. font->height == height)
  92. {
  93. font->refer_count ++;
  94. return font;
  95. }
  96. }
  97. rtgui_list_foreach(node, &_rtgui_font_list)
  98. {
  99. font = rtgui_list_entry(node, struct rtgui_font, list);
  100. if (rt_strncmp(font->family, family, RTGUI_NAME_MAX) == 0)
  101. {
  102. font->refer_count ++;
  103. return font;
  104. }
  105. }
  106. return RT_NULL;
  107. }
  108. RTM_EXPORT(rtgui_font_refer);
  109. void rtgui_font_derefer(struct rtgui_font *font)
  110. {
  111. RT_ASSERT(font != RT_NULL);
  112. font->refer_count --;
  113. /* no refer, remove font */
  114. if (font->refer_count == 0)
  115. {
  116. rtgui_font_system_remove_font(font);
  117. }
  118. }
  119. RTM_EXPORT(rtgui_font_derefer);
  120. /* draw a text */
  121. void rtgui_font_draw(struct rtgui_font *font, struct rtgui_dc *dc, const char *text, rt_ubase_t len, struct rtgui_rect *rect)
  122. {
  123. RT_ASSERT(font != RT_NULL);
  124. if (font->engine != RT_NULL &&
  125. font->engine->font_draw_text != RT_NULL)
  126. {
  127. font->engine->font_draw_text(font, dc, text, len, rect);
  128. }
  129. }
  130. int rtgui_font_get_string_width(struct rtgui_font *font, const char *text)
  131. {
  132. rtgui_rect_t rect;
  133. /* get metrics */
  134. rtgui_font_get_metrics(font, text, &rect);
  135. return rect.x2 - rect.x1;
  136. }
  137. RTM_EXPORT(rtgui_font_get_string_width);
  138. void rtgui_font_get_metrics(struct rtgui_font *font, const char *text, rtgui_rect_t *rect)
  139. {
  140. RT_ASSERT(font != RT_NULL);
  141. if (font->engine != RT_NULL &&
  142. font->engine->font_get_metrics != RT_NULL)
  143. {
  144. font->engine->font_get_metrics(font, text, rect);
  145. }
  146. else
  147. {
  148. /* no font engine found, set rect to zero */
  149. rt_memset(rect, 0, sizeof(rtgui_rect_t));
  150. }
  151. }
  152. RTM_EXPORT(rtgui_font_get_metrics);
  153. /* GB18030 encoding:
  154. * 1st byte 2nd byte 3rd byte 4th byte
  155. * 1byte: 0x00~0x7F
  156. * 2bytes: 0x81~0xFE 0x40~0xFE
  157. * 4bytes: 0x81~0xFE 0x30~0x39 0x81~0xFE 0x30~0x39
  158. */
  159. struct rtgui_char_position _string_char_width(char *str, rt_size_t len, rt_size_t offset)
  160. {
  161. struct rtgui_char_position pos = {0, 0};
  162. unsigned char *pc;
  163. RT_ASSERT(offset < len);
  164. pc = (unsigned char*)str;
  165. while (pc <= (unsigned char*)str + offset)
  166. {
  167. if (pc[0] < 0x80)
  168. {
  169. pos.char_width = 1;
  170. }
  171. else if (0x81 <= pc[0] && pc[0] <= 0xFE)
  172. {
  173. if (0x40 <= pc[1] && pc[1] <= 0xFE)
  174. {
  175. /* GBK */
  176. pos.char_width = 2;
  177. }
  178. else if (0x30 <= pc[1] && pc[1] <= 0x39)
  179. {
  180. /* GB18030 */
  181. pos.char_width = 4;
  182. }
  183. else
  184. {
  185. /* FIXME: unknown encoding */
  186. RT_ASSERT(0);
  187. pos.char_width = 1;
  188. }
  189. }
  190. else
  191. {
  192. /* FIXME: unknown encoding */
  193. RT_ASSERT(0);
  194. pos.char_width = 1;
  195. }
  196. pc += pos.char_width;
  197. }
  198. pos.remain = pc - (unsigned char*)&str[offset];
  199. return pos;
  200. }