Răsfoiți Sursa

[GUI] Update GUI engine code and add Kconfig file.

bernard 8 ani în urmă
părinte
comite
01108b5252
81 a modificat fișierele cu 5496 adăugiri și 3494 ștergeri
  1. 4 2
      components/KConfig
  2. 61 0
      components/gui/Kconfig
  3. 1 0
      components/gui/SConscript
  4. 9 7
      components/gui/include/rtgui/blit.h
  5. 15 5
      components/gui/include/rtgui/color.h
  6. 59 30
      components/gui/include/rtgui/dc.h
  7. 0 27
      components/gui/include/rtgui/dc_client.h
  8. 3 3
      components/gui/include/rtgui/dc_draw.h
  9. 0 24
      components/gui/include/rtgui/dc_hw.h
  10. 24 0
      components/gui/include/rtgui/dc_trans.h
  11. 27 17
      components/gui/include/rtgui/driver.h
  12. 25 6
      components/gui/include/rtgui/event.h
  13. 15 5
      components/gui/include/rtgui/filerw.h
  14. 16 5
      components/gui/include/rtgui/font.h
  15. 40 16
      components/gui/include/rtgui/font_fnt.h
  16. 26 1
      components/gui/include/rtgui/font_freetype.h
  17. 15 5
      components/gui/include/rtgui/image.h
  18. 15 5
      components/gui/include/rtgui/image_bmp.h
  19. 58 0
      components/gui/include/rtgui/image_container.h
  20. 31 6
      components/gui/include/rtgui/image_hdc.h
  21. 0 8
      components/gui/include/rtgui/image_jpeg.h
  22. 0 21
      components/gui/include/rtgui/image_png.h
  23. 0 21
      components/gui/include/rtgui/image_xpm.h
  24. 15 5
      components/gui/include/rtgui/kbddef.h
  25. 15 5
      components/gui/include/rtgui/list.h
  26. 45 21
      components/gui/include/rtgui/matrix.h
  27. 21 7
      components/gui/include/rtgui/region.h
  28. 13 21
      components/gui/include/rtgui/rtgui.h
  29. 15 5
      components/gui/include/rtgui/rtgui_app.h
  30. 15 5
      components/gui/include/rtgui/rtgui_config.h
  31. 17 7
      components/gui/include/rtgui/rtgui_object.h
  32. 23 6
      components/gui/include/rtgui/rtgui_server.h
  33. 15 5
      components/gui/include/rtgui/rtgui_system.h
  34. 15 5
      components/gui/include/rtgui/widgets/box.h
  35. 15 5
      components/gui/include/rtgui/widgets/container.h
  36. 15 5
      components/gui/include/rtgui/widgets/title.h
  37. 6 6
      components/gui/include/rtgui/widgets/widget.h
  38. 21 8
      components/gui/include/rtgui/widgets/window.h
  39. 15 5
      components/gui/src/asc12font.c
  40. 271 261
      components/gui/src/asc16font.c
  41. 592 269
      components/gui/src/blit.c
  42. 15 5
      components/gui/src/box.c
  43. 15 5
      components/gui/src/color.c
  44. 44 8
      components/gui/src/container.c
  45. 81 52
      components/gui/src/dc.c
  46. 381 314
      components/gui/src/dc_blend.c
  47. 431 362
      components/gui/src/dc_buffer.c
  48. 45 37
      components/gui/src/dc_client.c
  49. 24 15
      components/gui/src/dc_hw.c
  50. 565 512
      components/gui/src/dc_rotozoom.c
  51. 44 18
      components/gui/src/dc_trans.c
  52. 15 5
      components/gui/src/filerw.c
  53. 25 5
      components/gui/src/font.c
  54. 21 11
      components/gui/src/font_bmp.c
  55. 222 197
      components/gui/src/font_fnt.c
  56. 459 237
      components/gui/src/font_freetype.c
  57. 23 1
      components/gui/src/font_hz_bmp.c
  58. 23 0
      components/gui/src/font_hz_file.c
  59. 23 0
      components/gui/src/hz12font.c
  60. 23 0
      components/gui/src/hz16font.c
  61. 32 15
      components/gui/src/image.c
  62. 68 50
      components/gui/src/image_bmp.c
  63. 440 0
      components/gui/src/image_container.c
  64. 33 120
      components/gui/src/image_hdc.c
  65. 103 85
      components/gui/src/image_jpg.c
  66. 223 190
      components/gui/src/image_png.c
  67. 15 6
      components/gui/src/image_xpm.c
  68. 67 43
      components/gui/src/matrix.c
  69. 21 11
      components/gui/src/mouse.c
  70. 15 5
      components/gui/src/mouse.h
  71. 53 117
      components/gui/src/region.c
  72. 23 13
      components/gui/src/rtgui_app.c
  73. 75 14
      components/gui/src/rtgui_driver.c
  74. 20 10
      components/gui/src/rtgui_object.c
  75. 38 20
      components/gui/src/rtgui_system.c
  76. 67 48
      components/gui/src/server.c
  77. 20 9
      components/gui/src/title.c
  78. 27 16
      components/gui/src/topwin.c
  79. 15 5
      components/gui/src/topwin.h
  80. 30 39
      components/gui/src/widget.c
  81. 44 29
      components/gui/src/window.c

+ 4 - 2
components/KConfig

@@ -16,10 +16,12 @@ source "$RTT_DIR/components/finsh/KConfig"
 
 source "$RTT_DIR/components/dfs/KConfig"
 
+source "$RTT_DIR/components/net/KConfig"
+
 source "$RTT_DIR/components/drivers/KConfig"
 
-source "$RTT_DIR/components/libc/KConfig"
+source "$RTT_DIR/components/gui/KConfig"
 
-source "$RTT_DIR/components/net/KConfig"
+source "$RTT_DIR/components/libc/KConfig"
 
 endmenu

+ 61 - 0
components/gui/Kconfig

@@ -0,0 +1,61 @@
+menu "RT-Thread UI Engine"
+
+config RT_USING_GUIENGINE
+    bool "Enable UI Engine"
+    default n
+
+if RT_USING_GUIENGINE
+
+config RTGUI_NAME_MAX
+    int "The maximal size of name in GUI engine"
+    default 16
+
+config RTGUI_USING_TTF
+    bool "Support TrueType font"
+    default n
+
+config RTGUI_USING_FONT16
+    bool "Support 16 height font"
+    default y
+
+config RTGUI_USING_FONT12
+    bool "Support 12 height font"
+    default y
+
+config RTGUI_USING_FONTHZ
+    bool "Support Chinese font"
+    default n
+
+if RTGUI_USING_FONTHZ
+config RTGUI_USING_HZ_BMP
+    bool "Use bitmap Chinese font"
+    default n
+endif
+
+config RTGUI_IMAGE_XPM
+    bool "Support XPM image format"
+    default n
+
+config RTGUI_IMAGE_JPEG
+    bool "Support JPEG image format"
+    default n
+
+config RTGUI_IMAGE_TJPGD
+    bool "Use TJPGD for JPEG image"
+    default n
+
+config RTGUI_IMAGE_PNG
+    bool "Support PNG image format"
+    default n
+
+config RTGUI_IMAGE_LODEPNG
+    bool "Use lodepng for PNG image"
+    default n
+
+config RTGUI_IMAGE_BMP
+    bool "Support BMP image format"
+    default n
+
+endif
+
+endmenu

+ 1 - 0
components/gui/SConscript

@@ -28,6 +28,7 @@ src/hz12font.c
 src/hz16font.c
 src/image.c
 src/image_bmp.c
+src/image_container.c
 src/image_hdc.c
 src/image_jpg.c
 src/image_png.c

+ 9 - 7
components/gui/include/rtgui/blit.h

@@ -1,7 +1,7 @@
 /*
  * File      : blit.h
- * This file is part of RT-Thread GUI
- * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -47,6 +47,7 @@
 #define __RTGUI_BLIT_H__
 
 #include <rtgui/rtgui.h>
+#include <rtgui/dc.h>
 
 /* Assemble R-G-B values into a specified pixel format and store them */
 #define RGB565_FROM_RGB(Pixel, r, g, b)                                 \
@@ -201,13 +202,13 @@ struct rtgui_blit_info
     rt_uint8_t r, g, b, a;
 };
 
-struct rtgui_blit_info_src
+struct rtgui_image_info
 {
-	rt_uint8_t *src;
-	int src_w, src_h;
-	int src_skip;
+    rt_uint8_t *pixels;
+    int src_pitch;
 
-	rt_uint8_t src_fmt;
+    rt_uint8_t src_fmt;
+    rt_uint8_t a;
 };
 
 extern const rt_uint8_t* rtgui_blit_expand_byte[9];
@@ -217,6 +218,7 @@ rtgui_blit_line_func rtgui_blit_line_get(int dst_bpp, int src_bpp);
 rtgui_blit_line_func rtgui_blit_line_get_inv(int dst_bpp, int src_bpp);
 
 void rtgui_blit(struct rtgui_blit_info * info);
+void rtgui_image_info_blit(struct rtgui_image_info* image, struct rtgui_dc* dc, struct rtgui_rect *dc_rect);
 
 #endif
 

+ 15 - 5
components/gui/include/rtgui/color.h

@@ -1,11 +1,21 @@
 /*
  * File      : color.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 59 - 30
components/gui/include/rtgui/dc.h

@@ -1,11 +1,21 @@
 /*
  * File      : dc.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -23,7 +33,7 @@ extern "C" {
 #include <rtgui/driver.h>
 #include <rtgui/widgets/widget.h>
 
-#define RTGUI_DC(dc)		((struct rtgui_dc*)(dc))
+#define RTGUI_DC(dc)        ((struct rtgui_dc*)(dc))
 
 #ifndef M_PI
 #define M_PI    3.14159265358979323846
@@ -51,10 +61,10 @@ struct rtgui_dc_engine
 };
 
 /*
- * The abstract device context 
+ * The abstract device context
  *
  * Normally, a DC is a drawable canvas, user can draw point/line/cycle etc
- * on the DC. 
+ * on the DC.
  *
  * There are several kinds of DC:
  * - Hardware DC;
@@ -70,44 +80,49 @@ struct rtgui_dc
     const struct rtgui_dc_engine *engine;
 };
 
-/* 
- * The hardware device context 
+/*
+ * The hardware device context
  *
- * The hardware DC is a context based on hardware device, for examle the 
+ * The hardware DC is a context based on hardware device, for examle the
  * LCD device. The operations on the hardware DC are reflected to the real
- * hardware. 
- * 
+ * hardware.
+ *
  */
 struct rtgui_dc_hw
 {
-	struct rtgui_dc parent;
-	rtgui_widget_t *owner;
-	const struct rtgui_graphic_driver *hw_driver;
+    struct rtgui_dc parent;
+    rtgui_widget_t *owner;
+    const struct rtgui_graphic_driver *hw_driver;
 };
 
 /**
- * The buffer dc is a device context with memory buffer. 
+ * The buffer dc is a device context with memory buffer.
  *
  * All the operations on this device context is reflected to the memory buffer.
  */
 struct rtgui_dc_buffer
 {
-	struct rtgui_dc parent;
+    struct rtgui_dc parent;
+
+    /* graphic context */
+    rtgui_gc_t gc;
 
-	/* graphic context */
-	rtgui_gc_t gc;
+    /* pixel format */
+    rt_uint8_t pixel_format;
+    rt_uint8_t blend_mode;		/* RTGUI_BLENDMODE: None/Blend/Add/Mod */
 
-	/* pixel format */
-	rt_uint8_t pixel_format;
-	rt_uint8_t blend_mode;		/* RTGUI_BLENDMODE: None/Blend/Add/Mod */
+    /* width and height */
+    rt_uint16_t width, height;
+    /* pitch */
+    rt_uint16_t pitch;
 
-	/* width and height */
-	rt_uint16_t width, height;
-	/* pitch */
-	rt_uint16_t pitch;
+#ifdef RTGUI_IMAGE_CONTAINER
+    /* image dc */
+    struct rtgui_image_item *image_item;
+#endif
 
-	/* pixel data */
-	rt_uint8_t *pixel;
+    /* pixel data */
+    rt_uint8_t *pixel;
 };
 
 #define RTGUI_DC_FC(dc)         (rtgui_dc_get_gc(RTGUI_DC(dc))->foreground)
@@ -118,6 +133,10 @@ struct rtgui_dc_buffer
 /* create a buffer dc */
 struct rtgui_dc *rtgui_dc_buffer_create(int width, int height);
 struct rtgui_dc *rtgui_dc_buffer_create_pixformat(rt_uint8_t pixel_format, int w, int h);
+#ifdef RTGUI_IMAGE_CONTAINER
+struct rtgui_dc *rtgui_img_dc_create_pixformat(rt_uint8_t pixel_format, rt_uint8_t *pixel, 
+    struct rtgui_image_item *image_item);
+#endif
 struct rtgui_dc *rtgui_dc_buffer_create_from_dc(struct rtgui_dc* dc);
 
 /* create a widget dc */
@@ -125,11 +144,18 @@ struct rtgui_dc *rtgui_dc_widget_create(struct rtgui_widget * owner);
 
 /* begin and end a drawing */
 struct rtgui_dc *rtgui_dc_begin_drawing(rtgui_widget_t *owner);
-void rtgui_dc_end_drawing(struct rtgui_dc *dc);
+void rtgui_dc_end_drawing(struct rtgui_dc *dc, rt_bool_t update);
 
 /* destroy a dc */
 void rtgui_dc_destory(struct rtgui_dc *dc);
 
+/* create a hardware dc */
+struct rtgui_dc *rtgui_dc_hw_create(rtgui_widget_t *owner);
+
+/* create a client dc */
+struct rtgui_dc *rtgui_dc_client_create(rtgui_widget_t *owner);
+void rtgui_dc_client_init(rtgui_widget_t *owner);
+
 rt_uint8_t *rtgui_dc_buffer_get_pixel(struct rtgui_dc *dc);
 
 void rtgui_dc_draw_line(struct rtgui_dc *dc, int x1, int y1, int x2, int y2);
@@ -259,6 +285,9 @@ struct rtgui_dc *rtgui_dc_shrink(struct rtgui_dc *dc, int factorx, int factory);
 struct rtgui_dc *rtgui_dc_zoom(struct rtgui_dc *dc, double zoomx, double zoomy, int smooth);
 struct rtgui_dc *rtgui_dc_rotozoom(struct rtgui_dc *dc, double angle, double zoomx, double zoomy, int smooth);
 
+/* dc buffer dump to file */
+void rtgui_dc_buffer_dump(struct rtgui_dc *self, char *fn);
+
 #ifdef __cplusplus
 }
 #endif

+ 0 - 27
components/gui/include/rtgui/dc_client.h

@@ -1,27 +0,0 @@
-/*
- * 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
- * 2010-06-14     Bernard      embedded hardware dc to each widget
- * 2010-08-09     Bernard      rename hardware dc to client dc
- */
-
-#ifndef __RTGUI_DC_CLIENT_H__
-#define __RTGUI_DC_CLIENT_H__
-
-#include <rtgui/dc.h>
-
-/* create a hardware dc */
-struct rtgui_dc *rtgui_dc_client_create(rtgui_widget_t *owner);
-void rtgui_dc_client_init(rtgui_widget_t *owner);
-
-#endif
-

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

@@ -1,7 +1,7 @@
 /*
- * File      : dc_blend.c
- * This file is part of RT-Thread GUI
- * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team
+ * File      : dc_draw.h
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by

+ 0 - 24
components/gui/include/rtgui/dc_hw.h

@@ -1,24 +0,0 @@
-/*
- * 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
- * 2010-06-14     Bernard      embedded hardware dc to each widget
- */
-#ifndef __RTGUI_DC_HW_H__
-#define __RTGUI_DC_HW_H__
-
-#include <rtgui/dc.h>
-
-/* create a hardware dc */
-struct rtgui_dc *rtgui_dc_hw_create(rtgui_widget_t *owner);
-
-#endif
-

+ 24 - 0
components/gui/include/rtgui/dc_trans.h

@@ -1,3 +1,27 @@
+/*
+ * File      : dc_trans.h
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-04-10     Bernard      first version
+ */
+
 #ifndef __RTGUI_DC_TRANS_H__
 #define __RTGUI_DC_TRANS_H__
 

+ 27 - 17
components/gui/include/rtgui/driver.h

@@ -1,11 +1,21 @@
 /*
  * File      : driver.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -34,17 +44,17 @@ struct rtgui_graphic_driver_ops
 /* graphic extension operations */
 struct rtgui_graphic_ext_ops
 {
-	/* some 2D operations */
-	void (*draw_line)(rtgui_color_t *c, int x1, int y1, int x2, int y2);
+    /* some 2D operations */
+    void (*draw_line)(rtgui_color_t *c, int x1, int y1, int x2, int y2);
 
-	void (*draw_rect)(rtgui_color_t *c, int x1, int y1, int x2, int y2);
-	void (*fill_rect)(rtgui_color_t *c, int x1, int y1, int x2, int y2);
+    void (*draw_rect)(rtgui_color_t *c, int x1, int y1, int x2, int y2);
+    void (*fill_rect)(rtgui_color_t *c, int x1, int y1, int x2, int y2);
 
-	void (*draw_circle)(rtgui_color_t *c, int x, int y, int r);
-	void (*fill_circle)(rtgui_color_t *c, int x, int y, int r);
+    void (*draw_circle)(rtgui_color_t *c, int x, int y, int r);
+    void (*fill_circle)(rtgui_color_t *c, int x, int y, int r);
 
-	void (*draw_ellipse)(rtgui_color_t *c, int x, int y, int rx, int ry);
-	void (*fill_ellipse)(rtgui_color_t *c, int x, int y, int rx, int ry);
+    void (*draw_ellipse)(rtgui_color_t *c, int x, int y, int rx, int ry);
+    void (*fill_ellipse)(rtgui_color_t *c, int x, int y, int rx, int ry);
 };
 
 struct rtgui_graphic_driver
@@ -63,7 +73,7 @@ struct rtgui_graphic_driver
     struct rt_device* device;
 
     const struct rtgui_graphic_driver_ops *ops;
-	const struct rtgui_graphic_ext_ops *ext_ops;
+    const struct rtgui_graphic_ext_ops *ext_ops;
 };
 
 struct rtgui_graphic_driver *rtgui_graphic_driver_get_default(void);
@@ -77,7 +87,7 @@ void rtgui_graphic_driver_set_framebuffer(void *fb);
 
 rt_inline struct rtgui_graphic_driver *rtgui_graphic_get_device()
 {
-	return rtgui_graphic_driver_get_default();
+    return rtgui_graphic_driver_get_default();
 }
 
 #ifdef RTGUI_USING_HW_CURSOR
@@ -86,8 +96,8 @@ rt_inline struct rtgui_graphic_driver *rtgui_graphic_get_device()
  */
 enum rtgui_cursor_type
 {
-	RTGUI_CURSOR_ARROW,
-	RTGUI_CURSOR_HAND,
+    RTGUI_CURSOR_ARROW,
+    RTGUI_CURSOR_HAND,
 };
 
 void rtgui_cursor_set_device(const char* device_name);

+ 25 - 6
components/gui/include/rtgui/event.h

@@ -1,11 +1,21 @@
 /*
  * File      : event.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -41,6 +51,7 @@ enum _rtgui_event_type
     RTGUI_EVENT_WIN_CLOSE,             /* close a window        */
     RTGUI_EVENT_WIN_MOVE,              /* move a window         */
     RTGUI_EVENT_WIN_RESIZE,            /* resize a window       */
+    RTGUI_EVENT_WIN_UPDATE_END,        /* update done for window */
     RTGUI_EVENT_WIN_MODAL_ENTER,       /* the window is entering modal mode.
                                           This event should be sent after the
                                           window got setup and before the
@@ -169,6 +180,13 @@ struct rtgui_event_win_resize
     rtgui_rect_t rect;
 };
 
+struct rtgui_event_win_update_end
+{
+    _RTGUI_EVENT_WIN_ELEMENTS
+
+    rtgui_rect_t rect;
+};
+
 #define rtgui_event_win_destroy      rtgui_event_win
 #define rtgui_event_win_show         rtgui_event_win
 #define rtgui_event_win_hide         rtgui_event_win
@@ -187,6 +205,7 @@ struct rtgui_event_win_resize
 #define RTGUI_EVENT_WIN_CLOSE_INIT(e)       RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_CLOSE)
 #define RTGUI_EVENT_WIN_MOVE_INIT(e)        RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_MOVE)
 #define RTGUI_EVENT_WIN_RESIZE_INIT(e)      RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_RESIZE)
+#define RTGUI_EVENT_WIN_UPDATE_END_INIT(e)  RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_UPDATE_END)
 #define RTGUI_EVENT_WIN_MODAL_ENTER_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_MODAL_ENTER)
 
 /*
@@ -375,7 +394,7 @@ struct rtgui_event_kbd
 #define RTGUI_EVENT_KBD_INIT(e)             RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_KBD)
 
 /**
- * RTGUI Touch Event 
+ * RTGUI Touch Event
  * NOTE: There is not touch event to user applications, it's handled by server.
  */
 struct rtgui_event_touch

+ 15 - 5
components/gui/include/rtgui/filerw.h

@@ -1,11 +1,21 @@
 /*
  * File      : filerw.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 16 - 5
components/gui/include/rtgui/font.h

@@ -1,11 +1,21 @@
 /*
  * File      : font.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -17,6 +27,7 @@
 #include <rtgui/rtgui.h>
 #include <rtgui/list.h>
 
+
 #ifdef __cplusplus
 extern "C" {
 #endif

+ 40 - 16
components/gui/include/rtgui/font_fnt.h

@@ -1,3 +1,27 @@
+/*
+ * File      : font_fnt.h
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-04-10     Bernard      first version
+ */
+
 #ifndef __FONT_FNT_H__
 #define __FONT_FNT_H__
 
@@ -7,28 +31,28 @@
 /* fnt font header */
 struct fnt_header
 {
-	rt_uint8_t version[4];
-	rt_uint16_t max_width;
-	rt_uint16_t height;
-	rt_uint16_t ascent;
-	rt_uint16_t depth;
-	
-	rt_uint32_t first_char;
-	rt_uint32_t default_char;
-	rt_uint32_t size;
-	rt_uint32_t nbits;
-	rt_uint32_t noffset;
-	rt_uint32_t nwidth;
+    rt_uint8_t version[4];
+    rt_uint16_t max_width;
+    rt_uint16_t height;
+    rt_uint16_t ascent;
+    rt_uint16_t depth;
+
+    rt_uint32_t first_char;
+    rt_uint32_t default_char;
+    rt_uint32_t size;
+    rt_uint32_t nbits;
+    rt_uint32_t noffset;
+    rt_uint32_t nwidth;
 };
 typedef rt_uint8_t MWIMAGEBITS;
 
 struct fnt_font
 {
-	struct fnt_header header;
+    struct fnt_header header;
 
-	const MWIMAGEBITS *bits;   /* nbits */
-	const rt_uint16_t *offset; /* noffset */
-	const rt_uint8_t  *width;  /* nwidth */
+    const MWIMAGEBITS *bits;   /* nbits */
+    const rt_uint16_t *offset; /* noffset */
+    const rt_uint8_t  *width;  /* nwidth */
 };
 extern const struct rtgui_font_engine fnt_font_engine;
 

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

@@ -1,3 +1,27 @@
+/*
+ * File      : font_freetype.h
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-04-10     Bernard      first version
+ */
+
 #ifndef __RTGUI_FONT_TTF_H__
 #define __RTGUI_FONT_TTF_H__
 
@@ -8,7 +32,8 @@
 extern "C" {
 #endif
 
-rtgui_font_t *rtgui_freetype_font_create(const char *filename, int bold, int italic, rt_size_t size);
+void rtgui_ttf_system_init(void);
+rtgui_font_t *rtgui_freetype_font_create(const char *filename, rt_size_t size);
 void rtgui_freetype_font_destroy(rtgui_font_t *font);
 
 #ifdef __cplusplus

+ 15 - 5
components/gui/include/rtgui/image.h

@@ -1,11 +1,21 @@
 /*
  * File      : image.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 15 - 5
components/gui/include/rtgui/image_bmp.h

@@ -1,11 +1,21 @@
 /*
  * File      : image_bmp.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 58 - 0
components/gui/include/rtgui/image_container.h

@@ -0,0 +1,58 @@
+/*
+ * File      : image_container.h
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-04-10     Bernard      first version
+ */
+
+#ifndef __RTGUI_IMAGE_CONTAINER_H__
+#define __RTGUI_IMAGE_CONTAINER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtgui/rtgui.h>
+#include <rtgui/image.h>
+
+#if defined(RTGUI_IMAGE_CONTAINER)
+/* image item in image container */
+struct rtgui_image_item
+{
+    rtgui_image_t *image;
+    char *filename;
+
+    rt_uint32_t refcount;
+};
+typedef struct rtgui_image_item rtgui_image_item_t;
+
+void rtgui_system_image_container_init(void);
+
+struct rtgui_image_item *rtgui_image_container_get(const char *filename);
+void rtgui_image_container_put(struct rtgui_image_item *item);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 31 - 6
components/gui/include/rtgui/image_hdc.h

@@ -1,11 +1,21 @@
 /*
- * File      : image_xpm.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * File      : image_hdc.h
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -27,6 +37,21 @@ struct rtgui_image_hdcmm
     rt_uint8_t *pixels;
 };
 
+struct rtgui_image_hdc
+{
+    rt_bool_t is_loaded;
+
+    /* hdc image information */
+    rt_uint16_t byte_per_pixel;
+    rt_uint16_t pitch;
+    rt_uint8_t  pixel_format;
+
+    rt_size_t   pixel_offset;
+    rt_uint8_t *pixels;
+
+    struct rtgui_filerw *filerw;
+};
+
 void rtgui_image_hdc_init(void);
 extern const struct rtgui_image_engine rtgui_image_hdcmm_engine;
 

+ 0 - 8
components/gui/include/rtgui/image_jpeg.h

@@ -1,8 +0,0 @@
-#ifndef __RTGUI_IMAGE_JPEG_H__
-#define __RTGUI_IMAGE_JPEG_H__
-
-#include <rtgui/image.h>
-
-void rtgui_image_jpeg_init(void);
-
-#endif

+ 0 - 21
components/gui/include/rtgui/image_png.h

@@ -1,21 +0,0 @@
-/*
- * File      : image_png.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, 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
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_IMAGE_PNG_H__
-#define __RTGUI_IMAGE_PNG_H__
-
-#include <rtgui/image.h>
-
-void rtgui_image_png_init(void);
-
-#endif

+ 0 - 21
components/gui/include/rtgui/image_xpm.h

@@ -1,21 +0,0 @@
-/*
- * File      : image_xpm.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, 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
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_IMAGE_XPM_H__
-#define __RTGUI_IMAGE_XPM_H__
-
-#include <rtgui/image.h>
-
-void rtgui_image_xpm_init(void);
-
-#endif

+ 15 - 5
components/gui/include/rtgui/kbddef.h

@@ -1,11 +1,21 @@
 /*
  * File      : kbddef.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 15 - 5
components/gui/include/rtgui/list.h

@@ -1,11 +1,21 @@
 /*
  * File      : list.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 45 - 21
components/gui/include/rtgui/matrix.h

@@ -1,3 +1,27 @@
+/*
+ * File      : matrix.h
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-04-10     Grissiom     The first version
+ */
+
 #ifndef __MATRIX_H__
 #define __MATRIX_H__
 
@@ -12,7 +36,7 @@
  * this software and associated documentation files (the "Software"),  to deal in
  * the Software without restriction,  including without limitation the rights to
  * use,  copy,  modify,  merge,  publish,  distribute,  sublicense,  and/or sell copies of
- * the Software,  and to permit persons to whom the Software is furnished to do so, 
+ * the Software,  and to permit persons to whom the Software is furnished to do so,
  * subject to the following conditions:
  *
  * The above copyright notice and this permission notice shall be included in all
@@ -60,7 +84,7 @@ struct rtgui_matrix
      * fraction(m/RTGUI_MATRIX_FRAC). While the unit of m[4-5] is pixel.
      *
      */
-	int m[6];
+    int m[6];
 };
 
 rt_inline int32_t _rtgui_matrix_round_div32(int32_t n, int32_t d)
