فهرست منبع

add blit_line to DC.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@858 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 14 سال پیش
والد
کامیت
cf6882f35b

+ 21 - 2
components/rtgui/common/dc_buffer.c

@@ -44,6 +44,7 @@ static void rtgui_dc_buffer_draw_color_point(struct rtgui_dc* dc, int x, int y,
 static void rtgui_dc_buffer_draw_vline(struct rtgui_dc* dc, int x, int y1, int y2);
 static void rtgui_dc_buffer_draw_vline(struct rtgui_dc* dc, int x, int y1, int y2);
 static void rtgui_dc_buffer_draw_hline(struct rtgui_dc* dc, int x1, int x2, int y);
 static void rtgui_dc_buffer_draw_hline(struct rtgui_dc* dc, int x1, int x2, int y);
 static void rtgui_dc_buffer_fill_rect (struct rtgui_dc* dc, struct rtgui_rect* rect);
 static void rtgui_dc_buffer_fill_rect (struct rtgui_dc* dc, struct rtgui_rect* rect);
+static void rtgui_dc_buffer_blit_line(struct rtgui_dc* self, int x1, int x2, int y, rt_uint8_t* line_data);
 static void rtgui_dc_buffer_blit(struct rtgui_dc* self, struct rtgui_point* dc_point,
 static void rtgui_dc_buffer_blit(struct rtgui_dc* self, struct rtgui_point* dc_point,
 	struct rtgui_dc* dest, rtgui_rect_t* rect);
 	struct rtgui_dc* dest, rtgui_rect_t* rect);
 
 
@@ -60,6 +61,7 @@ const static struct rtgui_dc_engine dc_buffer_engine =
 	rtgui_dc_buffer_draw_vline,
 	rtgui_dc_buffer_draw_vline,
 	rtgui_dc_buffer_draw_hline,
 	rtgui_dc_buffer_draw_hline,
 	rtgui_dc_buffer_fill_rect,
 	rtgui_dc_buffer_fill_rect,
+	rtgui_dc_buffer_blit_line,
 	rtgui_dc_buffer_blit,
 	rtgui_dc_buffer_blit,
 
 
 	rtgui_dc_buffer_set_gc,
 	rtgui_dc_buffer_set_gc,
@@ -244,7 +246,7 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc* self, struct rtgui_point* dc_p
 			/* it's the same byte per pixel, draw it directly */
 			/* it's the same byte per pixel, draw it directly */
 			for (index = rect->y1; index < rect->y1 + rect_height; index++)
 			for (index = rect->y1; index < rect->y1 + rect_height; index++)
 			{
 			{
-				rtgui_dc_client_draw_raw_hline(hw, pixels, rect->x1, rect->x1 + rect_width, index);
+				dest->engine->blit_line(dest, rect->x1, rect->x1 + rect_width, index, pixels);
 				pixels += dc->width * sizeof(rtgui_color_t);
 				pixels += dc->width * sizeof(rtgui_color_t);
 			}
 			}
 		}
 		}
@@ -265,7 +267,7 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc* self, struct rtgui_point* dc_p
 				pixels += dc->width * sizeof(rtgui_color_t);
 				pixels += dc->width * sizeof(rtgui_color_t);
 
 
 				/* draw on hardware dc */
 				/* draw on hardware dc */
-				rtgui_dc_client_draw_raw_hline(hw, line_ptr, rect->x1, rect->x1 + rect_width, index);
+				dest->engine->blit_line(dest, rect->x1, rect->x1 + rect_width, index, line_ptr);
 			}
 			}
 
 
 			/* release line buffer */
 			/* release line buffer */
@@ -274,6 +276,23 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc* self, struct rtgui_point* dc_p
 	}
 	}
 }
 }
 
 
