Browse Source

gui 引擎代码更新;

yangfasheng 7 years ago
parent
commit
2d98c0e7be

+ 3 - 0
components/gui/include/rtgui/dc.h

@@ -121,6 +121,8 @@ struct rtgui_dc_buffer
     struct rtgui_image_item *image_item;
 #endif
 
+	/* pixel alpha */
+    rt_uint8_t pixel_alpha;
     /* pixel data */
     rt_uint8_t *pixel;
 };
@@ -138,6 +140,7 @@ struct rtgui_dc *rtgui_img_dc_create_pixformat(rt_uint8_t pixel_format, rt_uint8
     struct rtgui_image_item *image_item);
 #endif
 struct rtgui_dc *rtgui_dc_buffer_create_from_dc(struct rtgui_dc* dc);
+void rtgui_dc_buffer_set_alpha(struct rtgui_dc* dc, rt_uint8_t pixel_alpha);
 
 /* create a widget dc */
 struct rtgui_dc *rtgui_dc_widget_create(struct rtgui_widget * owner);

+ 1 - 0
components/gui/include/rtgui/event.h

@@ -329,6 +329,7 @@ enum rtgui_gesture_type
     RTGUI_GESTURE_PINCH     = 0x0002,
     RTGUI_GESTURE_DRAG      = 0x0004,
     RTGUI_GESTURE_LONGPRESS = 0x0008,
+	RTGUI_GESTURE_DRAGGED   = 0x0001 | 0x0004 | 0x0008,
     /* PINCH, DRAG finished. */
     RTGUI_GESTURE_FINISH    = 0x8000,
     /* The corresponding gesture should be canceled. */

+ 1 - 0
components/gui/include/rtgui/font_freetype.h

@@ -27,6 +27,7 @@
 
 #include <rtgui/dc.h>
 #include <rtgui/font.h>
+#include <rtgui/filerw.h>
 
 #ifdef __cplusplus
 extern "C" {

+ 3 - 3
components/gui/include/rtgui/region.h

@@ -99,9 +99,9 @@ int rtgui_region_is_flat(rtgui_region_t *region);
 /* rect functions */
 extern rtgui_rect_t rtgui_empty_rect;
 
-void rtgui_rect_moveto(rtgui_rect_t *rect, int x, int y);
-void rtgui_rect_moveto_point(rtgui_rect_t *rect, int x, int y);
-void rtgui_rect_moveto_align(const rtgui_rect_t *rect, rtgui_rect_t *to, int align);
+void rtgui_rect_move(rtgui_rect_t *rect, int x, int y);
+void rtgui_rect_move_to_point(rtgui_rect_t *rect, int x, int y);
+void rtgui_rect_move_to_align(const rtgui_rect_t *rect, rtgui_rect_t *to, int align);
 void rtgui_rect_inflate(rtgui_rect_t *rect, int d);
 void rtgui_rect_intersect(rtgui_rect_t *src, rtgui_rect_t *dest);
 int  rtgui_rect_contains_point(const rtgui_rect_t *rect, int x, int y);

+ 2 - 1
components/gui/include/rtgui/rtgui.h

@@ -158,6 +158,7 @@ enum RTGUI_ALIGN
     RTGUI_ALIGN_CENTER              = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL,
     RTGUI_ALIGN_EXPAND              = 0x10,
     RTGUI_ALIGN_STRETCH             = 0x20,
+    RTGUI_ALIGN_TTF_SIZE			= 0x40,
 };
 
 enum RTGUI_TEXTSTYLE
@@ -172,7 +173,7 @@ enum RTGUI_MODAL_CODE
 {
     RTGUI_MODAL_OK,
     RTGUI_MODAL_CANCEL,
-    RTGUI_MODAL_MAX = 0xFFFF,
+    RTGUI_MODAL_MAX = 0xFFFFFFFF,
 };
 typedef enum RTGUI_MODAL_CODE rtgui_modal_code_t;
 

+ 8 - 0
components/gui/include/rtgui/widgets/window.h

@@ -88,6 +88,9 @@ struct rtgui_win
     /* inherit from container */
     rtgui_container_t parent;
 
+	/* update count */
+	rt_base_t update;
+
     /* drawing count */
     rt_base_t drawing;
     struct rtgui_rect drawing_rect;
@@ -137,6 +140,11 @@ struct rtgui_win
 
     /* Private data. */
     rt_base_t (*_do_show)(struct rtgui_win *win);