@@ -100,22 +124,22 @@ rt_inline void rtgui_matrix_mul(struct rtgui_matrix *mm,
                                 const struct rtgui_matrix *mm1,
                                 const struct rtgui_matrix *mm2)
 {
-	int *m = mm->m;
-	const int *m1 = mm1->m;
-	const int *m2 = mm2->m;
-
-	m[0] = _rtgui_matrix_round_div32(m1[0] * m2[0] + m1[1] * m2[2], RTGUI_MATRIX_FRAC);
-	m[1] = _rtgui_matrix_round_div32(m1[0] * m2[1] + m1[1] * m2[3], RTGUI_MATRIX_FRAC);
-	m[2] = _rtgui_matrix_round_div32(m1[2] * m2[0] + m1[3] * m2[2], RTGUI_MATRIX_FRAC);
-	m[3] = _rtgui_matrix_round_div32(m1[2] * m2[1] + m1[3] * m2[3], RTGUI_MATRIX_FRAC);
-	m[4] = _rtgui_matrix_round_div32(m1[4] * m2[0] + m1[5] * m2[2], RTGUI_MATRIX_FRAC) + m2[4];
-	m[5] = _rtgui_matrix_round_div32(m1[4] * m2[1] + m1[5] * m2[3], RTGUI_MATRIX_FRAC) + m2[5];
+    int *m = mm->m;
+    const int *m1 = mm1->m;
+    const int *m2 = mm2->m;
+
+    m[0] = _rtgui_matrix_round_div32(m1[0] * m2[0] + m1[1] * m2[2], RTGUI_MATRIX_FRAC);
+    m[1] = _rtgui_matrix_round_div32(m1[0] * m2[1] + m1[1] * m2[3], RTGUI_MATRIX_FRAC);
+    m[2] = _rtgui_matrix_round_div32(m1[2] * m2[0] + m1[3] * m2[2], RTGUI_MATRIX_FRAC);
+    m[3] = _rtgui_matrix_round_div32(m1[2] * m2[1] + m1[3] * m2[3], RTGUI_MATRIX_FRAC);
+    m[4] = _rtgui_matrix_round_div32(m1[4] * m2[0] + m1[5] * m2[2], RTGUI_MATRIX_FRAC) + m2[4];
+    m[5] = _rtgui_matrix_round_div32(m1[4] * m2[1] + m1[5] * m2[3], RTGUI_MATRIX_FRAC) + m2[5];
 }
 
 /* Matrix multiply point[(p) = (x, y) * m], ignore the movement components. */
 rt_inline void rtgui_matrix_mul_point_nomove(struct rtgui_point *p,
-                                             int x, int y,
-                                             struct rtgui_matrix *m)
+        int x, int y,
+        struct rtgui_matrix *m)
 {
     int *mm = m->m;
 
@@ -137,13 +161,13 @@ rt_inline void rtgui_matrix_mul_point(struct rtgui_point *p,
 /** Set @mm to an identity matrix. */
 rt_inline void rtgu_matrix_identity(struct rtgui_matrix *mm)
 {
-	int *mat = mm->m;
-	mat[0] = RTGUI_MATRIX_FRAC;
-	mat[1] = 0;
-	mat[2] = 0;
-	mat[3] = RTGUI_MATRIX_FRAC;
-	mat[4] = 0;
-	mat[5] = 0;
+    int *mat = mm->m;
+    mat[0] = RTGUI_MATRIX_FRAC;
+    mat[1] = 0;
+    mat[2] = 0;
+    mat[3] = RTGUI_MATRIX_FRAC;
+    mat[4] = 0;
+    mat[5] = 0;
 }
 
 /** Save the inversed matrix of @mm to @mo.

+ 21 - 7
components/gui/include/rtgui/region.h

@@ -1,11 +1,21 @@
 /*
  * File      : region.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -90,6 +100,7 @@ int rtgui_region_is_flat(rtgui_region_t *region);
 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_inflate(rtgui_rect_t *rect, int d);
 void rtgui_rect_intersect(rtgui_rect_t *src, rtgui_rect_t *dest);
@@ -98,11 +109,14 @@ int  rtgui_rect_is_intersect(const rtgui_rect_t *rect1, const rtgui_rect_t *rect
 int  rtgui_rect_is_equal(const rtgui_rect_t *rect1, const rtgui_rect_t *rect2);
 rtgui_rect_t *rtgui_rect_set(rtgui_rect_t *rect, int x, int y, int w, int h);
 rt_bool_t rtgui_rect_is_empty(const rtgui_rect_t *rect);
+void rtgui_rect_union(rtgui_rect_t *src, rtgui_rect_t *dest);
 
 rt_inline void rtgui_rect_init(rtgui_rect_t* rect, int x, int y, int width, int height)
 {
-	rect->x1 = x; rect->y1 = y;
-	rect->x2 = x + width; rect->y2 = y + height;
+    rect->x1 = x;
+    rect->y1 = y;
+    rect->x2 = x + width;
+    rect->y2 = y + height;
 }
 
 #define RTGUI_RECT(rect, x, y, w, h)	\

+ 13 - 21
components/gui/include/rtgui/rtgui.h

@@ -1,7 +1,7 @@
 /*
  * File      : rtgui.h
- * This file is part of RT-Thread GUI
- * COPYRIGHT (C) 2009 - 2013, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -31,19 +31,10 @@
 extern "C" {
 #endif
 
-#define RTGUI_VERSION          0L        /**< major version number */
-#define RTGUI_SUBVERSION       8L        /**< minor version number */
-#define RTGUI_REVISION         1L        /**< revise version number */
-#define RTGUI_CODENAME         "Newton"  /**< code name */
-
-#define RT_INT16_MAX        32767
-#define RT_INT16_MIN        (-RT_INT16_MAX-1)
-#define RTGUI_NOT_FOUND     (-1)
-
-#define _UI_MIN(x, y)			(((x)<(y))?(x):(y))
-#define _UI_MAX(x, y)			(((x)>(y))?(x):(y))
-#define _UI_BITBYTES(bits)		((bits + 7)/8)
-#define _UI_ABS(x)				((x)>=0? (x):-(x))
+#define _UI_MIN(x, y)           (((x)<(y))?(x):(y))
+#define _UI_MAX(x, y)           (((x)>(y))?(x):(y))
+#define _UI_BITBYTES(bits)      ((bits + 7)/8)
+#define _UI_ABS(x)              ((x)>=0? (x):-(x))
 
 /* MDK, GCC and MSVC all support __restrict keyword. */
 #define RTGUI_RESTRICT      __restrict
@@ -136,13 +127,13 @@ enum RTGUI_BORDER_STYLE
 
 /**
  * Blend mode
- */ 
+ */
 enum RTGUI_BLENDMODE
 {
-	RTGUI_BLENDMODE_NONE = 0x00, 
-	RTGUI_BLENDMODE_BLEND,
-	RTGUI_BLENDMODE_ADD,
-	RTGUI_BLENDMODE_MOD,
+    RTGUI_BLENDMODE_NONE = 0x00,
+    RTGUI_BLENDMODE_BLEND,
+    RTGUI_BLENDMODE_ADD,
+    RTGUI_BLENDMODE_MOD,
 };
 
 /**
@@ -180,7 +171,8 @@ enum RTGUI_TEXTSTYLE
 enum RTGUI_MODAL_CODE
 {
     RTGUI_MODAL_OK,
-    RTGUI_MODAL_CANCEL
+    RTGUI_MODAL_CANCEL,
+    RTGUI_MODAL_MAX = 0xFFFF,
 };
 typedef enum RTGUI_MODAL_CODE rtgui_modal_code_t;
 

+ 15 - 5
components/gui/include/rtgui/rtgui_app.h

@@ -1,11 +1,21 @@
 /*
  * File      : rtgui_app.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 15 - 5
components/gui/include/rtgui/rtgui_config.h

@@ -1,11 +1,21 @@
 /*
  * File      : rtgui_config.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 17 - 7
components/gui/include/rtgui/rtgui_object.h

@@ -1,11 +1,21 @@
 /*
  * File      : rtgui_object.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -81,10 +91,10 @@ const char    *rtgui_type_name_get(const rtgui_type_t *type);
 const rtgui_type_t *rtgui_object_object_type_get(rtgui_object_t *object);
 
 #ifdef RTGUI_USING_CAST_CHECK
-	#define RTGUI_OBJECT_CAST(obj, obj_type, c_type) \
+#define RTGUI_OBJECT_CAST(obj, obj_type, c_type) \
 	 	((c_type *)rtgui_object_check_cast((rtgui_object_t *)(obj), (obj_type), __FUNCTION__, __LINE__))
 #else
-	#define RTGUI_OBJECT_CAST(obj, obj_type, c_type)     ((c_type *)(obj))
+#define RTGUI_OBJECT_CAST(obj, obj_type, c_type)     ((c_type *)(obj))
 #endif
 
 #define RTGUI_OBJECT_CHECK_TYPE(_obj, _type) \

+ 23 - 6
components/gui/include/rtgui/rtgui_server.h

@@ -1,11 +1,21 @@
 /*
  * File      : rtgui_server.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -14,6 +24,10 @@
 #ifndef __RTGUI_SERVER_H__
 #define __RTGUI_SERVER_H__
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <rtservice.h>
 #include <rtgui/list.h>
 
@@ -72,8 +86,11 @@ void rtgui_server_install_show_win_hook(void (*hk)(void));
 void rtgui_server_install_act_win_hook(void (*hk)(void));
 
 /* post an event to server */
-void rtgui_server_post_event(struct rtgui_event *event, rt_size_t size);
+rt_err_t rtgui_server_post_event(struct rtgui_event *event, rt_size_t size);
 rt_err_t rtgui_server_post_event_sync(struct rtgui_event *event, rt_size_t size);
 
+#ifdef __cplusplus
+}
 #endif
 
+#endif

+ 15 - 5
components/gui/include/rtgui/rtgui_system.h

@@ -1,11 +1,21 @@
 /*
  * File      : rtgui_system.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 15 - 5
components/gui/include/rtgui/widgets/box.h

@@ -1,11 +1,21 @@
 /*
  * File      : box.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 15 - 5
components/gui/include/rtgui/widgets/container.h

@@ -1,11 +1,21 @@
 /*
  * File      : container.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 15 - 5
components/gui/include/rtgui/widgets/title.h

@@ -1,11 +1,21 @@
 /*
  * File      : title.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 6 - 6
components/gui/include/rtgui/widgets/widget.h

@@ -1,7 +1,7 @@
 /*
  * File      : widget.h
- * This file is part of RT-Thread GUI
- * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -110,6 +110,10 @@ struct rtgui_widget
 
     /* the widget extent */
     rtgui_rect_t extent;
+    /* the visiable extent (includes the rectangles of children) */
+    rtgui_rect_t extent_visiable;
+    /* the rect clip information */
+    rtgui_region_t clip;
 
     /* minimal width and height of widget */
     rt_int16_t min_width, min_height;
@@ -117,13 +121,10 @@ struct rtgui_widget
     rt_int32_t align;
     rt_uint16_t border;
     rt_uint16_t border_style;
-    /* the rect clip */
-    rtgui_region_t clip;
 
     /* call back */
     rt_bool_t (*on_focus_in)(struct rtgui_object *widget, struct rtgui_event *event);
     rt_bool_t (*on_focus_out)(struct rtgui_object *widget, struct rtgui_event *event);
-    rt_bool_t (*on_paint)(struct rtgui_object *widget, struct rtgui_event *event);
 
     /* user private data */
     rt_uint32_t user_data;
@@ -142,7 +143,6 @@ void rtgui_widget_unfocus(rtgui_widget_t *widget);
 /* event handler for each command */
 void rtgui_widget_set_onfocus(rtgui_widget_t *widget, rtgui_event_handler_ptr handler);
 void rtgui_widget_set_onunfocus(rtgui_widget_t *widget, rtgui_event_handler_ptr handler);
-void rtgui_widget_set_onpaint(rtgui_widget_t *widget, rtgui_event_handler_ptr handler);
 
 /* get and set rect of widget */
 void rtgui_widget_get_rect(rtgui_widget_t *widget, rtgui_rect_t *rect);

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

@@ -1,11 +1,21 @@
 /*
  * File      : window.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -80,6 +90,7 @@ struct rtgui_win
 
     /* drawing count */
     rt_base_t drawing;
+    struct rtgui_rect drawing_rect;
 
     /* parent window. RT_NULL if the window is a top level window */
     struct rtgui_win *parent_window;
@@ -135,9 +146,9 @@ rtgui_win_t *rtgui_mainwin_create(struct rtgui_win *parent_window, const char *t
 void rtgui_win_destroy(rtgui_win_t *win);
 
 int rtgui_win_init(struct rtgui_win *win, struct rtgui_win *parent_window,
-                              const char *title,
-                              rtgui_rect_t *rect,
-                              rt_uint16_t style);
+                   const char *title,
+                   rtgui_rect_t *rect,
+                   rt_uint16_t style);
 int rtgui_win_fini(struct rtgui_win* win);
 
 /** Close window.
@@ -183,6 +194,8 @@ struct rtgui_dc *rtgui_win_get_drawing(rtgui_win_t * win);
 struct rtgui_win* rtgui_win_get_topmost_shown(void);
 struct rtgui_win* rtgui_win_get_next_shown(void);
 
+void rtgui_theme_draw_win(struct rtgui_wintitle *wint);
+
 #ifdef __cplusplus
 }
 #endif

+ 15 - 5
components/gui/src/asc12font.c

@@ -1,11 +1,21 @@
 /*
  * File      : asc12font.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 271 - 261
components/gui/src/asc16font.c

@@ -1,11 +1,21 @@
 /*
  * File      : asc16font.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -16,262 +26,262 @@
 #ifdef RTGUI_USING_FONT16
 const unsigned char asc16_font[] =
 {
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,  
-	0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,  
-	0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00,  
-	0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00,  
-	0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,  
-	0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00,  
-	0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,  
-	0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,  
-	0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00,  
-	0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
-	0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
-	0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,  
-	0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00,  
-	0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,  
-	0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00,  
-	0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00,  
-	0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,  
-	0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,  
-	0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,  
-	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
-	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
-	0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
-	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
-	0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
-	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
-	0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
-	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
-	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
-	0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
-	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
-	0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
-	0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
-	0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
-	0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
-	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
-	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
-	0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
-	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
-	0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,  
-	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,  
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
-	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,  
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,  
+    0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,  
+    0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00,  
+    0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00,  
+    0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,  
+    0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00,  
+    0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,  
+    0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,  
+    0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00,  
+    0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
+    0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
+    0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,  
+    0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00,  
+    0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,  
+    0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00,  
+    0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00,  
+    0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,  
+    0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,  
+    0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,  
+    0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
+    0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
+    0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
+    0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
+    0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
+    0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
+    0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
+    0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
+    0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
+    0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,  
+    0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
+    0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  
+    0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,  
+    0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,  
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
+    0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,  
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  
 };
 
 struct rtgui_font_bitmap asc16 =

+ 592 - 269
components/gui/src/blit.c

@@ -1,7 +1,7 @@
 /*
  * File      : blit.h
- * This file is part of RT-Thread GUI
- * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -48,62 +48,74 @@
 #include <rtgui/rtgui.h>
 #include <rtgui/blit.h>
 #include <rtgui/color.h>
+#include <rtgui/region.h>
+#include <rtgui/dc.h>
 
 /* Lookup tables to expand partial bytes to the full 0..255 range */
 
-static const rt_uint8_t lookup_0[] = {
-0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
-32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
-96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
-122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
-147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171,
-172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
-197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
-222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
-247, 248, 249, 250, 251, 252, 253, 254, 255
+static const rt_uint8_t lookup_0[] =
+{
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+    64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+    96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+    122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
+    147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171,
+    172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
+    197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
+    222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
+    247, 248, 249, 250, 251, 252, 253, 254, 255
 };
 
-static const rt_uint8_t lookup_1[] = {
-0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
-64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
-120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166,
-168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214,
-216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 255
+static const rt_uint8_t lookup_1[] =
+{
+    0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
+    64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
+    120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166,
+    168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214,
+    216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 255
 };
 
-static const rt_uint8_t lookup_2[] = {
-0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 85, 89, 93, 97, 101, 105, 109, 113, 117,
-121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 214, 218,
-222, 226, 230, 234, 238, 242, 246, 250, 255
+static const rt_uint8_t lookup_2[] =
+{
+    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 85, 89, 93, 97, 101, 105, 109, 113, 117,
+    121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 214, 218,
+    222, 226, 230, 234, 238, 242, 246, 250, 255
 };
 
-static const rt_uint8_t lookup_3[] = {
-0, 8, 16, 24, 32, 41, 49, 57, 65, 74, 82, 90, 98, 106, 115, 123, 131, 139, 148, 156, 164, 172, 180, 189, 197, 205, 213, 222,
-230, 238, 246, 255
+static const rt_uint8_t lookup_3[] =
+{
+    0, 8, 16, 24, 32, 41, 49, 57, 65, 74, 82, 90, 98, 106, 115, 123, 131, 139, 148, 156, 164, 172, 180, 189, 197, 205, 213, 222,
+    230, 238, 246, 255
 };
 
-static const rt_uint8_t lookup_4[] = {
-0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255
+static const rt_uint8_t lookup_4[] =
+{
+    0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255
 };
 
-static const rt_uint8_t lookup_5[] = {
-0, 36, 72, 109, 145, 182, 218, 255
+static const rt_uint8_t lookup_5[] =
+{
+    0, 36, 72, 109, 145, 182, 218, 255
 };
 
-static const rt_uint8_t lookup_6[] = {
-0, 85, 170, 255
+static const rt_uint8_t lookup_6[] =
+{
+    0, 85, 170, 255
 };
 
-static const rt_uint8_t lookup_7[] = {
-0, 255
+static const rt_uint8_t lookup_7[] =
+{
+    0, 255
 };
 
-static const rt_uint8_t lookup_8[] = {
-255
+static const rt_uint8_t lookup_8[] =
+{
+    255
 };
 
-const rt_uint8_t* rtgui_blit_expand_byte[9] = {
+const rt_uint8_t* rtgui_blit_expand_byte[9] =
+{
     lookup_0,
     lookup_1,
     lookup_2,
@@ -190,34 +202,39 @@ static void rtgui_blit_line_4_2(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int li
     rt_uint32_t *srcp = (rt_uint32_t *) src_ptr;
     rt_uint16_t *dstp = (rt_uint16_t *) dst_ptr;
 
-	/* *INDENT-OFF* */
-	DUFFS_LOOP4({
-	rt_uint32_t s = *srcp;
-	unsigned alpha = s >> 27; /* 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)) {
-		*dstp = (rt_uint16_t)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3  & 0x1f));
-	  } else {
-		rt_uint32_t d = *dstp;
-		/*
-		 * convert source and destination to G0RAB65565
-		 * and blend all components at the same time
-		 */
-		s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800)
-		  + (s >> 3 & 0x1f);
-		d = (d | d << 16) & 0x07e0f81f;
-		d += (s - d) * alpha >> 5;
-		d &= 0x07e0f81f;
-		*dstp = (rt_uint16_t)(d | d >> 16);
-	  }
-	}
-	srcp++;
-	dstp++;
-	}, width);
+    /* *INDENT-OFF* */
+    DUFFS_LOOP4(
+    {
+        rt_uint32_t s = *srcp;
+        unsigned alpha = s >> 27; /* 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))
+            {
+                *dstp = (rt_uint16_t)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3  & 0x1f));
+            }
+            else
+            {
+                rt_uint32_t d = *dstp;
+                /*
+                 * convert source and destination to G0RAB65565
+                 * and blend all components at the same time
+                 */
+                s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800)
+                    + (s >> 3 & 0x1f);
+                d = (d | d << 16) & 0x07e0f81f;
+                d += (s - d) * alpha >> 5;
+                d &= 0x07e0f81f;
+                *dstp = (rt_uint16_t)(d | d >> 16);
+            }
+        }
+        srcp++;
+        dstp++;
+    }, width);
 }
 
 static void rtgui_blit_line_1_3(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
@@ -362,7 +379,8 @@ static const rt_uint32_t RGB565_RGBA8888_LUT[512] =
 };
 
 /* Special optimized blit for RGB 5-6-5 --> ARGB 8-8-8-8 */
-static const rt_uint32_t RGB565_ARGB8888_LUT[512] = {
+static const rt_uint32_t RGB565_ARGB8888_LUT[512] =
+{
     0x00000000, 0xff000000, 0x00000008, 0xff002000,
     0x00000010, 0xff004000, 0x00000018, 0xff006100,
     0x00000020, 0xff008100, 0x00000029, 0xff00a100,
@@ -635,13 +653,13 @@ rtgui_blit_line_func rtgui_blit_line_get_inv(int dst_bpp, int src_bpp)
 
 /* 16bpp special case for per-surface alpha=50%: blend 2 pixels in parallel */
 /* blend a single 16 bit pixel at 50% */
-#define BLEND16_50(d, s, mask)						\
-	((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff)))
+#define BLEND16_50(d, s, mask)                      \
+    ((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff)))
 
 /* blend two 16 bit pixels at 50% */
-#define BLEND2x16_50(d, s, mask)					     \
-	(((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \
-	 + (s & d & (~(mask | mask << 16))))
+#define BLEND2x16_50(d, s, mask)                         \
+    (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \
+     + (s & d & (~(mask | mask << 16))))
 
 static void
 Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask)
@@ -653,8 +671,10 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask)
     rt_uint16_t *dstp = (rt_uint16_t *) info->dst;
     int dstskip = info->dst_skip >> 1;
 
-    while (height--) {
-        if (((unsigned int) srcp ^ (unsigned int) dstp) & 2) {
+    while (height--)
+    {
+        if (((unsigned int) srcp ^ (unsigned int) dstp) & 2)
+        {
             /*
              * Source and destination not aligned, pipeline it.
              * This is mostly a win for big blits but no loss for
@@ -664,7 +684,8 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask)
             int w = width;
 
             /* handle odd destination */
-            if ((unsigned int) dstp & 2) {
+            if ((unsigned int) dstp & 2)
+            {
                 rt_uint16_t d = *dstp, s = *srcp;
                 *dstp = BLEND16_50(d, s, mask);
                 dstp++;
@@ -676,7 +697,8 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask)
             /* bootstrap pipeline with first halfword */
             prev_sw = ((rt_uint32_t *) srcp)[-1];
 
-            while (w > 1) {
+            while (w > 1)
+            {
                 rt_uint32_t sw, dw, s;
                 sw = *(rt_uint32_t *) srcp;
                 dw = *(rt_uint32_t *) dstp;
@@ -689,7 +711,8 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask)
             }
 
             /* final pixel if any */
-            if (w) {
+            if (w)
+            {
                 rt_uint16_t d = *dstp, s;
                 s = (rt_uint16_t) (prev_sw >> 16);
                 *dstp = BLEND16_50(d, s, mask);
@@ -698,12 +721,15 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask)
             }
             srcp += srcskip - 1;
             dstp += dstskip;
-        } else {
+        }
+        else
+        {
             /* source and destination are aligned */
             int w = width;
 
             /* first odd pixel? */
-            if ((unsigned int) srcp & 2) {
+            if ((unsigned int) srcp & 2)
+            {
                 rt_uint16_t d = *dstp, s = *srcp;
                 *dstp = BLEND16_50(d, s, mask);
                 srcp++;
@@ -712,7 +738,8 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask)
             }
             /* srcp and dstp are now 32-bit aligned */
 
-            while (w > 1) {
+            while (w > 1)
+            {
                 rt_uint32_t sw = *(rt_uint32_t *) srcp;
                 rt_uint32_t dw = *(rt_uint32_t *) dstp;
                 *(rt_uint32_t *) dstp = BLEND2x16_50(dw, sw, mask);
@@ -722,7 +749,8 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask)
             }
 
             /* last odd pixel? */
-            if (w) {
+            if (w)
+            {
                 rt_uint16_t d = *dstp, s = *srcp;
                 *dstp = BLEND16_50(d, s, mask);
                 srcp++;
@@ -774,7 +802,8 @@ Blit565to565PixelAlpha(struct rtgui_blit_info * info)
         rt_uint32_t *srcp = (rt_uint32_t *) info->src;
         rt_uint32_t *dstp = (rt_uint32_t *) info->dst;
 
-        while (height--) {
+        while (height--)
+        {
             DUFFS_LOOP4(
             {
                 rt_uint32_t s = *srcp++;
@@ -814,62 +843,140 @@ Blit565to565PixelAlpha(struct rtgui_blit_info * info)
 /* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */
 static void BlitRGBtoRGBSurfaceAlpha128(struct rtgui_blit_info *info)
 {
-	int width = info->dst_w;
-	int height = info->dst_h;
-	rt_uint32_t *srcp = (rt_uint32_t *)info->src;
-	int srcskip = info->src_skip >> 2;
-	rt_uint32_t *dstp = (rt_uint32_t *)info->dst;
-	int dstskip = info->dst_skip >> 2;
-
-	while(height--) {
-	    DUFFS_LOOP4({
-		    rt_uint32_t s = *srcp++;
-		    rt_uint32_t d = *dstp;
-		    *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1)
-			       + (s & d & 0x00010101)) | 0xff000000;
-	    }, width);
-	    srcp += srcskip;
-	    dstp += dstskip;
-	}
+    int width = info->dst_w;
+    int height = info->dst_h;
+    rt_uint32_t *srcp = (rt_uint32_t *)info->src;
+    int srcskip = info->src_skip >> 2;
+    rt_uint32_t *dstp = (rt_uint32_t *)info->dst;
+    int dstskip = info->dst_skip >> 2;
+
+    while(height--)
+    {
+        DUFFS_LOOP4(
+        {
+            rt_uint32_t s = *srcp++;
+            rt_uint32_t d = *dstp;
+            *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1)
+            + (s & d & 0x00010101)) | 0xff000000;
+        }, width);
+        srcp += srcskip;
+        dstp += dstskip;
+    }
 }
 
 /* fast RGB888->(A)RGB888 blending with surface alpha */
 static void BlitRGBtoRGBSurfaceAlpha(struct rtgui_blit_info *info)
 {
-	unsigned int alpha = info->a;
-	if(alpha == 128) {
-		BlitRGBtoRGBSurfaceAlpha128(info);
-	} else {
-		int width = info->dst_w;
-		int height = info->dst_h;
-		rt_uint32_t *srcp = (rt_uint32_t *)info->src;
-		int srcskip = info->src_skip >> 2;
-		rt_uint32_t *dstp = (rt_uint32_t *)info->dst;
-		int dstskip = info->dst_skip >> 2;
-
-		while(height--) {
-			DUFFS_LOOP4({
-				rt_uint32_t s;
-				rt_uint32_t d;
-				rt_uint32_t s1;
-				rt_uint32_t d1;
-				s = *srcp;
-				d = *dstp;
-				s1 = s & 0xff00ff;
-				d1 = d & 0xff00ff;
-				d1 = (d1 + ((s1 - d1) * alpha >> 8))
-				     & 0xff00ff;
-				s &= 0xff00;
-				d &= 0xff00;
-				d = (d + ((s - d) * alpha >> 8)) & 0xff00;
-				*dstp = d1 | d | 0xff000000;
-				++srcp;
-				++dstp;
-			}, width);
-			srcp += srcskip;
-			dstp += dstskip;
-		}
-	}
+    unsigned int alpha = info->a;
+    if(alpha == 128)
+    {
+        BlitRGBtoRGBSurfaceAlpha128(info);
+    }
+    else
+    {
+        int width = info->dst_w;
+        int height = info->dst_h;
+        rt_uint32_t *srcp = (rt_uint32_t *)info->src;
+        int srcskip = info->src_skip >> 2;
+        rt_uint32_t *dstp = (rt_uint32_t *)info->dst;
+        int dstskip = info->dst_skip >> 2;
+
+        while(height--)
+        {
+            DUFFS_LOOP4(
+            {
+                rt_uint32_t s;
+                rt_uint32_t d;
+                rt_uint32_t s1;
+                rt_uint32_t d1;
+                s = *srcp;
+                d = *dstp;
+                s1 = s & 0xff00ff;
+                d1 = d & 0xff00ff;
+                d1 = (d1 + ((s1 - d1) * alpha >> 8))
+                & 0xff00ff;
+                s &= 0xff00;
+                d &= 0xff00;
+                d = (d + ((s - d) * alpha >> 8)) & 0xff00;
+                *dstp = d1 | d | 0xff000000;
+                ++srcp;
+                ++dstp;
+            }, width);
+            srcp += srcskip;
+            dstp += dstskip;
+        }
+    }
+}
+
+/* fast alpha -> RGB565 blending with pixel alpha */
+static void BlitAlphato565PixelAlpha(struct rtgui_blit_info * info)
+{
+    rt_uint32_t srcpixel, dstpixel;
+    rt_uint32_t srcR, srcG, srcB, srcA;
+
+
+    srcR = info->r;
+    srcG = info->g;
+    srcB = info->b;
+
+    while (info->dst_h--)
+    {
+        rt_uint8_t *src = (rt_uint8_t *)info->src;
+        rt_uint16_t *dst = (rt_uint16_t *)info->dst;
+        int n = info->dst_w;
+        while (n--)
+        {
+            srcA = (rt_uint8_t)(*src);
+            ARGB8888_FROM_RGBA(srcpixel, srcR, srcG, srcB, srcA);
+
+            /* not do alpha blend */
+            if (srcA == 255)
+            {
+                dstpixel = srcpixel;
+            }
+            else if (srcA >> 3 == 0)
+            {
+                /* keep original pixel data */
+            }
+            else
+            {
+                dstpixel = ((rt_uint32_t)srcA << 24) | ((rt_uint32_t)srcR << 16) | ((rt_uint32_t)srcG << 8) | srcB;
+            }
+
+            if (srcA >> 3 != 0)
+            {
+                rt_uint32_t s = dstpixel;
+                unsigned alpha = s >> 27;
+                if (alpha)
+                {
+                    if (alpha == (255 >> 3))
+                    {
+                        *dst = (rt_uint16_t)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f));
+                    }
+                    else
+                    {
+                        rt_uint32_t d = *dst;
+                        /*
+                        * convert source and destination to G0RAB65565
+                        * and blend all components at the same time
+                        */
+                        s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800)
+                            + (s >> 3 & 0x1f);
+                        d = (d | d << 16) & 0x07e0f81f;
+                        d += (s - d) * alpha >> 5;
+                        d &= 0x07e0f81f;
+                        *dst = (rt_uint16_t)(d | d >> 16);
+                    }
+                }
+            }
+
+            ++src;
+            ++dst;
+        }
+
+        info->src += info->src_pitch;
+        info->dst += info->dst_pitch;
+    }
 }
 
 /* fast ARGB8888->RGB565 blending with pixel alpha */
@@ -882,36 +989,42 @@ static void BlitARGBto565PixelAlpha(struct rtgui_blit_info * info)
     rt_uint16_t *dstp = (rt_uint16_t *) info->dst;
     int dstskip = info->dst_skip >> 1;
 
-    while (height--) {
-	    /* *INDENT-OFF* */
-	    DUFFS_LOOP4({
-		rt_uint32_t s = *srcp;
-		unsigned alpha = s >> 27; /* 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)) {
-		    *dstp = (rt_uint16_t)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3  & 0x1f));
-		  } else {
-		    rt_uint32_t d = *dstp;
-		    /*
-		     * convert source and destination to G0RAB65565
-		     * and blend all components at the same time
-		     */
-		    s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800)
-		      + (s >> 3 & 0x1f);
-		    d = (d | d << 16) & 0x07e0f81f;
-		    d += (s - d) * alpha >> 5;
-		    d &= 0x07e0f81f;
-		    *dstp = (rt_uint16_t)(d | d >> 16);
-		  }
-		}
-		srcp++;
-		dstp++;
-	    }, width);
-	    /* *INDENT-ON* */
+    while (height--)
+    {
+        /* *INDENT-OFF* */
+        DUFFS_LOOP4(
+        {
+            rt_uint32_t s = *srcp;
+            unsigned alpha = s >> 27; /* 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))
+                {
+                    *dstp = (rt_uint16_t)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3  & 0x1f));
+                }
+                else
+                {
+                    rt_uint32_t d = *dstp;
+                    /*
+                     * convert source and destination to G0RAB65565
+                     * and blend all components at the same time
+                     */
+                    s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800)
+                        + (s >> 3 & 0x1f);
+                    d = (d | d << 16) & 0x07e0f81f;
+                    d += (s - d) * alpha >> 5;
+                    d &= 0x07e0f81f;
+                    *dstp = (rt_uint16_t)(d | d >> 16);
+                }
+            }
+            srcp++;
+            dstp++;
+        }, width);
+        /* *INDENT-ON* */
         srcp += srcskip;
         dstp += dstskip;
     }
@@ -920,49 +1033,120 @@ static void BlitARGBto565PixelAlpha(struct rtgui_blit_info * info)
 /* fast ARGB888->(A)RGB888 blending with pixel alpha */
 static void BlitRGBtoRGBPixelAlpha(struct rtgui_blit_info *info)
 {
-	int width = info->dst_w;
-	int height = info->dst_h;
-	rt_uint32_t *srcp = (rt_uint32_t *)info->src;
-	int srcskip = info->src_skip >> 2;
-	rt_uint32_t *dstp = (rt_uint32_t *)info->dst;
-	int dstskip = info->dst_skip >> 2;
-
-	while(height--) {
-	    DUFFS_LOOP4({
-		rt_uint32_t dalpha;
-		rt_uint32_t d;
-		rt_uint32_t s1;
-		rt_uint32_t d1;
-		rt_uint32_t s = *srcp;
-		rt_uint32_t alpha = s >> 24;
-            
-		/* 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) {
-		    *dstp = (s & 0x00ffffff) | (*dstp & 0xff000000);
-		} else {
-		    /*
-		     * take out the middle component (green), and process
-		     * the other two in parallel. One multiply less.
-		     */
-		    d = *dstp;
-		    dalpha = d & 0xff000000;
-		    s1 = s & 0xff00ff;
-		    d1 = d & 0xff00ff;
-		    d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff;
-		    s &= 0xff00;
-		    d &= 0xff00;
-		    d = (d + ((s - d) * alpha >> 8)) & 0xff00;
-		    *dstp = d1 | d | dalpha;
-		}
-		++srcp;
-		++dstp;
-	    }, width);
-	    srcp += srcskip;
-	    dstp += dstskip;
-	}
+    int width = info->dst_w;
+    int height = info->dst_h;
+    rt_uint32_t *srcp = (rt_uint32_t *)info->src;
+    int srcskip = info->src_skip >> 2;
+    rt_uint32_t *dstp = (rt_uint32_t *)info->dst;
+    int dstskip = info->dst_skip >> 2;
+
+    while(height--)
+    {
+        DUFFS_LOOP4(
+        {
+            rt_uint32_t dalpha;
+            rt_uint32_t d;
+            rt_uint32_t s1;
+            rt_uint32_t d1;
+            rt_uint32_t s = *srcp;
+            rt_uint32_t alpha = s >> 24;
+
+            /* 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)
+            {
+                *dstp = (s & 0x00ffffff) | (*dstp & 0xff000000);
+            }
+            else {
+                /*
+                 * take out the middle component (green), and process
+                 * the other two in parallel. One multiply less.
+                 */
+                d = *dstp;
+                dalpha = d & 0xff000000;
+                s1 = s & 0xff00ff;
+                d1 = d & 0xff00ff;
+                d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff;
+                s &= 0xff00;
+                d &= 0xff00;
+                d = (d + ((s - d) * alpha >> 8)) & 0xff00;
+                *dstp = d1 | d | dalpha;
+            }
+            ++srcp;
+            ++dstp;
+        }, width);
+        srcp += srcskip;
+        dstp += dstskip;
+    }
+}
+
+static void BlitAlphatoARGB8888PixelAlpha(struct rtgui_blit_info *info)
+{
+    rt_uint32_t srcpixel;
+    rt_uint32_t srcR, srcG, srcB, srcA;
+    rt_uint32_t dstpixel;
+    rt_uint32_t dstR, dstG, dstB, dstA;
+
+    srcR = info->r;
+    srcG = info->g;
+    srcB = info->b;
+
+    while (info->dst_h--)
+    {
+        rt_uint8_t *src = (rt_uint8_t *)info->src;
+        rt_uint32_t *dst = (rt_uint32_t *)info->dst;
+        int n = info->dst_w;
+        while (n--)
+        {
+            srcA = (rt_uint8_t)(*src);
+            ARGB8888_FROM_RGBA(srcpixel, srcR, srcG, srcB, srcA);
+
+            /* not do alpha blend */
+            if (srcA == 255)
+            {
+                *dst = srcpixel;
+            }
+            else if (srcA >> 3 == 0)
+            {
+                /* keep original pixel data */
+            }
+            else
+            {
+                dstpixel = *dst;
+                dstA = (rt_uint8_t)(dstpixel >> 24);
+                dstR = (rt_uint8_t)(dstpixel >> 16);
+                dstG = (rt_uint8_t)(dstpixel >> 8);
+                dstB = (rt_uint8_t)dstpixel;
+
+                if (dstA)
+                {
+                    int alpha = srcA + 1;
+                    int inverse_alpha = 257 - alpha;
+
+                    dstR = ((srcR * alpha) + (inverse_alpha * dstR)) >> 8;
+                    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 = ((rt_uint32_t)srcA << 24) | ((rt_uint32_t)srcR << 16) | ((rt_uint32_t)srcG << 8) | srcB;
+                }
+
+                *dst = dstpixel;
+            }
+
+            ++src;
+            ++dst;
+        }
+
+        info->src += info->src_pitch;
+        info->dst += info->dst_pitch;
+    }
 }
 
 static void BlitARGB8888toARGB8888PixelAlpha(struct rtgui_blit_info *info)
@@ -972,23 +1156,50 @@ static void BlitARGB8888toARGB8888PixelAlpha(struct rtgui_blit_info *info)
     rt_uint32_t dstpixel;
     rt_uint32_t dstR, dstG, dstB, dstA;
 
-    while (info->dst_h--) {
+    while (info->dst_h--)
+    {
         rt_uint32_t *src = (rt_uint32_t *)info->src;
         rt_uint32_t *dst = (rt_uint32_t *)info->dst;
         int n = info->dst_w;
-        while (n--) {
+        while (n--)
+        {
             srcpixel = *src;
-            srcA = (rt_uint8_t)(srcpixel >> 24); srcR = (rt_uint8_t)(srcpixel >> 16); srcG = (rt_uint8_t)(srcpixel >> 8); srcB = (rt_uint8_t)srcpixel;
-            dstpixel = *dst;
-            dstA = (rt_uint8_t)(dstpixel >> 24); dstR = (rt_uint8_t)(dstpixel >> 16); dstG = (rt_uint8_t)(dstpixel >> 8); dstB = (rt_uint8_t)dstpixel;
+            srcA = (rt_uint8_t)(srcpixel >> 24);
 
-            dstR = srcR + ((255 - srcA) * dstR) / 255;
-            dstG = srcG + ((255 - srcA) * dstG) / 255;
-            dstB = srcB + ((255 - srcA) * dstB) / 255;
-            dstA = srcA + ((255 - srcA) * dstA) / 255;
+            /* not do alpha blend */
+            if (srcA == 255)
+            {
+                *dst = srcpixel;
+            }
+            else if (srcA == 0)
+            {
+                /* keep original pixel data */
+            }
+            else
+            {
+                srcR = (rt_uint8_t)(srcpixel >> 16);
+                srcG = (rt_uint8_t)(srcpixel >> 8);
+                srcB = (rt_uint8_t)srcpixel;
+                dstpixel = *dst;
+                dstA = (rt_uint8_t)(dstpixel >> 24);
+                dstR = (rt_uint8_t)(dstpixel >> 16);
+                dstG = (rt_uint8_t)(dstpixel >> 8);
+                dstB = (rt_uint8_t)dstpixel;
+
+                {
+                    int alpha = srcA + 1;
+                    int inverse_alpha = 257 - alpha;
+
+                    dstR = ((srcR * alpha) + (inverse_alpha * dstR)) >> 8;
+                    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;
+                *dst = dstpixel;
+            }
 
-            dstpixel = ((rt_uint32_t)dstA << 24) | ((rt_uint32_t)dstR << 16) | ((rt_uint32_t)dstG << 8) | dstB;
-            *dst = dstpixel;
             ++src;
             ++dst;
         }
@@ -1015,7 +1226,8 @@ BlitRGB565to32(struct rtgui_blit_info * info, const rt_uint32_t* map)
     dst = (rt_uint32_t *) info->dst;
     dstskip = info->dst_skip / 4;
 
-    while (height--) {
+    while (height--)
+    {
         /* *INDENT-OFF* */
         DUFFS_LOOP(
         {
@@ -1049,7 +1261,7 @@ void rtgui_blit(struct rtgui_blit_info * info)
     {
         info->dst_w = info->src_w;
         info->dst_skip  = info->dst_pitch - info->dst_w *
-                         rtgui_color_get_bpp(info->dst_fmt);
+                          rtgui_color_get_bpp(info->dst_fmt);
     }
     else if (info->src_w > info->dst_w)
     {
@@ -1060,64 +1272,175 @@ void rtgui_blit(struct rtgui_blit_info * info)
     if (info->src_h < info->dst_h)
         info->dst_h = info->src_h;
 
-	if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB565)
-	{
-		if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB565)
-			Blit565to565PixelAlpha(info);
-		else if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888)
-			BlitRGB565toARGB8888(info);
-	}
-	else if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888)
-	{
-		if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB565)
-			BlitARGBto565PixelAlpha(info);
-		else if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB888)
-			BlitRGBtoRGBPixelAlpha(info);
-		else if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888)
-			BlitARGB8888toARGB8888PixelAlpha(info);
-	}
+    if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB565)
+    {
+        if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB565)
+            Blit565to565PixelAlpha(info);
+        else if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888)
+            BlitRGB565toARGB8888(info);
+    }
+    else if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888)
+    {
+        switch (info->dst_fmt)
+        {
+        case RTGRAPHIC_PIXEL_FORMAT_RGB565:
+            BlitARGBto565PixelAlpha(info);
+            break;
+        case RTGRAPHIC_PIXEL_FORMAT_RGB888:
+            BlitRGBtoRGBPixelAlpha(info);
+            break;
+        case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
+            BlitARGB8888toARGB8888PixelAlpha(info);
+            break;
+        }
+    }
     else if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB888)
     {
         if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888)
             BlitRGBtoRGBSurfaceAlpha(info);
     }
+    else if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_ALPHA)
+    {
+        switch (info->dst_fmt)
+        {
+        case RTGRAPHIC_PIXEL_FORMAT_RGB565:
+            BlitAlphato565PixelAlpha(info);
+            break;
+        case RTGRAPHIC_PIXEL_FORMAT_RGB888:
+            break;
+        case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
+            BlitAlphatoARGB8888PixelAlpha(info);
+            break;
+        }
+    }
 }
 RTM_EXPORT(rtgui_blit);
 
-#if 0
-void rtgui_blit_client(rtgui_blit_info_src* src, struct rtgui_dc* client, struct rtgui_rect *dc_rect)
+void rtgui_image_info_blit(struct rtgui_image_info* image, struct rtgui_dc* dc, struct rtgui_rect *dc_rect)
 {
-	int index;
-	struct rtgui_widget* widget;
-	rtgui_region_t clip_region;
-	rtgui_rect_t rect;
-
-	/* get owner widget */
-    widget = RTGUI_CONTAINER_OF(client, struct rtgui_widget, dc_type);
-	/* get rect information */
-	if (dc_rect == NULL) rtgui_dc_get_rect(client, &rect);
-	else rect = *dc_rect;
-
-	/* to device */
-	rtgui_rect_moveto(&rect, widget->extent.x1, widget->extent.y1);
-	/* get the clipped region */
-    rtgui_region_intersect_rect(&clip_region, &widget->clip, &rect);
-
-	/* only 1 rect in extant */
-	if (clip_region.data == RT_NULL)
-	{
-		struct rtgui_blit_info info;
-	}
-	else
-	{
-		/* blit on each rect */
-	    for (index = 0; index < clip_region.data.numRects; index ++)
-	    {
-	    }
-	}
-
-    rtgui_region_fini(&clip_region);
-}
-RTM_EXPORT(rtgui_blit_client);
-#endif
+    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;
+
+    hw_driver = rtgui_graphic_driver_get_default();
+    dest_extent = *dc_rect;
+
+    if (dc->type == RTGUI_DC_CLIENT && hw_driver->framebuffer)
+    {
+        int index, num_rects;
+        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);
+
+        owner = RTGUI_CONTAINER_OF(dc, struct rtgui_widget, dc_type);
+        rtgui_widget_rect_to_device(owner, &dest_extent);
 