+static void rtgui_dc_buffer_blit_line(struct rtgui_dc* self, int x1, int x2, int y, rt_uint8_t* line_data)
+{
+	rtgui_color_t* color_ptr;
+	struct rtgui_dc_buffer* dc = (struct rtgui_dc_buffer*)self;
+
+	RT_ASSERT(dc != RT_NULL);
+	RT_ASSERT(line_data != RT_NULL);
+
+	/* out of range */
+	if ((x1 > dc->width) || (y > dc->height)) return;
+	/* check range */
+	if (x2 > dc->width) x2 = dc->width;
+
+	color_ptr = (rtgui_color_t*)(dc->pixel + y * dc->pitch + x1 * sizeof(rtgui_color_t));
+	rt_memcpy(color_ptr, line_data, (x2 - x1) * sizeof(rtgui_color_t));
+}
+
 static void rtgui_dc_buffer_set_gc(struct rtgui_dc* self, rtgui_gc_t *gc)
 static void rtgui_dc_buffer_set_gc(struct rtgui_dc* self, rtgui_gc_t *gc)
 {
 {
 	struct rtgui_dc_buffer* dc = (struct rtgui_dc_buffer*)self;
 	struct rtgui_dc_buffer* dc = (struct rtgui_dc_buffer*)self;

+ 55 - 53
components/rtgui/common/dc_client.c

@@ -28,6 +28,7 @@ static void rtgui_dc_client_draw_color_point(struct rtgui_dc* dc, int x, int y,
 static void rtgui_dc_client_draw_hline(struct rtgui_dc* dc, int x1, int x2, int y);
 static void rtgui_dc_client_draw_hline(struct rtgui_dc* dc, int x1, int x2, int y);
 static void rtgui_dc_client_draw_vline(struct rtgui_dc* dc, int x, int y1, int y2);
 static void rtgui_dc_client_draw_vline(struct rtgui_dc* dc, int x, int y1, int y2);
 static void rtgui_dc_client_fill_rect (struct rtgui_dc* dc, rtgui_rect_t* rect);
 static void rtgui_dc_client_fill_rect (struct rtgui_dc* dc, rtgui_rect_t* rect);
+static void rtgui_dc_client_blit_line (struct rtgui_dc* self, int x1, int x2, int y, rt_uint8_t* line_data);
 static void rtgui_dc_client_blit	  (struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect);
 static void rtgui_dc_client_blit	  (struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect);
 static void rtgui_dc_client_set_gc (struct rtgui_dc* dc, rtgui_gc_t *gc);
 static void rtgui_dc_client_set_gc (struct rtgui_dc* dc, rtgui_gc_t *gc);
 static rtgui_gc_t *rtgui_dc_client_get_gc (struct rtgui_dc* dc);
 static rtgui_gc_t *rtgui_dc_client_get_gc (struct rtgui_dc* dc);
@@ -62,6 +63,7 @@ const struct rtgui_dc_engine dc_client_engine =
 	rtgui_dc_client_draw_vline,
 	rtgui_dc_client_draw_vline,
 	rtgui_dc_client_draw_hline,
 	rtgui_dc_client_draw_hline,
 	rtgui_dc_client_fill_rect,
 	rtgui_dc_client_fill_rect,
+	rtgui_dc_client_blit_line,
 	rtgui_dc_client_blit,
 	rtgui_dc_client_blit,
 
 
 	rtgui_dc_client_set_gc,
 	rtgui_dc_client_set_gc,
@@ -413,6 +415,59 @@ static void rtgui_dc_client_fill_rect (struct rtgui_dc* self, struct rtgui_rect*
 	owner->gc.foreground = foreground;
 	owner->gc.foreground = foreground;
 }
 }
 
 
+static void rtgui_dc_client_blit_line (struct rtgui_dc* self, int x1, int x2, int y, rt_uint8_t* line_data)
+{
+	register rt_base_t index;
+	rtgui_widget_t *owner;
+
+	if (self == RT_NULL) return;
+
+	/* get owner */
+	owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
+	if (!RTGUI_WIDGET_IS_DC_VISIBLE(owner)) return;
+
+	/* convert logic to device */
+	x1 = x1 + owner->extent.x1;
+	x2 = x2 + owner->extent.x1;
+	y  = y + owner->extent.y1;
+
+	if (rtgui_region_is_flat(&(owner->clip)) == RT_EOK)
+	{
+		rtgui_rect_t* prect;
+
+		prect = &(owner->clip.extents);
+
+		/* calculate vline intersect */
+		if (prect->y1 > y  || prect->y2 <= y ) return;
+		if (prect->x2 <= x1 || prect->x1 > x2) return;
+
+		if (prect->x1 > x1) x1 = prect->x1;
+		if (prect->x2 < x2) x2 = prect->x2;
+
+		/* draw hline */
+		hw_driver->draw_raw_hline(line_data, x1, x2, y);
+	}
+	else for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++)
+	{
+		rtgui_rect_t* prect;
+		register rt_base_t draw_x1, draw_x2;
+
+		prect = ((rtgui_rect_t *)(owner->clip.data + index + 1));
+		draw_x1 = x1;
+		draw_x2 = x2;
+
+		/* calculate hline clip */
+		if (prect->y1 > y  || prect->y2 <= y ) continue;
+		if (prect->x2 <= x1 || prect->x1 > x2) continue;
+
+		if (prect->x1 > x1) draw_x1 = prect->x1;
+		if (prect->x2 < x2) draw_x2 = prect->x2;
+
+		/* draw hline */
+		hw_driver->draw_raw_hline(line_data, draw_x1, draw_x2, y);
+	}
+}
+
 static void rtgui_dc_client_blit(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect)
 static void rtgui_dc_client_blit(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect)
 {
 {
 	/* not blit in hardware dc */
 	/* not blit in hardware dc */
@@ -470,56 +525,3 @@ static void rtgui_dc_client_get_rect(struct rtgui_dc* self, rtgui_rect_t* rect)
 	rtgui_widget_get_rect(owner, rect);
 	rtgui_widget_get_rect(owner, rect);
 }
 }
 
 
-void rtgui_dc_client_draw_raw_hline(struct rtgui_dc* self, rt_uint8_t* raw_ptr, int x1, int x2, int y)
-{
-	register rt_base_t index;
-	rtgui_widget_t *owner;
-
-	if (self == RT_NULL) return;
-	
-	/* get owner */
-	owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
-	if (!RTGUI_WIDGET_IS_DC_VISIBLE(owner)) return;
-
-	/* convert logic to device */
-	x1 = x1 + owner->extent.x1;
-	x2 = x2 + owner->extent.x1;
-	y  = y + owner->extent.y1;
-
-	if (owner->clip.data == RT_NULL)
-	{
-		rtgui_rect_t* prect;
-
-		prect = &(owner->clip.extents);
-
-		/* calculate hline intersect */
-		if (prect->y1 > y  || prect->y2 <= y ) return;
-		if (prect->x2 <= x1 || prect->x1 > x2) return;
-
-		if (prect->x1 > x1) x1 = prect->x1;
-		if (prect->x2 < x2) x2 = prect->x2;
-
-		/* draw raw hline */
-		hw_driver->draw_raw_hline(raw_ptr, x1, x2, y);
-	}
-	else for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++)
-	{
-		rtgui_rect_t* prect;
-		register rt_base_t draw_x1, draw_x2;
-
-		prect = ((rtgui_rect_t *)(owner->clip.data + index + 1));
-		draw_x1 = x1;
-		draw_x2 = x2;
-
-		/* calculate hline clip */
-		if (prect->y1 > y  || prect->y2 <= y ) continue;
-		if (prect->x2 <= x1 || prect->x1 > x2) continue;
-
-		if (prect->x1 > x1) draw_x1 = prect->x1;
-		if (prect->x2 < x2) draw_x2 = prect->x2;
-
-		/* draw raw hline */
-		hw_driver->draw_raw_hline(raw_ptr + (draw_x1 - x1) * hw_driver->byte_per_pixel, draw_x1, draw_x2, y);
-	}
-}
-

