font_bmp.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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. * 2010-09-15 Bernard first version
  23. */
  24. #include <rtgui/font.h>
  25. #include <rtgui/dc.h>
  26. /* bitmap font private data */
  27. static void rtgui_bitmap_font_draw_text(struct rtgui_font *font, struct rtgui_dc *dc, const char *text, rt_ubase_t len, struct rtgui_rect *rect);
  28. static void rtgui_bitmap_font_get_metrics(struct rtgui_font *font, const char *text, rtgui_rect_t *rect);
  29. const struct rtgui_font_engine bmp_font_engine =
  30. {
  31. RT_NULL,
  32. RT_NULL,
  33. rtgui_bitmap_font_draw_text,
  34. rtgui_bitmap_font_get_metrics
  35. };
  36. RTM_EXPORT(bmp_font_engine);
  37. void rtgui_bitmap_font_draw_char(struct rtgui_font_bitmap *font, struct rtgui_dc *dc, const char ch,
  38. rtgui_rect_t *rect)
  39. {
  40. rtgui_color_t bc;
  41. const rt_uint8_t *font_ptr;
  42. int x, y, w, h, style;
  43. register rt_base_t i, j, /*k,*/ word_bytes;
  44. struct rtgui_rect dc_rect;
  45. /* check first and last char */
  46. if (ch < font->first_char || ch > font->last_char) return;
  47. /* get text style */
  48. style = rtgui_dc_get_gc(dc)->textstyle;
  49. bc = rtgui_dc_get_gc(dc)->background;
  50. rtgui_dc_get_rect(dc, &dc_rect);
  51. x = rect->x1;
  52. y = rect->y1;
  53. /* get width */
  54. if (font->char_width == RT_NULL)
  55. {
  56. word_bytes = (((font->width - 1) / 8) + 1);
  57. font_ptr = font->bmp + (ch - font->first_char) * word_bytes * font->height;
  58. }
  59. else
  60. {
  61. word_bytes = ((font->char_width[ch - font->first_char] - 1) / 8) + 1;
  62. font_ptr = font->bmp + font->offset[ch - font->first_char];
  63. }
  64. w = (font->width + x > rect->x2) ? rect->x2 - rect->x1 : font->width;
  65. h = (font->height + y > rect->y2) ? rect->y2 - rect->y1 : font->height;
  66. for (i = 0; i < h; i++)
  67. {
  68. rt_uint8_t chr = 0;
  69. const rt_uint8_t *ptr = font_ptr + i * word_bytes;
  70. if ((i + y) >= dc_rect.y2) continue;
  71. if ((i + y) < 0) continue;
  72. for (j = 0; j < w; j++)
  73. {
  74. if (j % 8 == 0)
  75. chr = *ptr++;
  76. if (chr & 0x80)
  77. rtgui_dc_draw_point(dc, j + x, i + y);
  78. else if (style & RTGUI_TEXTSTYLE_DRAW_BACKGROUND)
  79. rtgui_dc_draw_color_point(dc, j + x, i + y, bc);
  80. chr <<= 1;
  81. }
  82. }
  83. }
  84. static void rtgui_bitmap_font_draw_text(struct rtgui_font *font, struct rtgui_dc *dc,
  85. const char *text, rt_ubase_t len, struct rtgui_rect *rect)
  86. {
  87. rt_uint32_t length;
  88. struct rtgui_rect text_rect;
  89. struct rtgui_font_bitmap *bmp_font = (struct rtgui_font_bitmap *)(font->data);
  90. #ifdef RTGUI_USING_FONTHZ
  91. struct rtgui_font *hz_font;
  92. #endif
  93. RT_ASSERT(bmp_font != RT_NULL);
  94. rtgui_font_get_metrics(font, text, &text_rect);
  95. rtgui_rect_move_to_align(rect, &text_rect, RTGUI_DC_TEXTALIGN(dc));
  96. /* parameter check */
  97. if (text_rect.y1 > text_rect.y2) return;
  98. #ifdef RTGUI_USING_FONTHZ
  99. hz_font = rtgui_font_refer("hz", font->height);
  100. while ((text_rect.x1 < text_rect.x2) && len)
  101. {
  102. length = 0;
  103. while ((rt_uint8_t) * (text + length) >= 0x80) length ++; /* it's not a ascii character */
  104. if (length > 0)
  105. {
  106. if (hz_font != RT_NULL) rtgui_font_draw(hz_font, dc, text, length, &text_rect);
  107. text += length;
  108. len -= length;
  109. }
  110. length = 0;
  111. while (((rt_uint8_t) * (text + length) < 0x80) && *(text + length)) length ++;
  112. if (length > 0)
  113. {
  114. len -= length;
  115. while (length-- && text_rect.x1 < text_rect.x2)
  116. {
  117. rtgui_bitmap_font_draw_char(bmp_font, dc, *text, &text_rect);
  118. /* move x to next character */
  119. if (bmp_font->char_width == RT_NULL)
  120. text_rect.x1 += bmp_font->width;
  121. else
  122. text_rect.x1 += bmp_font->char_width[*text - bmp_font->first_char];
  123. text ++;
  124. }
  125. }
  126. }
  127. if (hz_font != RT_NULL) rtgui_font_derefer(hz_font);
  128. #else
  129. while ((text_rect.x1 < text_rect.x2) && len)
  130. {
  131. length = 0;
  132. while (((rt_uint8_t) * (text + length) < 0x80) && *(text + length)) length ++;
  133. if (length > 0)
  134. {
  135. len -= length;
  136. while (length-- && text_rect.x1 < text_rect.x2)
  137. {
  138. rtgui_bitmap_font_draw_char(bmp_font, dc, *text, &text_rect);
  139. /* move x to next character */
  140. if (bmp_font->char_width == RT_NULL)
  141. text_rect.x1 += bmp_font->width;
  142. else
  143. text_rect.x1 += bmp_font->char_width[*text - bmp_font->first_char];
  144. text ++;
  145. }
  146. }
  147. }
  148. #endif
  149. }
  150. static void rtgui_bitmap_font_get_metrics(struct rtgui_font *font, const char *text, rtgui_rect_t *rect)
  151. {
  152. rt_uint32_t length;
  153. struct rtgui_font_bitmap *bmp_font = (struct rtgui_font_bitmap *)(font->data);
  154. RT_ASSERT(bmp_font != RT_NULL);
  155. /* set init metrics rect */
  156. rect->x1 = rect->y1 = 0;
  157. rect->x2 = 0;
  158. rect->y2 = bmp_font->height;
  159. while (*text)
  160. {
  161. length = 0;
  162. while ((rt_uint8_t) * (text + length) >= 0x80) length ++; /* it's not a ascii character */
  163. rect->x2 += (font->height / 2) * length;
  164. text += length;
  165. length = 0;
  166. while (((rt_uint8_t) * (text + length) < 0x80) && *(text + length)) length ++;
  167. if (bmp_font->char_width != NULL)
  168. {
  169. /* get width for each character */
  170. while (*text && ((rt_uint8_t)*text < 0x80))
  171. {
  172. rect->x2 += bmp_font->char_width[*text - bmp_font->first_char];
  173. text ++;
  174. }
  175. }
  176. else
  177. {
  178. /* set metrics rect */
  179. rect->x2 += bmp_font->width * length;
  180. text += length;
  181. }
  182. }
  183. }