font_bmp.c 5.8 KB

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