Просмотр исходного кода

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

bernard 8 лет назад
Родитель
Сommit
01108b5252
81 измененных файлов с 5496 добавлено и 3494 удалено
  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/dfs/KConfig"
 
 
+source "$RTT_DIR/components/net/KConfig"
+
 source "$RTT_DIR/components/drivers/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
 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/hz16font.c
 src/image.c
 src/image.c
 src/image_bmp.c
 src/image_bmp.c
+src/image_container.c
 src/image_hdc.c
 src/image_hdc.c
 src/image_jpg.c
 src/image_jpg.c
 src/image_png.c
 src/image_png.c

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

@@ -1,7 +1,7 @@
 /*
 /*
  * File      : blit.h
  * 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
  *  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
  *  it under the terms of the GNU General Public License as published by
@@ -47,6 +47,7 @@
 #define __RTGUI_BLIT_H__
 #define __RTGUI_BLIT_H__
 
 
 #include <rtgui/rtgui.h>
 #include <rtgui/rtgui.h>
+#include <rtgui/dc.h>
 
 
 /* Assemble R-G-B values into a specified pixel format and store them */
 /* Assemble R-G-B values into a specified pixel format and store them */
 #define RGB565_FROM_RGB(Pixel, r, g, b)                                 \
 #define RGB565_FROM_RGB(Pixel, r, g, b)                                 \
@@ -201,13 +202,13 @@ struct rtgui_blit_info
     rt_uint8_t r, g, b, a;
     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];
 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);
 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_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
 #endif
 
 

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : color.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : dc.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -23,7 +33,7 @@ extern "C" {
 #include <rtgui/driver.h>
 #include <rtgui/driver.h>
 #include <rtgui/widgets/widget.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
 #ifndef M_PI
 #define M_PI    3.14159265358979323846
 #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
  * 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:
  * There are several kinds of DC:
  * - Hardware DC;
  * - Hardware DC;
@@ -70,44 +80,49 @@ struct rtgui_dc
     const struct rtgui_dc_engine *engine;
     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
  * LCD device. The operations on the hardware DC are reflected to the real
- * hardware. 
- * 
+ * hardware.
+ *
  */
  */
 struct rtgui_dc_hw
 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.
  * All the operations on this device context is reflected to the memory buffer.
  */
  */
 struct rtgui_dc_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)
 #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 */
 /* create a buffer dc */
 struct rtgui_dc *rtgui_dc_buffer_create(int width, int height);
 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);
 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);
 struct rtgui_dc *rtgui_dc_buffer_create_from_dc(struct rtgui_dc* dc);
 
 
 /* create a widget 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 */
 /* begin and end a drawing */
 struct rtgui_dc *rtgui_dc_begin_drawing(rtgui_widget_t *owner);
 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 */
 /* destroy a dc */
 void rtgui_dc_destory(struct rtgui_dc *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);
 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);
 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_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);
 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
 #ifdef __cplusplus
 }
 }
 #endif
 #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
  *  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
  *  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__
 #ifndef __RTGUI_DC_TRANS_H__
 #define __RTGUI_DC_TRANS_H__
 #define __RTGUI_DC_TRANS_H__
 
 

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : driver.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -34,17 +44,17 @@ struct rtgui_graphic_driver_ops
 /* graphic extension operations */
 /* graphic extension operations */
 struct rtgui_graphic_ext_ops
 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
 struct rtgui_graphic_driver
@@ -63,7 +73,7 @@ struct rtgui_graphic_driver
     struct rt_device* device;
     struct rt_device* device;
 
 
     const struct rtgui_graphic_driver_ops *ops;
     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);
 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()
 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
 #ifdef RTGUI_USING_HW_CURSOR
@@ -86,8 +96,8 @@ rt_inline struct rtgui_graphic_driver *rtgui_graphic_get_device()
  */
  */
 enum rtgui_cursor_type
 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);
 void rtgui_cursor_set_device(const char* device_name);

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : event.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -41,6 +51,7 @@ enum _rtgui_event_type
     RTGUI_EVENT_WIN_CLOSE,             /* close a window        */
     RTGUI_EVENT_WIN_CLOSE,             /* close a window        */
     RTGUI_EVENT_WIN_MOVE,              /* move a window         */
     RTGUI_EVENT_WIN_MOVE,              /* move a window         */
     RTGUI_EVENT_WIN_RESIZE,            /* resize 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.
     RTGUI_EVENT_WIN_MODAL_ENTER,       /* the window is entering modal mode.
                                           This event should be sent after the
                                           This event should be sent after the
                                           window got setup and before the
                                           window got setup and before the
@@ -169,6 +180,13 @@ struct rtgui_event_win_resize
     rtgui_rect_t rect;
     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_destroy      rtgui_event_win
 #define rtgui_event_win_show         rtgui_event_win
 #define rtgui_event_win_show         rtgui_event_win
 #define rtgui_event_win_hide         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_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_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_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)
 #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)
 #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.
  * NOTE: There is not touch event to user applications, it's handled by server.
  */
  */
 struct rtgui_event_touch
 struct rtgui_event_touch

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : filerw.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : font.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -17,6 +27,7 @@
 #include <rtgui/rtgui.h>
 #include <rtgui/rtgui.h>
 #include <rtgui/list.h>
 #include <rtgui/list.h>
 
 
+
 #ifdef __cplusplus
 #ifdef __cplusplus
 extern "C" {
 extern "C" {
 #endif
 #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__
 #ifndef __FONT_FNT_H__
 #define __FONT_FNT_H__
 #define __FONT_FNT_H__
 
 
@@ -7,28 +31,28 @@
 /* fnt font header */
 /* fnt font header */
 struct fnt_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;
 typedef rt_uint8_t MWIMAGEBITS;
 
 
 struct fnt_font
 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;
 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__
 #ifndef __RTGUI_FONT_TTF_H__
 #define __RTGUI_FONT_TTF_H__
 #define __RTGUI_FONT_TTF_H__
 
 
@@ -8,7 +32,8 @@
 extern "C" {
 extern "C" {
 #endif
 #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);
 void rtgui_freetype_font_destroy(rtgui_font_t *font);
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : image.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : image_bmp.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -27,6 +37,21 @@ struct rtgui_image_hdcmm
     rt_uint8_t *pixels;
     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);
 void rtgui_image_hdc_init(void);
 extern const struct rtgui_image_engine rtgui_image_hdcmm_engine;
 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
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : list.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * 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__
 #ifndef __MATRIX_H__
 #define __MATRIX_H__
 #define __MATRIX_H__
 
 
@@ -12,7 +36,7 @@
  * this software and associated documentation files (the "Software"),  to deal in
  * this software and associated documentation files (the "Software"),  to deal in
  * the Software without restriction,  including without limitation the rights to
  * the Software without restriction,  including without limitation the rights to
  * use,  copy,  modify,  merge,  publish,  distribute,  sublicense,  and/or sell copies of
  * 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:
  * subject to the following conditions:
  *
  *
  * The above copyright notice and this permission notice shall be included in all
  * 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.
      * 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)
 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 *mm1,
                                 const struct rtgui_matrix *mm2)
                                 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. */
 /* Matrix multiply point[(p) = (x, y) * m], ignore the movement components. */
 rt_inline void rtgui_matrix_mul_point_nomove(struct rtgui_point *p,
 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;
     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. */
 /** Set @mm to an identity matrix. */
 rt_inline void rtgu_matrix_identity(struct rtgui_matrix *mm)
 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.
 /** Save the inversed matrix of @mm to @mo.

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : region.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -90,6 +100,7 @@ int rtgui_region_is_flat(rtgui_region_t *region);
 extern rtgui_rect_t rtgui_empty_rect;
 extern rtgui_rect_t rtgui_empty_rect;
 
 
 void rtgui_rect_moveto(rtgui_rect_t *rect, int x, int y);
 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_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_inflate(rtgui_rect_t *rect, int d);
 void rtgui_rect_intersect(rtgui_rect_t *src, rtgui_rect_t *dest);
 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);
 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);
 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);
 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)
 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)	\
 #define RTGUI_RECT(rect, x, y, w, h)	\

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

@@ -1,7 +1,7 @@
 /*
 /*
  * File      : rtgui.h
  * 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
  *  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
  *  it under the terms of the GNU General Public License as published by
@@ -31,19 +31,10 @@
 extern "C" {
 extern "C" {
 #endif
 #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. */
 /* MDK, GCC and MSVC all support __restrict keyword. */
 #define RTGUI_RESTRICT      __restrict
 #define RTGUI_RESTRICT      __restrict
@@ -136,13 +127,13 @@ enum RTGUI_BORDER_STYLE
 
 
 /**
 /**
  * Blend mode
  * Blend mode
- */ 
+ */
 enum RTGUI_BLENDMODE
 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
 enum RTGUI_MODAL_CODE
 {
 {
     RTGUI_MODAL_OK,
     RTGUI_MODAL_OK,
-    RTGUI_MODAL_CANCEL
+    RTGUI_MODAL_CANCEL,
+    RTGUI_MODAL_MAX = 0xFFFF,
 };
 };
 typedef enum RTGUI_MODAL_CODE rtgui_modal_code_t;
 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
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : rtgui_config.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : rtgui_object.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * 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);
 const rtgui_type_t *rtgui_object_object_type_get(rtgui_object_t *object);
 
 
 #ifdef RTGUI_USING_CAST_CHECK
 #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__))
 	 	((c_type *)rtgui_object_check_cast((rtgui_object_t *)(obj), (obj_type), __FUNCTION__, __LINE__))
 #else
 #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
 #endif
 
 
 #define RTGUI_OBJECT_CHECK_TYPE(_obj, _type) \
 #define RTGUI_OBJECT_CHECK_TYPE(_obj, _type) \

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : rtgui_server.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -14,6 +24,10 @@
 #ifndef __RTGUI_SERVER_H__
 #ifndef __RTGUI_SERVER_H__
 #define __RTGUI_SERVER_H__
 #define __RTGUI_SERVER_H__
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include <rtservice.h>
 #include <rtservice.h>
 #include <rtgui/list.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));
 void rtgui_server_install_act_win_hook(void (*hk)(void));
 
 
 /* post an event to server */
 /* 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);
 rt_err_t rtgui_server_post_event_sync(struct rtgui_event *event, rt_size_t size);
 
 
+#ifdef __cplusplus
+}
 #endif
 #endif
 
 
+#endif

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : rtgui_system.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : box.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : container.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : title.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes

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

@@ -1,7 +1,7 @@
 /*
 /*
  * File      : widget.h
  * 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
  *  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
  *  it under the terms of the GNU General Public License as published by
@@ -110,6 +110,10 @@ struct rtgui_widget
 
 
     /* the widget extent */
     /* the widget extent */
     rtgui_rect_t 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 */
     /* minimal width and height of widget */
     rt_int16_t min_width, min_height;
     rt_int16_t min_width, min_height;
@@ -117,13 +121,10 @@ struct rtgui_widget
     rt_int32_t align;
     rt_int32_t align;
     rt_uint16_t border;
     rt_uint16_t border;
     rt_uint16_t border_style;
     rt_uint16_t border_style;
-    /* the rect clip */
-    rtgui_region_t clip;
 
 
     /* call back */
     /* call back */
     rt_bool_t (*on_focus_in)(struct rtgui_object *widget, struct rtgui_event *event);
     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_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 */
     /* user private data */
     rt_uint32_t user_data;
     rt_uint32_t user_data;
@@ -142,7 +143,6 @@ void rtgui_widget_unfocus(rtgui_widget_t *widget);
 /* event handler for each command */
 /* event handler for each command */
 void rtgui_widget_set_onfocus(rtgui_widget_t *widget, rtgui_event_handler_ptr handler);
 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_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 */
 /* get and set rect of widget */
 void rtgui_widget_get_rect(rtgui_widget_t *widget, rtgui_rect_t *rect);
 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
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -80,6 +90,7 @@ struct rtgui_win
 
 
     /* drawing count */
     /* drawing count */
     rt_base_t drawing;
     rt_base_t drawing;
+    struct rtgui_rect drawing_rect;
 
 
     /* parent window. RT_NULL if the window is a top level window */
     /* parent window. RT_NULL if the window is a top level window */
     struct rtgui_win *parent_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);
 void rtgui_win_destroy(rtgui_win_t *win);
 
 
 int rtgui_win_init(struct rtgui_win *win, struct rtgui_win *parent_window,
 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);
 int rtgui_win_fini(struct rtgui_win* win);
 
 
 /** Close window.
 /** 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_topmost_shown(void);
 struct rtgui_win* rtgui_win_get_next_shown(void);
 struct rtgui_win* rtgui_win_get_next_shown(void);
 
 
+void rtgui_theme_draw_win(struct rtgui_wintitle *wint);
+
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }
 #endif
 #endif

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : asc12font.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : asc16font.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -16,262 +26,262 @@
 #ifdef RTGUI_USING_FONT16
 #ifdef RTGUI_USING_FONT16
 const unsigned char asc16_font[] =
 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 =
 struct rtgui_font_bitmap asc16 =

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

@@ -1,7 +1,7 @@
 /*
 /*
  * File      : blit.h
  * 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
  *  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
  *  it under the terms of the GNU General Public License as published by
@@ -48,62 +48,74 @@
 #include <rtgui/rtgui.h>
 #include <rtgui/rtgui.h>
 #include <rtgui/blit.h>
 #include <rtgui/blit.h>
 #include <rtgui/color.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 */
 /* 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_0,
     lookup_1,
     lookup_1,
     lookup_2,
     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_uint32_t *srcp = (rt_uint32_t *) src_ptr;
     rt_uint16_t *dstp = (rt_uint16_t *) dst_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)
 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 */
 /* 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,
     0x00000000, 0xff000000, 0x00000008, 0xff002000,
     0x00000010, 0xff004000, 0x00000018, 0xff006100,
     0x00000010, 0xff004000, 0x00000018, 0xff006100,
     0x00000020, 0xff008100, 0x00000029, 0xff00a100,
     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 */
 /* 16bpp special case for per-surface alpha=50%: blend 2 pixels in parallel */
 /* blend a single 16 bit pixel at 50% */
 /* 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% */
 /* 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
 static void
 Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask)
 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;
     rt_uint16_t *dstp = (rt_uint16_t *) info->dst;
     int dstskip = info->dst_skip >> 1;
     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.
              * Source and destination not aligned, pipeline it.
              * This is mostly a win for big blits but no loss for
              * 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;
             int w = width;
 
 
             /* handle odd destination */
             /* handle odd destination */
