font.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*
  2. * File : font.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2009-10-16 Bernard first version
  13. * 2013-08-31 Bernard remove the default font setting.
  14. * (which set by theme)
  15. */
  16. #include <rtgui/font.h>
  17. #include <rtgui/dc.h>
  18. static rtgui_list_t _rtgui_font_list;
  19. static struct rtgui_font *rtgui_default_font;
  20. extern struct rtgui_font rtgui_font_asc16;
  21. extern struct rtgui_font rtgui_font_arial16;
  22. extern struct rtgui_font rtgui_font_asc12;
  23. extern struct rtgui_font rtgui_font_arial12;
  24. #ifdef RTGUI_USING_FONTHZ
  25. extern struct rtgui_font rtgui_font_hz16;
  26. extern struct rtgui_font rtgui_font_hz12;
  27. #endif
  28. void rtgui_font_system_init()
  29. {
  30. rtgui_list_init(&(_rtgui_font_list));
  31. /* set default font to NULL */
  32. rtgui_default_font = RT_NULL;
  33. #ifdef RTGUI_USING_FONT16
  34. rtgui_font_system_add_font(&rtgui_font_asc16);
  35. #ifdef RTGUI_USING_FONTHZ
  36. rtgui_font_system_add_font(&rtgui_font_hz16);
  37. #endif
  38. #endif
  39. #ifdef RTGUI_USING_FONT12
  40. rtgui_font_system_add_font(&rtgui_font_asc12);
  41. #ifdef RTGUI_USING_FONTHZ
  42. rtgui_font_system_add_font(&rtgui_font_hz12);
  43. #endif
  44. #endif
  45. }
  46. void rtgui_font_system_add_font(struct rtgui_font *font)
  47. {
  48. rtgui_list_init(&(font->list));
  49. rtgui_list_append(&_rtgui_font_list, &(font->list));
  50. /* init font */
  51. if (font->engine->font_init != RT_NULL)
  52. font->engine->font_init(font);
  53. /* first refer, load it */
  54. if (font->engine->font_load != RT_NULL)
  55. font->engine->font_load(font);
  56. }
  57. RTM_EXPORT(rtgui_font_system_add_font);
  58. void rtgui_font_system_remove_font(struct rtgui_font *font)
  59. {
  60. rtgui_list_remove(&_rtgui_font_list, &(font->list));
  61. }
  62. RTM_EXPORT(rtgui_font_system_remove_font);
  63. struct rtgui_font *rtgui_font_default()
  64. {
  65. return rtgui_default_font;
  66. }
  67. void rtgui_font_set_defaut(struct rtgui_font *font)
  68. {
  69. // rt_kprintf("set font size to %d\n", font->height);
  70. rtgui_default_font = font;
  71. }
  72. struct rtgui_font *rtgui_font_refer(const char *family, rt_uint16_t height)
  73. {
  74. /* search font */
  75. struct rtgui_list_node *node;
  76. struct rtgui_font *font;
  77. rtgui_list_foreach(node, &_rtgui_font_list)
  78. {
  79. font = rtgui_list_entry(node, struct rtgui_font, list);
  80. if ((rt_strncmp(font->family, family, RTGUI_NAME_MAX) == 0) &&
  81. font->height == height)
  82. {
  83. font->refer_count ++;
  84. return font;
  85. }
  86. }
  87. return RT_NULL;
  88. }
  89. RTM_EXPORT(rtgui_font_refer);
  90. void rtgui_font_derefer(struct rtgui_font *font)
  91. {
  92. RT_ASSERT(font != RT_NULL);
  93. font->refer_count --;
  94. /* no refer, remove font */
  95. if (font->refer_count == 0)
  96. {
  97. rtgui_font_system_remove_font(font);
  98. }
  99. }
  100. RTM_EXPORT(rtgui_font_derefer);
  101. /* draw a text */
  102. void rtgui_font_draw(struct rtgui_font *font, struct rtgui_dc *dc, const char *text, rt_ubase_t len, struct rtgui_rect *rect)
  103. {
  104. RT_ASSERT(font != RT_NULL);
  105. if (font->engine != RT_NULL &&
  106. font->engine->font_draw_text != RT_NULL)
  107. {
  108. font->engine->font_draw_text(font, dc, text, len, rect);
  109. }
  110. }
  111. int rtgui_font_get_string_width(struct rtgui_font *font, const char *text)
  112. {
  113. rtgui_rect_t rect;
  114. /* get metrics */
  115. rtgui_font_get_metrics(font, text, &rect);
  116. return rect.x2 - rect.x1;
  117. }
  118. RTM_EXPORT(rtgui_font_get_string_width);
  119. void rtgui_font_get_metrics(struct rtgui_font *font, const char *text, rtgui_rect_t *rect)
  120. {
  121. RT_ASSERT(font != RT_NULL);
  122. if (font->engine != RT_NULL &&
  123. font->engine->font_get_metrics != RT_NULL)
  124. {
  125. font->engine->font_get_metrics(font, text, rect);
  126. }
  127. else
  128. {
  129. /* no font engine found, set rect to zero */
  130. rt_memset(rect, 0, sizeof(rtgui_rect_t));
  131. }
  132. }
  133. RTM_EXPORT(rtgui_font_get_metrics);
  134. /* GB18030 encoding:
  135. * 1st byte 2nd byte 3rd byte 4th byte
  136. * 1byte: 0x00~0x7F
  137. * 2bytes: 0x81~0xFE 0x40~0xFE
  138. * 4bytes: 0x81~0xFE 0x30~0x39 0x81~0xFE 0x30~0x39
  139. */
  140. struct rtgui_char_position _string_char_width(char *str, rt_size_t len, rt_size_t offset)
  141. {
  142. struct rtgui_char_position pos = {0, 0};
  143. unsigned char *pc;
  144. RT_ASSERT(offset < len);
  145. pc = (unsigned char*)str;
  146. while (pc <= (unsigned char*)str + offset)
  147. {
  148. if (pc[0] < 0x80)
  149. {
  150. pos.char_width = 1;
  151. }
  152. else if (0x81 <= pc[0] && pc[0] <= 0xFE)
  153. {
  154. if (0x40 <= pc[1] && pc[1] <= 0xFE)
  155. {
  156. /* GBK */
  157. pos.char_width = 2;
  158. }
  159. else if (0x30 <= pc[1] && pc[1] <= 0x39)
  160. {
  161. /* GB18030 */
  162. pos.char_width = 4;
  163. }
  164. else
  165. {
  166. /* FIXME: unknown encoding */
  167. RT_ASSERT(0);
  168. pos.char_width = 1;
  169. }
  170. }
  171. else
  172. {
  173. /* FIXME: unknown encoding */
  174. RT_ASSERT(0);
  175. pos.char_width = 1;
  176. }
  177. pc += pos.char_width;
  178. }
  179. pos.remain = pc - (unsigned char*)&str[offset];
  180. return pos;
  181. }