Ver código fonte

add textstyle in gc; fix hz_cache memory leak issue; fix selection issue in radiobox.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1250 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 14 anos atrás
pai
commit
66037b4de6

+ 1 - 0
components/rtgui/SConscript

@@ -17,6 +17,7 @@ common/filerw.c
 common/image.c
 common/image_xpm.c
 common/image_hdc.c
+common/image_bmp.c
 common/font.c
 common/font_bmp.c
 common/font_hz_file.c

+ 10 - 1
components/rtgui/common/font_bmp.c

@@ -29,13 +29,18 @@ const struct rtgui_font_engine bmp_font_engine =
 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, h;
+	rt_uint16_t x, y, 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 */
@@ -63,6 +68,10 @@ void rtgui_bitmap_font_draw_char(struct rtgui_font_bitmap* font, struct rtgui_dc
 					/* draw a pixel */
 					rtgui_dc_draw_point(dc, k + 8 * j + x, i + y);
 				}
+				else if (style & RTGUI_TEXTSTYLE_DRAW_BACKGROUND)
+				{
+					rtgui_dc_draw_color_point(dc, k + 8 * j + x, i + y, bc);
+				}
 			}
 		}
 	}

+ 11 - 1
components/rtgui/common/font_hz_bmp.c

@@ -16,11 +16,17 @@ const struct rtgui_font_engine hz_bmp_font_engine =
 
 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;
+	rtgui_color_t bc;
+	rt_uint16_t style;
+	register rt_base_t h, word_bytes;
 
 	RT_ASSERT(bmp_font != RT_NULL);
 
+	/* get text style */
+	style = rtgui_dc_get_gc(dc)->textstyle;
+	bc = rtgui_dc_get_gc(dc)->background;
+
 	/* drawing height */
 	h = (bmp_font->height + rect->y1 > rect->y2)? rect->y2 - rect->y1 : bmp_font->height;
 	word_bytes = (bmp_font->width + 7)/8;
@@ -51,6 +57,10 @@ static void _rtgui_hz_bitmap_font_draw_text(struct rtgui_font_bitmap* bmp_font,
 					{
 						rtgui_dc_draw_point(dc, rect->x1 + 8*j + k, rect->y1 + i);
 					}
+					else if (style & RTGUI_TEXTSTYLE_DRAW_BACKGROUND)
+					{
+						rtgui_dc_draw_color_point(dc, rect->x1 + 8*j + k, rect->y1 + i, bc);
+					}
 				}
 		}
 

+ 34 - 6
components/rtgui/common/font_hz_file.c

@@ -41,16 +41,27 @@ static rt_uint8_t* _font_cache_get(struct rtgui_hz_file_font* font, rt_uint16_t
     struct hz_cache *cache, search;
 
     search.hz_id = hz_id;
-    cache = SPLAY_FIND(cache_tree, &(font->cache_root), &search);
+
+	/* enter critical */
+	rtgui_enter_critical();
+
+	cache = SPLAY_FIND(cache_tree, &(font->cache_root), &search);
     if (cache != RT_NULL)
     {
-        /* find it */
+		/* exit critical */
+		rtgui_exit_critical();
+
+        /* found it */
         return (rt_uint8_t*)(cache + 1);
     }
 
-    /* can not find it, load to cache */
+	/* exit critical */
+	rtgui_exit_critical();
+
+	/* can not find it, load to cache */
     cache = (struct hz_cache*) rtgui_malloc(sizeof(struct hz_cache) + font->font_data_size);
-    if (cache == RT_NULL) return RT_NULL; /* no memory yet */
+    if (cache == RT_NULL)
+		return RT_NULL; /* no memory yet */
 
     cache->hz_id = hz_id;
     seek = 94 * (((hz_id & 0xff) - 0xA0) - 1) + ((hz_id >> 8) - 0xA0) - 1;
@@ -65,7 +76,10 @@ static rt_uint8_t* _font_cache_get(struct rtgui_hz_file_font* font, rt_uint16_t
         return RT_NULL;
     }
 
-    /* insert to cache */
+	/* enter critical */
+	rtgui_enter_critical();
+
+	/* insert to cache */
     SPLAY_INSERT(cache_tree, &(font->cache_root), cache);
 	font->cache_size ++;
 
@@ -78,9 +92,13 @@ static rt_uint8_t* _font_cache_get(struct rtgui_hz_file_font* font, rt_uint16_t
 
         /* remove the left node */
         SPLAY_REMOVE(cache_tree, &(font->cache_root), left);
+		rtgui_free(left);
 		font->cache_size --;
     }
 
+	/* exit critical */
+	rtgui_exit_critical();
+
     return (rt_uint8_t*)(cache + 1);
 }
 