-            if ((unsigned int) dstp & 2) {
+            if ((unsigned int) dstp & 2)
+            {
                 rt_uint16_t d = *dstp, s = *srcp;
                 rt_uint16_t d = *dstp, s = *srcp;
                 *dstp = BLEND16_50(d, s, mask);
                 *dstp = BLEND16_50(d, s, mask);
                 dstp++;
                 dstp++;
@@ -676,7 +697,8 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask)
             /* bootstrap pipeline with first halfword */
             /* bootstrap pipeline with first halfword */
             prev_sw = ((rt_uint32_t *) srcp)[-1];
             prev_sw = ((rt_uint32_t *) srcp)[-1];
 
 
-            while (w > 1) {
+            while (w > 1)
+            {
                 rt_uint32_t sw, dw, s;
                 rt_uint32_t sw, dw, s;
                 sw = *(rt_uint32_t *) srcp;
                 sw = *(rt_uint32_t *) srcp;
                 dw = *(rt_uint32_t *) dstp;
                 dw = *(rt_uint32_t *) dstp;
@@ -689,7 +711,8 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask)
             }
             }
 
 
             /* final pixel if any */
             /* final pixel if any */
-            if (w) {
+            if (w)
+            {
                 rt_uint16_t d = *dstp, s;
                 rt_uint16_t d = *dstp, s;
                 s = (rt_uint16_t) (prev_sw >> 16);
                 s = (rt_uint16_t) (prev_sw >> 16);
                 *dstp = BLEND16_50(d, s, mask);
                 *dstp = BLEND16_50(d, s, mask);
@@ -698,12 +721,15 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask)
             }
             }
             srcp += srcskip - 1;
             srcp += srcskip - 1;
             dstp += dstskip;
             dstp += dstskip;
-        } else {
+        }
+        else
+        {
             /* source and destination are aligned */
             /* source and destination are aligned */
             int w = width;
             int w = width;
 
 
             /* first odd pixel? */
             /* first odd pixel? */
-            if ((unsigned int) srcp & 2) {
+            if ((unsigned int) srcp & 2)
+            {
                 rt_uint16_t d = *dstp, s = *srcp;
                 rt_uint16_t d = *dstp, s = *srcp;
                 *dstp = BLEND16_50(d, s, mask);
                 *dstp = BLEND16_50(d, s, mask);
                 srcp++;
                 srcp++;
@@ -712,7 +738,8 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask)
             }
             }
             /* srcp and dstp are now 32-bit aligned */
             /* 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 sw = *(rt_uint32_t *) srcp;
                 rt_uint32_t dw = *(rt_uint32_t *) dstp;
                 rt_uint32_t dw = *(rt_uint32_t *) dstp;
                 *(rt_uint32_t *) dstp = BLEND2x16_50(dw, sw, mask);
                 *(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? */
             /* last odd pixel? */