+        /* get intersect region clip */
+        rtgui_region_init_with_extents(&dest_region, &dest_extent);
+        rtgui_region_intersect_rect(&dest_region, &(owner->clip), &dest_extent);
+
+        num_rects = rtgui_region_num_rects(&dest_region);
+        rects = rtgui_region_rects(&dest_region);
+
+        /* fill common info */
+        info.a = image->a;
+        info.src_fmt = image->src_fmt;
+        info.src_pitch = image->src_pitch;
+
+        info.dst_fmt = hw_driver->pixel_format;
+        info.dst_pitch = hw_driver->pitch;
+
+        for (index = 0; index < num_rects; index ++)
+        {
+            struct rtgui_rect *r = &rects[index];
+
+            /* blit source */
+            info.src = image->pixels + (r->x1 - dest_extent.x1) * bpp + (r->y1 - dest_extent.y1) * image->src_pitch;
+            info.src_h = rtgui_rect_height(*r);
+            info.src_w = rtgui_rect_width(*r);
+            info.src_skip = info.src_pitch - info.src_w * bpp;
+
+            /* blit destination */
+            info.dst = (rt_uint8_t*)hw_driver->framebuffer + r->y1 * hw_driver->pitch +
+                       r->x1 * hw_bpp;
+            info.dst_h = rtgui_rect_height(*r);
+            info.dst_w = rtgui_rect_width(*r);
+            info.dst_skip = info.dst_pitch - info.dst_w * hw_bpp;
+
+            rtgui_blit(&info);
+        }
+
+        rtgui_region_fini(&dest_region);
+    }
+    else if (dc->type == RTGUI_DC_HW && hw_driver->framebuffer)
+    {
+        struct rtgui_dc_hw *hw = (struct rtgui_dc_hw *)dc;
+        struct rtgui_rect *r;
+
+        bpp = rtgui_color_get_bpp(image->src_fmt);
+        hw_bpp = rtgui_color_get_bpp(hw_driver->pixel_format);
+
+        owner = hw->owner;
+        rtgui_widget_rect_to_device(owner, &dest_extent);
+        r = &dest_extent;
+
+        /* fill common info */
+        info.a = image->a;
+        info.src_fmt = image->src_fmt;
+        info.src_pitch = image->src_pitch;
+
+        info.dst_fmt = hw_driver->pixel_format;
+        info.dst_pitch = hw_driver->pitch;
+
+        /* blit source */
+        info.src = image->pixels;
+        info.src_h = rtgui_rect_height(*r);
+        info.src_w = rtgui_rect_width(*r);
+        info.src_skip = info.src_pitch - info.src_w * bpp;
+
+        /* blit destination */
+        info.dst = (rt_uint8_t*)hw_driver->framebuffer + r->y1 * hw_driver->pitch + r->x1 * hw_bpp;
+        info.dst_h = rtgui_rect_height(*r);
+        info.dst_w = rtgui_rect_width(*r);
+        info.dst_skip = info.dst_pitch - info.dst_w * hw_bpp;
+
+        rtgui_blit(&info);
+    }
+    else if (dc->type == RTGUI_DC_BUFFER)
+    {
+        struct rtgui_rect *r;
+        struct rtgui_dc_buffer *dc_buffer = (struct rtgui_dc_buffer*)dc;
+
+        bpp = rtgui_color_get_bpp(image->src_fmt);
+        hw_bpp = rtgui_color_get_bpp(dc_buffer->pixel_format);
+
+        r = &dest_extent;
+
+        /* fill common info */
+        info.a = image->a;
+        info.src_fmt = image->src_fmt;
+        info.src_pitch = image->src_pitch;
+
+        info.dst_fmt = dc_buffer->pixel_format;
+        info.dst_pitch = dc_buffer->pitch;
+
+        /* blit source */
+        info.src = image->pixels;
+        info.src_w = rtgui_rect_width(*r);
+        info.src_h = rtgui_rect_height(*r);
+        info.src_skip = info.src_pitch - info.src_w * bpp;
+
+        /* blit destination */
+        info.dst = (rt_uint8_t*)dc_buffer->pixel + r->y1 * dc_buffer->pitch + r->x1 * hw_bpp;
+        info.dst_w = rtgui_rect_width(*r);
+        info.dst_h = rtgui_rect_height(*r);
+        info.dst_skip = info.dst_pitch - info.dst_w * hw_bpp;
+
+        rtgui_blit(&info);
+    }
+}
+RTM_EXPORT(rtgui_image_info_blit);

+ 15 - 5
components/gui/src/box.c

@@ -1,11 +1,21 @@
 /*
  * File      : box.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 15 - 5
components/gui/src/color.c

@@ -1,11 +1,21 @@
 /*
  * File      : color.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 44 - 8
components/gui/src/container.c

@@ -1,11 +1,21 @@
 /*
  * File      : container.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -49,15 +59,41 @@ rt_bool_t rtgui_container_dispatch_event(rtgui_container_t *container, rtgui_eve
 {
     /* handle in child widget */
     struct rtgui_list_node *node;
+    rtgui_event_t _event, save_event = *event;
+    rtgui_widget_t *widget = (rtgui_widget_t *)container;
 
     rtgui_list_foreach(node, &(container->children))
     {
         struct rtgui_widget *w;
         w = rtgui_list_entry(node, struct rtgui_widget, sibling);
 
+        _event = save_event;
+
+        if (RTGUI_EVENT_PAINT & _event.type)
+        {
+            if (widget->extent.x1 > w->extent.x2)
+            {
+                _event.type &= !RTGUI_EVENT_PAINT;
+            }
+            else if (widget->extent.x2 < w->extent.x1)
+            {
+                _event.type &= !RTGUI_EVENT_PAINT;
+            }
+            else if (widget->extent.y1 > w->extent.y2)
+            {
+                _event.type &= !RTGUI_EVENT_PAINT;
+            }
+            else if (widget->extent.y2 < w->extent.y1)
+            {
+                _event.type &= !RTGUI_EVENT_PAINT;
+            }
+        }
+
         if (RTGUI_OBJECT(w)->event_handler &&
-                RTGUI_OBJECT(w)->event_handler(RTGUI_OBJECT(w), event) == RT_TRUE)
+                RTGUI_OBJECT(w)->event_handler(RTGUI_OBJECT(w), &_event) == RT_TRUE)
+        {
             return RT_TRUE;
+        }
     }
 
     return RT_FALSE;
@@ -140,7 +176,7 @@ rt_bool_t rtgui_container_event_handler(struct rtgui_object *object, struct rtgu
         /* paint on each child */
         rtgui_container_dispatch_event(container, event);
 
-        rtgui_dc_end_drawing(dc);
+        rtgui_dc_end_drawing(dc, 1);
     }
     break;
 
@@ -158,8 +194,8 @@ rt_bool_t rtgui_container_event_handler(struct rtgui_object *object, struct rtgu
         rtgui_container_dispatch_event(container, event);
         break;
     case RTGUI_EVENT_HIDE:
-        rtgui_widget_onhide(RTGUI_OBJECT(container), event);
         rtgui_container_dispatch_event(container, event);
+        rtgui_widget_onhide(RTGUI_OBJECT(container), event);
         break;
     case RTGUI_EVENT_COMMAND:
         rtgui_container_dispatch_event(container, event);

+ 81 - 52
components/gui/src/dc.c

@@ -1,11 +1,21 @@
 /*
  * File      : dc.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -19,8 +29,6 @@
 #include <math.h>
 
 #include <rtgui/dc.h>
-#include <rtgui/dc_hw.h>
-#include <rtgui/dc_client.h>
 
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_server.h>
@@ -690,21 +698,20 @@ void rtgui_dc_draw_arc(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16
 
     /*
      * Draw arc
+     * Octant labelling
+     *
+     *  \ 5 | 6 /
+     *   \  |  /
+     *  4 \ | / 7
+     *     \|/
+     *------+------ +x
+     *     /|\
+     *  3 / | \ 0
+     *   /  |  \
+     *  / 2 | 1 \
+     *      +y
      */
 
-    // Octant labelling
-    //
-    //  \ 5 | 6 /
-    //   \  |  /
-    //  4 \ | / 7
-    //     \|/
-    //------+------ +x
-    //     /|\
-    //  3 / | \ 0
-    //   /  |  \
-    //  / 2 | 1 \
-    //      +y
-
     drawoct = 0; // 0x00000000
     // whether or not to keep drawing a given octant.
     // For example: 0x00111100 means we're drawing in octants 2-5
@@ -1319,18 +1326,20 @@ void rtgui_dc_draw_pie(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16
 }
 RTM_EXPORT(rtgui_dc_draw_pie);
 
-// Octant labelling
-//
-//  \ 5 | 6 /
-//   \  |  /
-//  4 \ | / 7
-//     \|/
-//------+------ +x
-//     /|\
-//  3 / | \ 0
-//   /  |  \
-//  / 2 | 1 \
-//      +y
+/*
+ * Octant labelling
+ *
+ *  \ 5 | 6 /
+ *   \  |  /
+ *  4 \ | / 7
+ *     \|/
+ *------+------ +x
+ *     /|\
+ *  3 / | \ 0
+ *   /  |  \
+ *  / 2 | 1 \
+ *      +y
+ */
 static void _draw_octant(struct rtgui_dc *dc,
                          rt_int16_t ox, rt_int16_t oy,
                          rt_int16_t y1, rt_int16_t y2, rt_int16_t x, int oct)
@@ -1814,6 +1823,10 @@ struct rtgui_dc *rtgui_dc_begin_drawing(rtgui_widget_t *owner)
         return RT_NULL;
 
     /* increase drawing count */
+    if (win->drawing == 0)
+    {
+        memset(&(win->drawing_rect), 0x0, sizeof(struct rtgui_rect));
+    }
     win->drawing ++;
 
     /* always drawing on the virtual mode */
@@ -1873,7 +1886,7 @@ struct rtgui_dc *rtgui_dc_begin_drawing(rtgui_widget_t *owner)
 }
 RTM_EXPORT(rtgui_dc_begin_drawing);
 
-void rtgui_dc_end_drawing(struct rtgui_dc *dc)
+void rtgui_dc_end_drawing(struct rtgui_dc *dc, rt_bool_t update)
 {
     struct rtgui_widget *owner;
     struct rtgui_win *win;
@@ -1889,30 +1902,47 @@ void rtgui_dc_end_drawing(struct rtgui_dc *dc)
     /* get window */
     win = owner->toplevel;
 
+    /* union drawing rect */
+    rtgui_rect_union(&(owner->extent_visiable), &(win->drawing_rect));
     /* decrease drawing counter */
-    win->drawing --;
-    if (win->drawing == 0 && rtgui_graphic_driver_is_vmode() == RT_FALSE)
-    {
-#ifdef RTGUI_USING_MOUSE_CURSOR
-        rt_mutex_release(&cursor_mutex);
-        /* show cursor */
-        rtgui_mouse_show_cursor();
-#endif
+    win->drawing--;
 
-        if (RTGUI_IS_WINTITLE(win))
+    if (win->drawing == 0)
+    {
+        /* notify window to handle window update done */
+        if (RTGUI_OBJECT(win)->event_handler)
         {
-            /* update screen */
-            rtgui_graphic_driver_screen_update(rtgui_graphic_driver_get_default(),
-                                               &(owner->extent));
+            struct rtgui_event_win_update_end ewin_update;
+
+            RTGUI_EVENT_WIN_UPDATE_END_INIT(&(ewin_update));
+            ewin_update.rect = win->drawing_rect;
+
+            RTGUI_OBJECT(win)->event_handler(RTGUI_OBJECT(win), (struct rtgui_event *)&ewin_update);
         }
-        else
+
+        if (rtgui_graphic_driver_is_vmode() == RT_FALSE && update)
         {
-            /* send to server for window update */
-            struct rtgui_event_update_end eupdate;
-            RTGUI_EVENT_UPDATE_END_INIT(&(eupdate));
-            eupdate.rect = owner->extent;
+#ifdef RTGUI_USING_MOUSE_CURSOR
+            rt_mutex_release(&cursor_mutex);
+            /* show cursor */
+            rtgui_mouse_show_cursor();
+#endif
 
-            rtgui_server_post_event((struct rtgui_event *)&eupdate, sizeof(eupdate));
+            if (RTGUI_IS_WINTITLE(win))
+            {
+                /* update screen */
+                rtgui_graphic_driver_screen_update(rtgui_graphic_driver_get_default(),
+                                                   &(owner->extent));
+            }
+            else
+            {
+                /* send to server for window update */
+                struct rtgui_event_update_end eupdate;
+                RTGUI_EVENT_UPDATE_END_INIT(&(eupdate));
+                eupdate.rect = owner->extent;
+
+                rtgui_server_post_event((struct rtgui_event *)&eupdate, sizeof(eupdate));
+            }
         }
     }
 
@@ -1920,4 +1950,3 @@ void rtgui_dc_end_drawing(struct rtgui_dc *dc)
     rtgui_screen_unlock();
 }
 RTM_EXPORT(rtgui_dc_end_drawing);
-

Fișier diff suprimat deoarece este prea mare
+ 381 - 314
components/gui/src/dc_blend.c


+ 431 - 362
components/gui/src/dc_buffer.c

@@ -1,11 +1,21 @@
 /*
  * File      : dc_buffer.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -14,11 +24,10 @@
 #include <rtgui/rtgui.h>
 #include <rtgui/dc.h>
 #include <rtgui/blit.h>
-#include <rtgui/dc_hw.h>
 #include <rtgui/color.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/dc_draw.h>
-
+#include <rtgui/image_container.h>
 #include <string.h>
 
 static rt_bool_t rtgui_dc_buffer_fini(struct rtgui_dc *dc);
@@ -44,61 +53,96 @@ const struct rtgui_dc_engine dc_buffer_engine =
     rtgui_dc_buffer_fini,
 };
 
-#define _dc_get_pitch(dc) 			\
-	(dc->pitch)
-#define _dc_get_pixel(dc, x, y)		\
-	((dc)->pixel + (y) * (dc)->pitch + (x) * rtgui_color_get_bpp((dc)->pixel_format))
-#define _dc_get_bits_per_pixel(dc)	\
-	rtgui_color_get_bits(dc->pixel_format)
+#define _dc_get_pitch(dc)           \
+    (dc->pitch)
+#define _dc_get_pixel(dc, x, y)     \
+    ((dc)->pixel + (y) * (dc)->pitch + (x) * rtgui_color_get_bpp((dc)->pixel_format))
+#define _dc_get_bits_per_pixel(dc)  \
+    rtgui_color_get_bits(dc->pixel_format)
 
 #define _hw_get_pixel(dst, x, y, type)  \
-		(type *)((rt_uint8_t*)((dst)->framebuffer) + (y) * (dst)->pitch + (x) * _UI_BITBYTES((dst)->bits_per_pixel))
+        (type *)((rt_uint8_t*)((dst)->framebuffer) + (y) * (dst)->pitch + (x) * _UI_BITBYTES((dst)->bits_per_pixel))
 
 struct rtgui_dc *rtgui_dc_buffer_create(int w, int h)
 {
-	rt_uint8_t pixel_format;
+    rt_uint8_t pixel_format;
 
-	pixel_format = rtgui_graphic_driver_get_default()->pixel_format;
+    pixel_format = rtgui_graphic_driver_get_default()->pixel_format;
 
-	/* create a dc_buffer with hardware driver pixel format */
-	return rtgui_dc_buffer_create_pixformat(pixel_format, w, h);
+    /* create a dc_buffer with hardware driver pixel format */
+    return rtgui_dc_buffer_create_pixformat(pixel_format, w, h);
 }
 RTM_EXPORT(rtgui_dc_buffer_create);
 
 struct rtgui_dc *rtgui_dc_buffer_create_pixformat(rt_uint8_t pixel_format, int w, int h)
 {
-	struct rtgui_dc_buffer *dc;
-
-	dc = (struct rtgui_dc_buffer *)rtgui_malloc(sizeof(struct rtgui_dc_buffer));
-	if (dc)
-	{
-		dc->parent.type = RTGUI_DC_BUFFER;
-		dc->parent.engine = &dc_buffer_engine;
-		dc->gc.foreground = default_foreground;
-		dc->gc.background = default_background;
-		dc->gc.font = rtgui_font_default();
-		dc->gc.textalign = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP;
-		dc->pixel_format = pixel_format;
-
-		dc->width = w;
-		dc->height = h;
-		dc->pitch = w * rtgui_color_get_bpp(pixel_format);
-
-		dc->pixel = rtgui_malloc(h * dc->pitch);
-		if (!dc->pixel)
-		{
-			rtgui_free(dc);
-			return RT_NULL;
-		}
-		rt_memset(dc->pixel, 0, h * dc->pitch);
-
-		return &(dc->parent);
-	}
-
-	return RT_NULL;
+    struct rtgui_dc_buffer *dc;
+
+    dc = (struct rtgui_dc_buffer *)rtgui_malloc(sizeof(struct rtgui_dc_buffer));
+    if (dc)
+    {
+        dc->parent.type = RTGUI_DC_BUFFER;
+        dc->parent.engine = &dc_buffer_engine;
+        dc->gc.foreground = default_foreground;
+        dc->gc.background = default_background;
+        dc->gc.font = rtgui_font_default();
+        dc->gc.textalign = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP;
+        dc->pixel_format = pixel_format;
+
+        dc->width = w;
+        dc->height = h;
+        dc->pitch = w * rtgui_color_get_bpp(pixel_format);
+
+#ifdef RTGUI_IMAGE_CONTAINER
+        dc->image_item = RT_NULL;
+#endif
+        dc->pixel = rtgui_malloc(h * dc->pitch);
+        if (!dc->pixel)
+        {
+            rtgui_free(dc);
+            return RT_NULL;
+        }
+        rt_memset(dc->pixel, 0, h * dc->pitch);
+
+        return &(dc->parent);
+    }
+
+    return RT_NULL;
 }
 RTM_EXPORT(rtgui_dc_buffer_create_pixformat);
 
+#ifdef RTGUI_IMAGE_CONTAINER
+struct rtgui_dc *rtgui_img_dc_create_pixformat(rt_uint8_t pixel_format, 
+    rt_uint8_t *pixel, struct rtgui_image_item *image_item)
+{
+    struct rtgui_dc_buffer *dc;
+
+    dc = (struct rtgui_dc_buffer *)rtgui_malloc(sizeof(struct rtgui_dc_buffer));
+    if (dc)
+    {
+        dc->parent.type = RTGUI_DC_BUFFER;
+        dc->parent.engine = &dc_buffer_engine;
+        dc->gc.foreground = default_foreground;
+        dc->gc.background = default_background;
+        dc->gc.font = rtgui_font_default();
+        dc->gc.textalign = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP;
+        dc->pixel_format = pixel_format;
+
+        dc->width = image_item->image->w;
+        dc->height = image_item->image->h;
+        dc->pitch = image_item->image->w * rtgui_color_get_bpp(pixel_format);
+
+        dc->image_item = image_item;
+        dc->pixel = pixel;
+
+        return &(dc->parent);
+    }
+
+    return RT_NULL;
+}
+RTM_EXPORT(rtgui_img_dc_create_pixformat);
+#endif
+
 struct rtgui_dc *rtgui_dc_buffer_create_from_dc(struct rtgui_dc* dc)
 {
     struct rtgui_dc_buffer *buffer;
@@ -112,8 +156,8 @@ struct rtgui_dc *rtgui_dc_buffer_create_from_dc(struct rtgui_dc* dc)
 
         /* buffer clone */
         buffer = (struct rtgui_dc_buffer*)rtgui_dc_buffer_create_pixformat(d->pixel_format,
-                                                                           d->width,
-                                                                           d->height);
+                 d->width,
+                 d->height);
         if (buffer != RT_NULL)
         {
             rt_memcpy(buffer->pixel, d->pixel, d->pitch * d->height);
@@ -142,8 +186,16 @@ static rt_bool_t rtgui_dc_buffer_fini(struct rtgui_dc *dc)
 
     if (dc->type != RTGUI_DC_BUFFER) return RT_FALSE;
 
-    rtgui_free(buffer->pixel);
-    buffer->pixel = RT_NULL;
+#ifdef RTGUI_IMAGE_CONTAINER
+    if (buffer->image_item)
+    {
+        rtgui_image_container_put(buffer->image_item);
+        buffer->pixel = RT_NULL;
+    }
+#endif
+
+    if (buffer->pixel)
+        rtgui_free(buffer->pixel);
 
     return RT_TRUE;
 }
@@ -157,61 +209,61 @@ static void rtgui_dc_buffer_draw_point(struct rtgui_dc *self, int x, int y)
 
     /* does not draw point out of dc */
     if ((x >= dst->width) || (y >= dst->height)) return;
-	if (x < 0 || y < 0) return;
-
-	r = RTGUI_RGB_R(dst->gc.foreground);
-	g = RTGUI_RGB_G(dst->gc.foreground);
-	b = RTGUI_RGB_B(dst->gc.foreground);
-	a = RTGUI_RGB_A(dst->gc.foreground);
-
-	switch (dst->pixel_format)
-	{
-	case RTGRAPHIC_PIXEL_FORMAT_RGB565:
-		DRAW_SETPIXELXY_RGB565(x, y);
-		break;
-	case RTGRAPHIC_PIXEL_FORMAT_BGR565:
-		DRAW_SETPIXELXY_BGR565(x, y);
-		break;
-	case RTGRAPHIC_PIXEL_FORMAT_RGB888:
-		DRAW_SETPIXELXY_RGB888(x, y);
-		break;
-	case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
-		DRAW_SETPIXELXY_ARGB8888(x, y);
-		break;
-	}
+    if (x < 0 || y < 0) return;
+
+    r = RTGUI_RGB_R(dst->gc.foreground);
+    g = RTGUI_RGB_G(dst->gc.foreground);
+    b = RTGUI_RGB_B(dst->gc.foreground);
+    a = RTGUI_RGB_A(dst->gc.foreground);
+
+    switch (dst->pixel_format)
+    {
+    case RTGRAPHIC_PIXEL_FORMAT_RGB565:
+        DRAW_SETPIXELXY_RGB565(x, y);
+        break;
+    case RTGRAPHIC_PIXEL_FORMAT_BGR565:
+        DRAW_SETPIXELXY_BGR565(x, y);
+        break;
+    case RTGRAPHIC_PIXEL_FORMAT_RGB888:
+        DRAW_SETPIXELXY_RGB888(x, y);
+        break;
+    case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
+        DRAW_SETPIXELXY_ARGB8888(x, y);
+        break;
+    }
 }
 
 static void rtgui_dc_buffer_draw_color_point(struct rtgui_dc *self, int x, int y, rtgui_color_t color)
 {
-	struct rtgui_dc_buffer *dst;
-	unsigned r, g, b, a;
-
-	dst = (struct rtgui_dc_buffer *)self;
-
-	/* does not draw point out of dc */
-	if ((x >= dst->width) || (y >= dst->height)) return;
-	if (x < 0 || y < 0) return;
-
-	r = RTGUI_RGB_R(color);
-	g = RTGUI_RGB_G(color);
-	b = RTGUI_RGB_B(color);
-	a = RTGUI_RGB_A(color);
-
-	switch (dst->pixel_format)
-	{
-	case RTGRAPHIC_PIXEL_FORMAT_RGB565:
-		DRAW_SETPIXELXY_RGB565(x, y);
-		break;
-	case RTGRAPHIC_PIXEL_FORMAT_BGR565:
-		DRAW_SETPIXELXY_BGR565(x, y);
-		break;
-	case RTGRAPHIC_PIXEL_FORMAT_RGB888:
-		DRAW_SETPIXELXY_RGB888(x, y);
-		break;
-	case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
-		DRAW_SETPIXELXY_ARGB8888(x, y);
-		break;
-	}
+    struct rtgui_dc_buffer *dst;
+    unsigned r, g, b, a;
+
+    dst = (struct rtgui_dc_buffer *)self;
+
+    /* does not draw point out of dc */
+    if ((x >= dst->width) || (y >= dst->height)) return;
+    if (x < 0 || y < 0) return;
+
+    r = RTGUI_RGB_R(color);
+    g = RTGUI_RGB_G(color);
+    b = RTGUI_RGB_B(color);
+    a = RTGUI_RGB_A(color);
+
+    switch (dst->pixel_format)
+    {
+    case RTGRAPHIC_PIXEL_FORMAT_RGB565:
+        DRAW_SETPIXELXY_RGB565(x, y);
+        break;
+    case RTGRAPHIC_PIXEL_FORMAT_BGR565:
+        DRAW_SETPIXELXY_BGR565(x, y);
+        break;
+    case RTGRAPHIC_PIXEL_FORMAT_RGB888:
+        DRAW_SETPIXELXY_RGB888(x, y);
+        break;
+    case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
+        DRAW_SETPIXELXY_ARGB8888(x, y);
+        break;
+    }
 }
 
 static void rtgui_dc_buffer_draw_vline(struct rtgui_dc *self, int x1, int y1, int y2)
@@ -224,29 +276,29 @@ static void rtgui_dc_buffer_draw_vline(struct rtgui_dc *self, int x1, int y1, in
     if (x1 < 0 || x1 >= dst->width) return;
     if (y1 >= dst->height) return;
 
-	if (y1 < 0) y1 = 0;
+    if (y1 < 0) y1 = 0;
     if (y2 > dst->height) y2 = dst->height;
 
-	r = RTGUI_RGB_R(dst->gc.foreground);
-	g = RTGUI_RGB_G(dst->gc.foreground);
-	b = RTGUI_RGB_B(dst->gc.foreground);
-	a = RTGUI_RGB_A(dst->gc.foreground);
-
-	switch (dst->pixel_format)
-	{
-	case RTGRAPHIC_PIXEL_FORMAT_RGB565:
-		VLINE(rt_uint16_t, DRAW_SETPIXEL_RGB565, 0);
-		break;
-	case RTGRAPHIC_PIXEL_FORMAT_BGR565:
-		VLINE(rt_uint16_t, DRAW_SETPIXEL_BGR565, 0);
-		break;
-	case RTGRAPHIC_PIXEL_FORMAT_RGB888:
-		VLINE(rt_uint16_t, DRAW_SETPIXEL_RGB888, 0);
-		break;
-	case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
-		VLINE(rt_uint32_t, DRAW_SETPIXEL_ARGB8888, 0);
-		break;
-	}
+    r = RTGUI_RGB_R(dst->gc.foreground);
+    g = RTGUI_RGB_G(dst->gc.foreground);
+    b = RTGUI_RGB_B(dst->gc.foreground);
+    a = RTGUI_RGB_A(dst->gc.foreground);
+
+    switch (dst->pixel_format)
+    {
+    case RTGRAPHIC_PIXEL_FORMAT_RGB565:
+        VLINE(rt_uint16_t, DRAW_SETPIXEL_RGB565, 0);
+        break;
+    case RTGRAPHIC_PIXEL_FORMAT_BGR565:
+        VLINE(rt_uint16_t, DRAW_SETPIXEL_BGR565, 0);
+        break;
+    case RTGRAPHIC_PIXEL_FORMAT_RGB888:
+        VLINE(rt_uint16_t, DRAW_SETPIXEL_RGB888, 0);
+        break;
+    case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
+        VLINE(rt_uint32_t, DRAW_SETPIXEL_ARGB8888, 0);
+        break;
+    }
 }
 
 static void rtgui_dc_buffer_draw_hline(struct rtgui_dc *self, int x1, int x2, int y1)
@@ -256,50 +308,50 @@ static void rtgui_dc_buffer_draw_hline(struct rtgui_dc *self, int x1, int x2, in
 
     dst = (struct rtgui_dc_buffer *)self;
 
-	/* parameter checking */
+    /* parameter checking */
     if (y1 < 0 || y1 >= dst->height) return;
     if (x1 >= dst->width) return;
 
-	if (x1 < 0) x1 = 0;
+    if (x1 < 0) x1 = 0;
     if (x2 > dst->width) x2 = dst->width;
 
-	r = RTGUI_RGB_R(dst->gc.foreground);
-	g = RTGUI_RGB_G(dst->gc.foreground);
-	b = RTGUI_RGB_B(dst->gc.foreground);
-	a = RTGUI_RGB_A(dst->gc.foreground);
-
-	switch (dst->pixel_format)
-	{
-	case RTGRAPHIC_PIXEL_FORMAT_RGB565:
-		HLINE(rt_uint16_t, DRAW_SETPIXEL_RGB565, 0);
-		break;
-	case RTGRAPHIC_PIXEL_FORMAT_BGR565:
-		HLINE(rt_uint16_t, DRAW_SETPIXEL_BGR565, 0);
-		break;
-	case RTGRAPHIC_PIXEL_FORMAT_RGB888:
-		HLINE(rt_uint16_t, DRAW_SETPIXEL_RGB888, 0);
-		break;
-	case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
-		HLINE(rt_uint32_t, DRAW_SETPIXEL_ARGB8888, 0);
-		break;
-	}
+    r = RTGUI_RGB_R(dst->gc.foreground);
+    g = RTGUI_RGB_G(dst->gc.foreground);
+    b = RTGUI_RGB_B(dst->gc.foreground);
+    a = RTGUI_RGB_A(dst->gc.foreground);
+
+    switch (dst->pixel_format)
+    {
+    case RTGRAPHIC_PIXEL_FORMAT_RGB565:
+        HLINE(rt_uint16_t, DRAW_SETPIXEL_RGB565, 0);
+        break;
+    case RTGRAPHIC_PIXEL_FORMAT_BGR565:
+        HLINE(rt_uint16_t, DRAW_SETPIXEL_BGR565, 0);
+        break;
+    case RTGRAPHIC_PIXEL_FORMAT_RGB888:
+        HLINE(rt_uint16_t, DRAW_SETPIXEL_RGB888, 0);
+        break;
+    case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
+        HLINE(rt_uint32_t, DRAW_SETPIXEL_ARGB8888, 0);
+        break;
+    }
 }
 
 static void rtgui_dc_buffer_fill_rect(struct rtgui_dc *self, struct rtgui_rect *dst_rect)
 {
     struct rtgui_dc_buffer *dst;
-	unsigned r, g, b, a;
-	rtgui_rect_t _r, *rect;
+    unsigned r, g, b, a;
+    rtgui_rect_t _r, *rect;
 
     RT_ASSERT(self);
-	if (dst_rect == RT_NULL) rtgui_dc_get_rect(self, &_r);
-	else _r = *dst_rect;
+    if (dst_rect == RT_NULL) rtgui_dc_get_rect(self, &_r);
+    else _r = *dst_rect;
 
     dst = (struct rtgui_dc_buffer *)self;
 
-	if (_r.x2 < 0 || _r.y2 < 0) return; /* out of rect */
+    if (_r.x2 < 0 || _r.y2 < 0) return; /* out of rect */
 
-	/* parameter checking */
+    /* parameter checking */
     if (_r.x1 >= dst->width)
         return;
     else if (_r.x1 < 0)
@@ -313,28 +365,28 @@ static void rtgui_dc_buffer_fill_rect(struct rtgui_dc *self, struct rtgui_rect *
         _r.y1 = 0;
     if (_r.y2 > dst->height)
         _r.y2 = dst->height;
-	rect = &_r;
-
-	r = RTGUI_RGB_R(dst->gc.background);
-	g = RTGUI_RGB_G(dst->gc.background);
-	b = RTGUI_RGB_B(dst->gc.background);
-	a = RTGUI_RGB_A(dst->gc.background);
-
-	switch (dst->pixel_format)
-	{
-		case RTGRAPHIC_PIXEL_FORMAT_RGB565:
-			FILLRECT(rt_uint16_t, DRAW_SETPIXEL_RGB565);
-			break;
-		case RTGRAPHIC_PIXEL_FORMAT_BGR565:
-			FILLRECT(rt_uint16_t, DRAW_SETPIXEL_BGR565);
-			break;
-		case RTGRAPHIC_PIXEL_FORMAT_RGB888:
-			FILLRECT(rt_uint32_t, DRAW_SETPIXEL_RGB888);
-			break;
-		case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
-			FILLRECT(rt_uint32_t, DRAW_SETPIXEL_ARGB8888);
-			break;
-	}
+    rect = &_r;
+
+    r = RTGUI_RGB_R(dst->gc.background);
+    g = RTGUI_RGB_G(dst->gc.background);
+    b = RTGUI_RGB_B(dst->gc.background);
+    a = RTGUI_RGB_A(dst->gc.background);
+
+    switch (dst->pixel_format)
+    {
+    case RTGRAPHIC_PIXEL_FORMAT_RGB565:
+        FILLRECT(rt_uint16_t, DRAW_SETPIXEL_RGB565);
+        break;
+    case RTGRAPHIC_PIXEL_FORMAT_BGR565:
+        FILLRECT(rt_uint16_t, DRAW_SETPIXEL_BGR565);
+        break;
+    case RTGRAPHIC_PIXEL_FORMAT_RGB888:
+        FILLRECT(rt_uint32_t, DRAW_SETPIXEL_RGB888);
+        break;
+    case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
+        FILLRECT(rt_uint32_t, DRAW_SETPIXEL_ARGB8888);
+        break;
+    }
 }
 
 /* blit a dc to another dc */
@@ -343,16 +395,16 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc *self,
                                  struct rtgui_dc *dest,
                                  rtgui_rect_t *rect)
 {
-	int pitch;
-	rt_uint16_t rect_width, rect_height;
-	struct rtgui_rect _rect, *dest_rect;
+    int pitch;
+    rt_uint16_t rect_width, rect_height;
+    struct rtgui_rect _rect, *dest_rect;
     struct rtgui_point dc_point;
     struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer *)self;
 
     if (rtgui_dc_get_visible(dest) == RT_FALSE)
         return;
 
-	/* use the (0,0) origin point */
+    /* use the (0,0) origin point */
     if (dc_pt == RT_NULL)
         dc_point = rtgui_empty_point;
     else
@@ -361,12 +413,12 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc *self,
     }
 
     rtgui_dc_get_rect(dest, &_rect);
-	/* use the rect of dest dc */
-	if (rect == RT_NULL)
-	{
-		dest_rect = &_rect;
-	}
-	else
+    /* use the rect of dest dc */
+    if (rect == RT_NULL)
+    {
+        dest_rect = &_rect;
+    }
+    else
     {
         dest_rect = rect;
         if (dest_rect->x1 >= _rect.x2 || dest_rect->y1 >= _rect.y2)
@@ -391,204 +443,192 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc *self,
             dest_rect->y2 = _rect.y2;
     }
 
-	if (dest_rect->x2 < dest_rect->x1 || dest_rect->y2 < dest_rect->y1) return;
+    if (dest_rect->x2 < dest_rect->x1 || dest_rect->y2 < dest_rect->y1) return;
     if (dc_point.x >= dc->width || dc_point.y >= dc->height) return;
 