+ 17 - 17
components/rtgui/common/dc_hw.c

@@ -25,6 +25,7 @@ static void rtgui_dc_hw_draw_color_point(struct rtgui_dc* dc, int x, int y, rtgu
 static void rtgui_dc_hw_draw_hline(struct rtgui_dc* dc, int x1, int x2, int y);
 static void rtgui_dc_hw_draw_hline(struct rtgui_dc* dc, int x1, int x2, int y);
 static void rtgui_dc_hw_draw_vline(struct rtgui_dc* dc, int x, int y1, int y2);
 static void rtgui_dc_hw_draw_vline(struct rtgui_dc* dc, int x, int y1, int y2);
 static void rtgui_dc_hw_fill_rect (struct rtgui_dc* dc, rtgui_rect_t* rect);
 static void rtgui_dc_hw_fill_rect (struct rtgui_dc* dc, rtgui_rect_t* rect);
+static void rtgui_dc_hw_blit_line (struct rtgui_dc* self, int x1, int x2, int y, rt_uint8_t* line_data);
 static void rtgui_dc_hw_blit	  (struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect);
 static void rtgui_dc_hw_blit	  (struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect);
 static void rtgui_dc_hw_set_gc (struct rtgui_dc* dc, rtgui_gc_t *gc);
 static void rtgui_dc_hw_set_gc (struct rtgui_dc* dc, rtgui_gc_t *gc);
 static rtgui_gc_t *rtgui_dc_hw_get_gc (struct rtgui_dc* dc);
 static rtgui_gc_t *rtgui_dc_hw_get_gc (struct rtgui_dc* dc);
@@ -46,6 +47,7 @@ const struct rtgui_dc_engine dc_hw_engine =
 	rtgui_dc_hw_draw_vline,
 	rtgui_dc_hw_draw_vline,
 	rtgui_dc_hw_draw_hline,
 	rtgui_dc_hw_draw_hline,
 	rtgui_dc_hw_fill_rect,
 	rtgui_dc_hw_fill_rect,
+	rtgui_dc_hw_blit_line,
 	rtgui_dc_hw_blit,
 	rtgui_dc_hw_blit,
 
 
 	rtgui_dc_hw_set_gc,
 	rtgui_dc_hw_set_gc,
@@ -304,6 +306,21 @@ static void rtgui_dc_hw_fill_rect (struct rtgui_dc* self, struct rtgui_rect* rec
 	}
 	}
 }
 }
 
 