-            if (w) {
+            if (w)
+            {
                 rt_uint16_t d = *dstp, s = *srcp;
                 rt_uint16_t d = *dstp, s = *srcp;
                 *dstp = BLEND16_50(d, s, mask);
                 *dstp = BLEND16_50(d, s, mask);
                 srcp++;
                 srcp++;
@@ -774,7 +802,8 @@ Blit565to565PixelAlpha(struct rtgui_blit_info * info)
         rt_uint32_t *srcp = (rt_uint32_t *) info->src;
         rt_uint32_t *srcp = (rt_uint32_t *) info->src;
         rt_uint32_t *dstp = (rt_uint32_t *) info->dst;
         rt_uint32_t *dstp = (rt_uint32_t *) info->dst;
 
 
-        while (height--) {
+        while (height--)
+        {
             DUFFS_LOOP4(
             DUFFS_LOOP4(
             {
             {
                 rt_uint32_t s = *srcp++;
                 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 */
 /* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */
 static void BlitRGBtoRGBSurfaceAlpha128(struct rtgui_blit_info *info)
 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 */
 /* fast RGB888->(A)RGB888 blending with surface alpha */
 static void BlitRGBtoRGBSurfaceAlpha(struct rtgui_blit_info *info)
 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 */
 /* 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;
     rt_uint16_t *dstp = (rt_uint16_t *) info->dst;
     int dstskip = info->dst_skip >> 1;
     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;
         srcp += srcskip;
         dstp += dstskip;
         dstp += dstskip;
     }
     }
@@ -920,49 +1033,120 @@ static void BlitARGBto565PixelAlpha(struct rtgui_blit_info * info)
 /* fast ARGB888->(A)RGB888 blending with pixel alpha */
 /* fast ARGB888->(A)RGB888 blending with pixel alpha */
 static void BlitRGBtoRGBPixelAlpha(struct rtgui_blit_info *info)
 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)
 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 dstpixel;
     rt_uint32_t dstR, dstG, dstB, dstA;
     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 *src = (rt_uint32_t *)info->src;
         rt_uint32_t *dst = (rt_uint32_t *)info->dst;
         rt_uint32_t *dst = (rt_uint32_t *)info->dst;
         int n = info->dst_w;
         int n = info->dst_w;
-        while (n--) {
+        while (n--)
+        {
             srcpixel = *src;
             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;
             ++src;
             ++dst;
             ++dst;
         }
         }
@@ -1015,7 +1226,8 @@ BlitRGB565to32(struct rtgui_blit_info * info, const rt_uint32_t* map)
     dst = (rt_uint32_t *) info->dst;
     dst = (rt_uint32_t *) info->dst;
     dstskip = info->dst_skip / 4;
     dstskip = info->dst_skip / 4;
 
 
-    while (height--) {
+    while (height--)
+    {
         /* *INDENT-OFF* */
         /* *INDENT-OFF* */
         DUFFS_LOOP(
         DUFFS_LOOP(
         {
         {
@@ -1049,7 +1261,7 @@ void rtgui_blit(struct rtgui_blit_info * info)
     {
     {
         info->dst_w = info->src_w;
         info->dst_w = info->src_w;
         info->dst_skip  = info->dst_pitch - info->dst_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)
     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)
     if (info->src_h < info->dst_h)
         info->dst_h = info->src_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)
     else if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB888)
     {
     {
         if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888)
         if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888)
             BlitRGBtoRGBSurfaceAlpha(info);
             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);
 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
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : color.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : container.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -49,15 +59,41 @@ rt_bool_t rtgui_container_dispatch_event(rtgui_container_t *container, rtgui_eve
 {
 {
     /* handle in child widget */
     /* handle in child widget */
     struct rtgui_list_node *node;
     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))
     rtgui_list_foreach(node, &(container->children))
     {
     {
         struct rtgui_widget *w;
         struct rtgui_widget *w;
         w = rtgui_list_entry(node, struct rtgui_widget, sibling);
         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 &&
         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_TRUE;
+        }
     }
     }
 
 
     return RT_FALSE;
     return RT_FALSE;
@@ -140,7 +176,7 @@ rt_bool_t rtgui_container_event_handler(struct rtgui_object *object, struct rtgu
         /* paint on each child */
         /* paint on each child */
         rtgui_container_dispatch_event(container, event);
         rtgui_container_dispatch_event(container, event);
 
 
-        rtgui_dc_end_drawing(dc);
+        rtgui_dc_end_drawing(dc, 1);
     }
     }
     break;
     break;
 
 
@@ -158,8 +194,8 @@ rt_bool_t rtgui_container_event_handler(struct rtgui_object *object, struct rtgu
         rtgui_container_dispatch_event(container, event);
         rtgui_container_dispatch_event(container, event);
         break;
         break;
     case RTGUI_EVENT_HIDE:
     case RTGUI_EVENT_HIDE:
-        rtgui_widget_onhide(RTGUI_OBJECT(container), event);
         rtgui_container_dispatch_event(container, event);
         rtgui_container_dispatch_event(container, event);
+        rtgui_widget_onhide(RTGUI_OBJECT(container), event);
         break;
         break;
     case RTGUI_EVENT_COMMAND:
     case RTGUI_EVENT_COMMAND:
         rtgui_container_dispatch_event(container, event);
         rtgui_container_dispatch_event(container, event);

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : dc.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -19,8 +29,6 @@
 #include <math.h>
 #include <math.h>
 
 
 #include <rtgui/dc.h>
 #include <rtgui/dc.h>
-#include <rtgui/dc_hw.h>
-#include <rtgui/dc_client.h>
 
 
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_server.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
      * 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
     drawoct = 0; // 0x00000000
     // whether or not to keep drawing a given octant.
     // whether or not to keep drawing a given octant.
     // For example: 0x00111100 means we're drawing in octants 2-5
     // 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);
 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,
 static void _draw_octant(struct rtgui_dc *dc,
                          rt_int16_t ox, rt_int16_t oy,
                          rt_int16_t ox, rt_int16_t oy,
                          rt_int16_t y1, rt_int16_t y2, rt_int16_t x, int oct)
                          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;
         return RT_NULL;
 
 
     /* increase drawing count */
     /* increase drawing count */
+    if (win->drawing == 0)
+    {
+        memset(&(win->drawing_rect), 0x0, sizeof(struct rtgui_rect));
+    }
     win->drawing ++;
     win->drawing ++;
 
 
     /* always drawing on the virtual mode */
     /* 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);
 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_widget *owner;
     struct rtgui_win *win;
     struct rtgui_win *win;
@@ -1889,30 +1902,47 @@ void rtgui_dc_end_drawing(struct rtgui_dc *dc)
     /* get window */
     /* get window */
     win = owner->toplevel;
     win = owner->toplevel;
 
 
+    /* union drawing rect */
+    rtgui_rect_union(&(owner->extent_visiable), &(win->drawing_rect));
     /* decrease drawing counter */
     /* 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();
     rtgui_screen_unlock();
 }
 }
 RTM_EXPORT(rtgui_dc_end_drawing);
 RTM_EXPORT(rtgui_dc_end_drawing);
-

Разница между файлами не показана из-за своего большого размера
+ 381 - 314
components/gui/src/dc_blend.c


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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : dc_buffer.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -14,11 +24,10 @@
 #include <rtgui/rtgui.h>
 #include <rtgui/rtgui.h>
 #include <rtgui/dc.h>
 #include <rtgui/dc.h>
 #include <rtgui/blit.h>
 #include <rtgui/blit.h>
-#include <rtgui/dc_hw.h>
 #include <rtgui/color.h>
 #include <rtgui/color.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/dc_draw.h>
 #include <rtgui/dc_draw.h>
-
+#include <rtgui/image_container.h>
 #include <string.h>
 #include <string.h>
 
 
 static rt_bool_t rtgui_dc_buffer_fini(struct rtgui_dc *dc);
 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,
     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)  \
 #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)
 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);
 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 *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);
 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 *rtgui_dc_buffer_create_from_dc(struct rtgui_dc* dc)
 {
 {
     struct rtgui_dc_buffer *buffer;
     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 clone */
         buffer = (struct rtgui_dc_buffer*)rtgui_dc_buffer_create_pixformat(d->pixel_format,
         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)
         if (buffer != RT_NULL)
         {
         {
             rt_memcpy(buffer->pixel, d->pixel, d->pitch * d->height);
             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;
     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;
     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 */
     /* does not draw point out of dc */
     if ((x >= dst->width) || (y >= dst->height)) return;
     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)
 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)
 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 (x1 < 0 || x1 >= dst->width) return;
     if (y1 >= dst->height) return;
     if (y1 >= dst->height) return;
 
 
-	if (y1 < 0) y1 = 0;
+    if (y1 < 0) y1 = 0;
     if (y2 > dst->height) y2 = dst->height;
     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)
 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;
     dst = (struct rtgui_dc_buffer *)self;
 
 
-	/* parameter checking */
+    /* parameter checking */
     if (y1 < 0 || y1 >= dst->height) return;
     if (y1 < 0 || y1 >= dst->height) return;
     if (x1 >= dst->width) return;
     if (x1 >= dst->width) return;
 
 
-	if (x1 < 0) x1 = 0;
+    if (x1 < 0) x1 = 0;
     if (x2 > dst->width) x2 = dst->width;
     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)
 static void rtgui_dc_buffer_fill_rect(struct rtgui_dc *self, struct rtgui_rect *dst_rect)
 {
 {
     struct rtgui_dc_buffer *dst;
     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);
     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;
     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)
     if (_r.x1 >= dst->width)
         return;
         return;
     else if (_r.x1 < 0)
     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;
         _r.y1 = 0;
     if (_r.y2 > dst->height)
     if (_r.y2 > dst->height)
         _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 */
 /* blit a dc to another dc */
@@ -343,16 +395,16 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc *self,
                                  struct rtgui_dc *dest,
                                  struct rtgui_dc *dest,
                                  rtgui_rect_t *rect)
                                  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_point dc_point;
     struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer *)self;
     struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer *)self;
 
 
     if (rtgui_dc_get_visible(dest) == RT_FALSE)
     if (rtgui_dc_get_visible(dest) == RT_FALSE)
         return;
         return;
 
 
-	/* use the (0,0) origin point */
+    /* use the (0,0) origin point */
     if (dc_pt == RT_NULL)
     if (dc_pt == RT_NULL)
         dc_point = rtgui_empty_point;
         dc_point = rtgui_empty_point;
     else
     else
@@ -361,12 +413,12 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc *self,
     }
     }
 
 
     rtgui_dc_get_rect(dest, &_rect);
     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;
         dest_rect = rect;
         if (dest_rect->x1 >= _rect.x2 || dest_rect->y1 >= _rect.y2)
         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;
             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;
     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))
     if ((dest->type == RTGUI_DC_HW) || (dest->type == RTGUI_DC_CLIENT))
     {
     {
-		int index;
+        int index;
         rt_uint8_t *line_ptr, *pixels;
         rt_uint8_t *line_ptr, *pixels;
         rtgui_blit_line_func blit_line;
         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 */
         /* 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
         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)
 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;
     struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer *)self;
 
 
     RT_ASSERT(dc != RT_NULL);
     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)
     if (x2 >= dc->width)
         x2 = dc->width-1;
         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));
     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
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -16,8 +26,6 @@
  * 2010-09-14     Bernard      fix vline and hline coordinate issue
  * 2010-09-14     Bernard      fix vline and hline coordinate issue
  */
  */
 #include <rtgui/dc.h>
 #include <rtgui/dc.h>
-#include <rtgui/dc_hw.h>
-#include <rtgui/dc_client.h>
 
 
 #include <rtgui/driver.h>
 #include <rtgui/driver.h>
 #include <rtgui/rtgui_system.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;
     rtgui_widget_t *owner;
 
 
     if (self == RT_NULL) return;
     if (self == RT_NULL) return;
-	if (!rtgui_dc_get_visible(self)) return;
+    if (!rtgui_dc_get_visible(self)) return;
 
 
     /* get owner */
     /* get owner */
     owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
     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;
     rtgui_widget_t *owner;
 
 
     if (self == RT_NULL) return;
     if (self == RT_NULL) return;
-	if (!rtgui_dc_get_visible(self)) return;
+    if (!rtgui_dc_get_visible(self)) return;
 
 
     /* get owner */
     /* get owner */
     owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
     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;
     rtgui_widget_t *owner;
 
 
     if (self == RT_NULL) return;
     if (self == RT_NULL) return;
-	if (!rtgui_dc_get_visible(self)) return;
+    if (!rtgui_dc_get_visible(self)) return;
 
 
     /* get owner */
     /* get owner */
     owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
     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);
         hw_driver->ops->draw_vline(&(owner->gc.foreground), x, y1, y2);
     }
     }
     else
     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;
     rtgui_widget_t *owner;
 
 
     if (self == RT_NULL) return;
     if (self == RT_NULL) return;
-	if (!rtgui_dc_get_visible(self)) return;
+    if (!rtgui_dc_get_visible(self)) return;
 
 
     /* get owner */
     /* get owner */
     owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
     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);
         hw_driver->ops->draw_hline(&(owner->gc.foreground), x1, x2, y);
     }
     }
     else
     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;
             rtgui_rect_t *prect;
             register rt_base_t draw_x1, draw_x2;
             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(self);
     RT_ASSERT(rect);
     RT_ASSERT(rect);
 
 
-	if (!rtgui_dc_get_visible(self)) return;
+    if (!rtgui_dc_get_visible(self)) return;
 
 
     /* get owner */
     /* get owner */
     owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
     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;
     rtgui_widget_t *owner;
 
 
     if (self == RT_NULL) return;
     if (self == RT_NULL) return;