-	/* get the minimal width and height */
-	rect_width  = _UI_MIN(rtgui_rect_width(*dest_rect), dc->width - dc_point.x);
-	rect_height = _UI_MIN(rtgui_rect_height(*dest_rect), dc->height - dc_point.y);
+    /* get the minimal width and height */
+    rect_width  = _UI_MIN(rtgui_rect_width(*dest_rect), dc->width - dc_point.x);
+    rect_height = _UI_MIN(rtgui_rect_height(*dest_rect), dc->height - dc_point.y);
 
     if ((dest->type == RTGUI_DC_HW) || (dest->type == RTGUI_DC_CLIENT))
     {
-		int index;
+        int index;
         rt_uint8_t *line_ptr, *pixels;
         rtgui_blit_line_func blit_line;
-		struct rtgui_graphic_driver *hw_driver;
+        struct rtgui_graphic_driver *hw_driver;
 
-		hw_driver = rtgui_graphic_driver_get_default();
+        hw_driver = rtgui_graphic_driver_get_default();
         /* prepare pixel line */
-		pixels = _dc_get_pixel(dc, dc_point.x, dc_point.y);
+        pixels = _dc_get_pixel(dc, dc_point.x, dc_point.y);
 
-        if (hw_driver->bits_per_pixel == _dc_get_bits_per_pixel(dc))
+        if (dest->type == RTGUI_DC_HW && hw_driver->framebuffer != RT_NULL)
+        {
+            /* use rtgui_blit */
+
+            struct rtgui_blit_info info;
+            struct rtgui_widget *owner;
+
+            info.a = 255;
+
+            /* blit source */
+            info.src = _dc_get_pixel(dc, dc_point.x, dc_point.y);
+            info.src_fmt = dc->pixel_format;
+            info.src_h = rect_height;
+            info.src_w = rect_width;
+            info.src_pitch = dc->pitch;
+            info.src_skip = info.src_pitch - info.src_w * rtgui_color_get_bpp(dc->pixel_format);
+
+            owner = ((struct rtgui_dc_hw*)dest)->owner;
+
+            /* blit destination */
+            info.dst = (rt_uint8_t*)hw_driver->framebuffer;
+            info.dst = info.dst + (owner->extent.y1 + dest_rect->y1) * hw_driver->pitch +
+                       (owner->extent.x1 + dest_rect->x1) * rtgui_color_get_bpp(hw_driver->pixel_format);
+            info.dst_fmt = hw_driver->pixel_format;
+            info.dst_h = rect_height;
+            info.dst_w = rect_width;
+            info.dst_pitch = hw_driver->pitch;
+            info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(hw_driver->pixel_format);
+
+            rtgui_blit(&info);
+        }
+        else if (dest->type == RTGUI_DC_CLIENT&& hw_driver->framebuffer != RT_NULL)
         {
-			if (dest->type == RTGUI_DC_HW && hw_driver->framebuffer != RT_NULL)
-			{
-				rt_uint8_t *hw_pixels;
-				struct rtgui_dc_hw *hw;
-
-				hw = (struct rtgui_dc_hw*)dest;
-
-				/* NOTES: the rect of DC is the logic coordination.
-				 * It should be converted to client
-				 */
-				if (dest_rect != &_rect)
-				{
-					/* use local rect */
-					_rect = *dest_rect;
-					dest_rect = &_rect;
-				}
-				rtgui_rect_moveto(dest_rect, hw->owner->extent.x1, hw->owner->extent.y1);
-
-				pitch = rtgui_color_get_bpp(hw_driver->pixel_format) * rect_width;
-				hw_pixels = (rt_uint8_t*)(hw_driver->framebuffer + dest_rect->y1 * hw_driver->pitch +
-					dest_rect->x1 * rtgui_color_get_bpp(hw_driver->pixel_format));
-
-				/* do the blit with memory copy */
-				for (index = 0; index < rect_height; index ++)
-				{
-					rt_memcpy(hw_pixels, pixels, pitch);
-					pixels += dc->pitch;
-					hw_pixels += hw_driver->pitch;
-				}
-			}
-			else
-			{
-	            /* it's the same bits per pixel, draw it directly */
-	            for (index = dest_rect->y1; index < dest_rect->y1 + rect_height; index++)
-	            {
-	                dest->engine->blit_line(dest, dest_rect->x1, dest_rect->x1 + rect_width, index, pixels);
-					pixels += dc->pitch;
-	            }
-			}
+            /* use rtgui_blit */
+            rt_uint8_t bpp, hw_bpp;
+            struct rtgui_blit_info info;
+            struct rtgui_widget *owner;
+            struct rtgui_region dest_region;
+            struct rtgui_rect dest_extent;
+            int num_rects;
+            struct rtgui_rect *rects;
+
+            /* get owner */
+            owner = RTGUI_CONTAINER_OF(dest, struct rtgui_widget, dc_type);
+
+            dest_extent = *dest_rect;
+            rtgui_widget_rect_to_device(owner, &dest_extent);
+
+            rtgui_region_init_with_extents(&dest_region, &dest_extent);
+            rtgui_region_intersect_rect(&dest_region, &(owner->clip), &dest_extent);
+            bpp = rtgui_color_get_bpp(dc->pixel_format);
+            hw_bpp = rtgui_color_get_bpp(hw_driver->pixel_format);
+
+            num_rects = rtgui_region_num_rects(&dest_region);
+            rects = rtgui_region_rects(&dest_region);
+
+            /* common info */
+            info.a = 255;
+            info.src_fmt = dc->pixel_format;
+            info.src_pitch = dc->pitch;
+
+            info.dst_fmt = hw_driver->pixel_format;
+            info.dst_pitch = hw_driver->pitch;
+
+            for (index = 0; index < num_rects; index ++)
+            {
+                struct rtgui_rect *r = &rects[index];
+
+                /* blit source */
+                info.src = _dc_get_pixel(dc, dc_point.x + (r->x1 - dest_extent.x1),
+                                         dc_point.y + (r->y1 - dest_extent.y1));
+                info.src_h = rtgui_rect_height(*r);
+                info.src_w = rtgui_rect_width(*r);
+                info.src_skip = info.src_pitch - info.src_w * bpp;
+
+                /* blit destination */
+                info.dst = (rt_uint8_t*)hw_driver->framebuffer + r->y1 * hw_driver->pitch +
+                           r->x1 * hw_bpp;
+                info.dst_h = rtgui_rect_height(*r);
+                info.dst_w = rtgui_rect_width(*r);
+                info.dst_skip = info.dst_pitch - info.dst_w * hw_bpp;
+
+                rtgui_blit(&info);
+            }
+
+            rtgui_region_fini(&dest_region);
         }
         else
         {
-			struct rtgui_graphic_driver *hw_driver;
-
-			hw_driver = rtgui_graphic_driver_get_default();
-
-			if ((dc->pixel_format == RTGRAPHIC_PIXEL_FORMAT_ARGB888) &&
-                (dest->type == RTGUI_DC_HW) &&
-				(hw_driver->framebuffer != RT_NULL) &&
-				(hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565))
-			{
-				/* do the fast ARGB to RGB565 blit */
-				struct rtgui_blit_info info;
-				struct rtgui_widget *owner;
-
-				/* blit source */
-				info.src = _dc_get_pixel(dc, dc_point.x, dc_point.y);
-				info.src_fmt = dc->pixel_format;
-				info.src_h = rect_height;
-				info.src_w = rect_width;
-				info.src_pitch = dc->pitch;
-				info.src_skip = info.src_pitch - info.src_w * rtgui_color_get_bpp(dc->pixel_format);
-
-				owner = ((struct rtgui_dc_hw*)dest)->owner;
-
-				/* blit destination */
-				info.dst = (rt_uint8_t*)hw_driver->framebuffer;
-				info.dst = info.dst + (owner->extent.y1 + dest_rect->y1) * hw_driver->pitch +
-                    (owner->extent.x1 + dest_rect->x1) * rtgui_color_get_bpp(hw_driver->pixel_format);
-				info.dst_fmt = hw_driver->pixel_format;
-				info.dst_h = rect_height;
-				info.dst_w = rect_width;
-				info.dst_pitch = hw_driver->pitch;
-				info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(hw_driver->pixel_format);
-
-				rtgui_blit(&info);
-			}
-			else
-			{
-				/* calculate pitch */
-				pitch = rect_width * rtgui_color_get_bpp(dc->pixel_format);
-
-	            /* get blit line function */
-	            blit_line = rtgui_blit_line_get(_UI_BITBYTES(hw_driver->bits_per_pixel),
-                                                rtgui_color_get_bpp(dc->pixel_format));
-				if (hw_driver->framebuffer != RT_NULL)
-				{
-					struct rtgui_widget* owner;
-					if (dest->type == RTGUI_DC_HW) owner = ((struct rtgui_dc_hw*) dest)->owner;
-					else if (dest->type == RTGUI_DC_CLIENT) owner = RTGUI_CONTAINER_OF(dest, struct rtgui_widget, dc_type);
-					else RT_ASSERT(0);
-
-					/* change the logic coordinate to the device coordinate */
-					rtgui_rect_moveto(dest_rect, owner->extent.x1, owner->extent.y1);
-
-					for (index = dest_rect->y1; index < dest_rect->y1 + rect_height; index ++)
-					{
-						line_ptr = _hw_get_pixel(hw_driver, dest_rect->x1, index, rt_uint8_t);
-						blit_line(line_ptr, (rt_uint8_t*)pixels, pitch);
-						pixels += dc->pitch;
-					}
-				}
-				else
-				{
-		            /* calculate pitch */
-		            pitch = rect_width * rtgui_color_get_bpp(dc->pixel_format);
-		            /* create line buffer */
-		            line_ptr = (rt_uint8_t *) rtgui_malloc(rect_width * _UI_BITBYTES(hw_driver->bits_per_pixel));
-
-		            /* draw each line */
-		            for (index = dest_rect->y1; index < dest_rect->y1 + rect_height; index ++)
-		            {
-		                /* blit on line buffer */
-		                blit_line(line_ptr, (rt_uint8_t *)pixels, pitch);
-		                pixels += dc->pitch;
-
-		                /* draw on hardware dc */
-		                dest->engine->blit_line(dest, dest_rect->x1, dest_rect->x1 + rect_width,
-	                                            index, line_ptr);
-		            }
-
-		            /* release line buffer */
-		            rtgui_free(line_ptr);
-				}
-			}
+            /* calculate pitch */
+            pitch = rect_width * rtgui_color_get_bpp(dc->pixel_format);
+
+            /* get blit line function */
+            blit_line = rtgui_blit_line_get(_UI_BITBYTES(hw_driver->bits_per_pixel),
+                                            rtgui_color_get_bpp(dc->pixel_format));
+            if (hw_driver->framebuffer != RT_NULL)
+            {
+                struct rtgui_widget* owner;
+                if (dest->type == RTGUI_DC_HW) owner = ((struct rtgui_dc_hw*) dest)->owner;
+                else if (dest->type == RTGUI_DC_CLIENT) owner = RTGUI_CONTAINER_OF(dest, struct rtgui_widget, dc_type);
+                else RT_ASSERT(0);
+
+                /* change the logic coordinate to the device coordinate */
+                rtgui_rect_moveto(dest_rect, owner->extent.x1, owner->extent.y1);
+
+                for (index = dest_rect->y1; index < dest_rect->y1 + rect_height; index ++)
+                {
+                    line_ptr = _hw_get_pixel(hw_driver, dest_rect->x1, index, rt_uint8_t);
+                    blit_line(line_ptr, (rt_uint8_t*)pixels, pitch);
+                    pixels += dc->pitch;
+                }
+            }
+            else
+            {
+                /* calculate pitch */
+                pitch = rect_width * rtgui_color_get_bpp(dc->pixel_format);
+                /* create line buffer */
+                line_ptr = (rt_uint8_t *) rtgui_malloc(rect_width * _UI_BITBYTES(hw_driver->bits_per_pixel));
+
+                /* draw each line */
+                for (index = dest_rect->y1; index < dest_rect->y1 + rect_height; index ++)
+                {
+                    /* blit on line buffer */
+                    blit_line(line_ptr, (rt_uint8_t *)pixels, pitch);
+                    pixels += dc->pitch;
+
+                    /* draw on hardware dc */
+                    dest->engine->blit_line(dest, dest_rect->x1, dest_rect->x1 + rect_width,
+                                            index, line_ptr);
+                }
+
+                /* release line buffer */
+                rtgui_free(line_ptr);
+            }
         }
     }
-	else if (dest->type == RTGUI_DC_BUFFER)
-	{
-		struct rtgui_dc_buffer *dest_dc = (struct rtgui_dc_buffer*)dest;
-
-		if (dest_dc->pixel_format == dc->pixel_format && dest_dc->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)
-		{
-			int index;
-			rt_uint8_t *pixels, *dest_pixels;
-
-			/* get pitch */
-			pitch = rect_width * rtgui_color_get_bpp(dc->pixel_format);
-
-			pixels = _dc_get_pixel(dc, dc_point.x, dc_point.y);
-			dest_pixels = _dc_get_pixel(dest_dc, dest_rect->x1, dest_rect->y1);
-
-			for (index = 0; index < rect_height; index ++)
-			{
-				rt_memcpy(dest_pixels, pixels, pitch);
-				pixels += dc->pitch;
-				dest_pixels += dest_dc->pitch;
-			}
-		}
-		else /* use rtgui_blit to handle buffer blit */
-		{
-			/* do the fast ARGB to RGB565 blit */
-			struct rtgui_blit_info info;
-
-			/* blit source */
-			info.src = _dc_get_pixel(dc, dc_point.x, dc_point.y);
-			info.src_fmt = dc->pixel_format;
-			info.src_h = rect_height;
-			info.src_w = rect_width;
-			info.src_pitch = dc->pitch;
-			info.src_skip = info.src_pitch - info.src_w * rtgui_color_get_bpp(dc->pixel_format);
-
-			/* blit destination */
-			info.dst = _dc_get_pixel(dest_dc, dest_rect->x1, dest_rect->y1);
-			info.dst_fmt = dest_dc->pixel_format;
-			info.dst_h = rect_height;
-			info.dst_w = rect_width;
-			info.dst_pitch = dest_dc->pitch;
-			info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(dest_dc->pixel_format);
-
-			rtgui_blit(&info);
-		}
-	}
+    else if (dest->type == RTGUI_DC_BUFFER)
+    {
+        struct rtgui_dc_buffer *dest_dc = (struct rtgui_dc_buffer*)dest;
+
+        /* use rtgui_blit to handle buffer blit */
+        struct rtgui_blit_info info;
+
+        info.a = 255;
+
+        /* blit source */
+        info.src = _dc_get_pixel(dc, dc_point.x, dc_point.y);
+        info.src_fmt = dc->pixel_format;
+        info.src_h = rect_height;
+        info.src_w = rect_width;
+        info.src_pitch = dc->pitch;
+        info.src_skip = info.src_pitch - info.src_w * rtgui_color_get_bpp(dc->pixel_format);
+
+        /* blit destination */
+        info.dst = _dc_get_pixel(dest_dc, dest_rect->x1, dest_rect->y1);
+        info.dst_fmt = dest_dc->pixel_format;
+        info.dst_h = rect_height;
+        info.dst_w = rect_width;
+        info.dst_pitch = dest_dc->pitch;
+        info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(dest_dc->pixel_format);
+
+        rtgui_blit(&info);
+    }
 }
 
 static void rtgui_dc_buffer_blit_line(struct rtgui_dc *self, int x1, int x2, int y, rt_uint8_t *line_data)
 {
-	rt_uint8_t *pixel;
+    rt_uint8_t *pixel;
     struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer *)self;
 
     RT_ASSERT(dc != RT_NULL);
@@ -604,7 +644,36 @@ static void rtgui_dc_buffer_blit_line(struct rtgui_dc *self, int x1, int x2, int
     if (x2 >= dc->width)
         x2 = dc->width-1;
 
-	pixel = _dc_get_pixel(dc,x1,y);
+    pixel = _dc_get_pixel(dc,x1,y);
     rt_memcpy(pixel, line_data, (x2 - x1) * rtgui_color_get_bpp(dc->pixel_format));
 }
 
+#ifdef RT_USING_DFS
+#include <dfs_posix.h>
+void rtgui_dc_buffer_dump(struct rtgui_dc *self, char *fn)
+{
+    struct dc_file_header
+    {
+        int w, h;
+        int format;
+    } header;
+    struct rtgui_dc_buffer *buffer;
+    int fd;
+
+    if (self->type != RTGUI_DC_BUFFER) return; /* only support DC buffer */
+    buffer = (struct rtgui_dc_buffer*)self;
+
+    header.w = buffer->width;
+    header.h = buffer->height;
+    header.format = buffer->pixel_format;
+
+    fd = open(fn, O_RDWR | O_CREAT | O_TRUNC, 0);
+    if (fd >= 0)
+    {
+        write(fd, &header, sizeof(header));
+        write(fd, buffer->pixel, header.w * header.h * rtgui_color_get_bpp(header.format));
+        close(fd);
+    }
+}
+#endif
+

+ 45 - 37
components/gui/src/dc_client.c

@@ -1,11 +1,21 @@
 /*
  * File      : dc_client.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -16,8 +26,6 @@
  * 2010-09-14     Bernard      fix vline and hline coordinate issue
  */
 #include <rtgui/dc.h>
-#include <rtgui/dc_hw.h>
-#include <rtgui/dc_client.h>
 
 #include <rtgui/driver.h>
 #include <rtgui/rtgui_system.h>
@@ -88,7 +96,7 @@ static void rtgui_dc_client_draw_point(struct rtgui_dc *self, int x, int y)
     rtgui_widget_t *owner;
 
     if (self == RT_NULL) return;
-	if (!rtgui_dc_get_visible(self)) return;
+    if (!rtgui_dc_get_visible(self)) return;
 
     /* get owner */
     owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
@@ -109,7 +117,7 @@ static void rtgui_dc_client_draw_color_point(struct rtgui_dc *self, int x, int y
     rtgui_widget_t *owner;
 
     if (self == RT_NULL) return;
-	if (!rtgui_dc_get_visible(self)) return;
+    if (!rtgui_dc_get_visible(self)) return;
 
     /* get owner */
     owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
@@ -133,7 +141,7 @@ static void rtgui_dc_client_draw_vline(struct rtgui_dc *self, int x, int y1, int
     rtgui_widget_t *owner;
 
     if (self == RT_NULL) return;
-	if (!rtgui_dc_get_visible(self)) return;
+    if (!rtgui_dc_get_visible(self)) return;
 
     /* get owner */
     owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
@@ -160,26 +168,26 @@ static void rtgui_dc_client_draw_vline(struct rtgui_dc *self, int x, int y1, int
         hw_driver->ops->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->ops->draw_vline(&(owner->gc.foreground), x, draw_y1, draw_y2);
-	    }
+    {
+        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->ops->draw_vline(&(owner->gc.foreground), x, draw_y1, draw_y2);
+        }
     }
 }
 
