diff --git a/components/KConfig b/components/KConfig index 0ec586b2becaf365b9039bc999e2e6892df479fc..1b0170467f2b21d5ea1736c6d91d514053b3a00b 100644 --- a/components/KConfig +++ b/components/KConfig @@ -16,10 +16,12 @@ source "$RTT_DIR/components/finsh/KConfig" source "$RTT_DIR/components/dfs/KConfig" +source "$RTT_DIR/components/net/KConfig" + source "$RTT_DIR/components/drivers/KConfig" -source "$RTT_DIR/components/libc/KConfig" +source "$RTT_DIR/components/gui/KConfig" -source "$RTT_DIR/components/net/KConfig" +source "$RTT_DIR/components/libc/KConfig" endmenu diff --git a/components/gui/Kconfig b/components/gui/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..ca03f21339c482b4cf2f2efe9ec5acd08a2e192d --- /dev/null +++ b/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 diff --git a/components/gui/SConscript b/components/gui/SConscript index 1b9064915133b4b9fab783a6d9ae1c35037bbfd6..68831d929fe7bfb60fe223e66cf55602371efd25 100644 --- a/components/gui/SConscript +++ b/components/gui/SConscript @@ -28,6 +28,7 @@ src/hz12font.c src/hz16font.c src/image.c src/image_bmp.c +src/image_container.c src/image_hdc.c src/image_jpg.c src/image_png.c diff --git a/components/gui/include/rtgui/blit.h b/components/gui/include/rtgui/blit.h index f0ff217cadeebeb14f12df620ac7412626f440be..3a07204f933a020997589d04737edd446c2735d8 100644 --- a/components/gui/include/rtgui/blit.h +++ b/components/gui/include/rtgui/blit.h @@ -1,7 +1,7 @@ /* * File : blit.h - * This file is part of RT-Thread GUI - * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,6 +47,7 @@ #define __RTGUI_BLIT_H__ #include +#include /* Assemble R-G-B values into a specified pixel format and store them */ #define RGB565_FROM_RGB(Pixel, r, g, b) \ @@ -201,13 +202,13 @@ struct rtgui_blit_info rt_uint8_t r, g, b, a; }; -struct rtgui_blit_info_src +struct rtgui_image_info { - rt_uint8_t *src; - int src_w, src_h; - int src_skip; + rt_uint8_t *pixels; + int src_pitch; - rt_uint8_t src_fmt; + rt_uint8_t src_fmt; + rt_uint8_t a; }; extern const rt_uint8_t* rtgui_blit_expand_byte[9]; @@ -217,6 +218,7 @@ rtgui_blit_line_func rtgui_blit_line_get(int dst_bpp, int src_bpp); rtgui_blit_line_func rtgui_blit_line_get_inv(int dst_bpp, int src_bpp); void rtgui_blit(struct rtgui_blit_info * info); +void rtgui_image_info_blit(struct rtgui_image_info* image, struct rtgui_dc* dc, struct rtgui_rect *dc_rect); #endif diff --git a/components/gui/include/rtgui/color.h b/components/gui/include/rtgui/color.h index 0a9854f4095658eb0278fd4de7de3ea035d2d77c..cf6ef08623af5fd2510dc53bd22f672ba2c55d29 100644 --- a/components/gui/include/rtgui/color.h +++ b/components/gui/include/rtgui/color.h @@ -1,11 +1,21 @@ /* * File : color.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/include/rtgui/dc.h b/components/gui/include/rtgui/dc.h index 73409659fc71c8da01cf38e958de9b0b31cc682e..20350cfe89ebc67bbce4957f9ae38e62d5429487 100644 --- a/components/gui/include/rtgui/dc.h +++ b/components/gui/include/rtgui/dc.h @@ -1,11 +1,21 @@ /* * File : dc.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -23,7 +33,7 @@ extern "C" { #include #include -#define RTGUI_DC(dc) ((struct rtgui_dc*)(dc)) +#define RTGUI_DC(dc) ((struct rtgui_dc*)(dc)) #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -51,10 +61,10 @@ struct rtgui_dc_engine }; /* - * The abstract device context + * The abstract device context * * Normally, a DC is a drawable canvas, user can draw point/line/cycle etc - * on the DC. + * on the DC. * * There are several kinds of DC: * - Hardware DC; @@ -70,44 +80,49 @@ struct rtgui_dc const struct rtgui_dc_engine *engine; }; -/* - * The hardware device context +/* + * The hardware device context * - * The hardware DC is a context based on hardware device, for examle the + * The hardware DC is a context based on hardware device, for examle the * LCD device. The operations on the hardware DC are reflected to the real - * hardware. - * + * hardware. + * */ struct rtgui_dc_hw { - struct rtgui_dc parent; - rtgui_widget_t *owner; - const struct rtgui_graphic_driver *hw_driver; + struct rtgui_dc parent; + rtgui_widget_t *owner; + const struct rtgui_graphic_driver *hw_driver; }; /** - * The buffer dc is a device context with memory buffer. + * The buffer dc is a device context with memory buffer. * * All the operations on this device context is reflected to the memory buffer. */ struct rtgui_dc_buffer { - struct rtgui_dc parent; + struct rtgui_dc parent; + + /* graphic context */ + rtgui_gc_t gc; - /* graphic context */ - rtgui_gc_t gc; + /* pixel format */ + rt_uint8_t pixel_format; + rt_uint8_t blend_mode; /* RTGUI_BLENDMODE: None/Blend/Add/Mod */ - /* pixel format */ - rt_uint8_t pixel_format; - rt_uint8_t blend_mode; /* RTGUI_BLENDMODE: None/Blend/Add/Mod */ + /* width and height */ + rt_uint16_t width, height; + /* pitch */ + rt_uint16_t pitch; - /* width and height */ - rt_uint16_t width, height; - /* pitch */ - rt_uint16_t pitch; +#ifdef RTGUI_IMAGE_CONTAINER + /* image dc */ + struct rtgui_image_item *image_item; +#endif - /* pixel data */ - rt_uint8_t *pixel; + /* pixel data */ + rt_uint8_t *pixel; }; #define RTGUI_DC_FC(dc) (rtgui_dc_get_gc(RTGUI_DC(dc))->foreground) @@ -118,6 +133,10 @@ struct rtgui_dc_buffer /* create a buffer dc */ struct rtgui_dc *rtgui_dc_buffer_create(int width, int height); struct rtgui_dc *rtgui_dc_buffer_create_pixformat(rt_uint8_t pixel_format, int w, int h); +#ifdef RTGUI_IMAGE_CONTAINER +struct rtgui_dc *rtgui_img_dc_create_pixformat(rt_uint8_t pixel_format, rt_uint8_t *pixel, + struct rtgui_image_item *image_item); +#endif struct rtgui_dc *rtgui_dc_buffer_create_from_dc(struct rtgui_dc* dc); /* create a widget dc */ @@ -125,11 +144,18 @@ struct rtgui_dc *rtgui_dc_widget_create(struct rtgui_widget * owner); /* begin and end a drawing */ struct rtgui_dc *rtgui_dc_begin_drawing(rtgui_widget_t *owner); -void rtgui_dc_end_drawing(struct rtgui_dc *dc); +void rtgui_dc_end_drawing(struct rtgui_dc *dc, rt_bool_t update); /* destroy a dc */ void rtgui_dc_destory(struct rtgui_dc *dc); +/* create a hardware dc */ +struct rtgui_dc *rtgui_dc_hw_create(rtgui_widget_t *owner); + +/* create a client dc */ +struct rtgui_dc *rtgui_dc_client_create(rtgui_widget_t *owner); +void rtgui_dc_client_init(rtgui_widget_t *owner); + rt_uint8_t *rtgui_dc_buffer_get_pixel(struct rtgui_dc *dc); void rtgui_dc_draw_line(struct rtgui_dc *dc, int x1, int y1, int x2, int y2); @@ -259,6 +285,9 @@ struct rtgui_dc *rtgui_dc_shrink(struct rtgui_dc *dc, int factorx, int factory); struct rtgui_dc *rtgui_dc_zoom(struct rtgui_dc *dc, double zoomx, double zoomy, int smooth); struct rtgui_dc *rtgui_dc_rotozoom(struct rtgui_dc *dc, double angle, double zoomx, double zoomy, int smooth); +/* dc buffer dump to file */ +void rtgui_dc_buffer_dump(struct rtgui_dc *self, char *fn); + #ifdef __cplusplus } #endif diff --git a/components/gui/include/rtgui/dc_client.h b/components/gui/include/rtgui/dc_client.h deleted file mode 100644 index e277654f04b5b815afc8dcae7dac446101ea7ce9..0000000000000000000000000000000000000000 --- a/components/gui/include/rtgui/dc_client.h +++ /dev/null @@ -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 - -/* 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 - diff --git a/components/gui/include/rtgui/dc_draw.h b/components/gui/include/rtgui/dc_draw.h index a2b85e828d8ec21fb2954b9ddccf3df794b33a8d..76482367d4357bfe8d6c652cb2ebaed93a3ef5b0 100644 --- a/components/gui/include/rtgui/dc_draw.h +++ b/components/gui/include/rtgui/dc_draw.h @@ -1,7 +1,7 @@ /* - * File : dc_blend.c - * This file is part of RT-Thread GUI - * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team + * File : dc_draw.h + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/components/gui/include/rtgui/dc_hw.h b/components/gui/include/rtgui/dc_hw.h deleted file mode 100644 index 0dadd7686e667904f1d6def931bfff5a28ed9f70..0000000000000000000000000000000000000000 --- a/components/gui/include/rtgui/dc_hw.h +++ /dev/null @@ -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 - -/* create a hardware dc */ -struct rtgui_dc *rtgui_dc_hw_create(rtgui_widget_t *owner); - -#endif - diff --git a/components/gui/include/rtgui/dc_trans.h b/components/gui/include/rtgui/dc_trans.h index 731571a3e0a9915242b8f33c7f4ccb1e524ef2c7..47216a21a3f907eeaf4ee08615dbadff6458dfae 100644 --- a/components/gui/include/rtgui/dc_trans.h +++ b/components/gui/include/rtgui/dc_trans.h @@ -1,3 +1,27 @@ +/* + * File : dc_trans.h + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2010-04-10 Bernard first version + */ + #ifndef __RTGUI_DC_TRANS_H__ #define __RTGUI_DC_TRANS_H__ diff --git a/components/gui/include/rtgui/driver.h b/components/gui/include/rtgui/driver.h index b070b7d4bb080d4d06ff9e2cf8e3a5d3d1c282ec..8246d8225624c30d1a68371dc46982e92536728c 100644 --- a/components/gui/include/rtgui/driver.h +++ b/components/gui/include/rtgui/driver.h @@ -1,11 +1,21 @@ /* * File : driver.h - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -34,17 +44,17 @@ struct rtgui_graphic_driver_ops /* graphic extension operations */ struct rtgui_graphic_ext_ops { - /* some 2D operations */ - void (*draw_line)(rtgui_color_t *c, int x1, int y1, int x2, int y2); + /* some 2D operations */ + void (*draw_line)(rtgui_color_t *c, int x1, int y1, int x2, int y2); - void (*draw_rect)(rtgui_color_t *c, int x1, int y1, int x2, int y2); - void (*fill_rect)(rtgui_color_t *c, int x1, int y1, int x2, int y2); + void (*draw_rect)(rtgui_color_t *c, int x1, int y1, int x2, int y2); + void (*fill_rect)(rtgui_color_t *c, int x1, int y1, int x2, int y2); - void (*draw_circle)(rtgui_color_t *c, int x, int y, int r); - void (*fill_circle)(rtgui_color_t *c, int x, int y, int r); + void (*draw_circle)(rtgui_color_t *c, int x, int y, int r); + void (*fill_circle)(rtgui_color_t *c, int x, int y, int r); - void (*draw_ellipse)(rtgui_color_t *c, int x, int y, int rx, int ry); - void (*fill_ellipse)(rtgui_color_t *c, int x, int y, int rx, int ry); + void (*draw_ellipse)(rtgui_color_t *c, int x, int y, int rx, int ry); + void (*fill_ellipse)(rtgui_color_t *c, int x, int y, int rx, int ry); }; struct rtgui_graphic_driver @@ -63,7 +73,7 @@ struct rtgui_graphic_driver struct rt_device* device; const struct rtgui_graphic_driver_ops *ops; - const struct rtgui_graphic_ext_ops *ext_ops; + const struct rtgui_graphic_ext_ops *ext_ops; }; struct rtgui_graphic_driver *rtgui_graphic_driver_get_default(void); @@ -77,7 +87,7 @@ void rtgui_graphic_driver_set_framebuffer(void *fb); rt_inline struct rtgui_graphic_driver *rtgui_graphic_get_device() { - return rtgui_graphic_driver_get_default(); + return rtgui_graphic_driver_get_default(); } #ifdef RTGUI_USING_HW_CURSOR @@ -86,8 +96,8 @@ rt_inline struct rtgui_graphic_driver *rtgui_graphic_get_device() */ enum rtgui_cursor_type { - RTGUI_CURSOR_ARROW, - RTGUI_CURSOR_HAND, + RTGUI_CURSOR_ARROW, + RTGUI_CURSOR_HAND, }; void rtgui_cursor_set_device(const char* device_name); diff --git a/components/gui/include/rtgui/event.h b/components/gui/include/rtgui/event.h index c937684fba9cb0928d96e925d34ace11c1620465..5ab3e679ca2e007a73c2e70307af6b5cf0b4fd9a 100644 --- a/components/gui/include/rtgui/event.h +++ b/components/gui/include/rtgui/event.h @@ -1,11 +1,21 @@ /* * File : event.h - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -41,6 +51,7 @@ enum _rtgui_event_type RTGUI_EVENT_WIN_CLOSE, /* close a window */ RTGUI_EVENT_WIN_MOVE, /* move a window */ RTGUI_EVENT_WIN_RESIZE, /* resize a window */ + RTGUI_EVENT_WIN_UPDATE_END, /* update done for window */ RTGUI_EVENT_WIN_MODAL_ENTER, /* the window is entering modal mode. This event should be sent after the window got setup and before the @@ -169,6 +180,13 @@ struct rtgui_event_win_resize rtgui_rect_t rect; }; +struct rtgui_event_win_update_end +{ + _RTGUI_EVENT_WIN_ELEMENTS + + rtgui_rect_t rect; +}; + #define rtgui_event_win_destroy rtgui_event_win #define rtgui_event_win_show rtgui_event_win #define rtgui_event_win_hide rtgui_event_win @@ -187,6 +205,7 @@ struct rtgui_event_win_resize #define RTGUI_EVENT_WIN_CLOSE_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_CLOSE) #define RTGUI_EVENT_WIN_MOVE_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_MOVE) #define RTGUI_EVENT_WIN_RESIZE_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_RESIZE) +#define RTGUI_EVENT_WIN_UPDATE_END_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_UPDATE_END) #define RTGUI_EVENT_WIN_MODAL_ENTER_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_MODAL_ENTER) /* @@ -375,7 +394,7 @@ struct rtgui_event_kbd #define RTGUI_EVENT_KBD_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_KBD) /** - * RTGUI Touch Event + * RTGUI Touch Event * NOTE: There is not touch event to user applications, it's handled by server. */ struct rtgui_event_touch diff --git a/components/gui/include/rtgui/filerw.h b/components/gui/include/rtgui/filerw.h index f1d3cc9bf2678ced14f8dd0894a25aeb62030090..edd2579875f20794516214b102e8137257d0bda5 100644 --- a/components/gui/include/rtgui/filerw.h +++ b/components/gui/include/rtgui/filerw.h @@ -1,11 +1,21 @@ /* * File : filerw.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/include/rtgui/font.h b/components/gui/include/rtgui/font.h index 72cc2326b2b6105ed150e89dc1ecde6fee443399..b1d480d048d0d209fd1da32c20754c91219d418a 100644 --- a/components/gui/include/rtgui/font.h +++ b/components/gui/include/rtgui/font.h @@ -1,11 +1,21 @@ /* * File : font.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -17,6 +27,7 @@ #include #include + #ifdef __cplusplus extern "C" { #endif diff --git a/components/gui/include/rtgui/font_fnt.h b/components/gui/include/rtgui/font_fnt.h index 4756418d6ada1c353d3069c63b3d561e82d859cf..3b0089d82ee8bc13016d755c23b3d9fa3c422b6d 100644 --- a/components/gui/include/rtgui/font_fnt.h +++ b/components/gui/include/rtgui/font_fnt.h @@ -1,3 +1,27 @@ +/* + * File : font_fnt.h + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2010-04-10 Bernard first version + */ + #ifndef __FONT_FNT_H__ #define __FONT_FNT_H__ @@ -7,28 +31,28 @@ /* fnt font header */ struct fnt_header { - rt_uint8_t version[4]; - rt_uint16_t max_width; - rt_uint16_t height; - rt_uint16_t ascent; - rt_uint16_t depth; - - rt_uint32_t first_char; - rt_uint32_t default_char; - rt_uint32_t size; - rt_uint32_t nbits; - rt_uint32_t noffset; - rt_uint32_t nwidth; + rt_uint8_t version[4]; + rt_uint16_t max_width; + rt_uint16_t height; + rt_uint16_t ascent; + rt_uint16_t depth; + + rt_uint32_t first_char; + rt_uint32_t default_char; + rt_uint32_t size; + rt_uint32_t nbits; + rt_uint32_t noffset; + rt_uint32_t nwidth; }; typedef rt_uint8_t MWIMAGEBITS; struct fnt_font { - struct fnt_header header; + struct fnt_header header; - const MWIMAGEBITS *bits; /* nbits */ - const rt_uint16_t *offset; /* noffset */ - const rt_uint8_t *width; /* nwidth */ + const MWIMAGEBITS *bits; /* nbits */ + const rt_uint16_t *offset; /* noffset */ + const rt_uint8_t *width; /* nwidth */ }; extern const struct rtgui_font_engine fnt_font_engine; diff --git a/components/gui/include/rtgui/font_freetype.h b/components/gui/include/rtgui/font_freetype.h index 0fadd887a64af7730f8f1abfe32fe6abdf2c894e..64766e37ada4caf61e88e6fd496dc0c3ae8ed046 100644 --- a/components/gui/include/rtgui/font_freetype.h +++ b/components/gui/include/rtgui/font_freetype.h @@ -1,3 +1,27 @@ +/* + * File : font_freetype.h + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2010-04-10 Bernard first version + */ + #ifndef __RTGUI_FONT_TTF_H__ #define __RTGUI_FONT_TTF_H__ @@ -8,7 +32,8 @@ extern "C" { #endif -rtgui_font_t *rtgui_freetype_font_create(const char *filename, int bold, int italic, rt_size_t size); +void rtgui_ttf_system_init(void); +rtgui_font_t *rtgui_freetype_font_create(const char *filename, rt_size_t size); void rtgui_freetype_font_destroy(rtgui_font_t *font); #ifdef __cplusplus diff --git a/components/gui/include/rtgui/image.h b/components/gui/include/rtgui/image.h index 9b9cb27462771a2d8d54f188f0fce908524ce4e1..07ddaec72128a145cc56a8eab92c43d5a03c357e 100644 --- a/components/gui/include/rtgui/image.h +++ b/components/gui/include/rtgui/image.h @@ -1,11 +1,21 @@ /* * File : image.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/include/rtgui/image_bmp.h b/components/gui/include/rtgui/image_bmp.h index 47761d5032a3a12cac1ff846ea0ba653aeb8828b..17fffd15e1f07d58365a47d6bfe8905dd9514763 100644 --- a/components/gui/include/rtgui/image_bmp.h +++ b/components/gui/include/rtgui/image_bmp.h @@ -1,11 +1,21 @@ /* * File : image_bmp.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/include/rtgui/image_container.h b/components/gui/include/rtgui/image_container.h new file mode 100644 index 0000000000000000000000000000000000000000..ecf033335975415e4cd436e326fe2baf27fa5532 --- /dev/null +++ b/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 +#include + +#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 + diff --git a/components/gui/include/rtgui/image_hdc.h b/components/gui/include/rtgui/image_hdc.h index 3ec1e7b1ef5ef94ce61507203cf40cf9c028e0d7..25beb93f249d48783acfae39ce3cb882ca103515 100644 --- a/components/gui/include/rtgui/image_hdc.h +++ b/components/gui/include/rtgui/image_hdc.h @@ -1,11 +1,21 @@ /* - * File : image_xpm.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * File : image_hdc.h + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -27,6 +37,21 @@ struct rtgui_image_hdcmm rt_uint8_t *pixels; }; +struct rtgui_image_hdc +{ + rt_bool_t is_loaded; + + /* hdc image information */ + rt_uint16_t byte_per_pixel; + rt_uint16_t pitch; + rt_uint8_t pixel_format; + + rt_size_t pixel_offset; + rt_uint8_t *pixels; + + struct rtgui_filerw *filerw; +}; + void rtgui_image_hdc_init(void); extern const struct rtgui_image_engine rtgui_image_hdcmm_engine; diff --git a/components/gui/include/rtgui/image_jpeg.h b/components/gui/include/rtgui/image_jpeg.h deleted file mode 100644 index 9a22a6880554816fe50369f95c314b151d042bdf..0000000000000000000000000000000000000000 --- a/components/gui/include/rtgui/image_jpeg.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __RTGUI_IMAGE_JPEG_H__ -#define __RTGUI_IMAGE_JPEG_H__ - -#include - -void rtgui_image_jpeg_init(void); - -#endif diff --git a/components/gui/include/rtgui/image_png.h b/components/gui/include/rtgui/image_png.h deleted file mode 100644 index f2a6d2311d32bfd062e664e0a8a75add698655ed..0000000000000000000000000000000000000000 --- a/components/gui/include/rtgui/image_png.h +++ /dev/null @@ -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 - -void rtgui_image_png_init(void); - -#endif diff --git a/components/gui/include/rtgui/image_xpm.h b/components/gui/include/rtgui/image_xpm.h deleted file mode 100644 index 5c6af213137979d42ea99a7c319b343873ea443c..0000000000000000000000000000000000000000 --- a/components/gui/include/rtgui/image_xpm.h +++ /dev/null @@ -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 - -void rtgui_image_xpm_init(void); - -#endif diff --git a/components/gui/include/rtgui/kbddef.h b/components/gui/include/rtgui/kbddef.h index d510445f0a389872acdefdccae0ec8e0e6522fef..a783a93568962e6f74a735be1d64644738e24f11 100644 --- a/components/gui/include/rtgui/kbddef.h +++ b/components/gui/include/rtgui/kbddef.h @@ -1,11 +1,21 @@ /* * File : kbddef.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/include/rtgui/list.h b/components/gui/include/rtgui/list.h index 20b395718135870171ceac54bb1a3ba83d64fe55..6eb77ccf8bf925f5cdc8e145eac67c53dec018c4 100644 --- a/components/gui/include/rtgui/list.h +++ b/components/gui/include/rtgui/list.h @@ -1,11 +1,21 @@ /* * File : list.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/include/rtgui/matrix.h b/components/gui/include/rtgui/matrix.h index 28fd087a767ea5778805e4d5e99a86d7e865a0f1..5d83c4ae85d310e84d65d76249a1577b6468dc4d 100644 --- a/components/gui/include/rtgui/matrix.h +++ b/components/gui/include/rtgui/matrix.h @@ -1,3 +1,27 @@ +/* + * File : matrix.h + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2010-04-10 Grissiom The first version + */ + #ifndef __MATRIX_H__ #define __MATRIX_H__ @@ -12,7 +36,7 @@ * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, + * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all @@ -60,7 +84,7 @@ struct rtgui_matrix * fraction(m/RTGUI_MATRIX_FRAC). While the unit of m[4-5] is pixel. * */ - int m[6]; + int m[6]; }; rt_inline int32_t _rtgui_matrix_round_div32(int32_t n, int32_t d) @@ -100,22 +124,22 @@ rt_inline void rtgui_matrix_mul(struct rtgui_matrix *mm, const struct rtgui_matrix *mm1, const struct rtgui_matrix *mm2) { - int *m = mm->m; - const int *m1 = mm1->m; - const int *m2 = mm2->m; - - m[0] = _rtgui_matrix_round_div32(m1[0] * m2[0] + m1[1] * m2[2], RTGUI_MATRIX_FRAC); - m[1] = _rtgui_matrix_round_div32(m1[0] * m2[1] + m1[1] * m2[3], RTGUI_MATRIX_FRAC); - m[2] = _rtgui_matrix_round_div32(m1[2] * m2[0] + m1[3] * m2[2], RTGUI_MATRIX_FRAC); - m[3] = _rtgui_matrix_round_div32(m1[2] * m2[1] + m1[3] * m2[3], RTGUI_MATRIX_FRAC); - m[4] = _rtgui_matrix_round_div32(m1[4] * m2[0] + m1[5] * m2[2], RTGUI_MATRIX_FRAC) + m2[4]; - m[5] = _rtgui_matrix_round_div32(m1[4] * m2[1] + m1[5] * m2[3], RTGUI_MATRIX_FRAC) + m2[5]; + int *m = mm->m; + const int *m1 = mm1->m; + const int *m2 = mm2->m; + + m[0] = _rtgui_matrix_round_div32(m1[0] * m2[0] + m1[1] * m2[2], RTGUI_MATRIX_FRAC); + m[1] = _rtgui_matrix_round_div32(m1[0] * m2[1] + m1[1] * m2[3], RTGUI_MATRIX_FRAC); + m[2] = _rtgui_matrix_round_div32(m1[2] * m2[0] + m1[3] * m2[2], RTGUI_MATRIX_FRAC); + m[3] = _rtgui_matrix_round_div32(m1[2] * m2[1] + m1[3] * m2[3], RTGUI_MATRIX_FRAC); + m[4] = _rtgui_matrix_round_div32(m1[4] * m2[0] + m1[5] * m2[2], RTGUI_MATRIX_FRAC) + m2[4]; + m[5] = _rtgui_matrix_round_div32(m1[4] * m2[1] + m1[5] * m2[3], RTGUI_MATRIX_FRAC) + m2[5]; } /* Matrix multiply point[(p) = (x, y) * m], ignore the movement components. */ rt_inline void rtgui_matrix_mul_point_nomove(struct rtgui_point *p, - int x, int y, - struct rtgui_matrix *m) + int x, int y, + struct rtgui_matrix *m) { int *mm = m->m; @@ -137,13 +161,13 @@ rt_inline void rtgui_matrix_mul_point(struct rtgui_point *p, /** Set @mm to an identity matrix. */ rt_inline void rtgu_matrix_identity(struct rtgui_matrix *mm) { - int *mat = mm->m; - mat[0] = RTGUI_MATRIX_FRAC; - mat[1] = 0; - mat[2] = 0; - mat[3] = RTGUI_MATRIX_FRAC; - mat[4] = 0; - mat[5] = 0; + int *mat = mm->m; + mat[0] = RTGUI_MATRIX_FRAC; + mat[1] = 0; + mat[2] = 0; + mat[3] = RTGUI_MATRIX_FRAC; + mat[4] = 0; + mat[5] = 0; } /** Save the inversed matrix of @mm to @mo. diff --git a/components/gui/include/rtgui/region.h b/components/gui/include/rtgui/region.h index a540e2b9c93c8d770fd10b6098d88d933108d39a..ef70528d88c0ba52b9ee0e542cbe1d3eb7c07702 100644 --- a/components/gui/include/rtgui/region.h +++ b/components/gui/include/rtgui/region.h @@ -1,11 +1,21 @@ /* * File : region.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -90,6 +100,7 @@ int rtgui_region_is_flat(rtgui_region_t *region); extern rtgui_rect_t rtgui_empty_rect; void rtgui_rect_moveto(rtgui_rect_t *rect, int x, int y); +void rtgui_rect_moveto_point(rtgui_rect_t *rect, int x, int y); void rtgui_rect_moveto_align(const rtgui_rect_t *rect, rtgui_rect_t *to, int align); void rtgui_rect_inflate(rtgui_rect_t *rect, int d); void rtgui_rect_intersect(rtgui_rect_t *src, rtgui_rect_t *dest); @@ -98,11 +109,14 @@ int rtgui_rect_is_intersect(const rtgui_rect_t *rect1, const rtgui_rect_t *rect int rtgui_rect_is_equal(const rtgui_rect_t *rect1, const rtgui_rect_t *rect2); rtgui_rect_t *rtgui_rect_set(rtgui_rect_t *rect, int x, int y, int w, int h); rt_bool_t rtgui_rect_is_empty(const rtgui_rect_t *rect); +void rtgui_rect_union(rtgui_rect_t *src, rtgui_rect_t *dest); rt_inline void rtgui_rect_init(rtgui_rect_t* rect, int x, int y, int width, int height) { - rect->x1 = x; rect->y1 = y; - rect->x2 = x + width; rect->y2 = y + height; + rect->x1 = x; + rect->y1 = y; + rect->x2 = x + width; + rect->y2 = y + height; } #define RTGUI_RECT(rect, x, y, w, h) \ diff --git a/components/gui/include/rtgui/rtgui.h b/components/gui/include/rtgui/rtgui.h index 4837e4103d842f0ea5ecf1945c62f12fc9097498..2ee2503c53de6b28f4de30ead3e57cf3c9873d3e 100644 --- a/components/gui/include/rtgui/rtgui.h +++ b/components/gui/include/rtgui/rtgui.h @@ -1,7 +1,7 @@ /* * File : rtgui.h - * This file is part of RT-Thread GUI - * COPYRIGHT (C) 2009 - 2013, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,19 +31,10 @@ extern "C" { #endif -#define RTGUI_VERSION 0L /**< major version number */ -#define RTGUI_SUBVERSION 8L /**< minor version number */ -#define RTGUI_REVISION 1L /**< revise version number */ -#define RTGUI_CODENAME "Newton" /**< code name */ - -#define RT_INT16_MAX 32767 -#define RT_INT16_MIN (-RT_INT16_MAX-1) -#define RTGUI_NOT_FOUND (-1) - -#define _UI_MIN(x, y) (((x)<(y))?(x):(y)) -#define _UI_MAX(x, y) (((x)>(y))?(x):(y)) -#define _UI_BITBYTES(bits) ((bits + 7)/8) -#define _UI_ABS(x) ((x)>=0? (x):-(x)) +#define _UI_MIN(x, y) (((x)<(y))?(x):(y)) +#define _UI_MAX(x, y) (((x)>(y))?(x):(y)) +#define _UI_BITBYTES(bits) ((bits + 7)/8) +#define _UI_ABS(x) ((x)>=0? (x):-(x)) /* MDK, GCC and MSVC all support __restrict keyword. */ #define RTGUI_RESTRICT __restrict @@ -136,13 +127,13 @@ enum RTGUI_BORDER_STYLE /** * Blend mode - */ + */ enum RTGUI_BLENDMODE { - RTGUI_BLENDMODE_NONE = 0x00, - RTGUI_BLENDMODE_BLEND, - RTGUI_BLENDMODE_ADD, - RTGUI_BLENDMODE_MOD, + RTGUI_BLENDMODE_NONE = 0x00, + RTGUI_BLENDMODE_BLEND, + RTGUI_BLENDMODE_ADD, + RTGUI_BLENDMODE_MOD, }; /** @@ -180,7 +171,8 @@ enum RTGUI_TEXTSTYLE enum RTGUI_MODAL_CODE { RTGUI_MODAL_OK, - RTGUI_MODAL_CANCEL + RTGUI_MODAL_CANCEL, + RTGUI_MODAL_MAX = 0xFFFF, }; typedef enum RTGUI_MODAL_CODE rtgui_modal_code_t; diff --git a/components/gui/include/rtgui/rtgui_app.h b/components/gui/include/rtgui/rtgui_app.h index 452ccb197088da5254b9ab10c9dfd50fda38a036..5cb2c83accdbd02f027137070e89b90954b65789 100644 --- a/components/gui/include/rtgui/rtgui_app.h +++ b/components/gui/include/rtgui/rtgui_app.h @@ -1,11 +1,21 @@ /* * File : rtgui_app.h - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/include/rtgui/rtgui_config.h b/components/gui/include/rtgui/rtgui_config.h index 7d6b1611ff47a560ff798d6a04c2093942cc8a9c..afb728ed84099674a44041c9539c57572a868fed 100644 --- a/components/gui/include/rtgui/rtgui_config.h +++ b/components/gui/include/rtgui/rtgui_config.h @@ -1,11 +1,21 @@ /* * File : rtgui_config.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/include/rtgui/rtgui_object.h b/components/gui/include/rtgui/rtgui_object.h index b70aa851d10acbfebbd78bf17050259847f8ac9f..34b23af5207713a16da674ab9b8b34e889634906 100644 --- a/components/gui/include/rtgui/rtgui_object.h +++ b/components/gui/include/rtgui/rtgui_object.h @@ -1,11 +1,21 @@ /* * File : rtgui_object.h - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -81,10 +91,10 @@ const char *rtgui_type_name_get(const rtgui_type_t *type); const rtgui_type_t *rtgui_object_object_type_get(rtgui_object_t *object); #ifdef RTGUI_USING_CAST_CHECK - #define RTGUI_OBJECT_CAST(obj, obj_type, c_type) \ +#define RTGUI_OBJECT_CAST(obj, obj_type, c_type) \ ((c_type *)rtgui_object_check_cast((rtgui_object_t *)(obj), (obj_type), __FUNCTION__, __LINE__)) #else - #define RTGUI_OBJECT_CAST(obj, obj_type, c_type) ((c_type *)(obj)) +#define RTGUI_OBJECT_CAST(obj, obj_type, c_type) ((c_type *)(obj)) #endif #define RTGUI_OBJECT_CHECK_TYPE(_obj, _type) \ diff --git a/components/gui/include/rtgui/rtgui_server.h b/components/gui/include/rtgui/rtgui_server.h index bb1481e8f482e5c83af978eaf06419741ae290fd..6d73bc5b66f8f6935e6a4a6239e3c55a1a51220f 100644 --- a/components/gui/include/rtgui/rtgui_server.h +++ b/components/gui/include/rtgui/rtgui_server.h @@ -1,11 +1,21 @@ /* * File : rtgui_server.h - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -14,6 +24,10 @@ #ifndef __RTGUI_SERVER_H__ #define __RTGUI_SERVER_H__ +#ifdef __cplusplus +extern "C" { +#endif + #include #include @@ -72,8 +86,11 @@ void rtgui_server_install_show_win_hook(void (*hk)(void)); void rtgui_server_install_act_win_hook(void (*hk)(void)); /* post an event to server */ -void rtgui_server_post_event(struct rtgui_event *event, rt_size_t size); +rt_err_t rtgui_server_post_event(struct rtgui_event *event, rt_size_t size); rt_err_t rtgui_server_post_event_sync(struct rtgui_event *event, rt_size_t size); +#ifdef __cplusplus +} #endif +#endif diff --git a/components/gui/include/rtgui/rtgui_system.h b/components/gui/include/rtgui/rtgui_system.h index 86b649345b09ff1183af30d785bb414d052e5cbe..14d7351e356e0ce0f36ba48ccec3ef7857600edc 100644 --- a/components/gui/include/rtgui/rtgui_system.h +++ b/components/gui/include/rtgui/rtgui_system.h @@ -1,11 +1,21 @@ /* * File : rtgui_system.h - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/include/rtgui/widgets/box.h b/components/gui/include/rtgui/widgets/box.h index 06486b958c241be67afff666f486b20c1644b509..e4ea354478e68a6264f5b3089cc0ec6bfdadb245 100644 --- a/components/gui/include/rtgui/widgets/box.h +++ b/components/gui/include/rtgui/widgets/box.h @@ -1,11 +1,21 @@ /* * File : box.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/include/rtgui/widgets/container.h b/components/gui/include/rtgui/widgets/container.h index fc89a14556a6f9f6f28b8e00ae543cf0282e3752..c45facca2df60b05ca91e1f90250f091176e6ec3 100644 --- a/components/gui/include/rtgui/widgets/container.h +++ b/components/gui/include/rtgui/widgets/container.h @@ -1,11 +1,21 @@ /* * File : container.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/include/rtgui/widgets/title.h b/components/gui/include/rtgui/widgets/title.h index 5394b9e8804522a78ed3a48d0c28bc91ea3e237b..128d1c3143f560797bc26731597ed1c0eafc1e8b 100644 --- a/components/gui/include/rtgui/widgets/title.h +++ b/components/gui/include/rtgui/widgets/title.h @@ -1,11 +1,21 @@ /* * File : title.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/include/rtgui/widgets/widget.h b/components/gui/include/rtgui/widgets/widget.h index 13efcb7e5b6bbb25bb23cc79a9eb775992ec6094..726bd4ae384f2631ce403084e4f93695948e6cf6 100644 --- a/components/gui/include/rtgui/widgets/widget.h +++ b/components/gui/include/rtgui/widgets/widget.h @@ -1,7 +1,7 @@ /* * File : widget.h - * This file is part of RT-Thread GUI - * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -110,6 +110,10 @@ struct rtgui_widget /* the widget extent */ rtgui_rect_t extent; + /* the visiable extent (includes the rectangles of children) */ + rtgui_rect_t extent_visiable; + /* the rect clip information */ + rtgui_region_t clip; /* minimal width and height of widget */ rt_int16_t min_width, min_height; @@ -117,13 +121,10 @@ struct rtgui_widget rt_int32_t align; rt_uint16_t border; rt_uint16_t border_style; - /* the rect clip */ - rtgui_region_t clip; /* call back */ rt_bool_t (*on_focus_in)(struct rtgui_object *widget, struct rtgui_event *event); rt_bool_t (*on_focus_out)(struct rtgui_object *widget, struct rtgui_event *event); - rt_bool_t (*on_paint)(struct rtgui_object *widget, struct rtgui_event *event); /* user private data */ rt_uint32_t user_data; @@ -142,7 +143,6 @@ void rtgui_widget_unfocus(rtgui_widget_t *widget); /* event handler for each command */ void rtgui_widget_set_onfocus(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); void rtgui_widget_set_onunfocus(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); -void rtgui_widget_set_onpaint(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); /* get and set rect of widget */ void rtgui_widget_get_rect(rtgui_widget_t *widget, rtgui_rect_t *rect); diff --git a/components/gui/include/rtgui/widgets/window.h b/components/gui/include/rtgui/widgets/window.h index 635e3bced98688bb6bf7ce50f13dd578cf12a567..362342629681fc4912327f7c94d9e75cd1277493 100644 --- a/components/gui/include/rtgui/widgets/window.h +++ b/components/gui/include/rtgui/widgets/window.h @@ -1,11 +1,21 @@ /* * File : window.h - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -80,6 +90,7 @@ struct rtgui_win /* drawing count */ rt_base_t drawing; + struct rtgui_rect drawing_rect; /* parent window. RT_NULL if the window is a top level window */ struct rtgui_win *parent_window; @@ -135,9 +146,9 @@ rtgui_win_t *rtgui_mainwin_create(struct rtgui_win *parent_window, const char *t void rtgui_win_destroy(rtgui_win_t *win); int rtgui_win_init(struct rtgui_win *win, struct rtgui_win *parent_window, - const char *title, - rtgui_rect_t *rect, - rt_uint16_t style); + const char *title, + rtgui_rect_t *rect, + rt_uint16_t style); int rtgui_win_fini(struct rtgui_win* win); /** Close window. @@ -183,6 +194,8 @@ struct rtgui_dc *rtgui_win_get_drawing(rtgui_win_t * win); struct rtgui_win* rtgui_win_get_topmost_shown(void); struct rtgui_win* rtgui_win_get_next_shown(void); +void rtgui_theme_draw_win(struct rtgui_wintitle *wint); + #ifdef __cplusplus } #endif diff --git a/components/gui/src/asc12font.c b/components/gui/src/asc12font.c index ef2134e63e64d273f28b4ca665b0e4a05c1568ab..b4810ad002f9d88f822048c5dfde25b1a69da35a 100644 --- a/components/gui/src/asc12font.c +++ b/components/gui/src/asc12font.c @@ -1,11 +1,21 @@ /* * File : asc12font.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/src/asc16font.c b/components/gui/src/asc16font.c index 71ebd23c77a7acb1e6645e6963cff2dd9a634b64..2a3ee8758e57af507064b35dec37e8468f2ee1aa 100644 --- a/components/gui/src/asc16font.c +++ b/components/gui/src/asc16font.c @@ -1,11 +1,21 @@ /* * File : asc16font.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -16,262 +26,262 @@ #ifdef RTGUI_USING_FONT16 const unsigned char asc16_font[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, - 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, - 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, - 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00, - 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, - 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, + 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; struct rtgui_font_bitmap asc16 = diff --git a/components/gui/src/blit.c b/components/gui/src/blit.c index 525aa3b25714d99263e00e52e0f02b1fd2069cd5..c9cd4b7904bd76ce3ef8ab910e43d06126b98458 100644 --- a/components/gui/src/blit.c +++ b/components/gui/src/blit.c @@ -1,7 +1,7 @@ /* * File : blit.h - * This file is part of RT-Thread GUI - * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -48,62 +48,74 @@ #include #include #include +#include +#include /* Lookup tables to expand partial bytes to the full 0..255 range */ -static const rt_uint8_t lookup_0[] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, -96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, -122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, -147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, -172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, -197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, -222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, -247, 248, 249, 250, 251, 252, 253, 254, 255 +static const rt_uint8_t lookup_0[] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255 }; -static const rt_uint8_t lookup_1[] = { -0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, -64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, -120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, -168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, -216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 255 +static const rt_uint8_t lookup_1[] = +{ + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, + 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, + 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, + 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, + 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 255 }; -static const rt_uint8_t lookup_2[] = { -0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 85, 89, 93, 97, 101, 105, 109, 113, 117, -121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 214, 218, -222, 226, 230, 234, 238, 242, 246, 250, 255 +static const rt_uint8_t lookup_2[] = +{ + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 85, 89, 93, 97, 101, 105, 109, 113, 117, + 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 214, 218, + 222, 226, 230, 234, 238, 242, 246, 250, 255 }; -static const rt_uint8_t lookup_3[] = { -0, 8, 16, 24, 32, 41, 49, 57, 65, 74, 82, 90, 98, 106, 115, 123, 131, 139, 148, 156, 164, 172, 180, 189, 197, 205, 213, 222, -230, 238, 246, 255 +static const rt_uint8_t lookup_3[] = +{ + 0, 8, 16, 24, 32, 41, 49, 57, 65, 74, 82, 90, 98, 106, 115, 123, 131, 139, 148, 156, 164, 172, 180, 189, 197, 205, 213, 222, + 230, 238, 246, 255 }; -static const rt_uint8_t lookup_4[] = { -0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255 +static const rt_uint8_t lookup_4[] = +{ + 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255 }; -static const rt_uint8_t lookup_5[] = { -0, 36, 72, 109, 145, 182, 218, 255 +static const rt_uint8_t lookup_5[] = +{ + 0, 36, 72, 109, 145, 182, 218, 255 }; -static const rt_uint8_t lookup_6[] = { -0, 85, 170, 255 +static const rt_uint8_t lookup_6[] = +{ + 0, 85, 170, 255 }; -static const rt_uint8_t lookup_7[] = { -0, 255 +static const rt_uint8_t lookup_7[] = +{ + 0, 255 }; -static const rt_uint8_t lookup_8[] = { -255 +static const rt_uint8_t lookup_8[] = +{ + 255 }; -const rt_uint8_t* rtgui_blit_expand_byte[9] = { +const rt_uint8_t* rtgui_blit_expand_byte[9] = +{ lookup_0, lookup_1, lookup_2, @@ -190,34 +202,39 @@ static void rtgui_blit_line_4_2(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int li rt_uint32_t *srcp = (rt_uint32_t *) src_ptr; rt_uint16_t *dstp = (rt_uint16_t *) dst_ptr; - /* *INDENT-OFF* */ - DUFFS_LOOP4({ - rt_uint32_t s = *srcp; - unsigned alpha = s >> 27; /* downscale alpha to 5 bits */ - /* FIXME: Here we special-case opaque alpha since the - compositioning used (>>8 instead of /255) doesn't handle - it correctly. Also special-case alpha=0 for speed? - Benchmark this! */ - if(alpha) { - if(alpha == (255 >> 3)) { - *dstp = (rt_uint16_t)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f)); - } else { - rt_uint32_t d = *dstp; - /* - * convert source and destination to G0RAB65565 - * and blend all components at the same time - */ - s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800) - + (s >> 3 & 0x1f); - d = (d | d << 16) & 0x07e0f81f; - d += (s - d) * alpha >> 5; - d &= 0x07e0f81f; - *dstp = (rt_uint16_t)(d | d >> 16); - } - } - srcp++; - dstp++; - }, width); + /* *INDENT-OFF* */ + DUFFS_LOOP4( + { + rt_uint32_t s = *srcp; + unsigned alpha = s >> 27; /* downscale alpha to 5 bits */ + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if(alpha) + { + if(alpha == (255 >> 3)) + { + *dstp = (rt_uint16_t)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f)); + } + else + { + rt_uint32_t d = *dstp; + /* + * convert source and destination to G0RAB65565 + * and blend all components at the same time + */ + s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800) + + (s >> 3 & 0x1f); + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp = (rt_uint16_t)(d | d >> 16); + } + } + srcp++; + dstp++; + }, width); } static void rtgui_blit_line_1_3(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line) @@ -362,7 +379,8 @@ static const rt_uint32_t RGB565_RGBA8888_LUT[512] = }; /* Special optimized blit for RGB 5-6-5 --> ARGB 8-8-8-8 */ -static const rt_uint32_t RGB565_ARGB8888_LUT[512] = { +static const rt_uint32_t RGB565_ARGB8888_LUT[512] = +{ 0x00000000, 0xff000000, 0x00000008, 0xff002000, 0x00000010, 0xff004000, 0x00000018, 0xff006100, 0x00000020, 0xff008100, 0x00000029, 0xff00a100, @@ -635,13 +653,13 @@ rtgui_blit_line_func rtgui_blit_line_get_inv(int dst_bpp, int src_bpp) /* 16bpp special case for per-surface alpha=50%: blend 2 pixels in parallel */ /* blend a single 16 bit pixel at 50% */ -#define BLEND16_50(d, s, mask) \ - ((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff))) +#define BLEND16_50(d, s, mask) \ + ((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff))) /* blend two 16 bit pixels at 50% */ -#define BLEND2x16_50(d, s, mask) \ - (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \ - + (s & d & (~(mask | mask << 16)))) +#define BLEND2x16_50(d, s, mask) \ + (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \ + + (s & d & (~(mask | mask << 16)))) static void Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask) @@ -653,8 +671,10 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask) rt_uint16_t *dstp = (rt_uint16_t *) info->dst; int dstskip = info->dst_skip >> 1; - while (height--) { - if (((unsigned int) srcp ^ (unsigned int) dstp) & 2) { + while (height--) + { + if (((unsigned int) srcp ^ (unsigned int) dstp) & 2) + { /* * Source and destination not aligned, pipeline it. * This is mostly a win for big blits but no loss for @@ -664,7 +684,8 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask) int w = width; /* handle odd destination */ - if ((unsigned int) dstp & 2) { + if ((unsigned int) dstp & 2) + { rt_uint16_t d = *dstp, s = *srcp; *dstp = BLEND16_50(d, s, mask); dstp++; @@ -676,7 +697,8 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask) /* bootstrap pipeline with first halfword */ prev_sw = ((rt_uint32_t *) srcp)[-1]; - while (w > 1) { + while (w > 1) + { rt_uint32_t sw, dw, s; sw = *(rt_uint32_t *) srcp; dw = *(rt_uint32_t *) dstp; @@ -689,7 +711,8 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask) } /* final pixel if any */ - if (w) { + if (w) + { rt_uint16_t d = *dstp, s; s = (rt_uint16_t) (prev_sw >> 16); *dstp = BLEND16_50(d, s, mask); @@ -698,12 +721,15 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask) } srcp += srcskip - 1; dstp += dstskip; - } else { + } + else + { /* source and destination are aligned */ int w = width; /* first odd pixel? */ - if ((unsigned int) srcp & 2) { + if ((unsigned int) srcp & 2) + { rt_uint16_t d = *dstp, s = *srcp; *dstp = BLEND16_50(d, s, mask); srcp++; @@ -712,7 +738,8 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask) } /* srcp and dstp are now 32-bit aligned */ - while (w > 1) { + while (w > 1) + { rt_uint32_t sw = *(rt_uint32_t *) srcp; rt_uint32_t dw = *(rt_uint32_t *) dstp; *(rt_uint32_t *) dstp = BLEND2x16_50(dw, sw, mask); @@ -722,7 +749,8 @@ Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask) } /* last odd pixel? */ - if (w) { + if (w) + { rt_uint16_t d = *dstp, s = *srcp; *dstp = BLEND16_50(d, s, mask); srcp++; @@ -774,7 +802,8 @@ Blit565to565PixelAlpha(struct rtgui_blit_info * info) rt_uint32_t *srcp = (rt_uint32_t *) info->src; rt_uint32_t *dstp = (rt_uint32_t *) info->dst; - while (height--) { + while (height--) + { DUFFS_LOOP4( { rt_uint32_t s = *srcp++; @@ -814,62 +843,140 @@ Blit565to565PixelAlpha(struct rtgui_blit_info * info) /* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */ static void BlitRGBtoRGBSurfaceAlpha128(struct rtgui_blit_info *info) { - int width = info->dst_w; - int height = info->dst_h; - rt_uint32_t *srcp = (rt_uint32_t *)info->src; - int srcskip = info->src_skip >> 2; - rt_uint32_t *dstp = (rt_uint32_t *)info->dst; - int dstskip = info->dst_skip >> 2; - - while(height--) { - DUFFS_LOOP4({ - rt_uint32_t s = *srcp++; - rt_uint32_t d = *dstp; - *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) - + (s & d & 0x00010101)) | 0xff000000; - }, width); - srcp += srcskip; - dstp += dstskip; - } + int width = info->dst_w; + int height = info->dst_h; + rt_uint32_t *srcp = (rt_uint32_t *)info->src; + int srcskip = info->src_skip >> 2; + rt_uint32_t *dstp = (rt_uint32_t *)info->dst; + int dstskip = info->dst_skip >> 2; + + while(height--) + { + DUFFS_LOOP4( + { + rt_uint32_t s = *srcp++; + rt_uint32_t d = *dstp; + *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) + + (s & d & 0x00010101)) | 0xff000000; + }, width); + srcp += srcskip; + dstp += dstskip; + } } /* fast RGB888->(A)RGB888 blending with surface alpha */ static void BlitRGBtoRGBSurfaceAlpha(struct rtgui_blit_info *info) { - unsigned int alpha = info->a; - if(alpha == 128) { - BlitRGBtoRGBSurfaceAlpha128(info); - } else { - int width = info->dst_w; - int height = info->dst_h; - rt_uint32_t *srcp = (rt_uint32_t *)info->src; - int srcskip = info->src_skip >> 2; - rt_uint32_t *dstp = (rt_uint32_t *)info->dst; - int dstskip = info->dst_skip >> 2; - - while(height--) { - DUFFS_LOOP4({ - rt_uint32_t s; - rt_uint32_t d; - rt_uint32_t s1; - rt_uint32_t d1; - s = *srcp; - d = *dstp; - s1 = s & 0xff00ff; - d1 = d & 0xff00ff; - d1 = (d1 + ((s1 - d1) * alpha >> 8)) - & 0xff00ff; - s &= 0xff00; - d &= 0xff00; - d = (d + ((s - d) * alpha >> 8)) & 0xff00; - *dstp = d1 | d | 0xff000000; - ++srcp; - ++dstp; - }, width); - srcp += srcskip; - dstp += dstskip; - } - } + unsigned int alpha = info->a; + if(alpha == 128) + { + BlitRGBtoRGBSurfaceAlpha128(info); + } + else + { + int width = info->dst_w; + int height = info->dst_h; + rt_uint32_t *srcp = (rt_uint32_t *)info->src; + int srcskip = info->src_skip >> 2; + rt_uint32_t *dstp = (rt_uint32_t *)info->dst; + int dstskip = info->dst_skip >> 2; + + while(height--) + { + DUFFS_LOOP4( + { + rt_uint32_t s; + rt_uint32_t d; + rt_uint32_t s1; + rt_uint32_t d1; + s = *srcp; + d = *dstp; + s1 = s & 0xff00ff; + d1 = d & 0xff00ff; + d1 = (d1 + ((s1 - d1) * alpha >> 8)) + & 0xff00ff; + s &= 0xff00; + d &= 0xff00; + d = (d + ((s - d) * alpha >> 8)) & 0xff00; + *dstp = d1 | d | 0xff000000; + ++srcp; + ++dstp; + }, width); + srcp += srcskip; + dstp += dstskip; + } + } +} + +/* fast alpha -> RGB565 blending with pixel alpha */ +static void BlitAlphato565PixelAlpha(struct rtgui_blit_info * info) +{ + rt_uint32_t srcpixel, dstpixel; + rt_uint32_t srcR, srcG, srcB, srcA; + + + srcR = info->r; + srcG = info->g; + srcB = info->b; + + while (info->dst_h--) + { + rt_uint8_t *src = (rt_uint8_t *)info->src; + rt_uint16_t *dst = (rt_uint16_t *)info->dst; + int n = info->dst_w; + while (n--) + { + srcA = (rt_uint8_t)(*src); + ARGB8888_FROM_RGBA(srcpixel, srcR, srcG, srcB, srcA); + + /* not do alpha blend */ + if (srcA == 255) + { + dstpixel = srcpixel; + } + else if (srcA >> 3 == 0) + { + /* keep original pixel data */ + } + else + { + dstpixel = ((rt_uint32_t)srcA << 24) | ((rt_uint32_t)srcR << 16) | ((rt_uint32_t)srcG << 8) | srcB; + } + + if (srcA >> 3 != 0) + { + rt_uint32_t s = dstpixel; + unsigned alpha = s >> 27; + if (alpha) + { + if (alpha == (255 >> 3)) + { + *dst = (rt_uint16_t)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f)); + } + else + { + rt_uint32_t d = *dst; + /* + * convert source and destination to G0RAB65565 + * and blend all components at the same time + */ + s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800) + + (s >> 3 & 0x1f); + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dst = (rt_uint16_t)(d | d >> 16); + } + } + } + + ++src; + ++dst; + } + + info->src += info->src_pitch; + info->dst += info->dst_pitch; + } } /* fast ARGB8888->RGB565 blending with pixel alpha */ @@ -882,36 +989,42 @@ static void BlitARGBto565PixelAlpha(struct rtgui_blit_info * info) rt_uint16_t *dstp = (rt_uint16_t *) info->dst; int dstskip = info->dst_skip >> 1; - while (height--) { - /* *INDENT-OFF* */ - DUFFS_LOOP4({ - rt_uint32_t s = *srcp; - unsigned alpha = s >> 27; /* downscale alpha to 5 bits */ - /* FIXME: Here we special-case opaque alpha since the - compositioning used (>>8 instead of /255) doesn't handle - it correctly. Also special-case alpha=0 for speed? - Benchmark this! */ - if(alpha) { - if(alpha == (255 >> 3)) { - *dstp = (rt_uint16_t)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f)); - } else { - rt_uint32_t d = *dstp; - /* - * convert source and destination to G0RAB65565 - * and blend all components at the same time - */ - s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800) - + (s >> 3 & 0x1f); - d = (d | d << 16) & 0x07e0f81f; - d += (s - d) * alpha >> 5; - d &= 0x07e0f81f; - *dstp = (rt_uint16_t)(d | d >> 16); - } - } - srcp++; - dstp++; - }, width); - /* *INDENT-ON* */ + while (height--) + { + /* *INDENT-OFF* */ + DUFFS_LOOP4( + { + rt_uint32_t s = *srcp; + unsigned alpha = s >> 27; /* downscale alpha to 5 bits */ + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if(alpha) + { + if(alpha == (255 >> 3)) + { + *dstp = (rt_uint16_t)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f)); + } + else + { + rt_uint32_t d = *dstp; + /* + * convert source and destination to G0RAB65565 + * and blend all components at the same time + */ + s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800) + + (s >> 3 & 0x1f); + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp = (rt_uint16_t)(d | d >> 16); + } + } + srcp++; + dstp++; + }, width); + /* *INDENT-ON* */ srcp += srcskip; dstp += dstskip; } @@ -920,49 +1033,120 @@ static void BlitARGBto565PixelAlpha(struct rtgui_blit_info * info) /* fast ARGB888->(A)RGB888 blending with pixel alpha */ static void BlitRGBtoRGBPixelAlpha(struct rtgui_blit_info *info) { - int width = info->dst_w; - int height = info->dst_h; - rt_uint32_t *srcp = (rt_uint32_t *)info->src; - int srcskip = info->src_skip >> 2; - rt_uint32_t *dstp = (rt_uint32_t *)info->dst; - int dstskip = info->dst_skip >> 2; - - while(height--) { - DUFFS_LOOP4({ - rt_uint32_t dalpha; - rt_uint32_t d; - rt_uint32_t s1; - rt_uint32_t d1; - rt_uint32_t s = *srcp; - rt_uint32_t alpha = s >> 24; - - /* FIXME: Here we special-case opaque alpha since the - compositioning used (>>8 instead of /255) doesn't handle - it correctly. Also special-case alpha=0 for speed? - Benchmark this! */ - if(alpha == 255) { - *dstp = (s & 0x00ffffff) | (*dstp & 0xff000000); - } else { - /* - * take out the middle component (green), and process - * the other two in parallel. One multiply less. - */ - d = *dstp; - dalpha = d & 0xff000000; - s1 = s & 0xff00ff; - d1 = d & 0xff00ff; - d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; - s &= 0xff00; - d &= 0xff00; - d = (d + ((s - d) * alpha >> 8)) & 0xff00; - *dstp = d1 | d | dalpha; - } - ++srcp; - ++dstp; - }, width); - srcp += srcskip; - dstp += dstskip; - } + int width = info->dst_w; + int height = info->dst_h; + rt_uint32_t *srcp = (rt_uint32_t *)info->src; + int srcskip = info->src_skip >> 2; + rt_uint32_t *dstp = (rt_uint32_t *)info->dst; + int dstskip = info->dst_skip >> 2; + + while(height--) + { + DUFFS_LOOP4( + { + rt_uint32_t dalpha; + rt_uint32_t d; + rt_uint32_t s1; + rt_uint32_t d1; + rt_uint32_t s = *srcp; + rt_uint32_t alpha = s >> 24; + + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if(alpha == 255) + { + *dstp = (s & 0x00ffffff) | (*dstp & 0xff000000); + } + else { + /* + * take out the middle component (green), and process + * the other two in parallel. One multiply less. + */ + d = *dstp; + dalpha = d & 0xff000000; + s1 = s & 0xff00ff; + d1 = d & 0xff00ff; + d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; + s &= 0xff00; + d &= 0xff00; + d = (d + ((s - d) * alpha >> 8)) & 0xff00; + *dstp = d1 | d | dalpha; + } + ++srcp; + ++dstp; + }, width); + srcp += srcskip; + dstp += dstskip; + } +} + +static void BlitAlphatoARGB8888PixelAlpha(struct rtgui_blit_info *info) +{ + rt_uint32_t srcpixel; + rt_uint32_t srcR, srcG, srcB, srcA; + rt_uint32_t dstpixel; + rt_uint32_t dstR, dstG, dstB, dstA; + + srcR = info->r; + srcG = info->g; + srcB = info->b; + + while (info->dst_h--) + { + rt_uint8_t *src = (rt_uint8_t *)info->src; + rt_uint32_t *dst = (rt_uint32_t *)info->dst; + int n = info->dst_w; + while (n--) + { + srcA = (rt_uint8_t)(*src); + ARGB8888_FROM_RGBA(srcpixel, srcR, srcG, srcB, srcA); + + /* not do alpha blend */ + if (srcA == 255) + { + *dst = srcpixel; + } + else if (srcA >> 3 == 0) + { + /* keep original pixel data */ + } + else + { + dstpixel = *dst; + dstA = (rt_uint8_t)(dstpixel >> 24); + dstR = (rt_uint8_t)(dstpixel >> 16); + dstG = (rt_uint8_t)(dstpixel >> 8); + dstB = (rt_uint8_t)dstpixel; + + if (dstA) + { + int alpha = srcA + 1; + int inverse_alpha = 257 - alpha; + + dstR = ((srcR * alpha) + (inverse_alpha * dstR)) >> 8; + dstG = ((srcG * alpha) + (inverse_alpha * dstG)) >> 8; + dstB = ((srcB * alpha) + (inverse_alpha * dstB)) >> 8; + dstA = srcA + ((255 - srcA) * dstA) / 255; + + dstpixel = ((rt_uint32_t)dstA << 24) | ((rt_uint32_t)dstR << 16) | ((rt_uint32_t)dstG << 8) | dstB; + } + else + { + dstpixel = ((rt_uint32_t)srcA << 24) | ((rt_uint32_t)srcR << 16) | ((rt_uint32_t)srcG << 8) | srcB; + } + + *dst = dstpixel; + } + + ++src; + ++dst; + } + + info->src += info->src_pitch; + info->dst += info->dst_pitch; + } } static void BlitARGB8888toARGB8888PixelAlpha(struct rtgui_blit_info *info) @@ -972,23 +1156,50 @@ static void BlitARGB8888toARGB8888PixelAlpha(struct rtgui_blit_info *info) rt_uint32_t dstpixel; rt_uint32_t dstR, dstG, dstB, dstA; - while (info->dst_h--) { + while (info->dst_h--) + { rt_uint32_t *src = (rt_uint32_t *)info->src; rt_uint32_t *dst = (rt_uint32_t *)info->dst; int n = info->dst_w; - while (n--) { + while (n--) + { srcpixel = *src; - srcA = (rt_uint8_t)(srcpixel >> 24); srcR = (rt_uint8_t)(srcpixel >> 16); srcG = (rt_uint8_t)(srcpixel >> 8); srcB = (rt_uint8_t)srcpixel; - dstpixel = *dst; - dstA = (rt_uint8_t)(dstpixel >> 24); dstR = (rt_uint8_t)(dstpixel >> 16); dstG = (rt_uint8_t)(dstpixel >> 8); dstB = (rt_uint8_t)dstpixel; + srcA = (rt_uint8_t)(srcpixel >> 24); - dstR = srcR + ((255 - srcA) * dstR) / 255; - dstG = srcG + ((255 - srcA) * dstG) / 255; - dstB = srcB + ((255 - srcA) * dstB) / 255; - dstA = srcA + ((255 - srcA) * dstA) / 255; + /* not do alpha blend */ + if (srcA == 255) + { + *dst = srcpixel; + } + else if (srcA == 0) + { + /* keep original pixel data */ + } + else + { + srcR = (rt_uint8_t)(srcpixel >> 16); + srcG = (rt_uint8_t)(srcpixel >> 8); + srcB = (rt_uint8_t)srcpixel; + dstpixel = *dst; + dstA = (rt_uint8_t)(dstpixel >> 24); + dstR = (rt_uint8_t)(dstpixel >> 16); + dstG = (rt_uint8_t)(dstpixel >> 8); + dstB = (rt_uint8_t)dstpixel; + + { + int alpha = srcA + 1; + int inverse_alpha = 257 - alpha; + + dstR = ((srcR * alpha) + (inverse_alpha * dstR)) >> 8; + dstG = ((srcG * alpha) + (inverse_alpha * dstG)) >> 8; + dstB = ((srcB * alpha) + (inverse_alpha * dstB)) >> 8; + dstA = srcA + ((255 - srcA) * dstA) / 255; + } + + dstpixel = ((rt_uint32_t)dstA << 24) | ((rt_uint32_t)dstR << 16) | ((rt_uint32_t)dstG << 8) | dstB; + *dst = dstpixel; + } - dstpixel = ((rt_uint32_t)dstA << 24) | ((rt_uint32_t)dstR << 16) | ((rt_uint32_t)dstG << 8) | dstB; - *dst = dstpixel; ++src; ++dst; } @@ -1015,7 +1226,8 @@ BlitRGB565to32(struct rtgui_blit_info * info, const rt_uint32_t* map) dst = (rt_uint32_t *) info->dst; dstskip = info->dst_skip / 4; - while (height--) { + while (height--) + { /* *INDENT-OFF* */ DUFFS_LOOP( { @@ -1049,7 +1261,7 @@ void rtgui_blit(struct rtgui_blit_info * info) { info->dst_w = info->src_w; info->dst_skip = info->dst_pitch - info->dst_w * - rtgui_color_get_bpp(info->dst_fmt); + rtgui_color_get_bpp(info->dst_fmt); } else if (info->src_w > info->dst_w) { @@ -1060,64 +1272,175 @@ void rtgui_blit(struct rtgui_blit_info * info) if (info->src_h < info->dst_h) info->dst_h = info->src_h; - if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB565) - { - if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB565) - Blit565to565PixelAlpha(info); - else if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888) - BlitRGB565toARGB8888(info); - } - else if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888) - { - if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB565) - BlitARGBto565PixelAlpha(info); - else if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB888) - BlitRGBtoRGBPixelAlpha(info); - else if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888) - BlitARGB8888toARGB8888PixelAlpha(info); - } + if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB565) + { + if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB565) + Blit565to565PixelAlpha(info); + else if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888) + BlitRGB565toARGB8888(info); + } + else if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888) + { + switch (info->dst_fmt) + { + case RTGRAPHIC_PIXEL_FORMAT_RGB565: + BlitARGBto565PixelAlpha(info); + break; + case RTGRAPHIC_PIXEL_FORMAT_RGB888: + BlitRGBtoRGBPixelAlpha(info); + break; + case RTGRAPHIC_PIXEL_FORMAT_ARGB888: + BlitARGB8888toARGB8888PixelAlpha(info); + break; + } + } else if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB888) { if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888) BlitRGBtoRGBSurfaceAlpha(info); } + else if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_ALPHA) + { + switch (info->dst_fmt) + { + case RTGRAPHIC_PIXEL_FORMAT_RGB565: + BlitAlphato565PixelAlpha(info); + break; + case RTGRAPHIC_PIXEL_FORMAT_RGB888: + break; + case RTGRAPHIC_PIXEL_FORMAT_ARGB888: + BlitAlphatoARGB8888PixelAlpha(info); + break; + } + } } RTM_EXPORT(rtgui_blit); -#if 0 -void rtgui_blit_client(rtgui_blit_info_src* src, struct rtgui_dc* client, struct rtgui_rect *dc_rect) +void rtgui_image_info_blit(struct rtgui_image_info* image, struct rtgui_dc* dc, struct rtgui_rect *dc_rect) { - int index; - struct rtgui_widget* widget; - rtgui_region_t clip_region; - rtgui_rect_t rect; - - /* get owner widget */ - widget = RTGUI_CONTAINER_OF(client, struct rtgui_widget, dc_type); - /* get rect information */ - if (dc_rect == NULL) rtgui_dc_get_rect(client, &rect); - else rect = *dc_rect; - - /* to device */ - rtgui_rect_moveto(&rect, widget->extent.x1, widget->extent.y1); - /* get the clipped region */ - rtgui_region_intersect_rect(&clip_region, &widget->clip, &rect); - - /* only 1 rect in extant */ - if (clip_region.data == RT_NULL) - { - struct rtgui_blit_info info; - } - else - { - /* blit on each rect */ - for (index = 0; index < clip_region.data.numRects; index ++) - { - } - } - - rtgui_region_fini(&clip_region); -} -RTM_EXPORT(rtgui_blit_client); -#endif + rt_uint8_t bpp, hw_bpp; + struct rtgui_widget *owner; + struct rtgui_blit_info info; + struct rtgui_rect dest_extent; + struct rtgui_graphic_driver *hw_driver; + + hw_driver = rtgui_graphic_driver_get_default(); + dest_extent = *dc_rect; + + if (dc->type == RTGUI_DC_CLIENT && hw_driver->framebuffer) + { + int index, num_rects; + struct rtgui_rect *rects; + struct rtgui_region dest_region; + + bpp = rtgui_color_get_bpp(image->src_fmt); + hw_bpp = rtgui_color_get_bpp(hw_driver->pixel_format); + + owner = RTGUI_CONTAINER_OF(dc, struct rtgui_widget, dc_type); + rtgui_widget_rect_to_device(owner, &dest_extent); + /* get intersect region clip */ + rtgui_region_init_with_extents(&dest_region, &dest_extent); + rtgui_region_intersect_rect(&dest_region, &(owner->clip), &dest_extent); + + num_rects = rtgui_region_num_rects(&dest_region); + rects = rtgui_region_rects(&dest_region); + + /* fill common info */ + info.a = image->a; + info.src_fmt = image->src_fmt; + info.src_pitch = image->src_pitch; + + info.dst_fmt = hw_driver->pixel_format; + info.dst_pitch = hw_driver->pitch; + + for (index = 0; index < num_rects; index ++) + { + struct rtgui_rect *r = &rects[index]; + + /* blit source */ + info.src = image->pixels + (r->x1 - dest_extent.x1) * bpp + (r->y1 - dest_extent.y1) * image->src_pitch; + info.src_h = rtgui_rect_height(*r); + info.src_w = rtgui_rect_width(*r); + info.src_skip = info.src_pitch - info.src_w * bpp; + + /* blit destination */ + info.dst = (rt_uint8_t*)hw_driver->framebuffer + r->y1 * hw_driver->pitch + + r->x1 * hw_bpp; + info.dst_h = rtgui_rect_height(*r); + info.dst_w = rtgui_rect_width(*r); + info.dst_skip = info.dst_pitch - info.dst_w * hw_bpp; + + rtgui_blit(&info); + } + + rtgui_region_fini(&dest_region); + } + else if (dc->type == RTGUI_DC_HW && hw_driver->framebuffer) + { + struct rtgui_dc_hw *hw = (struct rtgui_dc_hw *)dc; + struct rtgui_rect *r; + + bpp = rtgui_color_get_bpp(image->src_fmt); + hw_bpp = rtgui_color_get_bpp(hw_driver->pixel_format); + + owner = hw->owner; + rtgui_widget_rect_to_device(owner, &dest_extent); + r = &dest_extent; + + /* fill common info */ + info.a = image->a; + info.src_fmt = image->src_fmt; + info.src_pitch = image->src_pitch; + + info.dst_fmt = hw_driver->pixel_format; + info.dst_pitch = hw_driver->pitch; + + /* blit source */ + info.src = image->pixels; + info.src_h = rtgui_rect_height(*r); + info.src_w = rtgui_rect_width(*r); + info.src_skip = info.src_pitch - info.src_w * bpp; + + /* blit destination */ + info.dst = (rt_uint8_t*)hw_driver->framebuffer + r->y1 * hw_driver->pitch + r->x1 * hw_bpp; + info.dst_h = rtgui_rect_height(*r); + info.dst_w = rtgui_rect_width(*r); + info.dst_skip = info.dst_pitch - info.dst_w * hw_bpp; + + rtgui_blit(&info); + } + else if (dc->type == RTGUI_DC_BUFFER) + { + struct rtgui_rect *r; + struct rtgui_dc_buffer *dc_buffer = (struct rtgui_dc_buffer*)dc; + + bpp = rtgui_color_get_bpp(image->src_fmt); + hw_bpp = rtgui_color_get_bpp(dc_buffer->pixel_format); + + r = &dest_extent; + + /* fill common info */ + info.a = image->a; + info.src_fmt = image->src_fmt; + info.src_pitch = image->src_pitch; + + info.dst_fmt = dc_buffer->pixel_format; + info.dst_pitch = dc_buffer->pitch; + + /* blit source */ + info.src = image->pixels; + info.src_w = rtgui_rect_width(*r); + info.src_h = rtgui_rect_height(*r); + info.src_skip = info.src_pitch - info.src_w * bpp; + + /* blit destination */ + info.dst = (rt_uint8_t*)dc_buffer->pixel + r->y1 * dc_buffer->pitch + r->x1 * hw_bpp; + info.dst_w = rtgui_rect_width(*r); + info.dst_h = rtgui_rect_height(*r); + info.dst_skip = info.dst_pitch - info.dst_w * hw_bpp; + + rtgui_blit(&info); + } +} +RTM_EXPORT(rtgui_image_info_blit); diff --git a/components/gui/src/box.c b/components/gui/src/box.c index 1871d56b49f60b35e92cbe41aebc4c791cd317bb..4de36056a6688538957f5ed882cd95a4818b08bb 100644 --- a/components/gui/src/box.c +++ b/components/gui/src/box.c @@ -1,11 +1,21 @@ /* * File : box.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/src/color.c b/components/gui/src/color.c index d41704bc329e1052a0eb559a33e22194bc642006..289f56732f7c84d108af972f3d3e73f5eeb78ac8 100644 --- a/components/gui/src/color.c +++ b/components/gui/src/color.c @@ -1,11 +1,21 @@ /* * File : color.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/src/container.c b/components/gui/src/container.c index d9f1e79719c43e30a6de09058d2184c0ff5e82bb..5d1c2009ca11ca29492ed0e720ae098ecdb5e592 100644 --- a/components/gui/src/container.c +++ b/components/gui/src/container.c @@ -1,11 +1,21 @@ /* * File : container.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -49,15 +59,41 @@ rt_bool_t rtgui_container_dispatch_event(rtgui_container_t *container, rtgui_eve { /* handle in child widget */ struct rtgui_list_node *node; + rtgui_event_t _event, save_event = *event; + rtgui_widget_t *widget = (rtgui_widget_t *)container; rtgui_list_foreach(node, &(container->children)) { struct rtgui_widget *w; w = rtgui_list_entry(node, struct rtgui_widget, sibling); + _event = save_event; + + if (RTGUI_EVENT_PAINT & _event.type) + { + if (widget->extent.x1 > w->extent.x2) + { + _event.type &= !RTGUI_EVENT_PAINT; + } + else if (widget->extent.x2 < w->extent.x1) + { + _event.type &= !RTGUI_EVENT_PAINT; + } + else if (widget->extent.y1 > w->extent.y2) + { + _event.type &= !RTGUI_EVENT_PAINT; + } + else if (widget->extent.y2 < w->extent.y1) + { + _event.type &= !RTGUI_EVENT_PAINT; + } + } + if (RTGUI_OBJECT(w)->event_handler && - RTGUI_OBJECT(w)->event_handler(RTGUI_OBJECT(w), event) == RT_TRUE) + RTGUI_OBJECT(w)->event_handler(RTGUI_OBJECT(w), &_event) == RT_TRUE) + { return RT_TRUE; + } } return RT_FALSE; @@ -140,7 +176,7 @@ rt_bool_t rtgui_container_event_handler(struct rtgui_object *object, struct rtgu /* paint on each child */ rtgui_container_dispatch_event(container, event); - rtgui_dc_end_drawing(dc); + rtgui_dc_end_drawing(dc, 1); } break; @@ -158,8 +194,8 @@ rt_bool_t rtgui_container_event_handler(struct rtgui_object *object, struct rtgu rtgui_container_dispatch_event(container, event); break; case RTGUI_EVENT_HIDE: - rtgui_widget_onhide(RTGUI_OBJECT(container), event); rtgui_container_dispatch_event(container, event); + rtgui_widget_onhide(RTGUI_OBJECT(container), event); break; case RTGUI_EVENT_COMMAND: rtgui_container_dispatch_event(container, event); diff --git a/components/gui/src/dc.c b/components/gui/src/dc.c index 59d0e7ec4a6026ae132c8d16bf859f29b2d18c72..b7d16d30faa57c36307b282a23cf58057ff2276c 100644 --- a/components/gui/src/dc.c +++ b/components/gui/src/dc.c @@ -1,11 +1,21 @@ /* * File : dc.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -19,8 +29,6 @@ #include #include -#include -#include #include #include @@ -690,21 +698,20 @@ void rtgui_dc_draw_arc(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16 /* * Draw arc + * Octant labelling + * + * \ 5 | 6 / + * \ | / + * 4 \ | / 7 + * \|/ + *------+------ +x + * /|\ + * 3 / | \ 0 + * / | \ + * / 2 | 1 \ + * +y */ - // Octant labelling - // - // \ 5 | 6 / - // \ | / - // 4 \ | / 7 - // \|/ - //------+------ +x - // /|\ - // 3 / | \ 0 - // / | \ - // / 2 | 1 \ - // +y - drawoct = 0; // 0x00000000 // whether or not to keep drawing a given octant. // For example: 0x00111100 means we're drawing in octants 2-5 @@ -1319,18 +1326,20 @@ void rtgui_dc_draw_pie(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16 } RTM_EXPORT(rtgui_dc_draw_pie); -// Octant labelling -// -// \ 5 | 6 / -// \ | / -// 4 \ | / 7 -// \|/ -//------+------ +x -// /|\ -// 3 / | \ 0 -// / | \ -// / 2 | 1 \ -// +y +/* + * Octant labelling + * + * \ 5 | 6 / + * \ | / + * 4 \ | / 7 + * \|/ + *------+------ +x + * /|\ + * 3 / | \ 0 + * / | \ + * / 2 | 1 \ + * +y + */ static void _draw_octant(struct rtgui_dc *dc, rt_int16_t ox, rt_int16_t oy, rt_int16_t y1, rt_int16_t y2, rt_int16_t x, int oct) @@ -1814,6 +1823,10 @@ struct rtgui_dc *rtgui_dc_begin_drawing(rtgui_widget_t *owner) return RT_NULL; /* increase drawing count */ + if (win->drawing == 0) + { + memset(&(win->drawing_rect), 0x0, sizeof(struct rtgui_rect)); + } win->drawing ++; /* always drawing on the virtual mode */ @@ -1873,7 +1886,7 @@ struct rtgui_dc *rtgui_dc_begin_drawing(rtgui_widget_t *owner) } RTM_EXPORT(rtgui_dc_begin_drawing); -void rtgui_dc_end_drawing(struct rtgui_dc *dc) +void rtgui_dc_end_drawing(struct rtgui_dc *dc, rt_bool_t update) { struct rtgui_widget *owner; struct rtgui_win *win; @@ -1889,30 +1902,47 @@ void rtgui_dc_end_drawing(struct rtgui_dc *dc) /* get window */ win = owner->toplevel; + /* union drawing rect */ + rtgui_rect_union(&(owner->extent_visiable), &(win->drawing_rect)); /* decrease drawing counter */ - win->drawing --; - if (win->drawing == 0 && rtgui_graphic_driver_is_vmode() == RT_FALSE) - { -#ifdef RTGUI_USING_MOUSE_CURSOR - rt_mutex_release(&cursor_mutex); - /* show cursor */ - rtgui_mouse_show_cursor(); -#endif + win->drawing--; - if (RTGUI_IS_WINTITLE(win)) + if (win->drawing == 0) + { + /* notify window to handle window update done */ + if (RTGUI_OBJECT(win)->event_handler) { - /* update screen */ - rtgui_graphic_driver_screen_update(rtgui_graphic_driver_get_default(), - &(owner->extent)); + struct rtgui_event_win_update_end ewin_update; + + RTGUI_EVENT_WIN_UPDATE_END_INIT(&(ewin_update)); + ewin_update.rect = win->drawing_rect; + + RTGUI_OBJECT(win)->event_handler(RTGUI_OBJECT(win), (struct rtgui_event *)&ewin_update); } - else + + if (rtgui_graphic_driver_is_vmode() == RT_FALSE && update) { - /* send to server for window update */ - struct rtgui_event_update_end eupdate; - RTGUI_EVENT_UPDATE_END_INIT(&(eupdate)); - eupdate.rect = owner->extent; +#ifdef RTGUI_USING_MOUSE_CURSOR + rt_mutex_release(&cursor_mutex); + /* show cursor */ + rtgui_mouse_show_cursor(); +#endif - rtgui_server_post_event((struct rtgui_event *)&eupdate, sizeof(eupdate)); + if (RTGUI_IS_WINTITLE(win)) + { + /* update screen */ + rtgui_graphic_driver_screen_update(rtgui_graphic_driver_get_default(), + &(owner->extent)); + } + else + { + /* send to server for window update */ + struct rtgui_event_update_end eupdate; + RTGUI_EVENT_UPDATE_END_INIT(&(eupdate)); + eupdate.rect = owner->extent; + + rtgui_server_post_event((struct rtgui_event *)&eupdate, sizeof(eupdate)); + } } } @@ -1920,4 +1950,3 @@ void rtgui_dc_end_drawing(struct rtgui_dc *dc) rtgui_screen_unlock(); } RTM_EXPORT(rtgui_dc_end_drawing); - diff --git a/components/gui/src/dc_blend.c b/components/gui/src/dc_blend.c index 682cb5a81ad452ebf4eff9236483c9bdb2234996..83081f495b9f5483a20160d49a9453fa63f1deea 100644 --- a/components/gui/src/dc_blend.c +++ b/components/gui/src/dc_blend.c @@ -1,7 +1,7 @@ /* * File : dc_blend.c - * This file is part of RT-Thread GUI - * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -48,20 +48,20 @@ /* SDL2_gfx: graphics primitives for SDL Copyright (C) 2012 Andreas Schiffler - + This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. - + Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: - + 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. - + 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. @@ -77,70 +77,66 @@ #include #include - -#ifdef __CC_ARM -/* Keil define `abs` in stdlib... */ #include -#endif #define hw_driver (rtgui_graphic_driver_get_default()) #define _int_swap(x, y) do {x ^= y; y ^= x; x ^= y;} while (0) rt_inline rt_uint8_t _dc_get_bits_per_pixel(struct rtgui_dc* dc) { - rt_uint8_t bits_per_pixel = 0; + rt_uint8_t bits_per_pixel = 0; - if (dc->type == RTGUI_DC_HW || dc->type == RTGUI_DC_CLIENT) - bits_per_pixel = hw_driver->bits_per_pixel; - else if (dc->type == RTGUI_DC_BUFFER) - { - struct rtgui_dc_buffer *buffer = (struct rtgui_dc_buffer*)dc; + if (dc->type == RTGUI_DC_HW || dc->type == RTGUI_DC_CLIENT) + bits_per_pixel = hw_driver->bits_per_pixel; + else if (dc->type == RTGUI_DC_BUFFER) + { + struct rtgui_dc_buffer *buffer = (struct rtgui_dc_buffer*)dc; - bits_per_pixel = rtgui_color_get_bits(buffer->pixel_format); - } + bits_per_pixel = rtgui_color_get_bits(buffer->pixel_format); + } - return bits_per_pixel; + return bits_per_pixel; } rt_inline rt_uint16_t _dc_get_pitch(struct rtgui_dc* dc) { - rt_uint16_t pitch = 0; + rt_uint16_t pitch = 0; - if (dc->type == RTGUI_DC_HW || dc->type == RTGUI_DC_CLIENT) - pitch = hw_driver->pitch; - else if (dc->type == RTGUI_DC_BUFFER) - { - struct rtgui_dc_buffer *dc_buffer; + if (dc->type == RTGUI_DC_HW || dc->type == RTGUI_DC_CLIENT) + pitch = hw_driver->pitch; + else if (dc->type == RTGUI_DC_BUFFER) + { + struct rtgui_dc_buffer *dc_buffer; - dc_buffer = (struct rtgui_dc_buffer*)dc; - pitch = dc_buffer->pitch; - } + dc_buffer = (struct rtgui_dc_buffer*)dc; + pitch = dc_buffer->pitch; + } - return pitch; + return pitch; } rt_inline rt_uint8_t* _dc_get_pixel(struct rtgui_dc* dc, int x, int y) { - rt_uint8_t *pixel = RT_NULL; + rt_uint8_t *pixel = RT_NULL; - if ((dc->type == RTGUI_DC_HW) || (dc->type == RTGUI_DC_CLIENT)) - { - pixel = (rt_uint8_t*)(hw_driver->framebuffer); - if (pixel == RT_NULL) return RT_NULL; + if ((dc->type == RTGUI_DC_HW) || (dc->type == RTGUI_DC_CLIENT)) + { + pixel = (rt_uint8_t*)(hw_driver->framebuffer); + if (pixel == RT_NULL) return RT_NULL; - pixel = pixel + y * hw_driver->pitch + x * (_UI_BITBYTES(hw_driver->bits_per_pixel)); - } - else if (dc->type == RTGUI_DC_BUFFER) - { - struct rtgui_dc_buffer *dc_buffer; + pixel = pixel + y * hw_driver->pitch + x * (_UI_BITBYTES(hw_driver->bits_per_pixel)); + } + else if (dc->type == RTGUI_DC_BUFFER) + { + struct rtgui_dc_buffer *dc_buffer; - dc_buffer = (struct rtgui_dc_buffer*)dc; + dc_buffer = (struct rtgui_dc_buffer*)dc; - pixel = dc_buffer->pixel + y * dc_buffer->pitch + - x * rtgui_color_get_bpp(dc_buffer->pixel_format); - } + pixel = dc_buffer->pixel + y * dc_buffer->pitch + + x * rtgui_color_get_bpp(dc_buffer->pixel_format); + } - return pixel; + return pixel; } /* Use the Cohen-Sutherland algorithm for line clipping */ @@ -152,25 +148,25 @@ rt_inline rt_uint8_t* _dc_get_pixel(struct rtgui_dc* dc, int x, int y) static int ComputeOutCode(const rtgui_rect_t * rect, int x, int y) { int code = 0; - if (y < rect->y1) - { + if (y < rect->y1) + { code |= CODE_TOP; - } - else if (y > rect->y2) - { + } + else if (y > rect->y2) + { code |= CODE_BOTTOM; } - if (x < rect->x1) - { + if (x < rect->x1) + { code |= CODE_LEFT; - } - else if (x > rect->x2) - { + } + else if (x > rect->x2) + { code |= CODE_RIGHT; } - return code; + return code; } static rt_bool_t _intersect_rect_line(const rtgui_rect_t* rect, @@ -198,41 +194,57 @@ static rt_bool_t _intersect_rect_line(const rtgui_rect_t* rect, /* Check to see if entire line is inside rect */ if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 && - y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) { + y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) + { return RT_TRUE; } /* Check to see if entire line is to one side of rect */ if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) || - (y1 < recty1 && y2 < recty1) || (y1 > recty2 && y2 > recty2)) { + (y1 < recty1 && y2 < recty1) || (y1 > recty2 && y2 > recty2)) + { return RT_FALSE; } - if (y1 == y2) { + if (y1 == y2) + { /* Horizontal line, easy to clip */ - if (x1 < rectx1) { + if (x1 < rectx1) + { *X1 = rectx1; - } else if (x1 > rectx2) { + } + else if (x1 > rectx2) + { *X1 = rectx2; } - if (x2 < rectx1) { + if (x2 < rectx1) + { *X2 = rectx1; - } else if (x2 > rectx2) { + } + else if (x2 > rectx2) + { *X2 = rectx2; } return RT_TRUE; } - if (x1 == x2) { + if (x1 == x2) + { /* Vertical line, easy to clip */ - if (y1 < recty1) { + if (y1 < recty1) + { *Y1 = recty1; - } else if (y1 > recty2) { + } + else if (y1 > recty2) + { *Y1 = recty2; } - if (y2 < recty1) { + if (y2 < recty1) + { *Y2 = recty1; - } else if (y2 > recty2) { + } + else if (y2 > recty2) + { *Y2 = recty2; } return RT_TRUE; @@ -241,39 +253,58 @@ static rt_bool_t _intersect_rect_line(const rtgui_rect_t* rect, /* More complicated Cohen-Sutherland algorithm */ outcode1 = ComputeOutCode(rect, x1, y1); outcode2 = ComputeOutCode(rect, x2, y2); - while (outcode1 || outcode2) { - if (outcode1 & outcode2) { + while (outcode1 || outcode2) + { + if (outcode1 & outcode2) + { return RT_FALSE; } - if (outcode1) { - if (outcode1 & CODE_TOP) { + if (outcode1) + { + if (outcode1 & CODE_TOP) + { y = recty1; x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); - } else if (outcode1 & CODE_BOTTOM) { + } + else if (outcode1 & CODE_BOTTOM) + { y = recty2; x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); - } else if (outcode1 & CODE_LEFT) { + } + else if (outcode1 & CODE_LEFT) + { x = rectx1; y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); - } else if (outcode1 & CODE_RIGHT) { + } + else if (outcode1 & CODE_RIGHT) + { x = rectx2; y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); } x1 = x; y1 = y; outcode1 = ComputeOutCode(rect, x, y); - } else { - if (outcode2 & CODE_TOP) { + } + else + { + if (outcode2 & CODE_TOP) + { y = recty1; x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); - } else if (outcode2 & CODE_BOTTOM) { + } + else if (outcode2 & CODE_BOTTOM) + { y = recty2; x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); - } else if (outcode2 & CODE_LEFT) { + } + else if (outcode2 & CODE_LEFT) + { x = rectx1; y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); - } else if (outcode2 & CODE_RIGHT) { + } + else if (outcode2 & CODE_RIGHT) + { x = rectx2; y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); } @@ -293,101 +324,125 @@ static rt_bool_t _intersect_rect_line(const rtgui_rect_t* rect, static void _dc_draw_line1(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, rtgui_color_t color, - rt_bool_t draw_end) + rt_bool_t draw_end) { - if (y1 == y2) { + if (y1 == y2) + { int length; - int pitch = _dc_get_pitch(dst); rt_uint8_t *pixel; - if (x1 <= x2) { + if (x1 <= x2) + { pixel = (rt_uint8_t *)_dc_get_pixel(dst, x1, y1); length = draw_end ? (x2-x1+1) : (x2-x1); - } else { + } + else + { pixel = (rt_uint8_t *)_dc_get_pixel(dst, x2, y1); - if (!draw_end) { + if (!draw_end) + { ++pixel; } length = draw_end ? (x1-x2+1) : (x1-x2); } rt_memset(pixel, color, length); - } else if (x1 == x2) { + } + else if (x1 == x2) + { VLINE(rt_uint8_t, DRAW_FASTSETPIXEL1, draw_end); - } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + } + else if (ABS(x1 - x2) == ABS(y1 - y2)) + { DLINE(rt_uint8_t, DRAW_FASTSETPIXEL1, draw_end); - } else { + } + else + { BLINE(x1, y1, x2, y2, DRAW_FASTSETPIXELXY1, draw_end); } } static void _dc_draw_line2(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, rtgui_color_t c, - rt_bool_t draw_end) + rt_bool_t draw_end) { - rt_uint16_t color; + rt_uint16_t color; - if (rtgui_dc_get_pixel_format(dst) == RTGRAPHIC_PIXEL_FORMAT_RGB565) - color = rtgui_color_to_565(c); - else - color = rtgui_color_to_565p(c); + if (rtgui_dc_get_pixel_format(dst) == RTGRAPHIC_PIXEL_FORMAT_RGB565) + color = rtgui_color_to_565(c); + else + color = rtgui_color_to_565p(c); - if (y1 == y2) { + if (y1 == y2) + { HLINE(rt_uint16_t, DRAW_FASTSETPIXEL2, draw_end); - } else if (x1 == x2) { + } + else if (x1 == x2) + { VLINE(rt_uint16_t, DRAW_FASTSETPIXEL2, draw_end); - } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + } + else if (ABS(x1 - x2) == ABS(y1 - y2)) + { DLINE(rt_uint16_t, DRAW_FASTSETPIXEL2, draw_end); - } else { + } + else + { rt_uint8_t _r, _g, _b, _a; - _r = RTGUI_RGB_R(c); - _g = RTGUI_RGB_G(c); - _b = RTGUI_RGB_B(c); - _a = RTGUI_RGB_A(c); + _r = RTGUI_RGB_R(c); + _g = RTGUI_RGB_G(c); + _b = RTGUI_RGB_B(c); + _a = RTGUI_RGB_A(c); - if (rtgui_dc_get_pixel_format(dst) == RTGRAPHIC_PIXEL_FORMAT_RGB565) - { + if (rtgui_dc_get_pixel_format(dst) == RTGRAPHIC_PIXEL_FORMAT_RGB565) + { AALINE(x1, y1, x2, y2, DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY_BLEND_RGB565, draw_end); - } - else if (rtgui_dc_get_pixel_format(dst) == RTGRAPHIC_PIXEL_FORMAT_BGR565) - { - AALINE(x1, y1, x2, y2, - DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY_BLEND_BGR565, - draw_end); + } + else if (rtgui_dc_get_pixel_format(dst) == RTGRAPHIC_PIXEL_FORMAT_BGR565) + { + AALINE(x1, y1, x2, y2, + DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY_BLEND_BGR565, + draw_end); } } } static void _dc_draw_line4(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, rtgui_color_t color, - rt_bool_t draw_end) + rt_bool_t draw_end) { - if (y1 == y2) { + if (y1 == y2) + { HLINE(rt_uint32_t, DRAW_FASTSETPIXEL4, draw_end); - } else if (x1 == x2) { + } + else if (x1 == x2) + { VLINE(rt_uint32_t, DRAW_FASTSETPIXEL4, draw_end); - } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + } + else if (ABS(x1 - x2) == ABS(y1 - y2)) + { DLINE(rt_uint32_t, DRAW_FASTSETPIXEL4, draw_end); - } else { + } + else + { rt_uint8_t _r, _g, _b, _a; - _r = RTGUI_RGB_R(color); - _g = RTGUI_RGB_G(color); - _b = RTGUI_RGB_B(color); - _a = RTGUI_RGB_A(color); + _r = RTGUI_RGB_R(color); + _g = RTGUI_RGB_G(color); + _b = RTGUI_RGB_B(color); + _a = RTGUI_RGB_A(color); - if (rtgui_dc_get_pixel_format(dst) == RTGRAPHIC_PIXEL_FORMAT_RGB888) - { + if (rtgui_dc_get_pixel_format(dst) == RTGRAPHIC_PIXEL_FORMAT_RGB888) + { AALINE(x1, y1, x2, y2, - DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_RGB888, - draw_end); + DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_RGB888, + draw_end); } - else if (rtgui_dc_get_pixel_format(dst) == RTGRAPHIC_PIXEL_FORMAT_ARGB888) - { + else if (rtgui_dc_get_pixel_format(dst) == RTGRAPHIC_PIXEL_FORMAT_ARGB888) + { AALINE(x1, y1, x2, y2, - DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_ARGB8888, - draw_end); - } + DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_ARGB8888, + draw_end); + } } } @@ -398,7 +453,8 @@ typedef void (*DrawLineFunc) (struct rtgui_dc * dst, static DrawLineFunc _dc_calc_draw_line_func(int bpp) { - switch (bpp) { + switch (bpp) + { case 1: return _dc_draw_line1; case 2: @@ -407,7 +463,7 @@ _dc_calc_draw_line_func(int bpp) return _dc_draw_line4; } - return NULL; + return NULL; } static void _do_draw_line(struct rtgui_dc * dst, @@ -416,72 +472,74 @@ static void _do_draw_line(struct rtgui_dc * dst, int x2, int y2, rt_bool_t draw_end) { - int bpp; + int bpp; DrawLineFunc func; - bpp = _dc_get_bits_per_pixel(dst); + bpp = _dc_get_bits_per_pixel(dst); if (bpp < 8) return; func = _dc_calc_draw_line_func(bpp/8); if (!func) - { + { rt_kprintf("dc_draw_line(): Unsupported pixel format\n"); - return; + return; } - /* perform clip */ - if (dst->type == RTGUI_DC_CLIENT) - { + /* perform clip */ + if (dst->type == RTGUI_DC_CLIENT) + { rtgui_widget_t *owner; - /* get owner */ - owner = RTGUI_CONTAINER_OF(dst, struct rtgui_widget, dc_type); + /* get owner */ + owner = RTGUI_CONTAINER_OF(dst, struct rtgui_widget, dc_type); - x1 = x1 + owner->extent.x1; - x2 = x2 + owner->extent.x1; - y1 = y1 + owner->extent.y1; - y2 = y2 + owner->extent.y1; + x1 = x1 + owner->extent.x1; + x2 = x2 + owner->extent.x1; + y1 = y1 + owner->extent.y1; + y2 = y2 + owner->extent.y1; - if (owner->clip.data == RT_NULL) - { - rtgui_rect_t *prect; + if (owner->clip.data == RT_NULL) + { + rtgui_rect_t *prect; - /* no clip */ - prect = &(owner->clip.extents); + /* no clip */ + prect = &(owner->clip.extents); - /* calculate line intersect */ - if (_intersect_rect_line(prect, &x1, &y1, &x2, &y2) == RT_FALSE) + /* calculate line intersect */ + if (_intersect_rect_line(prect, &x1, &y1, &x2, &y2) == RT_FALSE) return; - /* draw line */ - func(dst, x1, y1, x2, y2, color, draw_end); - } - else - { - register rt_base_t index; + /* draw line */ + func(dst, x1, y1, x2, y2, color, draw_end); + } + else + { + register rt_base_t index; - 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; - int draw_x1, draw_x2; - int draw_y1, draw_y2; + rtgui_rect_t *prect; + int draw_x1, draw_x2; + int draw_y1, draw_y2; - prect = ((rtgui_rect_t *)(owner->clip.data + index + 1)); - draw_x1 = x1; draw_x2 = x2; - draw_y1 = y1; draw_y2 = y2; + prect = ((rtgui_rect_t *)(owner->clip.data + index + 1)); + draw_x1 = x1; + draw_x2 = x2; + draw_y1 = y1; + draw_y2 = y2; - /* calculate line intersect */ - if (_intersect_rect_line(prect, &draw_x1, &draw_y1, &draw_x2, &draw_y2) == RT_FALSE) + /* calculate line intersect */ + if (_intersect_rect_line(prect, &draw_x1, &draw_y1, &draw_x2, &draw_y2) == RT_FALSE) continue; - /* draw line */ - func(dst, draw_x1, draw_y1, draw_x2, draw_y2, color, draw_end); - } - } - } - else - { + /* draw line */ + func(dst, draw_x1, draw_y1, draw_x2, draw_y2, color, draw_end); + } + } + } + else + { if (dst->type == RTGUI_DC_HW) { rtgui_widget_t *owner; @@ -512,22 +570,22 @@ static void _do_draw_line(struct rtgui_dc * dst, return; } - func(dst, x1, y1, x2, y2, color, draw_end); - } + func(dst, x1, y1, x2, y2, color, draw_end); + } } void rtgui_dc_draw_aa_line(struct rtgui_dc * dst, int x1, int y1, int x2, int y2) { - rtgui_color_t color; + rtgui_color_t color; - RT_ASSERT(dst != RT_NULL); - if (!rtgui_dc_get_visible(dst)) + RT_ASSERT(dst != RT_NULL); + if (!rtgui_dc_get_visible(dst)) return; - /* we do not support pixel DC */ - if (_dc_get_pixel(dst, 0, 0) == RT_NULL) + /* we do not support pixel DC */ + if (_dc_get_pixel(dst, 0, 0) == RT_NULL) return; - color = rtgui_dc_get_gc(dst)->foreground; + color = rtgui_dc_get_gc(dst)->foreground; _do_draw_line(dst, color, x1, y1, x2, y2, RT_FALSE); } @@ -538,16 +596,16 @@ void rtgui_dc_draw_aa_lines(struct rtgui_dc * dst, const struct rtgui_point * po int i; int x1, y1; int x2, y2; - rtgui_color_t color; + rtgui_color_t color; - RT_ASSERT(dst); - if (!rtgui_dc_get_visible(dst)) + RT_ASSERT(dst); + if (!rtgui_dc_get_visible(dst)) return; - /* we do not support pixel DC */ - if (_dc_get_pixel(dst, 0, 0) == RT_NULL) + /* we do not support pixel DC */ + if (_dc_get_pixel(dst, 0, 0) == RT_NULL) return; - color = rtgui_dc_get_gc(dst)->foreground; + color = rtgui_dc_get_gc(dst)->foreground; for (i = 1; i < count; ++i) { @@ -564,7 +622,7 @@ void rtgui_dc_draw_aa_lines(struct rtgui_dc * dst, const struct rtgui_point * po } if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) - { + { rtgui_dc_draw_point(dst, points[count-1].x, points[count-1].y); } @@ -573,11 +631,12 @@ void rtgui_dc_draw_aa_lines(struct rtgui_dc * dst, const struct rtgui_point * po static int _dc_blend_point_rgb565(struct rtgui_dc * dst, int x, int y, enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, - rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) + rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) { unsigned inva = 0xff - a; - switch (blendMode) { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: DRAW_SETPIXELXY_BLEND_RGB565(x, y); break; @@ -596,34 +655,36 @@ _dc_blend_point_rgb565(struct rtgui_dc * dst, int x, int y, enum RTGUI_BLENDMODE static int _dc_blend_point_bgr565(struct rtgui_dc * dst, int x, int y, enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, - rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) + rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) { - unsigned inva = 0xff - a; - - switch (blendMode) { - case RTGUI_BLENDMODE_BLEND: - DRAW_SETPIXELXY_BLEND_BGR565(x, y); - break; - case RTGUI_BLENDMODE_ADD: - DRAW_SETPIXELXY_ADD_BGR565(x, y); - break; - case RTGUI_BLENDMODE_MOD: - DRAW_SETPIXELXY_MOD_BGR565(x, y); - break; - default: - DRAW_SETPIXELXY_BGR565(x, y); - break; - } - return 0; + unsigned inva = 0xff - a; + + switch (blendMode) + { + case RTGUI_BLENDMODE_BLEND: + DRAW_SETPIXELXY_BLEND_BGR565(x, y); + break; + case RTGUI_BLENDMODE_ADD: + DRAW_SETPIXELXY_ADD_BGR565(x, y); + break; + case RTGUI_BLENDMODE_MOD: + DRAW_SETPIXELXY_MOD_BGR565(x, y); + break; + default: + DRAW_SETPIXELXY_BGR565(x, y); + break; + } + return 0; } static int _dc_blend_point_rgb888(struct rtgui_dc * dst, int x, int y, enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, - rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) + rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) { unsigned inva = 0xff - a; - switch (blendMode) { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: DRAW_SETPIXELXY_BLEND_RGB888(x, y); break; @@ -642,11 +703,12 @@ _dc_blend_point_rgb888(struct rtgui_dc * dst, int x, int y, enum RTGUI_BLENDMODE static int _dc_blend_point_argb8888(struct rtgui_dc * dst, int x, int y, enum RTGUI_BLENDMODE blendMode, - rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) + rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) { unsigned inva = 0xff - a; - switch (blendMode) { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: DRAW_SETPIXELXY_BLEND_ARGB8888(x, y); break; @@ -665,71 +727,73 @@ _dc_blend_point_argb8888(struct rtgui_dc * dst, int x, int y, enum RTGUI_BLENDMO void rtgui_dc_blend_point(struct rtgui_dc * dst, int x, int y, enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, - rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) + rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) { - RT_ASSERT(dst != RT_NULL); + RT_ASSERT(dst != RT_NULL); /* Negative coordinates are always invisible. */ if (x < 0 || y < 0) return; - if (!rtgui_dc_get_visible(dst)) return; - /* we do not support pixel DC */ - if (_dc_get_pixel(dst, 0, 0) == RT_NULL) return; + if (!rtgui_dc_get_visible(dst)) return; + /* we do not support pixel DC */ + if (_dc_get_pixel(dst, 0, 0) == RT_NULL) return; - /* Perform clipping */ - if (dst->type == RTGUI_DC_CLIENT) - { - rtgui_widget_t *owner; - rtgui_rect_t rect; + /* Perform clipping */ + if (dst->type == RTGUI_DC_CLIENT) + { + rtgui_widget_t *owner; + rtgui_rect_t rect; - /* get owner */ - owner = RTGUI_CONTAINER_OF(dst, struct rtgui_widget, dc_type); + /* get owner */ + owner = RTGUI_CONTAINER_OF(dst, struct rtgui_widget, dc_type); - x = x + owner->extent.x1; - y = y + owner->extent.y1; + x = x + owner->extent.x1; + y = y + owner->extent.y1; - if (rtgui_region_contains_point(&(owner->clip), x, y, &rect) != RT_EOK) - return ; - } - else if (dst->type == RTGUI_DC_HW) - { - struct rtgui_dc_hw *dc = (struct rtgui_dc_hw *) dst; + if (rtgui_region_contains_point(&(owner->clip), x, y, &rect) != RT_EOK) + return ; + } + else if (dst->type == RTGUI_DC_HW) + { + struct rtgui_dc_hw *dc = (struct rtgui_dc_hw *) dst; - x = x + dc->owner->extent.x1; - y = y + dc->owner->extent.y1; - if (x >= dc->owner->extent.x2) + x = x + dc->owner->extent.x1; + y = y + dc->owner->extent.y1; + if (x >= dc->owner->extent.x2) return; - if (y >= dc->owner->extent.y2) + if (y >= dc->owner->extent.y2) return; - } + } else if (dst->type == RTGUI_DC_BUFFER) { - struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer *) dst; + struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer *) dst; if (x >= dc->width || y >= dc->height) return; } - if (blendMode == RTGUI_BLENDMODE_BLEND || blendMode == RTGUI_BLENDMODE_ADD) { + if (blendMode == RTGUI_BLENDMODE_BLEND || blendMode == RTGUI_BLENDMODE_ADD) + { r = DRAW_MUL(r, a); g = DRAW_MUL(g, a); b = DRAW_MUL(b, a); } - switch (rtgui_dc_get_pixel_format(dst)) { - case RTGRAPHIC_PIXEL_FORMAT_RGB565: + switch (rtgui_dc_get_pixel_format(dst)) + { + case RTGRAPHIC_PIXEL_FORMAT_RGB565: _dc_blend_point_rgb565(dst, x, y, blendMode, r, g, b, a); - break; - case RTGRAPHIC_PIXEL_FORMAT_BGR565: - _dc_blend_point_bgr565(dst, x, y, blendMode, r, g, b, a); - break; + break; + case RTGRAPHIC_PIXEL_FORMAT_BGR565: + _dc_blend_point_bgr565(dst, x, y, blendMode, r, g, b, a); + break; case RTGRAPHIC_PIXEL_FORMAT_RGB888: _dc_blend_point_rgb888(dst, x, y, blendMode, r, g, b, a); - break; - case RTGRAPHIC_PIXEL_FORMAT_ARGB888: - _dc_blend_point_argb8888(dst, x, y, blendMode, r, g, b, a); - break; + break; + case RTGRAPHIC_PIXEL_FORMAT_ARGB888: + _dc_blend_point_argb8888(dst, x, y, blendMode, r, g, b, a); + break; default: break; } @@ -738,106 +802,109 @@ RTM_EXPORT(rtgui_dc_blend_point); void rtgui_dc_blend_points(struct rtgui_dc *dst, const rtgui_point_t *points, int count, - enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) + enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) { int i; int x, y; int (*func)(struct rtgui_dc * dst, int x, int y, enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) = NULL; - RT_ASSERT(dst != RT_NULL); - if (!rtgui_dc_get_visible(dst)) return; - /* we do not support pixel DC */ - if (_dc_get_pixel(dst, 0, 0) == RT_NULL) return; + RT_ASSERT(dst != RT_NULL); + if (!rtgui_dc_get_visible(dst)) return; + /* we do not support pixel DC */ + if (_dc_get_pixel(dst, 0, 0) == RT_NULL) return; if (blendMode == RTGUI_BLENDMODE_BLEND || blendMode == RTGUI_BLENDMODE_ADD) - { + { r = DRAW_MUL(r, a); g = DRAW_MUL(g, a); b = DRAW_MUL(b, a); } /* FIXME: Does this function pointer slow things down significantly? */ - switch (rtgui_dc_get_pixel_format(dst)) - { - case RTGRAPHIC_PIXEL_FORMAT_RGB565: + switch (rtgui_dc_get_pixel_format(dst)) + { + case RTGRAPHIC_PIXEL_FORMAT_RGB565: func = _dc_blend_point_rgb565; break; case RTGRAPHIC_PIXEL_FORMAT_RGB888: func = _dc_blend_point_rgb888; - break; - case RTGRAPHIC_PIXEL_FORMAT_ARGB888: - func = _dc_blend_point_argb8888; + break; + case RTGRAPHIC_PIXEL_FORMAT_ARGB888: + func = _dc_blend_point_argb8888; default: return; } - /* get owner */ - if (dst->type == RTGUI_DC_CLIENT) - { - rtgui_widget_t *owner; - rtgui_rect_t rect; - - owner = RTGUI_CONTAINER_OF(dst, struct rtgui_widget, dc_type); - - for (i = 0; i < count; ++i) - { - x = points[i].x; - y = points[i].y; - - /* Perform clipping */ - x = x + owner->extent.x1; - y = y + owner->extent.y1; - - if (rtgui_region_contains_point(&(owner->clip), x, y, &rect) != RT_EOK) - continue; - - func(dst, x, y, blendMode, r, g, b, a); - } - } - else if (dst->type == RTGUI_DC_HW) - { - struct rtgui_dc_hw *dc = (struct rtgui_dc_hw *) dst; - - for (i = 0; i < count; ++i) - { - x = points[i].x; - y = points[i].y; - - x = x + dc->owner->extent.x1; - y = y + dc->owner->extent.y1; - if (x > dc->owner->extent.x2) return; - if (y > dc->owner->extent.y2) return; - - func(dst, x, y, blendMode, r, g, b, a); - } - } - else - { - for (i = 0; i < count; ++i) - { - x = points[i].x; - y = points[i].y; - - func(dst, x, y, blendMode, r, g, b, a); - } - } + /* get owner */ + if (dst->type == RTGUI_DC_CLIENT) + { + rtgui_widget_t *owner; + rtgui_rect_t rect; + + owner = RTGUI_CONTAINER_OF(dst, struct rtgui_widget, dc_type); + + for (i = 0; i < count; ++i) + { + x = points[i].x; + y = points[i].y; + + /* Perform clipping */ + x = x + owner->extent.x1; + y = y + owner->extent.y1; + + if (rtgui_region_contains_point(&(owner->clip), x, y, &rect) != RT_EOK) + continue; + + func(dst, x, y, blendMode, r, g, b, a); + } + } + else if (dst->type == RTGUI_DC_HW) + { + struct rtgui_dc_hw *dc = (struct rtgui_dc_hw *) dst; + + for (i = 0; i < count; ++i) + { + x = points[i].x; + y = points[i].y; + + x = x + dc->owner->extent.x1; + y = y + dc->owner->extent.y1; + if (x > dc->owner->extent.x2) return; + if (y > dc->owner->extent.y2) return; + + func(dst, x, y, blendMode, r, g, b, a); + } + } + else + { + for (i = 0; i < count; ++i) + { + x = points[i].x; + y = points[i].y; + + func(dst, x, y, blendMode, r, g, b, a); + } + } } RTM_EXPORT(rtgui_dc_blend_points); static void _dc_blend_line_rgb565(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, - enum RTGUI_BLENDMODE blendMode, rt_uint8_t _r, rt_uint8_t _g, rt_uint8_t _b, rt_uint8_t _a, - rt_bool_t draw_end) + enum RTGUI_BLENDMODE blendMode, rt_uint8_t _r, rt_uint8_t _g, rt_uint8_t _b, rt_uint8_t _a, + rt_bool_t draw_end) { unsigned r, g, b, a, inva; - if (blendMode == RTGUI_BLENDMODE_BLEND || blendMode == RTGUI_BLENDMODE_ADD) { + if (blendMode == RTGUI_BLENDMODE_BLEND || blendMode == RTGUI_BLENDMODE_ADD) + { r = DRAW_MUL(_r, _a); g = DRAW_MUL(_g, _a); b = DRAW_MUL(_b, _a); a = _a; - } else { + } + else + { r = _r; g = _g; b = _b; @@ -845,8 +912,10 @@ _dc_blend_line_rgb565(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, } inva = (a ^ 0xff); - if (y1 == y2) { - switch (blendMode) { + if (y1 == y2) + { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: HLINE(rt_uint16_t, DRAW_SETPIXEL_BLEND_RGB565, draw_end); break; @@ -860,8 +929,11 @@ _dc_blend_line_rgb565(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, HLINE(rt_uint16_t, DRAW_SETPIXEL_RGB565, draw_end); break; } - } else if (x1 == x2) { - switch (blendMode) { + } + else if (x1 == x2) + { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: VLINE(rt_uint16_t, DRAW_SETPIXEL_BLEND_RGB565, draw_end); break; @@ -875,8 +947,11 @@ _dc_blend_line_rgb565(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, VLINE(rt_uint16_t, DRAW_SETPIXEL_RGB565, draw_end); break; } - } else if (ABS(x1 - x2) == ABS(y1 - y2)) { - switch (blendMode) { + } + else if (ABS(x1 - x2) == ABS(y1 - y2)) + { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: DLINE(rt_uint16_t, DRAW_SETPIXEL_BLEND_RGB565, draw_end); break; @@ -890,8 +965,11 @@ _dc_blend_line_rgb565(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, DLINE(rt_uint16_t, DRAW_SETPIXEL_RGB565, draw_end); break; } - } else { - switch (blendMode) { + } + else + { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: AALINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB565, DRAW_SETPIXELXY_BLEND_RGB565, @@ -918,17 +996,20 @@ _dc_blend_line_rgb565(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, static void _dc_blend_line_bgr565(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, - enum RTGUI_BLENDMODE blendMode, rt_uint8_t _r, rt_uint8_t _g, rt_uint8_t _b, rt_uint8_t _a, - rt_bool_t draw_end) + enum RTGUI_BLENDMODE blendMode, rt_uint8_t _r, rt_uint8_t _g, rt_uint8_t _b, rt_uint8_t _a, + rt_bool_t draw_end) { unsigned r, g, b, a, inva; - if (blendMode == RTGUI_BLENDMODE_BLEND || blendMode == RTGUI_BLENDMODE_ADD) { + if (blendMode == RTGUI_BLENDMODE_BLEND || blendMode == RTGUI_BLENDMODE_ADD) + { r = DRAW_MUL(_r, _a); g = DRAW_MUL(_g, _a); b = DRAW_MUL(_b, _a); a = _a; - } else { + } + else + { r = _r; g = _g; b = _b; @@ -936,8 +1017,10 @@ _dc_blend_line_bgr565(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, } inva = (a ^ 0xff); - if (y1 == y2) { - switch (blendMode) { + if (y1 == y2) + { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: HLINE(rt_uint16_t, DRAW_SETPIXEL_BLEND_BGR565, draw_end); break; @@ -951,8 +1034,11 @@ _dc_blend_line_bgr565(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, HLINE(rt_uint16_t, DRAW_SETPIXEL_BGR565, draw_end); break; } - } else if (x1 == x2) { - switch (blendMode) { + } + else if (x1 == x2) + { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: VLINE(rt_uint16_t, DRAW_SETPIXEL_BLEND_BGR565, draw_end); break; @@ -966,8 +1052,11 @@ _dc_blend_line_bgr565(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, VLINE(rt_uint16_t, DRAW_SETPIXEL_BGR565, draw_end); break; } - } else if (ABS(x1 - x2) == ABS(y1 - y2)) { - switch (blendMode) { + } + else if (ABS(x1 - x2) == ABS(y1 - y2)) + { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: DLINE(rt_uint16_t, DRAW_SETPIXEL_BLEND_BGR565, draw_end); break; @@ -981,8 +1070,11 @@ _dc_blend_line_bgr565(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, DLINE(rt_uint16_t, DRAW_SETPIXEL_BGR565, draw_end); break; } - } else { - switch (blendMode) { + } + else + { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: AALINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_BGR565, DRAW_SETPIXELXY_BLEND_BGR565, @@ -1009,17 +1101,20 @@ _dc_blend_line_bgr565(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, static void _dc_blend_line_rgb888(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, - enum RTGUI_BLENDMODE blendMode, rt_uint8_t _r, rt_uint8_t _g, rt_uint8_t _b, rt_uint8_t _a, - rt_bool_t draw_end) + enum RTGUI_BLENDMODE blendMode, rt_uint8_t _r, rt_uint8_t _g, rt_uint8_t _b, rt_uint8_t _a, + rt_bool_t draw_end) { unsigned r, g, b, a, inva; - if (blendMode == RTGUI_BLENDMODE_BLEND || blendMode == RTGUI_BLENDMODE_ADD) { + if (blendMode == RTGUI_BLENDMODE_BLEND || blendMode == RTGUI_BLENDMODE_ADD) + { r = DRAW_MUL(_r, _a); g = DRAW_MUL(_g, _a); b = DRAW_MUL(_b, _a); a = _a; - } else { + } + else + { r = _r; g = _g; b = _b; @@ -1027,8 +1122,10 @@ _dc_blend_line_rgb888(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, } inva = (a ^ 0xff); - if (y1 == y2) { - switch (blendMode) { + if (y1 == y2) + { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: HLINE(rt_uint32_t, DRAW_SETPIXEL_BLEND_RGB888, draw_end); break; @@ -1042,8 +1139,11 @@ _dc_blend_line_rgb888(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, HLINE(rt_uint32_t, DRAW_SETPIXEL_RGB888, draw_end); break; } - } else if (x1 == x2) { - switch (blendMode) { + } + else if (x1 == x2) + { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: VLINE(rt_uint32_t, DRAW_SETPIXEL_BLEND_RGB888, draw_end); break; @@ -1057,8 +1157,11 @@ _dc_blend_line_rgb888(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, VLINE(rt_uint32_t, DRAW_SETPIXEL_RGB888, draw_end); break; } - } else if (ABS(x1 - x2) == ABS(y1 - y2)) { - switch (blendMode) { + } + else if (ABS(x1 - x2) == ABS(y1 - y2)) + { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: DLINE(rt_uint32_t, DRAW_SETPIXEL_BLEND_RGB888, draw_end); break; @@ -1072,8 +1175,11 @@ _dc_blend_line_rgb888(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, DLINE(rt_uint32_t, DRAW_SETPIXEL_RGB888, draw_end); break; } - } else { - switch (blendMode) { + } + else + { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: AALINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB888, DRAW_SETPIXELXY_BLEND_RGB888, @@ -1100,17 +1206,20 @@ _dc_blend_line_rgb888(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, static void _dc_blend_line_argb8888(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, - enum RTGUI_BLENDMODE blendMode, rt_uint8_t _r, rt_uint8_t _g, rt_uint8_t _b, rt_uint8_t _a, - rt_bool_t draw_end) + enum RTGUI_BLENDMODE blendMode, rt_uint8_t _r, rt_uint8_t _g, rt_uint8_t _b, rt_uint8_t _a, + rt_bool_t draw_end) { unsigned r, g, b, a, inva; - if (blendMode == RTGUI_BLENDMODE_BLEND || blendMode == RTGUI_BLENDMODE_ADD) { + if (blendMode == RTGUI_BLENDMODE_BLEND || blendMode == RTGUI_BLENDMODE_ADD) + { r = DRAW_MUL(_r, _a); g = DRAW_MUL(_g, _a); b = DRAW_MUL(_b, _a); a = _a; - } else { + } + else + { r = _r; g = _g; b = _b; @@ -1118,9 +1227,11 @@ _dc_blend_line_argb8888(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, } inva = (a ^ 0xff); - if (y1 == y2) { - switch (blendMode) { - case RTGUI_BLENDMODE_BLEND: + if (y1 == y2) + { + switch (blendMode) + { + case RTGUI_BLENDMODE_BLEND: HLINE(rt_uint32_t, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end); break; case RTGUI_BLENDMODE_ADD: @@ -1133,8 +1244,11 @@ _dc_blend_line_argb8888(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, HLINE(rt_uint32_t, DRAW_SETPIXEL_ARGB8888, draw_end); break; } - } else if (x1 == x2) { - switch (blendMode) { + } + else if (x1 == x2) + { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: VLINE(rt_uint32_t, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end); break; @@ -1148,8 +1262,11 @@ _dc_blend_line_argb8888(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, VLINE(rt_uint32_t, DRAW_SETPIXEL_ARGB8888, draw_end); break; } - } else if (ABS(x1 - x2) == ABS(y1 - y2)) { - switch (blendMode) { + } + else if (ABS(x1 - x2) == ABS(y1 - y2)) + { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: DLINE(rt_uint32_t, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end); break; @@ -1163,8 +1280,11 @@ _dc_blend_line_argb8888(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, DLINE(rt_uint32_t, DRAW_SETPIXEL_ARGB8888, draw_end); break; } - } else { - switch (blendMode) { + } + else + { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: AALINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888, @@ -1198,17 +1318,17 @@ typedef void (*BlendLineFunc) (struct rtgui_dc * dst, static BlendLineFunc _dc_calc_blend_line_func(rt_uint8_t pixel_format) { - switch (pixel_format) - { - case RTGRAPHIC_PIXEL_FORMAT_RGB565: - return _dc_blend_line_rgb565; - case RTGRAPHIC_PIXEL_FORMAT_BGR565: - return _dc_blend_line_bgr565; - case RTGRAPHIC_PIXEL_FORMAT_RGB888: - return _dc_blend_line_rgb888; - case RTGRAPHIC_PIXEL_FORMAT_ARGB888: - return _dc_blend_line_argb8888; - } + switch (pixel_format) + { + case RTGRAPHIC_PIXEL_FORMAT_RGB565: + return _dc_blend_line_rgb565; + case RTGRAPHIC_PIXEL_FORMAT_BGR565: + return _dc_blend_line_bgr565; + case RTGRAPHIC_PIXEL_FORMAT_RGB888: + return _dc_blend_line_rgb888; + case RTGRAPHIC_PIXEL_FORMAT_ARGB888: + return _dc_blend_line_argb8888; + } return NULL; } @@ -1221,9 +1341,9 @@ static void _do_blend_line(struct rtgui_dc * dst, rt_bool_t draw_end) { BlendLineFunc func; - rt_uint8_t pixel_format; - rt_uint8_t r, g, b, a; - rtgui_widget_t *owner; + rt_uint8_t pixel_format; + rt_uint8_t r, g, b, a; + rtgui_widget_t *owner; pixel_format = rtgui_dc_get_pixel_format(dst); func = _dc_calc_blend_line_func(pixel_format); @@ -1274,8 +1394,10 @@ static void _do_blend_line(struct rtgui_dc * dst, int draw_y1, draw_y2; prect = ((rtgui_rect_t *)(owner->clip.data + index + 1)); - draw_x1 = x1; draw_x2 = x2; - draw_y1 = y1; draw_y2 = y2; + draw_x1 = x1; + draw_x2 = x2; + draw_y1 = y1; + draw_y2 = y2; /* calculate line intersect */ if (_intersect_rect_line(prect, &draw_x1, &draw_y1, &draw_x2, &draw_y2) == RT_FALSE) @@ -1312,11 +1434,11 @@ void rtgui_dc_blend_line(struct rtgui_dc * dst, int x1, int y1, int x2, int y2, enum RTGUI_BLENDMODE blendMode, rtgui_color_t color) { - RT_ASSERT(dst != RT_NULL); - if (!rtgui_dc_get_visible(dst)) + RT_ASSERT(dst != RT_NULL); + if (!rtgui_dc_get_visible(dst)) return; - /* we do not support pixel DC */ - if (_dc_get_pixel(dst, 0, 0) == RT_NULL) + /* we do not support pixel DC */ + if (_dc_get_pixel(dst, 0, 0) == RT_NULL) return; _do_blend_line(dst, color, x1, y1, x2, y2, blendMode, RT_FALSE); @@ -1325,19 +1447,19 @@ RTM_EXPORT(rtgui_dc_blend_line); void rtgui_dc_blend_lines(struct rtgui_dc * dst, const rtgui_point_t * points, int count, - enum RTGUI_BLENDMODE blendMode, rtgui_color_t color) + enum RTGUI_BLENDMODE blendMode, rtgui_color_t color) { int i; - RT_ASSERT(dst != RT_NULL); - if (!rtgui_dc_get_visible(dst)) + RT_ASSERT(dst != RT_NULL); + if (!rtgui_dc_get_visible(dst)) return; - /* we do not support pixel DC */ - if (_dc_get_pixel(dst, 0, 0) == RT_NULL) + /* we do not support pixel DC */ + if (_dc_get_pixel(dst, 0, 0) == RT_NULL) return; for (i = 1; i < count; ++i) - { + { rt_bool_t draw_end; int x1, y1, x2, y2; @@ -1346,13 +1468,13 @@ rtgui_dc_blend_lines(struct rtgui_dc * dst, const rtgui_point_t * points, int co x2 = points[i].x; y2 = points[i].y; - /* Draw the end if it was clipped */ - draw_end = (x2 != points[i].x || y2 != points[i].y); + /* Draw the end if it was clipped */ + draw_end = (x2 != points[i].x || y2 != points[i].y); _do_blend_line(dst, color, x1, y1, x2, y2, blendMode, draw_end); } if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) - { + { rt_uint8_t r, g, b, a; r = RTGUI_RGB_R(color); @@ -1368,11 +1490,12 @@ RTM_EXPORT(rtgui_dc_blend_lines); static void _dc_blend_fill_rect_rgb565(struct rtgui_dc * dst, const rtgui_rect_t * rect, - enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) + enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) { unsigned inva = 0xff - a; - switch (blendMode) { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: FILLRECT(rt_uint16_t, DRAW_SETPIXEL_BLEND_RGB565); break; @@ -1390,11 +1513,12 @@ _dc_blend_fill_rect_rgb565(struct rtgui_dc * dst, const rtgui_rect_t * rect, static void _dc_blend_fill_rect_bgr565(struct rtgui_dc * dst, const rtgui_rect_t * rect, - enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) + enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) { unsigned inva = 0xff - a; - switch (blendMode) { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: FILLRECT(rt_uint16_t, DRAW_SETPIXEL_BLEND_RGB565); break; @@ -1412,11 +1536,12 @@ _dc_blend_fill_rect_bgr565(struct rtgui_dc * dst, const rtgui_rect_t * rect, static void _dc_blend_fill_rect_rgb888(struct rtgui_dc * dst, const rtgui_rect_t * rect, - enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) + enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) { unsigned inva = 0xff - a; - switch (blendMode) { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: FILLRECT(rt_uint32_t, DRAW_SETPIXEL_BLEND_RGB888); break; @@ -1434,11 +1559,12 @@ _dc_blend_fill_rect_rgb888(struct rtgui_dc * dst, const rtgui_rect_t * rect, static void _dc_blend_fill_rect_argb8888(struct rtgui_dc * dst, const rtgui_rect_t * rect, - enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) + enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a) { unsigned inva = 0xff - a; - switch (blendMode) { + switch (blendMode) + { case RTGUI_BLENDMODE_BLEND: FILLRECT(rt_uint32_t, DRAW_SETPIXEL_BLEND_ARGB8888); break; @@ -1455,218 +1581,222 @@ _dc_blend_fill_rect_argb8888(struct rtgui_dc * dst, const rtgui_rect_t * rect, } typedef void (*BlendFillFunc)(struct rtgui_dc * dst, const rtgui_rect_t * rect, - enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a); + enum RTGUI_BLENDMODE blendMode, rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a); void rtgui_dc_blend_fill_rect(struct rtgui_dc* dst, const rtgui_rect_t *rect, - enum RTGUI_BLENDMODE blendMode, rtgui_color_t color) + enum RTGUI_BLENDMODE blendMode, rtgui_color_t color) { unsigned r, g, b, a; - BlendFillFunc func = RT_NULL; + BlendFillFunc func = RT_NULL; - RT_ASSERT(dst != RT_NULL); + RT_ASSERT(dst != RT_NULL); - if (!rtgui_dc_get_visible(dst)) return; + if (!rtgui_dc_get_visible(dst)) return; /* This function doesn't work on surfaces < 8 bpp */ - if (_dc_get_bits_per_pixel(dst) < 8) { + if (_dc_get_bits_per_pixel(dst) < 8) + { rt_kprintf("dc_blend_fill_rect(): Unsupported pixel format\n"); - return ; + return ; } - r = RTGUI_RGB_R(color); - g = RTGUI_RGB_G(color); - b = RTGUI_RGB_B(color); - a = RTGUI_RGB_A(color); + r = RTGUI_RGB_R(color); + g = RTGUI_RGB_G(color); + b = RTGUI_RGB_B(color); + a = RTGUI_RGB_A(color); - if (blendMode == RTGUI_BLENDMODE_BLEND || blendMode == RTGUI_BLENDMODE_ADD) { + if (blendMode == RTGUI_BLENDMODE_BLEND || blendMode == RTGUI_BLENDMODE_ADD) + { r = DRAW_MUL(r, a); g = DRAW_MUL(g, a); b = DRAW_MUL(b, a); } switch (rtgui_dc_get_pixel_format(dst)) - { + { case RTGRAPHIC_PIXEL_FORMAT_RGB565: func = _dc_blend_fill_rect_rgb565; - break; - case RTGRAPHIC_PIXEL_FORMAT_BGR565: + break; + case RTGRAPHIC_PIXEL_FORMAT_BGR565: func = _dc_blend_fill_rect_bgr565; - break; - case RTGRAPHIC_PIXEL_FORMAT_RGB888: - func = _dc_blend_fill_rect_rgb888; - break; - case RTGRAPHIC_PIXEL_FORMAT_ARGB888: - func = _dc_blend_fill_rect_argb8888; - break; + break; + case RTGRAPHIC_PIXEL_FORMAT_RGB888: + func = _dc_blend_fill_rect_rgb888; + break; + case RTGRAPHIC_PIXEL_FORMAT_ARGB888: + func = _dc_blend_fill_rect_argb8888; + break; default: break; } - if (func == RT_NULL) - { + if (func == RT_NULL) + { rt_kprintf("dc_blend_fill_rect(): Unsupported pixel format\n"); - return ; - } - - if (dst->type == RTGUI_DC_CLIENT) - { - register rt_base_t index; - rtgui_widget_t *owner; - rtgui_rect_t draw_rect; - - /* get owner */ - owner = RTGUI_CONTAINER_OF(dst, struct rtgui_widget, dc_type); - - if (owner->clip.data == RT_NULL) - { - rtgui_rect_t *prect; - prect = &(owner->clip.extents); - - /* convert logic to device */ - draw_rect = *rect; - rtgui_rect_moveto(&draw_rect,owner->extent.x1, owner->extent.y1); - - /* calculate rect intersect */ - if (prect->y1 > draw_rect.y2 || prect->y2 <= draw_rect.y1) return ; - if (prect->x2 <= draw_rect.x1 || prect->x1 > draw_rect.x2 ) return ; - rtgui_rect_intersect(prect, &draw_rect); - - func(dst, &draw_rect, blendMode, r, g, b, a); - } - else - { - for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++) - { - rtgui_rect_t *prect; - - prect = ((rtgui_rect_t *)(owner->clip.data + index + 1)); - - draw_rect = *rect; - rtgui_rect_moveto(&draw_rect,owner->extent.x1, owner->extent.y1); - - /* calculate rect intersect */ - if (prect->y1 > draw_rect.y2 || prect->y2 <= draw_rect.y1) continue; - if (prect->x2 <= draw_rect.x1 || prect->x1 > draw_rect.x2 ) continue; - rtgui_rect_intersect(prect, &draw_rect); - - func(dst, &draw_rect, blendMode, r, g, b, a); - } - } - } - else - { - func(dst, rect, blendMode, r, g, b, a); - } + return ; + } + + if (dst->type == RTGUI_DC_CLIENT) + { + register rt_base_t index; + rtgui_widget_t *owner; + rtgui_rect_t draw_rect; + + /* get owner */ + owner = RTGUI_CONTAINER_OF(dst, struct rtgui_widget, dc_type); + + if (owner->clip.data == RT_NULL) + { + rtgui_rect_t *prect; + prect = &(owner->clip.extents); + + /* convert logic to device */ + draw_rect = *rect; + rtgui_rect_moveto(&draw_rect,owner->extent.x1, owner->extent.y1); + + /* calculate rect intersect */ + if (prect->y1 > draw_rect.y2 || prect->y2 <= draw_rect.y1) return ; + if (prect->x2 <= draw_rect.x1 || prect->x1 > draw_rect.x2 ) return ; + rtgui_rect_intersect(prect, &draw_rect); + + func(dst, &draw_rect, blendMode, r, g, b, a); + } + else + { + for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++) + { + rtgui_rect_t *prect; + + prect = ((rtgui_rect_t *)(owner->clip.data + index + 1)); + + draw_rect = *rect; + rtgui_rect_moveto(&draw_rect,owner->extent.x1, owner->extent.y1); + + /* calculate rect intersect */ + if (prect->y1 > draw_rect.y2 || prect->y2 <= draw_rect.y1) continue; + if (prect->x2 <= draw_rect.x1 || prect->x1 > draw_rect.x2 ) continue; + rtgui_rect_intersect(prect, &draw_rect); + + func(dst, &draw_rect, blendMode, r, g, b, a); + } + } + } + else + { + func(dst, rect, blendMode, r, g, b, a); + } } RTM_EXPORT(rtgui_dc_blend_fill_rect); void rtgui_dc_blend_fill_rects(struct rtgui_dc * dst, const rtgui_rect_t *rects, int count, - enum RTGUI_BLENDMODE blendMode, rtgui_color_t color) + enum RTGUI_BLENDMODE blendMode, rtgui_color_t color) { int i; rtgui_rect_t rect; - BlendFillFunc func = RT_NULL; - rt_uint8_t r, g, b, a; - rtgui_widget_t *owner = RT_NULL; + BlendFillFunc func = RT_NULL; + rt_uint8_t r, g, b, a; + rtgui_widget_t *owner = RT_NULL; - RT_ASSERT(dst != RT_NULL); + RT_ASSERT(dst != RT_NULL); - if (!rtgui_dc_get_visible(dst)) return; + if (!rtgui_dc_get_visible(dst)) return; /* This function doesn't work on surfaces < 8 bpp */ - if (_dc_get_bits_per_pixel(dst)< 8) { + if (_dc_get_bits_per_pixel(dst)< 8) + { rt_kprintf("dc_blend_fill_rects(): Unsupported pixel format\n"); - return; + return; } - r = RTGUI_RGB_R(color); - g = RTGUI_RGB_G(color); - b = RTGUI_RGB_B(color); - a = RTGUI_RGB_A(color); + r = RTGUI_RGB_R(color); + g = RTGUI_RGB_G(color); + b = RTGUI_RGB_B(color); + a = RTGUI_RGB_A(color); - if (blendMode == RTGUI_BLENDMODE_BLEND || blendMode == RTGUI_BLENDMODE_ADD) { + if (blendMode == RTGUI_BLENDMODE_BLEND || blendMode == RTGUI_BLENDMODE_ADD) + { r = DRAW_MUL(r, a); g = DRAW_MUL(g, a); b = DRAW_MUL(b, a); } switch (rtgui_dc_get_pixel_format(dst)) - { + { case RTGRAPHIC_PIXEL_FORMAT_RGB565: func = _dc_blend_fill_rect_rgb565; - break; - case RTGRAPHIC_PIXEL_FORMAT_BGR565: + break; + case RTGRAPHIC_PIXEL_FORMAT_BGR565: func = _dc_blend_fill_rect_bgr565; - break; - case RTGRAPHIC_PIXEL_FORMAT_RGB888: - func = _dc_blend_fill_rect_rgb888; - break; - case RTGRAPHIC_PIXEL_FORMAT_ARGB888: - func = _dc_blend_fill_rect_argb8888; - break; + break; + case RTGRAPHIC_PIXEL_FORMAT_RGB888: + func = _dc_blend_fill_rect_rgb888; + break; + case RTGRAPHIC_PIXEL_FORMAT_ARGB888: + func = _dc_blend_fill_rect_argb8888; + break; default: break; } - if (func == RT_NULL) - { + if (func == RT_NULL) + { rt_kprintf("dc_blend_fill_rects(): Unsupported pixel format\n"); - return; - } + return; + } - if (dst->type == RTGUI_DC_CLIENT) - { - /* get owner */ - owner = RTGUI_CONTAINER_OF(dst, struct rtgui_widget, dc_type); - } + if (dst->type == RTGUI_DC_CLIENT) + { + /* get owner */ + owner = RTGUI_CONTAINER_OF(dst, struct rtgui_widget, dc_type); + } for (i = 0; i < count; ++i) - { - rect = rects[i]; - - if (dst->type == RTGUI_DC_CLIENT) - { - register rt_base_t index; - rtgui_rect_t draw_rect; - - if (owner->clip.data == RT_NULL) - { - rtgui_rect_t *prect; - prect = &(owner->clip.extents); - - /* convert logic to device */ - draw_rect = rect; - rtgui_rect_moveto(&draw_rect,owner->extent.x1, owner->extent.y1); - - /* calculate rect intersect */ - if (prect->y1 > draw_rect.y2 || prect->y2 <= draw_rect.y1) return ; - if (prect->x2 <= draw_rect.x1 || prect->x1 > draw_rect.x2 ) return ; - rtgui_rect_intersect(prect, &draw_rect); - - func(dst, &draw_rect, blendMode, r, g, b, a); - } - else - { - for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++) - { - rtgui_rect_t *prect; - - prect = ((rtgui_rect_t *)(owner->clip.data + index + 1)); - - draw_rect = rect; - rtgui_rect_moveto(&draw_rect,owner->extent.x1, owner->extent.y1); - - /* calculate rect intersect */ - if (prect->y1 > draw_rect.y2 || prect->y2 <= draw_rect.y1) continue; - if (prect->x2 <= draw_rect.x1 || prect->x1 > draw_rect.x2 ) continue; - rtgui_rect_intersect(prect, &draw_rect); - - func(dst, &draw_rect, blendMode, r, g, b, a); - } - } - } - else - { - func(dst, &rect, blendMode, r, g, b, a); - } + { + rect = rects[i]; + + if (dst->type == RTGUI_DC_CLIENT) + { + register rt_base_t index; + rtgui_rect_t draw_rect; + + if (owner->clip.data == RT_NULL) + { + rtgui_rect_t *prect; + prect = &(owner->clip.extents); + + /* convert logic to device */ + draw_rect = rect; + rtgui_rect_moveto(&draw_rect,owner->extent.x1, owner->extent.y1); + + /* calculate rect intersect */ + if (prect->y1 > draw_rect.y2 || prect->y2 <= draw_rect.y1) return ; + if (prect->x2 <= draw_rect.x1 || prect->x1 > draw_rect.x2 ) return ; + rtgui_rect_intersect(prect, &draw_rect); + + func(dst, &draw_rect, blendMode, r, g, b, a); + } + else + { + for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++) + { + rtgui_rect_t *prect; + + prect = ((rtgui_rect_t *)(owner->clip.data + index + 1)); + + draw_rect = rect; + rtgui_rect_moveto(&draw_rect,owner->extent.x1, owner->extent.y1); + + /* calculate rect intersect */ + if (prect->y1 > draw_rect.y2 || prect->y2 <= draw_rect.y1) continue; + if (prect->x2 <= draw_rect.x1 || prect->x1 > draw_rect.x2 ) continue; + rtgui_rect_intersect(prect, &draw_rect); + + func(dst, &draw_rect, blendMode, r, g, b, a); + } + } + } + else + { + func(dst, &rect, blendMode, r, g, b, a); + } } } RTM_EXPORT(rtgui_dc_blend_fill_rects); @@ -1679,19 +1809,19 @@ RTM_EXPORT(rtgui_dc_blend_fill_rects); static __inline long lrint(float f) { - return _mm_cvtss_si32(_mm_load_ss(&f)); + return _mm_cvtss_si32(_mm_load_ss(&f)); } #elif defined(_M_IX86) __inline long int lrint (double flt) { - int intgr; - _asm - { - fld flt - fistp intgr - }; - return intgr; + int intgr; + _asm + { + fld flt + fistp intgr + }; + return intgr; } #elif defined(_M_ARM) #include @@ -1700,10 +1830,10 @@ lrint (double flt) __declspec(naked) long int lrint (double flt) { - __emit(0xEC410B10); // fmdrr d0, r0, r1 - __emit(0xEEBD0B40); // ftosid s0, d0 - __emit(0xEE100A10); // fmrs r0, s0 - __emit(0xE12FFF1E); // bx lr + __emit(0xEC410B10); // fmdrr d0, r0, r1 + __emit(0xEEBD0B40); // ftosid s0, d0 + __emit(0xEE100A10); // fmrs r0, s0 + __emit(0xE12FFF1E); // bx lr } #pragma warning(pop) #else @@ -1712,230 +1842,251 @@ lrint (double flt) #endif rt_inline void _draw_pixel_weight(struct rtgui_dc * dc, rt_int16_t x, rt_int16_t y, - rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a, rt_uint32_t weight) + rt_uint8_t r, rt_uint8_t g, rt_uint8_t b, rt_uint8_t a, rt_uint32_t weight) { - /* - * Modify Alpha by weight - */ - rt_uint32_t ax = a; - ax = ((ax * weight) >> 8); - if (ax > 255) { - a = 255; - } else { - a = (rt_uint8_t)(ax & 0x000000ff); - } - - rtgui_dc_blend_point(dc, x, y, RTGUI_BLENDMODE_BLEND, r, g, b, a); + /* + * Modify Alpha by weight + */ + rt_uint32_t ax = a; + ax = ((ax * weight) >> 8); + if (ax > 255) + { + a = 255; + } + else + { + a = (rt_uint8_t)(ax & 0x000000ff); + } + + rtgui_dc_blend_point(dc, x, y, RTGUI_BLENDMODE_BLEND, r, g, b, a); } void rtgui_dc_draw_aa_ellipse(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t rx, rt_int16_t ry) { - int i; - int a2, b2, ds, dt, dxt, t, s, d; - rt_int16_t xp, yp, xs, ys, od, dyt, xx, yy, xc2, yc2; - int cp; - double sab; - rt_uint8_t weight, iweight; - rt_uint8_t r, g, b, a; - - /* Sanity check radii */ - if ((rx < 0) || (ry < 0)) return ; - - /* - * Special case for rx=0 - draw a vline - */ - if (rx == 0) { - rtgui_dc_draw_vline(dc, x, y - ry, y + ry); - return; - } - /* - * Special case for ry=0 - draw an hline - */ - if (ry == 0) { - rtgui_dc_draw_hline(dc, x - rx, x + rx, y); - return; - } - - /* Variable setup */ - r = RTGUI_RGB_R(RTGUI_DC_FC(dc)); - g = RTGUI_RGB_G(RTGUI_DC_FC(dc)); - b = RTGUI_RGB_B(RTGUI_DC_FC(dc)); - a = RTGUI_RGB_A(RTGUI_DC_FC(dc)); - - a2 = rx * rx; - b2 = ry * ry; - - ds = 2 * a2; - dt = 2 * b2; - - xc2 = 2 * x; - yc2 = 2 * y; - - sab = sqrt((double)(a2 + b2)); - od = (rt_int16_t)lrint(sab*0.01) + 1; /* introduce some overdraw */ - dxt = (rt_int16_t)lrint((double)a2 / sab) + od; - - t = 0; - s = -2 * a2 * ry; - d = 0; - - xp = x; - yp = y - ry; - - /* Draw */ - - /* "End points" */ - rtgui_dc_blend_point(dc, xp, yp, RTGUI_BLENDMODE_NONE, r, g, b, a); - rtgui_dc_blend_point(dc, xc2 - xp, yp, RTGUI_BLENDMODE_NONE, r, g, b, a); - rtgui_dc_blend_point(dc, xp, yc2 - yp, RTGUI_BLENDMODE_NONE, r, g, b, a); - rtgui_dc_blend_point(dc, xc2 - xp, yc2 - yp, RTGUI_BLENDMODE_NONE, r, g, b, a); - - for (i = 1; i <= dxt; i++) - { - xp--; - d += t - b2; - - if (d >= 0) - ys = yp - 1; - else if ((d - s - a2) > 0) - { - if ((2 * d - s - a2) >= 0) - ys = yp + 1; - else { - ys = yp; - yp++; - d -= s + a2; - s += ds; - } - } else { - yp++; - ys = yp + 1; - d -= s + a2; - s += ds; - } - - t -= dt; - - /* Calculate alpha */ - if (s != 0) { - cp = 255 * abs(d) / abs(s); - if (cp > 255) { - cp = 255; - } - } else { - cp = 255; - } - - /* Calculate weights */ - weight = cp; - iweight = 255 - weight; - - /* Upper half */ - xx = xc2 - xp; - _draw_pixel_weight(dc, xp, yp, r, g, b, a, iweight); - _draw_pixel_weight(dc, xx, yp, r, g, b, a, iweight); - - _draw_pixel_weight(dc, xp, ys, r, g, b, a, weight); - _draw_pixel_weight(dc, xx, ys, r, g, b, a, weight); - - /* Lower half */ - yy = yc2 - yp; - _draw_pixel_weight(dc, xp, yy, r, g, b, a, iweight); - _draw_pixel_weight(dc, xx, yy, r, g, b, a, iweight); - - yy = yc2 - ys; - _draw_pixel_weight(dc, xp, yy, r, g, b, a, weight); - _draw_pixel_weight(dc, xx, yy, r, g, b, a, weight); - } - - /* Replaces original approximation code dyt = abs(yp - yc); */ - dyt = (rt_int16_t)lrint((double)b2 / sab ) + od; - for (i = 1; i <= dyt; i++) - { - yp++; - d -= s + a2; - - if (d <= 0) - xs = xp + 1; - else if ((d + t - b2) < 0) - { - if ((2 * d + t - b2) <= 0) - xs = xp - 1; - else { - xs = xp; - xp--; - d += t - b2; - t -= dt; - } - } else { - xp--; - xs = xp - 1; - d += t - b2; - t -= dt; - } - - s += ds; - - /* Calculate alpha */ - if (t != 0) { - cp = 255 * abs(d) / abs(t); - if (cp > 255) { - cp = 255; - } - } else { - cp = 255; - } - - /* Calculate weight */ - weight = cp; - iweight = 255 - weight; - - /* Left half */ - xx = xc2 - xp; - yy = yc2 - yp; - _draw_pixel_weight(dc, xp, yp, r, g, b, a, iweight); - _draw_pixel_weight(dc, xx, yp, r, g, b, a, iweight); - - _draw_pixel_weight(dc, xp, yy, r, g, b, a, iweight); - _draw_pixel_weight(dc, xx, yy, r, g, b, a, iweight); - - /* Right half */ - xx = xc2 - xs; - _draw_pixel_weight(dc, xs, yp, r, g, b, a, weight); - _draw_pixel_weight(dc, xx, yp, r, g, b, a, weight); - - _draw_pixel_weight(dc, xs, yy, r, g, b, a, weight); - _draw_pixel_weight(dc, xx, yy, r, g, b, a, weight); - } + int i; + int a2, b2, ds, dt, dxt, t, s, d; + rt_int16_t xp, yp, xs, ys, od, dyt, xx, yy, xc2, yc2; + int cp; + double sab; + rt_uint8_t weight, iweight; + rt_uint8_t r, g, b, a; + + /* Sanity check radii */ + if ((rx < 0) || (ry < 0)) return ; + + /* + * Special case for rx=0 - draw a vline + */ + if (rx == 0) + { + rtgui_dc_draw_vline(dc, x, y - ry, y + ry); + return; + } + /* + * Special case for ry=0 - draw an hline + */ + if (ry == 0) + { + rtgui_dc_draw_hline(dc, x - rx, x + rx, y); + return; + } + + /* Variable setup */ + r = RTGUI_RGB_R(RTGUI_DC_FC(dc)); + g = RTGUI_RGB_G(RTGUI_DC_FC(dc)); + b = RTGUI_RGB_B(RTGUI_DC_FC(dc)); + a = RTGUI_RGB_A(RTGUI_DC_FC(dc)); + + a2 = rx * rx; + b2 = ry * ry; + + ds = 2 * a2; + dt = 2 * b2; + + xc2 = 2 * x; + yc2 = 2 * y; + + sab = sqrt((double)(a2 + b2)); + od = (rt_int16_t)lrint(sab*0.01) + 1; /* introduce some overdraw */ + dxt = (rt_int16_t)lrint((double)a2 / sab) + od; + + t = 0; + s = -2 * a2 * ry; + d = 0; + + xp = x; + yp = y - ry; + + /* Draw */ + + /* "End points" */ + rtgui_dc_blend_point(dc, xp, yp, RTGUI_BLENDMODE_NONE, r, g, b, a); + rtgui_dc_blend_point(dc, xc2 - xp, yp, RTGUI_BLENDMODE_NONE, r, g, b, a); + rtgui_dc_blend_point(dc, xp, yc2 - yp, RTGUI_BLENDMODE_NONE, r, g, b, a); + rtgui_dc_blend_point(dc, xc2 - xp, yc2 - yp, RTGUI_BLENDMODE_NONE, r, g, b, a); + + for (i = 1; i <= dxt; i++) + { + xp--; + d += t - b2; + + if (d >= 0) + ys = yp - 1; + else if ((d - s - a2) > 0) + { + if ((2 * d - s - a2) >= 0) + ys = yp + 1; + else + { + ys = yp; + yp++; + d -= s + a2; + s += ds; + } + } + else + { + yp++; + ys = yp + 1; + d -= s + a2; + s += ds; + } + + t -= dt; + + /* Calculate alpha */ + if (s != 0) + { + cp = 255 * abs(d) / abs(s); + if (cp > 255) + { + cp = 255; + } + } + else + { + cp = 255; + } + + /* Calculate weights */ + weight = cp; + iweight = 255 - weight; + + /* Upper half */ + xx = xc2 - xp; + _draw_pixel_weight(dc, xp, yp, r, g, b, a, iweight); + _draw_pixel_weight(dc, xx, yp, r, g, b, a, iweight); + + _draw_pixel_weight(dc, xp, ys, r, g, b, a, weight); + _draw_pixel_weight(dc, xx, ys, r, g, b, a, weight); + + /* Lower half */ + yy = yc2 - yp; + _draw_pixel_weight(dc, xp, yy, r, g, b, a, iweight); + _draw_pixel_weight(dc, xx, yy, r, g, b, a, iweight); + + yy = yc2 - ys; + _draw_pixel_weight(dc, xp, yy, r, g, b, a, weight); + _draw_pixel_weight(dc, xx, yy, r, g, b, a, weight); + } + + /* Replaces original approximation code dyt = abs(yp - yc); */ + dyt = (rt_int16_t)lrint((double)b2 / sab ) + od; + for (i = 1; i <= dyt; i++) + { + yp++; + d -= s + a2; + + if (d <= 0) + xs = xp + 1; + else if ((d + t - b2) < 0) + { + if ((2 * d + t - b2) <= 0) + xs = xp - 1; + else + { + xs = xp; + xp--; + d += t - b2; + t -= dt; + } + } + else + { + xp--; + xs = xp - 1; + d += t - b2; + t -= dt; + } + + s += ds; + + /* Calculate alpha */ + if (t != 0) + { + cp = 255 * abs(d) / abs(t); + if (cp > 255) + { + cp = 255; + } + } + else + { + cp = 255; + } + + /* Calculate weight */ + weight = cp; + iweight = 255 - weight; + + /* Left half */ + xx = xc2 - xp; + yy = yc2 - yp; + _draw_pixel_weight(dc, xp, yp, r, g, b, a, iweight); + _draw_pixel_weight(dc, xx, yp, r, g, b, a, iweight); + + _draw_pixel_weight(dc, xp, yy, r, g, b, a, iweight); + _draw_pixel_weight(dc, xx, yy, r, g, b, a, iweight); + + /* Right half */ + xx = xc2 - xs; + _draw_pixel_weight(dc, xs, yp, r, g, b, a, weight); + _draw_pixel_weight(dc, xx, yp, r, g, b, a, weight); + + _draw_pixel_weight(dc, xs, yy, r, g, b, a, weight); + _draw_pixel_weight(dc, xx, yy, r, g, b, a, weight); + } } RTM_EXPORT(rtgui_dc_draw_aa_ellipse); void rtgui_dc_draw_aa_circle(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t r) { - rtgui_dc_draw_aa_ellipse(dc, x, y, r, r); + rtgui_dc_draw_aa_ellipse(dc, x, y, r, r); } RTM_EXPORT(rtgui_dc_draw_aa_circle); /*! \brief The structure passed to the internal Bresenham iterator. */ -typedef struct { - rt_int16_t x, y; - int dx, dy, s1, s2, swapdir, error; - rt_uint32_t count; +typedef struct +{ + rt_int16_t x, y; + int dx, dy, s1, s2, swapdir, error; + rt_uint32_t count; } _BresenhamIterator; /*! \brief The structure passed to the internal Murphy iterator. */ -typedef struct { - rt_uint32_t color; - struct rtgui_dc *dst; - int u, v; /* delta x , delta y */ - int ku, kt, kv, kd; /* loop constants */ - int oct2; - int quad4; - rt_int16_t last1x, last1y, last2x, last2y, first1x, first1y, first2x, first2y, tempx, tempy; +typedef struct +{ + rt_uint32_t color; + struct rtgui_dc *dst; + int u, v; /* delta x , delta y */ + int ku, kt, kv, kd; /* loop constants */ + int oct2; + int quad4; + rt_int16_t last1x, last1y, last2x, last2y, first1x, first1y, first2x, first2y, tempx, tempy; } _MurphyIterator; /*! @@ -1944,9 +2095,9 @@ typedef struct { Example of use: _BresenhamIterator b; _bresenhamInitialize (&b, x1, y1, x2, y2); -do { -plot(b.x, b.y); -} while (_bresenhamIterate(&b)==0); +do { +plot(b.x, b.y); +} while (_bresenhamIterate(&b)==0); \param b Pointer to struct for bresenham line drawing state. \param x1 X coordinate of the first point of the line. @@ -1958,54 +2109,70 @@ plot(b.x, b.y); */ int _bresenhamInitialize(_BresenhamIterator *b, rt_int16_t x1, rt_int16_t y1, rt_int16_t x2, rt_int16_t y2) { - int temp; - - if (b==NULL) { - return(-1); - } - - b->x = x1; - b->y = y1; - - /* dx = abs(x2-x1), s1 = sign(x2-x1) */ - if ((b->dx = x2 - x1) != 0) { - if (b->dx < 0) { - b->dx = -b->dx; - b->s1 = -1; - } else { - b->s1 = 1; - } - } else { - b->s1 = 0; - } - - /* dy = abs(y2-y1), s2 = sign(y2-y1) */ - if ((b->dy = y2 - y1) != 0) { - if (b->dy < 0) { - b->dy = -b->dy; - b->s2 = -1; - } else { - b->s2 = 1; - } - } else { - b->s2 = 0; - } - - if (b->dy > b->dx) { - temp = b->dx; - b->dx = b->dy; - b->dy = temp; - b->swapdir = 1; - } else { - b->swapdir = 0; - } - - b->count = (b->dx<0) ? 0 : (unsigned int)b->dx; - b->dy <<= 1; - b->error = b->dy - b->dx; - b->dx <<= 1; - - return(0); + int temp; + + if (b==NULL) + { + return(-1); + } + + b->x = x1; + b->y = y1; + + /* dx = abs(x2-x1), s1 = sign(x2-x1) */ + if ((b->dx = x2 - x1) != 0) + { + if (b->dx < 0) + { + b->dx = -b->dx; + b->s1 = -1; + } + else + { + b->s1 = 1; + } + } + else + { + b->s1 = 0; + } + + /* dy = abs(y2-y1), s2 = sign(y2-y1) */ + if ((b->dy = y2 - y1) != 0) + { + if (b->dy < 0) + { + b->dy = -b->dy; + b->s2 = -1; + } + else + { + b->s2 = 1; + } + } + else + { + b->s2 = 0; + } + + if (b->dy > b->dx) + { + temp = b->dx; + b->dx = b->dy; + b->dy = temp; + b->swapdir = 1; + } + else + { + b->swapdir = 0; + } + + b->count = (b->dx<0) ? 0 : (unsigned int)b->dx; + b->dy <<= 1; + b->error = b->dy - b->dx; + b->dx <<= 1; + + return(0); } @@ -2020,36 +2187,45 @@ Maybe updates the x and y coordinates of the iterator struct. */ int _bresenhamIterate(_BresenhamIterator *b) { - if (b==NULL) { - return (-1); - } - - /* last point check */ - if (b->count==0) { - return (2); - } - - while (b->error >= 0) { - if (b->swapdir) { - b->x += b->s1; - } else { - b->y += b->s2; - } - - b->error -= b->dx; - } - - if (b->swapdir) { - b->y += b->s2; - } else { - b->x += b->s1; - } - - b->error += b->dy; - b->count--; - - /* count==0 indicates "end-of-line" */ - return ((b->count) ? 0 : 1); + if (b==NULL) + { + return (-1); + } + + /* last point check */ + if (b->count==0) + { + return (2); + } + + while (b->error >= 0) + { + if (b->swapdir) + { + b->x += b->s1; + } + else + { + b->y += b->s2; + } + + b->error -= b->dx; + } + + if (b->swapdir) + { + b->y += b->s2; + } + else + { + b->x += b->s1; + } + + b->error += b->dy; + b->count--; + + /* count==0 indicates "end-of-line" */ + return ((b->count) ? 0 : 1); } @@ -2063,36 +2239,49 @@ int _bresenhamIterate(_BresenhamIterator *b) */ void _murphyParaline(_MurphyIterator *m, rt_int16_t x, rt_int16_t y, int d1) { - int p; - d1 = -d1; - - for (p = 0; p <= m->u; p++) { - rtgui_dc_draw_point(m->dst, x, y); - - if (d1 <= m->kt) { - if (m->oct2 == 0) { - x++; - } else { - if (m->quad4 == 0) { - y++; - } else { - y--; - } - } - d1 += m->kv; - } else { - x++; - if (m->quad4 == 0) { - y++; - } else { - y--; - } - d1 += m->kd; - } - } - - m->tempx = x; - m->tempy = y; + int p; + d1 = -d1; + + for (p = 0; p <= m->u; p++) + { + rtgui_dc_draw_point(m->dst, x, y); + + if (d1 <= m->kt) + { + if (m->oct2 == 0) + { + x++; + } + else + { + if (m->quad4 == 0) + { + y++; + } + else + { + y--; + } + } + d1 += m->kv; + } + else + { + x++; + if (m->quad4 == 0) + { + y++; + } + else + { + y--; + } + d1 += m->kd; + } + } + + m->tempx = x; + m->tempy = y; } /*! @@ -2111,109 +2300,123 @@ void _murphyParaline(_MurphyIterator *m, rt_int16_t x, rt_int16_t y, int d1) */ void _murphyIteration(_MurphyIterator *m, rt_uint8_t miter, - rt_uint16_t ml1bx, rt_uint16_t ml1by, rt_uint16_t ml2bx, rt_uint16_t ml2by, - rt_uint16_t ml1x, rt_uint16_t ml1y, rt_uint16_t ml2x, rt_uint16_t ml2y) + rt_uint16_t ml1bx, rt_uint16_t ml1by, rt_uint16_t ml2bx, rt_uint16_t ml2by, + rt_uint16_t ml1x, rt_uint16_t ml1y, rt_uint16_t ml2x, rt_uint16_t ml2y) { - int atemp1, atemp2; - int ftmp1, ftmp2; - rt_uint16_t m1x, m1y, m2x, m2y; - rt_uint16_t fix, fiy, lax, lay, curx, cury; - int px[4], py[4]; - _BresenhamIterator b; - - if (miter > 1) { - if (m->first1x != -32768) { - fix = (m->first1x + m->first2x) / 2; - fiy = (m->first1y + m->first2y) / 2; - lax = (m->last1x + m->last2x) / 2; - lay = (m->last1y + m->last2y) / 2; - curx = (ml1x + ml2x) / 2; - cury = (ml1y + ml2y) / 2; - - atemp1 = (fix - curx); - atemp2 = (fiy - cury); - ftmp1 = atemp1 * atemp1 + atemp2 * atemp2; - atemp1 = (lax - curx); - atemp2 = (lay - cury); - ftmp2 = atemp1 * atemp1 + atemp2 * atemp2; - - if (ftmp1 <= ftmp2) { - m1x = m->first1x; - m1y = m->first1y; - m2x = m->first2x; - m2y = m->first2y; - } else { - m1x = m->last1x; - m1y = m->last1y; - m2x = m->last2x; - m2y = m->last2y; - } - - atemp1 = (m2x - ml2x); - atemp2 = (m2y - ml2y); - ftmp1 = atemp1 * atemp1 + atemp2 * atemp2; - atemp1 = (m2x - ml2bx); - atemp2 = (m2y - ml2by); - ftmp2 = atemp1 * atemp1 + atemp2 * atemp2; - - if (ftmp2 >= ftmp1) { - ftmp1 = ml2bx; - ftmp2 = ml2by; - ml2bx = ml2x; - ml2by = ml2y; - ml2x = ftmp1; - ml2y = ftmp2; - ftmp1 = ml1bx; - ftmp2 = ml1by; - ml1bx = ml1x; - ml1by = ml1y; - ml1x = ftmp1; - ml1y = ftmp2; - } - - _bresenhamInitialize(&b, m2x, m2y, m1x, m1y); - do { - rtgui_dc_draw_color_point(m->dst, b.x, b.y, m->color); - } while (_bresenhamIterate(&b)==0); - - _bresenhamInitialize(&b, m1x, m1y, ml1bx, ml1by); - do { - rtgui_dc_draw_color_point(m->dst, b.x, b.y, m->color); - } while (_bresenhamIterate(&b)==0); - - _bresenhamInitialize(&b, ml1bx, ml1by, ml2bx, ml2by); - do { - rtgui_dc_draw_color_point(m->dst, b.x, b.y, m->color); - } while (_bresenhamIterate(&b)==0); - - _bresenhamInitialize(&b, ml2bx, ml2by, m2x, m2y); - do { - rtgui_dc_draw_color_point(m->dst, b.x, b.y, m->color); - } while (_bresenhamIterate(&b)==0); - - px[0] = m1x; - px[1] = m2x; - px[2] = ml1bx; - px[3] = ml2bx; - py[0] = m1y; - py[1] = m2y; - py[2] = ml1by; - py[3] = ml2by; - rtgui_dc_draw_polygon(m->dst, px, py, 4); - } - } - - m->last1x = ml1x; - m->last1y = ml1y; - m->last2x = ml2x; - m->last2y = ml2y; - m->first1x = ml1bx; - m->first1y = ml1by; - m->first2x = ml2bx; - m->first2y = ml2by; + int atemp1, atemp2; + int ftmp1, ftmp2; + rt_uint16_t m1x, m1y, m2x, m2y; + rt_uint16_t fix, fiy, lax, lay, curx, cury; + int px[4], py[4]; + _BresenhamIterator b; + + if (miter > 1) + { + if (m->first1x != -32768) + { + fix = (m->first1x + m->first2x) / 2; + fiy = (m->first1y + m->first2y) / 2; + lax = (m->last1x + m->last2x) / 2; + lay = (m->last1y + m->last2y) / 2; + curx = (ml1x + ml2x) / 2; + cury = (ml1y + ml2y) / 2; + + atemp1 = (fix - curx); + atemp2 = (fiy - cury); + ftmp1 = atemp1 * atemp1 + atemp2 * atemp2; + atemp1 = (lax - curx); + atemp2 = (lay - cury); + ftmp2 = atemp1 * atemp1 + atemp2 * atemp2; + + if (ftmp1 <= ftmp2) + { + m1x = m->first1x; + m1y = m->first1y; + m2x = m->first2x; + m2y = m->first2y; + } + else + { + m1x = m->last1x; + m1y = m->last1y; + m2x = m->last2x; + m2y = m->last2y; + } + + atemp1 = (m2x - ml2x); + atemp2 = (m2y - ml2y); + ftmp1 = atemp1 * atemp1 + atemp2 * atemp2; + atemp1 = (m2x - ml2bx); + atemp2 = (m2y - ml2by); + ftmp2 = atemp1 * atemp1 + atemp2 * atemp2; + + if (ftmp2 >= ftmp1) + { + ftmp1 = ml2bx; + ftmp2 = ml2by; + ml2bx = ml2x; + ml2by = ml2y; + ml2x = ftmp1; + ml2y = ftmp2; + ftmp1 = ml1bx; + ftmp2 = ml1by; + ml1bx = ml1x; + ml1by = ml1y; + ml1x = ftmp1; + ml1y = ftmp2; + } + + _bresenhamInitialize(&b, m2x, m2y, m1x, m1y); + do + { + rtgui_dc_draw_color_point(m->dst, b.x, b.y, m->color); + } + while (_bresenhamIterate(&b)==0); + + _bresenhamInitialize(&b, m1x, m1y, ml1bx, ml1by); + do + { + rtgui_dc_draw_color_point(m->dst, b.x, b.y, m->color); + } + while (_bresenhamIterate(&b)==0); + + _bresenhamInitialize(&b, ml1bx, ml1by, ml2bx, ml2by); + do + { + rtgui_dc_draw_color_point(m->dst, b.x, b.y, m->color); + } + while (_bresenhamIterate(&b)==0); + + _bresenhamInitialize(&b, ml2bx, ml2by, m2x, m2y); + do + { + rtgui_dc_draw_color_point(m->dst, b.x, b.y, m->color); + } + while (_bresenhamIterate(&b)==0); + + px[0] = m1x; + px[1] = m2x; + px[2] = ml1bx; + px[3] = ml2bx; + py[0] = m1y; + py[1] = m2y; + py[2] = ml1by; + py[3] = ml2by; + rtgui_dc_draw_polygon(m->dst, px, py, 4); + } + } + + m->last1x = ml1x; + m->last1y = ml1y; + m->last2x = ml2x; + m->last2y = ml2y; + m->first1x = ml1bx; + m->first1y = ml1by; + m->first2x = ml2bx; + m->first2y = ml2by; } -#define HYPOT(x,y) sqrt((double)(x)*(double)(x)+(double)(y)*(double)(y)) +#define HYPOT(x,y) sqrt((double)(x)*(double)(x)+(double)(y)*(double)(y)) /*! \brief Internal function to to draw wide lines with Murphy algorithm. @@ -2231,172 +2434,227 @@ Draws lines parallel to ideal line. */ void _murphyWideline(_MurphyIterator *m, rt_int16_t x1, rt_int16_t y1, rt_int16_t x2, rt_int16_t y2, rt_uint8_t width, rt_uint8_t miter) { - float offset = (float)width / 2.f; - - rt_int16_t temp; - rt_int16_t ptx, pty, ml1x, ml1y, ml2x, ml2y, ml1bx, ml1by, ml2bx, ml2by; - - int d0, d1; /* difference terms d0=perpendicular to line, d1=along line */ - - int q; /* pel counter,q=perpendicular to line */ - int tmp; - - int dd; /* distance along line */ - int tk; /* thickness threshold */ - double ang; /* angle for initial point calculation */ - double sang, cang; - - /* Initialisation */ - m->u = x2 - x1; /* delta x */ - m->v = y2 - y1; /* delta y */ - - if (m->u < 0) { /* swap to make sure we are in quadrants 1 or 4 */ - temp = x1; - x1 = x2; - x2 = temp; - temp = y1; - y1 = y2; - y2 = temp; - m->u *= -1; - m->v *= -1; - } - - if (m->v < 0) { /* swap to 1st quadrant and flag */ - m->v *= -1; - m->quad4 = 1; - } else { - m->quad4 = 0; - } - - if (m->v > m->u) { /* swap things if in 2 octant */ - tmp = m->u; - m->u = m->v; - m->v = tmp; - m->oct2 = 1; - } else { - m->oct2 = 0; - } - - m->ku = m->u + m->u; /* change in l for square shift */ - m->kv = m->v + m->v; /* change in d for square shift */ - m->kd = m->kv - m->ku; /* change in d for diagonal shift */ - m->kt = m->u - m->kv; /* diag/square decision threshold */ - - d0 = 0; - d1 = 0; - dd = 0; - - ang = atan((double) m->v / (double) m->u); /* calc new initial point - offset both sides of ideal */ - sang = sin(ang); - cang = cos(ang); - - if (m->oct2 == 0) { - ptx = x1 + (rt_int16_t)lrint(offset * sang); - if (m->quad4 == 0) { - pty = y1 - (rt_int16_t)lrint(offset * cang); - } else { - pty = y1 + (rt_int16_t)lrint(offset * cang); - } - } else { - ptx = x1 - (rt_int16_t)lrint(offset * cang); - if (m->quad4 == 0) { - pty = y1 + (rt_int16_t)lrint(offset * sang); - } else { - pty = y1 - (rt_int16_t)lrint(offset * sang); - } - } - - /* used here for constant thickness line */ - tk = (int) (4. * HYPOT(ptx - x1, pty - y1) * HYPOT(m->u, m->v)); - - if (miter == 0) { - m->first1x = -32768; - m->first1y = -32768; - m->first2x = -32768; - m->first2y = -32768; - m->last1x = -32768; - m->last1y = -32768; - m->last2x = -32768; - m->last2y = -32768; - } - - for (q = 0; dd <= tk; q++) { /* outer loop, stepping perpendicular to line */ - - _murphyParaline(m, ptx, pty, d1); /* call to inner loop - right edge */ - if (q == 0) { - ml1x = ptx; - ml1y = pty; - ml1bx = m->tempx; - ml1by = m->tempy; - } else { - ml2x = ptx; - ml2y = pty; - ml2bx = m->tempx; - ml2by = m->tempy; - } - if (d0 < m->kt) { /* square move */ - if (m->oct2 == 0) { - if (m->quad4 == 0) { - pty++; - } else { - pty--; - } - } else { - ptx++; - } - } else { /* diagonal move */ - dd += m->kv; - d0 -= m->ku; - if (d1 < m->kt) { /* normal diagonal */ - if (m->oct2 == 0) { - ptx--; - if (m->quad4 == 0) { - pty++; - } else { - pty--; - } - } else { - ptx++; - if (m->quad4 == 0) { - pty--; - } else { - pty++; - } - } - d1 += m->kv; - } else { /* double square move, extra parallel line */ - if (m->oct2 == 0) { - ptx--; - } else { - if (m->quad4 == 0) { - pty--; - } else { - pty++; - } - } - d1 += m->kd; - if (dd > tk) { - _murphyIteration(m, miter, ml1bx, ml1by, ml2bx, ml2by, ml1x, ml1y, ml2x, ml2y); - return; /* breakout on the extra line */ - } - _murphyParaline(m, ptx, pty, d1); - if (m->oct2 == 0) { - if (m->quad4 == 0) { - pty++; - } else { - - pty--; - } - } else { - ptx++; - } - } - } - dd += m->ku; - d0 += m->kv; - } - - _murphyIteration(m, miter, ml1bx, ml1by, ml2bx, ml2by, ml1x, ml1y, ml2x, ml2y); + float offset = (float)width / 2.f; + + rt_int16_t temp; + rt_int16_t ptx, pty, ml1x, ml1y, ml2x, ml2y, ml1bx, ml1by, ml2bx, ml2by; + + int d0, d1; /* difference terms d0=perpendicular to line, d1=along line */ + + int q; /* pel counter,q=perpendicular to line */ + int tmp; + + int dd; /* distance along line */ + int tk; /* thickness threshold */ + double ang; /* angle for initial point calculation */ + double sang, cang; + + /* Initialisation */ + m->u = x2 - x1; /* delta x */ + m->v = y2 - y1; /* delta y */ + + if (m->u < 0) /* swap to make sure we are in quadrants 1 or 4 */ + { + temp = x1; + x1 = x2; + x2 = temp; + temp = y1; + y1 = y2; + y2 = temp; + m->u *= -1; + m->v *= -1; + } + + if (m->v < 0) /* swap to 1st quadrant and flag */ + { + m->v *= -1; + m->quad4 = 1; + } + else + { + m->quad4 = 0; + } + + if (m->v > m->u) /* swap things if in 2 octant */ + { + tmp = m->u; + m->u = m->v; + m->v = tmp; + m->oct2 = 1; + } + else + { + m->oct2 = 0; + } + + m->ku = m->u + m->u; /* change in l for square shift */ + m->kv = m->v + m->v; /* change in d for square shift */ + m->kd = m->kv - m->ku; /* change in d for diagonal shift */ + m->kt = m->u - m->kv; /* diag/square decision threshold */ + + d0 = 0; + d1 = 0; + dd = 0; + + ang = atan((double) m->v / (double) m->u); /* calc new initial point - offset both sides of ideal */ + sang = sin(ang); + cang = cos(ang); + + if (m->oct2 == 0) + { + ptx = x1 + (rt_int16_t)lrint(offset * sang); + if (m->quad4 == 0) + { + pty = y1 - (rt_int16_t)lrint(offset * cang); + } + else + { + pty = y1 + (rt_int16_t)lrint(offset * cang); + } + } + else + { + ptx = x1 - (rt_int16_t)lrint(offset * cang); + if (m->quad4 == 0) + { + pty = y1 + (rt_int16_t)lrint(offset * sang); + } + else + { + pty = y1 - (rt_int16_t)lrint(offset * sang); + } + } + + /* used here for constant thickness line */ + tk = (int) (4. * HYPOT(ptx - x1, pty - y1) * HYPOT(m->u, m->v)); + + if (miter == 0) + { + m->first1x = -32768; + m->first1y = -32768; + m->first2x = -32768; + m->first2y = -32768; + m->last1x = -32768; + m->last1y = -32768; + m->last2x = -32768; + m->last2y = -32768; + } + + for (q = 0; dd <= tk; q++) /* outer loop, stepping perpendicular to line */ + { + + _murphyParaline(m, ptx, pty, d1); /* call to inner loop - right edge */ + if (q == 0) + { + ml1x = ptx; + ml1y = pty; + ml1bx = m->tempx; + ml1by = m->tempy; + } + else + { + ml2x = ptx; + ml2y = pty; + ml2bx = m->tempx; + ml2by = m->tempy; + } + if (d0 < m->kt) /* square move */ + { + if (m->oct2 == 0) + { + if (m->quad4 == 0) + { + pty++; + } + else + { + pty--; + } + } + else + { + ptx++; + } + } + else /* diagonal move */ + { + dd += m->kv; + d0 -= m->ku; + if (d1 < m->kt) /* normal diagonal */ + { + if (m->oct2 == 0) + { + ptx--; + if (m->quad4 == 0) + { + pty++; + } + else + { + pty--; + } + } + else + { + ptx++; + if (m->quad4 == 0) + { + pty--; + } + else + { + pty++; + } + } + d1 += m->kv; + } + else /* double square move, extra parallel line */ + { + if (m->oct2 == 0) + { + ptx--; + } + else + { + if (m->quad4 == 0) + { + pty--; + } + else + { + pty++; + } + } + d1 += m->kd; + if (dd > tk) + { + _murphyIteration(m, miter, ml1bx, ml1by, ml2bx, ml2by, ml1x, ml1y, ml2x, ml2y); + return; /* breakout on the extra line */ + } + _murphyParaline(m, ptx, pty, d1); + if (m->oct2 == 0) + { + if (m->quad4 == 0) + { + pty++; + } + else + { + + pty--; + } + } + else + { + ptx++; + } + } + } + dd += m->ku; + d0 += m->kv; + } + + _murphyIteration(m, miter, ml1bx, ml1by, ml2bx, ml2by, ml1x, ml1y, ml2x, ml2y); } @@ -2409,34 +2667,34 @@ void _murphyWideline(_MurphyIterator *m, rt_int16_t x1, rt_int16_t y1, rt_int16_ \param x2 X coordinate of the second point of the line. \param y2 Y coordinate of the second point of the line. \param width Width of the line in pixels. Must be >0. -\param color The color value of the line to draw (0xRRGGBBAA). +\param color The color value of the line to draw (0xRRGGBBAA). \returns Returns 0 on success, -1 on failure. */ int rtgui_dc_draw_thick_line(struct rtgui_dc * dst, rt_int16_t x1, rt_int16_t y1, rt_int16_t x2, rt_int16_t y2, rt_uint8_t width) { - int wh; - _MurphyIterator m; + int wh; + _MurphyIterator m; - if (dst == NULL) return -1; - if (width < 1) return -1; + if (dst == NULL) return -1; + if (width < 1) return -1; - /* Special case: thick "point" */ - if ((x1 == x2) && (y1 == y2)) - { - struct rtgui_rect rect; - wh = width / 2; + /* Special case: thick "point" */ + if ((x1 == x2) && (y1 == y2)) + { + struct rtgui_rect rect; + wh = width / 2; - rtgui_rect_init(&rect, x1 - wh, y1 - wh, x2 + width, y2 + width); - rtgui_dc_fill_rect(dst, &rect); - } + rtgui_rect_init(&rect, x1 - wh, y1 - wh, x2 + width, y2 + width); + rtgui_dc_fill_rect(dst, &rect); + } - m.dst = dst; - m.color = RTGUI_DC_FC(dst); + m.dst = dst; + m.color = RTGUI_DC_FC(dst); - _murphyWideline(&m, x1, y1, x2, y2, width, 0); - _murphyWideline(&m, x1, y1, x2, y2, width, 1); + _murphyWideline(&m, x1, y1, x2, y2, width, 0); + _murphyWideline(&m, x1, y1, x2, y2, width, 1); - return(0); + return(0); } RTM_EXPORT(rtgui_dc_draw_thick_line); diff --git a/components/gui/src/dc_buffer.c b/components/gui/src/dc_buffer.c index f8fd07ae28f909d98d6799ae7b2376324f8c32b9..196184e1ad11e18c630bb1e8bacf04aad8bf9c0d 100644 --- a/components/gui/src/dc_buffer.c +++ b/components/gui/src/dc_buffer.c @@ -1,11 +1,21 @@ /* * File : dc_buffer.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -14,11 +24,10 @@ #include #include #include -#include #include #include #include - +#include #include static rt_bool_t rtgui_dc_buffer_fini(struct rtgui_dc *dc); @@ -44,61 +53,96 @@ const struct rtgui_dc_engine dc_buffer_engine = rtgui_dc_buffer_fini, }; -#define _dc_get_pitch(dc) \ - (dc->pitch) -#define _dc_get_pixel(dc, x, y) \ - ((dc)->pixel + (y) * (dc)->pitch + (x) * rtgui_color_get_bpp((dc)->pixel_format)) -#define _dc_get_bits_per_pixel(dc) \ - rtgui_color_get_bits(dc->pixel_format) +#define _dc_get_pitch(dc) \ + (dc->pitch) +#define _dc_get_pixel(dc, x, y) \ + ((dc)->pixel + (y) * (dc)->pitch + (x) * rtgui_color_get_bpp((dc)->pixel_format)) +#define _dc_get_bits_per_pixel(dc) \ + rtgui_color_get_bits(dc->pixel_format) #define _hw_get_pixel(dst, x, y, type) \ - (type *)((rt_uint8_t*)((dst)->framebuffer) + (y) * (dst)->pitch + (x) * _UI_BITBYTES((dst)->bits_per_pixel)) + (type *)((rt_uint8_t*)((dst)->framebuffer) + (y) * (dst)->pitch + (x) * _UI_BITBYTES((dst)->bits_per_pixel)) struct rtgui_dc *rtgui_dc_buffer_create(int w, int h) { - rt_uint8_t pixel_format; + rt_uint8_t pixel_format; - pixel_format = rtgui_graphic_driver_get_default()->pixel_format; + pixel_format = rtgui_graphic_driver_get_default()->pixel_format; - /* create a dc_buffer with hardware driver pixel format */ - return rtgui_dc_buffer_create_pixformat(pixel_format, w, h); + /* create a dc_buffer with hardware driver pixel format */ + return rtgui_dc_buffer_create_pixformat(pixel_format, w, h); } RTM_EXPORT(rtgui_dc_buffer_create); struct rtgui_dc *rtgui_dc_buffer_create_pixformat(rt_uint8_t pixel_format, int w, int h) { - struct rtgui_dc_buffer *dc; - - dc = (struct rtgui_dc_buffer *)rtgui_malloc(sizeof(struct rtgui_dc_buffer)); - if (dc) - { - dc->parent.type = RTGUI_DC_BUFFER; - dc->parent.engine = &dc_buffer_engine; - dc->gc.foreground = default_foreground; - dc->gc.background = default_background; - dc->gc.font = rtgui_font_default(); - dc->gc.textalign = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP; - dc->pixel_format = pixel_format; - - dc->width = w; - dc->height = h; - dc->pitch = w * rtgui_color_get_bpp(pixel_format); - - dc->pixel = rtgui_malloc(h * dc->pitch); - if (!dc->pixel) - { - rtgui_free(dc); - return RT_NULL; - } - rt_memset(dc->pixel, 0, h * dc->pitch); - - return &(dc->parent); - } - - return RT_NULL; + struct rtgui_dc_buffer *dc; + + dc = (struct rtgui_dc_buffer *)rtgui_malloc(sizeof(struct rtgui_dc_buffer)); + if (dc) + { + dc->parent.type = RTGUI_DC_BUFFER; + dc->parent.engine = &dc_buffer_engine; + dc->gc.foreground = default_foreground; + dc->gc.background = default_background; + dc->gc.font = rtgui_font_default(); + dc->gc.textalign = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP; + dc->pixel_format = pixel_format; + + dc->width = w; + dc->height = h; + dc->pitch = w * rtgui_color_get_bpp(pixel_format); + +#ifdef RTGUI_IMAGE_CONTAINER + dc->image_item = RT_NULL; +#endif + dc->pixel = rtgui_malloc(h * dc->pitch); + if (!dc->pixel) + { + rtgui_free(dc); + return RT_NULL; + } + rt_memset(dc->pixel, 0, h * dc->pitch); + + return &(dc->parent); + } + + return RT_NULL; } RTM_EXPORT(rtgui_dc_buffer_create_pixformat); +#ifdef RTGUI_IMAGE_CONTAINER +struct rtgui_dc *rtgui_img_dc_create_pixformat(rt_uint8_t pixel_format, + rt_uint8_t *pixel, struct rtgui_image_item *image_item) +{ + struct rtgui_dc_buffer *dc; + + dc = (struct rtgui_dc_buffer *)rtgui_malloc(sizeof(struct rtgui_dc_buffer)); + if (dc) + { + dc->parent.type = RTGUI_DC_BUFFER; + dc->parent.engine = &dc_buffer_engine; + dc->gc.foreground = default_foreground; + dc->gc.background = default_background; + dc->gc.font = rtgui_font_default(); + dc->gc.textalign = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP; + dc->pixel_format = pixel_format; + + dc->width = image_item->image->w; + dc->height = image_item->image->h; + dc->pitch = image_item->image->w * rtgui_color_get_bpp(pixel_format); + + dc->image_item = image_item; + dc->pixel = pixel; + + return &(dc->parent); + } + + return RT_NULL; +} +RTM_EXPORT(rtgui_img_dc_create_pixformat); +#endif + struct rtgui_dc *rtgui_dc_buffer_create_from_dc(struct rtgui_dc* dc) { struct rtgui_dc_buffer *buffer; @@ -112,8 +156,8 @@ struct rtgui_dc *rtgui_dc_buffer_create_from_dc(struct rtgui_dc* dc) /* buffer clone */ buffer = (struct rtgui_dc_buffer*)rtgui_dc_buffer_create_pixformat(d->pixel_format, - d->width, - d->height); + d->width, + d->height); if (buffer != RT_NULL) { rt_memcpy(buffer->pixel, d->pixel, d->pitch * d->height); @@ -142,8 +186,16 @@ static rt_bool_t rtgui_dc_buffer_fini(struct rtgui_dc *dc) if (dc->type != RTGUI_DC_BUFFER) return RT_FALSE; - rtgui_free(buffer->pixel); - buffer->pixel = RT_NULL; +#ifdef RTGUI_IMAGE_CONTAINER + if (buffer->image_item) + { + rtgui_image_container_put(buffer->image_item); + buffer->pixel = RT_NULL; + } +#endif + + if (buffer->pixel) + rtgui_free(buffer->pixel); return RT_TRUE; } @@ -157,61 +209,61 @@ static void rtgui_dc_buffer_draw_point(struct rtgui_dc *self, int x, int y) /* does not draw point out of dc */ if ((x >= dst->width) || (y >= dst->height)) return; - if (x < 0 || y < 0) return; - - r = RTGUI_RGB_R(dst->gc.foreground); - g = RTGUI_RGB_G(dst->gc.foreground); - b = RTGUI_RGB_B(dst->gc.foreground); - a = RTGUI_RGB_A(dst->gc.foreground); - - switch (dst->pixel_format) - { - case RTGRAPHIC_PIXEL_FORMAT_RGB565: - DRAW_SETPIXELXY_RGB565(x, y); - break; - case RTGRAPHIC_PIXEL_FORMAT_BGR565: - DRAW_SETPIXELXY_BGR565(x, y); - break; - case RTGRAPHIC_PIXEL_FORMAT_RGB888: - DRAW_SETPIXELXY_RGB888(x, y); - break; - case RTGRAPHIC_PIXEL_FORMAT_ARGB888: - DRAW_SETPIXELXY_ARGB8888(x, y); - break; - } + if (x < 0 || y < 0) return; + + r = RTGUI_RGB_R(dst->gc.foreground); + g = RTGUI_RGB_G(dst->gc.foreground); + b = RTGUI_RGB_B(dst->gc.foreground); + a = RTGUI_RGB_A(dst->gc.foreground); + + switch (dst->pixel_format) + { + case RTGRAPHIC_PIXEL_FORMAT_RGB565: + DRAW_SETPIXELXY_RGB565(x, y); + break; + case RTGRAPHIC_PIXEL_FORMAT_BGR565: + DRAW_SETPIXELXY_BGR565(x, y); + break; + case RTGRAPHIC_PIXEL_FORMAT_RGB888: + DRAW_SETPIXELXY_RGB888(x, y); + break; + case RTGRAPHIC_PIXEL_FORMAT_ARGB888: + DRAW_SETPIXELXY_ARGB8888(x, y); + break; + } } static void rtgui_dc_buffer_draw_color_point(struct rtgui_dc *self, int x, int y, rtgui_color_t color) { - struct rtgui_dc_buffer *dst; - unsigned r, g, b, a; - - dst = (struct rtgui_dc_buffer *)self; - - /* does not draw point out of dc */ - if ((x >= dst->width) || (y >= dst->height)) return; - if (x < 0 || y < 0) return; - - r = RTGUI_RGB_R(color); - g = RTGUI_RGB_G(color); - b = RTGUI_RGB_B(color); - a = RTGUI_RGB_A(color); - - switch (dst->pixel_format) - { - case RTGRAPHIC_PIXEL_FORMAT_RGB565: - DRAW_SETPIXELXY_RGB565(x, y); - break; - case RTGRAPHIC_PIXEL_FORMAT_BGR565: - DRAW_SETPIXELXY_BGR565(x, y); - break; - case RTGRAPHIC_PIXEL_FORMAT_RGB888: - DRAW_SETPIXELXY_RGB888(x, y); - break; - case RTGRAPHIC_PIXEL_FORMAT_ARGB888: - DRAW_SETPIXELXY_ARGB8888(x, y); - break; - } + struct rtgui_dc_buffer *dst; + unsigned r, g, b, a; + + dst = (struct rtgui_dc_buffer *)self; + + /* does not draw point out of dc */ + if ((x >= dst->width) || (y >= dst->height)) return; + if (x < 0 || y < 0) return; + + r = RTGUI_RGB_R(color); + g = RTGUI_RGB_G(color); + b = RTGUI_RGB_B(color); + a = RTGUI_RGB_A(color); + + switch (dst->pixel_format) + { + case RTGRAPHIC_PIXEL_FORMAT_RGB565: + DRAW_SETPIXELXY_RGB565(x, y); + break; + case RTGRAPHIC_PIXEL_FORMAT_BGR565: + DRAW_SETPIXELXY_BGR565(x, y); + break; + case RTGRAPHIC_PIXEL_FORMAT_RGB888: + DRAW_SETPIXELXY_RGB888(x, y); + break; + case RTGRAPHIC_PIXEL_FORMAT_ARGB888: + DRAW_SETPIXELXY_ARGB8888(x, y); + break; + } } static void rtgui_dc_buffer_draw_vline(struct rtgui_dc *self, int x1, int y1, int y2) @@ -224,29 +276,29 @@ static void rtgui_dc_buffer_draw_vline(struct rtgui_dc *self, int x1, int y1, in if (x1 < 0 || x1 >= dst->width) return; if (y1 >= dst->height) return; - if (y1 < 0) y1 = 0; + if (y1 < 0) y1 = 0; if (y2 > dst->height) y2 = dst->height; - r = RTGUI_RGB_R(dst->gc.foreground); - g = RTGUI_RGB_G(dst->gc.foreground); - b = RTGUI_RGB_B(dst->gc.foreground); - a = RTGUI_RGB_A(dst->gc.foreground); - - switch (dst->pixel_format) - { - case RTGRAPHIC_PIXEL_FORMAT_RGB565: - VLINE(rt_uint16_t, DRAW_SETPIXEL_RGB565, 0); - break; - case RTGRAPHIC_PIXEL_FORMAT_BGR565: - VLINE(rt_uint16_t, DRAW_SETPIXEL_BGR565, 0); - break; - case RTGRAPHIC_PIXEL_FORMAT_RGB888: - VLINE(rt_uint16_t, DRAW_SETPIXEL_RGB888, 0); - break; - case RTGRAPHIC_PIXEL_FORMAT_ARGB888: - VLINE(rt_uint32_t, DRAW_SETPIXEL_ARGB8888, 0); - break; - } + r = RTGUI_RGB_R(dst->gc.foreground); + g = RTGUI_RGB_G(dst->gc.foreground); + b = RTGUI_RGB_B(dst->gc.foreground); + a = RTGUI_RGB_A(dst->gc.foreground); + + switch (dst->pixel_format) + { + case RTGRAPHIC_PIXEL_FORMAT_RGB565: + VLINE(rt_uint16_t, DRAW_SETPIXEL_RGB565, 0); + break; + case RTGRAPHIC_PIXEL_FORMAT_BGR565: + VLINE(rt_uint16_t, DRAW_SETPIXEL_BGR565, 0); + break; + case RTGRAPHIC_PIXEL_FORMAT_RGB888: + VLINE(rt_uint16_t, DRAW_SETPIXEL_RGB888, 0); + break; + case RTGRAPHIC_PIXEL_FORMAT_ARGB888: + VLINE(rt_uint32_t, DRAW_SETPIXEL_ARGB8888, 0); + break; + } } static void rtgui_dc_buffer_draw_hline(struct rtgui_dc *self, int x1, int x2, int y1) @@ -256,50 +308,50 @@ static void rtgui_dc_buffer_draw_hline(struct rtgui_dc *self, int x1, int x2, in dst = (struct rtgui_dc_buffer *)self; - /* parameter checking */ + /* parameter checking */ if (y1 < 0 || y1 >= dst->height) return; if (x1 >= dst->width) return; - if (x1 < 0) x1 = 0; + if (x1 < 0) x1 = 0; if (x2 > dst->width) x2 = dst->width; - r = RTGUI_RGB_R(dst->gc.foreground); - g = RTGUI_RGB_G(dst->gc.foreground); - b = RTGUI_RGB_B(dst->gc.foreground); - a = RTGUI_RGB_A(dst->gc.foreground); - - switch (dst->pixel_format) - { - case RTGRAPHIC_PIXEL_FORMAT_RGB565: - HLINE(rt_uint16_t, DRAW_SETPIXEL_RGB565, 0); - break; - case RTGRAPHIC_PIXEL_FORMAT_BGR565: - HLINE(rt_uint16_t, DRAW_SETPIXEL_BGR565, 0); - break; - case RTGRAPHIC_PIXEL_FORMAT_RGB888: - HLINE(rt_uint16_t, DRAW_SETPIXEL_RGB888, 0); - break; - case RTGRAPHIC_PIXEL_FORMAT_ARGB888: - HLINE(rt_uint32_t, DRAW_SETPIXEL_ARGB8888, 0); - break; - } + r = RTGUI_RGB_R(dst->gc.foreground); + g = RTGUI_RGB_G(dst->gc.foreground); + b = RTGUI_RGB_B(dst->gc.foreground); + a = RTGUI_RGB_A(dst->gc.foreground); + + switch (dst->pixel_format) + { + case RTGRAPHIC_PIXEL_FORMAT_RGB565: + HLINE(rt_uint16_t, DRAW_SETPIXEL_RGB565, 0); + break; + case RTGRAPHIC_PIXEL_FORMAT_BGR565: + HLINE(rt_uint16_t, DRAW_SETPIXEL_BGR565, 0); + break; + case RTGRAPHIC_PIXEL_FORMAT_RGB888: + HLINE(rt_uint16_t, DRAW_SETPIXEL_RGB888, 0); + break; + case RTGRAPHIC_PIXEL_FORMAT_ARGB888: + HLINE(rt_uint32_t, DRAW_SETPIXEL_ARGB8888, 0); + break; + } } static void rtgui_dc_buffer_fill_rect(struct rtgui_dc *self, struct rtgui_rect *dst_rect) { struct rtgui_dc_buffer *dst; - unsigned r, g, b, a; - rtgui_rect_t _r, *rect; + unsigned r, g, b, a; + rtgui_rect_t _r, *rect; RT_ASSERT(self); - if (dst_rect == RT_NULL) rtgui_dc_get_rect(self, &_r); - else _r = *dst_rect; + if (dst_rect == RT_NULL) rtgui_dc_get_rect(self, &_r); + else _r = *dst_rect; dst = (struct rtgui_dc_buffer *)self; - if (_r.x2 < 0 || _r.y2 < 0) return; /* out of rect */ + if (_r.x2 < 0 || _r.y2 < 0) return; /* out of rect */ - /* parameter checking */ + /* parameter checking */ if (_r.x1 >= dst->width) return; else if (_r.x1 < 0) @@ -313,28 +365,28 @@ static void rtgui_dc_buffer_fill_rect(struct rtgui_dc *self, struct rtgui_rect * _r.y1 = 0; if (_r.y2 > dst->height) _r.y2 = dst->height; - rect = &_r; - - r = RTGUI_RGB_R(dst->gc.background); - g = RTGUI_RGB_G(dst->gc.background); - b = RTGUI_RGB_B(dst->gc.background); - a = RTGUI_RGB_A(dst->gc.background); - - switch (dst->pixel_format) - { - case RTGRAPHIC_PIXEL_FORMAT_RGB565: - FILLRECT(rt_uint16_t, DRAW_SETPIXEL_RGB565); - break; - case RTGRAPHIC_PIXEL_FORMAT_BGR565: - FILLRECT(rt_uint16_t, DRAW_SETPIXEL_BGR565); - break; - case RTGRAPHIC_PIXEL_FORMAT_RGB888: - FILLRECT(rt_uint32_t, DRAW_SETPIXEL_RGB888); - break; - case RTGRAPHIC_PIXEL_FORMAT_ARGB888: - FILLRECT(rt_uint32_t, DRAW_SETPIXEL_ARGB8888); - break; - } + rect = &_r; + + r = RTGUI_RGB_R(dst->gc.background); + g = RTGUI_RGB_G(dst->gc.background); + b = RTGUI_RGB_B(dst->gc.background); + a = RTGUI_RGB_A(dst->gc.background); + + switch (dst->pixel_format) + { + case RTGRAPHIC_PIXEL_FORMAT_RGB565: + FILLRECT(rt_uint16_t, DRAW_SETPIXEL_RGB565); + break; + case RTGRAPHIC_PIXEL_FORMAT_BGR565: + FILLRECT(rt_uint16_t, DRAW_SETPIXEL_BGR565); + break; + case RTGRAPHIC_PIXEL_FORMAT_RGB888: + FILLRECT(rt_uint32_t, DRAW_SETPIXEL_RGB888); + break; + case RTGRAPHIC_PIXEL_FORMAT_ARGB888: + FILLRECT(rt_uint32_t, DRAW_SETPIXEL_ARGB8888); + break; + } } /* blit a dc to another dc */ @@ -343,16 +395,16 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc *self, struct rtgui_dc *dest, rtgui_rect_t *rect) { - int pitch; - rt_uint16_t rect_width, rect_height; - struct rtgui_rect _rect, *dest_rect; + int pitch; + rt_uint16_t rect_width, rect_height; + struct rtgui_rect _rect, *dest_rect; struct rtgui_point dc_point; struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer *)self; if (rtgui_dc_get_visible(dest) == RT_FALSE) return; - /* use the (0,0) origin point */ + /* use the (0,0) origin point */ if (dc_pt == RT_NULL) dc_point = rtgui_empty_point; else @@ -361,12 +413,12 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc *self, } rtgui_dc_get_rect(dest, &_rect); - /* use the rect of dest dc */ - if (rect == RT_NULL) - { - dest_rect = &_rect; - } - else + /* use the rect of dest dc */ + if (rect == RT_NULL) + { + dest_rect = &_rect; + } + else { dest_rect = rect; if (dest_rect->x1 >= _rect.x2 || dest_rect->y1 >= _rect.y2) @@ -391,204 +443,192 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc *self, dest_rect->y2 = _rect.y2; } - if (dest_rect->x2 < dest_rect->x1 || dest_rect->y2 < dest_rect->y1) return; + if (dest_rect->x2 < dest_rect->x1 || dest_rect->y2 < dest_rect->y1) return; if (dc_point.x >= dc->width || dc_point.y >= dc->height) return; - /* get the minimal width and height */ - rect_width = _UI_MIN(rtgui_rect_width(*dest_rect), dc->width - dc_point.x); - rect_height = _UI_MIN(rtgui_rect_height(*dest_rect), dc->height - dc_point.y); + /* get the minimal width and height */ + rect_width = _UI_MIN(rtgui_rect_width(*dest_rect), dc->width - dc_point.x); + rect_height = _UI_MIN(rtgui_rect_height(*dest_rect), dc->height - dc_point.y); if ((dest->type == RTGUI_DC_HW) || (dest->type == RTGUI_DC_CLIENT)) { - int index; + int index; rt_uint8_t *line_ptr, *pixels; rtgui_blit_line_func blit_line; - struct rtgui_graphic_driver *hw_driver; + struct rtgui_graphic_driver *hw_driver; - hw_driver = rtgui_graphic_driver_get_default(); + hw_driver = rtgui_graphic_driver_get_default(); /* prepare pixel line */ - pixels = _dc_get_pixel(dc, dc_point.x, dc_point.y); + pixels = _dc_get_pixel(dc, dc_point.x, dc_point.y); - if (hw_driver->bits_per_pixel == _dc_get_bits_per_pixel(dc)) + if (dest->type == RTGUI_DC_HW && hw_driver->framebuffer != RT_NULL) + { + /* use rtgui_blit */ + + struct rtgui_blit_info info; + struct rtgui_widget *owner; + + info.a = 255; + + /* blit source */ + info.src = _dc_get_pixel(dc, dc_point.x, dc_point.y); + info.src_fmt = dc->pixel_format; + info.src_h = rect_height; + info.src_w = rect_width; + info.src_pitch = dc->pitch; + info.src_skip = info.src_pitch - info.src_w * rtgui_color_get_bpp(dc->pixel_format); + + owner = ((struct rtgui_dc_hw*)dest)->owner; + + /* blit destination */ + info.dst = (rt_uint8_t*)hw_driver->framebuffer; + info.dst = info.dst + (owner->extent.y1 + dest_rect->y1) * hw_driver->pitch + + (owner->extent.x1 + dest_rect->x1) * rtgui_color_get_bpp(hw_driver->pixel_format); + info.dst_fmt = hw_driver->pixel_format; + info.dst_h = rect_height; + info.dst_w = rect_width; + info.dst_pitch = hw_driver->pitch; + info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(hw_driver->pixel_format); + + rtgui_blit(&info); + } + else if (dest->type == RTGUI_DC_CLIENT&& hw_driver->framebuffer != RT_NULL) { - if (dest->type == RTGUI_DC_HW && hw_driver->framebuffer != RT_NULL) - { - rt_uint8_t *hw_pixels; - struct rtgui_dc_hw *hw; - - hw = (struct rtgui_dc_hw*)dest; - - /* NOTES: the rect of DC is the logic coordination. - * It should be converted to client - */ - if (dest_rect != &_rect) - { - /* use local rect */ - _rect = *dest_rect; - dest_rect = &_rect; - } - rtgui_rect_moveto(dest_rect, hw->owner->extent.x1, hw->owner->extent.y1); - - pitch = rtgui_color_get_bpp(hw_driver->pixel_format) * rect_width; - hw_pixels = (rt_uint8_t*)(hw_driver->framebuffer + dest_rect->y1 * hw_driver->pitch + - dest_rect->x1 * rtgui_color_get_bpp(hw_driver->pixel_format)); - - /* do the blit with memory copy */ - for (index = 0; index < rect_height; index ++) - { - rt_memcpy(hw_pixels, pixels, pitch); - pixels += dc->pitch; - hw_pixels += hw_driver->pitch; - } - } - else - { - /* it's the same bits per pixel, draw it directly */ - for (index = dest_rect->y1; index < dest_rect->y1 + rect_height; index++) - { - dest->engine->blit_line(dest, dest_rect->x1, dest_rect->x1 + rect_width, index, pixels); - pixels += dc->pitch; - } - } + /* use rtgui_blit */ + rt_uint8_t bpp, hw_bpp; + struct rtgui_blit_info info; + struct rtgui_widget *owner; + struct rtgui_region dest_region; + struct rtgui_rect dest_extent; + int num_rects; + struct rtgui_rect *rects; + + /* get owner */ + owner = RTGUI_CONTAINER_OF(dest, struct rtgui_widget, dc_type); + + dest_extent = *dest_rect; + rtgui_widget_rect_to_device(owner, &dest_extent); + + rtgui_region_init_with_extents(&dest_region, &dest_extent); + rtgui_region_intersect_rect(&dest_region, &(owner->clip), &dest_extent); + bpp = rtgui_color_get_bpp(dc->pixel_format); + hw_bpp = rtgui_color_get_bpp(hw_driver->pixel_format); + + num_rects = rtgui_region_num_rects(&dest_region); + rects = rtgui_region_rects(&dest_region); + + /* common info */ + info.a = 255; + info.src_fmt = dc->pixel_format; + info.src_pitch = dc->pitch; + + info.dst_fmt = hw_driver->pixel_format; + info.dst_pitch = hw_driver->pitch; + + for (index = 0; index < num_rects; index ++) + { + struct rtgui_rect *r = &rects[index]; + + /* blit source */ + info.src = _dc_get_pixel(dc, dc_point.x + (r->x1 - dest_extent.x1), + dc_point.y + (r->y1 - dest_extent.y1)); + info.src_h = rtgui_rect_height(*r); + info.src_w = rtgui_rect_width(*r); + info.src_skip = info.src_pitch - info.src_w * bpp; + + /* blit destination */ + info.dst = (rt_uint8_t*)hw_driver->framebuffer + r->y1 * hw_driver->pitch + + r->x1 * hw_bpp; + info.dst_h = rtgui_rect_height(*r); + info.dst_w = rtgui_rect_width(*r); + info.dst_skip = info.dst_pitch - info.dst_w * hw_bpp; + + rtgui_blit(&info); + } + + rtgui_region_fini(&dest_region); } else { - struct rtgui_graphic_driver *hw_driver; - - hw_driver = rtgui_graphic_driver_get_default(); - - if ((dc->pixel_format == RTGRAPHIC_PIXEL_FORMAT_ARGB888) && - (dest->type == RTGUI_DC_HW) && - (hw_driver->framebuffer != RT_NULL) && - (hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)) - { - /* do the fast ARGB to RGB565 blit */ - struct rtgui_blit_info info; - struct rtgui_widget *owner; - - /* blit source */ - info.src = _dc_get_pixel(dc, dc_point.x, dc_point.y); - info.src_fmt = dc->pixel_format; - info.src_h = rect_height; - info.src_w = rect_width; - info.src_pitch = dc->pitch; - info.src_skip = info.src_pitch - info.src_w * rtgui_color_get_bpp(dc->pixel_format); - - owner = ((struct rtgui_dc_hw*)dest)->owner; - - /* blit destination */ - info.dst = (rt_uint8_t*)hw_driver->framebuffer; - info.dst = info.dst + (owner->extent.y1 + dest_rect->y1) * hw_driver->pitch + - (owner->extent.x1 + dest_rect->x1) * rtgui_color_get_bpp(hw_driver->pixel_format); - info.dst_fmt = hw_driver->pixel_format; - info.dst_h = rect_height; - info.dst_w = rect_width; - info.dst_pitch = hw_driver->pitch; - info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(hw_driver->pixel_format); - - rtgui_blit(&info); - } - else - { - /* calculate pitch */ - pitch = rect_width * rtgui_color_get_bpp(dc->pixel_format); - - /* get blit line function */ - blit_line = rtgui_blit_line_get(_UI_BITBYTES(hw_driver->bits_per_pixel), - rtgui_color_get_bpp(dc->pixel_format)); - if (hw_driver->framebuffer != RT_NULL) - { - struct rtgui_widget* owner; - if (dest->type == RTGUI_DC_HW) owner = ((struct rtgui_dc_hw*) dest)->owner; - else if (dest->type == RTGUI_DC_CLIENT) owner = RTGUI_CONTAINER_OF(dest, struct rtgui_widget, dc_type); - else RT_ASSERT(0); - - /* change the logic coordinate to the device coordinate */ - rtgui_rect_moveto(dest_rect, owner->extent.x1, owner->extent.y1); - - for (index = dest_rect->y1; index < dest_rect->y1 + rect_height; index ++) - { - line_ptr = _hw_get_pixel(hw_driver, dest_rect->x1, index, rt_uint8_t); - blit_line(line_ptr, (rt_uint8_t*)pixels, pitch); - pixels += dc->pitch; - } - } - else - { - /* calculate pitch */ - pitch = rect_width * rtgui_color_get_bpp(dc->pixel_format); - /* create line buffer */ - line_ptr = (rt_uint8_t *) rtgui_malloc(rect_width * _UI_BITBYTES(hw_driver->bits_per_pixel)); - - /* draw each line */ - for (index = dest_rect->y1; index < dest_rect->y1 + rect_height; index ++) - { - /* blit on line buffer */ - blit_line(line_ptr, (rt_uint8_t *)pixels, pitch); - pixels += dc->pitch; - - /* draw on hardware dc */ - dest->engine->blit_line(dest, dest_rect->x1, dest_rect->x1 + rect_width, - index, line_ptr); - } - - /* release line buffer */ - rtgui_free(line_ptr); - } - } + /* calculate pitch */ + pitch = rect_width * rtgui_color_get_bpp(dc->pixel_format); + + /* get blit line function */ + blit_line = rtgui_blit_line_get(_UI_BITBYTES(hw_driver->bits_per_pixel), + rtgui_color_get_bpp(dc->pixel_format)); + if (hw_driver->framebuffer != RT_NULL) + { + struct rtgui_widget* owner; + if (dest->type == RTGUI_DC_HW) owner = ((struct rtgui_dc_hw*) dest)->owner; + else if (dest->type == RTGUI_DC_CLIENT) owner = RTGUI_CONTAINER_OF(dest, struct rtgui_widget, dc_type); + else RT_ASSERT(0); + + /* change the logic coordinate to the device coordinate */ + rtgui_rect_moveto(dest_rect, owner->extent.x1, owner->extent.y1); + + for (index = dest_rect->y1; index < dest_rect->y1 + rect_height; index ++) + { + line_ptr = _hw_get_pixel(hw_driver, dest_rect->x1, index, rt_uint8_t); + blit_line(line_ptr, (rt_uint8_t*)pixels, pitch); + pixels += dc->pitch; + } + } + else + { + /* calculate pitch */ + pitch = rect_width * rtgui_color_get_bpp(dc->pixel_format); + /* create line buffer */ + line_ptr = (rt_uint8_t *) rtgui_malloc(rect_width * _UI_BITBYTES(hw_driver->bits_per_pixel)); + + /* draw each line */ + for (index = dest_rect->y1; index < dest_rect->y1 + rect_height; index ++) + { + /* blit on line buffer */ + blit_line(line_ptr, (rt_uint8_t *)pixels, pitch); + pixels += dc->pitch; + + /* draw on hardware dc */ + dest->engine->blit_line(dest, dest_rect->x1, dest_rect->x1 + rect_width, + index, line_ptr); + } + + /* release line buffer */ + rtgui_free(line_ptr); + } } } - else if (dest->type == RTGUI_DC_BUFFER) - { - struct rtgui_dc_buffer *dest_dc = (struct rtgui_dc_buffer*)dest; - - if (dest_dc->pixel_format == dc->pixel_format && dest_dc->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565) - { - int index; - rt_uint8_t *pixels, *dest_pixels; - - /* get pitch */ - pitch = rect_width * rtgui_color_get_bpp(dc->pixel_format); - - pixels = _dc_get_pixel(dc, dc_point.x, dc_point.y); - dest_pixels = _dc_get_pixel(dest_dc, dest_rect->x1, dest_rect->y1); - - for (index = 0; index < rect_height; index ++) - { - rt_memcpy(dest_pixels, pixels, pitch); - pixels += dc->pitch; - dest_pixels += dest_dc->pitch; - } - } - else /* use rtgui_blit to handle buffer blit */ - { - /* do the fast ARGB to RGB565 blit */ - struct rtgui_blit_info info; - - /* blit source */ - info.src = _dc_get_pixel(dc, dc_point.x, dc_point.y); - info.src_fmt = dc->pixel_format; - info.src_h = rect_height; - info.src_w = rect_width; - info.src_pitch = dc->pitch; - info.src_skip = info.src_pitch - info.src_w * rtgui_color_get_bpp(dc->pixel_format); - - /* blit destination */ - info.dst = _dc_get_pixel(dest_dc, dest_rect->x1, dest_rect->y1); - info.dst_fmt = dest_dc->pixel_format; - info.dst_h = rect_height; - info.dst_w = rect_width; - info.dst_pitch = dest_dc->pitch; - info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(dest_dc->pixel_format); - - rtgui_blit(&info); - } - } + else if (dest->type == RTGUI_DC_BUFFER) + { + struct rtgui_dc_buffer *dest_dc = (struct rtgui_dc_buffer*)dest; + + /* use rtgui_blit to handle buffer blit */ + struct rtgui_blit_info info; + + info.a = 255; + + /* blit source */ + info.src = _dc_get_pixel(dc, dc_point.x, dc_point.y); + info.src_fmt = dc->pixel_format; + info.src_h = rect_height; + info.src_w = rect_width; + info.src_pitch = dc->pitch; + info.src_skip = info.src_pitch - info.src_w * rtgui_color_get_bpp(dc->pixel_format); + + /* blit destination */ + info.dst = _dc_get_pixel(dest_dc, dest_rect->x1, dest_rect->y1); + info.dst_fmt = dest_dc->pixel_format; + info.dst_h = rect_height; + info.dst_w = rect_width; + info.dst_pitch = dest_dc->pitch; + info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(dest_dc->pixel_format); + + rtgui_blit(&info); + } } static void rtgui_dc_buffer_blit_line(struct rtgui_dc *self, int x1, int x2, int y, rt_uint8_t *line_data) { - rt_uint8_t *pixel; + rt_uint8_t *pixel; struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer *)self; RT_ASSERT(dc != RT_NULL); @@ -604,7 +644,36 @@ static void rtgui_dc_buffer_blit_line(struct rtgui_dc *self, int x1, int x2, int if (x2 >= dc->width) x2 = dc->width-1; - pixel = _dc_get_pixel(dc,x1,y); + pixel = _dc_get_pixel(dc,x1,y); rt_memcpy(pixel, line_data, (x2 - x1) * rtgui_color_get_bpp(dc->pixel_format)); } +#ifdef RT_USING_DFS +#include +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 + diff --git a/components/gui/src/dc_client.c b/components/gui/src/dc_client.c index bd173ff63dac84188e00ecacc72c1f6ec7667c87..762859f677d36cae516e7d0c1c34ffb89e42ea80 100644 --- a/components/gui/src/dc_client.c +++ b/components/gui/src/dc_client.c @@ -1,11 +1,21 @@ /* * File : dc_client.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -16,8 +26,6 @@ * 2010-09-14 Bernard fix vline and hline coordinate issue */ #include -#include -#include #include #include @@ -88,7 +96,7 @@ static void rtgui_dc_client_draw_point(struct rtgui_dc *self, int x, int y) rtgui_widget_t *owner; if (self == RT_NULL) return; - if (!rtgui_dc_get_visible(self)) return; + if (!rtgui_dc_get_visible(self)) return; /* get owner */ owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type); @@ -109,7 +117,7 @@ static void rtgui_dc_client_draw_color_point(struct rtgui_dc *self, int x, int y rtgui_widget_t *owner; if (self == RT_NULL) return; - if (!rtgui_dc_get_visible(self)) return; + if (!rtgui_dc_get_visible(self)) return; /* get owner */ owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type); @@ -133,7 +141,7 @@ static void rtgui_dc_client_draw_vline(struct rtgui_dc *self, int x, int y1, int rtgui_widget_t *owner; if (self == RT_NULL) return; - if (!rtgui_dc_get_visible(self)) return; + if (!rtgui_dc_get_visible(self)) return; /* get owner */ owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type); @@ -160,26 +168,26 @@ static void rtgui_dc_client_draw_vline(struct rtgui_dc *self, int x, int y1, int hw_driver->ops->draw_vline(&(owner->gc.foreground), x, y1, y2); } else - { - for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++) - { - rtgui_rect_t *prect; - register rt_base_t draw_y1, draw_y2; - - prect = ((rtgui_rect_t *)(owner->clip.data + index + 1)); - draw_y1 = y1; - draw_y2 = y2; - - /* calculate vline clip */ - if (prect->x1 > x || prect->x2 <= x) continue; - if (prect->y2 <= y1 || prect->y1 > y2) continue; - - if (prect->y1 > y1) draw_y1 = prect->y1; - if (prect->y2 < y2) draw_y2 = prect->y2; - - /* draw vline */ - hw_driver->ops->draw_vline(&(owner->gc.foreground), x, draw_y1, draw_y2); - } + { + for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++) + { + rtgui_rect_t *prect; + register rt_base_t draw_y1, draw_y2; + + prect = ((rtgui_rect_t *)(owner->clip.data + index + 1)); + draw_y1 = y1; + draw_y2 = y2; + + /* calculate vline clip */ + if (prect->x1 > x || prect->x2 <= x) continue; + if (prect->y2 <= y1 || prect->y1 > y2) continue; + + if (prect->y1 > y1) draw_y1 = prect->y1; + if (prect->y2 < y2) draw_y2 = prect->y2; + + /* draw vline */ + hw_driver->ops->draw_vline(&(owner->gc.foreground), x, draw_y1, draw_y2); + } } } @@ -192,7 +200,7 @@ static void rtgui_dc_client_draw_hline(struct rtgui_dc *self, int x1, int x2, in rtgui_widget_t *owner; if (self == RT_NULL) return; - if (!rtgui_dc_get_visible(self)) return; + if (!rtgui_dc_get_visible(self)) return; /* get owner */ owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type); @@ -220,8 +228,8 @@ static void rtgui_dc_client_draw_hline(struct rtgui_dc *self, int x1, int x2, in hw_driver->ops->draw_hline(&(owner->gc.foreground), x1, x2, y); } else - { - for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++) + { + for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++) { rtgui_rect_t *prect; register rt_base_t draw_x1, draw_x2; @@ -252,7 +260,7 @@ static void rtgui_dc_client_fill_rect(struct rtgui_dc *self, struct rtgui_rect * RT_ASSERT(self); RT_ASSERT(rect); - if (!rtgui_dc_get_visible(self)) return; + if (!rtgui_dc_get_visible(self)) return; /* get owner */ owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type); @@ -279,7 +287,7 @@ static void rtgui_dc_client_blit_line(struct rtgui_dc *self, int x1, int x2, int rtgui_widget_t *owner; if (self == RT_NULL) return; - if (!rtgui_dc_get_visible(self)) return; + if (!rtgui_dc_get_visible(self)) return; /* get owner */ owner = RTGUI_CONTAINER_OF(self, struct rtgui_widget, dc_type); @@ -312,8 +320,8 @@ static void rtgui_dc_client_blit_line(struct rtgui_dc *self, int x1, int x2, int hw_driver->ops->draw_raw_hline(line_data + offset, x1, x2, y); } else - { - for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++) + { + for (index = 0; index < rtgui_region_num_rects(&(owner->clip)); index ++) { rtgui_rect_t *prect; register rt_base_t draw_x1, draw_x2; diff --git a/components/gui/src/dc_hw.c b/components/gui/src/dc_hw.c index 2ff6ba9a5f6d7f15afaab1680d37c506db4c3c66..dfed6f8e9feb12d868a5275553b4a48f41803188 100644 --- a/components/gui/src/dc_hw.c +++ b/components/gui/src/dc_hw.c @@ -1,18 +1,27 @@ /* * File : dc_hw.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes * 2009-10-16 Bernard first version */ #include -#include #include #include #include @@ -54,17 +63,17 @@ struct rtgui_dc *rtgui_dc_hw_create(rtgui_widget_t *owner) /* create DC */ dc = (struct rtgui_dc_hw *) rtgui_malloc(sizeof(struct rtgui_dc_hw)); - if (dc) - { - dc->parent.type = RTGUI_DC_HW; - dc->parent.engine = &dc_hw_engine; - dc->owner = owner; - dc->hw_driver = rtgui_graphic_driver_get_default(); + if (dc) + { + dc->parent.type = RTGUI_DC_HW; + dc->parent.engine = &dc_hw_engine; + dc->owner = owner; + dc->hw_driver = rtgui_graphic_driver_get_default(); - return &(dc->parent); - } + return &(dc->parent); + } - return RT_NULL; + return RT_NULL; } static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc *dc) diff --git a/components/gui/src/dc_rotozoom.c b/components/gui/src/dc_rotozoom.c index 2c823dff1f23a9bc3f84859e4f8fc23a49de820a..e6700a6b404fd0509f200d70e83df2356352389b 100644 --- a/components/gui/src/dc_rotozoom.c +++ b/components/gui/src/dc_rotozoom.c @@ -22,7 +22,7 @@ * 2014-03-15 Bernard porting SDL_gfx to RT-Thread GUI */ -/* +/* SDL_rotozoom.c: rotozoomer, zoomer and shrinker for 32bit or 8bit surfaces @@ -65,32 +65,34 @@ Andreas Schiffler -- aschiffler at ferzkopp dot net /*! \brief A 32 bit RGBA pixel. */ -typedef struct tColorRGBA { - rt_uint8_t r; - rt_uint8_t g; - rt_uint8_t b; - rt_uint8_t a; +typedef struct tColorRGBA +{ + rt_uint8_t r; + rt_uint8_t g; + rt_uint8_t b; + rt_uint8_t a; } tColorRGBA; /*! \brief A 8bit Y/palette pixel. */ -typedef struct tColorY { - rt_uint8_t y; +typedef struct tColorY +{ + rt_uint8_t y; } tColorY; -/*! +/*! \brief Returns maximum of two numbers a and b. */ #define MAX(a,b) (((a) > (b)) ? (a) : (b)) -/*! +/*! \brief Number of guard rows added to destination surfaces. This is a simple but effective workaround for observed issues. These rows allocate extra memory and are then hidden from the surface. -Rows are added to the end of destination surfaces when they are allocated. -This catches any potential overflows which seem to happen with +Rows are added to the end of destination surfaces when they are allocated. +This catches any potential overflows which seem to happen with just the right src image dimensions and scale/rotation and can lead to a situation where the program can segfault. */ @@ -99,11 +101,11 @@ to a situation where the program can segfault. /*! \brief Lower limit of absolute zoom factor or rotation degrees. */ -#define VALUE_LIMIT 0.001 +#define VALUE_LIMIT 0.001 void rtgui_dc_zoom_size(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight); -/*! +/*! \brief Internal 32 bit integer-factor averaging Shrinker. Shrinks 32 bit RGBA/ABGR 'src' surface to 'dst' surface. @@ -120,82 +122,82 @@ Assumes dst surface was allocated with the correct dimensions. */ int _rtgui_dc_shrink_RGBA(struct rtgui_dc_buffer * src, struct rtgui_dc_buffer * dst, int factorx, int factory) { - int x, y, dx, dy, sgap, dgap, ra, ga, ba, aa; - int n_average; - tColorRGBA *sp, *osp, *oosp; - tColorRGBA *dp; - - /* - * Averaging integer shrink - */ - - /* Precalculate division factor */ - n_average = factorx*factory; - - /* - * Scan destination - */ - sp = (tColorRGBA *) src->pixel; - sgap = src->pitch - src->width * 4; + int x, y, dx, dy, sgap, dgap, ra, ga, ba, aa; + int n_average; + tColorRGBA *sp, *osp, *oosp; + tColorRGBA *dp; + + /* + * Averaging integer shrink + */ + + /* Precalculate division factor */ + n_average = factorx*factory; + + /* + * Scan destination + */ + sp = (tColorRGBA *) src->pixel; + sgap = src->pitch - src->width * 4; sgap = sgap; - dp = (tColorRGBA *) dst->pixel; - dgap = dst->pitch - dst->width * 4; - - for (y = 0; y < dst->height; y++) - { - osp=sp; - for (x = 0; x < dst->width; x++) - { - /* Trace out source box and accumulate */ - oosp=sp; - ra=ga=ba=aa=0; - for (dy=0; dy < factory; dy++) - { - for (dx=0; dx < factorx; dx++) - { - ra += sp->r; - ga += sp->g; - ba += sp->b; - aa += sp->a; - - sp++; - } - /* src dx loop */ - sp = (tColorRGBA *)((rt_uint8_t*)sp + (src->pitch - 4*factorx)); // next y - } - /* src dy loop */ - - /* next box-x */ - sp = (tColorRGBA *)((rt_uint8_t*)oosp + 4*factorx); - - /* Store result in destination */ - dp->r = ra/n_average; - dp->g = ga/n_average; - dp->b = ba/n_average; - dp->a = aa/n_average; - - /* - * Advance destination pointer - */ - dp++; - } - /* dst x loop */ - - /* next box-y */ - sp = (tColorRGBA *)((rt_uint8_t*)osp + src->pitch*factory); - - /* - * Advance destination pointers - */ - dp = (tColorRGBA *) ((rt_uint8_t *) dp + dgap); - } - /* dst y loop */ - - return (0); + dp = (tColorRGBA *) dst->pixel; + dgap = dst->pitch - dst->width * 4; + + for (y = 0; y < dst->height; y++) + { + osp=sp; + for (x = 0; x < dst->width; x++) + { + /* Trace out source box and accumulate */ + oosp=sp; + ra=ga=ba=aa=0; + for (dy=0; dy < factory; dy++) + { + for (dx=0; dx < factorx; dx++) + { + ra += sp->r; + ga += sp->g; + ba += sp->b; + aa += sp->a; + + sp++; + } + /* src dx loop */ + sp = (tColorRGBA *)((rt_uint8_t*)sp + (src->pitch - 4*factorx)); // next y + } + /* src dy loop */ + + /* next box-x */ + sp = (tColorRGBA *)((rt_uint8_t*)oosp + 4*factorx); + + /* Store result in destination */ + dp->r = ra/n_average; + dp->g = ga/n_average; + dp->b = ba/n_average; + dp->a = aa/n_average; + + /* + * Advance destination pointer + */ + dp++; + } + /* dst x loop */ + + /* next box-y */ + sp = (tColorRGBA *)((rt_uint8_t*)osp + src->pitch*factory); + + /* + * Advance destination pointers + */ + dp = (tColorRGBA *) ((rt_uint8_t *) dp + dgap); + } + /* dst y loop */ + + return (0); } -/*! +/*! \brief Internal 32 bit Zoomer with optional anti-aliasing by bilinear interpolation. Zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface. @@ -212,226 +214,256 @@ Assumes dst surface was allocated with the correct dimensions. */ int _rtgui_dc_zoom_RGBA(struct rtgui_dc_buffer * src, struct rtgui_dc_buffer * dst, int flipx, int flipy, int smooth) { - int x, y, sx, sy, ssx, ssy, *sax, *say, *csax, *csay, *salast, csx, csy, ex, ey, cx, cy, sstep, sstepx, sstepy; - tColorRGBA *c00, *c01, *c10, *c11; - tColorRGBA *sp, *csp, *dp; - int spixelgap, spixelw, spixelh, dgap, t1, t2; - - /* - * Allocate memory for row/column increments - */ - if ((sax = (int *) rtgui_malloc((dst->width + 1) * sizeof(rt_uint32_t))) == RT_NULL) { - return (-1); - } - if ((say = (int *) rtgui_malloc((dst->height + 1) * sizeof(rt_uint32_t))) == RT_NULL) { - rtgui_free(sax); - return (-1); - } - - /* - * Precalculate row increments - */ - spixelw = (src->width - 1); - spixelh = (src->height- 1); - if (smooth) { - sx = (int) (65536.0 * (double) spixelw / (double) (dst->width - 1)); - sy = (int) (65536.0 * (double) spixelh / (double) (dst->height - 1)); - } else { - sx = (int) (65536.0 * (double) (src->width) / (double) (dst->width)); - sy = (int) (65536.0 * (double) (src->height) / (double) (dst->height)); - } - - /* Maximum scaled source size */ - ssx = (src->width << 16) - 1; - ssy = (src->height << 16) - 1; - - /* Precalculate horizontal row increments */ - csx = 0; - csax = sax; - for (x = 0; x <= dst->width; x++) { - *csax = csx; - csax++; - csx += sx; - - /* Guard from overflows */ - if (csx > ssx) { - csx = ssx; - } - } - - /* Precalculate vertical row increments */ - csy = 0; - csay = say; - for (y = 0; y <= dst->height; y++) { - *csay = csy; - csay++; - csy += sy; - - /* Guard from overflows */ - if (csy > ssy) { - csy = ssy; - } - } - - sp = (tColorRGBA *) src->pixel; - dp = (tColorRGBA *) dst->pixel; - dgap = dst->pitch - dst->width * 4; - spixelgap = src->pitch/4; - - if (flipx) sp += spixelw; - if (flipy) sp += (spixelgap * spixelh); - - /* - * Switch between interpolating and non-interpolating code - */ - if (smooth) { - - /* - * Interpolating Zoom - */ - csay = say; - for (y = 0; y < dst->height; y++) { - csp = sp; - csax = sax; - for (x = 0; x < dst->width; x++) { - /* - * Setup color source pointers - */ - ex = (*csax & 0xffff); - ey = (*csay & 0xffff); - cx = (*csax >> 16); - cy = (*csay >> 16); - sstepx = cx < spixelw; - sstepy = cy < spixelh; - c00 = sp; - c01 = sp; - c10 = sp; - if (sstepy) { - if (flipy) { - c10 -= spixelgap; - } else { - c10 += spixelgap; - } - } - c11 = c10; - if (sstepx) { - if (flipx) { - c01--; - c11--; - } else { - c01++; - c11++; - } - } - - /* - * Draw and interpolate colors - */ - t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff; - t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff; - dp->r = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff; - t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff; - dp->g = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff; - t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff; - dp->b = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff; - t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff; - dp->a = (((t2 - t1) * ey) >> 16) + t1; - /* - * Advance source pointer x - */ - salast = csax; - csax++; - sstep = (*csax >> 16) - (*salast >> 16); - if (flipx) { - sp -= sstep; - } else { - sp += sstep; - } - - /* - * Advance destination pointer x - */ - dp++; - } - /* - * Advance source pointer y - */ - salast = csay; - csay++; - sstep = (*csay >> 16) - (*salast >> 16); - sstep *= spixelgap; - if (flipy) { - sp = csp - sstep; - } else { - sp = csp + sstep; - } - - /* - * Advance destination pointer y - */ - dp = (tColorRGBA *) ((rt_uint8_t *) dp + dgap); - } - } else { - /* - * Non-Interpolating Zoom - */ - csay = say; - for (y = 0; y < dst->height; y++) { - csp = sp; - csax = sax; - for (x = 0; x < dst->width; x++) { - /* - * Draw - */ - *dp = *sp; - - /* - * Advance source pointer x - */ - salast = csax; - csax++; - sstep = (*csax >> 16) - (*salast >> 16); - if (flipx) sstep = -sstep; - sp += sstep; - - /* - * Advance destination pointer x - */ - dp++; - } - /* - * Advance source pointer y - */ - salast = csay; - csay++; - sstep = (*csay >> 16) - (*salast >> 16); - sstep *= spixelgap; - if (flipy) sstep = -sstep; - sp = csp + sstep; - - /* - * Advance destination pointer y - */ - dp = (tColorRGBA *) ((rt_uint8_t *) dp + dgap); - } - } - - /* - * Remove temp arrays - */ - rtgui_free(sax); - rtgui_free(say); - - return (0); + int x, y, sx, sy, ssx, ssy, *sax, *say, *csax, *csay, *salast, csx, csy, ex, ey, cx, cy, sstep, sstepx, sstepy; + tColorRGBA *c00, *c01, *c10, *c11; + tColorRGBA *sp, *csp, *dp; + int spixelgap, spixelw, spixelh, dgap, t1, t2; + + /* + * Allocate memory for row/column increments + */ + if ((sax = (int *) rtgui_malloc((dst->width + 1) * sizeof(rt_uint32_t))) == RT_NULL) + { + return (-1); + } + if ((say = (int *) rtgui_malloc((dst->height + 1) * sizeof(rt_uint32_t))) == RT_NULL) + { + rtgui_free(sax); + return (-1); + } + + /* + * Precalculate row increments + */ + spixelw = (src->width - 1); + spixelh = (src->height- 1); + if (smooth) + { + sx = (int) (65536.0 * (double) spixelw / (double) (dst->width - 1)); + sy = (int) (65536.0 * (double) spixelh / (double) (dst->height - 1)); + } + else + { + sx = (int) (65536.0 * (double) (src->width) / (double) (dst->width)); + sy = (int) (65536.0 * (double) (src->height) / (double) (dst->height)); + } + + /* Maximum scaled source size */ + ssx = (src->width << 16) - 1; + ssy = (src->height << 16) - 1; + + /* Precalculate horizontal row increments */ + csx = 0; + csax = sax; + for (x = 0; x <= dst->width; x++) + { + *csax = csx; + csax++; + csx += sx; + + /* Guard from overflows */ + if (csx > ssx) + { + csx = ssx; + } + } + + /* Precalculate vertical row increments */ + csy = 0; + csay = say; + for (y = 0; y <= dst->height; y++) + { + *csay = csy; + csay++; + csy += sy; + + /* Guard from overflows */ + if (csy > ssy) + { + csy = ssy; + } + } + + sp = (tColorRGBA *) src->pixel; + dp = (tColorRGBA *) dst->pixel; + dgap = dst->pitch - dst->width * 4; + spixelgap = src->pitch/4; + + if (flipx) sp += spixelw; + if (flipy) sp += (spixelgap * spixelh); + + /* + * Switch between interpolating and non-interpolating code + */ + if (smooth) + { + + /* + * Interpolating Zoom + */ + csay = say; + for (y = 0; y < dst->height; y++) + { + csp = sp; + csax = sax; + for (x = 0; x < dst->width; x++) + { + /* + * Setup color source pointers + */ + ex = (*csax & 0xffff); + ey = (*csay & 0xffff); + cx = (*csax >> 16); + cy = (*csay >> 16); + sstepx = cx < spixelw; + sstepy = cy < spixelh; + c00 = sp; + c01 = sp; + c10 = sp; + if (sstepy) + { + if (flipy) + { + c10 -= spixelgap; + } + else + { + c10 += spixelgap; + } + } + c11 = c10; + if (sstepx) + { + if (flipx) + { + c01--; + c11--; + } + else + { + c01++; + c11++; + } + } + + /* + * Draw and interpolate colors + */ + t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff; + t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff; + dp->r = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff; + t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff; + dp->g = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff; + t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff; + dp->b = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff; + t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff; + dp->a = (((t2 - t1) * ey) >> 16) + t1; + /* + * Advance source pointer x + */ + salast = csax; + csax++; + sstep = (*csax >> 16) - (*salast >> 16); + if (flipx) + { + sp -= sstep; + } + else + { + sp += sstep; + } + + /* + * Advance destination pointer x + */ + dp++; + } + /* + * Advance source pointer y + */ + salast = csay; + csay++; + sstep = (*csay >> 16) - (*salast >> 16); + sstep *= spixelgap; + if (flipy) + { + sp = csp - sstep; + } + else + { + sp = csp + sstep; + } + + /* + * Advance destination pointer y + */ + dp = (tColorRGBA *) ((rt_uint8_t *) dp + dgap); + } + } + else + { + /* + * Non-Interpolating Zoom + */ + csay = say; + for (y = 0; y < dst->height; y++) + { + csp = sp; + csax = sax; + for (x = 0; x < dst->width; x++) + { + /* + * Draw + */ + *dp = *sp; + + /* + * Advance source pointer x + */ + salast = csax; + csax++; + sstep = (*csax >> 16) - (*salast >> 16); + if (flipx) sstep = -sstep; + sp += sstep; + + /* + * Advance destination pointer x + */ + dp++; + } + /* + * Advance source pointer y + */ + salast = csay; + csay++; + sstep = (*csay >> 16) - (*salast >> 16); + sstep *= spixelgap; + if (flipy) sstep = -sstep; + sp = csp + sstep; + + /* + * Advance destination pointer y + */ + dp = (tColorRGBA *) ((rt_uint8_t *) dp + dgap); + } + } + + /* + * Remove temp arrays + */ + rtgui_free(sax); + rtgui_free(say); + + return (0); } -/*! +/*! \brief Internal 32 bit rotozoomer with optional anti-aliasing. -Rotates and zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control +Rotates and zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control parameters by scanning the destination surface and applying optionally anti-aliasing by bilinear interpolation. Assumes src and dst surfaces are of 32 bit depth. @@ -447,115 +479,131 @@ Assumes dst surface was allocated with the correct dimensions. \param flipy Flag indicating vertical mirroring should be applied. \param smooth Flag indicating anti-aliasing should be used. */ -int _rtgui_dc_transform_RGBA(struct rtgui_dc_buffer * src, struct rtgui_dc_buffer * dst, - int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth) +int _rtgui_dc_transform_RGBA(struct rtgui_dc_buffer * src, struct rtgui_dc_buffer * dst, + int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth) { - int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh; - tColorRGBA c00, c01, c10, c11, cswap; - tColorRGBA *pc, *sp; - int gap; - - /* - * Variable setup - */ - xd = ((src->width - dst->width) << 15); - yd = ((src->height - dst->height) << 15); - ax = (cx << 16) - (icos * cx); - ay = (cy << 16) - (isin * cx); - sw = src->width - 1; - sh = src->height - 1; - pc = (tColorRGBA*) dst->pixel; - gap = dst->pitch - dst->width * 4; - - /* - * Switch between interpolating and non-interpolating code - */ - if (smooth) { - for (y = 0; y < dst->height; y++) - { - dy = cy - y; - sdx = (ax + (isin * dy)) + xd; - sdy = (ay - (icos * dy)) + yd; - for (x = 0; x < dst->width; x++) - { - dx = (sdx >> 16); - dy = (sdy >> 16); - if (flipx) dx = sw - dx; - if (flipy) dy = sh - dy; - if ((dx > -1) && (dy > -1) && (dx < (src->width-1)) && (dy < (src->height-1))) - { - sp = (tColorRGBA *)src->pixel;; - sp += ((src->pitch/4) * dy); - sp += dx; - c00 = *sp; - sp += 1; - c01 = *sp; - sp += (src->pitch/4); - c11 = *sp; - sp -= 1; - c10 = *sp; - if (flipx) { - cswap = c00; c00=c01; c01=cswap; - cswap = c10; c10=c11; c11=cswap; - } - if (flipy) { - cswap = c00; c00=c10; c10=cswap; - cswap = c01; c01=c11; c11=cswap; - } - /* - * Interpolate colors - */ - ex = (sdx & 0xffff); - ey = (sdy & 0xffff); - t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff; - t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff; - pc->r = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff; - t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff; - pc->g = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff; - t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff; - pc->b = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff; - t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff; - pc->a = (((t2 - t1) * ey) >> 16) + t1; - } - sdx += icos; - sdy += isin; - pc++; - } - pc = (tColorRGBA *) ((rt_uint8_t *) pc + gap); - } - } else { - for (y = 0; y < dst->height; y++) { - dy = cy - y; - sdx = (ax + (isin * dy)) + xd; - sdy = (ay - (icos * dy)) + yd; - for (x = 0; x < dst->width; x++) { - dx = (short) (sdx >> 16); - dy = (short) (sdy >> 16); - if (flipx) dx = (src->width-1)-dx; - if (flipy) dy = (src->height-1)-dy; - if ((dx >= 0) && (dy >= 0) && (dx < src->width) && (dy < src->height)) { - sp = (tColorRGBA *) ((rt_uint8_t *) src->pixel + src->pitch * dy); - sp += dx; - *pc = *sp; - } - sdx += icos; - sdy += isin; - pc++; - } - pc = (tColorRGBA *) ((rt_uint8_t *) pc + gap); - } - } - - return 0; + int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh; + tColorRGBA c00, c01, c10, c11, cswap; + tColorRGBA *pc, *sp; + int gap; + + /* + * Variable setup + */ + xd = ((src->width - dst->width) << 15); + yd = ((src->height - dst->height) << 15); + ax = (cx << 16) - (icos * cx); + ay = (cy << 16) - (isin * cx); + sw = src->width - 1; + sh = src->height - 1; + pc = (tColorRGBA*) dst->pixel; + gap = dst->pitch - dst->width * 4; + + /* + * Switch between interpolating and non-interpolating code + */ + if (smooth) + { + for (y = 0; y < dst->height; y++) + { + dy = cy - y; + sdx = (ax + (isin * dy)) + xd; + sdy = (ay - (icos * dy)) + yd; + for (x = 0; x < dst->width; x++) + { + dx = (sdx >> 16); + dy = (sdy >> 16); + if (flipx) dx = sw - dx; + if (flipy) dy = sh - dy; + if ((dx > -1) && (dy > -1) && (dx < (src->width-1)) && (dy < (src->height-1))) + { + sp = (tColorRGBA *)src->pixel;; + sp += ((src->pitch/4) * dy); + sp += dx; + c00 = *sp; + sp += 1; + c01 = *sp; + sp += (src->pitch/4); + c11 = *sp; + sp -= 1; + c10 = *sp; + if (flipx) + { + cswap = c00; + c00=c01; + c01=cswap; + cswap = c10; + c10=c11; + c11=cswap; + } + if (flipy) + { + cswap = c00; + c00=c10; + c10=cswap; + cswap = c01; + c01=c11; + c11=cswap; + } + /* + * Interpolate colors + */ + ex = (sdx & 0xffff); + ey = (sdy & 0xffff); + t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff; + t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff; + pc->r = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff; + t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff; + pc->g = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff; + t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff; + pc->b = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff; + t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff; + pc->a = (((t2 - t1) * ey) >> 16) + t1; + } + sdx += icos; + sdy += isin; + pc++; + } + pc = (tColorRGBA *) ((rt_uint8_t *) pc + gap); + } + } + else + { + for (y = 0; y < dst->height; y++) + { + dy = cy - y; + sdx = (ax + (isin * dy)) + xd; + sdy = (ay - (icos * dy)) + yd; + for (x = 0; x < dst->width; x++) + { + dx = (short) (sdx >> 16); + dy = (short) (sdy >> 16); + if (flipx) dx = (src->width-1)-dx; + if (flipy) dy = (src->height-1)-dy; + if ((dx >= 0) && (dy >= 0) && (dx < src->width) && (dy < src->height)) + { + sp = (tColorRGBA *) ((rt_uint8_t *) src->pixel + src->pitch * dy); + sp += dx; + *pc = *sp; + } + sdx += icos; + sdy += isin; + pc++; + } + pc = (tColorRGBA *) ((rt_uint8_t *) pc + gap); + } + } + + return 0; } /*! \brief Rotates a 32 bit surface in increments of 90 degrees. -Specialized 90 degree rotator which rotates a 'src' surface in 90 degree +Specialized 90 degree rotator which rotates a 'src' surface in 90 degree increments clockwise returning a new surface. Faster than rotozoomer since not scanning or interpolation takes place. Input surface must be 32 bit. (code contributed by J. Schiller, improved by C. Allport and A. Schiffler) @@ -565,117 +613,122 @@ not scanning or interpolation takes place. Input surface must be 32 bit. \returns The new, rotated surface; or RT_NULL for surfaces with incorrect input format. */ -struct rtgui_dc* rtgui_dc_rotate_90degrees(struct rtgui_dc_buffer* src, int numClockwiseTurns) +struct rtgui_dc* rtgui_dc_rotate_90degrees(struct rtgui_dc_buffer* src, int numClockwiseTurns) { - int row, col, newWidth, newHeight; - int bpp, src_ipr, dst_ipr; - struct rtgui_dc_buffer* dst; - rt_uint32_t* srcBuf; - rt_uint32_t* dstBuf; - - /* sanity check */ - if (src == RT_NULL) return RT_NULL; - /* we only support 32bit */ - if (rtgui_color_get_bits(src->pixel_format) != 32) return RT_NULL; - - /* normalize numClockwiseTurns */ - while(numClockwiseTurns < 0) { numClockwiseTurns += 4; } - numClockwiseTurns = (numClockwiseTurns % 4); - - /* if it's even, our new width will be the same as the source surface */ - newWidth = (numClockwiseTurns % 2) ? (src->height) : (src->width); - newHeight = (numClockwiseTurns % 2) ? (src->width) : (src->height); - dst = (struct rtgui_dc_buffer*) rtgui_dc_buffer_create_pixformat(RTGRAPHIC_PIXEL_FORMAT_ARGB888, newWidth, newHeight); - if(!dst) return RT_NULL; - - /* Calculate int-per-row */ - bpp = rtgui_color_get_bpp(src->pixel_format); - src_ipr = src->pitch / bpp; - dst_ipr = dst->pitch / bpp; - - switch(numClockwiseTurns) - { - case 0: /* Make a copy of the surface */ - { - /* Unfortunately SDL_BlitSurface cannot be used to make a copy of the surface - since it does not preserve alpha. */ - if (src->pitch == dst->pitch) - { - /* If the pitch is the same for both surfaces, the memory can be copied all at once. */ - rt_memcpy(dst->pixel, src->pixel, (src->height * src->pitch)); - } - else - { - /* If the pitch differs, copy each row separately */ - srcBuf = (rt_uint32_t*)(src->pixel); - dstBuf = (rt_uint32_t*)(dst->pixel); - - for (row = 0; row < src->height; row++) - { - rt_memcpy(dstBuf, srcBuf, dst->width * bpp); - srcBuf += src_ipr; - dstBuf += dst_ipr; - } /* end for(col) */ - } /* end for(row) */ - } - break; - - /* rotate clockwise */ - case 1: /* rotated 90 degrees clockwise */ - { - for (row = 0; row < src->height; ++row) { - srcBuf = (rt_uint32_t*)(src->pixel) + (row * src_ipr); - dstBuf = (rt_uint32_t*)(dst->pixel) + (dst->width - row - 1); - for (col = 0; col < src->width; ++col) { - *dstBuf = *srcBuf; - ++srcBuf; - dstBuf += dst_ipr; - } - /* end for(col) */ - } - /* end for(row) */ - } - break; - - case 2: /* rotated 180 degrees clockwise */ - { - for (row = 0; row < src->height; ++row) - { - srcBuf = (rt_uint32_t*)(src->pixel) + (row * src_ipr); - dstBuf = (rt_uint32_t*)(dst->pixel) + ((dst->height - row - 1) * dst_ipr) + (dst->width - 1); - for (col = 0; col < src->width; ++col) - { - *dstBuf = *srcBuf; - ++srcBuf; - --dstBuf; - } - } - } - break; - - case 3: - { - for (row = 0; row < src->height; ++row) - { - srcBuf = (rt_uint32_t*)(src->pixel) + (row * src_ipr); - dstBuf = (rt_uint32_t*)(dst->pixel) + row + ((dst->height - 1) * dst_ipr); - for (col = 0; col < src->width; ++col) - { - *dstBuf = *srcBuf; - ++srcBuf; - dstBuf -= dst_ipr; - } - } - } - break; - } - /* end switch */ - - return RTGUI_DC(dst); + int row, col, newWidth, newHeight; + int bpp, src_ipr, dst_ipr; + struct rtgui_dc_buffer* dst; + rt_uint32_t* srcBuf; + rt_uint32_t* dstBuf; + + /* sanity check */ + if (src == RT_NULL) return RT_NULL; + /* we only support 32bit */ + if (rtgui_color_get_bits(src->pixel_format) != 32) return RT_NULL; + + /* normalize numClockwiseTurns */ + while(numClockwiseTurns < 0) + { + numClockwiseTurns += 4; + } + numClockwiseTurns = (numClockwiseTurns % 4); + + /* if it's even, our new width will be the same as the source surface */ + newWidth = (numClockwiseTurns % 2) ? (src->height) : (src->width); + newHeight = (numClockwiseTurns % 2) ? (src->width) : (src->height); + dst = (struct rtgui_dc_buffer*) rtgui_dc_buffer_create_pixformat(RTGRAPHIC_PIXEL_FORMAT_ARGB888, newWidth, newHeight); + if(!dst) return RT_NULL; + + /* Calculate int-per-row */ + bpp = rtgui_color_get_bpp(src->pixel_format); + src_ipr = src->pitch / bpp; + dst_ipr = dst->pitch / bpp; + + switch(numClockwiseTurns) + { + case 0: /* Make a copy of the surface */ + { + /* Unfortunately SDL_BlitSurface cannot be used to make a copy of the surface + since it does not preserve alpha. */ + if (src->pitch == dst->pitch) + { + /* If the pitch is the same for both surfaces, the memory can be copied all at once. */ + rt_memcpy(dst->pixel, src->pixel, (src->height * src->pitch)); + } + else + { + /* If the pitch differs, copy each row separately */ + srcBuf = (rt_uint32_t*)(src->pixel); + dstBuf = (rt_uint32_t*)(dst->pixel); + + for (row = 0; row < src->height; row++) + { + rt_memcpy(dstBuf, srcBuf, dst->width * bpp); + srcBuf += src_ipr; + dstBuf += dst_ipr; + } /* end for(col) */ + } /* end for(row) */ + } + break; + + /* rotate clockwise */ + case 1: /* rotated 90 degrees clockwise */ + { + for (row = 0; row < src->height; ++row) + { + srcBuf = (rt_uint32_t*)(src->pixel) + (row * src_ipr); + dstBuf = (rt_uint32_t*)(dst->pixel) + (dst->width - row - 1); + for (col = 0; col < src->width; ++col) + { + *dstBuf = *srcBuf; + ++srcBuf; + dstBuf += dst_ipr; + } + /* end for(col) */ + } + /* end for(row) */ + } + break; + + case 2: /* rotated 180 degrees clockwise */ + { + for (row = 0; row < src->height; ++row) + { + srcBuf = (rt_uint32_t*)(src->pixel) + (row * src_ipr); + dstBuf = (rt_uint32_t*)(dst->pixel) + ((dst->height - row - 1) * dst_ipr) + (dst->width - 1); + for (col = 0; col < src->width; ++col) + { + *dstBuf = *srcBuf; + ++srcBuf; + --dstBuf; + } + } + } + break; + + case 3: + { + for (row = 0; row < src->height; ++row) + { + srcBuf = (rt_uint32_t*)(src->pixel) + (row * src_ipr); + dstBuf = (rt_uint32_t*)(dst->pixel) + row + ((dst->height - 1) * dst_ipr); + for (col = 0; col < src->width; ++col) + { + *dstBuf = *srcBuf; + ++srcBuf; + dstBuf -= dst_ipr; + } + } + } + break; + } + /* end switch */ + + return RTGUI_DC(dst); } /*! -\brief Internal target surface sizing function for rotozooms with trig result return. +\brief Internal target surface sizing function for rotozooms with trig result return. \param width The source surface width. \param height The source surface height. @@ -688,39 +741,39 @@ struct rtgui_dc* rtgui_dc_rotate_90degrees(struct rtgui_dc_buffer* src, int numC \param sanglezoom The cosine of the angle adjusted by the zoom factor. */ -void _rtgui_dc_rotozoom_size(int width, int height, double angle, double zoomx, double zoomy, - int *dstwidth, int *dstheight, - double *canglezoom, double *sanglezoom) +void _rtgui_dc_rotozoom_size(int width, int height, double angle, double zoomx, double zoomy, + int *dstwidth, int *dstheight, + double *canglezoom, double *sanglezoom) { - double x, y, cx, cy, sx, sy; - double radangle; - int dstwidthhalf, dstheighthalf; - - /* - * Determine destination width and height by rotating a centered source box - */ - radangle = angle * (M_PI / 180.0); - *sanglezoom = sin(radangle); - *canglezoom = cos(radangle); - *sanglezoom *= zoomx; - *canglezoom *= zoomx; - x = (double)(width / 2); - y = (double)(height / 2); - cx = *canglezoom * x; - cy = *canglezoom * y; - sx = *sanglezoom * x; - sy = *sanglezoom * y; - - dstwidthhalf = MAX((int) - ceil(MAX(MAX(MAX(fabs(cx + sy), fabs(cx - sy)), fabs(-cx + sy)), fabs(-cx - sy))), 1); - dstheighthalf = MAX((int) - ceil(MAX(MAX(MAX(fabs(sx + cy), fabs(sx - cy)), fabs(-sx + cy)), fabs(-sx - cy))), 1); - *dstwidth = 2 * dstwidthhalf; - *dstheight = 2 * dstheighthalf; + double x, y, cx, cy, sx, sy; + double radangle; + int dstwidthhalf, dstheighthalf; + + /* + * Determine destination width and height by rotating a centered source box + */ + radangle = angle * (M_PI / 180.0); + *sanglezoom = sin(radangle); + *canglezoom = cos(radangle); + *sanglezoom *= zoomx; + *canglezoom *= zoomx; + x = (double)(width / 2); + y = (double)(height / 2); + cx = *canglezoom * x; + cy = *canglezoom * y; + sx = *sanglezoom * x; + sy = *sanglezoom * y; + + dstwidthhalf = MAX((int) + ceil(MAX(MAX(MAX(fabs(cx + sy), fabs(cx - sy)), fabs(-cx + sy)), fabs(-cx - sy))), 1); + dstheighthalf = MAX((int) + ceil(MAX(MAX(MAX(fabs(sx + cy), fabs(sx - cy)), fabs(-sx + cy)), fabs(-sx - cy))), 1); + *dstwidth = 2 * dstwidthhalf; + *dstheight = 2 * dstheighthalf; } -/*! -\brief Returns the size of the resulting target surface for a rotozoomSurface() call. +/*! +\brief Returns the size of the resulting target surface for a rotozoomSurface() call. \param width The source surface width. \param height The source surface height. @@ -731,13 +784,13 @@ void _rtgui_dc_rotozoom_size(int width, int height, double angle, double zoomx, */ void rtgui_dc_rotozoom_size(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight) { - double dummy_sanglezoom, dummy_canglezoom; + double dummy_sanglezoom, dummy_canglezoom; - _rtgui_dc_rotozoom_size(width, height, angle, zoom, zoom, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom); + _rtgui_dc_rotozoom_size(width, height, angle, zoom, zoom, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom); } /*! -\brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing. +\brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing. Rotates and zooms a 32bit or 8bit 'src' surface to newly created 'dst' surface. 'angle' is the rotation in degrees, 'zoomx and 'zoomy' scaling factors. If 'smooth' is set @@ -754,115 +807,115 @@ or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. */ struct rtgui_dc *rtgui_dc_rotozoom(struct rtgui_dc *dc, double angle, double zoomx, double zoomy, int smooth) { - struct rtgui_dc_buffer *rz_src; - struct rtgui_dc_buffer *rz_dst; - double zoominv; - double sanglezoom, canglezoom, sanglezoominv, canglezoominv; - int dstwidthhalf, dstwidth, dstheighthalf, dstheight; - int flipx,flipy; - int result; - - /* - * Sanity check - */ - rz_src = (struct rtgui_dc_buffer*)(dc); - if (rz_src == RT_NULL) return (RT_NULL); - /* we only support 32bit */ - if (rtgui_color_get_bits(rz_src->pixel_format) != 32) return RT_NULL; - - /* - * Sanity check zoom factor - */ - flipx = (zoomx<0.0); - if (flipx) zoomx=-zoomx; - flipy = (zoomy<0.0); - if (flipy) zoomy=-zoomy; - if (zoomx < VALUE_LIMIT) zoomx = VALUE_LIMIT; - if (zoomy < VALUE_LIMIT) zoomy = VALUE_LIMIT; - zoominv = 65536.0 / (zoomx * zoomx); - - /* - * Check if we have a rotozoom or just a zoom - */ - if (fabs(angle) > VALUE_LIMIT) - { - /* - * Angle!=0: full rotozoom - */ - /* - * ----------------------- - */ - - /* Determine target size */ - _rtgui_dc_rotozoom_size(rz_src->width, rz_src->height, angle, zoomx, zoomy, &dstwidth, &dstheight, &canglezoom, &sanglezoom); - - /* - * Calculate target factors from sin/cos and zoom - */ - sanglezoominv = sanglezoom; - canglezoominv = canglezoom; - sanglezoominv *= zoominv; - canglezoominv *= zoominv; - - /* Calculate half size */ - dstwidthhalf = dstwidth / 2; - dstheighthalf = dstheight / 2; - - /* - * Alloc space to completely contain the rotated surface - */ - rz_dst = (struct rtgui_dc_buffer*)rtgui_dc_buffer_create_pixformat(RTGRAPHIC_PIXEL_FORMAT_ARGB888, - dstwidth, dstheight + GUARD_ROWS); - /* Check target */ - if (rz_dst == RT_NULL)return RT_NULL; - - /* - * Call the 32bit transformation routine to do the rotation (using alpha) - */ - result = _rtgui_dc_transform_RGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf, - (int) (sanglezoominv), (int) (canglezoominv), - flipx, flipy, - smooth); - if (result != 0) - { - rtgui_dc_destory(RTGUI_DC(rz_dst)); - rz_dst = RT_NULL; - } - } - else - { - /* - * Angle=0: Just a zoom - */ - - /* - * Calculate target size - */ - rtgui_dc_zoom_size(rz_src->width, rz_src->height, zoomx, zoomy, &dstwidth, &dstheight); - - /* - * Alloc space to completely contain the zoomed surface - */ - rz_dst = (struct rtgui_dc_buffer*)rtgui_dc_buffer_create_pixformat(RTGRAPHIC_PIXEL_FORMAT_ARGB888, - dstwidth, dstheight + GUARD_ROWS); - /* Check target */ - if (rz_dst == RT_NULL) return RT_NULL; - - /* - * Call the 32bit transformation routine to do the zooming (using alpha) - */ - result = _rtgui_dc_zoom_RGBA(rz_src, rz_dst, flipx, flipy, smooth); - if (result != 0) - { - rtgui_dc_destory(RTGUI_DC(rz_dst)); - rz_dst = RT_NULL; - } - } - - /* - * Return destination surface - */ - return RTGUI_DC(rz_dst); + struct rtgui_dc_buffer *rz_src; + struct rtgui_dc_buffer *rz_dst; + double zoominv; + double sanglezoom, canglezoom, sanglezoominv, canglezoominv; + int dstwidthhalf, dstwidth, dstheighthalf, dstheight; + int flipx,flipy; + int result; + + /* + * Sanity check + */ + rz_src = (struct rtgui_dc_buffer*)(dc); + if (rz_src == RT_NULL) return (RT_NULL); + /* we only support 32bit */ + if (rtgui_color_get_bits(rz_src->pixel_format) != 32) return RT_NULL; + + /* + * Sanity check zoom factor + */ + flipx = (zoomx<0.0); + if (flipx) zoomx=-zoomx; + flipy = (zoomy<0.0); + if (flipy) zoomy=-zoomy; + if (zoomx < VALUE_LIMIT) zoomx = VALUE_LIMIT; + if (zoomy < VALUE_LIMIT) zoomy = VALUE_LIMIT; + zoominv = 65536.0 / (zoomx * zoomx); + + /* + * Check if we have a rotozoom or just a zoom + */ + if (fabs(angle) > VALUE_LIMIT) + { + /* + * Angle!=0: full rotozoom + */ + /* + * ----------------------- + */ + + /* Determine target size */ + _rtgui_dc_rotozoom_size(rz_src->width, rz_src->height, angle, zoomx, zoomy, &dstwidth, &dstheight, &canglezoom, &sanglezoom); + + /* + * Calculate target factors from sin/cos and zoom + */ + sanglezoominv = sanglezoom; + canglezoominv = canglezoom; + sanglezoominv *= zoominv; + canglezoominv *= zoominv; + + /* Calculate half size */ + dstwidthhalf = dstwidth / 2; + dstheighthalf = dstheight / 2; + + /* + * Alloc space to completely contain the rotated surface + */ + rz_dst = (struct rtgui_dc_buffer*)rtgui_dc_buffer_create_pixformat(RTGRAPHIC_PIXEL_FORMAT_ARGB888, + dstwidth, dstheight + GUARD_ROWS); + /* Check target */ + if (rz_dst == RT_NULL)return RT_NULL; + + /* + * Call the 32bit transformation routine to do the rotation (using alpha) + */ + result = _rtgui_dc_transform_RGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf, + (int) (sanglezoominv), (int) (canglezoominv), + flipx, flipy, + smooth); + if (result != 0) + { + rtgui_dc_destory(RTGUI_DC(rz_dst)); + rz_dst = RT_NULL; + } + } + else + { + /* + * Angle=0: Just a zoom + */ + + /* + * Calculate target size + */ + rtgui_dc_zoom_size(rz_src->width, rz_src->height, zoomx, zoomy, &dstwidth, &dstheight); + + /* + * Alloc space to completely contain the zoomed surface + */ + rz_dst = (struct rtgui_dc_buffer*)rtgui_dc_buffer_create_pixformat(RTGRAPHIC_PIXEL_FORMAT_ARGB888, + dstwidth, dstheight + GUARD_ROWS); + /* Check target */ + if (rz_dst == RT_NULL) return RT_NULL; + + /* + * Call the 32bit transformation routine to do the zooming (using alpha) + */ + result = _rtgui_dc_zoom_RGBA(rz_src, rz_dst, flipx, flipy, smooth); + if (result != 0) + { + rtgui_dc_destory(RTGUI_DC(rz_dst)); + rz_dst = RT_NULL; + } + } + + /* + * Return destination surface + */ + return RTGUI_DC(rz_dst); } RTM_EXPORT(rtgui_dc_rotozoom); /*! @@ -879,39 +932,43 @@ The minimum size of the target surface is 1. The input factors can be positive o */ void rtgui_dc_zoom_size(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight) { - /* - * Make zoom factors positive - */ - int flipx, flipy; - flipx = (zoomx<0.0); - if (flipx) zoomx = -zoomx; - flipy = (zoomy<0.0); - if (flipy) zoomy = -zoomy; - - /* - * Sanity check zoom factors - */ - if (zoomx < VALUE_LIMIT) { - zoomx = VALUE_LIMIT; - } - if (zoomy < VALUE_LIMIT) { - zoomy = VALUE_LIMIT; - } - - /* - * Calculate target size - */ - *dstwidth = (int) floor(((double) width * zoomx) + 0.5); - *dstheight = (int) floor(((double) height * zoomy) + 0.5); - if (*dstwidth < 1) { - *dstwidth = 1; - } - if (*dstheight < 1) { - *dstheight = 1; - } + /* + * Make zoom factors positive + */ + int flipx, flipy; + flipx = (zoomx<0.0); + if (flipx) zoomx = -zoomx; + flipy = (zoomy<0.0); + if (flipy) zoomy = -zoomy; + + /* + * Sanity check zoom factors + */ + if (zoomx < VALUE_LIMIT) + { + zoomx = VALUE_LIMIT; + } + if (zoomy < VALUE_LIMIT) + { + zoomy = VALUE_LIMIT; + } + + /* + * Calculate target size + */ + *dstwidth = (int) floor(((double) width * zoomx) + 0.5); + *dstheight = (int) floor(((double) height * zoomy) + 0.5); + if (*dstwidth < 1) + { + *dstwidth = 1; + } + if (*dstheight < 1) + { + *dstheight = 1; + } } -/*! +/*! \brief Zoom a surface by independent horizontal and vertical factors with optional smoothing. Zooms a 32bit or 8bit 'src' surface to newly created 'dst' surface. @@ -929,50 +986,50 @@ If zoom factors are negative, the image is flipped on the axes. */ struct rtgui_dc *rtgui_dc_zoom(struct rtgui_dc *dc, double zoomx, double zoomy, int smooth) { - struct rtgui_dc_buffer *rz_src; - struct rtgui_dc_buffer *rz_dst; - int dstwidth, dstheight; - int flipx, flipy; - - /* Sanity check */ - if (dc == RT_NULL) return dc; - rz_src = (struct rtgui_dc_buffer*)(dc); - /* we only support 32bit */ - if (rtgui_color_get_bits(rz_src->pixel_format) != 32) return RT_NULL; - - flipx = (zoomx<0.0); - if (flipx) zoomx = -zoomx; - flipy = (zoomy<0.0); - if (flipy) zoomy = -zoomy; - - /* Get size if target */ - rtgui_dc_zoom_size(rz_src->width, rz_src->height, zoomx, zoomy, &dstwidth, &dstheight); - - /* - * Alloc space to completely contain the zoomed surface - */ - rz_dst = (struct rtgui_dc_buffer*)rtgui_dc_buffer_create_pixformat(RTGRAPHIC_PIXEL_FORMAT_ARGB888, - dstwidth, dstheight + GUARD_ROWS); - /* Check target */ - if (rz_dst == RT_NULL) return RT_NULL; - - /* - * Call the 32bit transformation routine to do the zooming (using alpha) - */ - if (_rtgui_dc_zoom_RGBA(rz_src, rz_dst, flipx, flipy, smooth) != 0) - { - rtgui_dc_destory(RTGUI_DC(rz_dst)); - rz_dst = RT_NULL; - } - - /* - * Return destination surface - */ - return RTGUI_DC(rz_dst); + struct rtgui_dc_buffer *rz_src; + struct rtgui_dc_buffer *rz_dst; + int dstwidth, dstheight; + int flipx, flipy; + + /* Sanity check */ + if (dc == RT_NULL) return dc; + rz_src = (struct rtgui_dc_buffer*)(dc); + /* we only support 32bit */ + if (rtgui_color_get_bits(rz_src->pixel_format) != 32) return RT_NULL; + + flipx = (zoomx<0.0); + if (flipx) zoomx = -zoomx; + flipy = (zoomy<0.0); + if (flipy) zoomy = -zoomy; + + /* Get size if target */ + rtgui_dc_zoom_size(rz_src->width, rz_src->height, zoomx, zoomy, &dstwidth, &dstheight); + + /* + * Alloc space to completely contain the zoomed surface + */ + rz_dst = (struct rtgui_dc_buffer*)rtgui_dc_buffer_create_pixformat(RTGRAPHIC_PIXEL_FORMAT_ARGB888, + dstwidth, dstheight + GUARD_ROWS); + /* Check target */ + if (rz_dst == RT_NULL) return RT_NULL; + + /* + * Call the 32bit transformation routine to do the zooming (using alpha) + */ + if (_rtgui_dc_zoom_RGBA(rz_src, rz_dst, flipx, flipy, smooth) != 0) + { + rtgui_dc_destory(RTGUI_DC(rz_dst)); + rz_dst = RT_NULL; + } + + /* + * Return destination surface + */ + return RTGUI_DC(rz_dst); } RTM_EXPORT(rtgui_dc_zoom); -/*! +/*! \brief Shrink a dc by an integer ratio using averaging. Shrinks a 32bit or 8bit 'src' buffer dc to a newly created 'dst' dc. @@ -990,45 +1047,51 @@ The input surface is not modified. The output surface is newly allocated. */ struct rtgui_dc *rtgui_dc_shrink(struct rtgui_dc *dc, int factorx, int factory) { - struct rtgui_dc_buffer *rz_src; - struct rtgui_dc_buffer *rz_dst; - int dstwidth, dstheight; - - /* - * Sanity check - */ - if (dc == RT_NULL) return dc; - rz_src = (struct rtgui_dc_buffer*)(dc); - /* we only support 32bit */ - if (rtgui_color_get_bits(rz_src->pixel_format) != 32) return RT_NULL; - - /* Get size for target */ - dstwidth=rz_src->width/factorx; - while (dstwidth*factorx>rz_src->width) { dstwidth--; } - dstheight=rz_src->height/factory; - while (dstheight*factory>rz_src->height) { dstheight--; } - - /* - * Target surface is 32bit with source RGBA/ABGR ordering - */ - rz_dst = (struct rtgui_dc_buffer*)rtgui_dc_buffer_create_pixformat(RTGRAPHIC_PIXEL_FORMAT_ARGB888, - dstwidth, dstheight + GUARD_ROWS); - /* Check target */ - if (rz_dst == RT_NULL) return RT_NULL; - - /* - * Call the 32bit transformation routine to do the shrinking (using alpha) - */ - if (_rtgui_dc_shrink_RGBA(rz_src, rz_dst, factorx, factory) != 0) - { - rtgui_dc_destory(RTGUI_DC(rz_dst)); - rz_dst = RT_NULL; - } - - /* - * Return destination surface - */ - return RTGUI_DC(rz_dst); + struct rtgui_dc_buffer *rz_src; + struct rtgui_dc_buffer *rz_dst; + int dstwidth, dstheight; + + /* + * Sanity check + */ + if (dc == RT_NULL) return dc; + rz_src = (struct rtgui_dc_buffer*)(dc); + /* we only support 32bit */ + if (rtgui_color_get_bits(rz_src->pixel_format) != 32) return RT_NULL; + + /* Get size for target */ + dstwidth=rz_src->width/factorx; + while (dstwidth*factorx>rz_src->width) + { + dstwidth--; + } + dstheight=rz_src->height/factory; + while (dstheight*factory>rz_src->height) + { + dstheight--; + } + + /* + * Target surface is 32bit with source RGBA/ABGR ordering + */ + rz_dst = (struct rtgui_dc_buffer*)rtgui_dc_buffer_create_pixformat(RTGRAPHIC_PIXEL_FORMAT_ARGB888, + dstwidth, dstheight + GUARD_ROWS); + /* Check target */ + if (rz_dst == RT_NULL) return RT_NULL; + + /* + * Call the 32bit transformation routine to do the shrinking (using alpha) + */ + if (_rtgui_dc_shrink_RGBA(rz_src, rz_dst, factorx, factory) != 0) + { + rtgui_dc_destory(RTGUI_DC(rz_dst)); + rz_dst = RT_NULL; + } + + /* + * Return destination surface + */ + return RTGUI_DC(rz_dst); } RTM_EXPORT(rtgui_dc_shrink); diff --git a/components/gui/src/dc_trans.c b/components/gui/src/dc_trans.c index 9b8b7fb6670fbdd9d1f0fb0534504445109bc2b3..5b676ad41dcf99988879699d9744d577db157c7f 100644 --- a/components/gui/src/dc_trans.c +++ b/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 #include #include @@ -91,7 +115,7 @@ void rtgui_dc_trans_get_new_wh(struct rtgui_dc_trans *dct, &dct->m); /* Transform result of (w, 0). */ rtgui_matrix_mul_point_nomove(&bottomright, - rect.x2, 0, &dct->m); + rect.x2, 0, &dct->m); /* Transform result of (0, 0) is always (0, 0). */ #define NORMALIZE(x) do { if (x < 0) x = 0; } while (0) @@ -105,7 +129,7 @@ void rtgui_dc_trans_get_new_wh(struct rtgui_dc_trans *dct, NORMALIZE(bottomright.x); neww = _UI_MAX(topright.x, _UI_ABS(topleft.x - bottomright.x)) - + dct->m.m[4]; + + dct->m.m[4]; NORMALIZE(neww); *new_wp = neww; @@ -119,7 +143,7 @@ void rtgui_dc_trans_get_new_wh(struct rtgui_dc_trans *dct, NORMALIZE(bottomright.y); newh = _UI_MAX(topright.y, _UI_ABS(topleft.y - bottomright.y)) - + dct->m.m[5]; + + dct->m.m[5]; NORMALIZE(newh); *new_hp = newh; @@ -444,9 +468,9 @@ static void _blit_rotate_FR2FR_SF4B_AA(struct _fb_rect* RTGUI_RESTRICT src, /* FrameRect to FrameRect, from ARGB8888 to RGB565. */ static void _blit_rotate_FR2FR_ARGB2RGB565(struct _fb_rect* RTGUI_RESTRICT src, - const struct rtgui_point *dc_point, - struct _fb_rect* RTGUI_RESTRICT dst, - const struct rtgui_matrix *invm) + const struct rtgui_point *dc_point, + struct _fb_rect* RTGUI_RESTRICT dst, + const struct rtgui_matrix *invm) { rt_uint32_t* RTGUI_RESTRICT srcp = (rt_uint32_t*)src->fb; rt_uint16_t* RTGUI_RESTRICT dstp = (rt_uint16_t*)dst->fb; @@ -505,7 +529,7 @@ static void _blit_rotate_FR2FR_ARGB2RGB565(struct _fb_rect* RTGUI_RESTRICT src, * and blend all components at the same time */ op = ((op & 0xfc00) << 11) + (op >> 8 & 0xf800) - + (op >> 3 & 0x1f); + + (op >> 3 & 0x1f); d = (d | d << 16) & 0x07e0f81f; d += (op - d) * alpha >> 5; d &= 0x07e0f81f; @@ -518,9 +542,9 @@ static void _blit_rotate_FR2FR_ARGB2RGB565(struct _fb_rect* RTGUI_RESTRICT src, /* FrameRect to FrameRect, from ARGB8888 to RGB565. */ static void _blit_rotate_FR2FR_ARGB2RGB565_AA(struct _fb_rect* RTGUI_RESTRICT src, - const struct rtgui_point *dc_point, - struct _fb_rect* RTGUI_RESTRICT dst, - const struct rtgui_matrix *invm) + const struct rtgui_point *dc_point, + struct _fb_rect* RTGUI_RESTRICT dst, + const struct rtgui_matrix *invm) { rt_uint32_t* RTGUI_RESTRICT srcp = (rt_uint32_t*)src->fb; rt_uint16_t* RTGUI_RESTRICT dstp = (rt_uint16_t*)dst->fb; @@ -646,7 +670,8 @@ static void _blit_rotate_B2B(struct rtgui_dc_trans *dct, if (dc->pixel_format == dest->pixel_format) { - switch (rtgui_color_get_bpp(dest->pixel_format)) { + switch (rtgui_color_get_bpp(dest->pixel_format)) + { case 2: if (dct->use_aa) _blit_rotate_FR2FR_SF2B_AA(&srcfb, dc_point, @@ -724,7 +749,8 @@ static void _blit_rotate_B2H(struct rtgui_dc_trans *dct, if (dc->pixel_format == dest->hw_driver->pixel_format) { - switch (rtgui_color_get_bpp(dest->hw_driver->pixel_format)) { + switch (rtgui_color_get_bpp(dest->hw_driver->pixel_format)) + { case 2: if (dct->use_aa) _blit_rotate_FR2FR_SF2B_AA(&srcfb, dc_point, @@ -820,13 +846,13 @@ void rtgui_dc_trans_blit(struct rtgui_dc_trans *dct, if (dct->owner->type == RTGUI_DC_BUFFER) { if (dest->type == RTGUI_DC_BUFFER) - _blit_rotate_B2B(dct, dc_point, - (struct rtgui_dc_buffer*)dest, - rect, &invm, neww, newh); + _blit_rotate_B2B(dct, dc_point, + (struct rtgui_dc_buffer*)dest, + rect, &invm, neww, newh); else if (dest->type == RTGUI_DC_HW) - _blit_rotate_B2H(dct, dc_point, - (struct rtgui_dc_hw*)dest, - rect, &invm, neww, newh); + _blit_rotate_B2H(dct, dc_point, + (struct rtgui_dc_hw*)dest, + rect, &invm, neww, newh); else if (dest->type == RTGUI_DC_CLIENT) // TODO: ; diff --git a/components/gui/src/filerw.c b/components/gui/src/filerw.c index c08f11de50a9b27a2d2f98e709bd98925cd11429..4c1409277bfd394ed5d49f347309355bc2b05fb1 100644 --- a/components/gui/src/filerw.c +++ b/components/gui/src/filerw.c @@ -1,11 +1,21 @@ /* * File : filerw.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/src/font.c b/components/gui/src/font.c index d6fa62ba832f84af505cedf3a59bebc5eaf30664..d0c77de0eb6a147af308014f8cedcfb624cdf625 100644 --- a/components/gui/src/font.c +++ b/components/gui/src/font.c @@ -1,11 +1,21 @@ /* * File : font.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -99,6 +109,16 @@ struct rtgui_font *rtgui_font_refer(const char *family, rt_uint16_t height) } } + rtgui_list_foreach(node, &_rtgui_font_list) + { + font = rtgui_list_entry(node, struct rtgui_font, list); + if (rt_strncmp(font->family, family, RTGUI_NAME_MAX) == 0) + { + font->refer_count ++; + return font; + } + } + return RT_NULL; } RTM_EXPORT(rtgui_font_refer); diff --git a/components/gui/src/font_bmp.c b/components/gui/src/font_bmp.c index 98dcb83e9c51878c104799cd7d9d6201fa625809..f6aa34a11f87c97afd05366a8c7acd05bc3c2e7a 100644 --- a/components/gui/src/font_bmp.c +++ b/components/gui/src/font_bmp.c @@ -1,11 +1,21 @@ /* * File : font.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -34,15 +44,15 @@ void rtgui_bitmap_font_draw_char(struct rtgui_font_bitmap *font, struct rtgui_dc const rt_uint8_t *font_ptr; int x, y, w, h, style; register rt_base_t i, j, /*k,*/ word_bytes; - struct rtgui_rect dc_rect; - + struct rtgui_rect dc_rect; + /* check first and last char */ if (ch < font->first_char || ch > font->last_char) return; /* get text style */ style = rtgui_dc_get_gc(dc)->textstyle; bc = rtgui_dc_get_gc(dc)->background; - rtgui_dc_get_rect(dc, &dc_rect); + rtgui_dc_get_rect(dc, &dc_rect); x = rect->x1; y = rect->y1; @@ -65,8 +75,8 @@ void rtgui_bitmap_font_draw_char(struct rtgui_font_bitmap *font, struct rtgui_dc rt_uint8_t chr = 0; const rt_uint8_t *ptr = font_ptr + i * word_bytes; - if ((i + y) >= dc_rect.y2) continue; - if ((i + y) < 0) continue; + if ((i + y) >= dc_rect.y2) continue; + if ((i + y) < 0) continue; for (j = 0; j < w; j++) { @@ -92,7 +102,7 @@ static void rtgui_bitmap_font_draw_text(struct rtgui_font *font, struct rtgui_dc RT_ASSERT(bmp_font != RT_NULL); - /* parameter check */ + /* parameter check */ if (rect->y1 > rect->y2) return; #ifdef RTGUI_USING_FONTHZ diff --git a/components/gui/src/font_fnt.c b/components/gui/src/font_fnt.c index 69323bc6ed8e9fbc770314f69c895433b0a696cd..28ae24d5304384c45f52bec60e6fa066b02b0c0b 100644 --- a/components/gui/src/font_fnt.c +++ b/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 #include @@ -8,102 +32,103 @@ static void rtgui_fnt_font_draw_text(struct rtgui_font *font, struct rtgui_dc *d static void rtgui_fnt_font_get_metrics(struct rtgui_font *font, const char *text, rtgui_rect_t *rect); const struct rtgui_font_engine fnt_font_engine = { - RT_NULL, - RT_NULL, + RT_NULL, + RT_NULL, rtgui_fnt_font_draw_text, rtgui_fnt_font_get_metrics }; void rtgui_fnt_font_draw_text(struct rtgui_font *font, struct rtgui_dc *dc, const char *text, rt_ubase_t len, struct rtgui_rect *rect) { - int ch, i, j, c, width; - rt_uint32_t position; - struct fnt_font *fnt; - rt_uint8_t *data_ptr; - - fnt = (struct fnt_font*)font->data; - RT_ASSERT(fnt != RT_NULL); - - while (len) - { - /* get character */ - ch = *text; - /* NOTE: we only support asc character right now */ - if (ch > 0x80) - { - text += 1; len -= 1; - continue; - } - - /* get position and width */ - if (fnt->offset == RT_NULL) - { - width = fnt->header.max_width; - position = (ch - fnt->header.first_char) * width * ((fnt->header.height + 7)/8); - } - else - { - width = fnt->width[ch - fnt->header.first_char]; - position = fnt->offset[ch - fnt->header.first_char]; - } - - /* draw a character */ - data_ptr = (rt_uint8_t*)&fnt->bits[position]; - for (i = 0; i < width; i ++) /* x */ - { - for (j = 0; j < 8; j ++) /* y */ - { - for (c = 0; c < (fnt->header.height + 7)/8; c ++) - { - /* check drawable region */ - if ((rect->x1 + i > rect->x2) || (rect->y1 + c * 8 + j > rect->y2)) - continue; - - if (data_ptr[i + c * width] & (1 << j)) - rtgui_dc_draw_point(dc, rect->x1 + i, rect->y1 + c * 8 + j); - } - } - } - - rect->x1 += width; - text += 1; - len -= 1; - } + int ch, i, j, c, width; + rt_uint32_t position; + struct fnt_font *fnt; + rt_uint8_t *data_ptr; + + fnt = (struct fnt_font*)font->data; + RT_ASSERT(fnt != RT_NULL); + + while (len) + { + /* get character */ + ch = *text; + /* NOTE: we only support asc character right now */ + if (ch > 0x80) + { + text += 1; + len -= 1; + continue; + } + + /* get position and width */ + if (fnt->offset == RT_NULL) + { + width = fnt->header.max_width; + position = (ch - fnt->header.first_char) * width * ((fnt->header.height + 7)/8); + } + else + { + width = fnt->width[ch - fnt->header.first_char]; + position = fnt->offset[ch - fnt->header.first_char]; + } + + /* draw a character */ + data_ptr = (rt_uint8_t*)&fnt->bits[position]; + for (i = 0; i < width; i ++) /* x */ + { + for (j = 0; j < 8; j ++) /* y */ + { + for (c = 0; c < (fnt->header.height + 7)/8; c ++) + { + /* check drawable region */ + if ((rect->x1 + i > rect->x2) || (rect->y1 + c * 8 + j > rect->y2)) + continue; + + if (data_ptr[i + c * width] & (1 << j)) + rtgui_dc_draw_point(dc, rect->x1 + i, rect->y1 + c * 8 + j); + } + } + } + + rect->x1 += width; + text += 1; + len -= 1; + } } void rtgui_fnt_font_get_metrics(struct rtgui_font *font, const char *text, rtgui_rect_t *rect) { - int ch; - struct fnt_font *fnt; - - fnt = (struct fnt_font*)font->data; - RT_ASSERT(fnt != RT_NULL); - - rt_memset(rect, 0x00, sizeof(rtgui_rect_t)); - rect->y2 = fnt->header.height; - - while (*text) - { - if (fnt->width == RT_NULL) - { - /* fixed width font */ - rect->x2 += fnt->header.max_width; - } - else - { - ch = *text; - /* NOTE: we only support asc character right now */ - if (ch > 0x80) - { - text += 1; - continue; - } - - rect->x2 += fnt->width[ch - fnt->header.first_char]; - } - - text += 1; - } + int ch; + struct fnt_font *fnt; + + fnt = (struct fnt_font*)font->data; + RT_ASSERT(fnt != RT_NULL); + + rt_memset(rect, 0x00, sizeof(rtgui_rect_t)); + rect->y2 = fnt->header.height; + + while (*text) + { + if (fnt->width == RT_NULL) + { + /* fixed width font */ + rect->x2 += fnt->header.max_width; + } + else + { + ch = *text; + /* NOTE: we only support asc character right now */ + if (ch > 0x80) + { + text += 1; + continue; + } + + rect->x2 += fnt->width[ch - fnt->header.first_char]; + } + + text += 1; + } } #ifdef RTGUI_USING_FNT_FILE @@ -111,137 +136,137 @@ void rtgui_fnt_font_get_metrics(struct rtgui_font *font, const char *text, rtgui rt_inline int readbyte(int fd, unsigned char *cp) { - unsigned char buf[1]; + unsigned char buf[1]; - if (read(fd, buf, 1) != 1) - return 0; - *cp = buf[0]; - return 1; + if (read(fd, buf, 1) != 1) + return 0; + *cp = buf[0]; + return 1; } rt_inline int readshort(int fd, unsigned short *sp) { - unsigned char buf[2]; + unsigned char buf[2]; - if (read(fd, buf, 2) != 2) - return 0; - *sp = buf[0] | (buf[1] << 8); - return 1; + if (read(fd, buf, 2) != 2) + return 0; + *sp = buf[0] | (buf[1] << 8); + return 1; } rt_inline int readlong(int fd, rt_uint32_t *lp) { - unsigned char buf[4]; + unsigned char buf[4]; - if (read(fd, buf, 4) != 4) - return 0; - *lp = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); - return 1; + if (read(fd, buf, 4) != 4) + return 0; + *lp = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + return 1; } rt_inline int readstr(int fd, char *buf, int count) { - return read(fd, buf, count); + return read(fd, buf, count); } struct rtgui_font *fnt_font_create(const char* filename, const char* font_family) { - int fd = -1; - rt_uint32_t index; - struct rtgui_font *font = RT_NULL; - struct fnt_font *fnt = RT_NULL; - struct fnt_header *fnt_header; - - fd = open(filename, O_RDONLY, 0); - if (fd < 0) - { - goto __exit; - } - - font = (struct rtgui_font*) rtgui_malloc (sizeof(struct rtgui_font)); - if (font == RT_NULL) goto __exit; - fnt = (struct fnt_font*) rtgui_malloc (sizeof(struct fnt_font)); - if (fnt == RT_NULL) goto __exit; - rt_memset(fnt, 0x00, sizeof(struct fnt_font)); - font->data = (void*)fnt; - - fnt_header = &(fnt->header); - if (readstr(fd, fnt_header->version, 4) != 4) goto __exit; - if (!readshort(fd, &fnt_header->max_width)) goto __exit; - if (!readshort(fd, &fnt_header->height)) goto __exit; - if (!readshort(fd, &fnt_header->ascent)) goto __exit; - if (!readshort(fd, &fnt_header->depth)) goto __exit; - - if (!readlong(fd, &fnt_header->first_char)) goto __exit; - if (!readlong(fd, &fnt_header->default_char)) goto __exit; - if (!readlong(fd, &fnt_header->size)) goto __exit; - if (!readlong(fd, &fnt_header->nbits)) goto __exit; - if (!readlong(fd, &fnt_header->noffset)) goto __exit; - if (!readlong(fd, &fnt_header->nwidth)) goto __exit; - - fnt->bits = (MWIMAGEBITS*) rtgui_malloc (fnt_header->nbits * sizeof(MWIMAGEBITS)); - if (fnt->bits == RT_NULL) goto __exit; - /* read data */ - if (readstr(fd, &(fnt->bits[0]), fnt_header->nbits) != fnt_header->nbits) goto __exit; - - /* check boundary */ - if (fnt_header->nbits & 0x01) - { - rt_uint16_t pad; - readshort(fd, &pad); - pad = pad; /* skip warning */ - } - - if (fnt_header->noffset != 0) - { - fnt->offset = rtgui_malloc (fnt_header->noffset * sizeof(rt_uint32_t)); - if (fnt->offset == RT_NULL) goto __exit; - - for (index = 0; index < fnt_header->noffset; index ++) - { - if (!readshort(fd, &(fnt->offset[index]))) goto __exit; - } - } - - if (fnt_header->nwidth != 0) - { - fnt->width = rtgui_malloc (fnt_header->nwidth * sizeof(rt_uint8_t)); - if (fnt->width == RT_NULL) goto __exit; - - for (index = 0; index < fnt_header->nwidth; index ++) - { - if (!readbyte(fd, &(fnt->width[index]))) goto __exit; - } - } - - close(fd); - - font->family = rt_strdup(font_family); - font->height = fnt->header.height; - font->refer_count = 0; - font->engine = &fnt_font_engine; - - /* add to system */ - rtgui_font_system_add_font(font); - - return font; + int fd = -1; + rt_uint32_t index; + struct rtgui_font *font = RT_NULL; + struct fnt_font *fnt = RT_NULL; + struct fnt_header *fnt_header; + + fd = open(filename, O_RDONLY, 0); + if (fd < 0) + { + goto __exit; + } + + font = (struct rtgui_font*) rtgui_malloc (sizeof(struct rtgui_font)); + if (font == RT_NULL) goto __exit; + fnt = (struct fnt_font*) rtgui_malloc (sizeof(struct fnt_font)); + if (fnt == RT_NULL) goto __exit; + rt_memset(fnt, 0x00, sizeof(struct fnt_font)); + font->data = (void*)fnt; + + fnt_header = &(fnt->header); + if (readstr(fd, fnt_header->version, 4) != 4) goto __exit; + if (!readshort(fd, &fnt_header->max_width)) goto __exit; + if (!readshort(fd, &fnt_header->height)) goto __exit; + if (!readshort(fd, &fnt_header->ascent)) goto __exit; + if (!readshort(fd, &fnt_header->depth)) goto __exit; + + if (!readlong(fd, &fnt_header->first_char)) goto __exit; + if (!readlong(fd, &fnt_header->default_char)) goto __exit; + if (!readlong(fd, &fnt_header->size)) goto __exit; + if (!readlong(fd, &fnt_header->nbits)) goto __exit; + if (!readlong(fd, &fnt_header->noffset)) goto __exit; + if (!readlong(fd, &fnt_header->nwidth)) goto __exit; + + fnt->bits = (MWIMAGEBITS*) rtgui_malloc (fnt_header->nbits * sizeof(MWIMAGEBITS)); + if (fnt->bits == RT_NULL) goto __exit; + /* read data */ + if (readstr(fd, &(fnt->bits[0]), fnt_header->nbits) != fnt_header->nbits) goto __exit; + + /* check boundary */ + if (fnt_header->nbits & 0x01) + { + rt_uint16_t pad; + readshort(fd, &pad); + pad = pad; /* skip warning */ + } + + if (fnt_header->noffset != 0) + { + fnt->offset = rtgui_malloc (fnt_header->noffset * sizeof(rt_uint32_t)); + if (fnt->offset == RT_NULL) goto __exit; + + for (index = 0; index < fnt_header->noffset; index ++) + { + if (!readshort(fd, &(fnt->offset[index]))) goto __exit; + } + } + + if (fnt_header->nwidth != 0) + { + fnt->width = rtgui_malloc (fnt_header->nwidth * sizeof(rt_uint8_t)); + if (fnt->width == RT_NULL) goto __exit; + + for (index = 0; index < fnt_header->nwidth; index ++) + { + if (!readbyte(fd, &(fnt->width[index]))) goto __exit; + } + } + + close(fd); + + font->family = rt_strdup(font_family); + font->height = fnt->header.height; + font->refer_count = 0; + font->engine = &fnt_font_engine; + + /* add to system */ + rtgui_font_system_add_font(font); + + return font; __exit: - if (fd >= 0) close(fd); - if (fnt != RT_NULL) - { - if (fnt->bits != RT_NULL) rtgui_free(fnt->bits); - if (fnt->offset != RT_NULL) rtgui_free(fnt->offset); - if (fnt->width != RT_NULL) rtgui_free(fnt->width); - - rtgui_free(fnt); - } - - if (font != RT_NULL) - { - rtgui_free(font); - } - return RT_NULL; + if (fd >= 0) close(fd); + if (fnt != RT_NULL) + { + if (fnt->bits != RT_NULL) rtgui_free(fnt->bits); + if (fnt->offset != RT_NULL) rtgui_free(fnt->offset); + if (fnt->width != RT_NULL) rtgui_free(fnt->width); + + rtgui_free(fnt); + } + + if (font != RT_NULL) + { + rtgui_free(font); + } + return RT_NULL; } #endif diff --git a/components/gui/src/font_freetype.c b/components/gui/src/font_freetype.c index 152fbf5edd60d3c9d44981366a27d89d31322b71..02368a09399735440980ec33265c2d53b6abc6c2 100644 --- a/components/gui/src/font_freetype.c +++ b/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 #ifdef RTGUI_USING_TTF #include #include #include +#include #include +#include +#include #include #include FT_FREETYPE_H @@ -25,31 +52,8 @@ #define PINFO(...) #endif -static void ftf_draw_text(struct rtgui_font *font, - struct rtgui_dc *dc, - const char *text, - rt_ubase_t len, - struct rtgui_rect *rect); -static void ftf_get_metrics_kern(struct rtgui_font *font, - const char *text, - rtgui_rect_t *rect); - -static const struct rtgui_font_engine ftf_engine = -{ - RT_NULL, - RT_NULL, - ftf_draw_text, - ftf_get_metrics_kern -}; - -struct rtgui_freetype2_font -{ - int bold; - int italic; - - FT_Face face; - FT_Library library; -}; +#define _dc_get_pixel(dc, x, y) \ + ((dc)->pixel + (y) * (dc)->pitch + (x) * rtgui_color_get_bpp((dc)->pixel_format)) #if !defined(RT_USING_DFS) || !defined(RT_USING_DFS_ELMFAT) || (RT_DFS_ELM_CODE_PAGE != 936) extern rt_uint32_t gb2312tounicode(const rt_uint16_t key); @@ -87,129 +91,321 @@ static void gbk_to_unicode(rt_uint16_t *unicode, const char *text, int len) *unicode = '\0'; } -static void _draw_bitmap(struct rtgui_dc *dc, - FT_GlyphSlot slot, - rt_int16_t ox, rt_int16_t btm_y, - rt_uint8_t r, rt_uint8_t g, rt_uint8_t b) +static void _rtgui_rect_moveto_align(const rtgui_rect_t *rect, rtgui_rect_t *to, int align) { - int rows; - rt_uint8_t *ptr; - FT_Bitmap *bitmap; - rt_int16_t xstart; + int dw, dh; + dw = 0; + dh = 0; + + /* get delta width and height */ + dw = rtgui_rect_width(*rect) - rtgui_rect_width(*to); + dh = rtgui_rect_height(*rect) - rtgui_rect_height(*to); + if (dw < 0) dw = 0; + if (dh < 0) dh = 0; - bitmap = &slot->bitmap; - ptr = (rt_uint8_t *)bitmap->buffer; - xstart = ox + slot->bitmap_left; + /* move to insider of rect */ + rtgui_rect_moveto_point(to, rect->x1, rect->y1); - for (rows = 0; rows < bitmap->rows; rows++) + /* limited the destination rect to source rect */ + // if (dw == 0) to->x2 = rect->x2; + // if (dh == 0) to->y2 = rect->y2; + + /* align to right */ + if (align & RTGUI_ALIGN_RIGHT) { - int x; - int y = btm_y + rows - slot->bitmap_top; + to->x1 += dw; + to->x2 += dw; + } - for (x = 0; x < bitmap->width; x++) - { - /* Use 5bit alpha. */ - rt_uint8_t c = *ptr; - if (c >= 0xF8) - { - rtgui_dc_draw_point(dc, xstart + x, y); - } - else if (c >> 3) - { - rtgui_dc_blend_point(dc, xstart + x, y, - RTGUI_BLENDMODE_BLEND, - r, g, b, c); - } - ptr++; - } + /* align to bottom */ + if (align & RTGUI_ALIGN_BOTTOM) + { + to->y1 += dh; + to->y2 += dh; + } + + /* align to center horizontal */ + if (align & RTGUI_ALIGN_CENTER_HORIZONTAL) + { + to->x1 += dw >> 1; + to->x2 += dw >> 1; + } + + /* align to center vertical */ + if (align & RTGUI_ALIGN_CENTER_VERTICAL) + { + to->y1 += dh >> 1; + to->y2 += dh >> 1; } } -static void _draw_text_nkern(struct rtgui_dc *dc, - struct rtgui_freetype2_font *fft, - rt_uint16_t *text_short, - rt_int16_t begin_x, rt_int16_t btm_y, - rt_uint8_t r, rt_uint8_t g, rt_uint8_t b) +static void ftc_draw_text(struct rtgui_font *font, + struct rtgui_dc *dc, + const char *text, + rt_ubase_t len, + struct rtgui_rect *rect); +static void ftc_get_metrics(struct rtgui_font *font, const char *text, rtgui_rect_t *rect); + +static const struct rtgui_font_engine ftc_engine = { - rt_uint16_t *text_ptr; - FT_GlyphSlot slot; + RT_NULL, + RT_NULL, + ftc_draw_text, + ftc_get_metrics +}; - slot = fft->face->glyph; +struct ttf_face_id +{ + const char* pathname; + FT_Long face_index; +}; - for (text_ptr = text_short; *text_ptr; text_ptr++) +struct rtgui_ttf +{ + /* the ttf list */ + rtgui_list_t list; + rt_uint32_t refer_count; + + struct ttf_face_id face_id; + FT_Library library; + FTC_Manager manager; + FTC_SBitCache sbit_cache; + FTC_CMapCache cmap_cache; +}; + +struct rtgui_ttf_font +{ + struct rtgui_ttf *ttf; + FTC_ImageTypeRec image_type_rec; +}; + +static rtgui_list_t _rtgui_ttf_list; + +void rtgui_ttf_system_init(void) +{ + rtgui_list_init(&(_rtgui_ttf_list)); +} + +static void rtgui_ttf_system_add_ttf(struct rtgui_ttf *ttf) +{ + rtgui_list_append(&_rtgui_ttf_list, &(ttf->list)); +} + +static void rtgui_ttf_system_remove_ttf(struct rtgui_ttf *ttf) +{ + rtgui_list_remove(&_rtgui_ttf_list, &(ttf->list)); +} + +static struct rtgui_ttf *rtgui_ttf_refer(const char *family) +{ + /* search ttf */ + struct rtgui_list_node *node; + struct rtgui_ttf *ttf; + + rtgui_list_foreach(node, &_rtgui_ttf_list) { - FT_Error err = 0; + ttf = (struct rtgui_ttf *)node; + if (rt_strncmp(ttf->face_id.pathname, family, RT_DFS_ELM_MAX_LFN) == 0) + { + ttf->refer_count ++; + return ttf; + } + } - err = FT_Load_Char(fft->face, *text_ptr, FT_LOAD_RENDER | FT_LOAD_NO_HINTING); - if (err) - continue; /* ignore errors */ + return RT_NULL; +} - /* render font */ - _draw_bitmap(dc, slot, begin_x, btm_y, r, g, b); +static void rtgui_ttf_derefer(struct rtgui_ttf *ttf) +{ + RT_ASSERT(ttf != RT_NULL); - begin_x += slot->advance.x >> 6; + ttf->refer_count --; + + /* no refer, remove ttf */ + if (ttf->refer_count == 0) + { + rtgui_ttf_system_remove_ttf(ttf); } } -static void _draw_text_kern(struct rtgui_dc *dc, - struct rtgui_freetype2_font *fft, - rt_uint16_t *text_short, - rt_int16_t begin_x, rt_int16_t btm_y, - rt_uint8_t r, rt_uint8_t g, rt_uint8_t b) + +static void _get_metrics(struct rtgui_ttf_font *ttf_font, const rt_uint16_t *text_short, struct rtgui_rect *rect); + +static void _draw_bitmap(struct rtgui_dc *dc, + FTC_SBit bitmap, + rt_int16_t ox, rt_int16_t btm_y, + rt_uint8_t r, rt_uint8_t g, rt_uint8_t b) { - rt_uint16_t *tp; - FT_GlyphSlot slot; - FT_Face face; - rt_uint32_t prev_gidx; + rt_int16_t x_start, y_start; + struct rtgui_blit_info info; + struct rtgui_dc_buffer *dest_buf; + - face = fft->face; - slot = face->glyph; + x_start = ox + bitmap->left; + y_start = btm_y - bitmap->top; - prev_gidx = 0; - for (tp = text_short; *tp; tp++) + info.a = 255; + info.r = r; + info.g = g; + info.b = b; + + if (dc->type == RTGUI_DC_HW) { - FT_Error err; - rt_uint32_t cur_gidx; + struct rtgui_graphic_driver *hw_driver = rtgui_graphic_driver_get_default(); + dest_buf = (struct rtgui_dc_buffer*)dc; - cur_gidx = FT_Get_Char_Index(face, *tp); - if (prev_gidx && cur_gidx) + if (hw_driver->framebuffer != RT_NULL) { - FT_Vector delta; + struct rtgui_widget *owner = ((struct rtgui_dc_hw*)dest_buf)->owner; + + if (x_start + bitmap->width < 0 || y_start + bitmap->height < 0 + || x_start > owner->extent.x2 - owner->extent.x1 || y_start > owner->extent.y2 - owner->extent.y1) + return; + + /* blit source */ + info.src = (rt_uint8_t *)bitmap->buffer; + info.src = info.src + (y_start > 0 ? 0 : bitmap->top - btm_y) * bitmap->width + (x_start > 0 ? 0 : -x_start); + info.src_fmt = RTGRAPHIC_PIXEL_FORMAT_ALPHA; + info.src_w = bitmap->width - (x_start > 0 ? 0 : -x_start) - (x_start + bitmap->width < owner->extent.x2 - owner->extent.x1 ? 0 : x_start + bitmap->width - owner->extent.x2 + owner->extent.x1); + info.src_h = bitmap->height - (y_start > 0 ? 0 : bitmap->top - btm_y) - (y_start + bitmap->height < owner->extent.y2 - owner->extent.y1 ? 0 : y_start + bitmap->height - owner->extent.y2 + owner->extent.y1); + info.src_pitch = bitmap->width; + info.src_skip = info.src_pitch - info.src_w; + + /* blit destination */ + info.dst = (rt_uint8_t*)hw_driver->framebuffer; + info.dst = info.dst + (owner->extent.y1 + (y_start < 0 ? 0 : y_start)) * hw_driver->pitch + (owner->extent.x1 + (x_start < 0 ? 0 : x_start)) * rtgui_color_get_bpp(hw_driver->pixel_format); + info.dst_fmt = hw_driver->pixel_format; + info.dst_w = info.src_w; + info.dst_h = info.src_h; + info.dst_pitch = hw_driver->pitch; + info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(hw_driver->pixel_format); + + rtgui_blit(&info); + } + } + else if (dc->type == RTGUI_DC_BUFFER) + { + dest_buf = (struct rtgui_dc_buffer*)dc; + + if (x_start + bitmap->width < 0 || y_start + bitmap->height < 0 + || x_start > dest_buf->width || y_start > dest_buf->height) + return; + + /* blit source */ + info.src = (rt_uint8_t *)bitmap->buffer; + info.src = info.src + (y_start > 0 ? 0 : -y_start) * bitmap->width + (x_start > 0 ? 0 : -x_start); + info.src_fmt = RTGRAPHIC_PIXEL_FORMAT_ALPHA; + info.src_w = bitmap->width - (x_start > 0 ? 0 : -x_start) - (x_start + bitmap->width < dest_buf->width ? 0 : x_start + bitmap->width - dest_buf->width); + info.src_h = bitmap->height - (y_start > 0 ? 0 : -y_start) - (y_start + bitmap->height < dest_buf->height ? 0 : y_start + bitmap->height - dest_buf->height); + info.src_pitch = bitmap->width; + info.src_skip = info.src_pitch - info.src_w; + + /* blit destination */ + info.dst = _dc_get_pixel(dest_buf, (x_start < 0 ? 0 : x_start), (y_start < 0 ? 0 : y_start)); + info.dst_fmt = dest_buf->pixel_format; + info.dst_w = info.src_w; + info.dst_h = info.src_h; + info.dst_pitch = dest_buf->pitch; + info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(dest_buf->pixel_format); + + rtgui_blit(&info); + } + else + { + struct rtgui_rect text_rect; + struct rtgui_point dc_point = { 0, 0 }; + struct rtgui_dc *text_dc = rtgui_dc_buffer_create_pixformat(RTGRAPHIC_PIXEL_FORMAT_ARGB888, bitmap->width, bitmap->height); + if (text_dc) + { + dest_buf = (struct rtgui_dc_buffer*)text_dc; + + /* blit source */ + info.src = (rt_uint8_t *)bitmap->buffer; + info.src_fmt = RTGRAPHIC_PIXEL_FORMAT_ALPHA; + info.src_w = bitmap->width; + info.src_h = bitmap->height; + info.src_pitch = bitmap->width; + info.src_skip = 0; + + /* blit destination */ + info.dst = _dc_get_pixel(dest_buf, 0, 0); + info.dst_fmt = dest_buf->pixel_format; + info.dst_w = info.src_w; + info.dst_h = info.src_h; + info.dst_pitch = dest_buf->pitch; + info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(dest_buf->pixel_format); + + rtgui_blit(&info); + + text_rect.x1 = x_start; + text_rect.x2 = text_rect.x1 + bitmap->width; - FT_Get_Kerning(face, prev_gidx, cur_gidx, - FT_KERNING_DEFAULT, &delta ); + text_rect.y1 = y_start; + text_rect.y2 = text_rect.y1 + bitmap->height; - begin_x += delta.x >> 6; + rtgui_dc_blit(text_dc, &dc_point, dc, &text_rect); + + rtgui_dc_destory(text_dc); } - prev_gidx = cur_gidx; + } +} - err = FT_Load_Glyph(face, cur_gidx, FT_LOAD_RENDER | FT_LOAD_NO_HINTING); - if (err) - continue; +static void _draw_text(struct rtgui_dc *dc, + struct rtgui_ttf_font *ttf_font, + rt_uint16_t *text_short, + rt_int16_t begin_x, rt_int16_t btm_y, + rt_uint8_t r, rt_uint8_t g, rt_uint8_t b) +{ + int glyphIndex; + FTC_SBit ftcSBit = RT_NULL; + FT_Error err = 0; - /* render font */ - _draw_bitmap(dc, slot, begin_x, btm_y, r, g, b); + while (*text_short) + { + glyphIndex = FTC_CMapCache_Lookup(ttf_font->ttf->cmap_cache, &ttf_font->ttf->face_id, 0, *text_short); + + err = FTC_SBitCache_Lookup(ttf_font->ttf->sbit_cache, &ttf_font->image_type_rec, glyphIndex, &ftcSBit, 0); + if (err == 0 && ftcSBit->width != 0) + { + /* render font */ + _draw_bitmap(dc, ftcSBit, begin_x, btm_y, r, g, b); + + begin_x += ftcSBit->width + ftcSBit->left; + + text_short++; + } + else if (*text_short == ' ') + { + glyphIndex = FTC_CMapCache_Lookup(ttf_font->ttf->cmap_cache, &ttf_font->ttf->face_id, 0, '-'); + + err = FTC_SBitCache_Lookup(ttf_font->ttf->sbit_cache, &ttf_font->image_type_rec, glyphIndex, &ftcSBit, 0); + if (err == 0) + { + begin_x += ftcSBit->width; - begin_x += slot->advance.x >> 6; + text_short++; + } + } } } -static void ftf_draw_text(struct rtgui_font *font, +static void ftc_draw_text(struct rtgui_font *font, struct rtgui_dc *dc, const char *text, rt_ubase_t len, struct rtgui_rect *rect) { rt_uint16_t *text_short; - struct rtgui_freetype2_font *fft; + struct rtgui_ttf_font *ttf_font; rt_int16_t begin_x, btm_y; rt_int16_t topy; rt_uint8_t r, g, b; rtgui_color_t fgc; + struct rtgui_rect text_rect; RT_ASSERT(font != RT_NULL); - fft = (struct rtgui_freetype2_font *) font->data; - RT_ASSERT(fft != RT_NULL); + ttf_font = (struct rtgui_ttf_font *) font->data; + RT_ASSERT(ttf_font != RT_NULL); /* allocate unicode buffer */ text_short = (rt_uint16_t *)rtgui_malloc((len + 1) * 2); @@ -226,135 +422,104 @@ static void ftf_draw_text(struct rtgui_font *font, g = RTGUI_RGB_G(fgc); b = RTGUI_RGB_B(fgc); - /* FIXME: RTGUI has no concept of "base line" right now. FreeType - * coordinate(0, 0) start from base line. So we have to adjust the rect to - * fit the glyphs within the rect. */ - /* FIXME: face->size->metrics.descender is format specific actually. But it - * just works on TrueType. Varify this if you want to use with other fonts. */ - topy = rect->y1 + (fft->face->size->metrics.descender >> 6); - btm_y = topy + rtgui_rect_height(*rect); + /* text align */ + _get_metrics(ttf_font, text_short, &text_rect); + + topy = text_rect.y1; + + _rtgui_rect_moveto_align(rect, &text_rect, RTGUI_DC_TEXTALIGN(dc)); + + btm_y = topy + text_rect.y2; if (btm_y <= 0) return; - begin_x = rect->x1; + begin_x = text_rect.x1; if (dc->type == RTGUI_DC_BUFFER) { - struct rtgui_dc_buffer *bdc = (struct rtgui_dc_buffer *) dc; + struct rtgui_dc_buffer *bdc = (struct rtgui_dc_buffer *) dc; if (begin_x >= bdc->width || topy >= bdc->height) { goto _out; } } - else if (dc->type == RTGUI_DC_HW) - { + else if (dc->type == RTGUI_DC_HW) + { int x, y; - struct rtgui_dc_hw *hdc = (struct rtgui_dc_hw *) dc; + struct rtgui_dc_hw *hdc = (struct rtgui_dc_hw *) dc; - x = begin_x + hdc->owner->extent.x1; - y = topy + hdc->owner->extent.y1; - if (x >= hdc->owner->extent.x2) + x = begin_x + hdc->owner->extent.x1; + y = topy + hdc->owner->extent.y1; + if (x >= hdc->owner->extent.x2) goto _out; - if (y >= hdc->owner->extent.y2) + if (y >= hdc->owner->extent.y2) goto _out; - } - - if (FT_HAS_KERNING(fft->face)) - { - _draw_text_kern(dc, fft, text_short, begin_x, btm_y, r, g, b); - } - else - { - _draw_text_nkern(dc, fft, text_short, begin_x, btm_y, r, g, b); } + _draw_text(dc, ttf_font, text_short, begin_x, btm_y, r, g, b); + _out: /* release unicode buffer */ rtgui_free(text_short); } -static void _get_metrics_nkern(FT_Face face, const rt_uint16_t *text_short, struct rtgui_rect *rect) +static void _get_metrics(struct rtgui_ttf_font *ttf_font, const rt_uint16_t *text_short, struct rtgui_rect *rect) { - rt_int16_t w; + FTC_SBit ftcSBit = RT_NULL; + rt_int16_t w = 0, top = 0, btm = 0; - w = 0; while (*text_short) { FT_Error err = 0; - rt_uint16_t index; - - index = FT_Get_Char_Index(face, *text_short); - err = FT_Load_Glyph(face, index, - FT_LOAD_DEFAULT | - FT_LOAD_NO_HINTING | - FT_LOAD_IGNORE_TRANSFORM | - FT_LOAD_NO_AUTOHINT); + int glyphIndex; - if (err == 0) - w += face->glyph->advance.x >> 6; + glyphIndex = FTC_CMapCache_Lookup(ttf_font->ttf->cmap_cache, &ttf_font->ttf->face_id, 0, *text_short); - text_short ++; - } - - rect->x1 = 0; - rect->y1 = 0; - rect->x2 = w; - rect->y2 = FT_MulFix(face->bbox.yMax - face->bbox.yMin, - face->size->metrics.y_scale) >> 6; -} - -static void _get_metrics_kern(FT_Face face, const rt_uint16_t *text_short, struct rtgui_rect *rect) -{ - rt_uint16_t prev_gidx; - rt_int16_t w; - - prev_gidx = 0; - w = 0; - while (*text_short) - { - FT_Error err = 0; - rt_uint16_t index; - - index = FT_Get_Char_Index(face, *text_short); - if (prev_gidx && index) + err = FTC_SBitCache_Lookup(ttf_font->ttf->sbit_cache, &ttf_font->image_type_rec, glyphIndex, &ftcSBit, 0); + if (err == 0 && ftcSBit->width != 0) { - FT_Vector delta; - - FT_Get_Kerning(face, prev_gidx, index, - FT_KERNING_DEFAULT, &delta); + if (w == 0) + w = ftcSBit->width; + else + w += ftcSBit->width + ftcSBit->left; - w += delta.x >> 6; + top = top > ftcSBit->top ? top : ftcSBit->top; + btm = (ftcSBit->top - ftcSBit->height) > btm ? btm : (ftcSBit->top - ftcSBit->height); } - prev_gidx = index; - err = FT_Load_Glyph(face, index, - FT_LOAD_DEFAULT | - FT_LOAD_NO_HINTING | - FT_LOAD_IGNORE_TRANSFORM | - FT_LOAD_NO_AUTOHINT); + else if (*text_short == ' ') + { + glyphIndex = FTC_CMapCache_Lookup(ttf_font->ttf->cmap_cache, &ttf_font->ttf->face_id, 0, '-'); - if (err == 0) - w += face->glyph->advance.x >> 6; + err = FTC_SBitCache_Lookup(ttf_font->ttf->sbit_cache, &ttf_font->image_type_rec, glyphIndex, &ftcSBit, 0); + if (err == 0) + { + w += ftcSBit->width; + } + } + PINFO(" bitmap:(%d, %d, %d, %d)\n", ftcSBit->left, ftcSBit->top, + ftcSBit->width, ftcSBit->height); text_short ++; } rect->x1 = 0; - rect->y1 = 0; + rect->y1 = btm; rect->x2 = w; - rect->y2 = FT_MulFix(face->bbox.yMax - face->bbox.yMin, - face->size->metrics.y_scale) >> 6; + rect->y2 = top; + + PINFO(" _get_metrics: %d %d %d %d\n", rect->x1, rect->y1, rect->x2, rect->y2); } -static void ftf_get_metrics_kern(struct rtgui_font *font, const char *text, rtgui_rect_t *rect) +static void ftc_get_metrics(struct rtgui_font *font, const char *text, struct rtgui_rect *rect) { int len; rt_uint16_t *text_short; - struct rtgui_freetype2_font *fft; + struct rtgui_ttf_font *ttf_font; RT_ASSERT(font != RT_NULL); RT_ASSERT(rect != RT_NULL); - fft = (struct rtgui_freetype2_font *) font->data; - RT_ASSERT(fft != RT_NULL); + ttf_font = (struct rtgui_ttf_font *) font->data; + RT_ASSERT(ttf_font != RT_NULL); len = strlen(text); memset(rect, 0, sizeof(struct rtgui_rect)); @@ -367,111 +532,168 @@ static void ftf_get_metrics_kern(struct rtgui_font *font, const char *text, rtgu /* convert gbk to unicode */ gbk_to_unicode(text_short, text, len); - if (FT_HAS_KERNING(fft->face)) - _get_metrics_kern(fft->face, text_short, rect); - else - _get_metrics_nkern(fft->face, text_short, rect); + _get_metrics(ttf_font, text_short, rect); + rtgui_rect_moveto_point(rect, 0, 0); + PINFO(" ftc_get_metrics_kern: %d %d %d %d\n", rect->x1, rect->y1, rect->x2, rect->y2); /* release unicode buffer */ rtgui_free(text_short); } -rtgui_font_t *rtgui_freetype_font_create(const char *filename, int bold, int italic, rt_size_t size) +static FT_Error ftc_face_requester(FTC_FaceID faceID, FT_Library lib, FT_Pointer reqData, FT_Face *face) +{ + int ret; + + struct ttf_face_id *face_id = (struct ttf_face_id *)faceID; + + PINFO("ftc_face_requester %s %d\n", face_id->pathname, face_id->face_index); + ret = FT_New_Face(lib, (char *)face_id->pathname, face_id->face_index, face); + if (ret != 0) + { + PERROR("FT_New_Face failed!\n"); + return -1; + } + + return 0; +} + +static struct rtgui_ttf *rtgui_ttf_load(const char *filename) { FT_Error err = 0; - struct rtgui_font *font; - struct rtgui_freetype2_font *fft; + struct rtgui_ttf *ttf; - font = (struct rtgui_font *)rtgui_malloc(sizeof(struct rtgui_font) - + sizeof(struct rtgui_freetype2_font)); - rt_memset(font, 0, sizeof(struct rtgui_font) + sizeof(struct rtgui_freetype2_font)); - if (!font) + ttf = (struct rtgui_ttf *)rtgui_malloc(sizeof(struct rtgui_ttf)); + if (!ttf) { - PERROR("failed to allocate structs\n"); + PERROR("rtgui_ttf_load rtgui_malloc failed!\n"); return RT_NULL; } - fft = (struct rtgui_freetype2_font *)(font + 1); - font->data = fft; + /* face_id init */ + ttf->face_id.pathname = rt_strdup(filename); + ttf->face_id.face_index = 0; - err = FT_Init_FreeType(&fft->library); + err = FT_Init_FreeType(&ttf->library); if (err) { - PERROR("failed to Init FreeType: %d\n", err); + PERROR("FT_Init_FreeType failed err: %d\n", err); goto _err_done_malloc; } - err = FT_New_Face(fft->library, filename, 0, &fft->face); - if (err) + err = FTC_Manager_New(ttf->library, 0, 0, 0, ftc_face_requester, 0, &ttf->manager); + if (err != 0) { - PERROR("failed to New Face: %d\n", err); + PERROR("FTC_Manager_New failed!\n"); goto _err_done_init; } - err = FT_Select_Charmap(fft->face, FT_ENCODING_UNICODE); - if (err) + err = FTC_CMapCache_New(ttf->manager, &ttf->cmap_cache); + if (err != 0) { - err = FT_Select_Charmap(fft->face, FT_ENCODING_ADOBE_LATIN_1); + PERROR("FTC_CMapCache_New failed!\n"); + goto _err_done_manager; } - err = FT_Set_Pixel_Sizes(fft->face, 0, size); + err = FTC_SBitCache_New(ttf->manager, &ttf->sbit_cache); if (err != 0) { - PERROR("failed to set Pixel Size: %d\n", err); - goto _err_done_face; + PERROR("FTC_SBitCache_New failed!\n"); + goto _err_done_manager; + } + + ttf->refer_count = 1; + + rtgui_ttf_system_add_ttf(ttf); + + return ttf; + +_err_done_manager: + FTC_Manager_Done(ttf->manager); +_err_done_init: + FT_Done_FreeType(ttf->library); +_err_done_malloc: + rt_free((void *)ttf->face_id.pathname); + rtgui_free(ttf); + + return RT_NULL; +} +RTM_EXPORT(rtgui_ttf_load); + +rtgui_font_t *rtgui_freetype_font_create(const char *filename, rt_size_t size) +{ + struct rtgui_font *font; + struct rtgui_ttf_font *ttf_font; + struct rtgui_ttf *ttf; + + ttf = rtgui_ttf_refer(filename); + if (!ttf) + { + PERROR("rtgui_ttf_refer failed!\n"); + + ttf = rtgui_ttf_load(filename); + if (!ttf) + { + PERROR("rtgui_ttf_load failed!\n"); + return RT_NULL; + } + } + + font = (struct rtgui_font *)rtgui_malloc(sizeof(struct rtgui_font) + sizeof(struct rtgui_ttf_font)); + if (!font) + { + PERROR("rtgui_ttf_load rtgui_malloc failed!\n"); + return RT_NULL; } - fft->bold = bold; - fft->italic = italic; + ttf_font = (struct rtgui_ttf_font *)(font + 1); + font->data = ttf_font; + + ttf_font->ttf = ttf; - PINFO("fonfile:%s\n", filename); - PINFO("font family_name:%s\n", fft->face->family_name); - PINFO("font style_name:%s\n", fft->face->style_name); - PINFO("%s kerneling\n", FT_HAS_KERNING(fft->face) ? "has" : "not has"); + /* image_type_rec init */ + ttf_font->image_type_rec.face_id = &ttf_font->ttf->face_id; + ttf_font->image_type_rec.width = size; + ttf_font->image_type_rec.height = size; + ttf_font->image_type_rec.flags = FT_LOAD_RENDER | FT_LOAD_NO_HINTING; /* set user data */ - font->family = rt_strdup(fft->face->family_name); - font->height = (rt_uint16_t)size; + font->family = (char *)(ttf_font->ttf->face_id.pathname); + font->height = (rt_uint16_t)ttf_font->image_type_rec.height; font->refer_count = 1; - font->engine = &ftf_engine; + font->engine = &ftc_engine; /* add to system */ rtgui_font_system_add_font(font); return font; - -_err_done_face: - FT_Done_Face(fft->face); -_err_done_init: - FT_Done_FreeType(fft->library); -_err_done_malloc: - rtgui_free(font); - - return RT_NULL; } RTM_EXPORT(rtgui_freetype_font_create); void rtgui_freetype_font_destroy(rtgui_font_t *font) { - struct rtgui_freetype2_font *fft; + struct rtgui_ttf_font *ttf_font; RT_ASSERT(font != RT_NULL); - fft = (struct rtgui_freetype2_font *) font->data; - RT_ASSERT(fft != RT_NULL); + ttf_font = (struct rtgui_ttf_font *) font->data; + RT_ASSERT(ttf_font != RT_NULL); rtgui_font_system_remove_font(font); - FT_Done_Face(fft->face); - FT_Done_FreeType(fft->library); - rt_free(font->family); + rtgui_ttf_derefer(ttf_font->ttf); + + if (ttf_font->ttf->refer_count == 0) + { + FTC_Manager_Done(ttf_font->ttf->manager); + FT_Done_FreeType(ttf_font->ttf->library); + rt_free(font->family); + } + rtgui_free(font); } RTM_EXPORT(rtgui_freetype_font_destroy); #ifdef RT_USING_FINSH #include -FINSH_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 diff --git a/components/gui/src/font_hz_bmp.c b/components/gui/src/font_hz_bmp.c index 9bef2c248063e0f7dc7efdddf7bf77c815393815..e58225e74675d0c2afd9d77e92ad23929e442e7f 100644 --- a/components/gui/src/font_hz_bmp.c +++ b/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 #include diff --git a/components/gui/src/font_hz_file.c b/components/gui/src/font_hz_file.c index 811fffb63de6ab79f11d5b800f61db9042c94409..1f453901f1ac154c4175922a96c162345991ea20 100644 --- a/components/gui/src/font_hz_file.c +++ b/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 */ diff --git a/components/gui/src/hz12font.c b/components/gui/src/hz12font.c index 550bc880ad88c0e25878052ffe0957de6f17ccf1..e71c995a7d4c3dd8fbc4c71203b1bbc09c50d4af 100644 --- a/components/gui/src/hz12font.c +++ b/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 #if defined(RTGUI_USING_FONT12) && defined(RTGUI_USING_FONTHZ) diff --git a/components/gui/src/hz16font.c b/components/gui/src/hz16font.c index dce1833a4e8695ad9ee2f1a82769f61244cf8c79..a670867a4b0d2b205d68da59521ed501a340e707 100644 --- a/components/gui/src/hz16font.c +++ b/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 #if defined(RTGUI_USING_FONT16) && defined(RTGUI_USING_FONTHZ) diff --git a/components/gui/src/image.c b/components/gui/src/image.c index 43fe29d79fe4f9edb52b469b1806a9b2801bb9ed..e8ab6c00a2b2bc269daa1d482edea09e8d3723c1 100644 --- a/components/gui/src/image.c +++ b/components/gui/src/image.c @@ -1,11 +1,21 @@ /* * File : image.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -18,6 +28,7 @@ #include #include +#include #include #ifdef _WIN32 @@ -25,17 +36,18 @@ #endif #ifdef RTGUI_IMAGE_XPM -#include +extern void rtgui_image_xpm_init(void); #endif #ifdef RTGUI_IMAGE_BMP #include #endif + #if (defined(RTGUI_IMAGE_JPEG) || defined(RTGUI_IMAGE_TJPGD)) -#include +extern void rtgui_image_jpeg_init(void); #endif #if defined(RTGUI_IMAGE_PNG) || defined(RTGUI_IMAGE_LODEPNG) -#include +extern void rtgui_image_png_init(void); #endif static rtgui_list_t _rtgui_system_image_list = {RT_NULL}; @@ -61,6 +73,11 @@ void rtgui_system_image_init(void) #if defined(RTGUI_IMAGE_PNG) || defined(RTGUI_IMAGE_LODEPNG) rtgui_image_png_init(); #endif + +#ifdef RTGUI_IMAGE_CONTAINER + /* initialize image container */ + rtgui_system_image_container_init(); +#endif } static struct rtgui_image_engine *rtgui_image_get_engine(const char *type) @@ -166,7 +183,7 @@ struct rtgui_image *rtgui_image_create(const char *filename, rt_bool_t load) /* create filerw context */ filerw = rtgui_filerw_create_file(filename, "rb"); - if (filerw == RT_NULL) + if (filerw == RT_NULL) { rt_kprintf("create filerw failed!\n"); return RT_NULL; @@ -287,18 +304,18 @@ RTM_EXPORT(rtgui_image_register_engine); void rtgui_image_blit(struct rtgui_image *image, struct rtgui_dc *dc, struct rtgui_rect *rect) { - struct rtgui_rect r; + struct rtgui_rect r; RT_ASSERT(dc != RT_NULL); if (rtgui_dc_get_visible(dc) != RT_TRUE) return; rtgui_dc_get_rect(dc, &r); - /* use rect of DC */ - if (rect == RT_NULL) - { - rect = &r; - } + /* use rect of DC */ + if (rect == RT_NULL) + { + rect = &r; + } else { /* Don't modify x1, y1, they are handled in engine->image_blit. */ diff --git a/components/gui/src/image_bmp.c b/components/gui/src/image_bmp.c index 09765e7629fd7900b80de0bfcae0688a8a0fd5e1..a496b9261f2a1d66c9fffb51a8d55607e735c3a5 100644 --- a/components/gui/src/image_bmp.c +++ b/components/gui/src/image_bmp.c @@ -1,4 +1,22 @@ /* + * File : image_bmp.c + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * * Change Logs: * Date Author Notes * 2012-01-24 onelife Reimplement to improve efficiency and add @@ -6,7 +24,7 @@ * provides scaledown function. */ #include -#include +#include #include #include #include @@ -127,7 +145,7 @@ static struct rtgui_image_palette *rtgui_image_bmp_load_palette( return RT_NULL; } - palette->ncolors = colorsUsed; + palette->ncolors = colorsUsed; if (alpha) { rt_uint8_t temp[4]; @@ -506,7 +524,7 @@ static void rtgui_image_bmp_blit(struct rtgui_image *image, struct rtgui_dc *dc, bytePerPixel = _UI_BITBYTES(bmp->bit_per_pixel); - imageWidth = image->w * bytePerPixel; /* Scaled width in byte */ + imageWidth = image->w * bytePerPixel; /* Scaled width in byte */ error = RT_FALSE; do @@ -515,8 +533,8 @@ static void rtgui_image_bmp_blit(struct rtgui_image *image, struct rtgui_dc *dc, if (rtgui_dc_get_visible(dc) != RT_TRUE) break; /* the minimum rect */ - w = _UI_MIN(image->w, rtgui_rect_width(*dst_rect)); - h = _UI_MIN(image->h, rtgui_rect_height(*dst_rect)); + w = _UI_MIN(image->w, rtgui_rect_width(*dst_rect)); + h = _UI_MIN(image->h, rtgui_rect_height(*dst_rect)); if (!bmp->is_loaded) { @@ -744,53 +762,53 @@ static void rtgui_image_bmp_blit(struct rtgui_image *image, struct rtgui_dc *dc, rt_uint16_t x, y; rt_uint8_t *ptr; - if (bmp->bit_per_pixel <= 8) - { - rtgui_color_t color; + if (bmp->bit_per_pixel <= 8) + { + rtgui_color_t color; - /* 1bpp, and using palette */ - for (y = 0; y < h; y ++) - { + /* 1bpp, and using palette */ + for (y = 0; y < h; y ++) + { ptr = bmp->pixels + (y * imageWidth); - for (x = 0; x < w; x ++) - { - color = image->palette->colors[*(ptr++)]; - rtgui_dc_draw_color_point(dc, - dst_rect->x1 + x, dst_rect->y1 + y, - color); - } - } - } - else - { - rtgui_blit_line_func blit_line; - rt_uint8_t hw_bytePerPixel = _UI_BITBYTES(hw_driver->bits_per_pixel); - rt_uint8_t *line_data; - - if (hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_BGR565) - { - blit_line = rtgui_blit_line_get_inv(hw_bytePerPixel, bytePerPixel); - } - else - { - blit_line = rtgui_blit_line_get(hw_bytePerPixel, bytePerPixel); - } - - line_data = (rt_uint8_t *)rtgui_malloc(w * rtgui_color_get_bpp(hw_driver->pixel_format)); - if (line_data == RT_NULL) break; /* out of memory */ - - ptr = bmp->pixels; - for (y = 0; y < h; y ++) - { - blit_line(line_data, ptr, bytePerPixel * w); - ptr += imageWidth; - - dc->engine->blit_line(dc, dst_rect->x1, dst_rect->x1 + w, - dst_rect->y1 + y, line_data); - } - - rtgui_free(line_data); - } + for (x = 0; x < w; x ++) + { + color = image->palette->colors[*(ptr++)]; + rtgui_dc_draw_color_point(dc, + dst_rect->x1 + x, dst_rect->y1 + y, + color); + } + } + } + else + { + rtgui_blit_line_func blit_line; + rt_uint8_t hw_bytePerPixel = _UI_BITBYTES(hw_driver->bits_per_pixel); + rt_uint8_t *line_data; + + if (hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_BGR565) + { + blit_line = rtgui_blit_line_get_inv(hw_bytePerPixel, bytePerPixel); + } + else + { + blit_line = rtgui_blit_line_get(hw_bytePerPixel, bytePerPixel); + } + + line_data = (rt_uint8_t *)rtgui_malloc(w * rtgui_color_get_bpp(hw_driver->pixel_format)); + if (line_data == RT_NULL) break; /* out of memory */ + + ptr = bmp->pixels; + for (y = 0; y < h; y ++) + { + blit_line(line_data, ptr, bytePerPixel * w); + ptr += imageWidth; + + dc->engine->blit_line(dc, dst_rect->x1, dst_rect->x1 + w, + dst_rect->y1 + y, line_data); + } + + rtgui_free(line_data); + } } } while (0); } diff --git a/components/gui/src/image_container.c b/components/gui/src/image_container.c new file mode 100644 index 0000000000000000000000000000000000000000..66b7191271428b728fdd3a44b5cf652db27c7e7f --- /dev/null +++ b/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 +#include + +/* + * 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 + diff --git a/components/gui/src/image_hdc.c b/components/gui/src/image_hdc.c index cd8b17192bc6a801184370aecf6ef3057877f8e0..b82a10625bfc452dd39cfbc8c87858edc3603e5f 100644 --- a/components/gui/src/image_hdc.c +++ b/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 -#include +#include #include #include #include @@ -9,21 +32,6 @@ extern int fastlz_decompress(const void *input, int length, void *output, int maxout); -struct rtgui_image_hdc -{ - rt_bool_t is_loaded; - - /* hdc image information */ - rt_uint16_t byte_per_pixel; - rt_uint16_t pitch; - rt_uint8_t pixel_format; - - rt_size_t pixel_offset; - rt_uint8_t *pixels; - - struct rtgui_filerw *filerw; -}; - static rt_bool_t rtgui_image_hdc_check(struct rtgui_filerw *file); static rt_bool_t rtgui_image_hdc_load(struct rtgui_image *image, struct rtgui_filerw *file, rt_bool_t load); static void rtgui_image_hdc_unload(struct rtgui_image *image); @@ -257,112 +265,17 @@ static void rtgui_image_hdc_blit(struct rtgui_image *image, if (hdc->pixels != RT_NULL) { - rt_uint8_t *ptr; - - /* get pixel pointer */ - ptr = hdc->pixels + hdc->pitch * yoff + hdc->byte_per_pixel * xoff; - - if (hdc->pixel_format == rtgui_dc_get_pixel_format(dc) && - hdc->pixel_format != RTGRAPHIC_PIXEL_FORMAT_ARGB888) - { - for (y = 0; y < h; y ++) - { - dc->engine->blit_line(dc, - dst_rect->x1, - dst_rect->x1 + w, - dst_rect->y1 + y, - ptr); - ptr += hdc->pitch; - } - } - else if (dc->type == RTGUI_DC_CLIENT) - { - const struct rtgui_graphic_driver *hw_driver; - struct rtgui_widget *owner = RTGUI_CONTAINER_OF(dc, struct rtgui_widget, dc_type); + struct rtgui_image_info info; + struct rtgui_rect dest = *dst_rect; + info.a = 255; + info.pixels = hdc->pixels + hdc->pitch * yoff + hdc->byte_per_pixel * xoff; + info.src_fmt = hdc->pixel_format; + info.src_pitch = hdc->pitch; - hw_driver = rtgui_graphic_driver_get_default(); - if (hdc->pixel_format == RTGRAPHIC_PIXEL_FORMAT_ARGB888) - { - rt_uint8_t alpha; - - for (y = 0; y < h; y ++) - { - int x; - - rtgui_color_t *pixel = (rtgui_color_t *)(hdc->pixels + hdc->pitch * (yoff + y) + hdc->byte_per_pixel * xoff); - - for (x = 0; x < w; x ++) - { - alpha = RTGUI_RGB_A(*pixel); - - if (alpha == 0) { } - if (alpha == 0xff) - { - rtgui_dc_draw_color_point(dc, dst_rect->x1 + x, dst_rect->y1 + y, *pixel); - } - else - { - /* draw an alpha blending point */ - if (hw_driver->framebuffer != RT_NULL) - rtgui_dc_blend_point(dc, dst_rect->x1 + x, dst_rect->y1 + y, RTGUI_BLENDMODE_BLEND, - RTGUI_RGB_R(*pixel), RTGUI_RGB_G(*pixel), RTGUI_RGB_B(*pixel), RTGUI_RGB_A(*pixel)); - } - - pixel ++; - } - } - } - } - else - { - struct rtgui_blit_info info; - info.a = 0; - - /* initialize source blit information */ - info.src = ptr; - info.src_h = h; - info.src_w = w; - info.src_fmt = hdc->pixel_format; - info.src_pitch = hdc->pitch; - info.src_skip = hdc->pitch - w * rtgui_color_get_bpp(hdc->pixel_format); - - /* initialize destination blit information */ - if (dc->type == RTGUI_DC_BUFFER) - { - struct rtgui_dc_buffer *buffer; - buffer = (struct rtgui_dc_buffer *)dc; - - info.dst = rtgui_dc_buffer_get_pixel(RTGUI_DC(buffer)) + dst_rect->y1 * buffer->pitch + - dst_rect->x1 * rtgui_color_get_bpp(buffer->pixel_format); - info.dst_h = h; - info.dst_w = w; - info.dst_fmt = buffer->pixel_format; - info.dst_pitch = buffer->pitch; - info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(buffer->pixel_format); - } - else if (dc->type == RTGUI_DC_HW) - { - struct rtgui_widget *owner; - struct rtgui_rect r; - struct rtgui_dc_hw *ddc = (struct rtgui_dc_hw *)dc; - - owner = ((struct rtgui_dc_hw *)dc)->owner; - - rtgui_graphic_driver_get_rect(RT_NULL, &r); - - /* blit destination */ - info.dst = (rt_uint8_t *)ddc->hw_driver->framebuffer; - info.dst = info.dst + (owner->extent.y1 + dst_rect->y1) * ddc->hw_driver->pitch + - (owner->extent.x1 + dst_rect->x1) * rtgui_color_get_bpp(ddc->hw_driver->pixel_format); - info.dst_fmt = ddc->hw_driver->pixel_format; - info.dst_h = h; - info.dst_w = w; - info.dst_pitch = ddc->hw_driver->pitch; - info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(ddc->hw_driver->pixel_format); - } + dest.x2 = dst_rect->x1 + w; + dest.y2 = dst_rect->y1 + h; - rtgui_blit(&info); - } + rtgui_image_info_blit(&info, dc, &dest); } else { diff --git a/components/gui/src/image_jpg.c b/components/gui/src/image_jpg.c index 0bb82921ad6280b381f15586d9125c7db0327f4b..c7ba06498d19c3f82d15caa5353d3b591d28b488 100644 --- a/components/gui/src/image_jpg.c +++ b/components/gui/src/image_jpg.c @@ -1,6 +1,25 @@ /* + * File : image_jpg.c + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * * Change Logs: * Date Author Notes + * 2010-09-15 Bernard first version * 2012-01-24 onelife add TJpgDec (Tiny JPEG Decompressor) support */ #include @@ -13,7 +32,6 @@ #include #include -#include #include #ifdef RTGUI_USING_DFS_FILERW @@ -403,61 +421,61 @@ static void rtgui_image_jpeg_blit(struct rtgui_image *image, struct rtgui_dc *dc { ptr = (rtgui_color_t *) jpeg->pixels; - if (dc->type == RTGUI_DC_BUFFER) - { - /* blit ARGB888 to this buffered DC */ - int dst_x, dst_y; - int w, h; - struct rtgui_blit_info info; - struct rtgui_dc_buffer *buffer = (struct rtgui_dc_buffer*)dc; - - w = _UI_MIN(image->w, rtgui_rect_width(*rect)); - h = _UI_MIN(image->h, rtgui_rect_height(*rect)); - - info.a = 0; - - /* initialize source blit information */ - info.src_fmt = RTGRAPHIC_PIXEL_FORMAT_ARGB888;; - info.src_h = h; - info.src_w = w; - info.src_pitch = image->w * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888); - info.src_skip = info.src_pitch - w * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888); - info.src = (rt_uint8_t *)image->data + y * info.src_pitch + x * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888); - - if (rect->x1 < 0) dst_x = 0; - else dst_x = rect->x1; - if (rect->y1 < 0) dst_y = 0; - else dst_y = rect->y1; - - /* initialize destination blit information */ - info.dst = rtgui_dc_buffer_get_pixel(RTGUI_DC(buffer)) + dst_y * buffer->pitch + - dst_x * rtgui_color_get_bpp(buffer->pixel_format); - info.dst_h = h; - info.dst_w = w; - info.dst_fmt = buffer->pixel_format; - info.dst_pitch = buffer->pitch; - info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(buffer->pixel_format); - - rtgui_blit(&info); - } - else - { - /* draw each point within dc */ - for (y = 0; y < image->h; y ++) - { - for (x = 0; x < image->w; x++) - { - /* not alpha */ - if ((*ptr >> 24) != 255) - { - rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, *ptr); - } - - /* move to next color buffer */ - ptr ++; - } - } - } + if (dc->type == RTGUI_DC_BUFFER) + { + /* blit ARGB888 to this buffered DC */ + int dst_x, dst_y; + int w, h; + struct rtgui_blit_info info; + struct rtgui_dc_buffer *buffer = (struct rtgui_dc_buffer*)dc; + + w = _UI_MIN(image->w, rtgui_rect_width(*rect)); + h = _UI_MIN(image->h, rtgui_rect_height(*rect)); + + info.a = 0; + + /* initialize source blit information */ + info.src_fmt = RTGRAPHIC_PIXEL_FORMAT_ARGB888;; + info.src_h = h; + info.src_w = w; + info.src_pitch = image->w * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888); + info.src_skip = info.src_pitch - w * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888); + info.src = (rt_uint8_t *)image->data + y * info.src_pitch + x * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888); + + if (rect->x1 < 0) dst_x = 0; + else dst_x = rect->x1; + if (rect->y1 < 0) dst_y = 0; + else dst_y = rect->y1; + + /* initialize destination blit information */ + info.dst = rtgui_dc_buffer_get_pixel(RTGUI_DC(buffer)) + dst_y * buffer->pitch + + dst_x * rtgui_color_get_bpp(buffer->pixel_format); + info.dst_h = h; + info.dst_w = w; + info.dst_fmt = buffer->pixel_format; + info.dst_pitch = buffer->pitch; + info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(buffer->pixel_format); + + rtgui_blit(&info); + } + else + { + /* draw each point within dc */ + for (y = 0; y < image->h; y ++) + { + for (x = 0; x < image->w; x++) + { + /* not alpha */ + if ((*ptr >> 24) != 255) + { + rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, *ptr); + } + + /* move to next color buffer */ + ptr ++; + } + } + } } else { @@ -606,9 +624,9 @@ struct rtgui_image_jpeg rt_uint16_t dst_x, dst_y; rt_uint16_t dst_w, dst_h; rt_bool_t is_loaded; - rt_uint8_t byte_per_pixel; + rt_uint8_t byte_per_pixel; - JDEC tjpgd; /* jpeg structure */ + JDEC tjpgd; /* jpeg structure */ void *pool; rt_uint8_t *pixels; }; @@ -699,9 +717,9 @@ static UINT tjpgd_out_func(JDEC *jdec, void *bitmap, JRECT *rect) if (rect->left > jpeg->dst_w) return 1; if (rect->top > jpeg->dst_h) return 0; - w = _UI_MIN(rect->right, jpeg->dst_w); + w = _UI_MIN(rect->right, jpeg->dst_w); w = w - rect->left + 1; - h = _UI_MIN(rect->bottom, jpeg->dst_h); + h = _UI_MIN(rect->bottom, jpeg->dst_h); h = h - rect->top + 1; for (y = 0; y < h; y++) @@ -718,15 +736,15 @@ static UINT tjpgd_out_func(JDEC *jdec, void *bitmap, JRECT *rect) static rt_bool_t rtgui_image_jpeg_check(struct rtgui_filerw *file) { - rt_uint8_t soi[2]; - rtgui_filerw_seek(file, 0, RTGUI_FILE_SEEK_SET); - rtgui_filerw_read(file, &soi, 2, 1); - rtgui_filerw_seek(file, 0, RTGUI_FILE_SEEK_SET); + rt_uint8_t soi[2]; + rtgui_filerw_seek(file, 0, RTGUI_FILE_SEEK_SET); + rtgui_filerw_read(file, &soi, 2, 1); + rtgui_filerw_seek(file, 0, RTGUI_FILE_SEEK_SET); - /* check SOI==FFD8 */ - if (soi[0] == 0xff && soi[1] == 0xd8) return RT_TRUE; + /* check SOI==FFD8 */ + if (soi[0] == 0xff && soi[1] == 0xd8) return RT_TRUE; - return RT_FALSE; + return RT_FALSE; } static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image *image, struct rtgui_filerw *file, rt_bool_t load) @@ -734,7 +752,7 @@ static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image *image, struct rtgui_f rt_bool_t res = RT_FALSE; struct rtgui_image_jpeg *jpeg; JRESULT ret; - struct rtgui_graphic_driver *hw_driver; + struct rtgui_graphic_driver *hw_driver; do { @@ -745,7 +763,7 @@ static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image *image, struct rtgui_f jpeg->is_loaded = load; jpeg->pixels = RT_NULL; - /* allocate memory pool */ + /* allocate memory pool */ jpeg->pool = rt_malloc(TJPGD_WORKING_BUFFER_SIZE); if (jpeg->pool == RT_NULL) { @@ -769,15 +787,15 @@ static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image *image, struct rtgui_f break; } - /* use RGB565 format */ - hw_driver = rtgui_graphic_driver_get_default(); - if (hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565) - { - jpeg->tjpgd.format = 1; - jpeg->byte_per_pixel = 2; - } - /* else use RGB888 format */ - else jpeg->byte_per_pixel = 3; + /* use RGB565 format */ + hw_driver = rtgui_graphic_driver_get_default(); + if (hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565) + { + jpeg->tjpgd.format = 1; + jpeg->byte_per_pixel = 2; + } + /* else use RGB888 format */ + else jpeg->byte_per_pixel = 3; image->w = (rt_uint16_t)jpeg->tjpgd.width; image->h = (rt_uint16_t)jpeg->tjpgd.height; @@ -800,7 +818,7 @@ static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image *image, struct rtgui_f if (ret != JDR_OK) break; rtgui_filerw_close(jpeg->filerw); - jpeg->filerw = RT_NULL; + jpeg->filerw = RT_NULL; } res = RT_TRUE; } while (0); @@ -808,7 +826,7 @@ static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image *image, struct rtgui_f if (jpeg && (!res || jpeg->is_loaded)) { rt_free(jpeg->pool); - jpeg->pool = RT_NULL; + jpeg->pool = RT_NULL; } if (!res) @@ -817,8 +835,8 @@ static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image *image, struct rtgui_f rtgui_free(jpeg->pixels); rt_free(jpeg); - image->data = RT_NULL; - image->engine = RT_NULL; + image->data = RT_NULL; + image->engine = RT_NULL; } /* create jpeg image successful */ @@ -882,7 +900,7 @@ static void rtgui_image_jpeg_blit(struct rtgui_image *image, h = _UI_MIN(image->h - yoff, rtgui_rect_height(*dst_rect)); if (rtgui_dc_get_pixel_format(dc) == RTGRAPHIC_PIXEL_FORMAT_RGB888 && - jpeg->tjpgd.format != 0) + jpeg->tjpgd.format != 0) { jpeg->tjpgd.format = 0; jpeg->byte_per_pixel = 3; @@ -910,7 +928,7 @@ static void rtgui_image_jpeg_blit(struct rtgui_image *image, else { if ((rtgui_dc_get_pixel_format(dc) == RTGRAPHIC_PIXEL_FORMAT_RGB888 && jpeg->tjpgd.format == 0) || - (rtgui_dc_get_pixel_format(dc) == RTGRAPHIC_PIXEL_FORMAT_RGB565 && jpeg->tjpgd.format == 1)) + (rtgui_dc_get_pixel_format(dc) == RTGRAPHIC_PIXEL_FORMAT_RGB565 && jpeg->tjpgd.format == 1)) { rt_uint16_t imageWidth = image->w * jpeg->byte_per_pixel; rt_uint8_t *src = jpeg->pixels + yoff * imageWidth + xoff + jpeg->byte_per_pixel; @@ -940,7 +958,7 @@ static void rtgui_image_jpeg_blit(struct rtgui_image *image, info.src_skip = info.src_pitch - info.src_w * jpeg->byte_per_pixel; info.dst = rtgui_dc_buffer_get_pixel(RTGUI_DC(buffer)) + dst_rect->y1 * buffer->pitch + - dst_rect->x1 * rtgui_color_get_bpp(buffer->pixel_format); + dst_rect->x1 * rtgui_color_get_bpp(buffer->pixel_format); info.dst_h = rtgui_rect_height(*dst_rect); info.dst_w = rtgui_rect_width(*dst_rect); info.dst_fmt = buffer->pixel_format; diff --git a/components/gui/src/image_png.c b/components/gui/src/image_png.c index 9797d874884cdb5218a5d68698af34dbc37ebfa4..4d5512bf24c906ee8a568c32ab4d6021dfc8f394 100644 --- a/components/gui/src/image_png.c +++ b/components/gui/src/image_png.c @@ -1,11 +1,34 @@ -#include +/* + * 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 #include #include #include #ifdef RTGUI_IMAGE_PNG #include "png.h" -#include #define PNG_MAGIC_LEN 8 @@ -139,7 +162,7 @@ static rt_bool_t rtgui_image_png_check(struct rtgui_filerw *file) static void _image_png_error_fn(png_structp png_ptr, png_const_charp error_message) { - rt_kprintf(error_message); + rt_kprintf(error_message); } static rt_bool_t rtgui_image_png_load(struct rtgui_image *image, struct rtgui_filerw *file, rt_bool_t load) @@ -158,8 +181,8 @@ static rt_bool_t rtgui_image_png_load(struct rtgui_image *image, struct rtgui_fi rtgui_free(png); return RT_FALSE; } - png_set_error_fn(png->png_ptr, RT_NULL, _image_png_error_fn, _image_png_error_fn); - + png_set_error_fn(png->png_ptr, RT_NULL, _image_png_error_fn, _image_png_error_fn); + png->info_ptr = png_create_info_struct(png->png_ptr); if (png->info_ptr == RT_NULL) { @@ -169,7 +192,7 @@ static rt_bool_t rtgui_image_png_load(struct rtgui_image *image, struct rtgui_fi } png->filerw = file; - png->is_loaded = RT_FALSE; + png->is_loaded = RT_FALSE; png_set_read_fn(png->png_ptr, png->filerw, rtgui_image_png_read_data); png_read_info(png->png_ptr, png->info_ptr); @@ -220,11 +243,11 @@ static rt_bool_t rtgui_image_png_load(struct rtgui_image *image, struct rtgui_fi } rtgui_image_png_process(png->png_ptr, png->info_ptr, png); - png_read_end(png->png_ptr, RT_NULL); - png->is_loaded = RT_TRUE; - /* close file handler */ - rtgui_filerw_close(png->filerw); - png->filerw = RT_NULL; + png_read_end(png->png_ptr, RT_NULL); + png->is_loaded = RT_TRUE; + /* close file handler */ + rtgui_filerw_close(png->filerw); + png->filerw = RT_NULL; } else { @@ -271,8 +294,8 @@ static void rtgui_image_png_blit(struct rtgui_image *image, struct rtgui_dc *dc, png = (struct rtgui_image_png *) image->data; - w = _UI_MIN(image->w, rtgui_rect_width(*rect)); - h = _UI_MIN(image->h, rtgui_rect_height(*rect)); + w = _UI_MIN(image->w, rtgui_rect_width(*rect)); + h = _UI_MIN(image->h, rtgui_rect_height(*rect)); fg_maxsample = (1 << png->info_ptr->bit_depth) - 1; @@ -340,19 +363,19 @@ static void rtgui_image_png_blit(struct rtgui_image *image, struct rtgui_dc *dc, switch (png->info_ptr->color_type) { - case PNG_COLOR_TYPE_RGB: - for (y = 0; y < h; y++) - { - png_read_row(png->png_ptr, row, png_bytep_NULL); - for (x = 0; x < w; x++) - { - data = &(row[x * 3]); - rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, - RTGUI_RGB(data[0], data[1], data[2])); - } - } - break; - + case PNG_COLOR_TYPE_RGB: + for (y = 0; y < h; y++) + { + png_read_row(png->png_ptr, row, png_bytep_NULL); + for (x = 0; x < w; x++) + { + data = &(row[x * 3]); + rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, + RTGUI_RGB(data[0], data[1], data[2])); + } + } + break; + case PNG_COLOR_TYPE_RGBA: for (y = 0; y < h; y++) { @@ -452,7 +475,7 @@ static rt_bool_t rtgui_image_png_load(struct rtgui_image *image, struct rtgui_fi unsigned int width; unsigned int height; unsigned int error; - + rt_uint8_t* pixel; rt_uint8_t* in; rt_uint32_t in_size; @@ -468,13 +491,13 @@ static rt_bool_t rtgui_image_png_load(struct rtgui_image *image, struct rtgui_fi rtgui_filerw_seek(file, 0, SEEK_SET); rtgui_filerw_read(file, in, in_size, 1); - error = lodepng_decode32(&pixel, &width, &height, in, in_size); - if(error) - { - rt_kprintf("error %u: %s\n", error, lodepng_error_text(error)); - rtgui_free(in); - return RT_FALSE; - } + error = lodepng_decode32(&pixel, &width, &height, in, in_size); + if(error) + { + rt_kprintf("error %u: %s\n", error, lodepng_error_text(error)); + rtgui_free(in); + return RT_FALSE; + } rtgui_free(in); @@ -484,24 +507,24 @@ static rt_bool_t rtgui_image_png_load(struct rtgui_image *image, struct rtgui_fi image->engine = &rtgui_image_png_engine; image->data = pixel; - /* NOTE: the pixel format of PNG is ABGR888, bit0 R,G,B,A bit31 */ - /* convert pixel to ARGB888, swap B/G */ - { - rt_uint8_t* pixel_ptr; - rt_uint8_t* pixel_end; + /* NOTE: the pixel format of PNG is ABGR888, bit0 R,G,B,A bit31 */ + /* convert pixel to ARGB888, swap B/G */ + { + rt_uint8_t* pixel_ptr; + rt_uint8_t* pixel_end; - pixel_ptr = (rt_uint8_t*) pixel; - pixel_end = pixel_ptr + width * height * 4; + pixel_ptr = (rt_uint8_t*) pixel; + pixel_end = pixel_ptr + width * height * 4; - while (pixel_ptr < pixel_end) - { - pixel_ptr[0] = pixel_ptr[0] ^ pixel_ptr[2]; - pixel_ptr[2] = pixel_ptr[0] ^ pixel_ptr[2]; - pixel_ptr[0] = pixel_ptr[0] ^ pixel_ptr[2]; + while (pixel_ptr < pixel_end) + { + pixel_ptr[0] = pixel_ptr[0] ^ pixel_ptr[2]; + pixel_ptr[2] = pixel_ptr[0] ^ pixel_ptr[2]; + pixel_ptr[0] = pixel_ptr[0] ^ pixel_ptr[2]; - pixel_ptr += 4; - } - } + pixel_ptr += 4; + } + } /* close file handler */ rtgui_filerw_close(file); @@ -518,159 +541,169 @@ static void rtgui_image_png_unload(struct rtgui_image *image) pixels = (rt_uint8_t*) image->data; /* release data */ - rtgui_free(pixels); + //rtgui_free(pixels); + free(pixels); } } static void rtgui_image_png_blit(struct rtgui_image *image, struct rtgui_dc *dc, struct rtgui_rect *rect) { - int x, y; + int x, y; int w, h; - struct rtgui_blit_info info; - struct rtgui_graphic_driver *hw_driver = rtgui_graphic_driver_get_default(); + struct rtgui_blit_info info; + struct rtgui_graphic_driver *hw_driver = rtgui_graphic_driver_get_default(); RT_ASSERT(image != RT_NULL && dc != RT_NULL && rect != RT_NULL); RT_ASSERT(image->data != RT_NULL); #define blending(s, d, a) (((unsigned)(((s) - (d)) * (a)) >> 8) + (d)) - /* this dc is not visible */ - if (rtgui_dc_get_visible(dc) != RT_TRUE) return; - - w = _UI_MIN(image->w, rtgui_rect_width(*rect)); - h = _UI_MIN(image->h, rtgui_rect_height(*rect)); - - /* border checking */ - if (rect->x1 < 0) { x = -rect->x1; w += rect->x1; } - else x = 0; - - if (rect->y1 < 0) { y = -rect->y1; h += rect->y1; } - else y = 0; - - if (w < 0 || h < 0) return; /* no drawing */ - - if ((dc->type == RTGUI_DC_CLIENT) || (dc->type == RTGUI_DC_HW && hw_driver->framebuffer == RT_NULL)) - { - int dx, dy, start_x; - rtgui_rect_t r; - rtgui_color_t *pixel; - rt_uint8_t alpha; - rtgui_widget_t *owner = RT_NULL; - - if (dc->type == RTGUI_DC_CLIENT) - { - /* get owner and calculate dx,dy */ - owner = RTGUI_CONTAINER_OF(dc, struct rtgui_widget, dc_type); - dx = owner->extent.x1; dy = owner->extent.y1; - } - else - { - /* hardware DC */ - struct rtgui_dc_hw *hw = (struct rtgui_dc_hw *) dc; - dx = hw->owner->extent.x1; - dy = hw->owner->extent.y1; - } - - start_x = x; - for (; y < rect->y1 + h; ++y) - { - for (x = start_x; x < rect->x1 + w; ++x) - { - pixel = (rtgui_color_t*)((rt_uint8_t*)image->data + (y - rect->y1) * image->w * 4 + - (x - rect->x1) * 4); - - alpha = RTGUI_RGB_A(*pixel); - if (alpha == 0) continue; - if (alpha == 0xff) - { - rtgui_dc_draw_color_point(dc, x, y, *pixel); - } - else - { - rtgui_color_t bc, fc; - - /* draw an alpha blending point */ - if (hw_driver->framebuffer != RT_NULL) - rtgui_dc_blend_point(dc, x, y, RTGUI_BLENDMODE_BLEND, - RTGUI_RGB_R(*pixel), RTGUI_RGB_G(*pixel), RTGUI_RGB_B(*pixel), RTGUI_RGB_A(*pixel)); - else - { - x = x + dx; - y = y + dy; - - if (dc->type == RTGUI_DC_CLIENT) - { - if (rtgui_region_contains_point(&(owner->clip), x, y, &r) != RT_EOK) - continue ; - } - - /* get background pixel */ - hw_driver->ops->get_pixel(&bc, x, y); - /* alpha blending */ - fc = RTGUI_RGB(blending(RTGUI_RGB_R(bc), RTGUI_RGB_R(*pixel), alpha), - blending(RTGUI_RGB_G(bc), RTGUI_RGB_G(*pixel), alpha), - blending(RTGUI_RGB_B(bc), RTGUI_RGB_B(*pixel), alpha)); - hw_driver->ops->set_pixel(&fc, x, y); - } - } - } - } - } - else - { - int dst_x, dst_y; - - info.a = 0; - - /* initialize source blit information */ - info.src_fmt = RTGRAPHIC_PIXEL_FORMAT_ARGB888;; - info.src_h = h; - info.src_w = w; - info.src_pitch = image->w * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888); - info.src_skip = info.src_pitch - w * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888); - info.src = (rt_uint8_t *)image->data + y * info.src_pitch + x * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888); - - if (rect->x1 < 0) dst_x = 0; - else dst_x = rect->x1; - if (rect->y1 < 0) dst_y = 0; - else dst_y = rect->y1; - - /* initialize destination blit information */ - if (dc->type == RTGUI_DC_BUFFER) - { - struct rtgui_dc_buffer *buffer; - buffer = (struct rtgui_dc_buffer*)dc; - - info.dst = rtgui_dc_buffer_get_pixel(RTGUI_DC(buffer)) + dst_y * buffer->pitch + - dst_x * rtgui_color_get_bpp(buffer->pixel_format); - info.dst_h = h; - info.dst_w = w; - info.dst_fmt = buffer->pixel_format; - info.dst_pitch = buffer->pitch; - info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(buffer->pixel_format); - } - else if (dc->type == RTGUI_DC_HW) - { - struct rtgui_widget *owner; - struct rtgui_rect r; - - owner = ((struct rtgui_dc_hw*)dc)->owner; - - rtgui_graphic_driver_get_rect(RT_NULL, &r); - - /* blit destination */ - info.dst = (rt_uint8_t*)hw_driver->framebuffer; - info.dst = info.dst + (owner->extent.y1 + dst_y) * hw_driver->pitch + - (owner->extent.x1 + dst_x) * rtgui_color_get_bpp(hw_driver->pixel_format); - info.dst_fmt = hw_driver->pixel_format; - info.dst_h = h; - info.dst_w = w; - info.dst_pitch = hw_driver->pitch; - info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(hw_driver->pixel_format); - } - - rtgui_blit(&info); - } + /* this dc is not visible */ + if (rtgui_dc_get_visible(dc) != RT_TRUE) return; + + w = _UI_MIN(image->w, rtgui_rect_width(*rect)); + h = _UI_MIN(image->h, rtgui_rect_height(*rect)); + + /* border checking */ + if (rect->x1 < 0) + { + x = -rect->x1; + w += rect->x1; + } + else x = 0; + + if (rect->y1 < 0) + { + y = -rect->y1; + h += rect->y1; + } + else y = 0; + + if (w < 0 || h < 0) return; /* no drawing */ + + if ((dc->type == RTGUI_DC_CLIENT) || (dc->type == RTGUI_DC_HW && hw_driver->framebuffer == RT_NULL)) + { + int dx, dy, start_x; + rtgui_rect_t r; + rtgui_color_t *pixel; + rt_uint8_t alpha; + rtgui_widget_t *owner = RT_NULL; + + if (dc->type == RTGUI_DC_CLIENT) + { + /* get owner and calculate dx,dy */ + owner = RTGUI_CONTAINER_OF(dc, struct rtgui_widget, dc_type); + dx = owner->extent.x1; + dy = owner->extent.y1; + } + else + { + /* hardware DC */ + struct rtgui_dc_hw *hw = (struct rtgui_dc_hw *) dc; + dx = hw->owner->extent.x1; + dy = hw->owner->extent.y1; + } + + start_x = x; + for (; y < rect->y1 + h; ++y) + { + for (x = start_x; x < rect->x1 + w; ++x) + { + pixel = (rtgui_color_t*)((rt_uint8_t*)image->data + (y - rect->y1) * image->w * 4 + + (x - rect->x1) * 4); + + alpha = RTGUI_RGB_A(*pixel); + if (alpha == 0) continue; + if (alpha == 0xff) + { + rtgui_dc_draw_color_point(dc, x, y, *pixel); + } + else + { + rtgui_color_t bc, fc; + + /* draw an alpha blending point */ + if (hw_driver->framebuffer != RT_NULL) + rtgui_dc_blend_point(dc, x, y, RTGUI_BLENDMODE_BLEND, + RTGUI_RGB_R(*pixel), RTGUI_RGB_G(*pixel), RTGUI_RGB_B(*pixel), RTGUI_RGB_A(*pixel)); + else + { + x = x + dx; + y = y + dy; + + if (dc->type == RTGUI_DC_CLIENT) + { + if (rtgui_region_contains_point(&(owner->clip), x, y, &r) != RT_EOK) + continue ; + } + + /* get background pixel */ + hw_driver->ops->get_pixel(&bc, x, y); + /* alpha blending */ + fc = RTGUI_RGB(blending(RTGUI_RGB_R(bc), RTGUI_RGB_R(*pixel), alpha), + blending(RTGUI_RGB_G(bc), RTGUI_RGB_G(*pixel), alpha), + blending(RTGUI_RGB_B(bc), RTGUI_RGB_B(*pixel), alpha)); + hw_driver->ops->set_pixel(&fc, x, y); + } + } + } + } + } + else + { + int dst_x, dst_y; + + info.a = 0; + + /* initialize source blit information */ + info.src_fmt = RTGRAPHIC_PIXEL_FORMAT_ARGB888;; + info.src_h = h; + info.src_w = w; + info.src_pitch = image->w * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888); + info.src_skip = info.src_pitch - w * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888); + info.src = (rt_uint8_t *)image->data + y * info.src_pitch + x * rtgui_color_get_bpp(RTGRAPHIC_PIXEL_FORMAT_ARGB888); + + if (rect->x1 < 0) dst_x = 0; + else dst_x = rect->x1; + if (rect->y1 < 0) dst_y = 0; + else dst_y = rect->y1; + + /* initialize destination blit information */ + if (dc->type == RTGUI_DC_BUFFER) + { + struct rtgui_dc_buffer *buffer; + buffer = (struct rtgui_dc_buffer*)dc; + + info.dst = rtgui_dc_buffer_get_pixel(RTGUI_DC(buffer)) + dst_y * buffer->pitch + + dst_x * rtgui_color_get_bpp(buffer->pixel_format); + info.dst_h = h; + info.dst_w = w; + info.dst_fmt = buffer->pixel_format; + info.dst_pitch = buffer->pitch; + info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(buffer->pixel_format); + } + else if (dc->type == RTGUI_DC_HW) + { + struct rtgui_widget *owner; + struct rtgui_rect r; + + owner = ((struct rtgui_dc_hw*)dc)->owner; + + rtgui_graphic_driver_get_rect(RT_NULL, &r); + + /* blit destination */ + info.dst = (rt_uint8_t*)hw_driver->framebuffer; + info.dst = info.dst + (owner->extent.y1 + dst_y) * hw_driver->pitch + + (owner->extent.x1 + dst_x) * rtgui_color_get_bpp(hw_driver->pixel_format); + info.dst_fmt = hw_driver->pixel_format; + info.dst_h = h; + info.dst_w = w; + info.dst_pitch = hw_driver->pitch; + info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(hw_driver->pixel_format); + } + + rtgui_blit(&info); + } } void rtgui_image_png_init() diff --git a/components/gui/src/image_xpm.c b/components/gui/src/image_xpm.c index 032be397eee1b03d0b7e8015bc69df9f3ef10984..5a7b9b4ed0ec0d28a86f4a5c51addb5d4716999f 100644 --- a/components/gui/src/image_xpm.c +++ b/components/gui/src/image_xpm.c @@ -1,11 +1,21 @@ /* * File : image_xpm.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -15,7 +25,6 @@ #include #include -#include #include #ifdef RTGUI_IMAGE_XPM diff --git a/components/gui/src/matrix.c b/components/gui/src/matrix.c index cd89d226f46cbcb7fc30c20042474743d4ba27b6..e0dfcc3803c0d97de0d11d1a87050bad35ede3c8 100644 --- a/components/gui/src/matrix.c +++ b/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 #include @@ -12,7 +35,7 @@ * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, + * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all @@ -91,7 +114,8 @@ int rtgui_matrix_inverse(const struct rtgui_matrix *mm, struct rtgui_matrix *mo) /* @dd is the degree range in 0~512 */ rt_inline int icost(int dd) { - static const short t[COS_TABLE_SZ] = { + static const short t[COS_TABLE_SZ] = + { 2048, 2048, 2047, 2047, 2046, 2044, 2042, 2040, 2038, 2036, 2033, 2029, 2026, 2022, 2018, 2013, 2009, 2004, 1998, 1993, 1987, 1980, 1974, 1967, 1960, 1952, 1945, 1937, 1928, 1920, 1911, 1902, 1892, 1882, 1872, 1862, 1851, 1840, 1829, @@ -137,61 +161,61 @@ rt_inline int icost(int dd) dd &= COS_TABLE_SZ - 1; - return t[dd]; + return t[dd]; } rt_inline int icosd(int d) { - int dd = d; - return icost(dd); + int dd = d; + return icost(dd); } rt_inline int isind(int d) { - int dd = COS_TABLE_SZ / 4 - d; - return icost(dd); + int dd = COS_TABLE_SZ / 4 - d; + return icost(dd); } rt_inline void rot_mat(int *m, int d) { - int cosd = icosd(d); - int sind = isind(d); - - int m0_cosd = m[0] * cosd; - int m0_sind = m[0] * sind; - int m1_cosd = m[1] * cosd; - int m1_sind = m[1] * sind; - int m2_cosd = m[2] * cosd; - int m2_sind = m[2] * sind; - int m3_cosd = m[3] * cosd; - int m3_sind = m[3] * sind; - int m4_cosd = m[4] * cosd; - int m4_sind = m[4] * sind; - int m5_cosd = m[5] * cosd; - int m5_sind = m[5] * sind; - - m[0] = _rtgui_matrix_round_div32(m0_cosd - m1_sind, RTGUI_MATRIX_FRAC); - m[1] = _rtgui_matrix_round_div32(m0_sind + m1_cosd, RTGUI_MATRIX_FRAC); - m[2] = _rtgui_matrix_round_div32(m2_cosd - m3_sind, RTGUI_MATRIX_FRAC); - m[3] = _rtgui_matrix_round_div32(m2_sind + m3_cosd, RTGUI_MATRIX_FRAC); - m[4] = _rtgui_matrix_round_div32(m4_cosd - m5_sind, RTGUI_MATRIX_FRAC); - m[5] = _rtgui_matrix_round_div32(m4_sind + m5_cosd, RTGUI_MATRIX_FRAC); + int cosd = icosd(d); + int sind = isind(d); + + int m0_cosd = m[0] * cosd; + int m0_sind = m[0] * sind; + int m1_cosd = m[1] * cosd; + int m1_sind = m[1] * sind; + int m2_cosd = m[2] * cosd; + int m2_sind = m[2] * sind; + int m3_cosd = m[3] * cosd; + int m3_sind = m[3] * sind; + int m4_cosd = m[4] * cosd; + int m4_sind = m[4] * sind; + int m5_cosd = m[5] * cosd; + int m5_sind = m[5] * sind; + + m[0] = _rtgui_matrix_round_div32(m0_cosd - m1_sind, RTGUI_MATRIX_FRAC); + m[1] = _rtgui_matrix_round_div32(m0_sind + m1_cosd, RTGUI_MATRIX_FRAC); + m[2] = _rtgui_matrix_round_div32(m2_cosd - m3_sind, RTGUI_MATRIX_FRAC); + m[3] = _rtgui_matrix_round_div32(m2_sind + m3_cosd, RTGUI_MATRIX_FRAC); + m[4] = _rtgui_matrix_round_div32(m4_cosd - m5_sind, RTGUI_MATRIX_FRAC); + m[5] = _rtgui_matrix_round_div32(m4_sind + m5_cosd, RTGUI_MATRIX_FRAC); } rt_inline void scale_mat(int *m, int sx, int sy) { - if (sx != RTGUI_MATRIX_FRAC) + if (sx != RTGUI_MATRIX_FRAC) { - m[0] = _rtgui_matrix_round_div32(m[0] * sx, RTGUI_MATRIX_FRAC); - m[2] = _rtgui_matrix_round_div32(m[2] * sx, RTGUI_MATRIX_FRAC); - m[4] = _rtgui_matrix_round_div32(m[4] * sx, RTGUI_MATRIX_FRAC); - } - if (sy != RTGUI_MATRIX_FRAC) + m[0] = _rtgui_matrix_round_div32(m[0] * sx, RTGUI_MATRIX_FRAC); + m[2] = _rtgui_matrix_round_div32(m[2] * sx, RTGUI_MATRIX_FRAC); + m[4] = _rtgui_matrix_round_div32(m[4] * sx, RTGUI_MATRIX_FRAC); + } + if (sy != RTGUI_MATRIX_FRAC) { - m[1] = _rtgui_matrix_round_div32(m[1] * sy, RTGUI_MATRIX_FRAC); - m[3] = _rtgui_matrix_round_div32(m[3] * sy, RTGUI_MATRIX_FRAC); - m[5] = _rtgui_matrix_round_div32(m[5] * sy, RTGUI_MATRIX_FRAC); - } + m[1] = _rtgui_matrix_round_div32(m[1] * sy, RTGUI_MATRIX_FRAC); + m[3] = _rtgui_matrix_round_div32(m[3] * sy, RTGUI_MATRIX_FRAC); + m[5] = _rtgui_matrix_round_div32(m[5] * sy, RTGUI_MATRIX_FRAC); + } } void rtgui_matrix_rotate(struct rtgui_matrix *m, int rot) @@ -203,18 +227,18 @@ RTM_EXPORT(rtgui_matrix_rotate); void rtgui_matrix_scale(struct rtgui_matrix *m, int sx, int sy) { - scale_mat(m->m, sx, sy); + scale_mat(m->m, sx, sy); } void rtgui_matrix_move(struct rtgui_matrix *m, int dx, int dy) { - m->m[4] += dx; - m->m[5] += dy; + m->m[4] += dx; + m->m[5] += dy; } void rtgui_matrix_dump(const struct rtgui_matrix *m) { - const int *mm = m->m; + const int *mm = m->m; rt_kprintf("|%6d, %6d, %6d|\n", mm[0], mm[1], 0); rt_kprintf("|%6d, %6d, %6d|\n", mm[2], mm[3], 0); rt_kprintf("|%6d, %6d, %6d|\n", mm[4], mm[5], 1); diff --git a/components/gui/src/mouse.c b/components/gui/src/mouse.c index cc8d7febcdbb05c53d44e691db587e043b8505fa..0b87b73b93c3bad7ce95cfd5ed57cf1c739b55c1 100644 --- a/components/gui/src/mouse.c +++ b/components/gui/src/mouse.c @@ -1,11 +1,21 @@ /* * File : mouse.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -210,7 +220,7 @@ void rtgui_mouse_moveto(int x, int y) #endif if (x != _rtgui_cursor->cx || - y != _rtgui_cursor->cy) + y != _rtgui_cursor->cy) { #ifdef RTGUI_USING_WINMOVE if (_rtgui_cursor->win_rect_show) @@ -257,7 +267,7 @@ void rtgui_mouse_moveto(int x, int y) } #ifdef RTGUI_USING_HW_CURSOR - rtgui_cursor_set_position(_rtgui_cursor->cx, _rtgui_cursor->cy); + rtgui_cursor_set_position(_rtgui_cursor->cx, _rtgui_cursor->cy); #endif } @@ -268,12 +278,12 @@ void rtgui_mouse_moveto(int x, int y) void rtgui_mouse_set_position(int x, int y) { - /* move current cursor */ - _rtgui_cursor->cx = x; - _rtgui_cursor->cy = y; + /* move current cursor */ + _rtgui_cursor->cx = x; + _rtgui_cursor->cy = y; #ifdef RTGUI_USING_HW_CURSOR - rtgui_cursor_set_position(_rtgui_cursor->cx, _rtgui_cursor->cy); + rtgui_cursor_set_position(_rtgui_cursor->cx, _rtgui_cursor->cy); #endif } diff --git a/components/gui/src/mouse.h b/components/gui/src/mouse.h index 50aa98e7c9ddf68dee0ff518dbb3a4adc0cd8246..45d48231dff8720321dc3516fa94513d46167c7f 100644 --- a/components/gui/src/mouse.h +++ b/components/gui/src/mouse.h @@ -1,11 +1,21 @@ /* * File : mouse.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/src/region.c b/components/gui/src/region.c index c01b689096dcdbfb8726bc9589e42fd48d0d7342..0ff65a2550766e4fc456889de7bd4f43b349b8de 100644 --- a/components/gui/src/region.c +++ b/components/gui/src/region.c @@ -1,11 +1,21 @@ /* * File : region.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -2017,113 +2027,6 @@ rtgui_rect_t *rtgui_region_extents(rtgui_region_t *region) return(®ion->extents); } -#define ExchangeSpans(a, b) \ -{ \ - rtgui_point_t tpt; \ - int tw; \ - \ - tpt = spans[a]; spans[a] = spans[b]; spans[b] = tpt; \ - tw = widths[a]; widths[a] = widths[b]; widths[b] = tw; \ -} - -/* ||| I should apply the merge sort code to rectangle sorting above, and see - if mapping time can be improved. But right now I've been at work 12 hours, - so forget it. -*/ - -static void QuickSortSpans( - rtgui_point_t spans[], - int widths[], - int numSpans) -{ - int y; - int i, j, m; - rtgui_point_t *r; - - /* Always called with numSpans > 1 */ - /* Sorts only by y, doesn't bother to sort by x */ - - do - { - if (numSpans < 9) - { - /* Do insertion sort */ - int yprev; - - yprev = spans[0].y; - i = 1; - do - { - /* while i != numSpans */ - y = spans[i].y; - if (yprev > y) - { - /* spans[i] is out of order. Move into proper location. */ - rtgui_point_t tpt; - int tw, k; - - for (j = 0; y >= spans[j].y; j++) - {} - tpt = spans[i]; - tw = widths[i]; - for (k = i; k != j; k--) - { - spans[k] = spans[k - 1]; - widths[k] = widths[k - 1]; - } - spans[j] = tpt; - widths[j] = tw; - y = spans[i].y; - } /* if out of order */ - yprev = y; - i++; - } - while (i != numSpans); - return; - } - - /* Choose partition element, stick in location 0 */ - m = numSpans / 2; - if (spans[m].y > spans[0].y) ExchangeSpans(m, 0); - if (spans[m].y > spans[numSpans - 1].y) ExchangeSpans(m, numSpans - 1); - if (spans[m].y > spans[0].y) ExchangeSpans(m, 0); - y = spans[0].y; - - /* Partition array */ - i = 0; - j = numSpans; - do - { - r = &(spans[i]); - do - { - r++; - i++; - } - while (i != numSpans && r->y < y); - r = &(spans[j]); - do - { - r--; - j--; - } - while (y < r->y); - if (i < j) - ExchangeSpans(i, j); - } - while (i < j); - - /* Move partition element back to middle */ - ExchangeSpans(0, j); - - /* Recurse */ - if (numSpans - j - 1 > 1) - QuickSortSpans(&spans[j + 1], &widths[j + 1], numSpans - j - 1); - numSpans = j; - } - while (numSpans > 1); -} - #define RTGUI_REGION_TRACE #ifdef RTGUI_REGION_TRACE @@ -2167,7 +2070,7 @@ void rtgui_region_draw_clip(rtgui_region_t *region, struct rtgui_dc *dc) x = region->extents.x1; y = region->extents.y1; - + for (i = 0; i < num; i++) { struct rtgui_rect rect; @@ -2207,6 +2110,21 @@ void rtgui_rect_moveto(rtgui_rect_t *rect, int x, int y) } RTM_EXPORT(rtgui_rect_moveto); +void rtgui_rect_moveto_point(rtgui_rect_t *rect, int x, int y) +{ + int mx, my; + + mx = x - rect->x1; + my = y - rect->y1; + + rect->x1 += mx; + rect->x2 += mx; + + rect->y1 += my; + rect->y2 += my; +} +RTM_EXPORT(rtgui_rect_moveto_point); + void rtgui_rect_moveto_align(const rtgui_rect_t *rect, rtgui_rect_t *to, int align) { int dw, dh; @@ -2275,6 +2193,22 @@ void rtgui_rect_intersect(rtgui_rect_t *src, rtgui_rect_t *dest) } RTM_EXPORT(rtgui_rect_intersect); +/* union src rect into dest rect */ +void rtgui_rect_union(rtgui_rect_t *src, rtgui_rect_t *dest) +{ + if (rtgui_rect_is_empty(dest)) + { + *dest = *src; + return ; + } + + if (dest->x1 > src->x1) dest->x1 = src->x1; + if (dest->y1 > src->y1) dest->y1 = src->y1; + if (dest->x2 < src->x2) dest->x2 = src->x2; + if (dest->y2 < src->y2) dest->y2 = src->y2; +} +RTM_EXPORT(rtgui_rect_union); + int rtgui_rect_contains_point(const rtgui_rect_t *rect, int x, int y) { if (INBOX(rect, x, y)) return RT_EOK; @@ -2333,12 +2267,14 @@ RTM_EXPORT(rtgui_rect_is_empty); rtgui_rect_t *rtgui_rect_set(rtgui_rect_t *rect, int x, int y, int w, int h) { - RT_ASSERT(rect != RT_NULL); + RT_ASSERT(rect != RT_NULL); - rect->x1 = x; rect->y1 = y; - rect->x2 = x + w; rect->y2 = y + h; + rect->x1 = x; + rect->y1 = y; + rect->x2 = x + w; + rect->y2 = y + h; - return rect; + return rect; } RTM_EXPORT(rtgui_rect_set); diff --git a/components/gui/src/rtgui_app.c b/components/gui/src/rtgui_app.c index db3cdd4b2e1a63f4104c6acf867d89662f2d2772..b0a78195364488dd1b920863b8beae71688875b4 100644 --- a/components/gui/src/rtgui_app.c +++ b/components/gui/src/rtgui_app.c @@ -1,11 +1,21 @@ /* * File : rtgui_app.c - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2012, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -382,15 +392,15 @@ void rtgui_app_sleep(struct rtgui_app *app, int millisecond) rt_err_t result; rt_uint16_t current_ref; struct rtgui_event *event; - rt_tick_t tick, sleep_tick; - int delta_tick; + rt_tick_t tick, sleep_tick; + int delta_tick; - tick = rt_tick_get(); - millisecond = rt_tick_from_millisecond(millisecond); - if (millisecond == 0) return; + tick = rt_tick_get(); + millisecond = rt_tick_from_millisecond(millisecond); + if (millisecond == 0) return; - sleep_tick = tick + millisecond; - delta_tick = millisecond; + sleep_tick = tick + millisecond; + delta_tick = millisecond; /* point to event buffer */ event = (struct rtgui_event *)app->event_buffer; @@ -418,7 +428,7 @@ void rtgui_app_sleep(struct rtgui_app *app, int millisecond) delta_tick = sleep_tick - rt_tick_get(); } - app->ref_count --; + app->ref_count --; } RTM_EXPORT(rtgui_app_sleep); diff --git a/components/gui/src/rtgui_driver.c b/components/gui/src/rtgui_driver.c index 58b9c035054f244972c825a14ec5593d9230a3b1..fd1523b9a7ace3f9eba596c2649fe7512ca73387 100644 --- a/components/gui/src/rtgui_driver.c +++ b/components/gui/src/rtgui_driver.c @@ -1,11 +1,21 @@ /* * File : driver.c - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -107,8 +117,8 @@ rtgui_graphic_driver_get_rect_buffer(const struct rtgui_graphic_driver *driver, /* get source pixel */ pixel = (rt_uint8_t*)driver->framebuffer - + rect.y1 * driver->pitch - + rect.x1 * rtgui_color_get_bpp(driver->pixel_format); + + rect.y1 * driver->pitch + + rect.x1 * rtgui_color_get_bpp(driver->pixel_format); dst = buffer->pixel; @@ -276,7 +286,7 @@ static void _rgb565_get_pixel(rtgui_color_t *c, int x, int y) static void _rgb565_draw_hline(rtgui_color_t *c, int x1, int x2, int y) { - rt_ubase_t index; + int index; rt_uint16_t pixel; rt_uint16_t *pixel_ptr; @@ -298,7 +308,7 @@ static void _rgb565_draw_vline(rtgui_color_t *c, int x , int y1, int y2) struct rtgui_graphic_driver *drv; rt_uint8_t *dst; rt_uint16_t pixel; - rt_ubase_t index; + int index; drv = rtgui_graphic_get_device(); pixel = rtgui_color_to_565(*c); @@ -327,7 +337,7 @@ static void _rgb565p_get_pixel(rtgui_color_t *c, int x, int y) static void _rgb565p_draw_hline(rtgui_color_t *c, int x1, int x2, int y) { - rt_ubase_t index; + int index; rt_uint16_t pixel; rt_uint16_t *pixel_ptr; @@ -349,7 +359,7 @@ static void _rgb565p_draw_vline(rtgui_color_t *c, int x , int y1, int y2) struct rtgui_graphic_driver *drv; rt_uint8_t *dst; rt_uint16_t pixel; - rt_ubase_t index; + int index; drv = rtgui_graphic_get_device(); pixel = rtgui_color_to_565p(*c); @@ -361,6 +371,46 @@ static void _rgb565p_draw_vline(rtgui_color_t *c, int x , int y1, int y2) } } +static void _argb888_set_pixel(rtgui_color_t *c, int x, int y) +{ + *GET_PIXEL(rtgui_graphic_get_device(), x, y, rtgui_color_t) = *c; +} + +static void _argb888_get_pixel(rtgui_color_t *c, int x, int y) +{ + *c = (rtgui_color_t)*GET_PIXEL(rtgui_graphic_get_device(), x, y, rtgui_color_t); +} + +static void _argb888_draw_hline(rtgui_color_t *c, int x1, int x2, int y) +{ + int index; + rtgui_color_t *pixel_ptr; + + /* get pixel pointer in framebuffer */ + pixel_ptr = GET_PIXEL(rtgui_graphic_get_device(), x1, y, rtgui_color_t); + + for (index = x1; index < x2; index++) + { + *pixel_ptr = *c; + pixel_ptr++; + } +} + +static void _argb888_draw_vline(rtgui_color_t *c, int x, int y1, int y2) +{ + struct rtgui_graphic_driver *drv; + rtgui_color_t *dst; + int index; + + drv = rtgui_graphic_get_device(); + dst = GET_PIXEL(drv, x, y1, rtgui_color_t); + for (index = y1; index < y2; index++) + { + *dst = *c; + dst += drv->width; + } +} + /* draw raw hline */ static void framebuffer_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y) { @@ -391,6 +441,15 @@ const struct rtgui_graphic_driver_ops _framebuffer_rgb565p_ops = framebuffer_draw_raw_hline, }; +const struct rtgui_graphic_driver_ops _framebuffer_argb888_ops = +{ + _argb888_set_pixel, + _argb888_get_pixel, + _argb888_draw_hline, + _argb888_draw_vline, + framebuffer_draw_raw_hline, +}; + #define FRAMEBUFFER (drv->framebuffer) #define MONO_PIXEL(framebuffer, x, y) \ ((rt_uint8_t**)(framebuffer))[y/8][x] @@ -417,8 +476,8 @@ static void _mono_get_pixel(rtgui_color_t *c, int x, int y) static void _mono_draw_hline(rtgui_color_t *c, int x1, int x2, int y) { + int index; struct rtgui_graphic_driver *drv = rtgui_graphic_get_device(); - rt_ubase_t index; if (*c == white) for (index = x1; index < x2; index ++) @@ -435,7 +494,7 @@ static void _mono_draw_hline(rtgui_color_t *c, int x1, int x2, int y) static void _mono_draw_vline(rtgui_color_t *c, int x , int y1, int y2) { struct rtgui_graphic_driver *drv = rtgui_graphic_get_device(); - rt_ubase_t index; + int index; if (*c == white) for (index = y1; index < y2; index ++) @@ -453,7 +512,7 @@ static void _mono_draw_vline(rtgui_color_t *c, int x , int y1, int y2) static void _mono_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y) { struct rtgui_graphic_driver *drv = rtgui_graphic_get_device(); - rt_ubase_t index; + int index; for (index = x1; index < x2; index ++) { @@ -487,6 +546,8 @@ const struct rtgui_graphic_driver_ops *rtgui_framebuffer_get_ops(int pixel_forma return &_framebuffer_rgb565_ops; case RTGRAPHIC_PIXEL_FORMAT_RGB565P: return &_framebuffer_rgb565p_ops; + case RTGRAPHIC_PIXEL_FORMAT_ARGB888: + return &_framebuffer_argb888_ops; default: RT_ASSERT(0); break; diff --git a/components/gui/src/rtgui_object.c b/components/gui/src/rtgui_object.c index 9dc736f5d5d1c946bf5250e9822f81b3464ab86a..28e1fc7debd1b7fb7c8cce42e2d167c80b76fabc 100644 --- a/components/gui/src/rtgui_object.c +++ b/components/gui/src/rtgui_object.c @@ -1,11 +1,21 @@ /* * File : rtgui_object.c - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -170,11 +180,11 @@ rtgui_object_t *rtgui_object_check_cast(rtgui_object_t *obj, const rtgui_type_t { if (!obj) return RT_NULL; - if (!rtgui_type_inherits_from(obj->type, obj_type)) - { - rt_kprintf("%s[%d]: Invalid cast from \"%s\" to \"%s\"\n", func, line, - rtgui_type_name_get(obj->type), rtgui_type_name_get(obj_type)); - } + if (!rtgui_type_inherits_from(obj->type, obj_type)) + { + rt_kprintf("%s[%d]: Invalid cast from \"%s\" to \"%s\"\n", func, line, + rtgui_type_name_get(obj->type), rtgui_type_name_get(obj_type)); + } return obj; } diff --git a/components/gui/src/rtgui_system.c b/components/gui/src/rtgui_system.c index f5403adbec65c1fdcc291af2dbc2b104ef3fc191..f5da07ea4fd03f75fd001055cd5c4eb04fc9258d 100644 --- a/components/gui/src/rtgui_system.c +++ b/components/gui/src/rtgui_system.c @@ -1,16 +1,26 @@ /* * File : rtgui_system.c - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes * 2009-10-04 Bernard first version - * 2016-03-23 Bernard fix the default font initialization issue. + * 2016-03-23 Bernard fix the default font initialization issue. */ #include @@ -22,6 +32,10 @@ #include #include +#ifdef RTGUI_USING_TTF +#include +#endif + #ifdef _WIN32_NATIVE #define RTGUI_MEM_TRACE #endif @@ -60,6 +74,10 @@ int rtgui_system_server_init(void) rtgui_font_set_defaut(&rtgui_font_asc12); #endif +#ifdef RTGUI_USING_TTF + rtgui_ttf_system_init(); +#endif + return 0; } INIT_APP_EXPORT(rtgui_system_server_init); @@ -413,7 +431,7 @@ const char *rtgui_event_string[] = "TIMER", /* timer */ "UPDATE_TOPLVL", /* update toplevel */ - "VPAINT_REQ", /* virtual paint request */ + "VPAINT_REQ", /* virtual paint request */ /* clip rect information */ "CLIP_INFO", /* clip rect info */ @@ -423,7 +441,7 @@ const char *rtgui_event_string[] = "MOUSE_BUTTON", /* mouse button info */ "KBD", /* keyboard info */ "TOUCH", /* touch info */ - "GESTURE", /* gesture */ + "GESTURE", /* gesture */ "FOCUSED", /* widget got focuse */ "SCROLLED", /* scroll bar scrolled */ @@ -599,7 +617,7 @@ static void rtgui_event_dump(struct rtgui_app* app, rtgui_event_t *event) break; default: - break; + break; } rt_kprintf("\n"); @@ -722,7 +740,7 @@ RTM_EXPORT(rtgui_recv); rt_err_t rtgui_recv_filter(rt_uint32_t type, rtgui_event_t *event, rt_size_t event_size) { - rtgui_event_t *e; + rtgui_event_t *e; struct rtgui_app *app; RT_ASSERT(event != RT_NULL); @@ -732,7 +750,7 @@ rt_err_t rtgui_recv_filter(rt_uint32_t type, rtgui_event_t *event, rt_size_t eve if (app == RT_NULL) return -RT_ERROR; - e = (rtgui_event_t*)&app->event_buffer[0]; + e = (rtgui_event_t*)&app->event_buffer[0]; while (rt_mq_recv(app->mq, e, sizeof(union rtgui_event_generic), RT_WAITING_FOREVER) == RT_EOK) { if (e->type == type) @@ -785,23 +803,23 @@ RTM_EXPORT(rtgui_screen_unlock); int rtgui_screen_lock_freeze(void) { - int hold = 0; + int hold = 0; - if (_screen_lock.owner == rt_thread_self()) - { - int index; + if (_screen_lock.owner == rt_thread_self()) + { + int index; - index = hold = _screen_lock.hold; - while (index --) rt_mutex_release(&_screen_lock); - } + index = hold = _screen_lock.hold; + while (index --) rt_mutex_release(&_screen_lock); + } - return hold; + return hold; } RTM_EXPORT(rtgui_screen_lock_freeze); void rtgui_screen_lock_thaw(int value) { - while (value--) rt_mutex_take(&_screen_lock, RT_WAITING_FOREVER); + while (value--) rt_mutex_take(&_screen_lock, RT_WAITING_FOREVER); } RTM_EXPORT(rtgui_screen_lock_thaw); diff --git a/components/gui/src/server.c b/components/gui/src/server.c index 276a95d342969c731978196eec910aefd5bb3195..75e7879aa448e942c134e6c868036f924a23dac1 100644 --- a/components/gui/src/server.c +++ b/components/gui/src/server.c @@ -1,11 +1,21 @@ /* * File : server.c - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -71,12 +81,12 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse *event) /* re-init to server thread */ RTGUI_EVENT_MOUSE_BUTTON_INIT(event); - /* set cursor position */ - rtgui_mouse_set_position(event->x, event->y); + /* set cursor position */ + rtgui_mouse_set_position(event->x, event->y); #ifdef RTGUI_USING_WINMOVE if (rtgui_winrect_is_moved() && - event->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP)) + event->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP)) { struct rtgui_win *win; rtgui_rect_t rect; @@ -108,7 +118,7 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse *event) /* only raise window if the button is pressed down */ if (event->button & RTGUI_MOUSE_BUTTON_DOWN && - rtgui_topwin_get_focus() != wnd) + rtgui_topwin_get_focus() != wnd) { rtgui_topwin_activate_topwin(wnd); } @@ -175,34 +185,34 @@ void rtgui_server_handle_kbd(struct rtgui_event_kbd *event) void rtgui_server_handle_touch(struct rtgui_event_touch *event) { -// if (rtgui_touch_do_calibration(event) == RT_TRUE) -// { -// struct rtgui_event_mouse emouse; - -// /* convert it as a mouse event to rtgui */ -// if (event->up_down == RTGUI_TOUCH_MOTION) -// { -// RTGUI_EVENT_MOUSE_MOTION_INIT(&emouse); -// emouse.x = event->x; -// emouse.y = event->y; -// emouse.button = 0; - -// rtgui_server_handle_mouse_motion(&emouse); -// } -// else -// { -// RTGUI_EVENT_MOUSE_BUTTON_INIT(&emouse); -// emouse.x = event->x; -// emouse.y = event->y; -// emouse.button = RTGUI_MOUSE_BUTTON_LEFT; -// if (event->up_down == RTGUI_TOUCH_UP) -// emouse.button |= RTGUI_MOUSE_BUTTON_UP; -// else -// emouse.button |= RTGUI_MOUSE_BUTTON_DOWN; - -// rtgui_server_handle_mouse_btn(&emouse); -// } -// } +// if (rtgui_touch_do_calibration(event) == RT_TRUE) +// { +// struct rtgui_event_mouse emouse; + +// /* convert it as a mouse event to rtgui */ +// if (event->up_down == RTGUI_TOUCH_MOTION) +// { +// RTGUI_EVENT_MOUSE_MOTION_INIT(&emouse); +// emouse.x = event->x; +// emouse.y = event->y; +// emouse.button = 0; + +// rtgui_server_handle_mouse_motion(&emouse); +// } +// else +// { +// RTGUI_EVENT_MOUSE_BUTTON_INIT(&emouse); +// emouse.x = event->x; +// emouse.y = event->y; +// emouse.button = RTGUI_MOUSE_BUTTON_LEFT; +// if (event->up_down == RTGUI_TOUCH_UP) +// emouse.button |= RTGUI_MOUSE_BUTTON_UP; +// else +// emouse.button |= RTGUI_MOUSE_BUTTON_DOWN; + +// rtgui_server_handle_mouse_btn(&emouse); +// } +// } } #ifdef _WIN32_NATIVE @@ -210,7 +220,7 @@ void rtgui_server_handle_touch(struct rtgui_event_touch *event) #endif static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object, - struct rtgui_event *event) + struct rtgui_event *event) { RT_ASSERT(object != RT_NULL); RT_ASSERT(event != RT_NULL); @@ -232,7 +242,7 @@ static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object, } break; - /* mouse and keyboard event */ + /* mouse and keyboard event */ case RTGUI_EVENT_MOUSE_MOTION: /* handle mouse motion event */ rtgui_server_handle_mouse_motion((struct rtgui_event_mouse *)event); @@ -243,17 +253,17 @@ static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object, rtgui_server_handle_mouse_btn((struct rtgui_event_mouse *)event); break; - case RTGUI_EVENT_TOUCH: - /* handle touch event */ - rtgui_server_handle_touch((struct rtgui_event_touch *)event); - break; + case RTGUI_EVENT_TOUCH: + /* handle touch event */ + rtgui_server_handle_touch((struct rtgui_event_touch *)event); + break; case RTGUI_EVENT_KBD: /* handle keyboard event */ rtgui_server_handle_kbd((struct rtgui_event_kbd *)event); break; - /* window event */ + /* window event */ case RTGUI_EVENT_WIN_CREATE: if (rtgui_topwin_add((struct rtgui_event_win_create *)event) == RT_EOK) rtgui_ack(event, RTGUI_STATUS_OK); @@ -325,7 +335,7 @@ static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object, } break; - /* other event */ + /* other event */ case RTGUI_EVENT_COMMAND: break; @@ -373,7 +383,7 @@ static void rtgui_server_entry(void *parameter) rtgui_server_app = rtgui_app_create("rtgui"); if (rtgui_server_app == RT_NULL) { - rt_kprintf("Create GUI server failed.\n"); + rt_kprintf("Create GUI server failed.\n"); return; } @@ -391,12 +401,21 @@ static void rtgui_server_entry(void *parameter) rtgui_server_app = RT_NULL; } -void rtgui_server_post_event(struct rtgui_event *event, rt_size_t size) +rt_err_t rtgui_server_post_event(struct rtgui_event *event, rt_size_t size) { + rt_err_t result; + if (rtgui_server_app != RT_NULL) - rtgui_send(rtgui_server_app, event, size); + { + result = rtgui_send(rtgui_server_app, event, size); + } else + { rt_kprintf("post when server is not running\n"); + result = -RT_ENOSYS; + } + + return result; } rt_err_t rtgui_server_post_event_sync(struct rtgui_event *event, rt_size_t size) diff --git a/components/gui/src/title.c b/components/gui/src/title.c index e3ba27ffbef746d202cc5cae65e97f97a0169b42..be7948f5bc1e3f8d9b959e34c6d5ca28b5fa656f 100644 --- a/components/gui/src/title.c +++ b/components/gui/src/title.c @@ -1,11 +1,21 @@ /* * File : title.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -75,7 +85,8 @@ rt_bool_t rtgui_wintile_event_handler(struct rtgui_object *obj, rtgui_event_t *e rtgui_theme_draw_win(wint); return RT_FALSE; - case RTGUI_EVENT_MOUSE_BUTTON: { + case RTGUI_EVENT_MOUSE_BUTTON: + { struct rtgui_event_mouse *emou = (struct rtgui_event_mouse *)eve; if (win->style & RTGUI_WIN_STYLE_CLOSEBOX) @@ -107,8 +118,8 @@ rt_bool_t rtgui_wintile_event_handler(struct rtgui_object *obj, rtgui_event_t *e else if (emou->button & RTGUI_MOUSE_BUTTON_UP) { if (win->flag & RTGUI_WIN_FLAG_CB_PRESSED && - rtgui_rect_contains_point(&rect, - emou->x, emou->y) == RT_EOK) + rtgui_rect_contains_point(&rect, + emou->x, emou->y) == RT_EOK) { rtgui_win_close(win); return RT_TRUE; @@ -130,7 +141,7 @@ rt_bool_t rtgui_wintile_event_handler(struct rtgui_object *obj, rtgui_event_t *e #endif } } - return RT_TRUE; + return RT_TRUE; default: return rtgui_widget_event_handler(obj, eve); } diff --git a/components/gui/src/topwin.c b/components/gui/src/topwin.c index 0cb522c95fb05f0c07110a5dde5f330b15618487..df605c342df2bd455a3f0e19824c2bcbaf03a5ad 100644 --- a/components/gui/src/topwin.c +++ b/components/gui/src/topwin.c @@ -1,16 +1,26 @@ /* * File : topwin.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes * 2009-10-16 Bernard first version - * 2012-02-25 Grissiom rewrite topwin implementation + * 2012-02-25 Grissiom rewrite topwin implementation */ #include "topwin.h" #include "mouse.h" @@ -25,7 +35,7 @@ #include /* - * windows tree in the server side. + * windows tree in the server side. * * This list is divided into two parts. The first part is the shown list, in * which all the windows have the WINTITLE_SHOWN flag set. Second part is the @@ -224,7 +234,7 @@ static struct rtgui_topwin* _rtgui_topwin_get_next_shown(struct rtgui_topwin *to if (top->parent == RT_NULL) { if (top->list.next != &_rtgui_topwin_list && - get_topwin_from_list(top->list.next)->flag & WINTITLE_SHOWN) + get_topwin_from_list(top->list.next)->flag & WINTITLE_SHOWN) top = _rtgui_topwin_get_topmost_child_shown(get_topwin_from_list(top->list.next)); else return RT_NULL; @@ -605,7 +615,7 @@ rt_inline void _rtgui_topwin_preorder_map(struct rtgui_topwin *topwin, void (*fu func(topwin); rt_list_foreach(child, &topwin->child_list, next) - _rtgui_topwin_preorder_map(get_topwin_from_list(child), func); + _rtgui_topwin_preorder_map(get_topwin_from_list(child), func); } rt_inline void _rtgui_topwin_mark_hidden(struct rtgui_topwin *topwin) @@ -743,7 +753,7 @@ rt_err_t rtgui_topwin_move(struct rtgui_event_win_move *event) /* find in show list */ topwin = rtgui_topwin_search_in_list(event->wid, &_rtgui_topwin_list); if (topwin == RT_NULL || - !(topwin->flag & WINTITLE_SHOWN)) + !(topwin->flag & WINTITLE_SHOWN)) { return -RT_ERROR; } @@ -886,7 +896,7 @@ struct rtgui_topwin *rtgui_topwin_get_wnd_no_modaled(int x, int y) /* clip region from topwin, and the windows beneath it. */ rt_inline void _rtgui_topwin_clip_to_region(struct rtgui_topwin *topwin, - struct rtgui_region *region) + struct rtgui_region *region) { RT_ASSERT(region != RT_NULL); RT_ASSERT(topwin != RT_NULL); @@ -905,7 +915,7 @@ static void rtgui_topwin_update_clip(void) struct rtgui_region region_available; if (rt_list_isempty(&_rtgui_topwin_list) || - !(get_topwin_from_list(_rtgui_topwin_list.next)->flag & WINTITLE_SHOWN)) + !(get_topwin_from_list(_rtgui_topwin_list.next)->flag & WINTITLE_SHOWN)) return; RTGUI_EVENT_CLIP_INFO_INIT(&eclip); @@ -1004,7 +1014,8 @@ rt_err_t rtgui_topwin_modal_enter(struct rtgui_event_win_modal_enter *event) /* modal window should be on top already */ RT_ASSERT(get_topwin_from_list(parent_top->child_list.next) == topwin); - do { + do + { rt_list_foreach(node, &parent_top->child_list, next) { get_topwin_from_list(node)->flag |= WINTITLE_MODALED; @@ -1057,8 +1068,8 @@ void rtgui_topwin_remove_monitor_rect(struct rtgui_win *wid, rtgui_rect_t *rect) } static struct rtgui_object* _get_obj_in_topwin(struct rtgui_topwin *topwin, - struct rtgui_app *app, - rt_uint32_t id) + struct rtgui_app *app, + rt_uint32_t id) { struct rtgui_object *object; struct rt_list_node *node; @@ -1124,7 +1135,7 @@ static void _rtgui_topwin_dump(struct rtgui_topwin *topwin) topwin, topwin->wid->title, topwin->flag, topwin->flag & WINTITLE_SHOWN ? 'S' : 'H', topwin->flag & WINTITLE_MODALED ? 'm' : - topwin->flag & WINTITLE_MODALING ? 'M' : ' '); + topwin->flag & WINTITLE_MODALING ? 'M' : ' '); } static void _rtgui_topwin_dump_tree(struct rtgui_topwin *topwin) diff --git a/components/gui/src/topwin.h b/components/gui/src/topwin.h index c938532a00fee8652f5f851d0f10ef5ad8b82e37..35376f889bda9be9077c8c68e9bdd0c7985cb038 100644 --- a/components/gui/src/topwin.h +++ b/components/gui/src/topwin.h @@ -1,11 +1,21 @@ /* * File : topwin.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes diff --git a/components/gui/src/widget.c b/components/gui/src/widget.c index 5ef1899022579ce18e9d227149c650f35365c972..45919cfd4ff115a8530dc2ae3ccb32578040b19c 100644 --- a/components/gui/src/widget.c +++ b/components/gui/src/widget.c @@ -1,7 +1,7 @@ /* * File : widget.c - * This file is part of RT-Thread GUI - * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,14 +24,12 @@ * 2013-10-07 Bernard remove the win_check in update_clip. */ -#include +#include +#include #include #include #include #include -#ifdef RTGUI_USING_NOTEBOOK -#include -#endif static void _rtgui_widget_constructor(rtgui_widget_t *widget) { @@ -52,8 +50,8 @@ static void _rtgui_widget_constructor(rtgui_widget_t *widget) widget->align = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP; /* clear the garbage value of extent and clip */ - widget->extent.x1 = widget->extent.y1 = 0; - widget->extent.x2 = widget->extent.y2 = 0; + memset(&(widget->extent), 0x0, sizeof(widget->extent)); + memset(&(widget->extent_visiable), 0x0, sizeof(widget->extent_visiable)); widget->min_width = widget->min_height = 0; rtgui_region_init_with_extents(&widget->clip, &widget->extent); @@ -64,7 +62,6 @@ static void _rtgui_widget_constructor(rtgui_widget_t *widget) /* some common event handler */ widget->on_focus_in = RT_NULL; widget->on_focus_out = RT_NULL; - widget->on_paint = RT_NULL; /* set default event handler */ rtgui_object_set_event_handler(RTGUI_OBJECT(widget), rtgui_widget_event_handler); @@ -72,9 +69,6 @@ static void _rtgui_widget_constructor(rtgui_widget_t *widget) /* init user data private to 0 */ widget->user_data = 0; - /* init clip information */ - rtgui_region_init(&(widget->clip)); - /* init hardware dc */ rtgui_dc_client_init(widget); } @@ -127,6 +121,8 @@ void rtgui_widget_set_rect(rtgui_widget_t *widget, const rtgui_rect_t *rect) /* update extent rectangle */ widget->extent = *rect; + /* set the visiable extern as extern */ + widget->extent_visiable = *rect; if (RTGUI_IS_CONTAINER(widget)) { /* re-do layout */ @@ -166,7 +162,6 @@ void rtgui_widget_set_rect(rtgui_widget_t *widget, const rtgui_rect_t *rect) rtgui_widget_move_to_logic(widget, delta_x, delta_y); } - } RTM_EXPORT(rtgui_widget_set_rect); @@ -226,9 +221,18 @@ RTM_EXPORT(rtgui_widget_set_minheight); static void _widget_moveto(struct rtgui_widget* widget, int dx, int dy) { struct rtgui_list_node *node; - rtgui_widget_t *child; + rtgui_widget_t *child, *parent; rtgui_rect_moveto(&(widget->extent), dx, dy); + + /* handle visiable extent */ + widget->extent_visiable = widget->extent; + parent = widget->parent; + /* we should find out the none-transparent parent */ + while (parent != RT_NULL && parent->flag & RTGUI_WIDGET_FLAG_TRANSPARENT) parent = parent->parent; + if (widget->parent) + rtgui_rect_intersect(&(widget->parent->extent_visiable), &(widget->extent_visiable)); + /* reset clip info */ rtgui_region_init_with_extents(&(widget->clip), &(widget->extent)); @@ -260,7 +264,7 @@ void rtgui_widget_move_to_logic(rtgui_widget_t *widget, int dx, int dy) if (parent != RT_NULL) { /* get the parent rect, even if it's a transparent parent. */ - rect = parent->clip.extents; + rect = parent->extent_visiable; } /* we should find out the none-transparent parent */ @@ -270,7 +274,6 @@ void rtgui_widget_move_to_logic(rtgui_widget_t *widget, int dx, int dy) /* reset clip info */ rtgui_region_init_with_extents(&(widget->clip), &(widget->extent)); rtgui_region_intersect_rect(&(widget->clip), &(widget->clip), &rect); - rtgui_region_intersect_rect(&(widget->clip), &(widget->clip), &(parent->extent)); /* give back the extent */ rtgui_region_union(&(parent->clip), &(parent->clip), &(widget->clip)); @@ -344,14 +347,6 @@ void rtgui_widget_set_onunfocus(rtgui_widget_t *widget, rtgui_event_handler_ptr } RTM_EXPORT(rtgui_widget_set_onunfocus); -void rtgui_widget_set_onpaint(rtgui_widget_t *widget, rtgui_event_handler_ptr handler) -{ - RT_ASSERT(widget != RT_NULL); - - widget->on_paint = handler; -} -RTM_EXPORT(rtgui_widget_set_onpaint); - /** * @brief Focuses the widget. The focused widget is the widget which can receive the keyboard events * @param widget a widget @@ -511,15 +506,6 @@ rt_bool_t rtgui_widget_onupdate_toplvl(struct rtgui_object *object, struct rtgui } RTM_EXPORT(rtgui_widget_onupdate_toplvl); -rt_bool_t rtgui_widget_onpaint(struct rtgui_object *object, struct rtgui_event *event) -{ - if (RTGUI_WIDGET(object)->on_paint) - return RTGUI_WIDGET(object)->on_paint(object, event); - else - return RT_FALSE; -} -RTM_EXPORT(rtgui_widget_onpaint); - rt_bool_t rtgui_widget_event_handler(struct rtgui_object *object, rtgui_event_t *event) { RTGUI_WIDGET_EVENT_HANDLER_PREPARE; @@ -527,7 +513,7 @@ rt_bool_t rtgui_widget_event_handler(struct rtgui_object *object, rtgui_event_t switch (event->type) { case RTGUI_EVENT_PAINT: - return rtgui_widget_onpaint(object, event); + break; case RTGUI_EVENT_SHOW: return rtgui_widget_onshow(object, event); case RTGUI_EVENT_HIDE: @@ -556,7 +542,11 @@ void rtgui_widget_update_clip(rtgui_widget_t *widget) return; parent = widget->parent; - rect = parent->clip.extents; + /* reset visiable extent */ + widget->extent_visiable = widget->extent; + rtgui_rect_intersect(&(parent->extent_visiable), &(widget->extent_visiable)); + + rect = parent->extent_visiable; /* reset clip to extent */ rtgui_region_reset(&(widget->clip), &(widget->extent)); /* limit widget extent in parent extent */ @@ -575,7 +565,7 @@ void rtgui_widget_update_clip(rtgui_widget_t *widget) /* subtract widget clip in parent clip */ if (!(widget->flag & RTGUI_WIDGET_FLAG_TRANSPARENT) && RTGUI_IS_CONTAINER(parent)) { - rtgui_region_subtract_rect(&(parent->clip), &(parent->clip), &(widget->extent)); + rtgui_region_subtract_rect(&(parent->clip), &(parent->clip), &(widget->extent_visiable)); } } @@ -628,7 +618,6 @@ void rtgui_widget_hide(struct rtgui_widget *widget) if (RTGUI_WIDGET_IS_HIDE(widget)) return; - RTGUI_WIDGET_HIDE(widget); if (widget->toplevel != RT_NULL) { RTGUI_EVENT_HIDE_INIT(&ehide); @@ -639,6 +628,8 @@ void rtgui_widget_hide(struct rtgui_widget *widget) &ehide); } } + + RTGUI_WIDGET_HIDE(widget); } RTM_EXPORT(rtgui_widget_hide); @@ -648,7 +639,7 @@ rt_bool_t rtgui_widget_onshow(struct rtgui_object *object, struct rtgui_event *e if (RTGUI_WIDGET_IS_HIDE(object)) return RT_FALSE; - if (widget->parent != RT_NULL) + if (widget->parent != RT_NULL && !(RTGUI_WIDGET_FLAG(widget) & RTGUI_WIDGET_FLAG_TRANSPARENT)) { rtgui_widget_clip_parent(widget); } @@ -742,7 +733,7 @@ void rtgui_widget_update(rtgui_widget_t *widget) RT_ASSERT(widget != RT_NULL); if (RTGUI_OBJECT(widget)->event_handler != RT_NULL && - !(RTGUI_WIDGET_FLAG(widget) & RTGUI_WIDGET_FLAG_IN_ANIM)) + !(RTGUI_WIDGET_FLAG(widget) & RTGUI_WIDGET_FLAG_IN_ANIM)) { RTGUI_OBJECT(widget)->event_handler(RTGUI_OBJECT(widget), &paint.parent); diff --git a/components/gui/src/window.c b/components/gui/src/window.c index e5902d35b310c32b7388017d0e9aace6b0b3767f..8380622b95799230adda50575a6e5e05ce971615 100644 --- a/components/gui/src/window.c +++ b/components/gui/src/window.c @@ -1,11 +1,21 @@ /* * File : window.c - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * This file is part of RT-Thread GUI Engine + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes @@ -132,9 +142,9 @@ DEFINE_CLASS_TYPE(win, "win", sizeof(struct rtgui_win)); int rtgui_win_init(struct rtgui_win *win, struct rtgui_win *parent_window, - const char *title, - rtgui_rect_t *rect, - rt_uint16_t style) + const char *title, + rtgui_rect_t *rect, + rt_uint16_t style) { if (win == RT_NULL) return -1; @@ -425,7 +435,7 @@ RTM_EXPORT(rtgui_win_do_show); rt_base_t rtgui_win_show(struct rtgui_win *win, rt_bool_t is_modal) { - RTGUI_WIDGET_UNHIDE(win); + RTGUI_WIDGET_UNHIDE(win); if (is_modal) win->flag |= RTGUI_WIN_FLAG_MODAL; @@ -557,7 +567,7 @@ static rt_bool_t rtgui_win_ondraw(struct rtgui_win *win) /* fill area */ rtgui_dc_fill_rect(dc, &rect); - rtgui_widget_onpaint(RTGUI_OBJECT(win), RT_NULL); + /* widget drawing */ /* paint each widget */ RTGUI_EVENT_PAINT_INIT(&event); @@ -565,7 +575,7 @@ static rt_bool_t rtgui_win_ondraw(struct rtgui_win *win) rtgui_container_dispatch_event(RTGUI_CONTAINER(win), (rtgui_event_t *)&event); - rtgui_dc_end_drawing(dc); + rtgui_dc_end_drawing(dc, 1); return RT_FALSE; } @@ -623,11 +633,11 @@ static rt_bool_t _win_handle_mouse_btn(struct rtgui_win *win, struct rtgui_event * widgets). If not, it will receive two mouse up events. */ if (((struct rtgui_event_mouse *)eve)->button & RTGUI_MOUSE_BUTTON_UP - && win->last_mevent_widget != RT_NULL) + && win->last_mevent_widget != RT_NULL) { if (RTGUI_OBJECT(win->last_mevent_widget)->event_handler( - RTGUI_OBJECT(win->last_mevent_widget), - eve) == RT_TRUE) + RTGUI_OBJECT(win->last_mevent_widget), + eve) == RT_TRUE) { /* clean last mouse event handled widget */ win->last_mevent_widget = RT_NULL; @@ -643,7 +653,7 @@ static rt_bool_t _win_handle_mouse_btn(struct rtgui_win *win, struct rtgui_event * TODO: add it in the doc */ return rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win), - (struct rtgui_event_mouse *)eve); + (struct rtgui_event_mouse *)eve); } rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_event *event) @@ -681,7 +691,7 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_even case RTGUI_EVENT_WIN_ACTIVATE: if (win->flag & RTGUI_WIN_FLAG_UNDER_MODAL || - RTGUI_WIDGET_IS_HIDE(win)) + RTGUI_WIDGET_IS_HIDE(win)) { /* activate a hide window */ return RT_TRUE; @@ -713,6 +723,9 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_even break; + case RTGUI_EVENT_WIN_UPDATE_END: + break; + case RTGUI_EVENT_CLIP_INFO: /* update win clip */ rtgui_win_update_clip(win); @@ -725,22 +738,23 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_even break; #ifdef RTGUI_USING_VFRAMEBUFFER - case RTGUI_EVENT_VPAINT_REQ: - { + case RTGUI_EVENT_VPAINT_REQ: + { struct rtgui_event_vpaint_req *req = (struct rtgui_event_vpaint_req *)event; - struct rtgui_dc *dc; + struct rtgui_dc *dc; - /* get drawing dc */ - dc = rtgui_win_get_drawing(win); + /* get drawing dc */ + dc = rtgui_win_get_drawing(win); req->sender->buffer = dc; rt_completion_done(req->sender->cmp); - break; - } + break; + } #endif - case RTGUI_EVENT_MOUSE_BUTTON: { + case RTGUI_EVENT_MOUSE_BUTTON: + { struct rtgui_event_mouse *emouse = (struct rtgui_event_mouse*)event; if (rtgui_rect_contains_point(&RTGUI_WIDGET(win)->extent, @@ -757,7 +771,7 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_even case RTGUI_EVENT_MOUSE_MOTION: return rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win), - (struct rtgui_event_mouse *)event); + (struct rtgui_event_mouse *)event); case RTGUI_EVENT_KBD: /* we should dispatch key event firstly */ @@ -974,7 +988,8 @@ struct rtgui_dc *rtgui_win_get_drawing(rtgui_win_t * win) RTM_EXPORT(rtgui_win_get_drawing); #endif -static const rt_uint8_t close_byte[14] = { +static const rt_uint8_t close_byte[14] = +{ 0x06, 0x18, 0x03, 0x30, 0x01, 0xE0, 0x00, 0xC0, 0x01, 0xE0, 0x03, 0x30, 0x06, 0x18 }; @@ -1053,8 +1068,8 @@ void rtgui_theme_draw_win(struct rtgui_wintitle *wint) for (index = rect.x1; index < rect.x2 + 1; index ++) { RTGUI_WIDGET_FOREGROUND(win->_title_wgt) = RTGUI_RGB((r>>RGB_FACTOR), - (g>>RGB_FACTOR), - (b>>RGB_FACTOR)); + (g>>RGB_FACTOR), + (b>>RGB_FACTOR)); rtgui_dc_draw_vline(dc, index, rect.y1, rect.y2); r += delta; g += delta; @@ -1101,5 +1116,5 @@ void rtgui_theme_draw_win(struct rtgui_wintitle *wint) } } - rtgui_dc_end_drawing(dc); + rtgui_dc_end_drawing(dc, 1); }