-	if (!rtgui_dc_get_visible(self)) return;
+    if (!rtgui_dc_get_visible(self)) return;
 
 
     /* get owner */
     /* get owner */
     owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type);
     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);
         hw_driver->ops->draw_raw_hline(line_data + offset, x1, x2, y);
     }
     }
     else
     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;
             rtgui_rect_t *prect;
             register rt_base_t draw_x1, draw_x2;
             register rt_base_t draw_x1, draw_x2;

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

@@ -1,18 +1,27 @@
 /*
 /*
  * File      : dc_hw.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
  * 2009-10-16     Bernard      first version
  * 2009-10-16     Bernard      first version
  */
  */
 #include <rtgui/dc.h>
 #include <rtgui/dc.h>
-#include <rtgui/dc_hw.h>
 #include <rtgui/driver.h>
 #include <rtgui/driver.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_app.h>
 #include <rtgui/rtgui_app.h>
@@ -54,17 +63,17 @@ struct rtgui_dc *rtgui_dc_hw_create(rtgui_widget_t *owner)
 
 
     /* create DC */
     /* create DC */
     dc = (struct rtgui_dc_hw *) rtgui_malloc(sizeof(struct rtgui_dc_hw));
     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)
 static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc *dc)

Разница между файлами не показана из-за своего большого размера
+ 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.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/dc.h>
 #include <rtgui/dc.h>
@@ -91,7 +115,7 @@ void rtgui_dc_trans_get_new_wh(struct rtgui_dc_trans *dct,
                                   &dct->m);
                                   &dct->m);
     /* Transform result of (w, 0). */
     /* Transform result of (w, 0). */
     rtgui_matrix_mul_point_nomove(&bottomright,
     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). */
     /* Transform result of (0, 0) is always (0, 0). */
 
 
 #define NORMALIZE(x) do { if (x < 0) x = 0; } while (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);
         NORMALIZE(bottomright.x);
 
 
         neww = _UI_MAX(topright.x, _UI_ABS(topleft.x - bottomright.x))
         neww = _UI_MAX(topright.x, _UI_ABS(topleft.x - bottomright.x))
-            + dct->m.m[4];
+               + dct->m.m[4];
         NORMALIZE(neww);
         NORMALIZE(neww);
 
 
         *new_wp = neww;
         *new_wp = neww;
@@ -119,7 +143,7 @@ void rtgui_dc_trans_get_new_wh(struct rtgui_dc_trans *dct,
         NORMALIZE(bottomright.y);
         NORMALIZE(bottomright.y);
 
 
         newh = _UI_MAX(topright.y, _UI_ABS(topleft.y - bottomright.y))
         newh = _UI_MAX(topright.y, _UI_ABS(topleft.y - bottomright.y))
-            + dct->m.m[5];
+               + dct->m.m[5];
         NORMALIZE(newh);
         NORMALIZE(newh);
 
 
         *new_hp = 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. */
 /* FrameRect to FrameRect, from ARGB8888 to RGB565. */
 static void _blit_rotate_FR2FR_ARGB2RGB565(struct _fb_rect* RTGUI_RESTRICT src,
 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_uint32_t* RTGUI_RESTRICT srcp = (rt_uint32_t*)src->fb;
     rt_uint16_t* RTGUI_RESTRICT dstp = (rt_uint16_t*)dst->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
                  * and blend all components at the same time
                  */
                  */
                 op = ((op & 0xfc00) << 11) + (op >> 8 & 0xf800)
                 op = ((op & 0xfc00) << 11) + (op >> 8 & 0xf800)
-                    + (op >> 3 & 0x1f);
+                     + (op >> 3 & 0x1f);
                 d = (d | d << 16) & 0x07e0f81f;
                 d = (d | d << 16) & 0x07e0f81f;
                 d += (op - d) * alpha >> 5;
                 d += (op - d) * alpha >> 5;
                 d &= 0x07e0f81f;
                 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. */
 /* FrameRect to FrameRect, from ARGB8888 to RGB565. */
 static void _blit_rotate_FR2FR_ARGB2RGB565_AA(struct _fb_rect* RTGUI_RESTRICT src,
 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_uint32_t* RTGUI_RESTRICT srcp = (rt_uint32_t*)src->fb;
     rt_uint16_t* RTGUI_RESTRICT dstp = (rt_uint16_t*)dst->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)
     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:
         case 2:
             if (dct->use_aa)
             if (dct->use_aa)
                 _blit_rotate_FR2FR_SF2B_AA(&srcfb, dc_point,
                 _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)
     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:
         case 2:
             if (dct->use_aa)
             if (dct->use_aa)
                 _blit_rotate_FR2FR_SF2B_AA(&srcfb, dc_point,
                 _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 (dct->owner->type == RTGUI_DC_BUFFER)
     {
     {
         if (dest->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)
         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)
         else if (dest->type == RTGUI_DC_CLIENT)
             // TODO:
             // TODO:
             ;
             ;

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : filerw.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : font.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * 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;
     return RT_NULL;
 }
 }
 RTM_EXPORT(rtgui_font_refer);
 RTM_EXPORT(rtgui_font_refer);

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : font.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * 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;
     const rt_uint8_t *font_ptr;
     int x, y, w, h, style;
     int x, y, w, h, style;
     register rt_base_t i, j, /*k,*/ word_bytes;
     register rt_base_t i, j, /*k,*/ word_bytes;
-	struct rtgui_rect dc_rect;
-	
+    struct rtgui_rect dc_rect;
+
     /* check first and last char */
     /* check first and last char */
     if (ch < font->first_char || ch > font->last_char) return;
     if (ch < font->first_char || ch > font->last_char) return;
 
 
     /* get text style */
     /* get text style */
     style = rtgui_dc_get_gc(dc)->textstyle;
     style = rtgui_dc_get_gc(dc)->textstyle;
     bc = rtgui_dc_get_gc(dc)->background;
     bc = rtgui_dc_get_gc(dc)->background;
-	rtgui_dc_get_rect(dc, &dc_rect);
+    rtgui_dc_get_rect(dc, &dc_rect);
 
 
     x = rect->x1;
     x = rect->x1;
     y = rect->y1;
     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;
         rt_uint8_t chr = 0;
         const rt_uint8_t *ptr = font_ptr + i * word_bytes;
         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++)
         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);
     RT_ASSERT(bmp_font != RT_NULL);
 
 
-	/* parameter check */
+    /* parameter check */
     if (rect->y1 > rect->y2) return;
     if (rect->y1 > rect->y2) return;
 
 
 #ifdef RTGUI_USING_FONTHZ
 #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/font_fnt.h>
 #include <rtgui/rtgui_system.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);
 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 =
 const struct rtgui_font_engine fnt_font_engine =
 {
 {
-	RT_NULL,
-	RT_NULL,
+    RT_NULL,
+    RT_NULL,
     rtgui_fnt_font_draw_text,
     rtgui_fnt_font_draw_text,
     rtgui_fnt_font_get_metrics
     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)
 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)
 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
 #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)
 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)
 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)
 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)
 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)
 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:
 __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
 #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>
 #include <rtthread.h>
 
 
 #ifdef RTGUI_USING_TTF
 #ifdef RTGUI_USING_TTF
 #include <rtgui/rtgui.h>
 #include <rtgui/rtgui.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/dc.h>
 #include <rtgui/dc.h>
+#include <rtgui/blit.h>
 #include <rtgui/font.h>
 #include <rtgui/font.h>
+#include <rtgui/font_freetype.h>
 
 
+#include <ftcache.h>
 #include <ft2build.h>
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #include FT_FREETYPE_H
 
 
@@ -25,31 +52,8 @@
 #define PINFO(...)
 #define PINFO(...)
 #endif
 #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)
 #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);
 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';
     *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,
                           struct rtgui_dc *dc,
                           const char *text,
                           const char *text,
                           rt_ubase_t len,
                           rt_ubase_t len,
                           struct rtgui_rect *rect)
                           struct rtgui_rect *rect)
 {
 {
     rt_uint16_t *text_short;
     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 begin_x, btm_y;
     rt_int16_t topy;
     rt_int16_t topy;
     rt_uint8_t r, g, b;
     rt_uint8_t r, g, b;
     rtgui_color_t fgc;
     rtgui_color_t fgc;
+    struct rtgui_rect text_rect;
 
 
     RT_ASSERT(font != RT_NULL);
     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 */
     /* allocate unicode buffer */
     text_short = (rt_uint16_t *)rtgui_malloc((len + 1) * 2);
     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);
     g = RTGUI_RGB_G(fgc);
     b = RTGUI_RGB_B(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)
     if (btm_y <= 0)
         return;
         return;
-    begin_x = rect->x1;
+    begin_x = text_rect.x1;
 
 
     if (dc->type == RTGUI_DC_BUFFER)
     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)
         if (begin_x >= bdc->width || topy >= bdc->height)
         {
         {
             goto _out;
             goto _out;
         }
         }
     }
     }
-	else if (dc->type == RTGUI_DC_HW)
-	{
+    else if (dc->type == RTGUI_DC_HW)
+    {
         int x, y;
         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;
             goto _out;
-		if (y >= hdc->owner->extent.y2)
+        if (y >= hdc->owner->extent.y2)
             goto _out;
             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:
 _out:
     /* release unicode buffer */
     /* release unicode buffer */
     rtgui_free(text_short);
     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)
     while (*text_short)
     {
     {
         FT_Error err = 0;
         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 ++;
         text_short ++;
     }
     }
 
 
     rect->x1 = 0;
     rect->x1 = 0;
-    rect->y1 = 0;
+    rect->y1 = btm;
     rect->x2 = w;
     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;
     int len;
     rt_uint16_t *text_short;
     rt_uint16_t *text_short;
-    struct rtgui_freetype2_font *fft;
+    struct rtgui_ttf_font *ttf_font;
 
 
     RT_ASSERT(font != RT_NULL);
     RT_ASSERT(font != RT_NULL);
     RT_ASSERT(rect != 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);
     len = strlen(text);
     memset(rect, 0, sizeof(struct rtgui_rect));
     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 */
     /* convert gbk to unicode */
     gbk_to_unicode(text_short, text, len);
     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 */
     /* release unicode buffer */
     rtgui_free(text_short);
     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;
     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;
         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)
     if (err)
     {
     {
-        PERROR("failed to Init FreeType: %d\n", err);
+        PERROR("FT_Init_FreeType failed err: %d\n", err);
         goto _err_done_malloc;
         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;
         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)
     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 */
     /* 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->refer_count = 1;
-    font->engine = &ftf_engine;
+    font->engine = &ftc_engine;
 
 
     /* add to system */
     /* add to system */
     rtgui_font_system_add_font(font);
     rtgui_font_system_add_font(font);
 
 
     return 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);
 RTM_EXPORT(rtgui_freetype_font_create);
 
 
 void rtgui_freetype_font_destroy(rtgui_font_t *font)
 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);
     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);
     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);
     rtgui_free(font);
 }
 }
 RTM_EXPORT(rtgui_freetype_font_destroy);
 RTM_EXPORT(rtgui_freetype_font_destroy);
 
 
 #ifdef RT_USING_FINSH
 #ifdef RT_USING_FINSH
 #include <finsh.h>
 #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