+static void rtgui_dc_hw_blit_line (struct rtgui_dc* self, int x1, int x2, int y, rt_uint8_t* line_data)
+{
+	struct rtgui_dc_hw* dc;
+
+	RT_ASSERT(self != RT_NULL);
+	dc = (struct rtgui_dc_hw*) self;
+
+	/* convert logic to device */
+	x1 = x1 + dc->owner->extent.x1;
+	x2 = x2 + dc->owner->extent.x1;
+	y  = y + dc->owner->extent.y1;
+
+	dc->hw_driver->draw_raw_hline(line_data, x1, x2, y);
+}
+
 static void rtgui_dc_hw_blit(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect)
 static void rtgui_dc_hw_blit(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect)
 {
 {
 	/* not blit in hardware dc */
 	/* not blit in hardware dc */
@@ -353,20 +370,3 @@ static void rtgui_dc_hw_get_rect(struct rtgui_dc* self, rtgui_rect_t* rect)
 	/* get owner */
 	/* get owner */
 	rtgui_widget_get_rect(dc->owner, rect);
 	rtgui_widget_get_rect(dc->owner, rect);
 }
 }
-
-void rtgui_dc_hw_draw_raw_hline(struct rtgui_dc* self, rt_uint8_t* raw_ptr, int x1, int x2, int y)
-{
-	struct rtgui_dc_hw* dc;
-
-	RT_ASSERT(self != RT_NULL);
-	dc = (struct rtgui_dc_hw*) self;
-
-	/* convert logic to device */
-	x1 = x1 + dc->owner->extent.x1;
-	x2 = x2 + dc->owner->extent.x1;
-	y  = y + dc->owner->extent.y1;
-
-	/* draw raw hline */
-	dc->hw_driver->draw_raw_hline(raw_ptr, x1, x2, y);
-}
-

+ 100 - 55
components/rtgui/common/image_bmp.c

@@ -116,17 +116,58 @@ static rt_bool_t rtgui_image_bmp_check(struct rtgui_filerw* file)
 	return(is_bmp);
 	return(is_bmp);
 }
 }
 
 
