Browse Source

fix dc_buffer code in small size mode.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@595 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 15 năm trước cách đây
mục cha
commit
ca6a1a7ecb
5 tập tin đã thay đổi với 130 bổ sung130 xóa
  1. 35 60
      rtgui/common/dc_buffer.c
  2. 49 0
      rtgui/common/dc_hw.c
  3. 3 50
      rtgui/common/image_hdc.c
  4. 1 20
      rtgui/include/rtgui/dc.h
  5. 42 0
      rtgui/include/rtgui/dc_hw.h

+ 35 - 60
rtgui/common/dc_buffer.c

@@ -13,6 +13,7 @@
  */
 #include <rtgui/rtgui.h>
 #include <rtgui/dc.h>
+#include <rtgui/dc_hw.h>
 #include <rtgui/color.h>
 #include <rtgui/rtgui_system.h>
 
@@ -251,89 +252,63 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc* self, struct rtgui_point* dc_p
 
 	if (dc_point == RT_NULL) dc_point = &rtgui_empty_point;
 
-	if (dest->type == RTGUI_DC_HW)
+	if ((dest->type == RTGUI_DC_HW) && rtgui_dc_get_visible(dest) == RT_TRUE)
 	{
-		register int index;
-		int fb_pitch;
-		rtgui_rect_t abs_rect;
+		rtgui_color_t* pixel;
+		rt_uint8_t *line_ptr;
+		rt_uint16_t rect_width, rect_height, index;
 		void (*blit_line)(rtgui_color_t* color, rt_uint8_t* dest, int line);
 
-		abs_rect.x1 = hw->owner->extent.x1 + rect->x1;
-		abs_rect.y1 = hw->owner->extent.y1 + rect->y1;
-		abs_rect.x2 = abs_rect.x1 + rtgui_rect_width(*rect);
-		abs_rect.y2 = abs_rect.y1 + rtgui_rect_height(*rect);
+		/* calculate correct width and height */
+		if (rtgui_rect_width(*rect) > (dc->width - dc_point->x))
+			rect_width = dc->width - dc_point->x;
+		else
+			rect_width = rtgui_rect_width(*rect);
 
-		/* hw fb pitch */
-		fb_pitch = hw->device->byte_per_pixel * hw->device->width;
-
-		/* hardware dc blit */
-		if (!rtgui_region_not_empty(&dc->clip) ||
-			dc->clip_sync != hw->owner->clip_sync)
-		{
-			/* should re-calculate clip */
-			rtgui_region_intersect_rect(&(dc->clip),
-				&(hw->owner->clip), &abs_rect);
-		}
+		if (rtgui_rect_height(*rect) > (dc->height - dc_point->y))
+			rect_height = dc->height - dc_point->y;
+		else
+			rect_height = rtgui_rect_height(*rect);
 
+		/* get blit line function */
 		switch (hw->device->byte_per_pixel)
 		{
 		case 1:
 			blit_line = rtgui_blit_line_1;
 			break;
+
 		case 2:
 			blit_line = rtgui_blit_line_2;
 			break;
-		case 3:
+
+		case 4:
 			blit_line = rtgui_blit_line_4;
 			break;
 
 		default:
-			/* can not blit */
+			/* not support byte per pixel */
 			return;
 		}
 
-		/* blit each clip rect */
-		if (dc->clip.data == RT_NULL)
-		{
-			int y;
-			rtgui_color_t* pixel;
-			rt_uint8_t* fb;
-
-			pixel = (rtgui_color_t*)(dc->pixel + (dc_point->y + dc->clip.extents.y1 - abs_rect.y1) * dc->pitch +
-				(dc_point->x + dc->clip.extents.x1 - abs_rect.x1) * sizeof(rtgui_color_t));
-			fb = hw->device->get_framebuffer() + dc->clip.extents.y1 * fb_pitch +
-				dc->clip.extents.x1 * hw->device->byte_per_pixel;
-
-			for (y = dc->clip.extents.y1; y < dc->clip.extents.y2; y ++)
-			{
-				blit_line(pixel, fb, dc->clip.extents.x2 - dc->clip.extents.x1);
-
-				fb += fb_pitch;
-				pixel += dc->width;
-			}
-		}
-		else for (index = 0; index < rtgui_region_num_rects(&(dc->clip)); index ++)
-		{
-			int y;
-			rtgui_rect_t* prect;
-			rtgui_color_t* pixel;
-			rt_uint8_t* fb;
-
-			prect = ((rtgui_rect_t *)(dc->clip.data + index + 1));
+		/* create line buffer */
+		line_ptr = (rt_uint8_t*) rtgui_malloc(rect_width * hw->device->byte_per_pixel);
 
-			pixel = (rtgui_color_t*)(dc->pixel + (dc_point->y + prect->y1 - abs_rect.y1) * dc->pitch +
-				(dc_point->x + prect->x1 - abs_rect.x1) * sizeof(rtgui_color_t));
-			fb = hw->device->get_framebuffer() + prect->y1 * fb_pitch +
-				prect->x1 * hw->device->byte_per_pixel;
+		/* prepare pixel line */
+		pixel = (rtgui_color_t*)(dc->pixel + dc_point->y * dc->pitch + dc_point->x * sizeof(rtgui_color_t));
 
-			for (y = prect->y1; y < prect->y2; y ++)
-			{
-				blit_line(pixel, fb, prect->x2 - prect->x1);
-
-				fb += fb_pitch;
-				pixel += dc->width;
-			}
+		/* draw each line */
+		for (index = rect->y1; index < rect->y1 + rect_height; index ++)
+		{
+			/* blit on line buffer */
+			blit_line(pixel, line_ptr, rect_width);
+			pixel += dc->width;
+
+			/* draw on hardware dc */
+			rtgui_dc_hw_draw_raw_hline(hw, line_ptr, rect->x1, rect->x1 + rect_width, index);
 		}
+
+		/* release line buffer */
+		rtgui_free(line_ptr);
 	}
 }
 