-
 #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/dc.h>
 #include <rtgui/font.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
  * 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>
 #include <rtgui/font.h>
 
 
 #if defined(RTGUI_USING_FONT12) && defined(RTGUI_USING_FONTHZ)
 #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>
 #include <rtgui/font.h>
 
 
 #if defined(RTGUI_USING_FONT16) && defined(RTGUI_USING_FONTHZ)
 #if defined(RTGUI_USING_FONT16) && defined(RTGUI_USING_FONTHZ)

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : image.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -18,6 +28,7 @@
 
 
 #include <rtgui/image_hdc.h>
 #include <rtgui/image_hdc.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
+#include <rtgui/image_container.h>
 
 
 #include <string.h>
 #include <string.h>
 #ifdef _WIN32
 #ifdef _WIN32
@@ -25,17 +36,18 @@
 #endif
 #endif
 
 
 #ifdef RTGUI_IMAGE_XPM
 #ifdef RTGUI_IMAGE_XPM
-#include <rtgui/image_xpm.h>
+extern void rtgui_image_xpm_init(void);
 #endif
 #endif
 
 
 #ifdef RTGUI_IMAGE_BMP
 #ifdef RTGUI_IMAGE_BMP
 #include <rtgui/image_bmp.h>
 #include <rtgui/image_bmp.h>
 #endif
 #endif
+
 #if (defined(RTGUI_IMAGE_JPEG) || defined(RTGUI_IMAGE_TJPGD))
 #if (defined(RTGUI_IMAGE_JPEG) || defined(RTGUI_IMAGE_TJPGD))
-#include <rtgui/image_jpeg.h>
+extern void rtgui_image_jpeg_init(void);
 #endif
 #endif
 #if defined(RTGUI_IMAGE_PNG) || defined(RTGUI_IMAGE_LODEPNG)
 #if defined(RTGUI_IMAGE_PNG) || defined(RTGUI_IMAGE_LODEPNG)
-#include <rtgui/image_png.h>
+extern void rtgui_image_png_init(void);
 #endif
 #endif
 
 
 static rtgui_list_t _rtgui_system_image_list = {RT_NULL};
 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)
 #if defined(RTGUI_IMAGE_PNG) || defined(RTGUI_IMAGE_LODEPNG)
     rtgui_image_png_init();
     rtgui_image_png_init();
 #endif
 #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)
 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 */
     /* create filerw context */
     filerw = rtgui_filerw_create_file(filename, "rb");
     filerw = rtgui_filerw_create_file(filename, "rb");
-    if (filerw == RT_NULL) 
+    if (filerw == RT_NULL)
     {
     {
         rt_kprintf("create filerw failed!\n");
         rt_kprintf("create filerw failed!\n");
         return RT_NULL;
         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)
 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);
     RT_ASSERT(dc    != RT_NULL);
 
 
     if (rtgui_dc_get_visible(dc) != RT_TRUE) return;
     if (rtgui_dc_get_visible(dc) != RT_TRUE) return;
 
 
     rtgui_dc_get_rect(dc, &r);
     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
     else
     {
     {
         /* Don't modify x1, y1, they are handled in engine->image_blit. */
         /* 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
  * 2012-01-24     onelife      Reimplement to improve efficiency and add
  * 2012-01-24     onelife      Reimplement to improve efficiency and add
@@ -6,7 +24,7 @@
  *  provides scaledown function.
  *  provides scaledown function.
  */
  */
 #include <rtthread.h>
 #include <rtthread.h>
-#include <rtgui/dc_hw.h>
+#include <rtgui/dc.h>
 #include <rtgui/image.h>
 #include <rtgui/image.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/image_bmp.h>
 #include <rtgui/image_bmp.h>
@@ -127,7 +145,7 @@ static struct rtgui_image_palette *rtgui_image_bmp_load_palette(
         return RT_NULL;
         return RT_NULL;
     }
     }
 
 
-	palette->ncolors = colorsUsed;
+    palette->ncolors = colorsUsed;
     if (alpha)
     if (alpha)
     {
     {
         rt_uint8_t temp[4];
         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);
     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;
     error = RT_FALSE;
 
 
     do
     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;
         if (rtgui_dc_get_visible(dc) != RT_TRUE) break;
 
 
         /* the minimum rect */
         /* 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)
         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_uint16_t x, y;
             rt_uint8_t *ptr;
             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);
                     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);
     } 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 <rtthread.h>
-#include <rtgui/dc_hw.h>
+#include <rtgui/dc.h>
 #include <rtgui/image.h>
 #include <rtgui/image.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/image_hdc.h>
 #include <rtgui/image_hdc.h>
@@ -9,21 +32,6 @@
 
 
 extern int fastlz_decompress(const void *input, int length, void *output, int maxout);
 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_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 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);
 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)
     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
     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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
+ * 2010-09-15     Bernard      first version
  * 2012-01-24     onelife      add TJpgDec (Tiny JPEG Decompressor) support
  * 2012-01-24     onelife      add TJpgDec (Tiny JPEG Decompressor) support
  */
  */
 #include <rtthread.h>
 #include <rtthread.h>
@@ -13,7 +32,6 @@
 
 
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/filerw.h>
 #include <rtgui/filerw.h>
-#include <rtgui/image_jpeg.h>
 #include <rtgui/blit.h>
 #include <rtgui/blit.h>
 
 
 #ifdef RTGUI_USING_DFS_FILERW
 #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;
         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
     else
     {
     {
@@ -606,9 +624,9 @@ struct rtgui_image_jpeg
     rt_uint16_t dst_x, dst_y;
     rt_uint16_t dst_x, dst_y;
     rt_uint16_t dst_w, dst_h;
     rt_uint16_t dst_w, dst_h;
     rt_bool_t is_loaded;
     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;
     void *pool;
     rt_uint8_t *pixels;
     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->left > jpeg->dst_w) return 1;
         if (rect->top  > jpeg->dst_h) return 0;
         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;
         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;
         h = h - rect->top + 1;
 
 
         for (y = 0; y < h; y++)
         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)
 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)
 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;
     rt_bool_t res = RT_FALSE;
     struct rtgui_image_jpeg *jpeg;
     struct rtgui_image_jpeg *jpeg;
     JRESULT ret;
     JRESULT ret;
-	struct rtgui_graphic_driver *hw_driver;
+    struct rtgui_graphic_driver *hw_driver;
 
 
     do
     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->is_loaded = load;
         jpeg->pixels = RT_NULL;
         jpeg->pixels = RT_NULL;
 
 
-		/* allocate memory pool */
+        /* allocate memory pool */
         jpeg->pool = rt_malloc(TJPGD_WORKING_BUFFER_SIZE);
         jpeg->pool = rt_malloc(TJPGD_WORKING_BUFFER_SIZE);
         if (jpeg->pool == RT_NULL)
         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;
             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->w = (rt_uint16_t)jpeg->tjpgd.width;
         image->h = (rt_uint16_t)jpeg->tjpgd.height;
         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;
             if (ret != JDR_OK) break;
 
 
             rtgui_filerw_close(jpeg->filerw);
             rtgui_filerw_close(jpeg->filerw);
-			jpeg->filerw = RT_NULL;
+            jpeg->filerw = RT_NULL;
         }
         }
         res = RT_TRUE;
         res = RT_TRUE;
     } while (0);
     } 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))
     if (jpeg && (!res || jpeg->is_loaded))
     {
     {
         rt_free(jpeg->pool);
         rt_free(jpeg->pool);
-		jpeg->pool = RT_NULL;
+        jpeg->pool = RT_NULL;
     }
     }
 
 
     if (!res)
     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);
             rtgui_free(jpeg->pixels);
         rt_free(jpeg);
         rt_free(jpeg);
 
 
-		image->data   = RT_NULL;
-		image->engine = RT_NULL;
+        image->data   = RT_NULL;
+        image->engine = RT_NULL;
     }
     }
 
 
     /* create jpeg image successful */
     /* 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));
     h = _UI_MIN(image->h - yoff, rtgui_rect_height(*dst_rect));
 
 
     if (rtgui_dc_get_pixel_format(dc) == RTGRAPHIC_PIXEL_FORMAT_RGB888 &&
     if (rtgui_dc_get_pixel_format(dc) == RTGRAPHIC_PIXEL_FORMAT_RGB888 &&
-        jpeg->tjpgd.format != 0)
+            jpeg->tjpgd.format != 0)
     {
     {
         jpeg->tjpgd.format = 0;
         jpeg->tjpgd.format = 0;
         jpeg->byte_per_pixel = 3;
         jpeg->byte_per_pixel = 3;
@@ -910,7 +928,7 @@ static void rtgui_image_jpeg_blit(struct rtgui_image *image,
     else
     else
     {
     {
         if ((rtgui_dc_get_pixel_format(dc) == RTGRAPHIC_PIXEL_FORMAT_RGB888 && jpeg->tjpgd.format == 0) ||
         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_uint16_t imageWidth = image->w * jpeg->byte_per_pixel;
             rt_uint8_t *src = jpeg->pixels + yoff * imageWidth + xoff + 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.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 +
             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_h = rtgui_rect_height(*dst_rect);
             info.dst_w = rtgui_rect_width(*dst_rect);
             info.dst_w = rtgui_rect_width(*dst_rect);
             info.dst_fmt = buffer->pixel_format;
             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/rtgui_system.h>
 #include <rtgui/blit.h>
 #include <rtgui/blit.h>
 #include <rtgui/driver.h>
 #include <rtgui/driver.h>
 
 
 #ifdef RTGUI_IMAGE_PNG
 #ifdef RTGUI_IMAGE_PNG
 #include "png.h"
 #include "png.h"
-#include <rtgui/image_png.h>
 
 
 #define PNG_MAGIC_LEN       8
 #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)
 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)
 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);
         rtgui_free(png);
         return RT_FALSE;
         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);
     png->info_ptr = png_create_info_struct(png->png_ptr);
     if (png->info_ptr == RT_NULL)
     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->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_set_read_fn(png->png_ptr, png->filerw, rtgui_image_png_read_data);
 
 
     png_read_info(png->png_ptr, png->info_ptr);
     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);
         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
     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;
     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;
     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)
         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:
         case PNG_COLOR_TYPE_RGBA:
             for (y = 0; y < h; y++)
             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 width;
     unsigned int height;
     unsigned int height;
     unsigned int error;
     unsigned int error;
-	
+
     rt_uint8_t* pixel;
     rt_uint8_t* pixel;
     rt_uint8_t* in;
     rt_uint8_t* in;
     rt_uint32_t in_size;
     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_seek(file, 0, SEEK_SET);
     rtgui_filerw_read(file, in, in_size, 1);
     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);
     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->engine = &rtgui_image_png_engine;
     image->data = pixel;
     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 */
     /* close file handler */
     rtgui_filerw_close(file);
     rtgui_filerw_close(file);