+static struct rtgui_image_palette* rtgui_image_bmp_load_palette(struct rtgui_image_bmp_header* header, struct rtgui_filerw* src)
+{
+	/* Load the palette, if any */
+	rt_size_t i;
+	struct rtgui_image_palette* palette;
+
+	if (header->biClrUsed == 0)
+		header->biClrUsed = 1 << header->biBitCount;
+
+	palette = rtgui_image_palette_create(header->biClrUsed);
+	if (palette == RT_NULL) return RT_NULL;
+
+	if ( header->biSize == 12 )
+	{
+		rt_uint8_t r, g, b;
+		for ( i = 0; i < (int)header->biClrUsed; ++i )
+		{
+			rtgui_filerw_read(src, &b, 1, 1);
+			rtgui_filerw_read(src, &g, 1, 1);
+			rtgui_filerw_read(src, &r, 1, 1);
+			palette->colors[i] = RTGUI_RGB(r, g, b);
+		}
+	}
+	else
+	{
+		rt_uint8_t r, g, b, a;
+		for ( i = 0; i < (int)header->biClrUsed; ++i )
+		{
+			rtgui_filerw_read(src, &b, 1, 1);
+			rtgui_filerw_read(src, &g, 1, 1);
+			rtgui_filerw_read(src, &r, 1, 1);
+			rtgui_filerw_read(src, &a, 1, 1);
+			palette->colors[i] = RTGUI_ARGB(a, r, g, b);
+		}
+	}
+
+	return palette;
+}
+
 static rt_bool_t rtgui_image_bmp_load(struct rtgui_image* image, struct rtgui_filerw* src, rt_bool_t load)
 static rt_bool_t rtgui_image_bmp_load(struct rtgui_image* image, struct rtgui_filerw* src, rt_bool_t load)
 {
 {
-	struct rtgui_image_bmp* bmp;
-	struct rtgui_image_bmp_header* header;
-	int ExpandBMP, bmpPitch;
 	rt_uint32_t Rmask;
 	rt_uint32_t Rmask;
 	rt_uint32_t Gmask;
 	rt_uint32_t Gmask;
 	rt_uint32_t Bmask;
 	rt_uint32_t Bmask;
+	int ExpandBMP, bmpPitch;
+	struct rtgui_image_bmp* bmp;
+	struct rtgui_image_bmp_header* header;
+	struct rtgui_image_palette* palette;
 
 
 	bmp = RT_NULL;
 	bmp = RT_NULL;
 	header = RT_NULL;
 	header = RT_NULL;
+	palette = RT_NULL;
 	header = (struct rtgui_image_bmp_header*) rtgui_malloc(sizeof(struct rtgui_image_bmp_header));
 	header = (struct rtgui_image_bmp_header*) rtgui_malloc(sizeof(struct rtgui_image_bmp_header));
 	if (header == RT_NULL) return RT_FALSE;
 	if (header == RT_NULL) return RT_FALSE;
 
 
@@ -177,15 +218,26 @@ static rt_bool_t rtgui_image_bmp_load(struct rtgui_image* image, struct rtgui_fi
 
 
 	}
 	}
 
 
-	/* Expand 1 and 4 bit bitmaps to 8 bits per pixel */
+	/* allocate palette and expand 1 and 4 bit bitmaps to 8 bits per pixel */
 	switch (header->biBitCount)
 	switch (header->biBitCount)
 	{
 	{
 	case 1:
 	case 1:
+		ExpandBMP = header->biBitCount;
+		palette = rtgui_image_bmp_load_palette(header, src);
+		header->biBitCount = 8;
+		break;
+
 	case 4:
 	case 4:
 		ExpandBMP = header->biBitCount;
 		ExpandBMP = header->biBitCount;
+		palette = rtgui_image_bmp_load_palette(header, src);
 		header->biBitCount = 8;
 		header->biBitCount = 8;
 		break;
 		break;
 
 
+	case 8:
+		palette = rtgui_image_bmp_load_palette(header, src);
+		ExpandBMP = 0;
+		break;
+
 	default:
 	default:
 		ExpandBMP = 0;
 		ExpandBMP = 0;
 		break;
 		break;
@@ -259,39 +311,7 @@ static rt_bool_t rtgui_image_bmp_load(struct rtgui_image* image, struct rtgui_fi
 	bmp->pixel_offset = header->bfOffBits;
 	bmp->pixel_offset = header->bfOffBits;
 	bmp->Rmask = Rmask; bmp->Gmask = Gmask; bmp->Bmask = Bmask;
 	bmp->Rmask = Rmask; bmp->Gmask = Gmask; bmp->Bmask = Bmask;
 	bmp->ExpandBMP = ExpandBMP;
 	bmp->ExpandBMP = ExpandBMP;
-
-	/* Load the palette, if any */
-#if 0
-	if ( palette )
-	{
-		rt_size_t i;
-
-		if (header->biClrUsed == 0)
-			header->biClrUsed = 1 << header->biBitCount;
-
-		image->palette = rtgui_image_palette_create(header->biClrUsed);
-		if ( header->biSize == 12 )
-		{
-			for ( i = 0; i < (int)header->biClrUsed; ++i )
-			{
-				rtgui_filerw_read(src, &RTGUI_RGB_R(image->palette->colors[i]), 1, 1);
-				rtgui_filerw_read(src, &RTGUI_RGB_G(image->palette->colors[i]), 1, 1);
-				rtgui_filerw_read(src, &RTGUI_RGB_B(image->palette->colors[i]), 1, 1);
-				RTGUI_RGB_A(image->palette->colors[i]) = 0;
-			}
-		}
-		else
-		{
-			for ( i = 0; i < (int)header->biClrUsed; ++i )
-			{
-				rtgui_filerw_read(src, &RTGUI_RGB_R(image->palette->colors[i]), 1, 1);
-				rtgui_filerw_read(src, &RTGUI_RGB_G(image->palette->colors[i]), 1, 1);
-				rtgui_filerw_read(src, &RTGUI_RGB_B(image->palette->colors[i]), 1, 1);
-				rtgui_filerw_read(src, &RTGUI_RGB_A(image->palette->colors[i]), 1, 1);
-			}
-		}
-	}
-#endif
+	if (palette != RT_NULL) image->palette = palette;
 
 
 	/* get padding */
 	/* get padding */
 	switch (ExpandBMP)
 	switch (ExpandBMP)
@@ -379,6 +399,12 @@ static rt_bool_t rtgui_image_bmp_load(struct rtgui_image* image, struct rtgui_fi
 
 
 __exit:
 __exit:
 	rtgui_free(header);
 	rtgui_free(header);
+	if (palette != RT_NULL)
+	{
+		rtgui_free(palette);
+		image->palette = RT_NULL;
+	}
+
 	if (bmp != RT_NULL)
 	if (bmp != RT_NULL)
 		rtgui_free(bmp->pixels);
 		rtgui_free(bmp->pixels);
 	rtgui_free(bmp);
 	rtgui_free(bmp);
@@ -418,8 +444,6 @@ static void rtgui_image_bmp_blit(struct rtgui_image* image, struct rtgui_dc* dc,
 	bmp = (struct rtgui_image_bmp*) image->data;
 	bmp = (struct rtgui_image_bmp*) image->data;
 	RT_ASSERT(bmp != RT_NULL);
 	RT_ASSERT(bmp != RT_NULL);
 
 
-	if ((dc->type != RTGUI_DC_HW) && (dc->type != RTGUI_DC_CLIENT)) return;
-
 	/* the minimum rect */
 	/* the minimum rect */
 	if (image->w < rtgui_rect_width(*dst_rect)) w = image->w;
 	if (image->w < rtgui_rect_width(*dst_rect)) w = image->w;
 	else w = rtgui_rect_width(*dst_rect);
 	else w = rtgui_rect_width(*dst_rect);
@@ -438,34 +462,55 @@ static void rtgui_image_bmp_blit(struct rtgui_image* image, struct rtgui_dc* dc,
 			{
 			{
 				for (y = 0; y < h; y ++)
 				for (y = 0; y < h; y ++)
 				{
 				{
-					rtgui_dc_hw_draw_raw_hline(dc, ptr, 
+					dc->engine->blit_line(dc, 
 						dst_rect->x1, dst_rect->x1 + w,
 						dst_rect->x1, dst_rect->x1 + w,
-						dst_rect->y1 + y);
+						dst_rect->y1 + y, 
+						ptr);
 					ptr += bmp->pitch;
 					ptr += bmp->pitch;
 				}
 				}
 			}
 			}
 			else
 			else
 			{
 			{
-				rt_uint8_t *line_ptr;
-				rtgui_blit_line_func blit_line;
 				rt_size_t pitch;
 				rt_size_t pitch;
+				rt_uint8_t *line_ptr;
 
 
-				line_ptr = (rt_uint8_t*) rtgui_malloc(hw_driver->byte_per_pixel * w);
-				blit_line = rtgui_blit_line_get(hw_driver->byte_per_pixel , bmp->byte_per_pixel);
-				pitch = w * bmp->byte_per_pixel;
-				if (line_ptr != RT_NULL)
+				if (image->palette == RT_NULL)
 				{
 				{
-					for (y = 0; y < h; y ++)
+					rtgui_blit_line_func blit_line;
+					line_ptr = (rt_uint8_t*) rtgui_malloc(hw_driver->byte_per_pixel * w);
+					blit_line = rtgui_blit_line_get(hw_driver->byte_per_pixel , bmp->byte_per_pixel);
+					pitch = w * bmp->byte_per_pixel;
+					if (line_ptr != RT_NULL)
 					{
 					{
-						blit_line(line_ptr, ptr, pitch);
-						rtgui_dc_hw_draw_raw_hline(dc, line_ptr, 
-							dst_rect->x1, dst_rect->x1 + w,
-							dst_rect->y1 + y);
-						ptr += bmp->pitch;
+						for (y = 0; y < h; y ++)
+						{
+							blit_line(line_ptr, ptr, pitch);
+							dc->engine->blit_line(dc,
+								dst_rect->x1, dst_rect->x1 + w,
+								dst_rect->y1 + y, 
+								line_ptr);
+							ptr += bmp->pitch;
+						}
 					}
 					}
+					rtgui_free(line_ptr);
 				}
 				}
+				else
+				{
+					int x, p;
+					rtgui_color_t color;
 
 
-				rtgui_free(line_ptr);
+					/* use palette */
+					for (y = 0; y < h; y ++)
+					{
+						ptr = bmp->pixels + (y * bmp->pitch);
+						for (x = 0; x < w; x ++)
+						{
+							p = *ptr;
+							color = image->palette->colors[*ptr]; ptr ++;
+							rtgui_dc_draw_color_point(dc, dst_rect->x1 + x, dst_rect->y1 + y, color);
+						}
+					}
+				}
 			}
 			}
 		}
 		}
 	}
 	}
@@ -484,7 +529,7 @@ static void rtgui_image_bmp_blit(struct rtgui_image* image, struct rtgui_dc* dc,
 			if (rtgui_filerw_read(bmp->filerw, ptr, 1, bmp->pitch) != bmp->pitch)
 			if (rtgui_filerw_read(bmp->filerw, ptr, 1, bmp->pitch) != bmp->pitch)
 				break; /* read data failed */
 				break; /* read data failed */
 
 
-			rtgui_dc_client_draw_raw_hline(dc, ptr, dst_rect->x1,  dst_rect->x1 + w, dst_rect->y1 + y);
+			dc->engine->blit_line(dc, dst_rect->x1,  dst_rect->x1 + w, dst_rect->y1 + y, ptr);
 		}
 		}
 
 
 		rtgui_free(ptr);
 		rtgui_free(ptr);

+ 4 - 7
components/rtgui/common/image_hdc.c

@@ -155,8 +155,6 @@ static void rtgui_image_hdc_blit(struct rtgui_image* image, struct rtgui_dc* dc,
 	hdc = (struct rtgui_image_hdc*) image->data;
 	hdc = (struct rtgui_image_hdc*) image->data;
 	RT_ASSERT(hdc != RT_NULL);
 	RT_ASSERT(hdc != RT_NULL);
 
 
-	if ((dc->type != RTGUI_DC_HW) && (dc->type != RTGUI_DC_CLIENT)) return;
-
 	/* the minimum rect */
 	/* the minimum rect */
     if (image->w < rtgui_rect_width(*dst_rect)) w = image->w;
     if (image->w < rtgui_rect_width(*dst_rect)) w = image->w;
     else w = rtgui_rect_width(*dst_rect);
     else w = rtgui_rect_width(*dst_rect);
@@ -172,7 +170,7 @@ static void rtgui_image_hdc_blit(struct rtgui_image* image, struct rtgui_dc* dc,
 
 
 		for (y = 0; y < h; y ++)
 		for (y = 0; y < h; y ++)
 		{
 		{
-			rtgui_dc_client_draw_raw_hline(dc, ptr, dst_rect->x1, dst_rect->x1 + w, dst_rect->y1 + y);
+			dc->engine->blit_line(dc, dst_rect->x1, dst_rect->x1 + w, dst_rect->y1 + y, ptr);
 			ptr += hdc->pitch;
 			ptr += hdc->pitch;
 		}
 		}
     }
     }
@@ -191,7 +189,7 @@ static void rtgui_image_hdc_blit(struct rtgui_image* image, struct rtgui_dc* dc,
 			if (rtgui_filerw_read(hdc->filerw, ptr, 1, hdc->pitch) != hdc->pitch)
 			if (rtgui_filerw_read(hdc->filerw, ptr, 1, hdc->pitch) != hdc->pitch)
 				break; /* read data failed */
 				break; /* read data failed */
 
 
-			rtgui_dc_client_draw_raw_hline(dc, ptr, dst_rect->x1,  dst_rect->x1 + w, dst_rect->y1 + y);
+			dc->engine->blit_line(dc, dst_rect->x1,  dst_rect->x1 + w, dst_rect->y1 + y, ptr);
 		}
 		}
 
 
 		rtgui_free(ptr);
 		rtgui_free(ptr);
@@ -207,7 +205,7 @@ static void rtgui_image_hdcmm_blit(struct rtgui_image* image, struct rtgui_dc* d
 	RT_ASSERT(image != RT_NULL || dc != RT_NULL || dst_rect != RT_NULL);
 	RT_ASSERT(image != RT_NULL || dc != RT_NULL || dst_rect != RT_NULL);
 
 
 	/* this dc is not visible */
 	/* this dc is not visible */
-	if (rtgui_dc_get_visible(dc) != RT_TRUE || ((dc->type != RTGUI_DC_HW) && (dc->type != RTGUI_DC_CLIENT))) return;
+	if (rtgui_dc_get_visible(dc) != RT_TRUE) return;
 
 
 	hdc = (struct rtgui_image_hdcmm*) image;
 	hdc = (struct rtgui_image_hdcmm*) image;
 	RT_ASSERT(hdc != RT_NULL);
 	RT_ASSERT(hdc != RT_NULL);
@@ -224,7 +222,7 @@ static void rtgui_image_hdcmm_blit(struct rtgui_image* image, struct rtgui_dc* d
 
 
 	for (y = 0; y < h; y ++)
 	for (y = 0; y < h; y ++)
 	{
 	{
-		rtgui_dc_client_draw_raw_hline(dc, ptr, dst_rect->x1, dst_rect->x1 + w, dst_rect->y1 + y);
+		dc->engine->blit_line(dc, dst_rect->x1, dst_rect->x1 + w, dst_rect->y1 + y, ptr);
 		ptr += hdc->pitch;
 		ptr += hdc->pitch;
 	}
 	}
 }
 }
@@ -234,4 +232,3 @@ void rtgui_image_hdc_init()
 	/* register hdc on image system */
 	/* register hdc on image system */
 	rtgui_image_register_engine(&rtgui_image_hdc_engine);
 	rtgui_image_register_engine(&rtgui_image_hdc_engine);
 }
 }