@@ -192,7 +200,7 @@ static void rtgui_dc_client_draw_hline(struct rtgui_dc *self, int x1, int x2, in
     rtgui_widget_t *owner;
 
     if (self == RT_NULL) return;
-	if (!rtgui_dc_get_visible(self)) return;
+    if (!rtgui_dc_get_visible(self)) return;
 
     /* get owner */
     owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
@@ -220,8 +228,8 @@ static void rtgui_dc_client_draw_hline(struct rtgui_dc *self, int x1, int x2, in
         hw_driver->ops->draw_hline(&(owner->gc.foreground), x1, x2, y);
     }
     else
-	{
-		for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++)
+    {
+        for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++)
         {
             rtgui_rect_t *prect;
             register rt_base_t draw_x1, draw_x2;
@@ -252,7 +260,7 @@ static void rtgui_dc_client_fill_rect(struct rtgui_dc *self, struct rtgui_rect *
     RT_ASSERT(self);
     RT_ASSERT(rect);
 
-	if (!rtgui_dc_get_visible(self)) return;
+    if (!rtgui_dc_get_visible(self)) return;
 
     /* get owner */
     owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
@@ -279,7 +287,7 @@ static void rtgui_dc_client_blit_line(struct rtgui_dc *self, int x1, int x2, int
     rtgui_widget_t *owner;
 
     if (self == RT_NULL) return;
-	if (!rtgui_dc_get_visible(self)) return;
+    if (!rtgui_dc_get_visible(self)) return;
 
     /* get owner */
     owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
@@ -312,8 +320,8 @@ static void rtgui_dc_client_blit_line(struct rtgui_dc *self, int x1, int x2, int
         hw_driver->ops->draw_raw_hline(line_data + offset, x1, x2, y);
     }
     else
-	{
-		for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++)
+    {
+        for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++)
         {
             rtgui_rect_t *prect;
             register rt_base_t draw_x1, draw_x2;

+ 24 - 15
components/gui/src/dc_hw.c

@@ -1,18 +1,27 @@
 /*
  * File      : dc_hw.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
  * 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/rtgui_app.h>
@@ -54,17 +63,17 @@ struct rtgui_dc *rtgui_dc_hw_create(rtgui_widget_t *owner)
 
     /* create DC */
     dc = (struct rtgui_dc_hw *) rtgui_malloc(sizeof(struct rtgui_dc_hw));
-	if (dc)
-	{
-		dc->parent.type = RTGUI_DC_HW;
-		dc->parent.engine = &dc_hw_engine;
-		dc->owner = owner;
-		dc->hw_driver = rtgui_graphic_driver_get_default();
+    if (dc)
+    {
+        dc->parent.type = RTGUI_DC_HW;
+        dc->parent.engine = &dc_hw_engine;
+        dc->owner = owner;
+        dc->hw_driver = rtgui_graphic_driver_get_default();
 
-		return &(dc->parent);
-	}
+        return &(dc->parent);
+    }
 
-	return RT_NULL;
+    return RT_NULL;
 }
 
 static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc *dc)

Fișier diff suprimat deoarece este prea mare
+ 565 - 512
components/gui/src/dc_rotozoom.c


+ 44 - 18
components/gui/src/dc_trans.c

@@ -1,3 +1,27 @@
+/*
+ * File      : dc_trans.c
+ * This file is part of RT-Thread GUI
+ * COPYRIGHT (C) 2006 - 2014, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2014-03-15     Grissom      The first version
+ */
+
 #include <rtgui/rtgui.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/dc.h>
@@ -91,7 +115,7 @@ void rtgui_dc_trans_get_new_wh(struct rtgui_dc_trans *dct,
                                   &dct->m);
     /* Transform result of (w, 0). */
     rtgui_matrix_mul_point_nomove(&bottomright,
-                                   rect.x2, 0, &dct->m);
+                                  rect.x2, 0, &dct->m);
     /* Transform result of (0, 0) is always (0, 0). */
 
 #define NORMALIZE(x) do { if (x < 0) x = 0; } while (0)
@@ -105,7 +129,7 @@ void rtgui_dc_trans_get_new_wh(struct rtgui_dc_trans *dct,
         NORMALIZE(bottomright.x);
 
         neww = _UI_MAX(topright.x, _UI_ABS(topleft.x - bottomright.x))
-            + dct->m.m[4];
+               + dct->m.m[4];
         NORMALIZE(neww);
 
         *new_wp = neww;
@@ -119,7 +143,7 @@ void rtgui_dc_trans_get_new_wh(struct rtgui_dc_trans *dct,
         NORMALIZE(bottomright.y);
 
         newh = _UI_MAX(topright.y, _UI_ABS(topleft.y - bottomright.y))
-            + dct->m.m[5];
+               + dct->m.m[5];
         NORMALIZE(newh);
 
         *new_hp = newh;
@@ -444,9 +468,9 @@ static void _blit_rotate_FR2FR_SF4B_AA(struct _fb_rect* RTGUI_RESTRICT src,
 
 /* FrameRect to FrameRect, from ARGB8888 to RGB565. */
 static void _blit_rotate_FR2FR_ARGB2RGB565(struct _fb_rect* RTGUI_RESTRICT src,
-                                           const struct rtgui_point *dc_point,
-                                           struct _fb_rect* RTGUI_RESTRICT dst,
-                                           const struct rtgui_matrix *invm)
+        const struct rtgui_point *dc_point,
+        struct _fb_rect* RTGUI_RESTRICT dst,
+        const struct rtgui_matrix *invm)
 {
     rt_uint32_t* RTGUI_RESTRICT srcp = (rt_uint32_t*)src->fb;
     rt_uint16_t* RTGUI_RESTRICT dstp = (rt_uint16_t*)dst->fb;
@@ -505,7 +529,7 @@ static void _blit_rotate_FR2FR_ARGB2RGB565(struct _fb_rect* RTGUI_RESTRICT src,
                  * and blend all components at the same time
                  */
                 op = ((op & 0xfc00) << 11) + (op >> 8 & 0xf800)
-                    + (op >> 3 & 0x1f);
+                     + (op >> 3 & 0x1f);
                 d = (d | d << 16) & 0x07e0f81f;
                 d += (op - d) * alpha >> 5;
                 d &= 0x07e0f81f;
@@ -518,9 +542,9 @@ static void _blit_rotate_FR2FR_ARGB2RGB565(struct _fb_rect* RTGUI_RESTRICT src,
 
 /* FrameRect to FrameRect, from ARGB8888 to RGB565. */
 static void _blit_rotate_FR2FR_ARGB2RGB565_AA(struct _fb_rect* RTGUI_RESTRICT src,
-                                              const struct rtgui_point *dc_point,
-                                              struct _fb_rect* RTGUI_RESTRICT dst,
-                                              const struct rtgui_matrix *invm)
+        const struct rtgui_point *dc_point,
+        struct _fb_rect* RTGUI_RESTRICT dst,
+        const struct rtgui_matrix *invm)
 {
     rt_uint32_t* RTGUI_RESTRICT srcp = (rt_uint32_t*)src->fb;
     rt_uint16_t* RTGUI_RESTRICT dstp = (rt_uint16_t*)dst->fb;
@@ -646,7 +670,8 @@ static void _blit_rotate_B2B(struct rtgui_dc_trans *dct,
 
     if (dc->pixel_format == dest->pixel_format)
     {
-        switch (rtgui_color_get_bpp(dest->pixel_format)) {
+        switch (rtgui_color_get_bpp(dest->pixel_format))
+        {
         case 2:
             if (dct->use_aa)
                 _blit_rotate_FR2FR_SF2B_AA(&srcfb, dc_point,
@@ -724,7 +749,8 @@ static void _blit_rotate_B2H(struct rtgui_dc_trans *dct,
 
     if (dc->pixel_format == dest->hw_driver->pixel_format)
     {
-        switch (rtgui_color_get_bpp(dest->hw_driver->pixel_format)) {
+        switch (rtgui_color_get_bpp(dest->hw_driver->pixel_format))
+        {
         case 2:
             if (dct->use_aa)
                 _blit_rotate_FR2FR_SF2B_AA(&srcfb, dc_point,
@@ -820,13 +846,13 @@ void rtgui_dc_trans_blit(struct rtgui_dc_trans *dct,
     if (dct->owner->type == RTGUI_DC_BUFFER)
     {
         if (dest->type == RTGUI_DC_BUFFER)
-                _blit_rotate_B2B(dct, dc_point,
-                                 (struct rtgui_dc_buffer*)dest,
-                                 rect, &invm, neww, newh);
+            _blit_rotate_B2B(dct, dc_point,
+                             (struct rtgui_dc_buffer*)dest,
+                             rect, &invm, neww, newh);
         else if (dest->type == RTGUI_DC_HW)
-                _blit_rotate_B2H(dct, dc_point,
-                                 (struct rtgui_dc_hw*)dest,
-                                 rect, &invm, neww, newh);
+            _blit_rotate_B2H(dct, dc_point,
+                             (struct rtgui_dc_hw*)dest,
+                             rect, &invm, neww, newh);
         else if (dest->type == RTGUI_DC_CLIENT)
             // TODO:
             ;

+ 15 - 5
components/gui/src/filerw.c

@@ -1,11 +1,21 @@
 /*
  * File      : filerw.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 25 - 5
components/gui/src/font.c

@@ -1,11 +1,21 @@
 /*
  * File      : font.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -99,6 +109,16 @@ struct rtgui_font *rtgui_font_refer(const char *family, rt_uint16_t height)
         }
     }
 
+    rtgui_list_foreach(node, &_rtgui_font_list)
+    {
+        font = rtgui_list_entry(node, struct rtgui_font, list);
+        if (rt_strncmp(font->family, family, RTGUI_NAME_MAX) == 0)
+        {
+            font->refer_count ++;
+            return font;
+        }
+    }
+
     return RT_NULL;
 }
 RTM_EXPORT(rtgui_font_refer);

+ 21 - 11
components/gui/src/font_bmp.c

@@ -1,11 +1,21 @@
 /*
  * File      : font.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -34,15 +44,15 @@ void rtgui_bitmap_font_draw_char(struct rtgui_font_bitmap *font, struct rtgui_dc
     const rt_uint8_t *font_ptr;
     int x, y, w, h, style;
     register rt_base_t i, j, /*k,*/ word_bytes;
-	struct rtgui_rect dc_rect;
-	
+    struct rtgui_rect dc_rect;
+
     /* check first and last char */
     if (ch < font->first_char || ch > font->last_char) return;
 
     /* get text style */
     style = rtgui_dc_get_gc(dc)->textstyle;
     bc = rtgui_dc_get_gc(dc)->background;
-	rtgui_dc_get_rect(dc, &dc_rect);
+    rtgui_dc_get_rect(dc, &dc_rect);
 
     x = rect->x1;
     y = rect->y1;
@@ -65,8 +75,8 @@ void rtgui_bitmap_font_draw_char(struct rtgui_font_bitmap *font, struct rtgui_dc
         rt_uint8_t chr = 0;
         const rt_uint8_t *ptr = font_ptr + i * word_bytes;
 
-		if ((i + y) >= dc_rect.y2) continue;
-		if ((i + y) < 0) continue;
+        if ((i + y) >= dc_rect.y2) continue;
+        if ((i + y) < 0) continue;
 
         for (j = 0; j < w; j++)
         {
@@ -92,7 +102,7 @@ static void rtgui_bitmap_font_draw_text(struct rtgui_font *font, struct rtgui_dc
 
     RT_ASSERT(bmp_font != RT_NULL);
 
-	/* parameter check */
+    /* parameter check */
     if (rect->y1 > rect->y2) return;
 
 #ifdef RTGUI_USING_FONTHZ

+ 222 - 197
components/gui/src/font_fnt.c

@@ -1,5 +1,29 @@
 /*
- * rockbox fnt font engine 
+ * File      : font_fnt.c
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-09-15     Bernard      first version
+ */
+
+ /*
+ * rockbox fnt font engine
  */
 #include <rtgui/font_fnt.h>
 #include <rtgui/rtgui_system.h>
@@ -8,102 +32,103 @@ static void rtgui_fnt_font_draw_text(struct rtgui_font *font, struct rtgui_dc *d
 static void rtgui_fnt_font_get_metrics(struct rtgui_font *font, const char *text, rtgui_rect_t *rect);
 const struct rtgui_font_engine fnt_font_engine =
 {
-	RT_NULL,
-	RT_NULL,
+    RT_NULL,
+    RT_NULL,
     rtgui_fnt_font_draw_text,
     rtgui_fnt_font_get_metrics
 };
 
 void rtgui_fnt_font_draw_text(struct rtgui_font *font, struct rtgui_dc *dc, const char *text, rt_ubase_t len, struct rtgui_rect *rect)
 {
-	int ch, i, j, c, width;
-	rt_uint32_t position;
-	struct fnt_font *fnt;
-	rt_uint8_t *data_ptr;
-
-	fnt = (struct fnt_font*)font->data;
-	RT_ASSERT(fnt != RT_NULL);
-
-	while (len)
-	{
-		/* get character */
-		ch = *text;
-		/* NOTE: we only support asc character right now */
-		if (ch > 0x80) 
-		{
-			text += 1; len -= 1;
-			continue;
-		}
-
-		/* get position and width */
-		if (fnt->offset == RT_NULL)
-		{
-			width = fnt->header.max_width;
-			position = (ch - fnt->header.first_char) * width * ((fnt->header.height + 7)/8);
-		}
-		else
-		{
-			width = fnt->width[ch - fnt->header.first_char];
-			position = fnt->offset[ch - fnt->header.first_char];
-		}
-
-		/* draw a character */
-		data_ptr = (rt_uint8_t*)&fnt->bits[position];
-		for (i = 0; i < width; i ++) /* x */
-		{
-			for (j = 0; j < 8; j ++) /* y */
-			{
-				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))
-						continue;
-
-					if (data_ptr[i + c * width] & (1 << j)) 
-						rtgui_dc_draw_point(dc, rect->x1 + i, rect->y1 + c * 8 + j);
-				}
-			}
-		}
-
-		rect->x1 += width;
-		text += 1;
-		len -= 1;
-	}
+    int ch, i, j, c, width;
+    rt_uint32_t position;
+    struct fnt_font *fnt;
+    rt_uint8_t *data_ptr;
+
+    fnt = (struct fnt_font*)font->data;
+    RT_ASSERT(fnt != RT_NULL);
+
+    while (len)
+    {
+        /* get character */
+        ch = *text;
+        /* NOTE: we only support asc character right now */
+        if (ch > 0x80)
+        {
+            text += 1;
+            len -= 1;
+            continue;
+        }
+
+        /* get position and width */
+        if (fnt->offset == RT_NULL)
+        {
+            width = fnt->header.max_width;
+            position = (ch - fnt->header.first_char) * width * ((fnt->header.height + 7)/8);
+        }
+        else
+        {
+            width = fnt->width[ch - fnt->header.first_char];
+            position = fnt->offset[ch - fnt->header.first_char];
+        }
+
+        /* draw a character */
+        data_ptr = (rt_uint8_t*)&fnt->bits[position];
+        for (i = 0; i < width; i ++) /* x */
+        {
+            for (j = 0; j < 8; j ++) /* y */
+            {
+                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))
+                        continue;
+
+                    if (data_ptr[i + c * width] & (1 << j))
+                        rtgui_dc_draw_point(dc, rect->x1 + i, rect->y1 + c * 8 + j);
+                }
+            }
+        }
+
+        rect->x1 += width;
+        text += 1;
+        len -= 1;
+    }
 }
 
 void rtgui_fnt_font_get_metrics(struct rtgui_font *font, const char *text, rtgui_rect_t *rect)
 {
-	int ch;
-	struct fnt_font *fnt;
-
-	fnt = (struct fnt_font*)font->data;
-	RT_ASSERT(fnt != RT_NULL);
-
-	rt_memset(rect, 0x00, sizeof(rtgui_rect_t));
-	rect->y2 = fnt->header.height;
-
-	while (*text)
-	{
-		if (fnt->width == RT_NULL)
-		{
-			/* fixed width font */
-			rect->x2 += fnt->header.max_width;
-		}
-		else
-		{
-			ch = *text;
-			/* NOTE: we only support asc character right now */
-			if (ch > 0x80) 
-			{
-				text += 1;
-				continue;
-			}
-			
-			rect->x2 += fnt->width[ch - fnt->header.first_char];
-		}
-
-		text += 1;
-	}
+    int ch;
+    struct fnt_font *fnt;
+
+    fnt = (struct fnt_font*)font->data;
+    RT_ASSERT(fnt != RT_NULL);
+
+    rt_memset(rect, 0x00, sizeof(rtgui_rect_t));
+    rect->y2 = fnt->header.height;
+
+    while (*text)
+    {
+        if (fnt->width == RT_NULL)
+        {
+            /* fixed width font */
+            rect->x2 += fnt->header.max_width;
+        }
+        else
+        {
+            ch = *text;
+            /* NOTE: we only support asc character right now */
+            if (ch > 0x80)
+            {
+                text += 1;
+                continue;
+            }
+
+            rect->x2 += fnt->width[ch - fnt->header.first_char];
+        }
+
+        text += 1;
+    }
 }
 
 #ifdef RTGUI_USING_FNT_FILE
@@ -111,137 +136,137 @@ void rtgui_fnt_font_get_metrics(struct rtgui_font *font, const char *text, rtgui
 
 rt_inline int readbyte(int fd, unsigned char *cp)
 {
-	unsigned char buf[1];
+    unsigned char buf[1];
 
-	if (read(fd, buf, 1) != 1)
-		return 0;
-	*cp = buf[0];
-	return 1;
+    if (read(fd, buf, 1) != 1)
+        return 0;
+    *cp = buf[0];
+    return 1;
 }
 
 rt_inline int readshort(int fd, unsigned short *sp)
 {
-	unsigned char buf[2];
+    unsigned char buf[2];
 
-	if (read(fd, buf, 2) != 2)
-		return 0;
-	*sp = buf[0] | (buf[1] << 8);
-	return 1;
+    if (read(fd, buf, 2) != 2)
+        return 0;
+    *sp = buf[0] | (buf[1] << 8);
+    return 1;
 }
 
 rt_inline int readlong(int fd, rt_uint32_t *lp)
 {
-	unsigned char buf[4];
+    unsigned char buf[4];
 
-	if (read(fd, buf, 4) != 4)
-		return 0;
-	*lp = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
-	return 1;
+    if (read(fd, buf, 4) != 4)
+        return 0;
+    *lp = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+    return 1;
 }
 
 rt_inline int readstr(int fd, char *buf, int count)
 {
-	return read(fd, buf, count);
+    return read(fd, buf, count);
 }
 
 struct rtgui_font *fnt_font_create(const char* filename, const char* font_family)
 {
-	int fd = -1;
-	rt_uint32_t index;
-	struct rtgui_font *font = RT_NULL;
-	struct fnt_font *fnt = RT_NULL;
-	struct fnt_header *fnt_header;
-
-	fd = open(filename, O_RDONLY, 0);
-	if (fd < 0)
-	{
-		goto __exit;
-	}
-
-	font = (struct rtgui_font*) rtgui_malloc (sizeof(struct rtgui_font));
-	if (font == RT_NULL) goto __exit;
-	fnt = (struct fnt_font*) rtgui_malloc (sizeof(struct fnt_font));
-	if (fnt == RT_NULL) goto __exit;
-	rt_memset(fnt, 0x00, sizeof(struct fnt_font));
-	font->data = (void*)fnt;
-
-	fnt_header = &(fnt->header);
-	if (readstr(fd, fnt_header->version, 4) != 4) goto __exit;
-	if (!readshort(fd, &fnt_header->max_width)) goto __exit;
-	if (!readshort(fd, &fnt_header->height)) goto __exit;
-	if (!readshort(fd, &fnt_header->ascent)) goto __exit;
-	if (!readshort(fd, &fnt_header->depth)) goto __exit;
-
-	if (!readlong(fd, &fnt_header->first_char)) goto __exit;
-	if (!readlong(fd, &fnt_header->default_char)) goto __exit;
-	if (!readlong(fd, &fnt_header->size)) goto __exit;
-	if (!readlong(fd, &fnt_header->nbits)) goto __exit;
-	if (!readlong(fd, &fnt_header->noffset)) goto __exit;
-	if (!readlong(fd, &fnt_header->nwidth)) goto __exit;
-
-	fnt->bits = (MWIMAGEBITS*) rtgui_malloc (fnt_header->nbits * sizeof(MWIMAGEBITS));
-	if (fnt->bits == RT_NULL) goto __exit;
-	/* read data */
-	if (readstr(fd, &(fnt->bits[0]), fnt_header->nbits) != fnt_header->nbits) goto __exit;
-
-	/* check boundary */
-	if (fnt_header->nbits & 0x01)
-	{
-		rt_uint16_t pad;
-		readshort(fd, &pad);
-		pad = pad; /* skip warning */
-	}
-	
-	if (fnt_header->noffset != 0)
-	{
-		fnt->offset = rtgui_malloc (fnt_header->noffset * sizeof(rt_uint32_t));
-		if (fnt->offset == RT_NULL) goto __exit;
-
-		for (index = 0; index < fnt_header->noffset; index ++)
-		{
-			if (!readshort(fd, &(fnt->offset[index]))) goto __exit;
-		}
-	}
-
-	if (fnt_header->nwidth != 0)
-	{
-		fnt->width = rtgui_malloc (fnt_header->nwidth * sizeof(rt_uint8_t));
-		if (fnt->width == RT_NULL) goto __exit;
-
-		for (index = 0; index < fnt_header->nwidth; index ++)
-		{
-			if (!readbyte(fd, &(fnt->width[index]))) goto __exit;
-		}
-	}
-
-	close(fd);
-
-	font->family = rt_strdup(font_family);
-	font->height = fnt->header.height;
-	font->refer_count = 0;
-	font->engine = &fnt_font_engine;
-	
-	/* add to system */
-	rtgui_font_system_add_font(font);
-
-	return font;
+    int fd = -1;
+    rt_uint32_t index;
+    struct rtgui_font *font = RT_NULL;
+    struct fnt_font *fnt = RT_NULL;
+    struct fnt_header *fnt_header;
+
+    fd = open(filename, O_RDONLY, 0);
+    if (fd < 0)
+    {
+        goto __exit;
+    }
+
+    font = (struct rtgui_font*) rtgui_malloc (sizeof(struct rtgui_font));
+    if (font == RT_NULL) goto __exit;
+    fnt = (struct fnt_font*) rtgui_malloc (sizeof(struct fnt_font));
+    if (fnt == RT_NULL) goto __exit;
+    rt_memset(fnt, 0x00, sizeof(struct fnt_font));
+    font->data = (void*)fnt;
+
+    fnt_header = &(fnt->header);
+    if (readstr(fd, fnt_header->version, 4) != 4) goto __exit;
+    if (!readshort(fd, &fnt_header->max_width)) goto __exit;
+    if (!readshort(fd, &fnt_header->height)) goto __exit;
+    if (!readshort(fd, &fnt_header->ascent)) goto __exit;
+    if (!readshort(fd, &fnt_header->depth)) goto __exit;
+
+    if (!readlong(fd, &fnt_header->first_char)) goto __exit;
+    if (!readlong(fd, &fnt_header->default_char)) goto __exit;
+    if (!readlong(fd, &fnt_header->size)) goto __exit;
+    if (!readlong(fd, &fnt_header->nbits)) goto __exit;
+    if (!readlong(fd, &fnt_header->noffset)) goto __exit;
+    if (!readlong(fd, &fnt_header->nwidth)) goto __exit;
+
+    fnt->bits = (MWIMAGEBITS*) rtgui_malloc (fnt_header->nbits * sizeof(MWIMAGEBITS));
+    if (fnt->bits == RT_NULL) goto __exit;
+    /* read data */
+    if (readstr(fd, &(fnt->bits[0]), fnt_header->nbits) != fnt_header->nbits) goto __exit;
+
+    /* check boundary */
+    if (fnt_header->nbits & 0x01)
+    {
+        rt_uint16_t pad;
+        readshort(fd, &pad);
+        pad = pad; /* skip warning */
+    }
+
+    if (fnt_header->noffset != 0)
+    {
+        fnt->offset = rtgui_malloc (fnt_header->noffset * sizeof(rt_uint32_t));
+        if (fnt->offset == RT_NULL) goto __exit;
+
+        for (index = 0; index < fnt_header->noffset; index ++)
+        {
+            if (!readshort(fd, &(fnt->offset[index]))) goto __exit;
+        }
+    }
+
+    if (fnt_header->nwidth != 0)
+    {
+        fnt->width = rtgui_malloc (fnt_header->nwidth * sizeof(rt_uint8_t));
+        if (fnt->width == RT_NULL) goto __exit;
+
+        for (index = 0; index < fnt_header->nwidth; index ++)
+        {
+            if (!readbyte(fd, &(fnt->width[index]))) goto __exit;
+        }
+    }
+
+    close(fd);
+
+    font->family = rt_strdup(font_family);
+    font->height = fnt->header.height;
+    font->refer_count = 0;
+    font->engine = &fnt_font_engine;
+
+    /* add to system */
+    rtgui_font_system_add_font(font);
+
+    return font;
 
 __exit:
-	if (fd >= 0) close(fd);
-	if (fnt != RT_NULL)
-	{
-		if (fnt->bits != RT_NULL) rtgui_free(fnt->bits);
-		if (fnt->offset != RT_NULL) rtgui_free(fnt->offset);
-		if (fnt->width != RT_NULL) rtgui_free(fnt->width);
-
-		rtgui_free(fnt);
-	}
-
-	if (font != RT_NULL)
-	{
-		rtgui_free(font);
-	}
-	return RT_NULL;
+    if (fd >= 0) close(fd);
+    if (fnt != RT_NULL)
+    {
+        if (fnt->bits != RT_NULL) rtgui_free(fnt->bits);
+        if (fnt->offset != RT_NULL) rtgui_free(fnt->offset);
+        if (fnt->width != RT_NULL) rtgui_free(fnt->width);
+
+        rtgui_free(fnt);
+    }
+
+    if (font != RT_NULL)
+    {
+        rtgui_free(font);
+    }
+    return RT_NULL;
 }
 #endif
 

+ 459 - 237
components/gui/src/font_freetype.c

@@ -1,11 +1,38 @@
+/*
+ * File      : font_freetype.c
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-09-15     Grissom      first version
+ */
+
 #include <rtthread.h>
 
 #ifdef RTGUI_USING_TTF
 #include <rtgui/rtgui.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/dc.h>
+#include <rtgui/blit.h>
 #include <rtgui/font.h>
+#include <rtgui/font_freetype.h>
 
+#include <ftcache.h>
 #include <ft2build.h>
 #include FT_FREETYPE_H
 
@@ -25,31 +52,8 @@
 #define PINFO(...)
 #endif
 
-static void ftf_draw_text(struct rtgui_font *font,
-                          struct rtgui_dc *dc,
-                          const char *text,
-                          rt_ubase_t len,
-                          struct rtgui_rect *rect);
-static void ftf_get_metrics_kern(struct rtgui_font *font,
-                                  const char *text,
-                                  rtgui_rect_t *rect);
-
-static const struct rtgui_font_engine ftf_engine =
-{
-    RT_NULL,
-    RT_NULL,
-    ftf_draw_text,
-    ftf_get_metrics_kern
-};
-
-struct rtgui_freetype2_font
-{
-    int bold;
-    int italic;
-
-    FT_Face     face;
-    FT_Library  library;
-};
+#define _dc_get_pixel(dc, x, y)	\
+    ((dc)->pixel + (y) * (dc)->pitch + (x) * rtgui_color_get_bpp((dc)->pixel_format))
 
 #if !defined(RT_USING_DFS) || !defined(RT_USING_DFS_ELMFAT) || (RT_DFS_ELM_CODE_PAGE != 936)
 extern rt_uint32_t gb2312tounicode(const rt_uint16_t key);
@@ -87,129 +91,321 @@ static void gbk_to_unicode(rt_uint16_t *unicode, const char *text, int len)
     *unicode = '\0';
 }
 
-static void _draw_bitmap(struct rtgui_dc *dc,
-                         FT_GlyphSlot slot,
-                         rt_int16_t ox, rt_int16_t btm_y,
-                         rt_uint8_t r, rt_uint8_t g, rt_uint8_t b)
+static void _rtgui_rect_moveto_align(const rtgui_rect_t *rect, rtgui_rect_t *to, int align)
 {
-    int rows;
-    rt_uint8_t *ptr;
-    FT_Bitmap *bitmap;
-    rt_int16_t xstart;
+    int dw, dh;
+    dw = 0;
+    dh = 0;
+
+    /* get delta width and height */
+    dw = rtgui_rect_width(*rect) - rtgui_rect_width(*to);
+    dh = rtgui_rect_height(*rect) - rtgui_rect_height(*to);
+    if (dw < 0) dw = 0;
+    if (dh < 0) dh = 0;
 
-    bitmap = &slot->bitmap;
-    ptr = (rt_uint8_t *)bitmap->buffer;
-    xstart = ox + slot->bitmap_left;
+    /* move to insider of rect */
+    rtgui_rect_moveto_point(to, rect->x1, rect->y1);
 
-    for (rows = 0; rows < bitmap->rows; rows++)
+    /* limited the destination rect to source rect */
+    // if (dw == 0) to->x2 = rect->x2;
+    // if (dh == 0) to->y2 = rect->y2;
+
+    /* align to right */
+    if (align & RTGUI_ALIGN_RIGHT)
     {
-        int x;
-        int y = btm_y + rows - slot->bitmap_top;
+        to->x1 += dw;
+        to->x2 += dw;
+    }
 
-        for (x = 0; x < bitmap->width; x++)
-        {
-            /* Use 5bit alpha. */
-            rt_uint8_t c = *ptr;
-            if (c >= 0xF8)
-            {
-                rtgui_dc_draw_point(dc, xstart + x, y);
-            }
-            else if (c >> 3)
-            {
-                rtgui_dc_blend_point(dc, xstart + x, y,
-                                     RTGUI_BLENDMODE_BLEND,
-                                     r, g, b, c);
-            }
-            ptr++;
-        }
+    /* align to bottom */
+    if (align & RTGUI_ALIGN_BOTTOM)
+    {
+        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)
+    {
+        to->y1 += dh >> 1;
+        to->y2 += dh >> 1;
     }
 }
 
-static void _draw_text_nkern(struct rtgui_dc *dc,
-                             struct rtgui_freetype2_font *fft,
-                             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)
+static void ftc_draw_text(struct rtgui_font *font,
+                          struct rtgui_dc *dc,
+                          const char *text,
+                          rt_ubase_t len,
+                          struct rtgui_rect *rect);
+static void ftc_get_metrics(struct rtgui_font *font, const char *text, rtgui_rect_t *rect);
+
+static const struct rtgui_font_engine ftc_engine =
 {
-    rt_uint16_t *text_ptr;
-    FT_GlyphSlot  slot;
+    RT_NULL,
+    RT_NULL,
+    ftc_draw_text,
+    ftc_get_metrics
+};
 
-    slot = fft->face->glyph;
+struct ttf_face_id
+{
+    const char*  pathname;
+    FT_Long      face_index;
+};
 
-    for (text_ptr = text_short; *text_ptr; text_ptr++)
+struct rtgui_ttf
+{
+    /* the ttf list */
+    rtgui_list_t 	list;
+    rt_uint32_t		refer_count;
+
+    struct ttf_face_id  face_id;
+    FT_Library  		library;
+    FTC_Manager 		manager;
+    FTC_SBitCache 		sbit_cache;
+    FTC_CMapCache 		cmap_cache;
+};
+
+struct rtgui_ttf_font
+{
+    struct rtgui_ttf	*ttf;
+    FTC_ImageTypeRec	image_type_rec;
+};
+
+static rtgui_list_t _rtgui_ttf_list;
+
+void rtgui_ttf_system_init(void)
+{
+    rtgui_list_init(&(_rtgui_ttf_list));
+}
+
+static void rtgui_ttf_system_add_ttf(struct rtgui_ttf *ttf)
+{
+    rtgui_list_append(&_rtgui_ttf_list, &(ttf->list));
+}
+
+static void rtgui_ttf_system_remove_ttf(struct rtgui_ttf *ttf)
+{
+    rtgui_list_remove(&_rtgui_ttf_list, &(ttf->list));
+}
+
+static struct rtgui_ttf *rtgui_ttf_refer(const char *family)
+{
+    /* search ttf */
+    struct rtgui_list_node *node;
+    struct rtgui_ttf *ttf;
+
+    rtgui_list_foreach(node, &_rtgui_ttf_list)
     {
-        FT_Error err = 0;
+        ttf = (struct rtgui_ttf *)node;
+        if (rt_strncmp(ttf->face_id.pathname, family, RT_DFS_ELM_MAX_LFN) == 0)
+        {
+            ttf->refer_count ++;
+            return ttf;
+        }
+    }
 
-        err = FT_Load_Char(fft->face, *text_ptr, FT_LOAD_RENDER | FT_LOAD_NO_HINTING);
-        if (err)
-            continue;  /* ignore errors */
+    return RT_NULL;
+}
 
-        /* render font */
-        _draw_bitmap(dc, slot, begin_x, btm_y, r, g, b);
+static void rtgui_ttf_derefer(struct rtgui_ttf *ttf)
+{
+    RT_ASSERT(ttf != RT_NULL);
 
-        begin_x += slot->advance.x >> 6;
+    ttf->refer_count --;
+
+    /* no refer, remove ttf */
+    if (ttf->refer_count == 0)
+    {
+        rtgui_ttf_system_remove_ttf(ttf);
     }
 }
 
-static void _draw_text_kern(struct rtgui_dc *dc,
-                            struct rtgui_freetype2_font *fft,
-                            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)
+
+static void _get_metrics(struct rtgui_ttf_font *ttf_font, const rt_uint16_t *text_short, struct rtgui_rect *rect);
+
+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_uint16_t *tp;
-    FT_GlyphSlot  slot;
-    FT_Face  face;
-    rt_uint32_t prev_gidx;
+    rt_int16_t x_start, y_start;
+    struct rtgui_blit_info info;
+    struct rtgui_dc_buffer *dest_buf;
+
 
-    face = fft->face;
-    slot = face->glyph;
+    x_start = ox + bitmap->left;
+    y_start = btm_y - bitmap->top;
 
-    prev_gidx = 0;
-    for (tp = text_short; *tp; tp++)
+    info.a = 255;
+    info.r = r;
+    info.g = g;
+    info.b = b;
+
+    if (dc->type == RTGUI_DC_HW)
     {
-        FT_Error err;
-        rt_uint32_t cur_gidx;
+        struct rtgui_graphic_driver *hw_driver = rtgui_graphic_driver_get_default();
+        dest_buf = (struct rtgui_dc_buffer*)dc;
 
-        cur_gidx = FT_Get_Char_Index(face, *tp);
-        if (prev_gidx && cur_gidx)
+        if (hw_driver->framebuffer != RT_NULL)
         {
-            FT_Vector delta;
+            struct rtgui_widget *owner = ((struct rtgui_dc_hw*)dest_buf)->owner;
+
+            if (x_start + bitmap->width < 0 || y_start + bitmap->height < 0
+                    || x_start > owner->extent.x2 - owner->extent.x1 || y_start > owner->extent.y2 - owner->extent.y1)
+                return;
+
+            /* blit source */
+            info.src = (rt_uint8_t *)bitmap->buffer;
+            info.src = info.src + (y_start > 0 ? 0 : bitmap->top - btm_y) * bitmap->width + (x_start > 0 ? 0 : -x_start);
+            info.src_fmt = RTGRAPHIC_PIXEL_FORMAT_ALPHA;
+            info.src_w = bitmap->width - (x_start > 0 ? 0 : -x_start) - (x_start + bitmap->width < owner->extent.x2 - owner->extent.x1 ? 0 : x_start + bitmap->width - owner->extent.x2 + owner->extent.x1);
+            info.src_h = bitmap->height - (y_start > 0 ? 0 : bitmap->top - btm_y) - (y_start + bitmap->height < owner->extent.y2 - owner->extent.y1 ? 0 : y_start + bitmap->height - owner->extent.y2 + owner->extent.y1);
+            info.src_pitch = bitmap->width;
+            info.src_skip = info.src_pitch - info.src_w;
+
+            /* blit destination */
+            info.dst = (rt_uint8_t*)hw_driver->framebuffer;
+            info.dst = info.dst + (owner->extent.y1 + (y_start < 0 ? 0 : y_start)) * hw_driver->pitch + (owner->extent.x1 + (x_start < 0 ? 0 : x_start)) * rtgui_color_get_bpp(hw_driver->pixel_format);
+            info.dst_fmt = hw_driver->pixel_format;
+            info.dst_w = info.src_w;
+            info.dst_h = info.src_h;
+            info.dst_pitch = hw_driver->pitch;
+            info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(hw_driver->pixel_format);
+
+            rtgui_blit(&info);
+        }
+    }
+    else if (dc->type == RTGUI_DC_BUFFER)
+    {
+        dest_buf = (struct rtgui_dc_buffer*)dc;
+
+        if (x_start + bitmap->width < 0 || y_start + bitmap->height < 0
+                || x_start > dest_buf->width || y_start > dest_buf->height)
+            return;
+
+        /* blit source */
+        info.src = (rt_uint8_t *)bitmap->buffer;
+        info.src = info.src + (y_start > 0 ? 0 : -y_start) * bitmap->width + (x_start > 0 ? 0 : -x_start);
+        info.src_fmt = RTGRAPHIC_PIXEL_FORMAT_ALPHA;
+        info.src_w = bitmap->width - (x_start > 0 ? 0 : -x_start) - (x_start + bitmap->width < dest_buf->width ? 0 : x_start + bitmap->width - dest_buf->width);
+        info.src_h = bitmap->height - (y_start > 0 ? 0 : -y_start) - (y_start + bitmap->height < dest_buf->height ? 0 : y_start + bitmap->height - dest_buf->height);
+        info.src_pitch = bitmap->width;
+        info.src_skip = info.src_pitch - info.src_w;
+
+        /* blit destination */
+        info.dst = _dc_get_pixel(dest_buf, (x_start < 0 ? 0 : x_start), (y_start < 0 ? 0 : y_start));
+        info.dst_fmt = dest_buf->pixel_format;
+        info.dst_w = info.src_w;
+        info.dst_h = info.src_h;
+        info.dst_pitch = dest_buf->pitch;
+        info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(dest_buf->pixel_format);
+
+        rtgui_blit(&info);
+    }
+    else
+    {
+        struct rtgui_rect text_rect;
+        struct rtgui_point dc_point = { 0, 0 };
+        struct rtgui_dc *text_dc = rtgui_dc_buffer_create_pixformat(RTGRAPHIC_PIXEL_FORMAT_ARGB888, bitmap->width, bitmap->height);
+        if (text_dc)
+        {
+            dest_buf = (struct rtgui_dc_buffer*)text_dc;
+
+            /* blit source */
+            info.src = (rt_uint8_t *)bitmap->buffer;
+            info.src_fmt = RTGRAPHIC_PIXEL_FORMAT_ALPHA;
+            info.src_w = bitmap->width;
+            info.src_h = bitmap->height;
+            info.src_pitch = bitmap->width;
+            info.src_skip = 0;
+
+            /* blit destination */
+            info.dst = _dc_get_pixel(dest_buf, 0, 0);
+            info.dst_fmt = dest_buf->pixel_format;
+            info.dst_w = info.src_w;
+            info.dst_h = info.src_h;
+            info.dst_pitch = dest_buf->pitch;
+            info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(dest_buf->pixel_format);
+
+            rtgui_blit(&info);
+
+            text_rect.x1 = x_start;
+            text_rect.x2 = text_rect.x1 + bitmap->width;
 
-            FT_Get_Kerning(face, prev_gidx, cur_gidx,
-                            FT_KERNING_DEFAULT, &delta );
+            text_rect.y1 = y_start;
+            text_rect.y2 = text_rect.y1 + bitmap->height;
 
-            begin_x += delta.x >> 6;
+            rtgui_dc_blit(text_dc, &dc_point, dc, &text_rect);
+
+            rtgui_dc_destory(text_dc);
         }
-        prev_gidx = cur_gidx;
+    }
+}
 
-        err = FT_Load_Glyph(face, cur_gidx, FT_LOAD_RENDER | FT_LOAD_NO_HINTING);
-        if (err)
-            continue;
+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)
+{
+    int glyphIndex;
+    FTC_SBit ftcSBit = RT_NULL;
+    FT_Error err = 0;
 
-        /* render font */
-        _draw_bitmap(dc, slot, begin_x, btm_y, r, g, b);
+    while (*text_short)
+    {
+        glyphIndex = FTC_CMapCache_Lookup(ttf_font->ttf->cmap_cache, &ttf_font->ttf->face_id, 0, *text_short);
+
+        err = FTC_SBitCache_Lookup(ttf_font->ttf->sbit_cache, &ttf_font->image_type_rec, glyphIndex, &ftcSBit, 0);
+        if (err == 0 && ftcSBit->width != 0)
+        {
+            /* render font */
+            _draw_bitmap(dc, ftcSBit, begin_x, btm_y, r, g, b);
+
+            begin_x += ftcSBit->width + ftcSBit->left;
+
+            text_short++;
+        }
+        else if (*text_short == ' ')
+        {
+            glyphIndex = FTC_CMapCache_Lookup(ttf_font->ttf->cmap_cache, &ttf_font->ttf->face_id, 0, '-');
+
+            err = FTC_SBitCache_Lookup(ttf_font->ttf->sbit_cache, &ttf_font->image_type_rec, glyphIndex, &ftcSBit, 0);
+            if (err == 0)
+            {
+                begin_x += ftcSBit->width;
 
-        begin_x += slot->advance.x >> 6;
+                text_short++;
+            }
+        }
     }
 }
 
-static void ftf_draw_text(struct rtgui_font *font,
+static void ftc_draw_text(struct rtgui_font *font,
                           struct rtgui_dc *dc,
                           const char *text,
                           rt_ubase_t len,
                           struct rtgui_rect *rect)
 {
     rt_uint16_t *text_short;
-    struct rtgui_freetype2_font *fft;
+    struct rtgui_ttf_font *ttf_font;
     rt_int16_t begin_x, btm_y;
     rt_int16_t topy;
     rt_uint8_t r, g, b;
     rtgui_color_t fgc;
+    struct rtgui_rect text_rect;
 
     RT_ASSERT(font != RT_NULL);
-    fft = (struct rtgui_freetype2_font *) font->data;
-    RT_ASSERT(fft != RT_NULL);
+    ttf_font = (struct rtgui_ttf_font *) font->data;
+    RT_ASSERT(ttf_font != RT_NULL);
 
     /* allocate unicode buffer */
     text_short = (rt_uint16_t *)rtgui_malloc((len + 1) * 2);
@@ -226,135 +422,104 @@ static void ftf_draw_text(struct rtgui_font *font,
     g = RTGUI_RGB_G(fgc);
     b = RTGUI_RGB_B(fgc);
 
-    /* FIXME: RTGUI has no concept of "base line" right now. FreeType
-     * coordinate(0, 0) start from base line. So we have to adjust the rect to
-     * fit the glyphs within the rect. */
-    /* FIXME: face->size->metrics.descender is format specific actually. But it
-     * just works on TrueType. Varify this if you want to use with other fonts. */
-    topy = rect->y1 + (fft->face->size->metrics.descender >> 6);
-    btm_y = topy + rtgui_rect_height(*rect);
+    /* text align */
+    _get_metrics(ttf_font, text_short, &text_rect);
+
+    topy = text_rect.y1;
+
+    _rtgui_rect_moveto_align(rect, &text_rect, RTGUI_DC_TEXTALIGN(dc));
+
+    btm_y = topy + text_rect.y2;
     if (btm_y <= 0)
         return;
-    begin_x = rect->x1;
+    begin_x = text_rect.x1;
 
     if (dc->type == RTGUI_DC_BUFFER)
     {
-		struct rtgui_dc_buffer *bdc = (struct rtgui_dc_buffer *) dc;
+        struct rtgui_dc_buffer *bdc = (struct rtgui_dc_buffer *) dc;
 
         if (begin_x >= bdc->width || topy >= bdc->height)
         {
             goto _out;
         }
     }
-	else if (dc->type == RTGUI_DC_HW)
-	{
+    else if (dc->type == RTGUI_DC_HW)
+    {
         int x, y;
-		struct rtgui_dc_hw *hdc = (struct rtgui_dc_hw *) dc;
+        struct rtgui_dc_hw *hdc = (struct rtgui_dc_hw *) dc;
 
-		x = begin_x + hdc->owner->extent.x1;
-		y = topy + hdc->owner->extent.y1;
-		if (x >= hdc->owner->extent.x2)
+        x = begin_x + hdc->owner->extent.x1;
+        y = topy + hdc->owner->extent.y1;
+        if (x >= hdc->owner->extent.x2)
             goto _out;
-		if (y >= hdc->owner->extent.y2)
+        if (y >= hdc->owner->extent.y2)
             goto _out;
-	}
-
-    if (FT_HAS_KERNING(fft->face))
-    {
-        _draw_text_kern(dc, fft, text_short, begin_x, btm_y, r, g, b);
-    }
-    else
-    {
-        _draw_text_nkern(dc, fft, text_short, begin_x, btm_y, r, g, b);
     }
 
+    _draw_text(dc, ttf_font, text_short, begin_x, btm_y, r, g, b);
+
 _out:
     /* release unicode buffer */
     rtgui_free(text_short);
 }
 
-static void _get_metrics_nkern(FT_Face face, const rt_uint16_t *text_short, struct rtgui_rect *rect)
+static void _get_metrics(struct rtgui_ttf_font *ttf_font, const rt_uint16_t *text_short, struct rtgui_rect *rect)
 {
-    rt_int16_t w;
+    FTC_SBit ftcSBit = RT_NULL;
+    rt_int16_t w = 0, top = 0, btm = 0;
 
-    w = 0;
     while (*text_short)
     {
         FT_Error err = 0;
-        rt_uint16_t index;
-
-        index = FT_Get_Char_Index(face, *text_short);
-        err = FT_Load_Glyph(face, index,
-                            FT_LOAD_DEFAULT |
-                            FT_LOAD_NO_HINTING |
-                            FT_LOAD_IGNORE_TRANSFORM |
-                            FT_LOAD_NO_AUTOHINT);
+        int glyphIndex;
 
-        if (err == 0)
-            w += face->glyph->advance.x >> 6;
+        glyphIndex = FTC_CMapCache_Lookup(ttf_font->ttf->cmap_cache, &ttf_font->ttf->face_id, 0, *text_short);
 
-        text_short ++;
-    }
-
-    rect->x1 = 0;
-    rect->y1 = 0;
-    rect->x2 = w;
-    rect->y2 = FT_MulFix(face->bbox.yMax - face->bbox.yMin,
-                         face->size->metrics.y_scale) >> 6;
-}
-
-static void _get_metrics_kern(FT_Face face, const rt_uint16_t *text_short, struct rtgui_rect *rect)
-{
-    rt_uint16_t prev_gidx;
-    rt_int16_t w;
-
-    prev_gidx = 0;
-    w = 0;
-    while (*text_short)
-    {
-        FT_Error err = 0;
-        rt_uint16_t index;
-
-        index = FT_Get_Char_Index(face, *text_short);
-        if (prev_gidx && index)
+        err = FTC_SBitCache_Lookup(ttf_font->ttf->sbit_cache, &ttf_font->image_type_rec, glyphIndex, &ftcSBit, 0);
+        if (err == 0 && ftcSBit->width != 0)
         {
-            FT_Vector delta;
-
-            FT_Get_Kerning(face, prev_gidx, index,
-                            FT_KERNING_DEFAULT, &delta);
+            if (w == 0)
+                w = ftcSBit->width;
+            else
+                w += ftcSBit->width + ftcSBit->left;
 
-            w += delta.x >> 6;
+            top = top > ftcSBit->top ? top : ftcSBit->top;
+            btm = (ftcSBit->top - ftcSBit->height) > btm ? btm : (ftcSBit->top - ftcSBit->height);
         }
-        prev_gidx = index;
-        err = FT_Load_Glyph(face, index,
-                            FT_LOAD_DEFAULT |
-                            FT_LOAD_NO_HINTING |
-                            FT_LOAD_IGNORE_TRANSFORM |
-                            FT_LOAD_NO_AUTOHINT);
+        else if (*text_short == ' ')
+        {
+            glyphIndex = FTC_CMapCache_Lookup(ttf_font->ttf->cmap_cache, &ttf_font->ttf->face_id, 0, '-');
 
-        if (err == 0)
-            w += face->glyph->advance.x >> 6;
+            err = FTC_SBitCache_Lookup(ttf_font->ttf->sbit_cache, &ttf_font->image_type_rec, glyphIndex, &ftcSBit, 0);
+            if (err == 0)
+            {
+                w += ftcSBit->width;
+            }
+        }
+        PINFO(" bitmap:(%d, %d, %d, %d)\n", ftcSBit->left, ftcSBit->top,
+              ftcSBit->width, ftcSBit->height);
 
         text_short ++;
     }
 
     rect->x1 = 0;
-    rect->y1 = 0;
+    rect->y1 = btm;
     rect->x2 = w;
-    rect->y2 = FT_MulFix(face->bbox.yMax - face->bbox.yMin,
-                         face->size->metrics.y_scale) >> 6;
+    rect->y2 = top;
+
+    PINFO(" _get_metrics: %d %d %d %d\n", rect->x1, rect->y1, rect->x2, rect->y2);
 }
 
-static void ftf_get_metrics_kern(struct rtgui_font *font, const char *text, rtgui_rect_t *rect)
+static void ftc_get_metrics(struct rtgui_font *font, const char *text, struct rtgui_rect *rect)
 {
     int len;
     rt_uint16_t *text_short;
-    struct rtgui_freetype2_font *fft;
+    struct rtgui_ttf_font *ttf_font;
 
     RT_ASSERT(font != RT_NULL);
     RT_ASSERT(rect != RT_NULL);
-    fft = (struct rtgui_freetype2_font *) font->data;
-    RT_ASSERT(fft != RT_NULL);
+    ttf_font = (struct rtgui_ttf_font *) font->data;
+    RT_ASSERT(ttf_font != RT_NULL);
 
     len = strlen(text);
     memset(rect, 0, sizeof(struct rtgui_rect));
@@ -367,111 +532,168 @@ static void ftf_get_metrics_kern(struct rtgui_font *font, const char *text, rtgu
     /* convert gbk to unicode */
     gbk_to_unicode(text_short, text, len);
 
-    if (FT_HAS_KERNING(fft->face))
-        _get_metrics_kern(fft->face, text_short, rect);
-    else
-        _get_metrics_nkern(fft->face, text_short, rect);
+    _get_metrics(ttf_font, text_short, rect);
+    rtgui_rect_moveto_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 */
     rtgui_free(text_short);
 }
 
-rtgui_font_t *rtgui_freetype_font_create(const char *filename, int bold, int italic, rt_size_t size)
+static FT_Error ftc_face_requester(FTC_FaceID faceID, FT_Library lib, FT_Pointer reqData, FT_Face *face)
+{
+    int ret;
+
+    struct ttf_face_id *face_id = (struct ttf_face_id *)faceID;
+
+    PINFO("ftc_face_requester  %s  %d\n", face_id->pathname, face_id->face_index);
+    ret = FT_New_Face(lib, (char *)face_id->pathname, face_id->face_index, face);
+    if (ret != 0)
+    {
+        PERROR("FT_New_Face failed!\n");
+        return -1;
+    }
+
+    return 0;
+}
+
+static struct rtgui_ttf *rtgui_ttf_load(const char *filename)
 {
     FT_Error err = 0;
-    struct rtgui_font *font;
-    struct rtgui_freetype2_font *fft;
+    struct rtgui_ttf *ttf;
 
-    font = (struct rtgui_font *)rtgui_malloc(sizeof(struct rtgui_font)
-                                             + sizeof(struct rtgui_freetype2_font));
-    rt_memset(font, 0, sizeof(struct rtgui_font) + sizeof(struct rtgui_freetype2_font));
-    if (!font)
+    ttf = (struct rtgui_ttf *)rtgui_malloc(sizeof(struct rtgui_ttf));
+    if (!ttf)
     {
-        PERROR("failed to allocate structs\n");
+        PERROR("rtgui_ttf_load rtgui_malloc failed!\n");
         return RT_NULL;
     }
 
-    fft = (struct rtgui_freetype2_font *)(font + 1);
-    font->data = fft;
+    /* face_id init */
+    ttf->face_id.pathname = rt_strdup(filename);
+    ttf->face_id.face_index = 0;
 
-    err = FT_Init_FreeType(&fft->library);
+    err = FT_Init_FreeType(&ttf->library);
     if (err)
     {
-        PERROR("failed to Init FreeType: %d\n", err);
+        PERROR("FT_Init_FreeType failed err: %d\n", err);
         goto _err_done_malloc;
     }
 
-    err = FT_New_Face(fft->library, filename, 0, &fft->face);
-    if (err)
+    err = FTC_Manager_New(ttf->library, 0, 0, 0, ftc_face_requester, 0, &ttf->manager);
+    if (err != 0)
     {
-        PERROR("failed to New Face: %d\n", err);
+        PERROR("FTC_Manager_New failed!\n");
         goto _err_done_init;
     }
 
-    err = FT_Select_Charmap(fft->face, FT_ENCODING_UNICODE);
-    if (err)
+    err = FTC_CMapCache_New(ttf->manager, &ttf->cmap_cache);
+    if (err != 0)
     {
-        err = FT_Select_Charmap(fft->face, FT_ENCODING_ADOBE_LATIN_1);
+        PERROR("FTC_CMapCache_New failed!\n");
+        goto _err_done_manager;
     }
 
-    err = FT_Set_Pixel_Sizes(fft->face, 0, size);
+    err = FTC_SBitCache_New(ttf->manager, &ttf->sbit_cache);
     if (err != 0)
     {
-        PERROR("failed to set Pixel Size: %d\n", err);
-        goto _err_done_face;
+        PERROR("FTC_SBitCache_New failed!\n");
+        goto _err_done_manager;
+    }
+
+    ttf->refer_count = 1;
+
+    rtgui_ttf_system_add_ttf(ttf);
+
+    return ttf;
+
+_err_done_manager:
+    FTC_Manager_Done(ttf->manager);
+_err_done_init:
+    FT_Done_FreeType(ttf->library);
+_err_done_malloc:
+    rt_free((void *)ttf->face_id.pathname);
+    rtgui_free(ttf);
+
+    return RT_NULL;
+}
+RTM_EXPORT(rtgui_ttf_load);
+
+rtgui_font_t *rtgui_freetype_font_create(const char *filename, rt_size_t size)
+{
+    struct rtgui_font *font;
+    struct rtgui_ttf_font *ttf_font;
+    struct rtgui_ttf *ttf;
+
+    ttf = rtgui_ttf_refer(filename);
+    if (!ttf)
+    {
+        PERROR("rtgui_ttf_refer failed!\n");
+
+        ttf = rtgui_ttf_load(filename);
+        if (!ttf)
+        {
+            PERROR("rtgui_ttf_load failed!\n");
+            return RT_NULL;
+        }
+    }
+
+    font = (struct rtgui_font *)rtgui_malloc(sizeof(struct rtgui_font) + sizeof(struct rtgui_ttf_font));
+    if (!font)
+    {
+        PERROR("rtgui_ttf_load rtgui_malloc failed!\n");
+        return RT_NULL;
     }
 
-    fft->bold = bold;
-    fft->italic = italic;
+    ttf_font = (struct rtgui_ttf_font *)(font + 1);
+    font->data = ttf_font;
+
+    ttf_font->ttf = ttf;
 
-    PINFO("fonfile:%s\n", filename);
-    PINFO("font family_name:%s\n", fft->face->family_name);
-    PINFO("font style_name:%s\n", fft->face->style_name);
-    PINFO("%s kerneling\n", FT_HAS_KERNING(fft->face) ? "has" : "not has");
+    /* image_type_rec init */
+    ttf_font->image_type_rec.face_id = &ttf_font->ttf->face_id;
+    ttf_font->image_type_rec.width 	 = size;
+    ttf_font->image_type_rec.height  = size;
+    ttf_font->image_type_rec.flags 	 = FT_LOAD_RENDER | FT_LOAD_NO_HINTING;
 
     /* set user data */
-    font->family = rt_strdup(fft->face->family_name);
-    font->height = (rt_uint16_t)size;
+    font->family = (char *)(ttf_font->ttf->face_id.pathname);
+    font->height = (rt_uint16_t)ttf_font->image_type_rec.height;
     font->refer_count = 1;
-    font->engine = &ftf_engine;
+    font->engine = &ftc_engine;
 
     /* add to system */
     rtgui_font_system_add_font(font);
 
     return font;
-
-_err_done_face:
-    FT_Done_Face(fft->face);
-_err_done_init:
-    FT_Done_FreeType(fft->library);
-_err_done_malloc:
-    rtgui_free(font);
-
-    return RT_NULL;
 }
 RTM_EXPORT(rtgui_freetype_font_create);
 
 void rtgui_freetype_font_destroy(rtgui_font_t *font)
 {
-    struct rtgui_freetype2_font *fft;
+    struct rtgui_ttf_font *ttf_font;
 
     RT_ASSERT(font != RT_NULL);
-    fft = (struct rtgui_freetype2_font *) font->data;
-    RT_ASSERT(fft != RT_NULL);
+    ttf_font = (struct rtgui_ttf_font *) font->data;
+    RT_ASSERT(ttf_font != RT_NULL);
 
     rtgui_font_system_remove_font(font);
 
-    FT_Done_Face(fft->face);
-    FT_Done_FreeType(fft->library);
-    rt_free(font->family);
+    rtgui_ttf_derefer(ttf_font->ttf);
+
+    if (ttf_font->ttf->refer_count == 0)
+    {
+        FTC_Manager_Done(ttf_font->ttf->manager);
+        FT_Done_FreeType(ttf_font->ttf->library);
+        rt_free(font->family);
+    }
+
     rtgui_free(font);
 }
 RTM_EXPORT(rtgui_freetype_font_destroy);
 
 #ifdef RT_USING_FINSH
 #include <finsh.h>
-FINSH_FUNCTION_EXPORT_ALIAS(rtgui_freetype_font_create, ftc, "create freetype font: name, bold, italic, size")
-FINSH_FUNCTION_EXPORT_ALIAS(rtgui_freetype_font_destroy, ftd, "destroy freetype font")
+FINSH_FUNCTION_EXPORT_ALIAS(rtgui_freetype_font_create, ffc, "create freetype font: name, size")
 #endif
-
 #endif

+ 23 - 1
components/gui/src/font_hz_bmp.c

@@ -1,4 +1,26 @@
-
+/*
+ * File      : font_hz_bmp.c
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-09-15     Bernard      first version
+ */
 #include <rtgui/dc.h>
 #include <rtgui/font.h>
 

+ 23 - 0
components/gui/src/font_hz_file.c

@@ -1,3 +1,26 @@
+/*
+ * File      : font_hz_file.c
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-09-15     Bernard      first version
+ */
 /*
  * Cached HZ font engine
  */

+ 23 - 0
components/gui/src/hz12font.c

@@ -1,3 +1,26 @@
+/*
+ * File      : hz12font.c
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-09-15     Bernard      first version
+ */
 #include <rtgui/font.h>
 
 #if defined(RTGUI_USING_FONT12) && defined(RTGUI_USING_FONTHZ)

+ 23 - 0
components/gui/src/hz16font.c

@@ -1,3 +1,26 @@
+/*
+ * File      : hz16font.c
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-09-15     Bernard      first version
+ */
 #include <rtgui/font.h>
 
 #if defined(RTGUI_USING_FONT16) && defined(RTGUI_USING_FONTHZ)

+ 32 - 15
components/gui/src/image.c

@@ -1,11 +1,21 @@
 /*
  * File      : image.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -18,6 +28,7 @@
 
 #include <rtgui/image_hdc.h>
 #include <rtgui/rtgui_system.h>
+#include <rtgui/image_container.h>
 
 #include <string.h>
 #ifdef _WIN32
@@ -25,17 +36,18 @@
 #endif
 
 #ifdef RTGUI_IMAGE_XPM
-#include <rtgui/image_xpm.h>
+extern void rtgui_image_xpm_init(void);
 #endif
 
 #ifdef RTGUI_IMAGE_BMP
 #include <rtgui/image_bmp.h>
 #endif
+
 #if (defined(RTGUI_IMAGE_JPEG) || defined(RTGUI_IMAGE_TJPGD))
-#include <rtgui/image_jpeg.h>
+extern void rtgui_image_jpeg_init(void);
 #endif
 #if defined(RTGUI_IMAGE_PNG) || defined(RTGUI_IMAGE_LODEPNG)
-#include <rtgui/image_png.h>
+extern void rtgui_image_png_init(void);
 #endif
 
 static rtgui_list_t _rtgui_system_image_list = {RT_NULL};
@@ -61,6 +73,11 @@ void rtgui_system_image_init(void)
 #if defined(RTGUI_IMAGE_PNG) || defined(RTGUI_IMAGE_LODEPNG)
     rtgui_image_png_init();
 #endif
+
+#ifdef RTGUI_IMAGE_CONTAINER
+    /* initialize image container */
+    rtgui_system_image_container_init();
+#endif
 }
 
 static struct rtgui_image_engine *rtgui_image_get_engine(const char *type)
@@ -166,7 +183,7 @@ struct rtgui_image *rtgui_image_create(const char *filename, rt_bool_t load)
 
     /* create filerw context */
     filerw = rtgui_filerw_create_file(filename, "rb");
-    if (filerw == RT_NULL) 
+    if (filerw == RT_NULL)
     {
         rt_kprintf("create filerw failed!\n");
         return RT_NULL;
@@ -287,18 +304,18 @@ RTM_EXPORT(rtgui_image_register_engine);
 
 void rtgui_image_blit(struct rtgui_image *image, struct rtgui_dc *dc, struct rtgui_rect *rect)
 {
-	struct rtgui_rect r;
+    struct rtgui_rect r;
     RT_ASSERT(dc    != RT_NULL);
 
     if (rtgui_dc_get_visible(dc) != RT_TRUE) return;
 
     rtgui_dc_get_rect(dc, &r);
 
-	/* use rect of DC */
-	if (rect == RT_NULL)
-	{
-		rect = &r;
-	}
+    /* use rect of DC */
+    if (rect == RT_NULL)
+    {
+        rect = &r;
+    }
     else
     {
         /* Don't modify x1, y1, they are handled in engine->image_blit. */

+ 68 - 50
components/gui/src/image_bmp.c

@@ -1,4 +1,22 @@
 /*
+ * File      : image_bmp.c
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
  * Change Logs:
  * Date           Author       Notes
  * 2012-01-24     onelife      Reimplement to improve efficiency and add
@@ -6,7 +24,7 @@
  *  provides scaledown function.
  */
 #include <rtthread.h>
-#include <rtgui/dc_hw.h>
+#include <rtgui/dc.h>
 #include <rtgui/image.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/image_bmp.h>
@@ -127,7 +145,7 @@ static struct rtgui_image_palette *rtgui_image_bmp_load_palette(
         return RT_NULL;
     }
 
-	palette->ncolors = colorsUsed;
+    palette->ncolors = colorsUsed;
     if (alpha)
     {
         rt_uint8_t temp[4];
@@ -506,7 +524,7 @@ static void rtgui_image_bmp_blit(struct rtgui_image *image, struct rtgui_dc *dc,
 
     bytePerPixel = _UI_BITBYTES(bmp->bit_per_pixel);
 
-	imageWidth = image->w * bytePerPixel;       /* Scaled width in byte */
+    imageWidth = image->w * bytePerPixel;       /* Scaled width in byte */
     error = RT_FALSE;
 
     do
@@ -515,8 +533,8 @@ static void rtgui_image_bmp_blit(struct rtgui_image *image, struct rtgui_dc *dc,
         if (rtgui_dc_get_visible(dc) != RT_TRUE) break;
 
         /* the minimum rect */
-		w = _UI_MIN(image->w, rtgui_rect_width(*dst_rect));
-		h = _UI_MIN(image->h, rtgui_rect_height(*dst_rect));
+        w = _UI_MIN(image->w, rtgui_rect_width(*dst_rect));
+        h = _UI_MIN(image->h, rtgui_rect_height(*dst_rect));
 
         if (!bmp->is_loaded)
         {
@@ -744,53 +762,53 @@ static void rtgui_image_bmp_blit(struct rtgui_image *image, struct rtgui_dc *dc,
             rt_uint16_t x, y;
             rt_uint8_t *ptr;
 
-			if (bmp->bit_per_pixel <= 8)
-			{
-				rtgui_color_t color;
+            if (bmp->bit_per_pixel <= 8)
+            {
+                rtgui_color_t color;
 
-				/* 1bpp, and using palette */
-				for (y = 0; y < h; y ++)
-				{
+                /* 1bpp, and using palette */
+                for (y = 0; y < h; y ++)
+                {
                     ptr = bmp->pixels + (y * imageWidth);
-					for (x = 0; x < w; x ++)
-					{
-						color = image->palette->colors[*(ptr++)];
-						rtgui_dc_draw_color_point(dc,
-							dst_rect->x1 + x, dst_rect->y1 + y,
-							color);
-					}
-				}
-			}
-			else
-			{
-				rtgui_blit_line_func blit_line;
-				rt_uint8_t hw_bytePerPixel = _UI_BITBYTES(hw_driver->bits_per_pixel);
-				rt_uint8_t *line_data;
-
-				if (hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_BGR565)
-				{
-					blit_line = rtgui_blit_line_get_inv(hw_bytePerPixel, bytePerPixel);
-				}
-				else
-				{
-					blit_line = rtgui_blit_line_get(hw_bytePerPixel, bytePerPixel);
-				}
-
-				line_data = (rt_uint8_t *)rtgui_malloc(w * rtgui_color_get_bpp(hw_driver->pixel_format));
-				if (line_data == RT_NULL) break; /* out of memory */
-
-				ptr = bmp->pixels;
-				for (y = 0; y < h; y ++)
-				{
-					blit_line(line_data, ptr, bytePerPixel * w);
-					ptr += imageWidth;
-
-					dc->engine->blit_line(dc, dst_rect->x1, dst_rect->x1 + w,
-						dst_rect->y1 + y, line_data);
-				}
-
-				rtgui_free(line_data);
-			}
+                    for (x = 0; x < w; x ++)
+                    {
+                        color = image->palette->colors[*(ptr++)];
+                        rtgui_dc_draw_color_point(dc,
+                                                  dst_rect->x1 + x, dst_rect->y1 + y,
+                                                  color);
+                    }
+                }
+            }
+            else
+            {
+                rtgui_blit_line_func blit_line;
+                rt_uint8_t hw_bytePerPixel = _UI_BITBYTES(hw_driver->bits_per_pixel);
+                rt_uint8_t *line_data;
+
+                if (hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_BGR565)
+                {
+                    blit_line = rtgui_blit_line_get_inv(hw_bytePerPixel, bytePerPixel);
+                }
+                else
+                {
+                    blit_line = rtgui_blit_line_get(hw_bytePerPixel, bytePerPixel);
+                }
+
+                line_data = (rt_uint8_t *)rtgui_malloc(w * rtgui_color_get_bpp(hw_driver->pixel_format));
+                if (line_data == RT_NULL) break; /* out of memory */
+
+                ptr = bmp->pixels;
+                for (y = 0; y < h; y ++)
+                {
+                    blit_line(line_data, ptr, bytePerPixel * w);
+                    ptr += imageWidth;
+
+                    dc->engine->blit_line(dc, dst_rect->x1, dst_rect->x1 + w,
+                                          dst_rect->y1 + y, line_data);
+                }
+
+                rtgui_free(line_data);
+            }
         }
     } while (0);
 }

+ 440 - 0
components/gui/src/image_container.c

@@ -0,0 +1,440 @@
+/*
+ * File      : image_container.c
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-09-15     Bernard      first version
+ */
+#include <rtgui/rtgui_system.h>
+#include <rtgui/image_container.h>
+
+/*
+ * ImageContainer is a Image pool to manage image resource in the system.
+ *
+ * All of image in the ImageContainer should be loaded in the memory.
+ * All of image are identified by image file name.
+ *
+ * Applications can use rtgui_image_container_get/put to refer or derefer
+ * a image resource.
+ */
+
+#if defined(RTGUI_IMAGE_CONTAINER) && defined(RTGUI_USING_DFS_FILERW)
+typedef unsigned int (*rtgui_hash_func_t)(const void *key);
+typedef struct _rtgui_hash_table  rtgui_hash_table_t;
+typedef rt_bool_t (*rtgui_equal_func_t)(const void *a, const void *b);
+typedef void (*rtgui_user_func_t)(const void *value, const void *data);
+
+/*
+ *Hash tables
+ */
+rtgui_hash_table_t *hash_table_create(rtgui_hash_func_t hash_func, rtgui_equal_func_t key_equal_func);
+void hash_table_destroy(rtgui_hash_table_t *hash_table);
+
+void *hash_table_find(rtgui_hash_table_t *hash_table, const void *key);
+void hash_table_insert(rtgui_hash_table_t *hash_table, const void *key, void *value);
+rt_bool_t hash_table_remove(rtgui_hash_table_t *hash_table, const void *key);
+
+void hash_table_foreach(rtgui_hash_table_t *hash_table, rtgui_user_func_t user_func, void *data);
+unsigned int hash_table_get_size(rtgui_hash_table_t *hash_table);
+
+/* Hash Functions
+ */
+unsigned int direct_hash(const void *v);
+
+#define HASH_TABLE_MIN_SIZE 11
+#define HASH_TABLE_MAX_SIZE 6247
+
+typedef struct _gui_hash_node rtgui_hash_node_t;
+struct _gui_hash_node
+{
+    const void *key;
+    void *value;
+    rtgui_hash_node_t *next;
+};
+
+struct _rtgui_hash_table
+{
+    rt_uint16_t size;
+    rt_uint16_t nnodes;
+
+    rtgui_hash_node_t **nodes;
+    rtgui_hash_func_t hash_func;
+    rtgui_equal_func_t key_equal_func;
+};
+
+static const unsigned int primes[] =
+{
+    11,
+    19,
+    37,
+    73,
+    109,
+    163,
+    251,
+    367,
+    557,
+    823,
+    1237,
+    1861,
+    2777,
+    4177,
+    6247,
+};
+
+static const unsigned int nprimes = sizeof(primes) / sizeof(primes[0]);
+
+static void hash_table_resize(rtgui_hash_table_t *hash_table);
+static rtgui_hash_node_t **hash_table_find_node(rtgui_hash_table_t *hash_table, const void *key);
+static rtgui_hash_node_t *hash_node_create(const void *key, void *value);
+static void hash_node_destroy(rtgui_hash_node_t *hash_node);
+static void hash_nodes_destroy(rtgui_hash_node_t *hash_node);
+static unsigned int primes_closest(unsigned int num);
+static void hash_table_needresize(rtgui_hash_table_t *hash_table);
+
+rt_inline unsigned int primes_closest(unsigned int num)
+{
+    unsigned int i;
+
+    for (i = 0; i < nprimes; i++)
+        if (primes[i] > num)
+            return primes[i];
+
+    return primes[nprimes - 1];
+}
+
+/* directly hash */
+unsigned int direct_hash(const void *v)
+{
+    return (unsigned int)v;
+}
+
+rtgui_hash_table_t *hash_table_create(rtgui_hash_func_t hash_func, rtgui_equal_func_t key_equal_func)
+{
+    rtgui_hash_table_t *hash_table;
+
+    hash_table = (rtgui_hash_table_t *) rtgui_malloc(sizeof(rtgui_hash_table_t));
+    if (hash_table != RT_NULL)
+    {
+        hash_table->size               = HASH_TABLE_MIN_SIZE;
+        hash_table->nnodes             = 0;
+        hash_table->hash_func          = hash_func ? hash_func : direct_hash;
+        hash_table->key_equal_func     = key_equal_func;
+        hash_table->nodes              = (rtgui_hash_node_t **)rtgui_malloc(sizeof(rtgui_hash_node_t *) * hash_table->size);
+        if (hash_table->nodes == RT_NULL)
+        {
+            /* no memory yet */
+            rtgui_free(hash_table);
+            return RT_NULL;
+        }
+
+        rt_memset(hash_table->nodes, 0, sizeof(rtgui_hash_node_t *) * hash_table->size);
+    }
+
+    return hash_table;
+}
+
+void hash_table_destroy(rtgui_hash_table_t *hash_table)
+{
+    unsigned int i;
+
+    RT_ASSERT(hash_table != RT_NULL);
+
+    for (i = 0; i < hash_table->size; i++)
+        hash_nodes_destroy(hash_table->nodes[i]);
+
+    rtgui_free(hash_table->nodes);
+    rtgui_free(hash_table);
+}
+
+static rtgui_hash_node_t **hash_table_find_node(rtgui_hash_table_t *hash_table, const void *key)
+{
+    rtgui_hash_node_t **node;
+
+    node = &hash_table->nodes [(* hash_table->hash_func)(key) % hash_table->size];
+
+    if (hash_table->key_equal_func)
+        while (*node && !(*hash_table->key_equal_func)((*node)->key, key))
+            node = &(*node)->next;
+    else
+        while (*node && (*node)->key != key)
+            node = &(*node)->next;
+
+    return node;
+}
+
+void *hash_table_find(rtgui_hash_table_t *hash_table, const void *key)
+{
+    rtgui_hash_node_t *node;
+
+    RT_ASSERT(hash_table != RT_NULL);
+    RT_ASSERT(key != RT_NULL);
+
+    node = *hash_table_find_node(hash_table, key);
+
+    if (node) return node->value;
+    else return RT_NULL;
+}
+
+void hash_table_insert(rtgui_hash_table_t *hash_table, const void *key, void *value)
+{
+    rtgui_hash_node_t **node;
+
+    if (hash_table == RT_NULL)return;
+
+    node = hash_table_find_node(hash_table, key);
+    if (*node)
+    {
+        (*node)->value = value;
+    }
+    else
+    {
+        *node = hash_node_create(key, value);
+        hash_table->nnodes++;
+        hash_table_needresize(hash_table);
+    }
+}
+
+rt_bool_t hash_table_remove(rtgui_hash_table_t *hash_table, const void  *key)
+{
+    rtgui_hash_node_t **node, *dest;
+
+    if (hash_table == RT_NULL) return RT_FALSE;
+
+    node = hash_table_find_node(hash_table, key);
+    if (*node)
+    {
+        rt_enter_critical();
+        dest = *node;
+        (*node) = dest->next;
+        hash_node_destroy(dest);
+        hash_table->nnodes--;
+
+        hash_table_needresize(hash_table);
+        rt_exit_critical();
+
+        return RT_TRUE;
+    }
+
+    return RT_FALSE;
+}
+
+void hash_table_foreach(rtgui_hash_table_t *hash_table, rtgui_user_func_t user_func, void *data)
+{
+    rtgui_hash_node_t *node;
+    int i;
+
+    RT_ASSERT(hash_table != RT_NULL);
+    RT_ASSERT(user_func != RT_NULL);
+
+    for (i = 0; i < hash_table->size; i++)
+        for (node = hash_table->nodes[i]; node; node = node->next)
+            (* user_func)(node->value, data);
+}
+
+unsigned int hash_table_get_size(rtgui_hash_table_t *hash_table)
+{
+    if (hash_table == NULL) return 0;
+
+    return hash_table->nnodes;
+}
+
+static void hash_table_needresize(rtgui_hash_table_t *hash_table)
+{
+    if ((hash_table->size >= 3 * hash_table->nnodes && hash_table->size > HASH_TABLE_MIN_SIZE) ||
+            (3 * hash_table->size <= hash_table->nnodes && hash_table->size < HASH_TABLE_MAX_SIZE))
+        hash_table_resize(hash_table);
+}
+
+static void hash_table_resize(rtgui_hash_table_t *hash_table)
+{
+    rtgui_hash_node_t **new_nodes;
+    rtgui_hash_node_t *node;
+    rtgui_hash_node_t *next;
+    unsigned int hash_val;
+    int new_size;
+    int i;
+
+    i = primes_closest(hash_table->nnodes);
+    new_size = i > HASH_TABLE_MAX_SIZE ? HASH_TABLE_MAX_SIZE : i < HASH_TABLE_MIN_SIZE ? HASH_TABLE_MIN_SIZE : i ;
+
+    new_nodes = (rtgui_hash_node_t **)rtgui_malloc(sizeof(rtgui_hash_node_t *) * new_size);
+    if (new_nodes == RT_NULL) return; /* no memory yet */
+    rt_memset(new_nodes, 0, sizeof(rtgui_hash_node_t *) * new_size);
+
+    for (i = 0; i < hash_table->size; i++)
+    {
+        for (node = hash_table->nodes[i]; node; node = next)
+        {
+            next = node->next;
+
+            hash_val = (* hash_table->hash_func)(node->key) % new_size;
+
+            node->next = new_nodes[hash_val];
+            new_nodes[hash_val] = node;
+        }
+    }
+
+    rtgui_free(hash_table->nodes);
+    hash_table->nodes = new_nodes;
+    hash_table->size = new_size;
+}
+
+static rtgui_hash_node_t *hash_node_create(const void *key, void *value)
+{
+    rtgui_hash_node_t *hash_node;
+
+    hash_node = (rtgui_hash_node_t *) rtgui_malloc(sizeof(rtgui_hash_node_t));
+    if (hash_node != RT_NULL)
+    {
+        /* set value and key */
+        hash_node->key = key;
+        hash_node->value = value;;
+
+        hash_node->next = RT_NULL;
+    }
+
+    return hash_node;
+}
+
+static void hash_node_destroy(rtgui_hash_node_t *hash_node)
+{
+    rtgui_free(hash_node);
+}
+
+static void hash_nodes_destroy(rtgui_hash_node_t *hash_node)
+{
+    if (hash_node)
+    {
+        rtgui_hash_node_t *node = hash_node;
+        rtgui_hash_node_t *temp;
+
+        while (node->next)
+        {
+            node->key = NULL;
+            node->value = NULL;
+
+            temp = node;
+            node = node->next;
+            rtgui_free(temp);
+        }
+
+        node->key = NULL;
+        node->value = NULL;
+        rtgui_free(node);
+    }
+}
+
+unsigned int string_hash_func(const void *self)
+{
+    const char *p;
+    int h = 0, g;
+
+    for (p = self; *p != '\0'; p += 1)
+    {
+        h = (h << 4) + *p;
+        g = h;
+
+        if (g & 0xf0000000)
+        {
+            h = h ^ (g >> 24);
+            h = h ^ g;
+        }
+    }
+
+    return h ;
+}
+
+rt_bool_t string_equal_func(const void *a, const void *b)
+{
+    const char *str1, *str2;
+
+    str1 = (const char *)a;
+    str2 = (const char *)b;
+
+    if (strcmp(str1, str2) == 0) return RT_TRUE;
+    return RT_FALSE;
+}
+
+static rtgui_hash_table_t *image_hash_table;
+static struct rt_mutex _image_hash_lock;
+
+void rtgui_system_image_container_init(void)
+{
+    rt_mutex_init(&_image_hash_lock, "image", RT_IPC_FLAG_FIFO);
+
+    /* create image hash table */
+    image_hash_table = hash_table_create(string_hash_func, string_equal_func);
+    RT_ASSERT(image_hash_table != RT_NULL);
+}
+
+rtgui_image_item_t *rtgui_image_container_get(const char *filename)
+{
+    struct rtgui_image_item *item = RT_NULL;
+
+    if (rt_mutex_take(&_image_hash_lock, RT_WAITING_FOREVER) == RT_EOK)
+    {
+        item = hash_table_find(image_hash_table, filename);
+        if (item == RT_NULL)
+        {
+            item = (struct rtgui_image_item *) rtgui_malloc(sizeof(struct rtgui_image_item));
+            if (item == RT_NULL) return RT_NULL;
+
+            /* create a image object */
+            item->image = rtgui_image_create(filename, RT_TRUE);
+            if (item->image == RT_NULL)
+            {
+                rtgui_free(item);
+                return RT_NULL; /* create image failed */
+            }
+            item->refcount = 1;
+            item->filename = rt_strdup(filename);
+            hash_table_insert(image_hash_table, item->filename, item);
+        }
+        else
+        {
+            item->refcount ++; /* increase refcount */
+        }
+
+        rt_mutex_release(&_image_hash_lock);
+    }
+
+    return item;
+}
+RTM_EXPORT(rtgui_image_container_get);
+
+void rtgui_image_container_put(rtgui_image_item_t *item)
+{
+    rt_mutex_take(&_image_hash_lock, RT_WAITING_FOREVER);
+    item->refcount --;
+    if (item->refcount == 0)
+    {
+        /* remove item from container */
+        hash_table_remove(image_hash_table, item->filename);
+
+        /* destroy image and image item */
+        rt_free(item->filename);
+        rtgui_image_destroy(item->image);
+        rtgui_free(item);
+    }
+    rt_mutex_release(&_image_hash_lock);
+}
+RTM_EXPORT(rtgui_image_container_put);
+
+#endif
+

+ 33 - 120
components/gui/src/image_hdc.c

@@ -1,5 +1,28 @@
+/*
+ * File      : image_hdc.c
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-09-15     Bernard      first version
+ */
 #include <rtthread.h>
-#include <rtgui/dc_hw.h>
+#include <rtgui/dc.h>
 #include <rtgui/image.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/image_hdc.h>
@@ -9,21 +32,6 @@
 
 extern int fastlz_decompress(const void *input, int length, void *output, int maxout);
 
-struct rtgui_image_hdc
-{
-    rt_bool_t is_loaded;
-
-    /* hdc image information */
-    rt_uint16_t byte_per_pixel;
-    rt_uint16_t pitch;
-    rt_uint8_t  pixel_format;
-
-    rt_size_t   pixel_offset;
-    rt_uint8_t *pixels;
-
-    struct rtgui_filerw *filerw;
-};
-
 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);
 static void rtgui_image_hdc_unload(struct rtgui_image *image);
@@ -257,112 +265,17 @@ static void rtgui_image_hdc_blit(struct rtgui_image *image,
 
     if (hdc->pixels != RT_NULL)
     {
-        rt_uint8_t *ptr;
-
-        /* get pixel pointer */
-        ptr = hdc->pixels + hdc->pitch * yoff + hdc->byte_per_pixel * xoff;
-
-        if (hdc->pixel_format == rtgui_dc_get_pixel_format(dc) &&
-                hdc->pixel_format != RTGRAPHIC_PIXEL_FORMAT_ARGB888)
-        {
-            for (y = 0; y < h; y ++)
-            {
-                dc->engine->blit_line(dc,
-                                      dst_rect->x1,
-                                      dst_rect->x1 + w,
-                                      dst_rect->y1 + y,
-                                      ptr);
-                ptr += hdc->pitch;
-            }
-        }
-        else if (dc->type == RTGUI_DC_CLIENT)
-        {
-            const struct rtgui_graphic_driver *hw_driver;
-            struct rtgui_widget *owner = RTGUI_CONTAINER_OF(dc, struct rtgui_widget, dc_type);
+        struct rtgui_image_info info;
+        struct rtgui_rect dest = *dst_rect;
+        info.a = 255;
+        info.pixels = hdc->pixels + hdc->pitch * yoff + hdc->byte_per_pixel * xoff;
+        info.src_fmt = hdc->pixel_format;
+        info.src_pitch = hdc->pitch;
 
-            hw_driver = rtgui_graphic_driver_get_default();
-            if (hdc->pixel_format == RTGRAPHIC_PIXEL_FORMAT_ARGB888)
-            {
-                rt_uint8_t alpha;
-
-                for (y = 0; y < h; y ++)
-                {
-                    int x;
-
-                    rtgui_color_t *pixel = (rtgui_color_t *)(hdc->pixels + hdc->pitch * (yoff + y) + hdc->byte_per_pixel * xoff);
-
-                    for (x = 0; x < w; x ++)
-                    {
-                        alpha = RTGUI_RGB_A(*pixel);
-
-                        if (alpha == 0) { }
-                        if (alpha == 0xff)
-                        {
-                            rtgui_dc_draw_color_point(dc, dst_rect->x1 + x, dst_rect->y1 + y, *pixel);
-                        }
-                        else
-                        {
-                            /* draw an alpha blending point */
-                            if (hw_driver->framebuffer != RT_NULL)
-                                rtgui_dc_blend_point(dc, dst_rect->x1 + x, dst_rect->y1 + y, RTGUI_BLENDMODE_BLEND,
-                                                     RTGUI_RGB_R(*pixel), RTGUI_RGB_G(*pixel), RTGUI_RGB_B(*pixel), RTGUI_RGB_A(*pixel));
-                        }
-
-                        pixel ++;
-                    }
-                }
-            }
-        }
-        else
-        {
-            struct rtgui_blit_info info;
-            info.a = 0;
-
-            /* initialize source blit information */
-            info.src = ptr;
-            info.src_h = h;
-            info.src_w = w;
-            info.src_fmt = hdc->pixel_format;
-            info.src_pitch = hdc->pitch;
-            info.src_skip = hdc->pitch - w * rtgui_color_get_bpp(hdc->pixel_format);
-
-            /* initialize destination blit information */
-            if (dc->type == RTGUI_DC_BUFFER)
-            {
-                struct rtgui_dc_buffer *buffer;
-                buffer = (struct rtgui_dc_buffer *)dc;
-
-                info.dst = rtgui_dc_buffer_get_pixel(RTGUI_DC(buffer)) + dst_rect->y1 * buffer->pitch +
-                           dst_rect->x1 * rtgui_color_get_bpp(buffer->pixel_format);
-                info.dst_h = h;
-                info.dst_w = w;
-                info.dst_fmt = buffer->pixel_format;
-                info.dst_pitch = buffer->pitch;
-                info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(buffer->pixel_format);
-            }
-            else if (dc->type == RTGUI_DC_HW)
-            {
-                struct rtgui_widget *owner;
-                struct rtgui_rect r;
-                struct rtgui_dc_hw *ddc = (struct rtgui_dc_hw *)dc;
-
-                owner = ((struct rtgui_dc_hw *)dc)->owner;
-
-                rtgui_graphic_driver_get_rect(RT_NULL, &r);
-
-                /* blit destination */
-                info.dst = (rt_uint8_t *)ddc->hw_driver->framebuffer;
-                info.dst = info.dst + (owner->extent.y1 + dst_rect->y1) * ddc->hw_driver->pitch +
-                           (owner->extent.x1 + dst_rect->x1) * rtgui_color_get_bpp(ddc->hw_driver->pixel_format);
-                info.dst_fmt = ddc->hw_driver->pixel_format;
-                info.dst_h = h;
-                info.dst_w = w;
-                info.dst_pitch = ddc->hw_driver->pitch;
-                info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(ddc->hw_driver->pixel_format);
-            }
+        dest.x2 = dst_rect->x1 + w;
+        dest.y2 = dst_rect->y1 + h;
 
-            rtgui_blit(&info);
-        }
+        rtgui_image_info_blit(&info, dc, &dest);
     }
     else
     {

+ 103 - 85
components/gui/src/image_jpg.c

@@ -1,6 +1,25 @@
 /*
+ * File      : image_jpg.c
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
  * Change Logs:
  * Date           Author       Notes
+ * 2010-09-15     Bernard      first version
  * 2012-01-24     onelife      add TJpgDec (Tiny JPEG Decompressor) support
  */
 #include <rtthread.h>
@@ -13,7 +32,6 @@
 
 #include <rtgui/rtgui_system.h>
 #include <rtgui/filerw.h>
-#include <rtgui/image_jpeg.h>
 #include <rtgui/blit.h>
 
 #ifdef RTGUI_USING_DFS_FILERW
@@ -403,61 +421,61 @@ static void rtgui_image_jpeg_blit(struct rtgui_image *image, struct rtgui_dc *dc
     {
         ptr = (rtgui_color_t *) jpeg->pixels;
 
-		if (dc->type == RTGUI_DC_BUFFER)
-		{
-			/* blit ARGB888 to this buffered DC */
-			int dst_x, dst_y;
-			int w, h;
-			struct rtgui_blit_info info;
-			struct rtgui_dc_buffer *buffer = (struct rtgui_dc_buffer*)dc;
-
-			w = _UI_MIN(image->w, rtgui_rect_width(*rect));
-			h = _UI_MIN(image->h, rtgui_rect_height(*rect));
-
-			info.a = 0;
-
-			/* initialize source blit information */
-			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);
-			info.src_skip = info.src_pitch - w * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888);
-			info.src = (rt_uint8_t *)image->data + y * info.src_pitch + x * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888);
-
-			if (rect->x1 < 0) dst_x = 0;
-			else dst_x = rect->x1;
-			if (rect->y1 < 0) dst_y = 0;
-			else dst_y = rect->y1;
-
-			/* initialize destination blit information */
-			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;
-			info.dst_w = w;
-			info.dst_fmt = buffer->pixel_format;
-			info.dst_pitch = buffer->pitch;
-			info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(buffer->pixel_format);
-
-			rtgui_blit(&info);
-		}
-		else
-		{
-	        /* draw each point within dc */
-	        for (y = 0; y < image->h; y ++)
-	        {
-	            for (x = 0; x < image->w; x++)
-	            {
-	                /* not alpha */
-	                if ((*ptr >> 24) != 255)
-	                {
-	                    rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, *ptr);
-	                }
-
-	                /* move to next color buffer */
-	                ptr ++;
-	            }
-	        }
-		}
+        if (dc->type == RTGUI_DC_BUFFER)
+        {
+            /* blit ARGB888 to this buffered DC */
+            int dst_x, dst_y;
+            int w, h;
+            struct rtgui_blit_info info;
+            struct rtgui_dc_buffer *buffer = (struct rtgui_dc_buffer*)dc;
+
+            w = _UI_MIN(image->w, rtgui_rect_width(*rect));
+            h = _UI_MIN(image->h, rtgui_rect_height(*rect));
+
+            info.a = 0;
+
+            /* initialize source blit information */
+            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);
+            info.src_skip = info.src_pitch - w * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888);
+            info.src = (rt_uint8_t *)image->data + y * info.src_pitch + x * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888);
+
+            if (rect->x1 < 0) dst_x = 0;
+            else dst_x = rect->x1;
+            if (rect->y1 < 0) dst_y = 0;
+            else dst_y = rect->y1;
+
+            /* initialize destination blit information */
+            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;
+            info.dst_w = w;
+            info.dst_fmt = buffer->pixel_format;
+            info.dst_pitch = buffer->pitch;
+            info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(buffer->pixel_format);
+
+            rtgui_blit(&info);
+        }
+        else
+        {
+            /* draw each point within dc */
+            for (y = 0; y < image->h; y ++)
+            {
+                for (x = 0; x < image->w; x++)
+                {
+                    /* not alpha */
+                    if ((*ptr >> 24) != 255)
+                    {
+                        rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, *ptr);
+                    }
+
+                    /* move to next color buffer */
+                    ptr ++;
+                }
+            }
+        }
     }
     else
     {
@@ -606,9 +624,9 @@ struct rtgui_image_jpeg
     rt_uint16_t dst_x, dst_y;
     rt_uint16_t dst_w, dst_h;
     rt_bool_t is_loaded;
-	rt_uint8_t byte_per_pixel;
+    rt_uint8_t byte_per_pixel;
 
-	JDEC tjpgd;                     /* jpeg structure */
+    JDEC tjpgd;                     /* jpeg structure */
     void *pool;
     rt_uint8_t *pixels;
 };
@@ -699,9 +717,9 @@ static UINT tjpgd_out_func(JDEC *jdec, void *bitmap, JRECT *rect)
         if (rect->left > jpeg->dst_w) return 1;
         if (rect->top  > jpeg->dst_h) return 0;
 
-		w = _UI_MIN(rect->right, jpeg->dst_w);
+        w = _UI_MIN(rect->right, jpeg->dst_w);
         w = w - rect->left + 1;
-		h = _UI_MIN(rect->bottom, jpeg->dst_h);
+        h = _UI_MIN(rect->bottom, jpeg->dst_h);
         h = h - rect->top + 1;
 
         for (y = 0; y < h; y++)
@@ -718,15 +736,15 @@ static UINT tjpgd_out_func(JDEC *jdec, void *bitmap, JRECT *rect)
 
 static rt_bool_t rtgui_image_jpeg_check(struct rtgui_filerw *file)
 {
-	rt_uint8_t soi[2];
-	rtgui_filerw_seek(file, 0, RTGUI_FILE_SEEK_SET);
-	rtgui_filerw_read(file, &soi, 2, 1);
-	rtgui_filerw_seek(file, 0, RTGUI_FILE_SEEK_SET);
+    rt_uint8_t soi[2];
+    rtgui_filerw_seek(file, 0, RTGUI_FILE_SEEK_SET);
+    rtgui_filerw_read(file, &soi, 2, 1);
+    rtgui_filerw_seek(file, 0, RTGUI_FILE_SEEK_SET);
 
-	/* check SOI==FFD8 */
-	if (soi[0] == 0xff && soi[1] == 0xd8) return RT_TRUE;
+    /* check SOI==FFD8 */
+    if (soi[0] == 0xff && soi[1] == 0xd8) return RT_TRUE;
 
-	return RT_FALSE;
+    return RT_FALSE;
 }
 
 static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image *image, struct rtgui_filerw *file, rt_bool_t load)
@@ -734,7 +752,7 @@ static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image *image, struct rtgui_f
     rt_bool_t res = RT_FALSE;
     struct rtgui_image_jpeg *jpeg;
     JRESULT ret;
-	struct rtgui_graphic_driver *hw_driver;
+    struct rtgui_graphic_driver *hw_driver;
 
     do
     {
@@ -745,7 +763,7 @@ static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image *image, struct rtgui_f
         jpeg->is_loaded = load;
         jpeg->pixels = RT_NULL;
 
-		/* allocate memory pool */
+        /* allocate memory pool */
         jpeg->pool = rt_malloc(TJPGD_WORKING_BUFFER_SIZE);
         if (jpeg->pool == RT_NULL)
         {
@@ -769,15 +787,15 @@ static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image *image, struct rtgui_f
             break;
         }
 
-		/* use RGB565 format */
-		hw_driver = rtgui_graphic_driver_get_default();
-		if (hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)
-		{
-			jpeg->tjpgd.format = 1;
-			jpeg->byte_per_pixel = 2;
-		}
-		/* else use RGB888 format */
-		else jpeg->byte_per_pixel = 3;
+        /* use RGB565 format */
+        hw_driver = rtgui_graphic_driver_get_default();
+        if (hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)
+        {
+            jpeg->tjpgd.format = 1;
+            jpeg->byte_per_pixel = 2;
+        }
+        /* else use RGB888 format */
+        else jpeg->byte_per_pixel = 3;
 
         image->w = (rt_uint16_t)jpeg->tjpgd.width;
         image->h = (rt_uint16_t)jpeg->tjpgd.height;
@@ -800,7 +818,7 @@ static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image *image, struct rtgui_f
             if (ret != JDR_OK) break;
 
             rtgui_filerw_close(jpeg->filerw);
-			jpeg->filerw = RT_NULL;
+            jpeg->filerw = RT_NULL;
         }
         res = RT_TRUE;
     } while (0);
@@ -808,7 +826,7 @@ static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image *image, struct rtgui_f
     if (jpeg && (!res || jpeg->is_loaded))
     {
         rt_free(jpeg->pool);
-		jpeg->pool = RT_NULL;
+        jpeg->pool = RT_NULL;
     }
 
     if (!res)
@@ -817,8 +835,8 @@ static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image *image, struct rtgui_f
             rtgui_free(jpeg->pixels);
         rt_free(jpeg);
 
-		image->data   = RT_NULL;
-		image->engine = RT_NULL;
+        image->data   = RT_NULL;
+        image->engine = RT_NULL;
     }
 
     /* create jpeg image successful */
@@ -882,7 +900,7 @@ static void rtgui_image_jpeg_blit(struct rtgui_image *image,
     h = _UI_MIN(image->h - yoff, rtgui_rect_height(*dst_rect));
 
     if (rtgui_dc_get_pixel_format(dc) == RTGRAPHIC_PIXEL_FORMAT_RGB888 &&
-        jpeg->tjpgd.format != 0)
+            jpeg->tjpgd.format != 0)
     {
         jpeg->tjpgd.format = 0;
         jpeg->byte_per_pixel = 3;
@@ -910,7 +928,7 @@ static void rtgui_image_jpeg_blit(struct rtgui_image *image,
     else
     {
         if ((rtgui_dc_get_pixel_format(dc) == RTGRAPHIC_PIXEL_FORMAT_RGB888 && jpeg->tjpgd.format == 0) ||
-            (rtgui_dc_get_pixel_format(dc) == RTGRAPHIC_PIXEL_FORMAT_RGB565 && jpeg->tjpgd.format == 1))
+                (rtgui_dc_get_pixel_format(dc) == RTGRAPHIC_PIXEL_FORMAT_RGB565 && jpeg->tjpgd.format == 1))
         {
             rt_uint16_t imageWidth = image->w * jpeg->byte_per_pixel;
             rt_uint8_t *src = jpeg->pixels + yoff * imageWidth + xoff + jpeg->byte_per_pixel;
@@ -940,7 +958,7 @@ static void rtgui_image_jpeg_blit(struct rtgui_image *image,
             info.src_skip = info.src_pitch - info.src_w * jpeg->byte_per_pixel;
 
             info.dst = rtgui_dc_buffer_get_pixel(RTGUI_DC(buffer)) + dst_rect->y1 * buffer->pitch +
-                dst_rect->x1 * rtgui_color_get_bpp(buffer->pixel_format);
+                       dst_rect->x1 * rtgui_color_get_bpp(buffer->pixel_format);
             info.dst_h = rtgui_rect_height(*dst_rect);
             info.dst_w = rtgui_rect_width(*dst_rect);
             info.dst_fmt = buffer->pixel_format;

+ 223 - 190
components/gui/src/image_png.c

@@ -1,11 +1,34 @@
-#include <rtthread.h>
+/*
+ * File      : image_png.c
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-09-15     Bernard      first version
+ */
+
+ #include <rtthread.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/blit.h>
 #include <rtgui/driver.h>
 
 #ifdef RTGUI_IMAGE_PNG
 #include "png.h"
-#include <rtgui/image_png.h>
 
 #define PNG_MAGIC_LEN       8
 
@@ -139,7 +162,7 @@ static rt_bool_t rtgui_image_png_check(struct rtgui_filerw *file)
 
 static void _image_png_error_fn(png_structp png_ptr, png_const_charp error_message)
 {
-	rt_kprintf(error_message);
+    rt_kprintf(error_message);
 }
 
 static rt_bool_t rtgui_image_png_load(struct rtgui_image *image, struct rtgui_filerw *file, rt_bool_t load)
@@ -158,8 +181,8 @@ static rt_bool_t rtgui_image_png_load(struct rtgui_image *image, struct rtgui_fi
         rtgui_free(png);
         return RT_FALSE;
     }
-	png_set_error_fn(png->png_ptr, RT_NULL, _image_png_error_fn, _image_png_error_fn);
-	
+    png_set_error_fn(png->png_ptr, RT_NULL, _image_png_error_fn, _image_png_error_fn);
+
     png->info_ptr = png_create_info_struct(png->png_ptr);
     if (png->info_ptr == RT_NULL)
     {
@@ -169,7 +192,7 @@ static rt_bool_t rtgui_image_png_load(struct rtgui_image *image, struct rtgui_fi
     }
 
     png->filerw = file;
-	png->is_loaded = RT_FALSE;
+    png->is_loaded = RT_FALSE;
     png_set_read_fn(png->png_ptr, png->filerw, rtgui_image_png_read_data);
 
     png_read_info(png->png_ptr, png->info_ptr);
@@ -220,11 +243,11 @@ static rt_bool_t rtgui_image_png_load(struct rtgui_image *image, struct rtgui_fi
         }
 
         rtgui_image_png_process(png->png_ptr, png->info_ptr, png);
-		png_read_end(png->png_ptr, RT_NULL);
-		png->is_loaded = RT_TRUE;
-		/* close file handler */
-		rtgui_filerw_close(png->filerw);
-		png->filerw = RT_NULL;
+        png_read_end(png->png_ptr, RT_NULL);
+        png->is_loaded = RT_TRUE;
+        /* close file handler */
+        rtgui_filerw_close(png->filerw);
+        png->filerw = RT_NULL;
     }
     else
     {
@@ -271,8 +294,8 @@ static void rtgui_image_png_blit(struct rtgui_image *image, struct rtgui_dc *dc,
 
     png = (struct rtgui_image_png *) image->data;
 
-	w = _UI_MIN(image->w, rtgui_rect_width(*rect));
-	h = _UI_MIN(image->h, rtgui_rect_height(*rect));
+    w = _UI_MIN(image->w, rtgui_rect_width(*rect));
+    h = _UI_MIN(image->h, rtgui_rect_height(*rect));
 
     fg_maxsample = (1 << png->info_ptr->bit_depth) - 1;
 
@@ -340,19 +363,19 @@ static void rtgui_image_png_blit(struct rtgui_image *image, struct rtgui_dc *dc,
 
         switch (png->info_ptr->color_type)
         {
-		case PNG_COLOR_TYPE_RGB:
-			for (y = 0; y < h; y++)
-			{
-				png_read_row(png->png_ptr, row, png_bytep_NULL);
-				for (x = 0; x < w; x++)
-				{
-					data = &(row[x * 3]);
-					rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1,
-											  RTGUI_RGB(data[0], data[1], data[2]));
-				}
-			}
-			break;
-			
+        case PNG_COLOR_TYPE_RGB:
+            for (y = 0; y < h; y++)
+            {
+                png_read_row(png->png_ptr, row, png_bytep_NULL);
+                for (x = 0; x < w; x++)
+                {
+                    data = &(row[x * 3]);
+                    rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1,
+                                              RTGUI_RGB(data[0], data[1], data[2]));
+                }
+            }
+            break;
+
         case PNG_COLOR_TYPE_RGBA:
             for (y = 0; y < h; y++)
             {
@@ -452,7 +475,7 @@ static rt_bool_t rtgui_image_png_load(struct rtgui_image *image, struct rtgui_fi
     unsigned int width;
     unsigned int height;
     unsigned int error;
-	
+
     rt_uint8_t* pixel;
     rt_uint8_t* in;
     rt_uint32_t in_size;
@@ -468,13 +491,13 @@ static rt_bool_t rtgui_image_png_load(struct rtgui_image *image, struct rtgui_fi
     rtgui_filerw_seek(file, 0, SEEK_SET);
     rtgui_filerw_read(file, in, in_size, 1);
 
-    error = lodepng_decode32(&pixel, &width, &height, in, in_size);    
-    if(error) 
-	{
-		rt_kprintf("error %u: %s\n", error, lodepng_error_text(error));
-		rtgui_free(in);
-		return RT_FALSE;
-	}
+    error = lodepng_decode32(&pixel, &width, &height, in, in_size);
+    if(error)
+    {
+        rt_kprintf("error %u: %s\n", error, lodepng_error_text(error));
+        rtgui_free(in);
+        return RT_FALSE;
+    }
 
     rtgui_free(in);
 
@@ -484,24 +507,24 @@ static rt_bool_t rtgui_image_png_load(struct rtgui_image *image, struct rtgui_fi
     image->engine = &rtgui_image_png_engine;
     image->data = pixel;
 
-	/* NOTE: the pixel format of PNG is ABGR888, bit0 R,G,B,A bit31 */
-	/* convert pixel to ARGB888, swap B/G */
-	{
-		rt_uint8_t* pixel_ptr;
-		rt_uint8_t* pixel_end;
+    /* NOTE: the pixel format of PNG is ABGR888, bit0 R,G,B,A bit31 */
+    /* convert pixel to ARGB888, swap B/G */
+    {
+        rt_uint8_t* pixel_ptr;
+        rt_uint8_t* pixel_end;
 
-		pixel_ptr = (rt_uint8_t*) pixel;
-		pixel_end = pixel_ptr + width * height * 4;
+        pixel_ptr = (rt_uint8_t*) pixel;
+        pixel_end = pixel_ptr + width * height * 4;
 
-		while (pixel_ptr < pixel_end)
-		{
-			pixel_ptr[0] = pixel_ptr[0] ^ pixel_ptr[2];
-			pixel_ptr[2] = pixel_ptr[0] ^ pixel_ptr[2];
-			pixel_ptr[0] = pixel_ptr[0] ^ pixel_ptr[2];
+        while (pixel_ptr < pixel_end)
+        {
+            pixel_ptr[0] = pixel_ptr[0] ^ pixel_ptr[2];
+            pixel_ptr[2] = pixel_ptr[0] ^ pixel_ptr[2];
+            pixel_ptr[0] = pixel_ptr[0] ^ pixel_ptr[2];
 
-			pixel_ptr += 4;
-		}
-	}
+            pixel_ptr += 4;
+        }
+    }
 
     /* close file handler */
     rtgui_filerw_close(file);
@@ -518,159 +541,169 @@ static void rtgui_image_png_unload(struct rtgui_image *image)
         pixels = (rt_uint8_t*) image->data;
 
         /* release data */
-        rtgui_free(pixels);
+        //rtgui_free(pixels);
+        free(pixels);
     }
 }
 
 static void rtgui_image_png_blit(struct rtgui_image *image, struct rtgui_dc *dc, struct rtgui_rect *rect)
 {
-	int x, y;
+    int x, y;
     int w, h;
-	struct rtgui_blit_info info;
-	struct rtgui_graphic_driver *hw_driver = rtgui_graphic_driver_get_default();
+    struct rtgui_blit_info info;
+    struct rtgui_graphic_driver *hw_driver = rtgui_graphic_driver_get_default();
 
     RT_ASSERT(image != RT_NULL && dc != RT_NULL && rect != RT_NULL);
     RT_ASSERT(image->data != RT_NULL);
 
 #define blending(s, d, a) (((unsigned)(((s) - (d)) * (a)) >> 8) + (d))
 
-	/* this dc is not visible */
-	if (rtgui_dc_get_visible(dc) != RT_TRUE) return;
-
-	w = _UI_MIN(image->w, rtgui_rect_width(*rect));
-	h = _UI_MIN(image->h, rtgui_rect_height(*rect));
-
-	/* border checking */
-	if (rect->x1 < 0) { x = -rect->x1; w += rect->x1; }
-	else x = 0;
-
-	if (rect->y1 < 0) { y = -rect->y1; h += rect->y1; }
-	else y = 0;
-
-	if (w < 0 || h < 0) return; /* no drawing */
-
-	if ((dc->type == RTGUI_DC_CLIENT) || (dc->type == RTGUI_DC_HW && hw_driver->framebuffer == RT_NULL))
-	{
-		int dx, dy, start_x;
-		rtgui_rect_t r;
-		rtgui_color_t *pixel;
-		rt_uint8_t alpha;
-		rtgui_widget_t *owner = RT_NULL;
-
-		if (dc->type == RTGUI_DC_CLIENT)
-		{
-			/* get owner and calculate dx,dy */
-			owner = RTGUI_CONTAINER_OF(dc, struct rtgui_widget, dc_type);
-			dx = owner->extent.x1; dy = owner->extent.y1;
-		}
-		else
-		{
-			/* hardware DC */
-			struct rtgui_dc_hw *hw = (struct rtgui_dc_hw *) dc;
-			dx = hw->owner->extent.x1;
-			dy = hw->owner->extent.y1;
-		}
-
-		start_x = x;
-		for (; y < rect->y1 + h; ++y)
-		{
-			for (x = start_x; x < rect->x1 + w; ++x)
-			{
-				pixel = (rtgui_color_t*)((rt_uint8_t*)image->data + (y - rect->y1) * image->w * 4 + 
-					(x - rect->x1) * 4);
-
-				alpha = RTGUI_RGB_A(*pixel);
-				if (alpha == 0) continue;
-				if (alpha == 0xff)
-				{
-					rtgui_dc_draw_color_point(dc, x, y, *pixel);
-				}
-				else 
-				{
-					rtgui_color_t bc, fc;
-
-					/* draw an alpha blending point */
-					if (hw_driver->framebuffer != RT_NULL)
-						rtgui_dc_blend_point(dc, x, y, RTGUI_BLENDMODE_BLEND,
-							RTGUI_RGB_R(*pixel), RTGUI_RGB_G(*pixel), RTGUI_RGB_B(*pixel), RTGUI_RGB_A(*pixel));
-					else
-					{
-						x = x + dx;
-						y = y + dy;
-
-						if (dc->type == RTGUI_DC_CLIENT)
-						{
-							if (rtgui_region_contains_point(&(owner->clip), x, y, &r) != RT_EOK)
-								continue ;
-						}
-
-						/* get background pixel */
-						hw_driver->ops->get_pixel(&bc, x, y);
-						/* alpha blending */
-						fc = RTGUI_RGB(blending(RTGUI_RGB_R(bc), RTGUI_RGB_R(*pixel),  alpha), 
-								blending(RTGUI_RGB_G(bc), RTGUI_RGB_G(*pixel),  alpha), 
-								blending(RTGUI_RGB_B(bc), RTGUI_RGB_B(*pixel),  alpha));
-						hw_driver->ops->set_pixel(&fc, x, y);
-					}
-				}
-			}
-		}
-	}
-	else
-	{
-		int dst_x, dst_y;
-		
-		info.a = 0;
-
-		/* initialize source blit information */
-		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);
-		info.src_skip = info.src_pitch - w * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888);
-		info.src = (rt_uint8_t *)image->data + y * info.src_pitch + x * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888);
-
-		if (rect->x1 < 0) dst_x = 0;
-		else dst_x = rect->x1;
-		if (rect->y1 < 0) dst_y = 0;
-		else dst_y = rect->y1;
-		
-		/* initialize destination blit information */
-		if (dc->type == RTGUI_DC_BUFFER)
-		{
-			struct rtgui_dc_buffer *buffer;
-			buffer = (struct rtgui_dc_buffer*)dc;
-
-			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;
-			info.dst_w = w;
-			info.dst_fmt = buffer->pixel_format;
-			info.dst_pitch = buffer->pitch;
-			info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(buffer->pixel_format);
-		}
-		else if (dc->type == RTGUI_DC_HW)
-		{
-			struct rtgui_widget *owner;
-			struct rtgui_rect r;
-
-			owner = ((struct rtgui_dc_hw*)dc)->owner;
-
-			rtgui_graphic_driver_get_rect(RT_NULL, &r);
-			
-			/* blit destination */
-			info.dst = (rt_uint8_t*)hw_driver->framebuffer;
-			info.dst = info.dst + (owner->extent.y1 + dst_y) * hw_driver->pitch +
-				(owner->extent.x1 + dst_x) * rtgui_color_get_bpp(hw_driver->pixel_format);
-			info.dst_fmt = hw_driver->pixel_format;
-			info.dst_h = h;
-			info.dst_w = w;
-			info.dst_pitch = hw_driver->pitch;
-			info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(hw_driver->pixel_format);			
-		}
-
-		rtgui_blit(&info);
-	}
+    /* this dc is not visible */
+    if (rtgui_dc_get_visible(dc) != RT_TRUE) return;
+
+    w = _UI_MIN(image->w, rtgui_rect_width(*rect));
+    h = _UI_MIN(image->h, rtgui_rect_height(*rect));
+
+    /* border checking */
+    if (rect->x1 < 0)
+    {
+        x = -rect->x1;
+        w += rect->x1;
+    }
+    else x = 0;
+
+    if (rect->y1 < 0)
+    {
+        y = -rect->y1;
+        h += rect->y1;
+    }
+    else y = 0;
+
+    if (w < 0 || h < 0) return; /* no drawing */
+
+    if ((dc->type == RTGUI_DC_CLIENT) || (dc->type == RTGUI_DC_HW && hw_driver->framebuffer == RT_NULL))
+    {
+        int dx, dy, start_x;
+        rtgui_rect_t r;
+        rtgui_color_t *pixel;
+        rt_uint8_t alpha;
+        rtgui_widget_t *owner = RT_NULL;
+
+        if (dc->type == RTGUI_DC_CLIENT)
+        {
+            /* get owner and calculate dx,dy */
+            owner = RTGUI_CONTAINER_OF(dc, struct rtgui_widget, dc_type);
+            dx = owner->extent.x1;
+            dy = owner->extent.y1;
+        }
+        else
+        {
+            /* hardware DC */
+            struct rtgui_dc_hw *hw = (struct rtgui_dc_hw *) dc;
+            dx = hw->owner->extent.x1;
+            dy = hw->owner->extent.y1;
+        }
+
+        start_x = x;
+        for (; y < rect->y1 + h; ++y)
+        {
+            for (x = start_x; x < rect->x1 + w; ++x)
+            {
+                pixel = (rtgui_color_t*)((rt_uint8_t*)image->data + (y - rect->y1) * image->w * 4 +
+                                         (x - rect->x1) * 4);
+
+                alpha = RTGUI_RGB_A(*pixel);
+                if (alpha == 0) continue;
+                if (alpha == 0xff)
+                {
+                    rtgui_dc_draw_color_point(dc, x, y, *pixel);
+                }
+                else
+                {
+                    rtgui_color_t bc, fc;
+
+                    /* draw an alpha blending point */
+                    if (hw_driver->framebuffer != RT_NULL)
+                        rtgui_dc_blend_point(dc, x, y, RTGUI_BLENDMODE_BLEND,
+                                             RTGUI_RGB_R(*pixel), RTGUI_RGB_G(*pixel), RTGUI_RGB_B(*pixel), RTGUI_RGB_A(*pixel));
+                    else
+                    {
+                        x = x + dx;
+                        y = y + dy;
+
+                        if (dc->type == RTGUI_DC_CLIENT)
+                        {
+                            if (rtgui_region_contains_point(&(owner->clip), x, y, &r) != RT_EOK)
+                                continue ;
+                        }
+
+                        /* get background pixel */
+                        hw_driver->ops->get_pixel(&bc, x, y);
+                        /* alpha blending */
+                        fc = RTGUI_RGB(blending(RTGUI_RGB_R(bc), RTGUI_RGB_R(*pixel),  alpha),
+                                       blending(RTGUI_RGB_G(bc), RTGUI_RGB_G(*pixel),  alpha),
+                                       blending(RTGUI_RGB_B(bc), RTGUI_RGB_B(*pixel),  alpha));
+                        hw_driver->ops->set_pixel(&fc, x, y);
+                    }
+                }
+            }
+        }
+    }
+    else
+    {
+        int dst_x, dst_y;
+
+        info.a = 0;
+
+        /* initialize source blit information */
+        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);
+        info.src_skip = info.src_pitch - w * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888);
+        info.src = (rt_uint8_t *)image->data + y * info.src_pitch + x * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888);
+
+        if (rect->x1 < 0) dst_x = 0;
+        else dst_x = rect->x1;
+        if (rect->y1 < 0) dst_y = 0;
+        else dst_y = rect->y1;
+
+        /* initialize destination blit information */
+        if (dc->type == RTGUI_DC_BUFFER)
+        {
+            struct rtgui_dc_buffer *buffer;
+            buffer = (struct rtgui_dc_buffer*)dc;
+
+            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;
+            info.dst_w = w;
+            info.dst_fmt = buffer->pixel_format;
+            info.dst_pitch = buffer->pitch;
+            info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(buffer->pixel_format);
+        }
+        else if (dc->type == RTGUI_DC_HW)
+        {
+            struct rtgui_widget *owner;
+            struct rtgui_rect r;
+
+            owner = ((struct rtgui_dc_hw*)dc)->owner;
+
+            rtgui_graphic_driver_get_rect(RT_NULL, &r);
+
+            /* blit destination */
+            info.dst = (rt_uint8_t*)hw_driver->framebuffer;
+            info.dst = info.dst + (owner->extent.y1 + dst_y) * hw_driver->pitch +
+                       (owner->extent.x1 + dst_x) * rtgui_color_get_bpp(hw_driver->pixel_format);
+            info.dst_fmt = hw_driver->pixel_format;
+            info.dst_h = h;
+            info.dst_w = w;
+            info.dst_pitch = hw_driver->pitch;
+            info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(hw_driver->pixel_format);
+        }
+
+        rtgui_blit(&info);
+    }
 }
 
 void rtgui_image_png_init()

+ 15 - 6
components/gui/src/image_xpm.c

@@ -1,11 +1,21 @@
 /*
  * File      : image_xpm.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -15,7 +25,6 @@
 #include <string.h>
 
 #include <rtgui/filerw.h>
-#include <rtgui/image_xpm.h>
 #include <rtgui/rtgui_system.h>
 
 #ifdef RTGUI_IMAGE_XPM

+ 67 - 43
components/gui/src/matrix.c

@@ -1,3 +1,26 @@
+/*
+ * File      : matrix.c
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Grissiom      first version
+ */
 #include <rtgui/rtgui.h>
 #include <rtgui/matrix.h>
 
@@ -12,7 +35,7 @@
  * this software and associated documentation files (the "Software"),  to deal in
  * the Software without restriction,  including without limitation the rights to
  * use,  copy,  modify,  merge,  publish,  distribute,  sublicense,  and/or sell copies of
- * the Software,  and to permit persons to whom the Software is furnished to do so, 
+ * the Software,  and to permit persons to whom the Software is furnished to do so,
  * subject to the following conditions:
  *
  * The above copyright notice and this permission notice shall be included in all
@@ -91,7 +114,8 @@ int rtgui_matrix_inverse(const struct rtgui_matrix *mm, struct rtgui_matrix *mo)
 /* @dd is the degree range in 0~512 */
 rt_inline int icost(int dd)
 {
-    static const short t[COS_TABLE_SZ] = {
+    static const short t[COS_TABLE_SZ] =
+    {
         2048, 2048, 2047, 2047, 2046, 2044, 2042, 2040, 2038, 2036, 2033, 2029, 2026,
         2022, 2018, 2013, 2009, 2004, 1998, 1993, 1987, 1980, 1974, 1967, 1960, 1952,
         1945, 1937, 1928, 1920, 1911, 1902, 1892, 1882, 1872, 1862, 1851, 1840, 1829,
@@ -137,61 +161,61 @@ rt_inline int icost(int dd)
 
     dd &= COS_TABLE_SZ - 1;
 
-	return t[dd];
+    return t[dd];
 }
 
 rt_inline int icosd(int d)
 {
-	int dd = d;
-	return icost(dd);
+    int dd = d;
+    return icost(dd);
 }
 
 rt_inline int isind(int d)
 {
-	int dd = COS_TABLE_SZ / 4 - d;
-	return icost(dd);
+    int dd = COS_TABLE_SZ / 4 - d;
+    return icost(dd);
 }
 
 rt_inline void rot_mat(int *m, int d)
 {
-	int cosd = icosd(d);
-	int sind = isind(d);
-
-	int m0_cosd = m[0] * cosd;
-	int m0_sind = m[0] * sind;
-	int m1_cosd = m[1] * cosd;
-	int m1_sind = m[1] * sind;
-	int m2_cosd = m[2] * cosd;
-	int m2_sind = m[2] * sind;
-	int m3_cosd = m[3] * cosd;
-	int m3_sind = m[3] * sind;
-	int m4_cosd = m[4] * cosd;
-	int m4_sind = m[4] * sind;
-	int m5_cosd = m[5] * cosd;
-	int m5_sind = m[5] * sind;
-
-	m[0] = _rtgui_matrix_round_div32(m0_cosd - m1_sind, RTGUI_MATRIX_FRAC);
-	m[1] = _rtgui_matrix_round_div32(m0_sind + m1_cosd, RTGUI_MATRIX_FRAC);
-	m[2] = _rtgui_matrix_round_div32(m2_cosd - m3_sind, RTGUI_MATRIX_FRAC);
-	m[3] = _rtgui_matrix_round_div32(m2_sind + m3_cosd, RTGUI_MATRIX_FRAC);
-	m[4] = _rtgui_matrix_round_div32(m4_cosd - m5_sind, RTGUI_MATRIX_FRAC);
-	m[5] = _rtgui_matrix_round_div32(m4_sind + m5_cosd, RTGUI_MATRIX_FRAC);
+    int cosd = icosd(d);
+    int sind = isind(d);
+
+    int m0_cosd = m[0] * cosd;
+    int m0_sind = m[0] * sind;
+    int m1_cosd = m[1] * cosd;
+    int m1_sind = m[1] * sind;
+    int m2_cosd = m[2] * cosd;
+    int m2_sind = m[2] * sind;
+    int m3_cosd = m[3] * cosd;
+    int m3_sind = m[3] * sind;
+    int m4_cosd = m[4] * cosd;
+    int m4_sind = m[4] * sind;
+    int m5_cosd = m[5] * cosd;
+    int m5_sind = m[5] * sind;
+
+    m[0] = _rtgui_matrix_round_div32(m0_cosd - m1_sind, RTGUI_MATRIX_FRAC);
+    m[1] = _rtgui_matrix_round_div32(m0_sind + m1_cosd, RTGUI_MATRIX_FRAC);
+    m[2] = _rtgui_matrix_round_div32(m2_cosd - m3_sind, RTGUI_MATRIX_FRAC);
+    m[3] = _rtgui_matrix_round_div32(m2_sind + m3_cosd, RTGUI_MATRIX_FRAC);
+    m[4] = _rtgui_matrix_round_div32(m4_cosd - m5_sind, RTGUI_MATRIX_FRAC);
+    m[5] = _rtgui_matrix_round_div32(m4_sind + m5_cosd, RTGUI_MATRIX_FRAC);
 }
 
 rt_inline void scale_mat(int *m, int sx, int sy)
 {
-	if (sx != RTGUI_MATRIX_FRAC)
+    if (sx != RTGUI_MATRIX_FRAC)
     {
-		m[0] = _rtgui_matrix_round_div32(m[0] * sx, RTGUI_MATRIX_FRAC);
-		m[2] = _rtgui_matrix_round_div32(m[2] * sx, RTGUI_MATRIX_FRAC);
-		m[4] = _rtgui_matrix_round_div32(m[4] * sx, RTGUI_MATRIX_FRAC);
-	}
-	if (sy != RTGUI_MATRIX_FRAC)
+        m[0] = _rtgui_matrix_round_div32(m[0] * sx, RTGUI_MATRIX_FRAC);
+        m[2] = _rtgui_matrix_round_div32(m[2] * sx, RTGUI_MATRIX_FRAC);
+        m[4] = _rtgui_matrix_round_div32(m[4] * sx, RTGUI_MATRIX_FRAC);
+    }
+    if (sy != RTGUI_MATRIX_FRAC)
     {
-		m[1] = _rtgui_matrix_round_div32(m[1] * sy, RTGUI_MATRIX_FRAC);
-		m[3] = _rtgui_matrix_round_div32(m[3] * sy, RTGUI_MATRIX_FRAC);
-		m[5] = _rtgui_matrix_round_div32(m[5] * sy, RTGUI_MATRIX_FRAC);
-	}
+        m[1] = _rtgui_matrix_round_div32(m[1] * sy, RTGUI_MATRIX_FRAC);
+        m[3] = _rtgui_matrix_round_div32(m[3] * sy, RTGUI_MATRIX_FRAC);
+        m[5] = _rtgui_matrix_round_div32(m[5] * sy, RTGUI_MATRIX_FRAC);
+    }
 }
 
 void rtgui_matrix_rotate(struct rtgui_matrix *m, int rot)
@@ -203,18 +227,18 @@ RTM_EXPORT(rtgui_matrix_rotate);
 
 void rtgui_matrix_scale(struct rtgui_matrix *m, int sx, int sy)
 {
-	scale_mat(m->m, sx, sy);
+    scale_mat(m->m, sx, sy);
 }
 
 void rtgui_matrix_move(struct rtgui_matrix *m, int dx, int dy)
 {
-	m->m[4] += dx;
-	m->m[5] += dy;
+    m->m[4] += dx;
+    m->m[5] += dy;
 }
 
 void rtgui_matrix_dump(const struct rtgui_matrix *m)
 {
-	const int *mm = m->m;
+    const int *mm = m->m;
     rt_kprintf("|%6d, %6d, %6d|\n", mm[0], mm[1], 0);
     rt_kprintf("|%6d, %6d, %6d|\n", mm[2], mm[3], 0);
     rt_kprintf("|%6d, %6d, %6d|\n", mm[4], mm[5], 1);

+ 21 - 11
components/gui/src/mouse.c

@@ -1,11 +1,21 @@
 /*
  * File      : mouse.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -210,7 +220,7 @@ void rtgui_mouse_moveto(int x, int y)
 #endif
 
     if (x != _rtgui_cursor->cx ||
-        y != _rtgui_cursor->cy)
+            y != _rtgui_cursor->cy)
     {
 #ifdef RTGUI_USING_WINMOVE
         if (_rtgui_cursor->win_rect_show)
@@ -257,7 +267,7 @@ void rtgui_mouse_moveto(int x, int y)
         }
 
 #ifdef RTGUI_USING_HW_CURSOR
-		rtgui_cursor_set_position(_rtgui_cursor->cx, _rtgui_cursor->cy);
+        rtgui_cursor_set_position(_rtgui_cursor->cx, _rtgui_cursor->cy);
 #endif
     }
 
@@ -268,12 +278,12 @@ void rtgui_mouse_moveto(int x, int y)
 
 void rtgui_mouse_set_position(int x, int y)
 {
-	/* move current cursor */
-	_rtgui_cursor->cx = x;
-	_rtgui_cursor->cy = y;
+    /* move current cursor */
+    _rtgui_cursor->cx = x;
+    _rtgui_cursor->cy = y;
 
 #ifdef RTGUI_USING_HW_CURSOR
-	rtgui_cursor_set_position(_rtgui_cursor->cx, _rtgui_cursor->cy);
+    rtgui_cursor_set_position(_rtgui_cursor->cx, _rtgui_cursor->cy);
 #endif
 }
 

+ 15 - 5
components/gui/src/mouse.h

@@ -1,11 +1,21 @@
 /*
  * File      : mouse.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 53 - 117
components/gui/src/region.c

@@ -1,11 +1,21 @@
 /*
  * File      : region.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -2017,113 +2027,6 @@ rtgui_rect_t *rtgui_region_extents(rtgui_region_t *region)
     return(&region->extents);
 }
 
-#define ExchangeSpans(a, b)     \
-{                               \
-    rtgui_point_t tpt;          \
-    int    tw;                  \
-                                \
-    tpt = spans[a]; spans[a] = spans[b]; spans[b] = tpt;    \
-    tw = widths[a]; widths[a] = widths[b]; widths[b] = tw;  \
-}
-
-/* ||| I should apply the merge sort code to rectangle sorting above, and see
-   if mapping time can be improved.  But right now I've been at work 12 hours,
-   so forget it.
-*/
-
-static void QuickSortSpans(
-    rtgui_point_t spans[],
-    int     widths[],
-    int     numSpans)
-{
-    int     y;
-    int     i, j, m;
-    rtgui_point_t *r;
-
-    /* Always called with numSpans > 1 */
-    /* Sorts only by y, doesn't bother to sort by x */
-
-    do
-    {
-        if (numSpans < 9)
-        {
-            /* Do insertion sort */
-            int yprev;
-
-            yprev = spans[0].y;
-            i = 1;
-            do
-            {
-                /* while i != numSpans */
-                y = spans[i].y;
-                if (yprev > y)
-                {
-                    /* spans[i] is out of order.  Move into proper location. */
-                    rtgui_point_t tpt;
-                    int     tw, k;
-
-                    for (j = 0; y >= spans[j].y; j++)
-                    {}
-                    tpt = spans[i];
-                    tw  = widths[i];
-                    for (k = i; k != j; k--)
-                    {
-                        spans[k] = spans[k - 1];
-                        widths[k] = widths[k - 1];
-                    }
-                    spans[j] = tpt;
-                    widths[j] = tw;
-                    y = spans[i].y;
-                } /* if out of order */
-                yprev = y;
-                i++;
-            }
-            while (i != numSpans);
-            return;
-        }
-
-        /* Choose partition element, stick in location 0 */
-        m = numSpans / 2;
-        if (spans[m].y > spans[0].y)        ExchangeSpans(m, 0);
-        if (spans[m].y > spans[numSpans - 1].y)   ExchangeSpans(m, numSpans - 1);
-        if (spans[m].y > spans[0].y)        ExchangeSpans(m, 0);
-        y = spans[0].y;
-
-        /* Partition array */
-        i = 0;
-        j = numSpans;
-        do
-        {
-            r = &(spans[i]);
-            do
-            {
-                r++;
-                i++;
-            }
-            while (i != numSpans && r->y < y);
-            r = &(spans[j]);
-            do
-            {
-                r--;
-                j--;
-            }
-            while (y < r->y);
-            if (i < j)
-                ExchangeSpans(i, j);
-        }
-        while (i < j);
-
-        /* Move partition element back to middle */
-        ExchangeSpans(0, j);
-
-        /* Recurse */
-        if (numSpans - j - 1 > 1)
-            QuickSortSpans(&spans[j + 1], &widths[j + 1], numSpans - j - 1);
-        numSpans = j;
-    }
-    while (numSpans > 1);
-}
-
 #define RTGUI_REGION_TRACE
 
 #ifdef RTGUI_REGION_TRACE
@@ -2167,7 +2070,7 @@ void rtgui_region_draw_clip(rtgui_region_t *region, struct rtgui_dc *dc)
 
     x = region->extents.x1;
     y = region->extents.y1;
-    
+
     for (i = 0; i < num; i++)
     {
         struct rtgui_rect rect;
@@ -2207,6 +2110,21 @@ void rtgui_rect_moveto(rtgui_rect_t *rect, int x, int y)
 }
 RTM_EXPORT(rtgui_rect_moveto);
 
+void rtgui_rect_moveto_point(rtgui_rect_t *rect, int x, int y)
+{
+    int mx, my;
+
+    mx = x - rect->x1;
+    my = y - rect->y1;
+
+    rect->x1 += mx;
+    rect->x2 += mx;
+
+    rect->y1 += my;
+    rect->y2 += my;
+}
+RTM_EXPORT(rtgui_rect_moveto_point);
+
 void rtgui_rect_moveto_align(const rtgui_rect_t *rect, rtgui_rect_t *to, int align)
 {
     int dw, dh;
@@ -2275,6 +2193,22 @@ void rtgui_rect_intersect(rtgui_rect_t *src, rtgui_rect_t *dest)
 }
 RTM_EXPORT(rtgui_rect_intersect);
 
+/* union src rect into dest rect */
+void rtgui_rect_union(rtgui_rect_t *src, rtgui_rect_t *dest)
+{
+    if (rtgui_rect_is_empty(dest))
+    {
+        *dest = *src;
+        return ;
+    }
+
+    if (dest->x1 > src->x1) dest->x1 = src->x1;
+    if (dest->y1 > src->y1) dest->y1 = src->y1;
+    if (dest->x2 < src->x2) dest->x2 = src->x2;
+    if (dest->y2 < src->y2) dest->y2 = src->y2;
+}
+RTM_EXPORT(rtgui_rect_union);
+
 int rtgui_rect_contains_point(const rtgui_rect_t *rect, int x, int y)
 {
     if (INBOX(rect, x, y)) return RT_EOK;
@@ -2333,12 +2267,14 @@ RTM_EXPORT(rtgui_rect_is_empty);
 
 rtgui_rect_t *rtgui_rect_set(rtgui_rect_t *rect, int x, int y, int w, int h)
 {
-	RT_ASSERT(rect != RT_NULL);
+    RT_ASSERT(rect != RT_NULL);
 
-	rect->x1 = x; rect->y1 = y;
-	rect->x2 = x + w; rect->y2 = y + h;
+    rect->x1 = x;
+    rect->y1 = y;
+    rect->x2 = x + w;
+    rect->y2 = y + h;
 
-	return rect;
+    return rect;
 }
 RTM_EXPORT(rtgui_rect_set);
 

+ 23 - 13
components/gui/src/rtgui_app.c

@@ -1,11 +1,21 @@
 /*
  * File      : rtgui_app.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2012, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -382,15 +392,15 @@ void rtgui_app_sleep(struct rtgui_app *app, int millisecond)
     rt_err_t result;
     rt_uint16_t current_ref;
     struct rtgui_event *event;
-	rt_tick_t tick, sleep_tick;
-	int delta_tick;
+    rt_tick_t tick, sleep_tick;
+    int delta_tick;
 
-	tick = rt_tick_get();
-	millisecond = rt_tick_from_millisecond(millisecond);
-	if (millisecond == 0) return;
+    tick = rt_tick_get();
+    millisecond = rt_tick_from_millisecond(millisecond);
+    if (millisecond == 0) return;
 
-	sleep_tick = tick + millisecond;
-	delta_tick = millisecond;
+    sleep_tick = tick + millisecond;
+    delta_tick = millisecond;
 
     /* point to event buffer */
     event = (struct rtgui_event *)app->event_buffer;
@@ -418,7 +428,7 @@ void rtgui_app_sleep(struct rtgui_app *app, int millisecond)
         delta_tick = sleep_tick - rt_tick_get();
     }
 
-	app->ref_count --;
+    app->ref_count --;
 }
 RTM_EXPORT(rtgui_app_sleep);
 

+ 75 - 14
components/gui/src/rtgui_driver.c

@@ -1,11 +1,21 @@
 /*
  * File      : driver.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -107,8 +117,8 @@ rtgui_graphic_driver_get_rect_buffer(const struct rtgui_graphic_driver *driver,
 
     /* get source pixel */
     pixel = (rt_uint8_t*)driver->framebuffer
-        + rect.y1 * driver->pitch
-        + rect.x1 * rtgui_color_get_bpp(driver->pixel_format);
+            + rect.y1 * driver->pitch
+            + rect.x1 * rtgui_color_get_bpp(driver->pixel_format);
 
     dst = buffer->pixel;
 
@@ -276,7 +286,7 @@ static void _rgb565_get_pixel(rtgui_color_t *c, int x, int y)
 
 static void _rgb565_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
 {
-    rt_ubase_t index;
+    int index;
     rt_uint16_t pixel;
     rt_uint16_t *pixel_ptr;
 
@@ -298,7 +308,7 @@ static void _rgb565_draw_vline(rtgui_color_t *c, int x , int y1, int y2)
     struct rtgui_graphic_driver *drv;
     rt_uint8_t *dst;
     rt_uint16_t pixel;
-    rt_ubase_t index;
+    int index;
 
     drv = rtgui_graphic_get_device();
     pixel = rtgui_color_to_565(*c);
@@ -327,7 +337,7 @@ static void _rgb565p_get_pixel(rtgui_color_t *c, int x, int y)
 
 static void _rgb565p_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
 {
-    rt_ubase_t index;
+    int index;
     rt_uint16_t pixel;
     rt_uint16_t *pixel_ptr;
 
@@ -349,7 +359,7 @@ static void _rgb565p_draw_vline(rtgui_color_t *c, int x , int y1, int y2)
     struct rtgui_graphic_driver *drv;
     rt_uint8_t *dst;
     rt_uint16_t pixel;
-    rt_ubase_t index;
+    int index;
 
     drv = rtgui_graphic_get_device();
     pixel = rtgui_color_to_565p(*c);
@@ -361,6 +371,46 @@ static void _rgb565p_draw_vline(rtgui_color_t *c, int x , int y1, int y2)
     }
 }
 
+static void _argb888_set_pixel(rtgui_color_t *c, int x, int y)
+{
+    *GET_PIXEL(rtgui_graphic_get_device(), x, y, rtgui_color_t) = *c;
+}
+
+static void _argb888_get_pixel(rtgui_color_t *c, int x, int y)
+{
+    *c = (rtgui_color_t)*GET_PIXEL(rtgui_graphic_get_device(), x, y, rtgui_color_t);
+}
+
+static void _argb888_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
+{
+    int index;
+    rtgui_color_t *pixel_ptr;
+
+    /* get pixel pointer in framebuffer */
+    pixel_ptr = GET_PIXEL(rtgui_graphic_get_device(), x1, y, rtgui_color_t);
+
+    for (index = x1; index < x2; index++)
+    {
+        *pixel_ptr = *c;
+        pixel_ptr++;
+    }
+}
+
+static void _argb888_draw_vline(rtgui_color_t *c, int x, int y1, int y2)
+{
+    struct rtgui_graphic_driver *drv;
+    rtgui_color_t *dst;
+    int index;
+
+    drv = rtgui_graphic_get_device();
+    dst = GET_PIXEL(drv, x, y1, rtgui_color_t);
+    for (index = y1; index < y2; index++)
+    {
+        *dst = *c;
+        dst += drv->width;
+    }
+}
+
 /* draw raw hline */
 static void framebuffer_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y)
 {
@@ -391,6 +441,15 @@ const struct rtgui_graphic_driver_ops _framebuffer_rgb565p_ops =
     framebuffer_draw_raw_hline,
 };
 
+const struct rtgui_graphic_driver_ops _framebuffer_argb888_ops =
+{
+    _argb888_set_pixel,
+    _argb888_get_pixel,
+    _argb888_draw_hline,
+    _argb888_draw_vline,
+    framebuffer_draw_raw_hline,
+};
+
 #define FRAMEBUFFER (drv->framebuffer)
 #define MONO_PIXEL(framebuffer, x, y) \
     ((rt_uint8_t**)(framebuffer))[y/8][x]
@@ -417,8 +476,8 @@ static void _mono_get_pixel(rtgui_color_t *c, int x, int y)
 
 static void _mono_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
 {
+    int index;
     struct rtgui_graphic_driver *drv = rtgui_graphic_get_device();
-    rt_ubase_t index;
 
     if (*c == white)
         for (index = x1; index < x2; index ++)
@@ -435,7 +494,7 @@ static void _mono_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
 static void _mono_draw_vline(rtgui_color_t *c, int x , int y1, int y2)
 {
     struct rtgui_graphic_driver *drv = rtgui_graphic_get_device();
-    rt_ubase_t index;
+    int index;
 
     if (*c == white)
         for (index = y1; index < y2; index ++)
@@ -453,7 +512,7 @@ static void _mono_draw_vline(rtgui_color_t *c, int x , int y1, int y2)
 static void _mono_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y)
 {
     struct rtgui_graphic_driver *drv = rtgui_graphic_get_device();
-    rt_ubase_t index;
+    int index;
 
     for (index = x1; index < x2; index ++)
     {
@@ -487,6 +546,8 @@ const struct rtgui_graphic_driver_ops *rtgui_framebuffer_get_ops(int pixel_forma
         return &_framebuffer_rgb565_ops;
     case RTGRAPHIC_PIXEL_FORMAT_RGB565P:
         return &_framebuffer_rgb565p_ops;
+    case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
+        return &_framebuffer_argb888_ops;
     default:
         RT_ASSERT(0);
         break;

+ 20 - 10
components/gui/src/rtgui_object.c

@@ -1,11 +1,21 @@
 /*
  * File      : rtgui_object.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -170,11 +180,11 @@ rtgui_object_t *rtgui_object_check_cast(rtgui_object_t *obj, const rtgui_type_t
 {
     if (!obj) return RT_NULL;
 
-	if (!rtgui_type_inherits_from(obj->type, obj_type))
-	{
-		rt_kprintf("%s[%d]: Invalid cast from \"%s\" to \"%s\"\n", func, line,
-            rtgui_type_name_get(obj->type), rtgui_type_name_get(obj_type));
-	}
+    if (!rtgui_type_inherits_from(obj->type, obj_type))
+    {
+        rt_kprintf("%s[%d]: Invalid cast from \"%s\" to \"%s\"\n", func, line,
+                   rtgui_type_name_get(obj->type), rtgui_type_name_get(obj_type));
+    }
 
     return obj;
 }

+ 38 - 20
components/gui/src/rtgui_system.c

@@ -1,16 +1,26 @@
 /*
  * File      : rtgui_system.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
  * 2009-10-04     Bernard      first version
- * 2016-03-23     Bernard      fix the default font initialization issue. 
+ * 2016-03-23     Bernard      fix the default font initialization issue.
  */
 
 #include <rtgui/rtgui.h>
@@ -22,6 +32,10 @@
 #include <rtgui/rtgui_system.h>
 #include <rtgui/widgets/window.h>
 
+#ifdef RTGUI_USING_TTF
+#include <rtgui/font_freetype.h>
+#endif
+
 #ifdef _WIN32_NATIVE
 #define RTGUI_MEM_TRACE
 #endif
@@ -60,6 +74,10 @@ int rtgui_system_server_init(void)
     rtgui_font_set_defaut(&rtgui_font_asc12);
 #endif
 
+#ifdef RTGUI_USING_TTF
+    rtgui_ttf_system_init();
+#endif
+
     return 0;
 }
 INIT_APP_EXPORT(rtgui_system_server_init);
@@ -413,7 +431,7 @@ const char *rtgui_event_string[] =
     "TIMER",                /* timer                */
     "UPDATE_TOPLVL",        /* update toplevel      */
 
-	"VPAINT_REQ", 			/* virtual paint request */
+    "VPAINT_REQ", 			/* virtual paint request */
 
     /* clip rect information */
     "CLIP_INFO",            /* clip rect info       */
@@ -423,7 +441,7 @@ const char *rtgui_event_string[] =
     "MOUSE_BUTTON",         /* mouse button info    */
     "KBD",                  /* keyboard info        */
     "TOUCH",                /* touch info           */
-	"GESTURE", 				/* gesture              */
+    "GESTURE", 				/* gesture              */
 
     "FOCUSED",              /* widget got focuse    */
     "SCROLLED",             /* scroll bar scrolled  */
@@ -599,7 +617,7 @@ static void rtgui_event_dump(struct rtgui_app* app, rtgui_event_t *event)
     break;
 
     default:
-    break;
+        break;
     }
 
     rt_kprintf("\n");
@@ -722,7 +740,7 @@ RTM_EXPORT(rtgui_recv);
 
 rt_err_t rtgui_recv_filter(rt_uint32_t type, rtgui_event_t *event, rt_size_t event_size)
 {
-	rtgui_event_t *e;
+    rtgui_event_t *e;
     struct rtgui_app *app;
 
     RT_ASSERT(event != RT_NULL);
@@ -732,7 +750,7 @@ rt_err_t rtgui_recv_filter(rt_uint32_t type, rtgui_event_t *event, rt_size_t eve
     if (app == RT_NULL)
         return -RT_ERROR;
 
-	e = (rtgui_event_t*)&app->event_buffer[0];
+    e = (rtgui_event_t*)&app->event_buffer[0];
     while (rt_mq_recv(app->mq, e, sizeof(union rtgui_event_generic), RT_WAITING_FOREVER) == RT_EOK)
     {
         if (e->type == type)
@@ -785,23 +803,23 @@ RTM_EXPORT(rtgui_screen_unlock);
 
 int rtgui_screen_lock_freeze(void)
 {
-	int hold = 0;
+    int hold = 0;
 
-	if (_screen_lock.owner == rt_thread_self())
-	{
-		int index;
+    if (_screen_lock.owner == rt_thread_self())
+    {
+        int index;
 
-		index = hold = _screen_lock.hold;
-		while (index --) rt_mutex_release(&_screen_lock);
-	}
+        index = hold = _screen_lock.hold;
+        while (index --) rt_mutex_release(&_screen_lock);
+    }
 
-	return hold;
+    return hold;
 }
 RTM_EXPORT(rtgui_screen_lock_freeze);
 
 void rtgui_screen_lock_thaw(int value)
 {
-	while (value--) rt_mutex_take(&_screen_lock, RT_WAITING_FOREVER);
+    while (value--) rt_mutex_take(&_screen_lock, RT_WAITING_FOREVER);
 }
 RTM_EXPORT(rtgui_screen_lock_thaw);
 

+ 67 - 48
components/gui/src/server.c

@@ -1,11 +1,21 @@
 /*
  * File      : server.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -71,12 +81,12 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse *event)
     /* re-init to server thread */
     RTGUI_EVENT_MOUSE_BUTTON_INIT(event);
 
-	/* set cursor position */
-	rtgui_mouse_set_position(event->x, event->y);
+    /* set cursor position */
+    rtgui_mouse_set_position(event->x, event->y);
 
 #ifdef RTGUI_USING_WINMOVE
     if (rtgui_winrect_is_moved() &&
-        event->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP))
+            event->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP))
     {
         struct rtgui_win *win;
         rtgui_rect_t rect;
@@ -108,7 +118,7 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse *event)
 
     /* only raise window if the button is pressed down */
     if (event->button & RTGUI_MOUSE_BUTTON_DOWN &&
-        rtgui_topwin_get_focus() != wnd)
+            rtgui_topwin_get_focus() != wnd)
     {
         rtgui_topwin_activate_topwin(wnd);
     }
@@ -175,34 +185,34 @@ void rtgui_server_handle_kbd(struct rtgui_event_kbd *event)
 
 void rtgui_server_handle_touch(struct rtgui_event_touch *event)
 {
-//	if (rtgui_touch_do_calibration(event) == RT_TRUE)
-//	{
-//		struct rtgui_event_mouse emouse;
-
-//		/* convert it as a mouse event to rtgui */
-//		if (event->up_down == RTGUI_TOUCH_MOTION)
-//		{
-//			RTGUI_EVENT_MOUSE_MOTION_INIT(&emouse);
-//			emouse.x = event->x;
-//			emouse.y = event->y;
-//			emouse.button = 0;
-
-//			rtgui_server_handle_mouse_motion(&emouse);
-//		}
-//		else
-//		{
-//			RTGUI_EVENT_MOUSE_BUTTON_INIT(&emouse);
-//			emouse.x = event->x;
-//			emouse.y = event->y;
-//			emouse.button = RTGUI_MOUSE_BUTTON_LEFT;
-//			if (event->up_down == RTGUI_TOUCH_UP)
-//				emouse.button |= RTGUI_MOUSE_BUTTON_UP;
-//			else
-//				emouse.button |= RTGUI_MOUSE_BUTTON_DOWN;
-
-//			rtgui_server_handle_mouse_btn(&emouse);
-//		}
-//	}
+//  if (rtgui_touch_do_calibration(event) == RT_TRUE)
+//  {
+//      struct rtgui_event_mouse emouse;
+
+//      /* convert it as a mouse event to rtgui */
+//      if (event->up_down == RTGUI_TOUCH_MOTION)
+//      {
+//          RTGUI_EVENT_MOUSE_MOTION_INIT(&emouse);
+//          emouse.x = event->x;
+//          emouse.y = event->y;
+//          emouse.button = 0;
+
+//          rtgui_server_handle_mouse_motion(&emouse);
+//      }
+//      else
+//      {
+//          RTGUI_EVENT_MOUSE_BUTTON_INIT(&emouse);
+//          emouse.x = event->x;
+//          emouse.y = event->y;
+//          emouse.button = RTGUI_MOUSE_BUTTON_LEFT;
+//          if (event->up_down == RTGUI_TOUCH_UP)
+//              emouse.button |= RTGUI_MOUSE_BUTTON_UP;
+//          else
+//              emouse.button |= RTGUI_MOUSE_BUTTON_DOWN;
+
+//          rtgui_server_handle_mouse_btn(&emouse);
+//      }
+//  }
 }
 
 #ifdef _WIN32_NATIVE
@@ -210,7 +220,7 @@ void rtgui_server_handle_touch(struct rtgui_event_touch *event)
 #endif
 
 static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object,
-                                            struct rtgui_event *event)
+        struct rtgui_event *event)
 {
     RT_ASSERT(object != RT_NULL);
     RT_ASSERT(event != RT_NULL);
@@ -232,7 +242,7 @@ static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object,
         }
         break;
 
-        /* mouse and keyboard event */
+    /* mouse and keyboard event */
     case RTGUI_EVENT_MOUSE_MOTION:
         /* handle mouse motion event */
         rtgui_server_handle_mouse_motion((struct rtgui_event_mouse *)event);
@@ -243,17 +253,17 @@ static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object,
         rtgui_server_handle_mouse_btn((struct rtgui_event_mouse *)event);
         break;
 
-	case RTGUI_EVENT_TOUCH:
-		/* handle touch event */
-		rtgui_server_handle_touch((struct rtgui_event_touch *)event);
-		break;
+    case RTGUI_EVENT_TOUCH:
+        /* handle touch event */
+        rtgui_server_handle_touch((struct rtgui_event_touch *)event);
+        break;
 
     case RTGUI_EVENT_KBD:
         /* handle keyboard event */
         rtgui_server_handle_kbd((struct rtgui_event_kbd *)event);
         break;
 
-        /* window event */
+    /* window event */
     case RTGUI_EVENT_WIN_CREATE:
         if (rtgui_topwin_add((struct rtgui_event_win_create *)event) == RT_EOK)
             rtgui_ack(event, RTGUI_STATUS_OK);
@@ -325,7 +335,7 @@ static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object,
         }
         break;
 
-        /* other event */
+    /* other event */
     case RTGUI_EVENT_COMMAND:
         break;
 
@@ -373,7 +383,7 @@ static void rtgui_server_entry(void *parameter)
     rtgui_server_app = rtgui_app_create("rtgui");
     if (rtgui_server_app == RT_NULL)
     {
-		rt_kprintf("Create GUI server failed.\n");
+        rt_kprintf("Create GUI server failed.\n");
         return;
     }
 
@@ -391,12 +401,21 @@ static void rtgui_server_entry(void *parameter)
     rtgui_server_app = RT_NULL;
 }
 
-void rtgui_server_post_event(struct rtgui_event *event, rt_size_t size)
+rt_err_t rtgui_server_post_event(struct rtgui_event *event, rt_size_t size)
 {
+    rt_err_t result;
+
     if (rtgui_server_app != RT_NULL)
-        rtgui_send(rtgui_server_app, event, size);
+    {
+        result = rtgui_send(rtgui_server_app, event, size);
+    }
     else
+    {
         rt_kprintf("post when server is not running\n");
+        result = -RT_ENOSYS;
+    }
+
+    return result;
 }
 
 rt_err_t rtgui_server_post_event_sync(struct rtgui_event *event, rt_size_t size)

+ 20 - 9
components/gui/src/title.c

@@ -1,11 +1,21 @@
 /*
  * File      : title.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -75,7 +85,8 @@ rt_bool_t rtgui_wintile_event_handler(struct rtgui_object *obj, rtgui_event_t *e
         rtgui_theme_draw_win(wint);
         return RT_FALSE;
 
-    case RTGUI_EVENT_MOUSE_BUTTON: {
+    case RTGUI_EVENT_MOUSE_BUTTON:
+    {
         struct rtgui_event_mouse *emou = (struct rtgui_event_mouse *)eve;
 
         if (win->style & RTGUI_WIN_STYLE_CLOSEBOX)
@@ -107,8 +118,8 @@ rt_bool_t rtgui_wintile_event_handler(struct rtgui_object *obj, rtgui_event_t *e
                 else if (emou->button & RTGUI_MOUSE_BUTTON_UP)
                 {
                     if (win->flag & RTGUI_WIN_FLAG_CB_PRESSED &&
-                        rtgui_rect_contains_point(&rect,
-                                                  emou->x, emou->y) == RT_EOK)
+                            rtgui_rect_contains_point(&rect,
+                                                      emou->x, emou->y) == RT_EOK)
                     {
                         rtgui_win_close(win);
                         return RT_TRUE;
@@ -130,7 +141,7 @@ rt_bool_t rtgui_wintile_event_handler(struct rtgui_object *obj, rtgui_event_t *e
 #endif
         }
     }
-        return RT_TRUE;
+    return RT_TRUE;
     default:
         return rtgui_widget_event_handler(obj, eve);
     }

+ 27 - 16
components/gui/src/topwin.c

@@ -1,16 +1,26 @@
 /*
  * File      : topwin.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
  * 2009-10-16     Bernard      first version
- * 2012-02-25     Grissiom     rewrite topwin implementation 
+ * 2012-02-25     Grissiom     rewrite topwin implementation
  */
 #include "topwin.h"
 #include "mouse.h"
@@ -25,7 +35,7 @@
 #include <rtgui/widgets/container.h>
 
 /*
- * windows tree in the server side. 
+ * windows tree in the server side.
  *
  * This list is divided into two parts. The first part is the shown list, in
  * which all the windows have the WINTITLE_SHOWN flag set. Second part is the
@@ -224,7 +234,7 @@ static struct rtgui_topwin* _rtgui_topwin_get_next_shown(struct rtgui_topwin *to
     if (top->parent == RT_NULL)
     {
         if (top->list.next != &_rtgui_topwin_list &&
-            get_topwin_from_list(top->list.next)->flag & WINTITLE_SHOWN)
+                get_topwin_from_list(top->list.next)->flag & WINTITLE_SHOWN)
             top = _rtgui_topwin_get_topmost_child_shown(get_topwin_from_list(top->list.next));
         else
             return RT_NULL;
@@ -605,7 +615,7 @@ rt_inline void _rtgui_topwin_preorder_map(struct rtgui_topwin *topwin, void (*fu
     func(topwin);
 
     rt_list_foreach(child, &topwin->child_list, next)
-        _rtgui_topwin_preorder_map(get_topwin_from_list(child), func);
+    _rtgui_topwin_preorder_map(get_topwin_from_list(child), func);
 }
 
 rt_inline void _rtgui_topwin_mark_hidden(struct rtgui_topwin *topwin)
@@ -743,7 +753,7 @@ rt_err_t rtgui_topwin_move(struct rtgui_event_win_move *event)
     /* find in show list */
     topwin = rtgui_topwin_search_in_list(event->wid, &_rtgui_topwin_list);
     if (topwin == RT_NULL ||
-        !(topwin->flag & WINTITLE_SHOWN))
+            !(topwin->flag & WINTITLE_SHOWN))
     {
         return -RT_ERROR;
     }
@@ -886,7 +896,7 @@ struct rtgui_topwin *rtgui_topwin_get_wnd_no_modaled(int x, int y)
 
 /* clip region from topwin, and the windows beneath it. */
 rt_inline void _rtgui_topwin_clip_to_region(struct rtgui_topwin *topwin,
-                                            struct rtgui_region *region)
+        struct rtgui_region *region)
 {
     RT_ASSERT(region != RT_NULL);
     RT_ASSERT(topwin != RT_NULL);
@@ -905,7 +915,7 @@ static void rtgui_topwin_update_clip(void)
     struct rtgui_region region_available;
 
     if (rt_list_isempty(&_rtgui_topwin_list) ||
-        !(get_topwin_from_list(_rtgui_topwin_list.next)->flag & WINTITLE_SHOWN))
+            !(get_topwin_from_list(_rtgui_topwin_list.next)->flag & WINTITLE_SHOWN))
         return;
 
     RTGUI_EVENT_CLIP_INFO_INIT(&eclip);
@@ -1004,7 +1014,8 @@ rt_err_t rtgui_topwin_modal_enter(struct rtgui_event_win_modal_enter *event)
     /* modal window should be on top already */
     RT_ASSERT(get_topwin_from_list(parent_top->child_list.next) == topwin);
 
-    do {
+    do
+    {
         rt_list_foreach(node, &parent_top->child_list, next)
         {
             get_topwin_from_list(node)->flag |= WINTITLE_MODALED;
@@ -1057,8 +1068,8 @@ void rtgui_topwin_remove_monitor_rect(struct rtgui_win *wid, rtgui_rect_t *rect)
 }
 
 static struct rtgui_object* _get_obj_in_topwin(struct rtgui_topwin *topwin,
-                                               struct rtgui_app *app,
-                                               rt_uint32_t id)
+        struct rtgui_app *app,
+        rt_uint32_t id)
 {
     struct rtgui_object *object;
     struct rt_list_node *node;
@@ -1124,7 +1135,7 @@ static void _rtgui_topwin_dump(struct rtgui_topwin *topwin)
                topwin, topwin->wid->title, topwin->flag,
                topwin->flag & WINTITLE_SHOWN ? 'S' : 'H',
                topwin->flag & WINTITLE_MODALED ? 'm' :
-                  topwin->flag & WINTITLE_MODALING ? 'M' : ' ');
+               topwin->flag & WINTITLE_MODALING ? 'M' : ' ');
 }
 
 static void _rtgui_topwin_dump_tree(struct rtgui_topwin *topwin)

+ 15 - 5
components/gui/src/topwin.h

@@ -1,11 +1,21 @@
 /*
  * File      : topwin.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes

+ 30 - 39
components/gui/src/widget.c

@@ -1,7 +1,7 @@
 /*
  * File      : widget.c
- * This file is part of RT-Thread GUI
- * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -24,14 +24,12 @@
  * 2013-10-07     Bernard      remove the win_check in update_clip.
  */
 
-#include <rtgui/dc_client.h>
+#include <string.h>
+#include <rtgui/dc.h>
 #include <rtgui/rtgui_app.h>
 #include <rtgui/widgets/widget.h>
 #include <rtgui/widgets/window.h>
 #include <rtgui/widgets/container.h>
-#ifdef RTGUI_USING_NOTEBOOK
-#include <rtgui/widgets/notebook.h>
-#endif
 
 static void _rtgui_widget_constructor(rtgui_widget_t *widget)
 {
@@ -52,8 +50,8 @@ static void _rtgui_widget_constructor(rtgui_widget_t *widget)
     widget->align = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP;
 
     /* clear the garbage value of extent and clip */
-    widget->extent.x1 = widget->extent.y1 = 0;
-    widget->extent.x2 = widget->extent.y2 = 0;
+    memset(&(widget->extent), 0x0, sizeof(widget->extent));
+    memset(&(widget->extent_visiable), 0x0, sizeof(widget->extent_visiable));
     widget->min_width = widget->min_height = 0;
     rtgui_region_init_with_extents(&widget->clip, &widget->extent);
 
@@ -64,7 +62,6 @@ static void _rtgui_widget_constructor(rtgui_widget_t *widget)
     /* some common event handler */
     widget->on_focus_in   = RT_NULL;
     widget->on_focus_out  = RT_NULL;
-    widget->on_paint      = RT_NULL;
 
     /* set default event handler */
     rtgui_object_set_event_handler(RTGUI_OBJECT(widget), rtgui_widget_event_handler);
@@ -72,9 +69,6 @@ static void _rtgui_widget_constructor(rtgui_widget_t *widget)
     /* init user data private to 0 */
     widget->user_data = 0;
 
-    /* init clip information */
-    rtgui_region_init(&(widget->clip));
-
     /* init hardware dc */
     rtgui_dc_client_init(widget);
 }
@@ -127,6 +121,8 @@ void rtgui_widget_set_rect(rtgui_widget_t *widget, const rtgui_rect_t *rect)
 
     /* update extent rectangle */
     widget->extent = *rect;
+    /* set the visiable extern as extern */
+    widget->extent_visiable = *rect;
     if (RTGUI_IS_CONTAINER(widget))
     {
         /* re-do layout */
@@ -166,7 +162,6 @@ void rtgui_widget_set_rect(rtgui_widget_t *widget, const rtgui_rect_t *rect)
 
         rtgui_widget_move_to_logic(widget, delta_x, delta_y);
     }
-
 }
 RTM_EXPORT(rtgui_widget_set_rect);
 
@@ -226,9 +221,18 @@ RTM_EXPORT(rtgui_widget_set_minheight);
 static void _widget_moveto(struct rtgui_widget* widget, int dx, int dy)
 {
     struct rtgui_list_node *node;
-    rtgui_widget_t *child;
+    rtgui_widget_t *child, *parent;
 
     rtgui_rect_moveto(&(widget->extent), dx, dy);
+
+    /* handle visiable extent */
+    widget->extent_visiable = widget->extent;
+    parent = widget->parent;
+    /* we should find out the none-transparent parent */
+    while (parent != RT_NULL && parent->flag & RTGUI_WIDGET_FLAG_TRANSPARENT) parent = parent->parent;
+    if (widget->parent)
+        rtgui_rect_intersect(&(widget->parent->extent_visiable), &(widget->extent_visiable));
+
     /* reset clip info */
     rtgui_region_init_with_extents(&(widget->clip), &(widget->extent));
 
@@ -260,7 +264,7 @@ void rtgui_widget_move_to_logic(rtgui_widget_t *widget, int dx, int dy)
     if (parent != RT_NULL)
     {
         /* get the parent rect, even if it's a transparent parent. */
-        rect = parent->clip.extents;
+        rect = parent->extent_visiable;
     }
 
     /* we should find out the none-transparent parent */
@@ -270,7 +274,6 @@ void rtgui_widget_move_to_logic(rtgui_widget_t *widget, int dx, int dy)
         /* reset clip info */
         rtgui_region_init_with_extents(&(widget->clip), &(widget->extent));
         rtgui_region_intersect_rect(&(widget->clip), &(widget->clip), &rect);
-        rtgui_region_intersect_rect(&(widget->clip), &(widget->clip), &(parent->extent));
 
         /* give back the extent */
         rtgui_region_union(&(parent->clip), &(parent->clip), &(widget->clip));
@@ -344,14 +347,6 @@ void rtgui_widget_set_onunfocus(rtgui_widget_t *widget, rtgui_event_handler_ptr
 }
 RTM_EXPORT(rtgui_widget_set_onunfocus);
 
-void rtgui_widget_set_onpaint(rtgui_widget_t *widget, rtgui_event_handler_ptr handler)
-{
-    RT_ASSERT(widget != RT_NULL);
-
-    widget->on_paint = handler;
-}
-RTM_EXPORT(rtgui_widget_set_onpaint);
-
 /**
  * @brief Focuses the widget. The focused widget is the widget which can receive the keyboard events
  * @param widget a widget
@@ -511,15 +506,6 @@ rt_bool_t rtgui_widget_onupdate_toplvl(struct rtgui_object *object, struct rtgui
 }
 RTM_EXPORT(rtgui_widget_onupdate_toplvl);
 
-rt_bool_t rtgui_widget_onpaint(struct rtgui_object *object, struct rtgui_event *event)
-{
-    if (RTGUI_WIDGET(object)->on_paint)
-        return RTGUI_WIDGET(object)->on_paint(object, event);
-    else
-        return RT_FALSE;
-}
-RTM_EXPORT(rtgui_widget_onpaint);
-
 rt_bool_t rtgui_widget_event_handler(struct rtgui_object *object, rtgui_event_t *event)
 {
     RTGUI_WIDGET_EVENT_HANDLER_PREPARE;
@@ -527,7 +513,7 @@ rt_bool_t rtgui_widget_event_handler(struct rtgui_object *object, rtgui_event_t
     switch (event->type)
     {
     case RTGUI_EVENT_PAINT:
-        return rtgui_widget_onpaint(object, event);
+        break;
     case RTGUI_EVENT_SHOW:
         return rtgui_widget_onshow(object, event);
     case RTGUI_EVENT_HIDE:
@@ -556,7 +542,11 @@ void rtgui_widget_update_clip(rtgui_widget_t *widget)
         return;
 
     parent = widget->parent;
-    rect = parent->clip.extents;
+    /* reset visiable extent */
+    widget->extent_visiable = widget->extent;
+    rtgui_rect_intersect(&(parent->extent_visiable), &(widget->extent_visiable));
+
+    rect = parent->extent_visiable;
     /* reset clip to extent */
     rtgui_region_reset(&(widget->clip), &(widget->extent));
     /* limit widget extent in parent extent */
@@ -575,7 +565,7 @@ void rtgui_widget_update_clip(rtgui_widget_t *widget)
         /* subtract widget clip in parent clip */
         if (!(widget->flag & RTGUI_WIDGET_FLAG_TRANSPARENT) && RTGUI_IS_CONTAINER(parent))
         {
-            rtgui_region_subtract_rect(&(parent->clip), &(parent->clip), &(widget->extent));
+            rtgui_region_subtract_rect(&(parent->clip), &(parent->clip), &(widget->extent_visiable));
         }
     }
 
@@ -628,7 +618,6 @@ void rtgui_widget_hide(struct rtgui_widget *widget)
     if (RTGUI_WIDGET_IS_HIDE(widget))
         return;
 
-    RTGUI_WIDGET_HIDE(widget);
     if (widget->toplevel != RT_NULL)
     {
         RTGUI_EVENT_HIDE_INIT(&ehide);
@@ -639,6 +628,8 @@ void rtgui_widget_hide(struct rtgui_widget *widget)
                 &ehide);
         }
     }
+
+    RTGUI_WIDGET_HIDE(widget);
 }
 RTM_EXPORT(rtgui_widget_hide);
 
@@ -648,7 +639,7 @@ rt_bool_t rtgui_widget_onshow(struct rtgui_object *object, struct rtgui_event *e
 
     if (RTGUI_WIDGET_IS_HIDE(object)) return RT_FALSE;
 
-    if (widget->parent != RT_NULL)
+    if (widget->parent != RT_NULL && !(RTGUI_WIDGET_FLAG(widget) & RTGUI_WIDGET_FLAG_TRANSPARENT))
     {
         rtgui_widget_clip_parent(widget);
     }
@@ -742,7 +733,7 @@ void rtgui_widget_update(rtgui_widget_t *widget)
     RT_ASSERT(widget != RT_NULL);
 
     if (RTGUI_OBJECT(widget)->event_handler != RT_NULL &&
-        !(RTGUI_WIDGET_FLAG(widget) & RTGUI_WIDGET_FLAG_IN_ANIM))
+            !(RTGUI_WIDGET_FLAG(widget) & RTGUI_WIDGET_FLAG_IN_ANIM))
     {
         RTGUI_OBJECT(widget)->event_handler(RTGUI_OBJECT(widget),
                                             &paint.parent);

+ 44 - 29
components/gui/src/window.c

@@ -1,11 +1,21 @@
 /*
  * File      : window.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ * This file is part of RT-Thread GUI Engine
+ * COPYRIGHT (C) 2006 - 2017, 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
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Change Logs:
  * Date           Author       Notes
@@ -132,9 +142,9 @@ DEFINE_CLASS_TYPE(win, "win",
                   sizeof(struct rtgui_win));
 
 int rtgui_win_init(struct rtgui_win *win, struct rtgui_win *parent_window,
-                              const char *title,
-                              rtgui_rect_t *rect,
-                              rt_uint16_t style)
+                   const char *title,
+                   rtgui_rect_t *rect,
+                   rt_uint16_t style)
 {
     if (win == RT_NULL) return -1;
 
@@ -425,7 +435,7 @@ RTM_EXPORT(rtgui_win_do_show);
 
 rt_base_t rtgui_win_show(struct rtgui_win *win, rt_bool_t is_modal)
 {
-	RTGUI_WIDGET_UNHIDE(win);
+    RTGUI_WIDGET_UNHIDE(win);
 
     if (is_modal)
         win->flag |= RTGUI_WIN_FLAG_MODAL;
@@ -557,7 +567,7 @@ static rt_bool_t rtgui_win_ondraw(struct rtgui_win *win)
     /* fill area */
     rtgui_dc_fill_rect(dc, &rect);
 
-    rtgui_widget_onpaint(RTGUI_OBJECT(win), RT_NULL);
+    /* widget drawing */
 
     /* paint each widget */
     RTGUI_EVENT_PAINT_INIT(&event);
@@ -565,7 +575,7 @@ static rt_bool_t rtgui_win_ondraw(struct rtgui_win *win)
     rtgui_container_dispatch_event(RTGUI_CONTAINER(win),
                                    (rtgui_event_t *)&event);
 
-    rtgui_dc_end_drawing(dc);
+    rtgui_dc_end_drawing(dc, 1);
 
     return RT_FALSE;
 }
@@ -623,11 +633,11 @@ static rt_bool_t _win_handle_mouse_btn(struct rtgui_win *win, struct rtgui_event
      * widgets). If not, it will receive two mouse up events.
      */
     if (((struct rtgui_event_mouse *)eve)->button & RTGUI_MOUSE_BUTTON_UP
-        && win->last_mevent_widget != RT_NULL)
+            && win->last_mevent_widget != RT_NULL)
     {
         if (RTGUI_OBJECT(win->last_mevent_widget)->event_handler(
-                                                                 RTGUI_OBJECT(win->last_mevent_widget),
-                                                                 eve) == RT_TRUE)
+                    RTGUI_OBJECT(win->last_mevent_widget),
+                    eve) == RT_TRUE)
         {
             /* clean last mouse event handled widget */
             win->last_mevent_widget = RT_NULL;
@@ -643,7 +653,7 @@ static rt_bool_t _win_handle_mouse_btn(struct rtgui_win *win, struct rtgui_event
      * TODO: add it in the doc
      */
     return rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win),
-                                               (struct rtgui_event_mouse *)eve);
+            (struct rtgui_event_mouse *)eve);
 }
 
 rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_event *event)
