From 9641f5b7a051e14e907addca20608e656128426f Mon Sep 17 00:00:00 2001 From: "bernard.xiong@gmail.com" Date: Mon, 27 Sep 2010 15:36:03 +0000 Subject: [PATCH] update font engine. git-svn-id: https://rt-thread.googlecode.com/svn/trunk@966 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- components/rtgui/common/dc.c | 36 ----------- components/rtgui/common/font_bmp.c | 82 ++++++++++++++++++-------- components/rtgui/common/font_hz_bmp.c | 43 +++++++++++++- components/rtgui/common/font_hz_file.c | 45 +++++++++++++- 4 files changed, 140 insertions(+), 66 deletions(-) diff --git a/components/rtgui/common/dc.c b/components/rtgui/common/dc.c index 2644694307..08acafb872 100644 --- a/components/rtgui/common/dc.c +++ b/components/rtgui/common/dc.c @@ -265,9 +265,6 @@ void rtgui_dc_draw_text (struct rtgui_dc* dc, const char* text, struct rtgui_rec { rt_uint32_t len; struct rtgui_font *font; -#ifdef RTGUI_USING_FONTHZ - struct rtgui_font *gb2312_font; -#endif struct rtgui_rect text_rect; RT_ASSERT(dc != RT_NULL); @@ -279,45 +276,12 @@ void rtgui_dc_draw_text (struct rtgui_dc* dc, const char* text, struct rtgui_rec font = rtgui_font_default(); } -#ifdef RTGUI_USING_FONTHZ - gb2312_font = rtgui_font_refer("hz", font->height); - if (gb2312_font == RT_NULL) - { - gb2312_font = rtgui_font_refer("hz", 16); - } -#endif - /* text align */ rtgui_font_get_metrics(font, text, &text_rect); rtgui_rect_moveto_align(rect, &text_rect, RTGUI_DC_TEXTALIGN(dc)); -#ifdef RTGUI_USING_FONTHZ - while (*text) - { - len = 0; - while (((rt_uint8_t)*(text + len)) < 0x80 && *(text + len)) len ++; - if (len > 0) - { - rtgui_font_draw(font, dc, text, len, &text_rect); - - text += len; - } - - len = 0; - while (((rt_uint8_t)*(text + len)) > 0x80) len ++; - if (len > 0) - { - rtgui_font_draw(gb2312_font, dc, text, len, &text_rect); - - text += len; - } - } - - rtgui_font_derefer(gb2312_font); -#else len = strlen((const char*)text); rtgui_font_draw(font, dc, text, len, &text_rect); -#endif } /* diff --git a/components/rtgui/common/font_bmp.c b/components/rtgui/common/font_bmp.c index 5ea3701ac9..9887c6ad5d 100644 --- a/components/rtgui/common/font_bmp.c +++ b/components/rtgui/common/font_bmp.c @@ -70,49 +70,81 @@ void rtgui_bitmap_font_draw_char(struct rtgui_font_bitmap* font, struct rtgui_dc 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* hz_font; struct rtgui_font_bitmap* bmp_font = (struct rtgui_font_bitmap*)(font->data); RT_ASSERT(bmp_font != RT_NULL); - while (len-- && rect->x1 < rect->x2) + hz_font = rtgui_font_refer("hz", font->height); + while ((rect->x1 < rect->x2) && len) { - rtgui_bitmap_font_draw_char(bmp_font, dc, *text, rect); + 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; + } - /* 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 ++; + 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 ++; + } + } } + + rtgui_font_derefer(hz_font); } 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); - if (bmp_font->char_width != NULL) + /* set init metrics rect */ + rect->x1 = rect->y1 = 0;rect->x2 = 0; + rect->y2 = bmp_font->height; + + while (*text) { - rt_uint32_t index; + length = 0; + while (*(text + length) >= 0x80) length ++; /* it's not a ascii character */ + rect->x2 += (font->height/2) * length; + text += length; - /* set metrics rect */ - rect->x1 = rect->y1 = 0;rect->x2 = 0; - rect->y2 = bmp_font->height; - - /* get width for each character */ - while (*text) + length = 0; + while ((*(text + length) < 0x80) && *(text + length)) length ++; + if (bmp_font->char_width != NULL) { - rect->x2 += bmp_font->char_width[*text - bmp_font->first_char]; - text ++; + /* get width for each character */ + while (*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; } } - else - { - /* set metrics rect */ - rect->x1 = rect->y1 = 0; - rect->x2 = bmp_font->width * (rt_int16_t)rt_strlen((const char*)text); - rect->y2 = bmp_font->height; - } } diff --git a/components/rtgui/common/font_hz_bmp.c b/components/rtgui/common/font_hz_bmp.c index 17f5ed106d..7c0d125de7 100644 --- a/components/rtgui/common/font_hz_bmp.c +++ b/components/rtgui/common/font_hz_bmp.c @@ -14,11 +14,10 @@ const struct rtgui_font_engine hz_bmp_font_engine = rtgui_hz_bitmap_font_get_metrics }; -static void rtgui_hz_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_hz_bitmap_font_draw_text(struct rtgui_font_bitmap* bmp_font, struct rtgui_dc* dc, const char* text, rt_ubase_t len, struct rtgui_rect* rect) { register rt_base_t h, word_bytes; rt_uint8_t* str; - struct rtgui_font_bitmap* bmp_font = (struct rtgui_font_bitmap*)(font->data); RT_ASSERT(bmp_font != RT_NULL); @@ -62,6 +61,45 @@ static void rtgui_hz_bitmap_font_draw_text(struct rtgui_font* font, struct rtgui } } +static void rtgui_hz_bitmap_font_draw_text (struct rtgui_font* font, struct rtgui_dc* dc, const char* text, rt_ubase_t length, struct rtgui_rect* rect) +{ + rt_uint32_t len; + struct rtgui_font *efont; + struct rtgui_font_bitmap* bmp_font = (struct rtgui_font_bitmap*)(font->data); + + RT_ASSERT(dc != RT_NULL); + + /* get English font */ + efont = rtgui_font_refer("asc", bmp_font->height); + if (efont == RT_NULL) efont = rtgui_font_default(); /* use system default font */ + + while (length > 0) + { + len = 0; + while (((rt_uint8_t)*(text + len)) < 0x80 && *(text + len)) len ++; + /* draw text with English font */ + if (len > 0) + { + rtgui_font_draw(efont, dc, text, len, rect); + + text += len; + length -= len; + } + + len = 0; + while (((rt_uint8_t)*(text + len)) >= 0x80) len ++; + if (len > 0) + { + _rtgui_hz_bitmap_font_draw_text(bmp_font, dc, text, len, rect); + + text += len; + length -= len; + } + } + + rtgui_font_derefer(efont); +} + static void rtgui_hz_bitmap_font_get_metrics(struct rtgui_font* font, const char* text, rtgui_rect_t* rect) { struct rtgui_font_bitmap* bmp_font = (struct rtgui_font_bitmap*)(font->data); @@ -70,6 +108,7 @@ static void rtgui_hz_bitmap_font_get_metrics(struct rtgui_font* font, const char /* set metrics rect */ rect->x1 = rect->y1 = 0; + /* Chinese font is always fixed font */ rect->x2 = (rt_int16_t)(bmp_font->width * rt_strlen((const char*)text)); rect->y2 = bmp_font->height; } diff --git a/components/rtgui/common/font_hz_file.c b/components/rtgui/common/font_hz_file.c index d8859abf85..dce99e1213 100644 --- a/components/rtgui/common/font_hz_file.c +++ b/components/rtgui/common/font_hz_file.c @@ -5,6 +5,7 @@ #include #include #include + #ifdef RTGUI_USING_HZ_FILE #include @@ -91,12 +92,10 @@ static void rtgui_hz_file_font_load(struct rtgui_font* font) hz_file_font->fd = open(hz_file_font->font_fn, O_RDONLY, 0); } -static void rtgui_hz_file_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_hz_file_font_draw_text(struct rtgui_hz_file_font* hz_file_font, struct rtgui_dc* dc, const char* text, rt_ubase_t len, struct rtgui_rect* rect) { register rt_base_t h, word_bytes; rt_uint8_t* str; - struct rtgui_hz_file_font* hz_file_font = (struct rtgui_hz_file_font*)font->data; - RT_ASSERT(hz_file_font != RT_NULL); /* drawing height */ h = (hz_file_font->font_size + rect->y1 > rect->y2)? @@ -134,6 +133,46 @@ static void rtgui_hz_file_font_draw_text(struct rtgui_font* font, struct rtgui_d } } +static void rtgui_hz_file_font_draw_text(struct rtgui_font* font, struct rtgui_dc* dc, const char* text, rt_ubase_t length, struct rtgui_rect* rect) +{ + rt_uint32_t len; + struct rtgui_font *efont; + struct rtgui_hz_file_font* hz_file_font = (struct rtgui_hz_file_font*)font->data; + + RT_ASSERT(dc != RT_NULL); + RT_ASSERT(hz_file_font != RT_NULL); + + /* get English font */ + efont = rtgui_font_refer("asc", hz_file_font->font_size); + if (efont == RT_NULL) efont = rtgui_font_default(); /* use system default font */ + + while (length > 0) + { + len = 0; + while (((rt_uint8_t)*(text + len)) < 0x80 && *(text + len)) len ++; + /* draw text with English font */ + if (len > 0) + { + rtgui_font_draw(efont, dc, text, len, rect); + + text += len; + length -= len; + } + + len = 0; + while (((rt_uint8_t)*(text + len)) >= 0x80) len ++; + if (len > 0) + { + _rtgui_hz_file_font_draw_text(hz_file_font, dc, text, len, rect); + + text += len; + length -= len; + } + } + + rtgui_font_derefer(efont); +} + static void rtgui_hz_file_font_get_metrics(struct rtgui_font* font, const char* text, rtgui_rect_t* rect) { struct rtgui_hz_file_font* hz_file_font = (struct rtgui_hz_file_font*)font->data;