+	
+	/* app ref_count */
+	rt_uint16_t app_ref_count;
+	/* win magic flag, magic value is 0xA5A55A5A */
+	rt_uint32_t	magic;
 };
 
 rtgui_win_t *rtgui_win_create(struct rtgui_win *parent_window, const char *title,

+ 47 - 25
components/gui/src/blit.c

@@ -530,7 +530,7 @@ static void rtgui_blit_line_2_3(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int li
 
 void rtgui_blit_line_direct(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
 {
-    rt_memcpy(dst_ptr, src_ptr, line);
+    memcpy(dst_ptr, src_ptr, line);
 }
 
 /* convert 4bpp to 3bpp */
@@ -781,7 +781,7 @@ Blit565to565PixelAlpha(struct rtgui_blit_info * info)
 
         while (height--)
         {
-            rt_memcpy(dstp, srcp, len);
+            memcpy(dstp, srcp, len);
             dstp += info->dst_skip + len;
             srcp += info->src_skip + len;
         }
@@ -804,7 +804,7 @@ Blit565to565PixelAlpha(struct rtgui_blit_info * info)
 
         while (height--)
         {
-            DUFFS_LOOP4(
+            DUFFS_LOOP8(
             {
                 rt_uint32_t s = *srcp++;
                 rt_uint32_t d = *dstp;
@@ -927,10 +927,12 @@ static void BlitAlphato565PixelAlpha(struct rtgui_blit_info * info)
         while (n--)
         {
             srcA = (rt_uint8_t)(*src);
+            if (info->a > 0 && info->a != 255)
+                srcA = srcA * info->a / 255;
             ARGB8888_FROM_RGBA(srcpixel, srcR, srcG, srcB, srcA);
 
             /* not do alpha blend */
-            if (srcA == 255)
+            if ((srcA >> 3) == (255 >> 3) || info->a == 0)
             {
                 dstpixel = srcpixel;
             }
@@ -940,13 +942,15 @@ static void BlitAlphato565PixelAlpha(struct rtgui_blit_info * info)
             }
             else
             {
-                dstpixel = ((rt_uint32_t)srcA << 24) | ((rt_uint32_t)srcR << 16) | ((rt_uint32_t)srcG << 8) | srcB;
+                dstpixel = srcpixel;
             }
 
             if (srcA >> 3 != 0)
             {
                 rt_uint32_t s = dstpixel;
-                unsigned alpha = s >> 27;
+                unsigned alpha = s >> 24;
+                //alpha = alpha + ((255 - alpha) * alpha) / 255;
+                alpha = alpha >> 3;
                 if (alpha)
                 {
                     if (alpha == (255 >> 3))
@@ -995,14 +999,17 @@ static void BlitARGBto565PixelAlpha(struct rtgui_blit_info * info)
         DUFFS_LOOP4(
         {
             rt_uint32_t s = *srcp;
-            unsigned alpha = s >> 27; /* downscale alpha to 5 bits */
+            unsigned alpha = s >> 24;
+            if (info->a > 0 && info->a != 255)
+                alpha = alpha * info->a / 255;
+            alpha = alpha >> 3;	/* downscale alpha to 5 bits */
             /* FIXME: Here we special-case opaque alpha since the
                compositioning used (>>8 instead of /255) doesn't handle
                it correctly. Also special-case alpha=0 for speed?
                Benchmark this! */
             if(alpha)
             {
-                if(alpha == (255 >> 3))
+                if(alpha == (255 >> 3) || info->a == 0)
                 {
                     *dstp = (rt_uint16_t)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3  & 0x1f));
                 }
@@ -1031,7 +1038,7 @@ static void BlitARGBto565PixelAlpha(struct rtgui_blit_info * info)
 }
 
 /* fast ARGB888->(A)RGB888 blending with pixel alpha */
-static void BlitRGBtoRGBPixelAlpha(struct rtgui_blit_info *info)
+static void BlitARGBtoRGBPixelAlpha(struct rtgui_blit_info *info)
 {
     int width = info->dst_w;
     int height = info->dst_h;
@@ -1051,15 +1058,18 @@ static void BlitRGBtoRGBPixelAlpha(struct rtgui_blit_info *info)
             rt_uint32_t s = *srcp;
             rt_uint32_t alpha = s >> 24;
 
+            if (info->a > 0 && info->a != 255)
+                alpha = alpha * info->a / 255;
             /* FIXME: Here we special-case opaque alpha since the
                compositioning used (>>8 instead of /255) doesn't handle
                it correctly. Also special-case alpha=0 for speed?
                Benchmark this! */
-            if(alpha == 255)
+            if(alpha == 255 || info->a == 0)
             {
                 *dstp = (s & 0x00ffffff) | (*dstp & 0xff000000);
             }
-            else {
+            else
+            {
                 /*
                  * take out the middle component (green), and process
                  * the other two in parallel. One multiply less.
@@ -1101,10 +1111,12 @@ static void BlitAlphatoARGB8888PixelAlpha(struct rtgui_blit_info *info)
         while (n--)
         {
             srcA = (rt_uint8_t)(*src);
+            if (info->a > 0 && info->a != 255)
+                srcA = srcA * info->a / 255;
             ARGB8888_FROM_RGBA(srcpixel, srcR, srcG, srcB, srcA);
 
             /* not do alpha blend */
-            if (srcA == 255)
+            if (srcA == 255 || info->a == 0)
             {
                 *dst = srcpixel;
             }
@@ -1125,6 +1137,8 @@ static void BlitAlphatoARGB8888PixelAlpha(struct rtgui_blit_info *info)
                     int alpha = srcA + 1;
                     int inverse_alpha = 257 - alpha;
 
+                    //alpha = alpha + ((256 - alpha) * alpha) / 256;
+
                     dstR = ((srcR * alpha) + (inverse_alpha * dstR)) >> 8;
                     dstG = ((srcG * alpha) + (inverse_alpha * dstG)) >> 8;
                     dstB = ((srcB * alpha) + (inverse_alpha * dstB)) >> 8;
@@ -1165,9 +1179,11 @@ static void BlitARGB8888toARGB8888PixelAlpha(struct rtgui_blit_info *info)
         {
             srcpixel = *src;
             srcA = (rt_uint8_t)(srcpixel >> 24);
+            if (info->a > 0 && info->a != 255)
+                srcA = srcA * info->a / 255;
 
             /* not do alpha blend */
-            if (srcA == 255)
+            if (srcA == 255 || info->a == 0)
             {
                 *dst = srcpixel;
             }
@@ -1186,6 +1202,7 @@ static void BlitARGB8888toARGB8888PixelAlpha(struct rtgui_blit_info *info)
                 dstG = (rt_uint8_t)(dstpixel >> 8);
                 dstB = (rt_uint8_t)dstpixel;
 
+                if (dstA >> 3 != 0)
                 {
                     int alpha = srcA + 1;
                     int inverse_alpha = 257 - alpha;
@@ -1194,9 +1211,14 @@ static void BlitARGB8888toARGB8888PixelAlpha(struct rtgui_blit_info *info)
                     dstG = ((srcG * alpha) + (inverse_alpha * dstG)) >> 8;
                     dstB = ((srcB * alpha) + (inverse_alpha * dstB)) >> 8;
                     dstA = srcA + ((255 - srcA) * dstA) / 255;
+
+                    dstpixel = ((rt_uint32_t)dstA << 24) | ((rt_uint32_t)dstR << 16) | ((rt_uint32_t)dstG << 8) | dstB;
+                }
+                else
+                {
+                    dstpixel = srcpixel;
                 }
 
-                dstpixel = ((rt_uint32_t)dstA << 24) | ((rt_uint32_t)dstR << 16) | ((rt_uint32_t)dstG << 8) | dstB;
                 *dst = dstpixel;
             }
 
@@ -1211,7 +1233,7 @@ static void BlitARGB8888toARGB8888PixelAlpha(struct rtgui_blit_info *info)
 /* Special optimized blit for RGB 5-6-5 --> 32-bit RGB surfaces */
 #define RGB565_32(dst, src, map) (map[src[LO]*2] + map[src[HI]*2+1])
 static void
-BlitRGB565to32(struct rtgui_blit_info * info, const rt_uint32_t* map)
+BlitRGB565to32(struct rtgui_blit_info *info, const rt_uint32_t *map)
 {
     int width, height;
     rt_uint8_t *src;
@@ -1287,7 +1309,7 @@ void rtgui_blit(struct rtgui_blit_info * info)
             BlitARGBto565PixelAlpha(info);
             break;
         case RTGRAPHIC_PIXEL_FORMAT_RGB888:
-            BlitRGBtoRGBPixelAlpha(info);
+            BlitARGBtoRGBPixelAlpha(info);
             break;
         case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
             BlitARGB8888toARGB8888PixelAlpha(info);
@@ -1316,16 +1338,16 @@ void rtgui_blit(struct rtgui_blit_info * info)
 }
 RTM_EXPORT(rtgui_blit);
 
-void rtgui_image_info_blit(struct rtgui_image_info* image, struct rtgui_dc* dc, struct rtgui_rect *dc_rect)
+void rtgui_image_info_blit(struct rtgui_image_info *image, struct rtgui_dc *dc, struct rtgui_rect *dc_rect)
 {
     rt_uint8_t bpp, hw_bpp;
-    struct rtgui_widget *owner;
-    struct rtgui_blit_info info;
-    struct rtgui_rect dest_extent;
-    struct rtgui_graphic_driver *hw_driver;
+    struct rtgui_widget *owner;		//目标控件
+    struct rtgui_blit_info info = { 0 };
+    struct rtgui_rect dest_extent;	//相片大小
+    struct rtgui_graphic_driver *hw_driver;	//目标设备
 
-    hw_driver = rtgui_graphic_driver_get_default();
-    dest_extent = *dc_rect;
+    hw_driver = rtgui_graphic_driver_get_default(); //获取目标设备指针
+    dest_extent = *dc_rect;	//接收图片大小值
 
     if (dc->type == RTGUI_DC_CLIENT && hw_driver->framebuffer)
     {
@@ -1333,8 +1355,8 @@ void rtgui_image_info_blit(struct rtgui_image_info* image, struct rtgui_dc* dc,
         struct rtgui_rect *rects;
         struct rtgui_region dest_region;
 
-        bpp = rtgui_color_get_bpp(image->src_fmt);
-        hw_bpp = rtgui_color_get_bpp(hw_driver->pixel_format);
+        bpp = rtgui_color_get_bpp(image->src_fmt);				//获取图片一个像素点数据所占的字节数
+        hw_bpp = rtgui_color_get_bpp(hw_driver->pixel_format);	//获取目标设备一个像素点数据所占的字节数
 
         owner = RTGUI_CONTAINER_OF(dc, struct rtgui_widget, dc_type);
         rtgui_widget_rect_to_device(owner, &dest_extent);

+ 3 - 3
components/gui/src/box.c

@@ -117,7 +117,7 @@ static void rtgui_box_layout_vertical(struct rtgui_box *box, struct rtgui_rect *
         rtgui_rect_init(rect, 0, 0, widget->min_width, widget->min_height);
 
         /* left in default */
-        rtgui_rect_moveto(rect, next_x, next_y);
+        rtgui_rect_move(rect, next_x, next_y);
 
         if (widget->align & RTGUI_ALIGN_EXPAND)
         {
@@ -212,12 +212,12 @@ static void rtgui_box_layout_horizontal(struct rtgui_box *box, struct rtgui_rect
         rect = &(widget->extent);
 
         /* reset rect */
-        rtgui_rect_moveto(rect, -rect->x1, -rect->y1);
+        rtgui_rect_move(rect, -rect->x1, -rect->y1);
         rect->x2 = widget->min_width;
         rect->y2 = widget->min_height;
 
         /* top in default */
-        rtgui_rect_moveto(rect, next_x, next_y);
+        rtgui_rect_move(rect, next_x, next_y);
 
         if (widget->align & RTGUI_ALIGN_EXPAND)
         {

+ 8 - 10
components/gui/src/dc.c

@@ -313,7 +313,6 @@ void rtgui_dc_draw_text(struct rtgui_dc *dc, const char *text, struct rtgui_rect
 {
     rt_uint32_t len;
     struct rtgui_font *font;
-    struct rtgui_rect text_rect;
 
     RT_ASSERT(dc != RT_NULL);
 
@@ -324,12 +323,11 @@ void rtgui_dc_draw_text(struct rtgui_dc *dc, const char *text, struct rtgui_rect
         font = rtgui_font_default();
     }
 
-    /* text align */
-    rtgui_font_get_metrics(font, text, &text_rect);
-    rtgui_rect_moveto_align(rect, &text_rect, RTGUI_DC_TEXTALIGN(dc));
-
     len = strlen((const char *)text);
-    rtgui_font_draw(font, dc, text, len, &text_rect);
+	if (len == 0)
+		return;
+	
+    rtgui_font_draw(font, dc, text, len, rect);
 }
 RTM_EXPORT(rtgui_dc_draw_text);
 
@@ -349,7 +347,7 @@ void rtgui_dc_draw_text_stroke(struct rtgui_dc *dc, const char *text, struct rtg
         for (y = -1; y < 2; y++)
         {
             r = *rect;
-            rtgui_rect_moveto(&r, x, y);
+            rtgui_rect_move(&r, x, y);
             rtgui_dc_draw_text(dc, text, &r);
         }
     }
@@ -1781,7 +1779,7 @@ void rtgui_dc_rect_to_device(struct rtgui_dc *dc, struct rtgui_rect *rect)
         /* get owner */
         owner = RTGUI_CONTAINER_OF(dc, struct rtgui_widget, dc_type);
 
-        rtgui_rect_moveto(rect, owner->extent.x1, owner->extent.y1);
+        rtgui_rect_move(rect, owner->extent.x1, owner->extent.y1);
         break;
     }
     case RTGUI_DC_HW:
@@ -1791,7 +1789,7 @@ void rtgui_dc_rect_to_device(struct rtgui_dc *dc, struct rtgui_rect *rect)
 
         dc_hw = (struct rtgui_dc_hw *) dc;
         owner = dc_hw->owner;
-        rtgui_rect_moveto(rect, owner->extent.x1, owner->extent.y1);
+        rtgui_rect_move(rect, owner->extent.x1, owner->extent.y1);
         break;
     }
 
@@ -1920,7 +1918,7 @@ void rtgui_dc_end_drawing(struct rtgui_dc *dc, rt_bool_t update)
             RTGUI_OBJECT(win)->event_handler(RTGUI_OBJECT(win), (struct rtgui_event *)&ewin_update);
         }
 
-        if (rtgui_graphic_driver_is_vmode() == RT_FALSE && update)
+        if (rtgui_graphic_driver_is_vmode() == RT_FALSE && win->update == 0 && update)
         {
 #ifdef RTGUI_USING_MOUSE_CURSOR
             rt_mutex_release(&cursor_mutex);

+ 19 - 4
components/gui/src/dc_blend.c

@@ -1651,7 +1651,7 @@ rtgui_dc_blend_fill_rect(struct rtgui_dc* dst, const rtgui_rect_t *rect,
 
             /* convert logic to device */
             draw_rect = *rect;
-            rtgui_rect_moveto(&draw_rect,owner->extent.x1, owner->extent.y1);
+            rtgui_rect_move(&draw_rect,owner->extent.x1, owner->extent.y1);
 
             /* calculate rect intersect */
             if (prect->y1 > draw_rect.y2  || prect->y2 <= draw_rect.y1) return ;
@@ -1669,7 +1669,7 @@ rtgui_dc_blend_fill_rect(struct rtgui_dc* dst, const rtgui_rect_t *rect,
                 prect = ((rtgui_rect_t *)(owner->clip.data + index + 1));
 
                 draw_rect = *rect;
-                rtgui_rect_moveto(&draw_rect,owner->extent.x1, owner->extent.y1);
+                rtgui_rect_move(&draw_rect,owner->extent.x1, owner->extent.y1);
 
                 /* calculate rect intersect */
                 if (prect->y1 > draw_rect.y2  || prect->y2 <= draw_rect.y1) continue;
@@ -1680,6 +1680,21 @@ rtgui_dc_blend_fill_rect(struct rtgui_dc* dst, const rtgui_rect_t *rect,
             }
         }
     }
+    else if (dst->type == RTGUI_DC_HW)
+    {
+        rtgui_rect_t draw_rect = *rect;
+        struct rtgui_dc_hw *dc = (struct rtgui_dc_hw *) dst;
+
+        draw_rect.x2 = dc->owner->extent.x1 + draw_rect.x2 - draw_rect.x1;
+        draw_rect.y2 = dc->owner->extent.y1 + draw_rect.y2 - draw_rect.y1;
+
+        draw_rect.x1 = dc->owner->extent.x1 > 0 ? dc->owner->extent.x1 : 0;
+        draw_rect.y1 = dc->owner->extent.y1 > 0 ? dc->owner->extent.y1 : 0;
+		draw_rect.x2 = draw_rect.x2 > hw_driver->width ? hw_driver->width : draw_rect.x2;
+		draw_rect.y2 = draw_rect.y2 > hw_driver->height ? hw_driver->height : draw_rect.y2;
+
+        func(dst, &draw_rect, blendMode, r, g, b, a);
+    }
     else
     {
         func(dst, rect, blendMode, r, g, b, a);
@@ -1764,7 +1779,7 @@ rtgui_dc_blend_fill_rects(struct rtgui_dc * dst, const rtgui_rect_t *rects, int
 
                 /* convert logic to device */
                 draw_rect = rect;
-                rtgui_rect_moveto(&draw_rect,owner->extent.x1, owner->extent.y1);
+                rtgui_rect_move(&draw_rect,owner->extent.x1, owner->extent.y1);
 
                 /* calculate rect intersect */
                 if (prect->y1 > draw_rect.y2  || prect->y2 <= draw_rect.y1) return ;
@@ -1782,7 +1797,7 @@ rtgui_dc_blend_fill_rects(struct rtgui_dc * dst, const rtgui_rect_t *rects, int
                     prect = ((rtgui_rect_t *)(owner->clip.data + index + 1));
 
                     draw_rect = rect;
-                    rtgui_rect_moveto(&draw_rect,owner->extent.x1, owner->extent.y1);
+                    rtgui_rect_move(&draw_rect,owner->extent.x1, owner->extent.y1);
 
                     /* calculate rect intersect */
                     if (prect->y1 > draw_rect.y2  || prect->y2 <= draw_rect.y1) continue;

+ 30 - 9
components/gui/src/dc_buffer.c

@@ -88,6 +88,7 @@ struct rtgui_dc *rtgui_dc_buffer_create_pixformat(rt_uint8_t pixel_format, int w
         dc->gc.font = rtgui_font_default();
         dc->gc.textalign = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP;
         dc->pixel_format = pixel_format;
+        dc->pixel_alpha = 255;
 
         dc->width = w;
         dc->height = h;
@@ -127,6 +128,7 @@ struct rtgui_dc *rtgui_img_dc_create_pixformat(rt_uint8_t pixel_format,
         dc->gc.font = rtgui_font_default();
         dc->gc.textalign = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP;
         dc->pixel_format = pixel_format;
+        dc->pixel_alpha = 255;
 
         dc->width = image_item->image->w;
         dc->height = image_item->image->h;
@@ -160,7 +162,8 @@ struct rtgui_dc *rtgui_dc_buffer_create_from_dc(struct rtgui_dc* dc)
                  d->height);
         if (buffer != RT_NULL)
         {
-            rt_memcpy(buffer->pixel, d->pixel, d->pitch * d->height);
+            memcpy(buffer->pixel, d->pixel, d->pitch * d->height);
+            d->pixel_alpha = 255;
 
             return RTGUI_DC(buffer);
         }
@@ -170,6 +173,15 @@ struct rtgui_dc *rtgui_dc_buffer_create_from_dc(struct rtgui_dc* dc)
 }
 RTM_EXPORT(rtgui_dc_buffer_create_from_dc);
 
+void rtgui_dc_buffer_set_alpha(struct rtgui_dc* dc, rt_uint8_t pixel_alpha)
+{
+    struct rtgui_dc_buffer *d = (struct rtgui_dc_buffer*) dc;
+    if (d)
+    {
+        d->pixel_alpha = pixel_alpha;
+    }
+}
+
 rt_uint8_t *rtgui_dc_buffer_get_pixel(struct rtgui_dc *dc)
 {
     struct rtgui_dc_buffer *dc_buffer;
@@ -465,10 +477,13 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc *self,
         {
             /* use rtgui_blit */
 
-            struct rtgui_blit_info info;
+            struct rtgui_blit_info info = { 0 };
             struct rtgui_widget *owner;
 
-            info.a = 255;
+            if (self->type == RTGUI_DC_BUFFER)
+                info.a = dc->pixel_alpha;
+            else
+                info.a = 255;
 
             /* blit source */
             info.src = _dc_get_pixel(dc, dc_point.x, dc_point.y);
@@ -496,7 +511,7 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc *self,
         {
             /* use rtgui_blit */
             rt_uint8_t bpp, hw_bpp;
-            struct rtgui_blit_info info;
+            struct rtgui_blit_info info = { 0 };
             struct rtgui_widget *owner;
             struct rtgui_region dest_region;
             struct rtgui_rect dest_extent;
@@ -518,7 +533,10 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc *self,
             rects = rtgui_region_rects(&dest_region);
 
             /* common info */
-            info.a = 255;
+            if (self->type == RTGUI_DC_BUFFER)
+                info.a = dc->pixel_alpha;
+            else
+                info.a = 255;
             info.src_fmt = dc->pixel_format;
             info.src_pitch = dc->pitch;
 
@@ -564,7 +582,7 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc *self,
                 else RT_ASSERT(0);
 
                 /* change the logic coordinate to the device coordinate */
-                rtgui_rect_moveto(dest_rect, owner->extent.x1, owner->extent.y1);
+                rtgui_rect_move(dest_rect, owner->extent.x1, owner->extent.y1);
 
                 for (index = dest_rect->y1; index < dest_rect->y1 + rect_height; index ++)
                 {
@@ -602,9 +620,12 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc *self,
         struct rtgui_dc_buffer *dest_dc = (struct rtgui_dc_buffer*)dest;
 
         /* use rtgui_blit to handle buffer blit */
-        struct rtgui_blit_info info;
+        struct rtgui_blit_info info = { 0 };
 
-        info.a = 255;
+        if (self->type == RTGUI_DC_BUFFER)
+            info.a = dc->pixel_alpha;
+        else
+            info.a = 255;
 
         /* blit source */
         info.src = _dc_get_pixel(dc, dc_point.x, dc_point.y);
@@ -645,7 +666,7 @@ static void rtgui_dc_buffer_blit_line(struct rtgui_dc *self, int x1, int x2, int
         x2 = dc->width-1;
 
     pixel = _dc_get_pixel(dc,x1,y);
-    rt_memcpy(pixel, line_data, (x2 - x1) * rtgui_color_get_bpp(dc->pixel_format));
+    memcpy(pixel, line_data, (x2 - x1) * rtgui_color_get_bpp(dc->pixel_format));
 }
 
 #ifdef RT_USING_DFS

+ 10 - 0
components/gui/src/dc_hw.c

@@ -216,22 +216,32 @@ static void rtgui_dc_hw_fill_rect(struct rtgui_dc *self, struct rtgui_rect *rect
         return;
     if (x1 < dc->owner->extent.x1)
         x1 = dc->owner->extent.x1;
+	if (x1 < 0)
+		x1 = 0;
+
     x2 = rect->x2 + dc->owner->extent.x1;
     if (x2 < dc->owner->extent.x1)
         return;
     if (x2 > dc->owner->extent.x2)
         x2 = dc->owner->extent.x2;
+	if (x2 > dc->hw_driver->width)
+		x2 = dc->hw_driver->width;
 
     y1 = rect->y1 + dc->owner->extent.y1;
     if (y1 > dc->owner->extent.y2)
         return;
     if (y1 < dc->owner->extent.y1)
         y1 = dc->owner->extent.y1;
+	if (y1 < 0)
+		y1 = 0;
+
     y2 = rect->y2 + dc->owner->extent.y1;
     if (y2 < dc->owner->extent.y1)
         return;
     if (y2 > dc->owner->extent.y2)
         y2 = dc->owner->extent.y2;
+	if (y2 > dc->hw_driver->height)
+		y2 = dc->hw_driver->height;
 
     /* fill rect */
     for (; y1 < y2; y1++)

+ 2 - 2
components/gui/src/dc_rotozoom.c

@@ -653,7 +653,7 @@ struct rtgui_dc* rtgui_dc_rotate_90degrees(struct rtgui_dc_buffer* src, int numC
         if (src->pitch == dst->pitch)
         {
             /* If the pitch is the same for both surfaces, the memory can be copied all at once. */
-            rt_memcpy(dst->pixel, src->pixel, (src->height * src->pitch));
+            memcpy(dst->pixel, src->pixel, (src->height * src->pitch));
         }
         else
         {
@@ -663,7 +663,7 @@ struct rtgui_dc* rtgui_dc_rotate_90degrees(struct rtgui_dc_buffer* src, int numC
 
             for (row = 0; row < src->height; row++)
             {
-                rt_memcpy(dstBuf, srcBuf, dst->width * bpp);
+                memcpy(dstBuf, srcBuf, dst->width * bpp);
                 srcBuf += src_ipr;
                 dstBuf += dst_ipr;
             } /* end for(col) */

+ 1 - 1
components/gui/src/filerw.c

@@ -166,7 +166,7 @@ static int mem_read(struct rtgui_filerw *context, void *ptr, rt_size_t size, rt_
     if (total_bytes > mem_available)
         total_bytes = mem_available;
 
-    rt_memcpy(ptr, mem->mem_position, total_bytes);
+    memcpy(ptr, mem->mem_position, total_bytes);
     mem->mem_position += total_bytes;
 
     return (total_bytes / size);

+ 16 - 12
components/gui/src/font_bmp.c

@@ -95,6 +95,7 @@ static void rtgui_bitmap_font_draw_text(struct rtgui_font *font, struct rtgui_dc
                                         const char *text, rt_ubase_t len, struct rtgui_rect *rect)
 {
     rt_uint32_t length;
+    struct rtgui_rect text_rect;
     struct rtgui_font_bitmap *bmp_font = (struct rtgui_font_bitmap *)(font->data);
 #ifdef RTGUI_USING_FONTHZ
     struct rtgui_font *hz_font;
@@ -102,18 +103,21 @@ static void rtgui_bitmap_font_draw_text(struct rtgui_font *font, struct rtgui_dc
 
     RT_ASSERT(bmp_font != RT_NULL);
 
+    rtgui_font_get_metrics(rtgui_dc_get_gc(dc)->font, text, &text_rect);
+    rtgui_rect_move_to_align(rect, &text_rect, RTGUI_DC_TEXTALIGN(dc));
+
     /* parameter check */
-    if (rect->y1 > rect->y2) return;
+    if (text_rect.y1 > text_rect.y2) return;
 
 #ifdef RTGUI_USING_FONTHZ
     hz_font = rtgui_font_refer("hz", font->height);
-    while ((rect->x1 < rect->x2) && len)
+    while ((text_rect.x1 < text_rect.x2) && len)
     {
         length = 0;
         while ((rt_uint8_t) * (text + length) >= 0x80) length ++; /* it's not a ascii character */
         if (length > 0)
         {
-            if (hz_font != RT_NULL) rtgui_font_draw(hz_font, dc, text, length, rect);
+            if (hz_font != RT_NULL) rtgui_font_draw(hz_font, dc, text, length, &text_rect);
             text += length;
             len -= length;
         }
@@ -123,15 +127,15 @@ static void rtgui_bitmap_font_draw_text(struct rtgui_font *font, struct rtgui_dc
         if (length > 0)
         {
             len -= length;
-            while (length-- && rect->x1 < rect->x2)
+            while (length-- && text_rect.x1 < text_rect.x2)
             {
-                rtgui_bitmap_font_draw_char(bmp_font, dc, *text, rect);
+                rtgui_bitmap_font_draw_char(bmp_font, dc, *text, &text_rect);
 
                 /* move x to next character */
                 if (bmp_font->char_width == RT_NULL)
-                    rect->x1 += bmp_font->width;
+                    text_rect.x1 += bmp_font->width;
                 else
-                    rect->x1 += bmp_font->char_width[*text - bmp_font->first_char];
+                    text_rect.x1 += bmp_font->char_width[*text - bmp_font->first_char];
                 text ++;
             }
         }
@@ -140,22 +144,22 @@ static void rtgui_bitmap_font_draw_text(struct rtgui_font *font, struct rtgui_dc
     if (hz_font != RT_NULL) rtgui_font_derefer(hz_font);
 
 #else
-    while ((rect->x1 < rect->x2) && len)
+    while ((text_rect.x1 < text_rect.x2) && len)
     {
         length = 0;
         while (((rt_uint8_t) * (text + length) < 0x80) && *(text + length)) length ++;
         if (length > 0)
         {
             len -= length;
-            while (length-- && rect->x1 < rect->x2)
+            while (length-- && text_rect.x1 < text_rect.x2)
             {
-                rtgui_bitmap_font_draw_char(bmp_font, dc, *text, rect);
+                rtgui_bitmap_font_draw_char(bmp_font, dc, *text, &text_rect);
 
                 /* move x to next character */
                 if (bmp_font->char_width == RT_NULL)
-                    rect->x1 += bmp_font->width;
+                    text_rect.x1 += bmp_font->width;
                 else
-                    rect->x1 += bmp_font->char_width[*text - bmp_font->first_char];
+                    text_rect.x1 += bmp_font->char_width[*text - bmp_font->first_char];
                 text ++;
             }
         }

+ 7 - 3
components/gui/src/font_fnt.c

@@ -44,10 +44,14 @@ void rtgui_fnt_font_draw_text(struct rtgui_font *font, struct rtgui_dc *dc, cons
     rt_uint32_t position;
     struct fnt_font *fnt;
     rt_uint8_t *data_ptr;
+    struct rtgui_rect text_rect;
 
     fnt = (struct fnt_font*)font->data;
     RT_ASSERT(fnt != RT_NULL);
 
+    rtgui_font_get_metrics(rtgui_dc_get_gc(dc)->font, text, &text_rect);
+    rtgui_rect_move_to_align(rect, &text_rect, RTGUI_DC_TEXTALIGN(dc));
+
     while (len)
     {
         /* get character */
@@ -81,16 +85,16 @@ void rtgui_fnt_font_draw_text(struct rtgui_font *font, struct rtgui_dc *dc, cons
                 for (c = 0; c < (fnt->header.height + 7)/8; c ++)
                 {
                     /* check drawable region */
-                    if ((rect->x1 + i > rect->x2) || (rect->y1 + c * 8 + j > rect->y2))
+                    if ((text_rect.x1 + i > text_rect.x2) || (text_rect.y1 + c * 8 + j > text_rect.y2))
                         continue;
 
                     if (data_ptr[i + c * width] & (1 << j))
-                        rtgui_dc_draw_point(dc, rect->x1 + i, rect->y1 + c * 8 + j);
+                        rtgui_dc_draw_point(dc, text_rect.x1 + i, text_rect.y1 + c * 8 + j);
                 }
             }
         }
 
-        rect->x1 += width;
+        text_rect.x1 += width;
         text += 1;
         len -= 1;
     }

+ 249 - 33
components/gui/src/font_freetype.c

@@ -91,7 +91,161 @@ static void gbk_to_unicode(rt_uint16_t *unicode, const char *text, int len)
     *unicode = '\0';
 }
 
-static void _rtgui_rect_moveto_align(const rtgui_rect_t *rect, rtgui_rect_t *to, int align)
+static rt_uint16_t _get_unicode(const char* str, int n)
+{
+    int i;
+    rt_uint16_t unicode = str[0] & ((1 << (8 - n)) - 1);
+
+    for (i = 1; i<n; i++)
+    {
+        unicode = unicode << 6 | ((rt_uint8_t)str[i] & 0x3f);
+    }
+
+    return unicode;
+}
+
+static int utf8_to_unicode_len(const char* utf8, int len)
+{
+    int index = 0, unicode_len = 0;
+    rt_uint8_t c;
+
+    if (!utf8)
+    {
+        return 0;
+    }
+
+    if (*utf8 == 0)
+    {
+        return 0;
+    }
+
+    for (index = 0; index < len;)
+    {
+        c = *utf8;
+
+        if ((c & 0x80) == 0)
+        {
+            utf8 += 1;
+            index += 1;
+            unicode_len += 1;
+        }
+        else if ((c & 0xe0) == 0xc0)
+        {
+            utf8 += 2;
+            index += 2;
+            unicode_len += 1;
+        }
+        else if ((c & 0xf0) == 0xe0)
+        {
+            utf8 += 3;
+            index += 3;
+            unicode_len += 1;
+        }
+        else if ((c & 0xf8) == 0xf0)
+        {
+            utf8 += 4;
+            index += 4;
+            unicode_len += 1;
+        }
+        else if ((c & 0xfc) == 0xf8)
+        {
+            utf8 += 5;
+            index += 5;
+            unicode_len += 1;
+        }
+        else if ((c & 0xfe) == 0xfc)
+        {
+            utf8 += 6;
+            index += 6;
+            unicode_len += 1;
+        }
+        else
+        {
+            return unicode_len;
+        }
+    }
+
+    return unicode_len;
+}
+
+static int utf8_to_unicode(rt_uint16_t* unicode, const char* utf8, int len)
+{
+    int index = 0;
+    rt_uint8_t c;
+
+    if (!utf8 || !unicode)
+    {
+        return 0;
+    }
+
+    if (*utf8 == 0)
+    {
+        return 0;
+    }
+
+    for (index = 0; index < len;)
+    {
+        c = *utf8;
+
+        if ((c & 0x80) == 0)
+        {
+            *unicode = _get_unicode(utf8, 1);
+
+            utf8 += 1;
+            unicode++;
+            index += 1;
+        }
+        else if ((c & 0xe0) == 0xc0)
+        {
+            *unicode = _get_unicode(utf8, 2);
+
+            utf8 += 2;
+            unicode++;
+            index += 2;
+        }
+        else if ((c & 0xf0) == 0xe0)
+        {
+            *unicode = _get_unicode(utf8, 3);
+
+            utf8 += 3;
+            unicode++;
+            index += 3;
+        }
+        else if ((c & 0xf8) == 0xf0)
+        {
+            *unicode = _get_unicode(utf8, 4);
+
+            utf8 += 4;
+            unicode++;
+            index += 4;
+        }
+        else if ((c & 0xfc) == 0xf8)
+        {
+            *unicode = _get_unicode(utf8, 5);
+
+            utf8 += 5;
+            unicode++;
+            index += 5;
+        }
+        else if ((c & 0xfe) == 0xfc)
+        {
+            *unicode = _get_unicode(utf8, 6);
+
+            utf8 += 6;
+            unicode++;
+            index += 6;
+        }
+        else
+        {
+            return index;
+        }
+    }
+
+    return index;
+}
+
+
+static void _rtgui_rect_move_to_align(const rtgui_rect_t *rect, rtgui_rect_t *to, rt_uint16_t height, int align)
 {
     int dw, dh;
     dw = 0;
@@ -99,16 +253,21 @@ static void _rtgui_rect_moveto_align(const rtgui_rect_t *rect, rtgui_rect_t *to,
 
     /* get delta width and height */
     dw = rtgui_rect_width(*rect) - rtgui_rect_width(*to);
-    dh = rtgui_rect_height(*rect) - rtgui_rect_height(*to);
+    if (RTGUI_ALIGN_TTF_SIZE & align)
+        dh = rtgui_rect_height(*rect) - height;
+    else
+        dh = rtgui_rect_height(*rect) - rtgui_rect_height(*to);
     if (dw < 0) dw = 0;
     if (dh < 0) dh = 0;
 
-    /* move to insider of rect */
-    rtgui_rect_moveto_point(to, rect->x1, rect->y1);
+    PINFO(" rect align =1=>  %d %d %d %d\n", to->x1, to->y1, to->x2, to->y2);
 
-    /* limited the destination rect to source rect */
-    // if (dw == 0) to->x2 = rect->x2;
-    // if (dh == 0) to->y2 = rect->y2;
+    /* move to insider of rect */
+    if (RTGUI_ALIGN_TTF_SIZE & align)
+        rtgui_rect_move_to_point(to, rect->x1, rect->y1 + height * 3 / 4 - to->y2);
+    else
+        rtgui_rect_move_to_point(to, rect->x1, rect->y1);
+    PINFO(" rect align =2=>  %d %d %d %d\n", to->x1, to->y1, to->x2, to->y2);
 
     /* align to right */
     if (align & RTGUI_ALIGN_RIGHT)
@@ -116,6 +275,12 @@ static void _rtgui_rect_moveto_align(const rtgui_rect_t *rect, rtgui_rect_t *to,
         to->x1 += dw;
         to->x2 += dw;
     }
+	/* align to center horizontal */
+	else if (align & RTGUI_ALIGN_CENTER_HORIZONTAL)
+	{
+		to->x1 += dw >> 1;
+		to->x2 += dw >> 1;
+	}
 
     /* align to bottom */
     if (align & RTGUI_ALIGN_BOTTOM)
@@ -123,20 +288,14 @@ static void _rtgui_rect_moveto_align(const rtgui_rect_t *rect, rtgui_rect_t *to,
         to->y1 += dh;
         to->y2 += dh;
     }
-
-    /* align to center horizontal */
-    if (align & RTGUI_ALIGN_CENTER_HORIZONTAL)
-    {
-        to->x1 += dw >> 1;
-        to->x2 += dw >> 1;
-    }
-
     /* align to center vertical */
-    if (align & RTGUI_ALIGN_CENTER_VERTICAL)
+    else if (align & RTGUI_ALIGN_CENTER_VERTICAL)
     {
         to->y1 += dh >> 1;
         to->y2 += dh >> 1;
     }
+
+    PINFO(" rect align =3=>  %d %d %d %d\n", to->x1, to->y1, to->x2, to->y2);
 }
 
 static void ftc_draw_text(struct rtgui_font *font,
@@ -234,17 +393,17 @@ static void _get_metrics(struct rtgui_ttf_font *ttf_font, const rt_uint16_t *tex
 static void _draw_bitmap(struct rtgui_dc *dc,
                          FTC_SBit bitmap,
                          rt_int16_t ox, rt_int16_t btm_y,
-                         rt_uint8_t r, rt_uint8_t g, rt_uint8_t b)
+                         rt_uint8_t a, rt_uint8_t r, rt_uint8_t g, rt_uint8_t b)
 {
     rt_int16_t x_start, y_start;
-    struct rtgui_blit_info info;
+    struct rtgui_blit_info info = { 0 };
     struct rtgui_dc_buffer *dest_buf;
 
 
     x_start = ox + bitmap->left;
     y_start = btm_y - bitmap->top;
 
-    info.a = 255;
+    info.a = a;
     info.r = r;
     info.g = g;
     info.b = b;
@@ -320,6 +479,7 @@ static void _draw_bitmap(struct rtgui_dc *dc,
             dest_buf = (struct rtgui_dc_buffer*)text_dc;
 
             /* blit source */
+            info.a = 0;
             info.src = (rt_uint8_t *)bitmap->buffer;
             info.src_fmt = RTGRAPHIC_PIXEL_FORMAT_ALPHA;
             info.src_w = bitmap->width;
@@ -343,6 +503,7 @@ static void _draw_bitmap(struct rtgui_dc *dc,
             text_rect.y1 = y_start;
             text_rect.y2 = text_rect.y1 + bitmap->height;
 
+            rtgui_dc_buffer_set_alpha(text_dc, a);
             rtgui_dc_blit(text_dc, &dc_point, dc, &text_rect);
 
             rtgui_dc_destory(text_dc);
@@ -354,7 +515,7 @@ static void _draw_text(struct rtgui_dc *dc,
                        struct rtgui_ttf_font *ttf_font,
                        rt_uint16_t *text_short,
                        rt_int16_t begin_x, rt_int16_t btm_y,
-                       rt_uint8_t r, rt_uint8_t g, rt_uint8_t b)
+                       rt_uint8_t a, rt_uint8_t r, rt_uint8_t g, rt_uint8_t b)
 {
     int glyphIndex;
     FTC_SBit ftcSBit = RT_NULL;
@@ -368,7 +529,9 @@ static void _draw_text(struct rtgui_dc *dc,
         if (err == 0 && ftcSBit->width != 0)
         {
             /* render font */
-            _draw_bitmap(dc, ftcSBit, begin_x, btm_y, r, g, b);
+            begin_x -= (ftcSBit->left - (abs(ftcSBit->left) + 2) / 2);
+
+            _draw_bitmap(dc, ftcSBit, begin_x, btm_y, a, r, g, b);
 
             begin_x += ftcSBit->width + ftcSBit->left;
 
@@ -399,7 +562,7 @@ static void ftc_draw_text(struct rtgui_font *font,
     struct rtgui_ttf_font *ttf_font;
     rt_int16_t begin_x, btm_y;
     rt_int16_t topy;
-    rt_uint8_t r, g, b;
+    rt_uint8_t a, r, g, b;
     rtgui_color_t fgc;
     struct rtgui_rect text_rect;
 
@@ -408,16 +571,30 @@ static void ftc_draw_text(struct rtgui_font *font,
     RT_ASSERT(ttf_font != RT_NULL);
 
     /* allocate unicode buffer */
+#ifndef UTF8_TO_UNICODE
     text_short = (rt_uint16_t *)rtgui_malloc((len + 1) * 2);
+#else
+    text_short = (rt_uint16_t *)rtgui_malloc((utf8_to_unicode_len(text, len) + 1) * 2);
+#endif
     if (text_short == RT_NULL)
         return; /* out of memory */
+#ifndef UTF8_TO_UNICODE
+    rt_memset(text_short, 0x00, (len + 1) * 2);
+#else
+    rt_memset(text_short, 0x00, (utf8_to_unicode_len(text, len) + 1) * 2);
+#endif
 
     RT_ASSERT(rect);
 
     /* convert gbk to unicode */
+#ifndef UTF8_TO_UNICODE
     gbk_to_unicode(text_short, text, len);
+#else
+    utf8_to_unicode(text_short, text, len);
+#endif
 
     fgc = RTGUI_DC_FC(dc);
+    a = RTGUI_RGB_A(fgc);
     r = RTGUI_RGB_R(fgc);
     g = RTGUI_RGB_G(fgc);
     b = RTGUI_RGB_B(fgc);
@@ -427,7 +604,7 @@ static void ftc_draw_text(struct rtgui_font *font,
 
     topy = text_rect.y1;
 
-    _rtgui_rect_moveto_align(rect, &text_rect, RTGUI_DC_TEXTALIGN(dc));
+    _rtgui_rect_move_to_align(rect, &text_rect, font->height, RTGUI_DC_TEXTALIGN(dc));
 
     btm_y = topy + text_rect.y2;
     if (btm_y <= 0)
@@ -456,7 +633,7 @@ static void ftc_draw_text(struct rtgui_font *font,
             goto _out;
     }
 
-    _draw_text(dc, ttf_font, text_short, begin_x, btm_y, r, g, b);
+    _draw_text(dc, ttf_font, text_short, begin_x, btm_y, a, r, g, b);
 
 _out:
     /* release unicode buffer */
@@ -478,10 +655,8 @@ static void _get_metrics(struct rtgui_ttf_font *ttf_font, const rt_uint16_t *tex
         err = FTC_SBitCache_Lookup(ttf_font->ttf->sbit_cache, &ttf_font->image_type_rec, glyphIndex, &ftcSBit, 0);
         if (err == 0 && ftcSBit->width != 0)
         {
-            if (w == 0)
-                w = ftcSBit->width;
-            else
-                w += ftcSBit->width + ftcSBit->left;
+            w -= (ftcSBit->left - (abs(ftcSBit->left) + 2) / 2);
+            w += ftcSBit->width + ftcSBit->left;
 
             top = top > ftcSBit->top ? top : ftcSBit->top;
             btm = (ftcSBit->top - ftcSBit->height) > btm ? btm : (ftcSBit->top - ftcSBit->height);
@@ -496,12 +671,13 @@ static void _get_metrics(struct rtgui_ttf_font *ttf_font, const rt_uint16_t *tex
                 w += ftcSBit->width;
             }
         }
-        PINFO(" bitmap:(%d, %d, %d, %d)\n", ftcSBit->left, ftcSBit->top,
-              ftcSBit->width, ftcSBit->height);
+        PINFO(" bitmap:(%d, %d, %d, %d)\n", ftcSBit->left, ftcSBit->top - ftcSBit->height, ftcSBit->width, ftcSBit->height);
 
         text_short ++;
     }
 
+    w += ftcSBit->left - (ftcSBit->left - (abs(ftcSBit->left) + 2) / 2);
+
     rect->x1 = 0;
     rect->y1 = btm;
     rect->x2 = w;
@@ -522,18 +698,35 @@ static void ftc_get_metrics(struct rtgui_font *font, const char *text, struct rt
     RT_ASSERT(ttf_font != RT_NULL);
 
     len = strlen(text);
+	if (len == 0)
+		return;
+	
     memset(rect, 0, sizeof(struct rtgui_rect));
 
     /* allocate unicode buffer */
+#ifndef UTF8_TO_UNICODE
     text_short = (rt_uint16_t *)rtgui_malloc((len + 1) * 2);
+#else
+    text_short = (rt_uint16_t *)rtgui_malloc((utf8_to_unicode_len(text, len) + 1) * 2);
+#endif
     if (text_short == RT_NULL)
         return; /* out of memory */
 
+#ifndef UTF8_TO_UNICODE
+    rt_memset(text_short, 0x00, (len + 1) * 2);
+#else
+    rt_memset(text_short, 0x00, (utf8_to_unicode_len(text, len) + 1) * 2);
+#endif
+	
     /* convert gbk to unicode */
+#ifndef UTF8_TO_UNICODE
     gbk_to_unicode(text_short, text, len);
+#else
+    utf8_to_unicode(text_short, text, len);
+#endif
 
     _get_metrics(ttf_font, text_short, rect);
-    rtgui_rect_moveto_point(rect, 0, 0);
+    rtgui_rect_move_to_point(rect, 0, 0);
 
     PINFO(" ftc_get_metrics_kern: %d %d %d %d\n", rect->x1, rect->y1, rect->x2, rect->y2);
     /* release unicode buffer */
@@ -569,6 +762,20 @@ static struct rtgui_ttf *rtgui_ttf_load(const char *filename)
         return RT_NULL;
     }
 
+    /* chack ttf file */
+    {
+        int fd = open(filename, O_RDONLY, 0);
+        if (fd > 0)
+        {
+            close(fd);
+        }
+        else
+        {
+            PERROR("open %s failed!\n", filename);
+            return RT_NULL;
+        }
+    }
+	
     /* face_id init */
     ttf->face_id.pathname = rt_strdup(filename);
     ttf->face_id.face_index = 0;
@@ -628,8 +835,6 @@ rtgui_font_t *rtgui_freetype_font_create(const char *filename, rt_size_t size)
     ttf = rtgui_ttf_refer(filename);
     if (!ttf)
     {
-        PERROR("rtgui_ttf_refer failed!\n");
-
         ttf = rtgui_ttf_load(filename);
         if (!ttf)
         {
@@ -637,6 +842,17 @@ rtgui_font_t *rtgui_freetype_font_create(const char *filename, rt_size_t size)
             return RT_NULL;
         }
     }
+    else
+    {
+        font = rtgui_font_refer(filename, size);
+        if (font)
+        {
+			if (font->height == size)
+				return font;
+			else
+				rtgui_font_derefer(font);
+        }		
+    }
 
     font = (struct rtgui_font *)rtgui_malloc(sizeof(struct rtgui_font) + sizeof(struct rtgui_ttf_font));
     if (!font)

+ 6 - 2
components/gui/src/font_hz_bmp.c

@@ -131,9 +131,13 @@ static void rtgui_hz_bitmap_font_draw_text(struct rtgui_font *font, struct rtgui
     rt_uint32_t len;
     struct rtgui_font *efont;
     struct rtgui_font_bitmap *bmp_font = (struct rtgui_font_bitmap *)(font->data);
+    struct rtgui_rect text_rect;
 
     RT_ASSERT(dc != RT_NULL);
 
+    rtgui_font_get_metrics(rtgui_dc_get_gc(dc)->font, text, &text_rect);
+    rtgui_rect_move_to_align(rect, &text_rect, RTGUI_DC_TEXTALIGN(dc));
+
     /* get English font */
     efont = rtgui_font_refer("asc", bmp_font->height);
     if (efont == RT_NULL) efont = rtgui_font_default(); /* use system default font */
@@ -145,7 +149,7 @@ static void rtgui_hz_bitmap_font_draw_text(struct rtgui_font *font, struct rtgui
         /* draw text with English font */
         if (len > 0)
         {
-            rtgui_font_draw(efont, dc, text, len, rect);
+            rtgui_font_draw(efont, dc, text, len, &text_rect);
 
             text += len;
             length -= len;
@@ -155,7 +159,7 @@ static void rtgui_hz_bitmap_font_draw_text(struct rtgui_font *font, struct rtgui
         while (((rt_uint8_t) * (text + len)) >= 0x80 && len < length) len ++;
         if (len > 0)
         {
-            _rtgui_hz_bitmap_font_draw_text(bmp_font, dc, text, len, rect);
+            _rtgui_hz_bitmap_font_draw_text(bmp_font, dc, text, len, &text_rect);
 
             text += len;
             length -= len;

+ 6 - 2
components/gui/src/font_hz_file.c

@@ -206,10 +206,14 @@ static void rtgui_hz_file_font_draw_text(struct rtgui_font *font, struct rtgui_d
     rt_uint32_t len;
     struct rtgui_font *efont;
     struct rtgui_hz_file_font *hz_file_font = (struct rtgui_hz_file_font *)font->data;
+    struct rtgui_rect text_rect;
 
     RT_ASSERT(dc != RT_NULL);
     RT_ASSERT(hz_file_font != RT_NULL);
 
+    rtgui_font_get_metrics(rtgui_dc_get_gc(dc)->font, text, &text_rect);
+    rtgui_rect_move_to_align(rect, &text_rect, RTGUI_DC_TEXTALIGN(dc));
+
     /* get English font */
     efont = rtgui_font_refer("asc", hz_file_font->font_size);
     if (efont == RT_NULL) efont = rtgui_font_default(); /* use system default font */
@@ -221,7 +225,7 @@ static void rtgui_hz_file_font_draw_text(struct rtgui_font *font, struct rtgui_d
         /* draw text with English font */
         if (len > 0)
         {
-            rtgui_font_draw(efont, dc, text, len, rect);
+            rtgui_font_draw(efont, dc, text, len, &text_rect);
 
             text += len;
             length -= len;
@@ -231,7 +235,7 @@ static void rtgui_hz_file_font_draw_text(struct rtgui_font *font, struct rtgui_d
         while (((rt_uint8_t) * (text + len)) >= 0x80 && len < length) len ++;
         if (len > 0)
         {
-            _rtgui_hz_file_font_draw_text(hz_file_font, dc, text, len, rect);
+            _rtgui_hz_file_font_draw_text(hz_file_font, dc, text, len, &text_rect);
 
             text += len;
             length -= len;

+ 2 - 2
components/gui/src/image_bmp.c

@@ -423,14 +423,14 @@ static rt_bool_t rtgui_image_bmp_load(struct rtgui_image *image, struct rtgui_fi
                     {
                         if (bmp->scale == 0)
                         {
-                            rt_memcpy((void *)dst, (void *)wrkBuffer, readLength);
+                            memcpy((void *)dst, (void *)wrkBuffer, readLength);
                             dst += readLength;
                         }
                         else
                         {
                             for (loadIndex = skipLength; loadIndex < readLength; loadIndex += bytePerPixel << bmp->scale)
                             {
-                                rt_memcpy((void *)dst, (void *)&wrkBuffer[loadIndex], bytePerPixel);
+                                memcpy((void *)dst, (void *)&wrkBuffer[loadIndex], bytePerPixel);
                                 dst += bytePerPixel;
                             }
                             if (readLength % (1 << bmp->scale))

+ 6 - 1
components/gui/src/image_container.c

@@ -393,13 +393,18 @@ rtgui_image_item_t *rtgui_image_container_get(const char *filename)
         if (item == RT_NULL)
         {
             item = (struct rtgui_image_item *) rtgui_malloc(sizeof(struct rtgui_image_item));
-            if (item == RT_NULL) return RT_NULL;
+            if (item == RT_NULL)
+			{
+				rt_mutex_release(&_image_hash_lock);
+				return RT_NULL;
+			}
 
             /* create a image object */
             item->image = rtgui_image_create(filename, RT_TRUE);
             if (item->image == RT_NULL)
             {
                 rtgui_free(item);
+				rt_mutex_release(&_image_hash_lock);
                 return RT_NULL; /* create image failed */
             }
             item->refcount = 1;

+ 2 - 0
components/gui/src/image_hdc.c

@@ -30,7 +30,9 @@
 
 #define HDC_MAGIC_LEN       4
 
+#ifdef PKG_USING_FASTLZ
 extern int fastlz_decompress(const void *input, int length, void *output, int maxout);
+#endif
 
 static rt_bool_t rtgui_image_hdc_check(struct rtgui_filerw *file);
 static rt_bool_t rtgui_image_hdc_load(struct rtgui_image *image, struct rtgui_filerw *file, rt_bool_t load);

+ 3 - 3
components/gui/src/image_jpg.c

@@ -427,7 +427,7 @@ static void rtgui_image_jpeg_blit(struct rtgui_image *image, struct rtgui_dc *dc
             /* blit ARGB888 to this buffered DC */
             int dst_x, dst_y;
             int w, h;
-            struct rtgui_blit_info info;
+            struct rtgui_blit_info info = { 0 };
             struct rtgui_dc_buffer *buffer = (struct rtgui_dc_buffer*)dc;
 
             w = _UI_MIN(image->w, rtgui_rect_width(*rect));
@@ -704,7 +704,7 @@ static UINT tjpgd_out_func(JDEC *jdec, void *bitmap, JRECT *rect)
         /* Left-top of destination rectangular */
         for (h = rect->top; h <= rect->bottom; h++)
         {
-            rt_memcpy(dst, src, rectWidth);
+            memcpy(dst, src, rectWidth);
             src += rectWidth;
             dst += imageWidth;           /* Next line */
         }
@@ -945,7 +945,7 @@ static void rtgui_image_jpeg_blit(struct rtgui_image *image,
         /* if the format is not match, only support DC buffer */
         else if (dc->type == RTGUI_DC_BUFFER)
         {
-            struct rtgui_blit_info info;
+            struct rtgui_blit_info info = { 0 };
             struct rtgui_dc_buffer *buffer;
 
             buffer = (struct rtgui_dc_buffer*)dc;

+ 6 - 3
components/gui/src/image_png.c

@@ -550,7 +550,7 @@ static void rtgui_image_png_blit(struct rtgui_image *image, struct rtgui_dc *dc,
 {
     int x, y;
     int w, h;
-    struct rtgui_blit_info info;
+    struct rtgui_blit_info info = {0};
     struct rtgui_graphic_driver *hw_driver = rtgui_graphic_driver_get_default();
 
     RT_ASSERT(image != RT_NULL && dc != RT_NULL && rect != RT_NULL);
@@ -653,10 +653,10 @@ static void rtgui_image_png_blit(struct rtgui_image *image, struct rtgui_dc *dc,
     {
         int dst_x, dst_y;
 
-        info.a = 0;
+        info.a = 255;
 
         /* initialize source blit information */
-        info.src_fmt = RTGRAPHIC_PIXEL_FORMAT_ARGB888;;
+        info.src_fmt = RTGRAPHIC_PIXEL_FORMAT_ARGB888;
         info.src_h = h;
         info.src_w = w;
         info.src_pitch = image->w * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888);
@@ -674,6 +674,9 @@ static void rtgui_image_png_blit(struct rtgui_image *image, struct rtgui_dc *dc,
             struct rtgui_dc_buffer *buffer;
             buffer = (struct rtgui_dc_buffer*)dc;
 
+            if (buffer->pixel_alpha == 0)
+                info.a = 0;
+
             info.dst = rtgui_dc_buffer_get_pixel(RTGUI_DC(buffer)) + dst_y * buffer->pitch +
                        dst_x * rtgui_color_get_bpp(buffer->pixel_format);
             info.dst_h = h;

+ 5 - 5
components/gui/src/mouse.c

@@ -235,7 +235,7 @@ void rtgui_mouse_moveto(int x, int y)
 #endif
 
             /* move winrect */
-            rtgui_rect_moveto(&(_rtgui_cursor->win_rect), x - _rtgui_cursor->cx,
+            rtgui_rect_move(&(_rtgui_cursor->win_rect), x - _rtgui_cursor->cx,
                               y - _rtgui_cursor->cy);
             rtgui_winrect_save();
 
@@ -360,7 +360,7 @@ static void rtgui_cursor_restore()
 
     for (idx = 0; idx < height; idx ++)
     {
-        rt_memcpy(fb_ptr, cursor_ptr, cursor_pitch);
+        memcpy(fb_ptr, cursor_ptr, cursor_pitch);
 
         fb_ptr += _rtgui_cursor->screen_pitch;
         cursor_ptr += _rtgui_cursor->cursor_pitch;
@@ -387,7 +387,7 @@ static void rtgui_cursor_save()
 
     for (idx = 0; idx < height; idx ++)
     {
-        rt_memcpy(cursor_ptr, fb_ptr, cursor_pitch);
+        memcpy(cursor_ptr, fb_ptr, cursor_pitch);
 
         fb_ptr += _rtgui_cursor->screen_pitch;
         cursor_ptr += _rtgui_cursor->cursor_pitch;
@@ -407,7 +407,7 @@ static void rtgui_cursor_show()
     set_pixel = rtgui_graphic_driver_get_default()->ops->set_pixel;
 
     rtgui_mouse_get_cursor_rect(&rect);
-    rtgui_rect_moveto(&rect, _rtgui_cursor->cx, _rtgui_cursor->cy);
+    rtgui_rect_move(&rect, _rtgui_cursor->cx, _rtgui_cursor->cy);
 
     /* draw each point */
     for (y = rect.y1; y < rect.y2; y ++)
@@ -530,7 +530,7 @@ static void rtgui_winrect_show()
 #define display_direct_memcpy(src, dest, src_pitch, dest_pitch, height, len)    \
     for (idx = 0; idx < height; idx ++)     \
     {                                       \
-        rt_memcpy(dest, src, len);          \
+        memcpy(dest, src, len);             \
         src  += src_pitch;                  \
         dest += dest_pitch;                 \
     }

+ 17 - 19
components/gui/src/region.c

@@ -2077,7 +2077,7 @@ void rtgui_region_draw_clip(rtgui_region_t *region, struct rtgui_dc *dc)
 
         rect = rects[i];
 
-        rtgui_rect_moveto(&rect, -x, -y);
+		rtgui_rect_move(&rect, -x, -y);
         rtgui_dc_draw_rect(dc, &rect);
 
         rt_snprintf(text, sizeof(text) - 1, "%d", i);
@@ -2100,7 +2100,7 @@ int rtgui_region_is_flat(rtgui_region_t *region)
 }
 RTM_EXPORT(rtgui_region_is_flat);
 
-void rtgui_rect_moveto(rtgui_rect_t *rect, int x, int y)
+void rtgui_rect_move(rtgui_rect_t *rect, int x, int y)
 {
     rect->x1 += x;
     rect->x2 += x;
@@ -2108,9 +2108,9 @@ void rtgui_rect_moveto(rtgui_rect_t *rect, int x, int y)
     rect->y1 += y;
     rect->y2 += y;
 }
-RTM_EXPORT(rtgui_rect_moveto);
+RTM_EXPORT(rtgui_rect_move);
 
-void rtgui_rect_moveto_point(rtgui_rect_t *rect, int x, int y)
+void rtgui_rect_move_to_point(rtgui_rect_t *rect, int x, int y)
 {
     int mx, my;
 
@@ -2123,9 +2123,9 @@ void rtgui_rect_moveto_point(rtgui_rect_t *rect, int x, int y)
     rect->y1 += my;
     rect->y2 += my;
 }
-RTM_EXPORT(rtgui_rect_moveto_point);
+RTM_EXPORT(rtgui_rect_move_to_point);
 
-void rtgui_rect_moveto_align(const rtgui_rect_t *rect, rtgui_rect_t *to, int align)
+void rtgui_rect_move_to_align(const rtgui_rect_t *rect, rtgui_rect_t *to, int align)
 {
     int dw, dh;
     dw = 0;
@@ -2138,11 +2138,11 @@ void rtgui_rect_moveto_align(const rtgui_rect_t *rect, rtgui_rect_t *to, int ali
     if (dh < 0) dh = 0;
 
     /* move to insider of rect */
-    rtgui_rect_moveto(to, rect->x1, rect->y1);
+	rtgui_rect_move_to_point(to, rect->x1, rect->y1);
 
     /* limited the destination rect to source rect */
-    // if (dw == 0) to->x2 = rect->x2;
-    // if (dh == 0) to->y2 = rect->y2;
+     if (dw == 0) to->x2 = rect->x2;
+     if (dh == 0) to->y2 = rect->y2;
 
     /* align to right */
     if (align & RTGUI_ALIGN_RIGHT)
@@ -2150,6 +2150,12 @@ void rtgui_rect_moveto_align(const rtgui_rect_t *rect, rtgui_rect_t *to, int ali
         to->x1 += dw;
         to->x2 += dw;
     }
+	/* align to center horizontal */
+	else if (align & RTGUI_ALIGN_CENTER_HORIZONTAL)
+	{
+		to->x1 += dw >> 1;
+		to->x2 += dw >> 1;
+	}
 
     /* align to bottom */
     if (align & RTGUI_ALIGN_BOTTOM)
@@ -2157,22 +2163,14 @@ void rtgui_rect_moveto_align(const rtgui_rect_t *rect, rtgui_rect_t *to, int ali
         to->y1 += dh;
         to->y2 += dh;
     }
-
-    /* align to center horizontal */
-    if (align & RTGUI_ALIGN_CENTER_HORIZONTAL)
-    {
-        to->x1 += dw >> 1;
-        to->x2 += dw >> 1;
-    }
-
     /* align to center vertical */
-    if (align & RTGUI_ALIGN_CENTER_VERTICAL)
+    else if (align & RTGUI_ALIGN_CENTER_VERTICAL)
     {
         to->y1 += dh >> 1;
         to->y2 += dh >> 1;
     }
 }
-RTM_EXPORT(rtgui_rect_moveto_align);
+RTM_EXPORT(rtgui_rect_move_to_align);
 
 void rtgui_rect_inflate(rtgui_rect_t *rect, int d)
 {

+ 25 - 2
components/gui/src/rtgui_app.c

@@ -26,6 +26,7 @@
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_app.h>
 #include <rtgui/widgets/window.h>
+#include <topwin.h>
 
 static void _rtgui_app_constructor(struct rtgui_app *app)
 {
@@ -82,7 +83,7 @@ struct rtgui_app *rtgui_app_create(const char *title)
 
     rt_snprintf(mq_name, RT_NAME_MAX, "g%s", title);
     app->mq = rt_mq_create(mq_name,
-                           sizeof(union rtgui_event_generic), 64,
+                           sizeof(union rtgui_event_generic), 256,
                            RT_IPC_FLAG_FIFO);
     if (app->mq == RT_NULL)
     {
@@ -185,7 +186,6 @@ RTM_EXPORT(rtgui_app_set_onidle);
 
 rtgui_idle_func_t rtgui_app_get_onidle(struct rtgui_app *app)
 {
-
     _rtgui_application_check(app);
     return app->on_idle;
 }
@@ -200,6 +200,11 @@ rt_inline rt_bool_t _rtgui_application_dest_handle(
 
     if (wevent->wid == RT_NULL)
         return RT_FALSE;
+	
+	if (wevent->wid->magic != 0xA5A55A5A)
+	{
+		return RT_FALSE;
+	}
 
     /* this window has been closed. */
     if (wevent->wid != RT_NULL && wevent->wid->flag & RTGUI_WIN_FLAG_CLOSED)
@@ -276,11 +281,14 @@ rt_bool_t rtgui_app_event_handler(struct rtgui_object *object, rtgui_event_t *ev
 
     case RTGUI_EVENT_TIMER:
     {
+		rt_base_t level;
         struct rtgui_timer *timer;
         struct rtgui_event_timer *etimer = (struct rtgui_event_timer *) event;
 
         timer = etimer->timer;
+		level = rt_hw_interrupt_disable();
         timer->pending_cnt--;
+		rt_hw_interrupt_enable(level);
         RT_ASSERT(timer->pending_cnt >= 0);
         if (timer->state == RTGUI_TIMER_ST_DESTROY_PENDING)
         {
@@ -309,6 +317,21 @@ rt_bool_t rtgui_app_event_handler(struct rtgui_object *object, rtgui_event_t *ev
 
         if (ecmd->wid != RT_NULL)
             return _rtgui_application_dest_handle(app, event);
+		else
+		{
+			struct rtgui_topwin *wnd;
+
+			wnd = rtgui_topwin_get_focus();
+			if (wnd != RT_NULL)
+			{
+				RT_ASSERT(wnd->flag & WINTITLE_ACTIVATE)
+
+				/* send to focus window */
+				ecmd->wid = wnd->wid;
+
+				return _rtgui_application_dest_handle(app, event);
+			}			
+		}
     }
     default:
         return rtgui_object_event_handler(object, event);

+ 2 - 2
components/gui/src/rtgui_driver.c

@@ -124,7 +124,7 @@ rtgui_graphic_driver_get_rect_buffer(const struct rtgui_graphic_driver *driver,
 
     while (h--)
     {
-        rt_memcpy(dst, pixel, buffer->pitch);
+        memcpy(dst, pixel, buffer->pitch);
 
         dst += buffer->pitch;
         pixel += driver->pitch;
@@ -419,7 +419,7 @@ static void framebuffer_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y
 
     drv = rtgui_graphic_get_device();
     dst = GET_PIXEL(drv, x1, y, rt_uint8_t);
-    rt_memcpy(dst, pixels,
+    memcpy(dst, pixels,
               (x2 - x1) * _UI_BITBYTES(drv->bits_per_pixel));
 }
 

+ 5 - 2
components/gui/src/rtgui_system.c

@@ -351,7 +351,7 @@ void *rtgui_realloc(void *ptr, rt_size_t size)
     new_ptr = rtgui_malloc(size);
     if ((new_ptr != RT_NULL) && (ptr != RT_NULL))
     {
-        rt_memcpy(new_ptr, ptr, size);
+        memcpy(new_ptr, ptr, size);
         rtgui_free(ptr);
     }
 #else
@@ -417,6 +417,7 @@ const char *rtgui_event_string[] =
     "WIN_CLOSE",            /* close a window       */
     "WIN_MOVE",             /* move a window        */
     "WIN_RESIZE",           /* resize a window      */
+	"WIN_UPDATE_END",
     "WIN_MODAL_ENTER",          /* a window modals      */
 
     "SET_WM",               /* set window manager   */
@@ -546,6 +547,8 @@ static void rtgui_event_dump(struct rtgui_app* app, rtgui_event_t *event)
     break;
 
     case RTGUI_EVENT_WIN_ACTIVATE:
+	case RTGUI_EVENT_WIN_DESTROY:
+	case RTGUI_EVENT_WIN_CLOSE:
     case RTGUI_EVENT_WIN_DEACTIVATE:
     case RTGUI_EVENT_WIN_SHOW:
     case RTGUI_EVENT_WIN_HIDE:
@@ -755,7 +758,7 @@ rt_err_t rtgui_recv_filter(rt_uint32_t type, rtgui_event_t *event, rt_size_t eve
     {
         if (e->type == type)
         {
-            rt_memcpy(event, e, event_size);
+            memcpy(event, e, event_size);
             return RT_EOK;
         }
         else

+ 3 - 2
components/gui/src/topwin.c

@@ -764,7 +764,7 @@ rt_err_t rtgui_topwin_move(struct rtgui_event_win_move *event)
 
     old_rect = topwin->extent;
     /* move window rect */
-    rtgui_rect_moveto(&(topwin->extent), dx, dy);
+	rtgui_rect_move(&(topwin->extent), dx, dy);
 
     /* move the monitor rect list */
     rtgui_list_foreach(node, &(topwin->monitor_list))
@@ -772,7 +772,7 @@ rt_err_t rtgui_topwin_move(struct rtgui_event_win_move *event)
         struct rtgui_mouse_monitor *monitor = rtgui_list_entry(node,
                                               struct rtgui_mouse_monitor,
                                               list);
-        rtgui_rect_moveto(&(monitor->rect), dx, dy);
+		rtgui_rect_move(&(monitor->rect), dx, dy);
     }
 
     /* update windows clip info */
@@ -790,6 +790,7 @@ rt_err_t rtgui_topwin_move(struct rtgui_event_win_move *event)
         struct rtgui_event_paint epaint;
         RTGUI_EVENT_PAINT_INIT(&epaint);
         epaint.wid = topwin->wid;
+
         rtgui_send(topwin->app, &(epaint.parent), sizeof(epaint));
     }
 

+ 4 - 4
components/gui/src/widget.c

@@ -218,12 +218,12 @@ void rtgui_widget_set_minheight(rtgui_widget_t *widget, int height)
 }
 RTM_EXPORT(rtgui_widget_set_minheight);
 
-static void _widget_moveto(struct rtgui_widget* widget, int dx, int dy)
+static void _widget_move(struct rtgui_widget* widget, int dx, int dy)
 {
     struct rtgui_list_node *node;
     rtgui_widget_t *child, *parent;
 
-    rtgui_rect_moveto(&(widget->extent), dx, dy);
+	rtgui_rect_move(&(widget->extent), dx, dy);
 
     /* handle visiable extent */
     widget->extent_visiable = widget->extent;
@@ -243,7 +243,7 @@ static void _widget_moveto(struct rtgui_widget* widget, int dx, int dy)
         {
             child = rtgui_list_entry(node, rtgui_widget_t, sibling);
 
-            _widget_moveto(child, dx, dy);
+            _widget_move(child, dx, dy);
         }
     }
 }
@@ -280,7 +280,7 @@ void rtgui_widget_move_to_logic(rtgui_widget_t *widget, int dx, int dy)
     }
 
     /* move this widget (and its children if it's a container) to destination point */
-    _widget_moveto(widget, dx, dy);
+    _widget_move(widget, dx, dy);
     /* update this widget */
     rtgui_widget_update_clip(widget);
 }

+ 22 - 3
components/gui/src/window.c

@@ -29,7 +29,6 @@
 #include <rtgui/rtgui_app.h>
 
 #include <rtgui/widgets/window.h>
-//#include <rtgui/widgets/button.h>
 #include <rtgui/widgets/title.h>
 
 static rt_bool_t _rtgui_win_deal_close(struct rtgui_win *win,
@@ -42,6 +41,7 @@ static void _rtgui_win_constructor(rtgui_win_t *win)
     RTGUI_WIDGET(win)->toplevel = win;
 
     /* init win property */
+	win->update = 0;
     win->drawing = 0;
 
     RTGUI_WIDGET(win)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
@@ -208,6 +208,8 @@ RTM_EXPORT(rtgui_win_init);
 
 int rtgui_win_fini(struct rtgui_win* win)
 {
+    win->magic = 0;
+
     /* close the window first if it's not. */
     if (!(win->flag & RTGUI_WIN_FLAG_CLOSED))
     {
@@ -372,6 +374,7 @@ rt_base_t rtgui_win_enter_modal(struct rtgui_win *win)
         return exit_code;
 
     win->flag |= RTGUI_WIN_FLAG_MODAL;
+    win->app_ref_count = win->app->ref_count + 1;
     exit_code = rtgui_app_run(win->app);
     win->flag &= ~RTGUI_WIN_FLAG_MODAL;
 
@@ -437,6 +440,8 @@ rt_base_t rtgui_win_show(struct rtgui_win *win, rt_bool_t is_modal)
 {
     RTGUI_WIDGET_UNHIDE(win);
 
+    win->magic = 0xA5A55A5A;
+
     if (is_modal)
         win->flag |= RTGUI_WIN_FLAG_MODAL;
     if (win->_do_show)
@@ -447,9 +452,22 @@ RTM_EXPORT(rtgui_win_show);
 
 void rtgui_win_end_modal(struct rtgui_win *win, rtgui_modal_code_t modal_code)
 {
+    int i = 0;
     if (win == RT_NULL || !(win->flag & RTGUI_WIN_FLAG_MODAL))
         return;
 
+    while (win->app_ref_count < win->app->ref_count)
+    {
+        rtgui_app_exit(win->app, 0);
+
+        i ++;
+        if (i >= 1000)
+        {
+            rt_kprintf(" =*=> rtgui_win_end_modal while (win->app_ref_count < win->app->ref_count) \n");
+            RT_ASSERT(0);
+        }
+    }
+
     rtgui_app_exit(win->app, modal_code);
 
     /* remove modal mode */
@@ -530,7 +548,7 @@ void rtgui_win_move(struct rtgui_win *win, int x, int y)
         dy = y - wgt->extent.y1;
         rtgui_widget_move_to_logic(wgt, dx, dy);
     }
-    rtgui_rect_moveto(&win->outer_extent, dx, dy);
+	rtgui_rect_move(&win->outer_extent, dx, dy);
 
     if (win->flag & RTGUI_WIN_FLAG_CONNECTED)
     {
@@ -572,6 +590,7 @@ static rt_bool_t rtgui_win_ondraw(struct rtgui_win *win)
     /* paint each widget */
     RTGUI_EVENT_PAINT_INIT(&event);
     event.wid = RT_NULL;
+
     rtgui_container_dispatch_event(RTGUI_CONTAINER(win),
                                    (rtgui_event_t *)&event);
 
@@ -1095,7 +1114,7 @@ void rtgui_theme_draw_win(struct rtgui_wintitle *wint)
         {
             /* get close button rect */
             rtgui_rect_t box_rect = {0, 0, WINTITLE_CB_WIDTH, WINTITLE_CB_HEIGHT};
-            rtgui_rect_moveto_align(&rect, &box_rect, RTGUI_ALIGN_CENTER_VERTICAL | RTGUI_ALIGN_RIGHT);
+            rtgui_rect_move_to_align(&rect, &box_rect, RTGUI_ALIGN_CENTER_VERTICAL | RTGUI_ALIGN_RIGHT);
             box_rect.x1 -= 3;
             box_rect.x2 -= 3;
             rtgui_dc_fill_rect(dc, &box_rect);