+ 49 - 0
rtgui/common/dc_hw.c

@@ -12,6 +12,7 @@
  * 2009-10-16     Bernard      first version
  */
 #include <rtgui/dc.h>
+#include <rtgui/dc_hw.h>
 #include <rtgui/driver.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/widgets/view.h>
@@ -436,3 +437,51 @@ static void rtgui_dc_hw_get_rect(struct rtgui_dc* self, rtgui_rect_t* rect)
 
 	rtgui_widget_get_rect(dc->owner, rect);
 }
+
+void rtgui_dc_hw_draw_raw_hline(struct rtgui_dc_hw* dc, rt_uint8_t* raw_ptr, int x1, int x2, int y)
+{
+	register rt_base_t index;
+	register rt_base_t bpp;
+
+	/* convert logic to device */
+	x1 = x1 + dc->owner->extent.x1;
+	x2 = x2 + dc->owner->extent.x1;
+	y  = y + dc->owner->extent.y1;
+
+	bpp = dc->device->byte_per_pixel;
+	if (dc->owner->clip.data == RT_NULL)
+	{
+		rtgui_rect_t* prect;
+
+		prect = &(dc->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 */
+		dc->device->draw_raw_hline(raw_ptr, x1, x2, y);
+	}
+	else for (index = 0; index < rtgui_region_num_rects(&(dc->owner->clip)); index ++)
+	{
+		rtgui_rect_t* prect;
+		register rt_base_t draw_x1, draw_x2;
+
+		prect = ((rtgui_rect_t *)(dc->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 */
+		dc->device->draw_raw_hline(raw_ptr + (draw_x1 - x1) * bpp, draw_x1, draw_x2, y);
+	}
+}

+ 3 - 50
rtgui/common/image_hdc.c

@@ -1,4 +1,5 @@
 #include <rtthread.h>
+#include <rtgui/dc_hw.h>
 #include <rtgui/image.h>
 #include <rtgui/rtgui_system.h>
 
@@ -129,54 +130,6 @@ static void rtgui_image_hdc_unload(struct rtgui_image* image)
 	}
 }
 
-static void rtgui_image_hdc_raw_hline(struct rtgui_dc_hw* dc, rt_uint8_t* raw_ptr, int x1, int x2, int y)
-{
-	register rt_base_t index;
-	register rt_base_t bpp;
-
-	/* convert logic to device */
-	x1 = x1 + dc->owner->extent.x1;
-	x2 = x2 + dc->owner->extent.x1;
-	y  = y + dc->owner->extent.y1;
-
-	bpp = dc->device->byte_per_pixel;
-	if (dc->owner->clip.data == RT_NULL)
-	{
-		rtgui_rect_t* prect;
-
-		prect = &(dc->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 */
-		dc->device->draw_raw_hline(raw_ptr, x1, x2, y);
-	}
-	else for (index = 0; index < rtgui_region_num_rects(&(dc->owner->clip)); index ++)
-	{
-		rtgui_rect_t* prect;
-		register rt_base_t draw_x1, draw_x2;
-
-		prect = ((rtgui_rect_t *)(dc->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 */
-		dc->device->draw_raw_hline(raw_ptr + (draw_x1 - x1) * bpp, draw_x1, draw_x2, y);
-	}
-}
-
 static void rtgui_image_hdc_blit(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* dst_rect)
 {
 	rt_uint16_t y, w, h;
@@ -207,7 +160,7 @@ static void rtgui_image_hdc_blit(struct rtgui_image* image, struct rtgui_dc* dc,
 
 		for (y = 0; y < h; y ++)
 		{
-			rtgui_image_hdc_raw_hline((struct rtgui_dc_hw*)dc, ptr, dst_rect->x1, dst_rect->x1 + w, dst_rect->y1 + y);
+			rtgui_dc_hw_draw_raw_hline((struct rtgui_dc_hw*)dc, ptr, dst_rect->x1, dst_rect->x1 + w, dst_rect->y1 + y);
 			ptr += hdc->pitch;
 		}
     }
@@ -226,7 +179,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)
 				break; /* read data failed */
 
-			rtgui_image_hdc_raw_hline((struct rtgui_dc_hw*)dc, ptr, dst_rect->x1,  dst_rect->x1 + w, dst_rect->y1 + y);
+			rtgui_dc_hw_draw_raw_hline((struct rtgui_dc_hw*)dc, ptr, dst_rect->x1,  dst_rect->x1 + w, dst_rect->y1 + y);
 		}
 
 		rtgui_free(ptr);

+ 1 - 20
rtgui/include/rtgui/dc.h

@@ -23,6 +23,7 @@ enum rtgui_dc_type
 {
 	RTGUI_DC_HW,
 	RTGUI_DC_BUFFER,
+	RTGUI_DC_IMLIB2,
 };
 
 /* the abstract device context */
@@ -57,30 +58,10 @@ struct rtgui_dc
 	rt_bool_t (*fini )(struct rtgui_dc* dc);
 };
 
-/* hardware device context */
-struct rtgui_dc_hw
-{
-	struct rtgui_dc parent;
-
-	/* widget owner */
-	rtgui_widget_t* owner;
-
-	/* visible */
-	rt_bool_t visible;
-
-	/* display driver */
-	struct rtgui_graphic_driver* device;
-};
-
 /* create a buffer dc */
 struct rtgui_dc* rtgui_dc_buffer_create(int width, int height);
 rt_uint8_t* rtgui_dc_buffer_get_pixel(struct rtgui_dc* dc);
 
-/* create a hardware dc */
-struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner);
-struct rtgui_dc* rtgui_dc_begin_drawing(rtgui_widget_t* owner);
-void rtgui_dc_end_drawing(struct rtgui_dc* dc);
-
 /* destroy a dc */
 void rtgui_dc_destory(struct rtgui_dc* dc);
 

+ 42 - 0
rtgui/include/rtgui/dc_hw.h

@@ -0,0 +1,42 @@
+/*
+ * File      : dc_buffer.h
+ * 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-04-10     Bernard      first version
+ */
+#ifndef __RTGUI_DC_HW_H__
+#define __RTGUI_DC_HW_H__
+
+#include <rtgui/dc.h>
+
+/* hardware device context */
+struct rtgui_dc_hw
+{
+	struct rtgui_dc parent;
+
+	/* widget owner */
+	rtgui_widget_t* owner;
+
+	/* visible */
+	rt_bool_t visible;
+
+	/* display driver */
+	struct rtgui_graphic_driver* device;
+};
+
+/* create a hardware dc */
+struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner);
+struct rtgui_dc* rtgui_dc_begin_drawing(rtgui_widget_t* owner);
+void rtgui_dc_end_drawing(struct rtgui_dc* dc);
+
+/* draw a hline with raw pixel data */
+void rtgui_dc_hw_draw_raw_hline(struct rtgui_dc_hw* dc, rt_uint8_t* raw_ptr, int x1, int x2, int y);
+
+#endif