re-write Hardware DC implementation.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@849 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
bernard.xiong 2010-08-13 10:36:36 +00:00
parent 0c2f85b5fb
commit b1218f8c39
4 changed files with 41 additions and 129 deletions

View File

@ -13,7 +13,9 @@
* 2010-08-09 Bernard rename hardware dc to client dc
*/
#include <rtgui/dc.h>
#include <rtgui/dc_hw.h>
#include <rtgui/dc_client.h>
#include <rtgui/driver.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/widgets/view.h>
@ -39,12 +41,18 @@ static void rtgui_dc_client_get_rect(struct rtgui_dc* dc, rtgui_rect_t* rect);
struct rtgui_dc* rtgui_dc_begin_drawing(rtgui_widget_t* owner)
{
if (rtgui_region_is_flat(&owner->clip))
{
/* use hardware DC */
return rtgui_dc_hw_create(owner);
}
return rtgui_dc_client_create(owner);
}
void rtgui_dc_end_drawing(struct rtgui_dc* dc)
{
rtgui_dc_client_fini(dc);
dc->engine->fini(dc);
}
const struct rtgui_dc_engine dc_client_engine =

View File

@ -215,11 +215,8 @@ static void rtgui_dc_hw_draw_point(struct rtgui_dc* self, int x, int y)
x = x + owner->extent.x1;
y = y + owner->extent.y1;
if (rtgui_region_contains_point(&(owner->clip), x, y, &rect) == RT_EOK)
{
/* draw this point */
hw_driver->set_pixel(&(owner->gc.foreground), x, y);
}
/* draw this point */
hw_driver->set_pixel(&(owner->gc.foreground), x, y);
}
static void rtgui_dc_hw_draw_color_point(struct rtgui_dc* self, int x, int y, rtgui_color_t color)
@ -236,11 +233,8 @@ static void rtgui_dc_hw_draw_color_point(struct rtgui_dc* self, int x, int y, rt
x = x + owner->extent.x1;
y = y + owner->extent.y1;
if (rtgui_region_contains_point(&(owner->clip), x, y, &rect) == RT_EOK)
{
/* draw this point */
hw_driver->set_pixel(&color, x, y);
}
/* draw this point */
hw_driver->set_pixel(&color, x, y);
}
/*
@ -261,41 +255,8 @@ static void rtgui_dc_hw_draw_vline(struct rtgui_dc* self, int x, int y1, int y2)
y1 = y1 + owner->extent.y1;
y2 = y2 + owner->extent.y1;
if (owner->clip.data == RT_NULL)
{
rtgui_rect_t* prect;
prect = &(owner->clip.extents);
/* calculate vline intersect */
if (prect->x1 > x || prect->x2 <= x) return;
if (prect->y2 <= y1 || prect->y1 > y2) return;
if (prect->y1 > y1) y1 = prect->y1;
if (prect->y2 < y2) y2 = prect->y2;
/* draw vline */
hw_driver->draw_vline(&(owner->gc.foreground), x, y1, y2);
}
else for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++)
{
rtgui_rect_t* prect;
register rt_base_t draw_y1, draw_y2;
prect = ((rtgui_rect_t *)(owner->clip.data + index + 1));
draw_y1 = y1;
draw_y2 = y2;
/* calculate vline clip */
if (prect->x1 > x || prect->x2 <= x) continue;
if (prect->y2 <= y1 || prect->y1 > y2) continue;
if (prect->y1 > y1) draw_y1 = prect->y1;
if (prect->y2 < y2) draw_y2 = prect->y2;
/* draw vline */
hw_driver->draw_vline(&(owner->gc.foreground), x, draw_y1, draw_y2);
}
/* draw vline */
hw_driver->draw_vline(&(owner->gc.foreground), x, y1, y2);
}
/*
@ -317,69 +278,33 @@ static void rtgui_dc_hw_draw_hline(struct rtgui_dc* self, int x1, int x2, int y)
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 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_hline(&(owner->gc.foreground), 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_hline(&(owner->gc.foreground), draw_x1, draw_x2, y);
}
/* draw hline */
hw_driver->draw_hline(&(owner->gc.foreground), x1, x2, y);
}
static void rtgui_dc_hw_fill_rect (struct rtgui_dc* self, struct rtgui_rect* rect)
{
rtgui_color_t foreground;
register rt_base_t index;
rtgui_color_t color;
register rt_base_t index, x1, x2;
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;
/* save foreground color */
foreground = owner->gc.foreground;
/* set background color as foreground color */
owner->gc.foreground = owner->gc.background;
/* get background color */
color = owner->gc.background;
/* convert logic to device */
x1 = rect->x1 + owner->extent.x1;
x2 = rect->x2 + owner->extent.x1;
/* fill rect */
for (index = rect->y1; index < rect->y2; index ++)
for (index = owner->extent.y1 + rect->y1; index < owner->extent.y1 + rect->y2; index ++)
{
rtgui_dc_hw_draw_hline(self, rect->x1, rect->x2, index);
hw_driver->draw_hline(&color, x1, x2, index);
}
/* restore foreground color */
owner->gc.foreground = foreground;
}
static void rtgui_dc_hw_blit(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect)
@ -455,40 +380,7 @@ void rtgui_dc_hw_draw_raw_hline(struct rtgui_dc* self, rt_uint8_t* raw_ptr, int
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);
}
/* draw raw hline */
hw_driver->draw_raw_hline(raw_ptr, x1, x2, y);
}

View File

@ -2128,6 +2128,17 @@ void rtgui_region_dump(rtgui_region_t* region)
}
}
int rtgui_region_is_flat(rtgui_region_t* region)
{
int num;
num = PIXREGION_NUM_RECTS(region);
if (num == 1) return RT_EOK;
return -RT_ERROR;
}
void rtgui_rect_moveto(rtgui_rect_t *rect, int x, int y)
{
rect->x1 += x;

View File

@ -82,6 +82,7 @@ rtgui_region_status_t rtgui_region_validate (rtgui_region_t *badreg, int *pOverl
void rtgui_region_reset(rtgui_region_t *region, rtgui_rect_t* rect);
void rtgui_region_empty (rtgui_region_t *region);
void rtgui_region_dump(rtgui_region_t* region);
int rtgui_region_is_flat(rtgui_region_t* region);
/* rect functions */
extern rtgui_rect_t rtgui_empty_rect;