@@ -518,159 +541,169 @@ static void rtgui_image_png_unload(struct rtgui_image *image)
         pixels = (rt_uint8_t*) image->data;
         pixels = (rt_uint8_t*) image->data;
 
 
         /* release 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)
 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;
     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 != RT_NULL && dc != RT_NULL && rect != RT_NULL);
     RT_ASSERT(image->data != RT_NULL);
     RT_ASSERT(image->data != RT_NULL);
 
 
 #define blending(s, d, a) (((unsigned)(((s) - (d)) * (a)) >> 8) + (d))
 #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()
 void rtgui_image_png_init()

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : image_xpm.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -15,7 +25,6 @@
 #include <string.h>
 #include <string.h>
 
 
 #include <rtgui/filerw.h>
 #include <rtgui/filerw.h>
-#include <rtgui/image_xpm.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
 
 
 #ifdef RTGUI_IMAGE_XPM
 #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/rtgui.h>
 #include <rtgui/matrix.h>
 #include <rtgui/matrix.h>
 
 
@@ -12,7 +35,7 @@
  * this software and associated documentation files (the "Software"),  to deal in
  * this software and associated documentation files (the "Software"),  to deal in
  * the Software without restriction,  including without limitation the rights to
  * the Software without restriction,  including without limitation the rights to
  * use,  copy,  modify,  merge,  publish,  distribute,  sublicense,  and/or sell copies of
  * 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:
  * subject to the following conditions:
  *
  *
  * The above copyright notice and this permission notice shall be included in all
  * 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 */
 /* @dd is the degree range in 0~512 */
 rt_inline int icost(int dd)
 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,
         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,
         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,
         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;
     dd &= COS_TABLE_SZ - 1;
 
 
-	return t[dd];
+    return t[dd];
 }
 }
 
 
 rt_inline int icosd(int d)
 rt_inline int icosd(int d)
 {
 {
-	int dd = d;
-	return icost(dd);
+    int dd = d;
+    return icost(dd);
 }
 }
 
 
 rt_inline int isind(int d)
 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)
 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)
 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)
 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)
 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)
 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)
 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[0], mm[1], 0);
     rt_kprintf("|%6d, %6d, %6d|\n", mm[2], mm[3], 0);
     rt_kprintf("|%6d, %6d, %6d|\n", mm[2], mm[3], 0);
     rt_kprintf("|%6d, %6d, %6d|\n", mm[4], mm[5], 1);
     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
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -210,7 +220,7 @@ void rtgui_mouse_moveto(int x, int y)
 #endif
 #endif
 
 
     if (x != _rtgui_cursor->cx ||
     if (x != _rtgui_cursor->cx ||
-        y != _rtgui_cursor->cy)
+            y != _rtgui_cursor->cy)
     {
     {
 #ifdef RTGUI_USING_WINMOVE
 #ifdef RTGUI_USING_WINMOVE
         if (_rtgui_cursor->win_rect_show)
         if (_rtgui_cursor->win_rect_show)
@@ -257,7 +267,7 @@ void rtgui_mouse_moveto(int x, int y)
         }
         }
 
 
 #ifdef RTGUI_USING_HW_CURSOR
 #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
 #endif
     }
     }
 
 
@@ -268,12 +278,12 @@ void rtgui_mouse_moveto(int x, int y)
 
 
 void rtgui_mouse_set_position(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
 #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
 #endif
 }
 }
 
 

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : mouse.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : region.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -2017,113 +2027,6 @@ rtgui_rect_t *rtgui_region_extents(rtgui_region_t *region)
     return(&region->extents);
     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
 #define RTGUI_REGION_TRACE
 
 
 #ifdef 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;
     x = region->extents.x1;
     y = region->extents.y1;
     y = region->extents.y1;
-    
+
     for (i = 0; i < num; i++)
     for (i = 0; i < num; i++)
     {
     {
         struct rtgui_rect rect;
         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);
 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)
 void rtgui_rect_moveto_align(const rtgui_rect_t *rect, rtgui_rect_t *to, int align)
 {
 {
     int dw, dh;
     int dw, dh;
@@ -2275,6 +2193,22 @@ void rtgui_rect_intersect(rtgui_rect_t *src, rtgui_rect_t *dest)
 }
 }
 RTM_EXPORT(rtgui_rect_intersect);
 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)
 int rtgui_rect_contains_point(const rtgui_rect_t *rect, int x, int y)
 {
 {
     if (INBOX(rect, x, y)) return RT_EOK;
     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)
 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);
 RTM_EXPORT(rtgui_rect_set);
 
 

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : rtgui_app.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -382,15 +392,15 @@ void rtgui_app_sleep(struct rtgui_app *app, int millisecond)
     rt_err_t result;
     rt_err_t result;
     rt_uint16_t current_ref;
     rt_uint16_t current_ref;
     struct rtgui_event *event;
     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 */
     /* point to event buffer */
     event = (struct rtgui_event *)app->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();
         delta_tick = sleep_tick - rt_tick_get();
     }
     }
 
 
-	app->ref_count --;
+    app->ref_count --;
 }
 }
 RTM_EXPORT(rtgui_app_sleep);
 RTM_EXPORT(rtgui_app_sleep);
 
 

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : driver.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -107,8 +117,8 @@ rtgui_graphic_driver_get_rect_buffer(const struct rtgui_graphic_driver *driver,
 
 
     /* get source pixel */
     /* get source pixel */
     pixel = (rt_uint8_t*)driver->framebuffer
     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;
     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)
 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;
     rt_uint16_t *pixel_ptr;
     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;
     struct rtgui_graphic_driver *drv;
     rt_uint8_t *dst;
     rt_uint8_t *dst;
     rt_uint16_t pixel;
     rt_uint16_t pixel;
-    rt_ubase_t index;
+    int index;
 
 
     drv = rtgui_graphic_get_device();
     drv = rtgui_graphic_get_device();
     pixel = rtgui_color_to_565(*c);
     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)
 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;
     rt_uint16_t *pixel_ptr;
     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;
     struct rtgui_graphic_driver *drv;
     rt_uint8_t *dst;
     rt_uint8_t *dst;
     rt_uint16_t pixel;
     rt_uint16_t pixel;