@@ -681,7 +691,7 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_even
 
     case RTGUI_EVENT_WIN_ACTIVATE:
         if (win->flag & RTGUI_WIN_FLAG_UNDER_MODAL ||
-            RTGUI_WIDGET_IS_HIDE(win))
+                RTGUI_WIDGET_IS_HIDE(win))
         {
             /* activate a hide window */
             return RT_TRUE;
@@ -713,6 +723,9 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_even
 
         break;
 
+    case RTGUI_EVENT_WIN_UPDATE_END:
+        break;
+
     case RTGUI_EVENT_CLIP_INFO:
         /* update win clip */
         rtgui_win_update_clip(win);
@@ -725,22 +738,23 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_even
         break;
 
 #ifdef RTGUI_USING_VFRAMEBUFFER
-	case RTGUI_EVENT_VPAINT_REQ:
-	{
+    case RTGUI_EVENT_VPAINT_REQ:
+    {
         struct rtgui_event_vpaint_req *req = (struct rtgui_event_vpaint_req *)event;
-		struct rtgui_dc *dc;
+        struct rtgui_dc *dc;
 
-		/* get drawing dc */
-		dc = rtgui_win_get_drawing(win);
+        /* get drawing dc */
+        dc = rtgui_win_get_drawing(win);
 
         req->sender->buffer = dc;
         rt_completion_done(req->sender->cmp);
 
-		break;
-	}
+        break;
+    }
 #endif
 
-    case RTGUI_EVENT_MOUSE_BUTTON: {
+    case RTGUI_EVENT_MOUSE_BUTTON:
+    {
         struct rtgui_event_mouse *emouse = (struct rtgui_event_mouse*)event;
 
         if (rtgui_rect_contains_point(&RTGUI_WIDGET(win)->extent,
@@ -757,7 +771,7 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_even
 
     case RTGUI_EVENT_MOUSE_MOTION:
         return rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win),
-                                                    (struct rtgui_event_mouse *)event);
+                (struct rtgui_event_mouse *)event);
 
     case RTGUI_EVENT_KBD:
         /* we should dispatch key event firstly */
@@ -974,7 +988,8 @@ struct rtgui_dc *rtgui_win_get_drawing(rtgui_win_t * win)
 RTM_EXPORT(rtgui_win_get_drawing);
 #endif
 
-static const rt_uint8_t close_byte[14] = {
+static const rt_uint8_t close_byte[14] =
+{
     0x06, 0x18, 0x03, 0x30, 0x01, 0xE0, 0x00,
     0xC0, 0x01, 0xE0, 0x03, 0x30, 0x06, 0x18
 };
@@ -1053,8 +1068,8 @@ void rtgui_theme_draw_win(struct rtgui_wintitle *wint)
         for (index = rect.x1; index < rect.x2 + 1; index ++)
         {
             RTGUI_WIDGET_FOREGROUND(win->_title_wgt) = RTGUI_RGB((r>>RGB_FACTOR),
-                                                                 (g>>RGB_FACTOR),
-                                                                 (b>>RGB_FACTOR));
+                    (g>>RGB_FACTOR),
+                    (b>>RGB_FACTOR));
             rtgui_dc_draw_vline(dc, index, rect.y1, rect.y2);
             r += delta;
             g += delta;
@@ -1101,5 +1116,5 @@ void rtgui_theme_draw_win(struct rtgui_wintitle *wint)
         }
     }
 
-    rtgui_dc_end_drawing(dc);
+    rtgui_dc_end_drawing(dc, 1);
 }

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff