From b1218f8c394dc4b58d5d06f92bb0f59a32eb9cf4 Mon Sep 17 00:00:00 2001 From: "bernard.xiong" Date: Fri, 13 Aug 2010 10:36:36 +0000 Subject: [PATCH] re-write Hardware DC implementation. git-svn-id: https://rt-thread.googlecode.com/svn/trunk@849 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- components/rtgui/common/dc_client.c | 10 +- components/rtgui/common/dc_hw.c | 148 ++++-------------------- components/rtgui/common/region.c | 11 ++ components/rtgui/include/rtgui/region.h | 1 + 4 files changed, 41 insertions(+), 129 deletions(-) diff --git a/components/rtgui/common/dc_client.c b/components/rtgui/common/dc_client.c index 6a87cc8af3..0370b5e0d8 100644 --- a/components/rtgui/common/dc_client.c +++ b/components/rtgui/common/dc_client.c @@ -13,7 +13,9 @@ * 2010-08-09 Bernard rename hardware dc to client dc */ #include +#include #include + #include #include #include @@ -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 = diff --git a/components/rtgui/common/dc_hw.c b/components/rtgui/common/dc_hw.c index f403daecd9..46ef311ec1 100644 --- a/components/rtgui/common/dc_hw.c +++ b/components/rtgui/common/dc_hw.c @@ -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); } diff --git a/components/rtgui/common/region.c b/components/rtgui/common/region.c index 42ac6cd121..9fee345e1f 100644 --- a/components/rtgui/common/region.c +++ b/components/rtgui/common/region.c @@ -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; diff --git a/components/rtgui/include/rtgui/region.h b/components/rtgui/include/rtgui/region.h index c822212bff..38d50a1f85 100644 --- a/components/rtgui/include/rtgui/region.h +++ b/components/rtgui/include/rtgui/region.h @@ -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; -- GitLab