-

+ 2 - 6
components/rtgui/include/rtgui/dc.h

@@ -35,6 +35,7 @@ struct rtgui_dc_engine
 	void (*draw_vline)(struct rtgui_dc* dc, int x, int y1, int y2);
 	void (*draw_vline)(struct rtgui_dc* dc, int x, int y1, int y2);
 	void (*draw_hline)(struct rtgui_dc* dc, int x1, int x2, int y);
 	void (*draw_hline)(struct rtgui_dc* dc, int x1, int x2, int y);
 	void (*fill_rect )(struct rtgui_dc* dc, rtgui_rect_t* rect);
 	void (*fill_rect )(struct rtgui_dc* dc, rtgui_rect_t* rect);
+	void (*blit_line) (struct rtgui_dc* dc, int x1, int x2, int y, rt_uint8_t* line_data);
 	void (*blit		 )(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect);
 	void (*blit		 )(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect);
 
 
 	/* set and get graphic context */
 	/* set and get graphic context */
@@ -153,8 +154,6 @@ rt_inline void rtgui_dc_fill_rect (struct rtgui_dc* dc, struct rtgui_rect* rect)
  */
  */
 rt_inline void rtgui_dc_blit(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect)
 rt_inline void rtgui_dc_blit(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect)
 {
 {
-	if (dest == RT_NULL || rect == RT_NULL) return;
-
 	dc->engine->blit(dc, dc_point, dest, rect);
 	dc->engine->blit(dc, dc_point, dest, rect);
 }
 }
 
 