-    rt_ubase_t index;
+    int index;
 
 
     drv = rtgui_graphic_get_device();
     drv = rtgui_graphic_get_device();
     pixel = rtgui_color_to_565p(*c);
     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 */
 /* draw raw hline */
 static void framebuffer_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y)
 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,
     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 FRAMEBUFFER (drv->framebuffer)
 #define MONO_PIXEL(framebuffer, x, y) \
 #define MONO_PIXEL(framebuffer, x, y) \
     ((rt_uint8_t**)(framebuffer))[y/8][x]
     ((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)
 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();
     struct rtgui_graphic_driver *drv = rtgui_graphic_get_device();
-    rt_ubase_t index;
 
 
     if (*c == white)
     if (*c == white)
         for (index = x1; index < x2; index ++)
         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)
 static void _mono_draw_vline(rtgui_color_t *c, int x , int y1, int y2)
 {
 {
     struct rtgui_graphic_driver *drv = rtgui_graphic_get_device();
     struct rtgui_graphic_driver *drv = rtgui_graphic_get_device();
-    rt_ubase_t index;
+    int index;
 
 
     if (*c == white)
     if (*c == white)
         for (index = y1; index < y2; index ++)
         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)
 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();
     struct rtgui_graphic_driver *drv = rtgui_graphic_get_device();
-    rt_ubase_t index;
+    int index;
 
 
     for (index = x1; index < x2; 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;
         return &_framebuffer_rgb565_ops;
     case RTGRAPHIC_PIXEL_FORMAT_RGB565P:
     case RTGRAPHIC_PIXEL_FORMAT_RGB565P:
         return &_framebuffer_rgb565p_ops;
         return &_framebuffer_rgb565p_ops;
+    case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
+        return &_framebuffer_argb888_ops;
     default:
     default:
         RT_ASSERT(0);
         RT_ASSERT(0);
         break;
         break;

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : rtgui_object.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * 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 (!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;
     return obj;
 }
 }

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

@@ -1,16 +1,26 @@
 /*
 /*
  * File      : rtgui_system.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
  * 2009-10-04     Bernard      first version
  * 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>
 #include <rtgui/rtgui.h>
@@ -22,6 +32,10 @@
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/widgets/window.h>
 #include <rtgui/widgets/window.h>
 
 
+#ifdef RTGUI_USING_TTF
+#include <rtgui/font_freetype.h>
+#endif
+
 #ifdef _WIN32_NATIVE
 #ifdef _WIN32_NATIVE
 #define RTGUI_MEM_TRACE
 #define RTGUI_MEM_TRACE
 #endif
 #endif
@@ -60,6 +74,10 @@ int rtgui_system_server_init(void)
     rtgui_font_set_defaut(&rtgui_font_asc12);
     rtgui_font_set_defaut(&rtgui_font_asc12);
 #endif
 #endif
 
 
+#ifdef RTGUI_USING_TTF
+    rtgui_ttf_system_init();
+#endif
+
     return 0;
     return 0;
 }
 }
 INIT_APP_EXPORT(rtgui_system_server_init);
 INIT_APP_EXPORT(rtgui_system_server_init);
@@ -413,7 +431,7 @@ const char *rtgui_event_string[] =
     "TIMER",                /* timer                */
     "TIMER",                /* timer                */
     "UPDATE_TOPLVL",        /* update toplevel      */
     "UPDATE_TOPLVL",        /* update toplevel      */
 
 
-	"VPAINT_REQ", 			/* virtual paint request */
+    "VPAINT_REQ", 			/* virtual paint request */
 
 
     /* clip rect information */
     /* clip rect information */
     "CLIP_INFO",            /* clip rect info       */
     "CLIP_INFO",            /* clip rect info       */
@@ -423,7 +441,7 @@ const char *rtgui_event_string[] =
     "MOUSE_BUTTON",         /* mouse button info    */
     "MOUSE_BUTTON",         /* mouse button info    */
     "KBD",                  /* keyboard info        */
     "KBD",                  /* keyboard info        */
     "TOUCH",                /* touch info           */
     "TOUCH",                /* touch info           */
-	"GESTURE", 				/* gesture              */
+    "GESTURE", 				/* gesture              */
 
 
     "FOCUSED",              /* widget got focuse    */
     "FOCUSED",              /* widget got focuse    */
     "SCROLLED",             /* scroll bar scrolled  */
     "SCROLLED",             /* scroll bar scrolled  */
@@ -599,7 +617,7 @@ static void rtgui_event_dump(struct rtgui_app* app, rtgui_event_t *event)
     break;
     break;
 
 
     default:
     default:
-    break;
+        break;
     }
     }
 
 
     rt_kprintf("\n");
     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)
 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;
     struct rtgui_app *app;
 
 
     RT_ASSERT(event != RT_NULL);
     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)
     if (app == RT_NULL)
         return -RT_ERROR;
         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)
     while (rt_mq_recv(app->mq, e, sizeof(union rtgui_event_generic), RT_WAITING_FOREVER) == RT_EOK)
     {
     {
         if (e->type == type)
         if (e->type == type)
@@ -785,23 +803,23 @@ RTM_EXPORT(rtgui_screen_unlock);
 
 
 int rtgui_screen_lock_freeze(void)
 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);
 RTM_EXPORT(rtgui_screen_lock_freeze);
 
 
 void rtgui_screen_lock_thaw(int value)
 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);
 RTM_EXPORT(rtgui_screen_lock_thaw);
 
 

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : server.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -71,12 +81,12 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse *event)
     /* re-init to server thread */
     /* re-init to server thread */
     RTGUI_EVENT_MOUSE_BUTTON_INIT(event);
     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
 #ifdef RTGUI_USING_WINMOVE
     if (rtgui_winrect_is_moved() &&
     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;
         struct rtgui_win *win;
         rtgui_rect_t rect;
         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 */
     /* only raise window if the button is pressed down */
     if (event->button & RTGUI_MOUSE_BUTTON_DOWN &&
     if (event->button & RTGUI_MOUSE_BUTTON_DOWN &&
-        rtgui_topwin_get_focus() != wnd)
+            rtgui_topwin_get_focus() != wnd)
     {
     {
         rtgui_topwin_activate_topwin(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)
 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
 #ifdef _WIN32_NATIVE
@@ -210,7 +220,7 @@ void rtgui_server_handle_touch(struct rtgui_event_touch *event)
 #endif
 #endif
 
 
 static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object,
 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(object != RT_NULL);
     RT_ASSERT(event != RT_NULL);
     RT_ASSERT(event != RT_NULL);
@@ -232,7 +242,7 @@ static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object,
         }
         }
         break;
         break;
 
 
-        /* mouse and keyboard event */
+    /* mouse and keyboard event */
     case RTGUI_EVENT_MOUSE_MOTION:
     case RTGUI_EVENT_MOUSE_MOTION:
         /* handle mouse motion event */
         /* handle mouse motion event */
         rtgui_server_handle_mouse_motion((struct rtgui_event_mouse *)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);
         rtgui_server_handle_mouse_btn((struct rtgui_event_mouse *)event);
         break;
         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:
     case RTGUI_EVENT_KBD:
         /* handle keyboard event */
         /* handle keyboard event */
         rtgui_server_handle_kbd((struct rtgui_event_kbd *)event);
         rtgui_server_handle_kbd((struct rtgui_event_kbd *)event);
         break;
         break;
 
 
-        /* window event */
+    /* window event */
     case RTGUI_EVENT_WIN_CREATE:
     case RTGUI_EVENT_WIN_CREATE:
         if (rtgui_topwin_add((struct rtgui_event_win_create *)event) == RT_EOK)
         if (rtgui_topwin_add((struct rtgui_event_win_create *)event) == RT_EOK)
             rtgui_ack(event, RTGUI_STATUS_OK);
             rtgui_ack(event, RTGUI_STATUS_OK);
@@ -325,7 +335,7 @@ static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object,
         }
         }
         break;
         break;
 
 
-        /* other event */
+    /* other event */
     case RTGUI_EVENT_COMMAND:
     case RTGUI_EVENT_COMMAND:
         break;
         break;
 
 
@@ -373,7 +383,7 @@ static void rtgui_server_entry(void *parameter)
     rtgui_server_app = rtgui_app_create("rtgui");
     rtgui_server_app = rtgui_app_create("rtgui");
     if (rtgui_server_app == RT_NULL)
     if (rtgui_server_app == RT_NULL)
     {
     {
-		rt_kprintf("Create GUI server failed.\n");
+        rt_kprintf("Create GUI server failed.\n");
         return;
         return;
     }
     }
 
 
@@ -391,12 +401,21 @@ static void rtgui_server_entry(void *parameter)
     rtgui_server_app = RT_NULL;
     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)
     if (rtgui_server_app != RT_NULL)
-        rtgui_send(rtgui_server_app, event, size);
+    {
+        result = rtgui_send(rtgui_server_app, event, size);
+    }
     else
     else
+    {
         rt_kprintf("post when server is not running\n");
         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)
 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
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * 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);
         rtgui_theme_draw_win(wint);
         return RT_FALSE;
         return RT_FALSE;
 
 
-    case RTGUI_EVENT_MOUSE_BUTTON: {
+    case RTGUI_EVENT_MOUSE_BUTTON:
+    {
         struct rtgui_event_mouse *emou = (struct rtgui_event_mouse *)eve;
         struct rtgui_event_mouse *emou = (struct rtgui_event_mouse *)eve;
 
 
         if (win->style & RTGUI_WIN_STYLE_CLOSEBOX)
         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)
                 else if (emou->button & RTGUI_MOUSE_BUTTON_UP)
                 {
                 {
                     if (win->flag & RTGUI_WIN_FLAG_CB_PRESSED &&
                     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);
                         rtgui_win_close(win);
                         return RT_TRUE;
                         return RT_TRUE;
@@ -130,7 +141,7 @@ rt_bool_t rtgui_wintile_event_handler(struct rtgui_object *obj, rtgui_event_t *e
 #endif
 #endif
         }
         }
     }
     }
-        return RT_TRUE;
+    return RT_TRUE;
     default:
     default:
         return rtgui_widget_event_handler(obj, eve);
         return rtgui_widget_event_handler(obj, eve);
     }
     }

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

@@ -1,16 +1,26 @@
 /*
 /*
  * File      : topwin.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
  * 2009-10-16     Bernard      first version
  * 2009-10-16     Bernard      first version
- * 2012-02-25     Grissiom     rewrite topwin implementation 
+ * 2012-02-25     Grissiom     rewrite topwin implementation
  */
  */
 #include "topwin.h"
 #include "topwin.h"
 #include "mouse.h"
 #include "mouse.h"
