font_bmp.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. void rtgui_bitmap_font_draw_char(struct rtgui_font_bitmap* font, struct rtgui_dc* dc, const char ch,
  27. rtgui_rect_t* rect)
  28. {
  29. const rt_uint8_t* font_ptr;
  30. rt_uint16_t x, y, h;
  31. register rt_base_t i, j, k, word_bytes;
  32. /* check first and last char */
  33. if (ch < font->first_char || ch > font->last_char) return;
  34. x = rect->x1;
  35. y = rect->y1;
  36. /* get width */
  37. if (font->char_width == RT_NULL)
  38. {
  39. word_bytes = (((font->width - 1) / 8) + 1);
  40. font_ptr = font->bmp + (ch - font->first_char) * word_bytes * font->height;
  41. }
  42. else
  43. {
  44. word_bytes = ((font->char_width[ch - font->first_char] - 1)/8) + 1;
  45. font_ptr = font->bmp + font->offset[ch - font->first_char];
  46. }
  47. h = (font->height + y > rect->y2) ? rect->y2 - rect->y1 : font->height;
  48. for (i = 0; i < h; i++)
  49. {
  50. for (j = 0; j < word_bytes; j++)
  51. {
  52. for (k = 0; k < 8; k++)
  53. {
  54. if (((font_ptr[i * word_bytes + j] >> (7 - k)) & 0x01) != 0)
  55. {
  56. /* draw a pixel */
  57. rtgui_dc_draw_point(dc, k + 8 * j + x, i + y);
  58. }
  59. }
  60. }
  61. }
  62. }
  63. 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)
  64. {
  65. rt_uint32_t length;
  66. struct rtgui_font_bitmap* bmp_font = (struct rtgui_font_bitmap*)(font->data);
  67. #ifdef RTGUI_USING_FONTHZ
  68. struct rtgui_font* hz_font;
  69. RT_ASSERT(bmp_font != RT_NULL);
  70. hz_font = rtgui_font_refer("hz", font->height);
  71. while ((rect->x1 < rect->x2) && len)
  72. {
  73. length = 0;
  74. while ((rt_uint8_t)*(text + length) >= 0x80) length ++; /* it's not a ascii character */
  75. if (length > 0)
  76. {
  77. if (hz_font != RT_NULL)
  78. rtgui_font_draw(hz_font, dc, text, length, rect);
  79. text += length;
  80. len -= length;
  81. }
  82. length = 0;
  83. while (((rt_uint8_t)*(text + length) < 0x80) && *(text + length)) length ++;
  84. if (length > 0)
  85. {
  86. len -= length;
  87. while (length-- && rect->x1 < rect->x2)
  88. {
  89. rtgui_bitmap_font_draw_char(bmp_font, dc, *text, rect);
  90. /* move x to next character */
  91. if (bmp_font->char_width == RT_NULL)
  92. rect->x1 += bmp_font->width;
  93. else
  94. rect->x1 += bmp_font->char_width[*text - bmp_font->first_char];
  95. text ++;
  96. }
  97. }
  98. }
  99. rtgui_font_derefer(hz_font);
  100. #else
  101. while ((rect->x1 < rect->x2) && len)
  102. {
  103. while (((rt_uint8_t)*(text + length) < 0x80) && *(text + length)) length ++;
  104. if (length > 0)
  105. {
  106. len -= length;
  107. while (length-- && rect->x1 < rect->x2)
  108. {
  109. rtgui_bitmap_font_draw_char(bmp_font, dc, *text, rect);
  110. /* move x to next character */
  111. if (bmp_font->char_width == RT_NULL)
  112. rect->x1 += bmp_font->width;
  113. else
  114. rect->x1 += bmp_font->char_width[*text - bmp_font->first_char];
  115. text ++;
  116. }
  117. }
  118. }
  119. #endif
  120. }
  121. static void rtgui_bitmap_font_get_metrics(struct rtgui_font* font, const char* text, rtgui_rect_t* rect)
  122. {
  123. rt_uint32_t length;
  124. struct rtgui_font_bitmap* bmp_font = (struct rtgui_font_bitmap*)(font->data);
  125. RT_ASSERT(bmp_font != RT_NULL);
  126. /* set init metrics rect */
  127. rect->x1 = rect->y1 = 0;rect->x2 = 0;
  128. rect->y2 = bmp_font->height;
  129. while (*text)
  130. {
  131. length = 0;
  132. while (*(text + length) >= 0x80) length ++; /* it's not a ascii character */
  133. rect->x2 += (font->height/2) * length;
  134. text += length;
  135. length = 0;
  136. while ((*(text + length) < 0x80) && *(text + length)) length ++;
  137. if (bmp_font->char_width != NULL)
  138. {
  139. /* get width for each character */
  140. while (*text && (*text < 0x80))
  141. {
  142. rect->x2 += bmp_font->char_width[*text - bmp_font->first_char];
  143. text ++;
  144. }
  145. }
  146. else
  147. {
  148. /* set metrics rect */
  149. rect->x2 += bmp_font->width * length;
  150. text += length;
  151. }
  152. }
  153. }