@@ -94,8 +112,14 @@ static void rtgui_hz_file_font_load(struct rtgui_font* font)
 
 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;
+	rtgui_color_t bc;
+	rt_uint16_t style;
+	register rt_base_t h, word_bytes;
+
+	/* get text style */
+	style = rtgui_dc_get_gc(dc)->textstyle;
+	bc = rtgui_dc_get_gc(dc)->background;
 
 	/* drawing height */
 	h = (hz_file_font->font_size + rect->y1 > rect->y2)?
@@ -123,6 +147,10 @@ static void _rtgui_hz_file_font_draw_text(struct rtgui_hz_file_font* hz_file_fon
 					{
 						rtgui_dc_draw_point(dc, rect->x1 + 8*j + k, rect->y1 + i);
 					}
+					else if (style & RTGUI_TEXTSTYLE_DRAW_BACKGROUND)
+					{
+						rtgui_dc_draw_color_point(dc, rect->x1 + 8*j + k, rect->y1 + i, bc);
+					}
 				}
 		}
 

+ 11 - 1
components/rtgui/include/rtgui/rtgui.h

@@ -56,8 +56,10 @@ struct rtgui_gc
 	/* foreground and background color */
 	rtgui_color_t foreground, background;
 
+	/* text style */
+	rt_uint16_t textstyle;
 	/* text align */
-	rt_base_t textalign;
+	rt_uint16_t textalign;
 
 	/* font */
 	struct rtgui_font* font;
@@ -107,6 +109,14 @@ enum RTGUI_ALIGN
 	RTGUI_ALIGN_STRETCH				= 0x20,
 };
 
+enum RTGUI_TEXTSTYLE
+{
+	RTGUI_TEXTSTYLE_NORMAL 			= 0x00,
+	RTGUI_TEXTSTYLE_DRAW_BACKGROUND = 0x01,
+	RTGUI_TEXTSTYLE_SHADOW 			= 0x02,
+	RTGUI_TEXTSTYLE_OUTLINE 		= 0x04,
+};
+
 enum RTGUI_MODAL_CODE
 {
 	RTGUI_MODAL_OK,

+ 3 - 0
components/rtgui/include/rtgui/rtgui_system.h

@@ -93,5 +93,8 @@ void* rtgui_malloc(rt_size_t size);
 void rtgui_free(void* ptr);
 void* rtgui_realloc(void* ptr, rt_size_t size);
 
+#define rtgui_enter_critical	rt_enter_critical
+#define rtgui_exit_critical		rt_exit_critical
+
 #endif
 

+ 1 - 1
components/rtgui/include/rtgui/widgets/listbox.h

@@ -49,7 +49,7 @@ struct rtgui_listbox
     /* the number of item in a page */
     rt_uint16_t page_items;
     /* current item */
-    rt_uint16_t current_item;
+    rt_int16_t current_item;
 };
 typedef struct rtgui_listbox rtgui_listbox_t;
 typedef void (*rtgui_onitem_func_t)(struct rtgui_widget* widget, rtgui_event_t *event);

+ 4 - 4
components/rtgui/include/rtgui/widgets/listctrl.h

@@ -20,11 +20,11 @@
 #include <rtgui/rtgui_system.h>
 #include <rtgui/widgets/widget.h>
 
-/** Gets the type of a list ctrl */
+/** Gets the type of a listctrl */
 #define RTGUI_LISTCTRL_TYPE		(rtgui_listctrl_type_get())
-/** Casts the object to a filelist */
+/** Casts the object to a listctrl */
 #define RTGUI_LISTCTRL(obj)		(RTGUI_OBJECT_CAST((obj), RTGUI_LISTCTRL_TYPE, rtgui_listctrl_t))