@@ -25,7 +35,7 @@
 #include <rtgui/widgets/container.h>
 #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
  * 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
  * 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->parent == RT_NULL)
     {
     {
         if (top->list.next != &_rtgui_topwin_list &&
         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));
             top = _rtgui_topwin_get_topmost_child_shown(get_topwin_from_list(top->list.next));
         else
         else
             return RT_NULL;
             return RT_NULL;
@@ -605,7 +615,7 @@ rt_inline void _rtgui_topwin_preorder_map(struct rtgui_topwin *topwin, void (*fu
     func(topwin);
     func(topwin);
 
 
     rt_list_foreach(child, &topwin->child_list, next)
     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)
 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 */
     /* find in show list */
     topwin = rtgui_topwin_search_in_list(event->wid, &_rtgui_topwin_list);
     topwin = rtgui_topwin_search_in_list(event->wid, &_rtgui_topwin_list);
     if (topwin == RT_NULL ||
     if (topwin == RT_NULL ||
-        !(topwin->flag & WINTITLE_SHOWN))
+            !(topwin->flag & WINTITLE_SHOWN))
     {
     {
         return -RT_ERROR;
         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. */
 /* clip region from topwin, and the windows beneath it. */
 rt_inline void _rtgui_topwin_clip_to_region(struct rtgui_topwin *topwin,
 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(region != RT_NULL);
     RT_ASSERT(topwin != RT_NULL);
     RT_ASSERT(topwin != RT_NULL);
@@ -905,7 +915,7 @@ static void rtgui_topwin_update_clip(void)
     struct rtgui_region region_available;
     struct rtgui_region region_available;
 
 
     if (rt_list_isempty(&_rtgui_topwin_list) ||
     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;
         return;
 
 
     RTGUI_EVENT_CLIP_INFO_INIT(&eclip);
     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 */
     /* modal window should be on top already */
     RT_ASSERT(get_topwin_from_list(parent_top->child_list.next) == topwin);
     RT_ASSERT(get_topwin_from_list(parent_top->child_list.next) == topwin);
 
 
-    do {
+    do
+    {
         rt_list_foreach(node, &parent_top->child_list, next)
         rt_list_foreach(node, &parent_top->child_list, next)
         {
         {
             get_topwin_from_list(node)->flag |= WINTITLE_MODALED;
             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,
 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 rtgui_object *object;
     struct rt_list_node *node;
     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, topwin->wid->title, topwin->flag,
                topwin->flag & WINTITLE_SHOWN ? 'S' : 'H',
                topwin->flag & WINTITLE_SHOWN ? 'S' : 'H',
                topwin->flag & WINTITLE_MODALED ? 'm' :
                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)
 static void _rtgui_topwin_dump_tree(struct rtgui_topwin *topwin)

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : topwin.h
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes

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

@@ -1,7 +1,7 @@
 /*
 /*
  * File      : widget.c
  * 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
  *  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
  *  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.
  * 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/rtgui_app.h>
 #include <rtgui/widgets/widget.h>
 #include <rtgui/widgets/widget.h>
 #include <rtgui/widgets/window.h>
 #include <rtgui/widgets/window.h>
 #include <rtgui/widgets/container.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)
 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;
     widget->align = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP;
 
 
     /* clear the garbage value of extent and clip */
     /* 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;
     widget->min_width = widget->min_height = 0;
     rtgui_region_init_with_extents(&widget->clip, &widget->extent);
     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 */
     /* some common event handler */
     widget->on_focus_in   = RT_NULL;
     widget->on_focus_in   = RT_NULL;
     widget->on_focus_out  = RT_NULL;
     widget->on_focus_out  = RT_NULL;
-    widget->on_paint      = RT_NULL;
 
 
     /* set default event handler */
     /* set default event handler */
     rtgui_object_set_event_handler(RTGUI_OBJECT(widget), rtgui_widget_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 */
     /* init user data private to 0 */
     widget->user_data = 0;
     widget->user_data = 0;
 
 
-    /* init clip information */
-    rtgui_region_init(&(widget->clip));
-
     /* init hardware dc */
     /* init hardware dc */
     rtgui_dc_client_init(widget);
     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 */
     /* update extent rectangle */
     widget->extent = *rect;
     widget->extent = *rect;
+    /* set the visiable extern as extern */
+    widget->extent_visiable = *rect;
     if (RTGUI_IS_CONTAINER(widget))
     if (RTGUI_IS_CONTAINER(widget))
     {
     {
         /* re-do layout */
         /* 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);
         rtgui_widget_move_to_logic(widget, delta_x, delta_y);
     }
     }
-
 }
 }
 RTM_EXPORT(rtgui_widget_set_rect);
 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)
 static void _widget_moveto(struct rtgui_widget* widget, int dx, int dy)
 {
 {
     struct rtgui_list_node *node;
     struct rtgui_list_node *node;
-    rtgui_widget_t *child;
+    rtgui_widget_t *child, *parent;
 
 
     rtgui_rect_moveto(&(widget->extent), dx, dy);
     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 */
     /* reset clip info */
     rtgui_region_init_with_extents(&(widget->clip), &(widget->extent));
     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)
     if (parent != RT_NULL)
     {
     {
         /* get the parent rect, even if it's a transparent parent. */
         /* 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 */
     /* 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 */
         /* reset clip info */
         rtgui_region_init_with_extents(&(widget->clip), &(widget->extent));
         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), &rect);
-        rtgui_region_intersect_rect(&(widget->clip), &(widget->clip), &(parent->extent));
 
 
         /* give back the extent */
         /* give back the extent */
         rtgui_region_union(&(parent->clip), &(parent->clip), &(widget->clip));
         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);
 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
  * @brief Focuses the widget. The focused widget is the widget which can receive the keyboard events
  * @param widget a widget
  * @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);
 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)
 rt_bool_t rtgui_widget_event_handler(struct rtgui_object *object, rtgui_event_t *event)
 {
 {
     RTGUI_WIDGET_EVENT_HANDLER_PREPARE;
     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)
     switch (event->type)
     {
     {
     case RTGUI_EVENT_PAINT:
     case RTGUI_EVENT_PAINT:
-        return rtgui_widget_onpaint(object, event);
+        break;
     case RTGUI_EVENT_SHOW:
     case RTGUI_EVENT_SHOW:
         return rtgui_widget_onshow(object, event);
         return rtgui_widget_onshow(object, event);
     case RTGUI_EVENT_HIDE:
     case RTGUI_EVENT_HIDE:
@@ -556,7 +542,11 @@ void rtgui_widget_update_clip(rtgui_widget_t *widget)
         return;
         return;
 
 
     parent = widget->parent;
     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 */
     /* reset clip to extent */
     rtgui_region_reset(&(widget->clip), &(widget->extent));
     rtgui_region_reset(&(widget->clip), &(widget->extent));
     /* limit widget extent in parent 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 */
         /* subtract widget clip in parent clip */
         if (!(widget->flag & RTGUI_WIDGET_FLAG_TRANSPARENT) && RTGUI_IS_CONTAINER(parent))
         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))
     if (RTGUI_WIDGET_IS_HIDE(widget))
         return;
         return;
 
 
-    RTGUI_WIDGET_HIDE(widget);
     if (widget->toplevel != RT_NULL)
     if (widget->toplevel != RT_NULL)
     {
     {
         RTGUI_EVENT_HIDE_INIT(&ehide);
         RTGUI_EVENT_HIDE_INIT(&ehide);
@@ -639,6 +628,8 @@ void rtgui_widget_hide(struct rtgui_widget *widget)
                 &ehide);
                 &ehide);
         }
         }
     }
     }
+
+    RTGUI_WIDGET_HIDE(widget);
 }
 }
 RTM_EXPORT(rtgui_widget_hide);
 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 (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);
         rtgui_widget_clip_parent(widget);
     }
     }
@@ -742,7 +733,7 @@ void rtgui_widget_update(rtgui_widget_t *widget)
     RT_ASSERT(widget != RT_NULL);
     RT_ASSERT(widget != RT_NULL);
 
 
     if (RTGUI_OBJECT(widget)->event_handler != 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),
         RTGUI_OBJECT(widget)->event_handler(RTGUI_OBJECT(widget),
                                             &paint.parent);
                                             &paint.parent);

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

@@ -1,11 +1,21 @@
 /*
 /*
  * File      : window.c
  * 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:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
@@ -132,9 +142,9 @@ DEFINE_CLASS_TYPE(win, "win",
                   sizeof(struct rtgui_win));
                   sizeof(struct rtgui_win));
 
 
 int rtgui_win_init(struct rtgui_win *win, struct rtgui_win *parent_window,
 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;
     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)
 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)
     if (is_modal)
         win->flag |= RTGUI_WIN_FLAG_MODAL;
         win->flag |= RTGUI_WIN_FLAG_MODAL;
@@ -557,7 +567,7 @@ static rt_bool_t rtgui_win_ondraw(struct rtgui_win *win)
     /* fill area */
     /* fill area */
     rtgui_dc_fill_rect(dc, &rect);
     rtgui_dc_fill_rect(dc, &rect);
 
 
-    rtgui_widget_onpaint(RTGUI_OBJECT(win), RT_NULL);
+    /* widget drawing */
 
 
     /* paint each widget */
     /* paint each widget */
     RTGUI_EVENT_PAINT_INIT(&event);
     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_container_dispatch_event(RTGUI_CONTAINER(win),
                                    (rtgui_event_t *)&event);
                                    (rtgui_event_t *)&event);
 
 
-    rtgui_dc_end_drawing(dc);
+    rtgui_dc_end_drawing(dc, 1);
 
 
     return RT_FALSE;
     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.
      * widgets). If not, it will receive two mouse up events.
      */
      */
     if (((struct rtgui_event_mouse *)eve)->button & RTGUI_MOUSE_BUTTON_UP
     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(
         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 */
             /* clean last mouse event handled widget */
             win->last_mevent_widget = RT_NULL;
             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
      * TODO: add it in the doc
      */
      */
     return rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win),
     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)
 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:
     case RTGUI_EVENT_WIN_ACTIVATE:
         if (win->flag & RTGUI_WIN_FLAG_UNDER_MODAL ||
         if (win->flag & RTGUI_WIN_FLAG_UNDER_MODAL ||
-            RTGUI_WIDGET_IS_HIDE(win))
+                RTGUI_WIDGET_IS_HIDE(win))
         {
         {
             /* activate a hide window */
             /* activate a hide window */
             return RT_TRUE;
             return RT_TRUE;
@@ -713,6 +723,9 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_even
 
 
         break;
         break;
 
 
+    case RTGUI_EVENT_WIN_UPDATE_END:
+        break;
+
     case RTGUI_EVENT_CLIP_INFO:
     case RTGUI_EVENT_CLIP_INFO:
         /* update win clip */
         /* update win clip */
         rtgui_win_update_clip(win);
         rtgui_win_update_clip(win);
@@ -725,22 +738,23 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_even
         break;
         break;
 
 
 #ifdef RTGUI_USING_VFRAMEBUFFER
 #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_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;
         req->sender->buffer = dc;
         rt_completion_done(req->sender->cmp);
         rt_completion_done(req->sender->cmp);
 
 
-		break;
-	}
+        break;
+    }
 #endif
 #endif
 
 
-    case RTGUI_EVENT_MOUSE_BUTTON: {
+    case RTGUI_EVENT_MOUSE_BUTTON:
+    {
         struct rtgui_event_mouse *emouse = (struct rtgui_event_mouse*)event;
         struct rtgui_event_mouse *emouse = (struct rtgui_event_mouse*)event;
 
 
         if (rtgui_rect_contains_point(&RTGUI_WIDGET(win)->extent,
         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:
     case RTGUI_EVENT_MOUSE_MOTION:
         return rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win),
         return rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win),
-                                                    (struct rtgui_event_mouse *)event);
+                (struct rtgui_event_mouse *)event);
 
 
     case RTGUI_EVENT_KBD:
     case RTGUI_EVENT_KBD:
         /* we should dispatch key event firstly */
         /* 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);
 RTM_EXPORT(rtgui_win_get_drawing);
 #endif
 #endif
 
 
-static const rt_uint8_t close_byte[14] = {
+static const rt_uint8_t close_byte[14] =
+{
     0x06, 0x18, 0x03, 0x30, 0x01, 0xE0, 0x00,
     0x06, 0x18, 0x03, 0x30, 0x01, 0xE0, 0x00,
     0xC0, 0x01, 0xE0, 0x03, 0x30, 0x06, 0x18
     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 ++)
         for (index = rect.x1; index < rect.x2 + 1; index ++)
         {
         {
             RTGUI_WIDGET_FOREGROUND(win->_title_wgt) = RTGUI_RGB((r>>RGB_FACTOR),
             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);
             rtgui_dc_draw_vline(dc, index, rect.y1, rect.y2);
             r += delta;
             r += delta;
             g += 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);
 }
 }

Некоторые файлы не были показаны из-за большого количества измененных файлов