@@ -187,10 +186,7 @@ rt_inline rt_bool_t rtgui_dc_get_visible(struct rtgui_dc* dc)
  */
  */
 rt_inline void rtgui_dc_get_rect(struct rtgui_dc*dc, rtgui_rect_t* rect)
 rt_inline void rtgui_dc_get_rect(struct rtgui_dc*dc, rtgui_rect_t* rect)
 {
 {
-	if (rect != RT_NULL)
-	{
-		dc->engine->get_rect(dc, rect);
-	}
+	dc->engine->get_rect(dc, rect);
 }
 }
 
 
 #endif
 #endif

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

@@ -23,8 +23,5 @@
 struct rtgui_dc* rtgui_dc_client_create(rtgui_widget_t* owner);
 struct rtgui_dc* rtgui_dc_client_create(rtgui_widget_t* owner);
 void rtgui_dc_client_init(rtgui_widget_t* owner);
 void rtgui_dc_client_init(rtgui_widget_t* owner);
 
 
-/* draw a hline with raw pixel data */
-void rtgui_dc_client_draw_raw_hline(struct rtgui_dc* dc, rt_uint8_t* raw_ptr, int x1, int x2, int y);
-
 #endif
 #endif
 
 

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

@@ -20,8 +20,5 @@
 /* create a hardware dc */
 /* create a hardware dc */
 struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner);
 struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner);
 
 
-/* draw a hline with raw pixel data */
-void rtgui_dc_hw_draw_raw_hline(struct rtgui_dc* dc, rt_uint8_t* raw_ptr, int x1, int x2, int y);
-
 #endif
 #endif