-/** Checks if the object is a filelist ctrl */
+/** Checks if the object is a listctrl */
 #define RTGUI_IS_LISTCTRL(obj)	(RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_LISTCTRL_TYPE))
 
 struct rtgui_listctrl
@@ -40,7 +40,7 @@ struct rtgui_listctrl
     /* the number of item in a page */
     rt_uint16_t page_items;
     /* current item */
-    rt_uint16_t current_item;
+    rt_int16_t current_item;
 
 	/* item event handler */
 	void (*on_item)(rtgui_widget_t *widget, struct rtgui_event* event);

+ 12 - 6
components/rtgui/widgets/listbox.c

@@ -24,7 +24,7 @@ static void _rtgui_listbox_constructor(struct rtgui_listbox *box)
 
 	RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
 
-	box->current_item = 0;
+	box->current_item = -1;
 	box->items_count = 0;
 	box->page_items = 1;
 	box->on_item = 0;
@@ -71,7 +71,11 @@ void rtgui_listbox_ondraw(struct rtgui_listbox* box)
 	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
 
 	/* get current page */
-	page_index = (box->current_item / box->page_items) * box->page_items;
+	if (box->current_item == -1)
+		page_index = 0;
+	else
+		page_index = (box->current_item / box->page_items) * box->page_items;
+
 	for (index = 0; index < box->page_items; index ++)
 	{
 		if (page_index + index >= box->items_count) break;
@@ -103,13 +107,13 @@ void rtgui_listbox_ondraw(struct rtgui_listbox* box)
 	rtgui_dc_end_drawing(dc);
 }
 
-void rtgui_listbox_update_current(struct rtgui_listbox* box, rt_uint16_t old_item)
+static void rtgui_listbox_update_current(struct rtgui_listbox* box, rt_int16_t old_item)
 {
 	struct rtgui_dc* dc;
 	const struct rtgui_listbox_item* item;
 	rtgui_rect_t rect, item_rect;
 
-	if (old_item/box->page_items != box->current_item/box->page_items)
+	if ((old_item == -1) || (old_item/box->page_items != box->current_item/box->page_items))
 	{
 		/* it's not a same page, update all */
 		rtgui_widget_update(RTGUI_WIDGET(box));
@@ -258,9 +262,11 @@ rt_bool_t rtgui_listbox_event_handler(struct rtgui_widget* widget, struct rtgui_
             struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
             if ((ekbd->type == RTGUI_KEYDOWN) && (box->items_count > 0))
             {
-				rt_uint16_t old_item;
+				rt_int16_t old_item;
 
+				if (box->current_item == -1) return RT_FALSE;
 				old_item = box->current_item;
+
                 switch (ekbd->key)
                 {
 				case RTGUIK_LEFT:
@@ -343,7 +349,7 @@ void rtgui_listbox_set_items(rtgui_listbox_t* box, struct rtgui_listbox_item* it
 	
 	box->items = items;
 	box->items_count = count;
-	box->current_item = 0;
+	box->current_item = -1;
 
 	rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
 	box->page_items = rtgui_rect_height(rect) / (2 + rtgui_theme_get_selected_height());

+ 1 - 1
components/rtgui/widgets/listctrl.c

@@ -24,7 +24,7 @@ static void _rtgui_listctrl_constructor(struct rtgui_listctrl *ctrl)
 
 	RTGUI_WIDGET(ctrl)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
 
-	ctrl->current_item = 0;
+	ctrl->current_item = -1;
 	ctrl->items_count = 0;
 	ctrl->page_items = 0;
 	ctrl->on_item = 0;

+ 1 - 0
components/rtgui/widgets/widget.c

@@ -32,6 +32,7 @@ static void _rtgui_widget_constructor(rtgui_widget_t *widget)
 	widget->gc.foreground = default_foreground;
 	widget->gc.background = default_background;
 	widget->gc.font = rtgui_font_default();
+	widget->gc.textstyle = RTGUI_TEXTSTYLE_NORMAL;
 	widget->gc.textalign = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP;
 #ifndef RTGUI_USING_SMALL_SIZE
 	widget->align = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP;