123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- /*
- * File : font.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date Author Notes
- * 2010-09-15 Bernard first version
- */
- #include <rtgui/font.h>
- #include <rtgui/dc.h>
- /* bitmap font private data */
- 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);
- static void rtgui_bitmap_font_get_metrics(struct rtgui_font *font, const char *text, rtgui_rect_t *rect);
- const struct rtgui_font_engine bmp_font_engine =
- {
- RT_NULL,
- RT_NULL,
- rtgui_bitmap_font_draw_text,
- rtgui_bitmap_font_get_metrics
- };
- void rtgui_bitmap_font_draw_char(struct rtgui_font_bitmap *font, struct rtgui_dc *dc, const char ch,
- rtgui_rect_t *rect)
- {
- rtgui_color_t bc;
- const rt_uint8_t *font_ptr;
- rt_uint16_t x, y, w, h, style;
- register rt_base_t i, j, /*k,*/ word_bytes;
- /* check first and last char */
- if (ch < font->first_char || ch > font->last_char) return;
- /* get text style */
- style = rtgui_dc_get_gc(dc)->textstyle;
- bc = rtgui_dc_get_gc(dc)->background;
- x = rect->x1;
- y = rect->y1;
- /* get width */
- if (font->char_width == RT_NULL)
- {
- word_bytes = (((font->width - 1) / 8) + 1);
- font_ptr = font->bmp + (ch - font->first_char) * word_bytes * font->height;
- }
- else
- {
- word_bytes = ((font->char_width[ch - font->first_char] - 1) / 8) + 1;
- font_ptr = font->bmp + font->offset[ch - font->first_char];
- }
- w = (font->width + x > rect->x2) ? rect->x2 - rect->x1 : font->width;
- h = (font->height + y > rect->y2) ? rect->y2 - rect->y1 : font->height;
- for (i = 0; i < h; i++)
- {
- rt_uint8_t chr;
- const rt_uint8_t *ptr = font_ptr + i * word_bytes;
- for (j = 0; j < w; j++)
- {
- if (j % 8 == 0)chr = *ptr++;
- if (chr & 0x80)
- rtgui_dc_draw_point(dc, j + x, i + y);
- else if (style & RTGUI_TEXTSTYLE_DRAW_BACKGROUND)
- rtgui_dc_draw_color_point(dc, j + x, i + y, bc);
- chr <<= 1;
- }
- }
- }
- 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)
- {
- rt_uint32_t length;
- struct rtgui_font_bitmap *bmp_font = (struct rtgui_font_bitmap *)(font->data);
- #ifdef RTGUI_USING_FONTHZ
- struct rtgui_font *hz_font;
- RT_ASSERT(bmp_font != RT_NULL);
- if (rect->y1 > rect->y2) return;
- hz_font = rtgui_font_refer("hz", font->height);
- while ((rect->x1 < rect->x2) && len)
- {
- length = 0;
- while ((rt_uint8_t) * (text + length) >= 0x80) length ++; /* it's not a ascii character */
- if (length > 0)
- {
- if (hz_font != RT_NULL) rtgui_font_draw(hz_font, dc, text, length, rect);
- text += length;
- len -= length;
- }
- length = 0;
- while (((rt_uint8_t) * (text + length) < 0x80) && *(text + length)) length ++;
- if (length > 0)
- {
- len -= length;
- while (length-- && rect->x1 < rect->x2)
- {
- rtgui_bitmap_font_draw_char(bmp_font, dc, *text, rect);
- /* move x to next character */
- if (bmp_font->char_width == RT_NULL)
- rect->x1 += bmp_font->width;
- else
- rect->x1 += bmp_font->char_width[*text - bmp_font->first_char];
- text ++;
- }
- }
- }
- if (hz_font != RT_NULL) rtgui_font_derefer(hz_font);
- #else
- if (rect->y1 > rect->y2) return;
- while ((rect->x1 < rect->x2) && len)
- {
- length = 0;
- while (((rt_uint8_t) * (text + length) < 0x80) && *(text + length)) length ++;
- if (length > 0)
- {
- len -= length;
- while (length-- && rect->x1 < rect->x2)
- {
- rtgui_bitmap_font_draw_char(bmp_font, dc, *text, rect);
- /* move x to next character */
- if (bmp_font->char_width == RT_NULL)
- rect->x1 += bmp_font->width;
- else
- rect->x1 += bmp_font->char_width[*text - bmp_font->first_char];
- text ++;
- }
- }
- }
- #endif
- }
- static void rtgui_bitmap_font_get_metrics(struct rtgui_font *font, const char *text, rtgui_rect_t *rect)
- {
- rt_uint32_t length;
- struct rtgui_font_bitmap *bmp_font = (struct rtgui_font_bitmap *)(font->data);
- RT_ASSERT(bmp_font != RT_NULL);
- /* set init metrics rect */
- rect->x1 = rect->y1 = 0;
- rect->x2 = 0;
- rect->y2 = bmp_font->height;
- while (*text)
- {
- length = 0;
- while ((rt_uint8_t) * (text + length) >= 0x80) length ++; /* it's not a ascii character */
- rect->x2 += (font->height / 2) * length;
- text += length;
- length = 0;
- while (((rt_uint8_t) * (text + length) < 0x80) && *(text + length)) length ++;
- if (bmp_font->char_width != NULL)
- {
- /* get width for each character */
- while (*text && ((rt_uint8_t)*text < 0x80))
- {
- rect->x2 += bmp_font->char_width[*text - bmp_font->first_char];
- text ++;
- }
- }
- else
- {
- /* set metrics rect */
- rect->x2 += bmp_font->width * length;
- text += length;
- }
- }
- }
|