From 7a6e5d071f6460fb0f7133f101092c4f0c0a43d1 Mon Sep 17 00:00:00 2001 From: idea4good Date: Sun, 21 Jun 2020 22:48:26 +0800 Subject: [PATCH] refactor frame_layer --- GuiLite.h | 218 +++++++++++---------------- documents/HowToWork-cn.md | 2 +- workspace/core_include/bitmap.h | 49 +++--- workspace/core_include/display.h | 145 +++++++----------- workspace/core_include/rect.h | 2 +- workspace/widgets_include/dialog.h | 8 +- workspace/widgets_include/edit.h | 13 +- workspace/widgets_include/list_box.h | 7 +- 8 files changed, 178 insertions(+), 266 deletions(-) diff --git a/GuiLite.h b/GuiLite.h index e349cfa..6f0b212 100644 --- a/GuiLite.h +++ b/GuiLite.h @@ -211,7 +211,7 @@ public: } void Empty() { - m_left = m_top = m_right = m_bottom = 0; + m_left = m_top = m_right = m_bottom = -1; } int IsEmpty() const { @@ -391,7 +391,7 @@ class c_display { public: inline c_display(void* phy_fb, int display_width, int display_height, int surface_width, int surface_height, unsigned int color_bytes, int surface_cnt, EXTERNAL_GFX_OP* gfx_op = 0);//multiple surface or surface_no_fb inline c_display(void* phy_fb, int display_width, int display_height, c_surface* surface);//single custom surface - inline c_surface* alloc_surface(Z_ORDER_LEVEL max_zorder);//for multiple surfaces + inline c_surface* alloc_surface(Z_ORDER_LEVEL max_zorder, c_rect overlap_rect = c_rect(0, 0, -1, -1));//for multiple surfaces inline int swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset); int get_width() { return m_width; } int get_height() { return m_height; } @@ -449,21 +449,19 @@ private: int m_surface_cnt; int m_surface_index; }; -class c_frame_layer +class c_overlap_zone { public: - c_frame_layer() { fb = 0; } + c_overlap_zone() { fb = 0; } void* fb; - c_rect visible_rect; + c_rect rect; }; class c_surface { friend class c_display; friend class c_bitmap; public: - c_surface(unsigned int width, unsigned int height, unsigned int color_bytes, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0) : m_width(width), m_height(height), m_color_bytes(color_bytes), m_fb(0), m_is_active(false), m_top_zorder(Z_ORDER_LEVEL_0), m_phy_fb(0), m_phy_write_index(0), m_display(0) + c_surface(unsigned int width, unsigned int height, unsigned int color_bytes, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0, c_rect overlpa_rect = c_rect(0, 0, -1, -1)) : m_width(width), m_height(height), m_color_bytes(color_bytes), m_fb(0), m_is_active(false), m_top_zorder(Z_ORDER_LEVEL_0), m_phy_fb(0), m_phy_write_index(0), m_display(0) { - memset(m_frame_layers, 0, sizeof(m_frame_layers)); - m_frame_layers[Z_ORDER_LEVEL_0].visible_rect = c_rect(0, 0, m_width, m_height); - set_surface(max_zorder); + (overlpa_rect == c_rect(0, 0, -1, -1)) ? set_surface(max_zorder, c_rect(0, 0, width - 1, height - 1)) : set_surface(max_zorder, overlpa_rect); } int get_width() { return m_width; } int get_height() { return m_height; } @@ -474,9 +472,9 @@ public: ASSERT(false); return 0; } - if (m_frame_layers[z_order].fb) + if (m_overlap_zones[z_order].fb) { - return (m_color_bytes == 4) ? ((unsigned int*)(m_frame_layers[z_order].fb))[y * m_width + x] : GL_RGB_16_to_32(((unsigned short*)(m_frame_layers[z_order].fb))[y * m_width + x]); + return (m_color_bytes == 4) ? ((unsigned int*)(m_overlap_zones[z_order].fb))[y * m_width + x] : GL_RGB_16_to_32(((unsigned short*)(m_overlap_zones[z_order].fb))[y * m_width + x]); } else if (m_fb) { @@ -499,11 +497,6 @@ public: ASSERT(false); return; } - if (0 == m_frame_layers[z_order].visible_rect.PtInRect(x, y)) - { - ASSERT(false); - return; - } if (z_order == m_max_zorder) { return draw_pixel_on_fb(x, y, rgb); @@ -513,28 +506,33 @@ public: { m_top_zorder = (Z_ORDER_LEVEL)z_order; } - if (m_color_bytes == 4) + if (m_overlap_zones[z_order].rect.PtInRect(x, y)) { - ((unsigned int*)(m_frame_layers[z_order].fb))[x + y * m_width] = rgb; - } - else - { - ((unsigned short*)(m_frame_layers[z_order].fb))[x + y * m_width] = GL_RGB_32_to_16(rgb); + c_rect overlap_rect = m_overlap_zones[z_order].rect; + if (m_color_bytes == 4) + { + ((unsigned int*)(m_overlap_zones[z_order].fb))[(x - overlap_rect.m_left) + (y - overlap_rect.m_top) * overlap_rect.Width()] = rgb; + } + else + { + ((unsigned short*)(m_overlap_zones[z_order].fb))[(x - overlap_rect.m_left) + (y - overlap_rect.m_top) * overlap_rect.Width()] = GL_RGB_32_to_16(rgb); + } } + if (z_order == m_top_zorder) { return draw_pixel_on_fb(x, y, rgb); } - bool is_covered = false; + bool be_overlapped = false; for (unsigned int tmp_z_order = Z_ORDER_LEVEL_MAX - 1; tmp_z_order > z_order; tmp_z_order--) { - if (true == m_frame_layers[tmp_z_order].visible_rect.PtInRect(x, y)) + if (m_overlap_zones[tmp_z_order].rect.PtInRect(x, y)) { - is_covered = true; + be_overlapped = true; break; } } - if (!is_covered) + if (!be_overlapped) { draw_pixel_on_fb(x, y, rgb); } @@ -552,29 +550,22 @@ public: if (z_order == m_top_zorder) { int x, y; - unsigned short* mem_fb_16 = 0; - unsigned int* mem_fb_32 = 0; + c_rect overlap_rect = m_overlap_zones[z_order].rect; unsigned int rgb_16 = GL_RGB_32_to_16(rgb); for (y = y0; y <= y1; y++) { - x = x0; - if (m_color_bytes == 4) + for (x = x0; x <= x1; x++) { - mem_fb_32 = &((unsigned int*)m_frame_layers[z_order].fb)[y * m_width + x]; - } - else - { - mem_fb_16 = &((unsigned short*)m_frame_layers[z_order].fb)[y * m_width + x]; - } - for (; x <= x1; x++) - { - if (m_color_bytes == 4) + if (overlap_rect.PtInRect(x, y)) { - *mem_fb_32++ = rgb; - } - else - { - *mem_fb_16++ = rgb_16; + if (m_color_bytes == 4) + { + ((unsigned int*)m_overlap_zones[z_order].fb)[(y - overlap_rect.m_top) * overlap_rect.Width() + (x - overlap_rect.m_left)] = rgb; + } + else + { + ((unsigned short*)m_overlap_zones[z_order].fb)[(y - overlap_rect.m_top) * overlap_rect.Width() + (x - overlap_rect.m_left)] = rgb_16; + } } } } @@ -676,50 +667,22 @@ public: } bool is_active() { return m_is_active; } c_display* get_display() { return m_display; } - int set_frame_layer_visible_rect(c_rect& rect, unsigned int z_order) + int show_overlapped_rect(c_rect& rect, unsigned int z_order) { - if (rect == m_frame_layers[z_order].visible_rect) + ASSERT(z_order >= Z_ORDER_LEVEL_0 && z_order < Z_ORDER_LEVEL_MAX); + c_rect overlap_rect = m_overlap_zones[z_order].rect; + ASSERT(rect.m_left >= overlap_rect.m_left && rect.m_right <= overlap_rect.m_right && + rect.m_top >= overlap_rect.m_top && rect.m_bottom <= overlap_rect.m_bottom); + void* fb = m_overlap_zones[z_order].fb; + int width = overlap_rect.Width(); + for (int y = rect.m_top; y <= rect.m_bottom; y++) { - return 0; - } - if (rect.m_left < 0 || rect.m_left >= m_width || - rect.m_right < 0 || rect.m_right >= m_width || - rect.m_top < 0 || rect.m_top >= m_height || - rect.m_bottom < 0 || rect.m_bottom >= m_height) - { - ASSERT(false); - return -1; - } - if (!(z_order > Z_ORDER_LEVEL_0&& z_order < Z_ORDER_LEVEL_MAX)) - { - ASSERT(false); - return -2; - } - if (z_order < (unsigned int)m_top_zorder) - { - ASSERT(false); - return -3; - } - m_top_zorder = (Z_ORDER_LEVEL)z_order; - c_rect old_rect = m_frame_layers[z_order].visible_rect; - //Recover the lower layer - int src_zorder = (Z_ORDER_LEVEL)(z_order - 1); - for (int y = old_rect.m_top; y <= old_rect.m_bottom; y++) - { - for (int x = old_rect.m_left; x <= old_rect.m_right; x++) + for (int x = rect.m_left; x <= rect.m_right; x++) { - if (!rect.PtInRect(x, y)) - { - unsigned int rgb = (m_color_bytes == 4) ? ((unsigned int*)(m_frame_layers[src_zorder].fb))[x + y * m_width] : GL_RGB_16_to_32(((unsigned short*)(m_frame_layers[src_zorder].fb))[x + y * m_width]); - draw_pixel_on_fb(x, y, rgb); - } + unsigned int rgb = (m_color_bytes == 4) ? ((unsigned int*)fb)[(x - overlap_rect.m_left) + (y - overlap_rect.m_top) * width] : GL_RGB_16_to_32(((unsigned short*)fb)[(x - overlap_rect.m_left) + (y - overlap_rect.m_top) * width]); + draw_pixel_on_fb(x, y, rgb); } } - m_frame_layers[z_order].visible_rect = rect; - if (rect.IsEmpty()) - { - m_top_zorder = (Z_ORDER_LEVEL)(z_order - 1); - } return 0; } void set_active(bool flag) { m_is_active = flag; } @@ -802,7 +765,7 @@ protected: m_phy_fb = display->m_phy_fb; m_phy_write_index = &display->m_phy_write_index; } - void set_surface(Z_ORDER_LEVEL max_z_order) + void set_surface(Z_ORDER_LEVEL max_z_order, c_rect overlap_rect) { m_max_zorder = max_z_order; if (m_display && (m_display->m_surface_cnt > 1)) @@ -811,16 +774,15 @@ protected: } for (int i = Z_ORDER_LEVEL_0; i < m_max_zorder; i++) {//Top layber fb always be 0 - ASSERT(!m_frame_layers[i].fb); - m_frame_layers[i].fb = calloc(m_width * m_height, m_color_bytes); - ASSERT(m_frame_layers[i].fb); + ASSERT(m_overlap_zones[i].fb = calloc(overlap_rect.Width() * overlap_rect.Height(), m_color_bytes)); + m_overlap_zones[i].rect = overlap_rect; } } int m_width; //in pixels int m_height; //in pixels int m_color_bytes; //16 bits, 32 bits only void* m_fb; //frame buffer you could see - c_frame_layer m_frame_layers[Z_ORDER_LEVEL_MAX];//Top layber fb always be 0 + c_overlap_zone m_overlap_zones[Z_ORDER_LEVEL_MAX];//Top layber fb always be 0 bool m_is_active; Z_ORDER_LEVEL m_max_zorder; Z_ORDER_LEVEL m_top_zorder; @@ -831,7 +793,7 @@ protected: class c_surface_no_fb : public c_surface {//No physical framebuffer friend class c_display; public: - c_surface_no_fb(unsigned int width, unsigned int height, unsigned int color_bytes, struct EXTERNAL_GFX_OP* gfx_op, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0) : c_surface(width, height, color_bytes, max_zorder), m_gfx_op(gfx_op) {} + c_surface_no_fb(unsigned int width, unsigned int height, unsigned int color_bytes, struct EXTERNAL_GFX_OP* gfx_op, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0, c_rect overlpa_rect = c_rect(0, 0, -1, -1)) : c_surface(width, height, color_bytes, max_zorder, overlpa_rect), m_gfx_op(gfx_op) {} protected: virtual void fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb) { @@ -916,10 +878,10 @@ inline c_display::c_display(void* phy_fb, int display_width, int display_height, surface->m_is_active = true; (m_surface_group[0] = surface)->attach_display(this); } -inline c_surface* c_display::alloc_surface(Z_ORDER_LEVEL max_zorder) +inline c_surface* c_display::alloc_surface(Z_ORDER_LEVEL max_zorder, c_rect overlap_rect) { ASSERT(max_zorder < Z_ORDER_LEVEL_MAX && m_surface_index < m_surface_cnt); - m_surface_group[m_surface_index]->set_surface(max_zorder); + (overlap_rect == c_rect(0, 0, -1, -1)) ? m_surface_group[m_surface_index]->set_surface(max_zorder, c_rect(0, 0, m_width - 1, m_height - 1)) : m_surface_group[m_surface_index]->set_surface(max_zorder, overlap_rect); return m_surface_group[m_surface_index++]; } inline int c_display::swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset) @@ -1280,38 +1242,38 @@ class c_bitmap public: static void draw_bitmap(c_surface* surface, int z_order, const BITMAP_INFO *pBitmap, int x, int y, unsigned int mask_rgb = DEFAULT_MASK_COLOR) { - if (0 == pBitmap) - { - return; - } + ASSERT(pBitmap); unsigned short* lower_fb_16 = 0; unsigned int* lower_fb_32 = 0; - int lower_fb_width = surface->m_width; + int lower_fb_width = 0; + c_rect lower_fb_rect; if (z_order >= Z_ORDER_LEVEL_1) { - lower_fb_16 = (unsigned short*)surface->m_frame_layers[z_order - 1].fb; - lower_fb_32 = (unsigned int*)surface->m_frame_layers[z_order - 1].fb; + lower_fb_16 = (unsigned short*)surface->m_overlap_zones[z_order - 1].fb; + lower_fb_32 = (unsigned int*)surface->m_overlap_zones[z_order - 1].fb; + lower_fb_rect = surface->m_overlap_zones[z_order - 1].rect; + lower_fb_width = lower_fb_rect.Width(); } unsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb); int xsize = pBitmap->width; int ysize = pBitmap->height; const unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array; int color_bytes = surface->m_color_bytes; - for (int j = 0; j < ysize; j++) + for (int y_ = y; y_ < y + ysize; y_++) { - for (int i = 0; i < xsize; i++) + for (int x_ = x; x_ < x + xsize; x_++) { unsigned int rgb = *pData++; if (mask_rgb_16 == rgb) { - if (lower_fb_16) - {//restore lower layer - surface->draw_pixel(x + i, y + j, (color_bytes == 4) ? lower_fb_32[(y + j) * lower_fb_width + x + i] : GL_RGB_16_to_32(lower_fb_16[(y + j) * lower_fb_width + x + i]), z_order); + if (lower_fb_rect.PtInRect(x_, y_)) + {//show lower layer + surface->draw_pixel(x_, y_, (color_bytes == 4) ? lower_fb_32[(y_ - lower_fb_rect.m_top) * lower_fb_width + (x_ - lower_fb_rect.m_left)] : GL_RGB_16_to_32(lower_fb_16[(y_ - lower_fb_rect.m_top) * lower_fb_width + (x_ - lower_fb_rect.m_left)]), z_order); } } else { - surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(rgb), z_order); + surface->draw_pixel(x_, y_, GL_RGB_16_to_32(rgb), z_order); } } } @@ -1324,31 +1286,34 @@ public: } unsigned short* lower_fb_16 = 0; unsigned int* lower_fb_32 = 0; - int lower_fb_width = surface->m_width; + int lower_fb_width = 0; + c_rect lower_fb_rect; if (z_order >= Z_ORDER_LEVEL_1) { - lower_fb_16 = (unsigned short*)surface->m_frame_layers[z_order - 1].fb; - lower_fb_32 = (unsigned int*)surface->m_frame_layers[z_order - 1].fb; + lower_fb_16 = (unsigned short*)surface->m_overlap_zones[z_order - 1].fb; + lower_fb_32 = (unsigned int*)surface->m_overlap_zones[z_order - 1].fb; + lower_fb_rect = surface->m_overlap_zones[z_order - 1].rect; + lower_fb_width = lower_fb_rect.Width(); } unsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb); const unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array; int color_bytes = surface->m_color_bytes; - for (int j = 0; j < height; j++) + for (int y_ = 0; y_ < height; y_++) { - const unsigned short* p = &pData[src_x + (src_y + j) * pBitmap->width]; - for (int i = 0; i < width; i++) + const unsigned short* p = &pData[src_x + (src_y + y_) * pBitmap->width]; + for (int x_ = 0; x_ < width; x_++) { unsigned int rgb = *p++; if (mask_rgb_16 == rgb) { - if (lower_fb_16) - {//restore lower layer - surface->draw_pixel(x + i, y + j, (color_bytes == 4) ? lower_fb_32[(y + j) * lower_fb_width + x + i] : GL_RGB_16_to_32(lower_fb_16[(y + j) * lower_fb_width + x + i]), z_order); + if (lower_fb_rect.PtInRect(x + x_, y + y_)) + {//show lower layer + surface->draw_pixel(x + x_, y + y_, (color_bytes == 4) ? lower_fb_32[(y + y_ - lower_fb_rect.m_top) * lower_fb_width + x + x_ - lower_fb_rect.m_left] : GL_RGB_16_to_32(lower_fb_16[(y + y_ - lower_fb_rect.m_top) * lower_fb_width + x + x_ - lower_fb_rect.m_left]), z_order); } } else { - surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(rgb), z_order); + surface->draw_pixel(x + x_, y + y_, GL_RGB_16_to_32(rgb), z_order); } } } @@ -1960,9 +1925,6 @@ public: { cur_dlg->set_attr(WND_ATTRIBUTION(0)); } - c_rect rc; - p_dlg->get_screen_rect(rc); - p_dlg->get_surface()->set_frame_layer_visible_rect(rc, Z_ORDER_LEVEL_1); p_dlg->set_attr(modal_mode ? (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_PRIORITY) : (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS)); p_dlg->show_window(); p_dlg->set_me_the_dialog(); @@ -1976,8 +1938,9 @@ public: return 0; } c_rect rc; + dlg->get_screen_rect(rc); dlg->set_attr(WND_ATTRIBUTION(0)); - surface->set_frame_layer_visible_rect(rc, dlg->m_z_order); + surface->show_overlapped_rect(rc, dlg->m_z_order - 1); //clear the dialog for (int i = 0; i < SURFACE_CNT_MAX; i++) { @@ -2294,18 +2257,17 @@ protected: } virtual void on_paint() { - c_rect rect; + c_rect rect, kb_rect; get_screen_rect(rect); - c_rect empty_rect; - empty_rect.Empty(); + s_keyboard.get_screen_rect(kb_rect); switch (m_status) { case STATUS_NORMAL: if (m_z_order > m_parent->get_z_order()) { s_keyboard.disconnect(); - m_surface->set_frame_layer_visible_rect(empty_rect, s_keyboard.get_z_order()); m_z_order = m_parent->get_z_order(); + m_surface->show_overlapped_rect(kb_rect, m_z_order); m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); } m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); @@ -2315,8 +2277,8 @@ protected: if (m_z_order > m_parent->get_z_order()) { s_keyboard.disconnect(); - m_surface->set_frame_layer_visible_rect(empty_rect, s_keyboard.get_z_order()); m_z_order = m_parent->get_z_order(); + m_surface->show_overlapped_rect(kb_rect, m_z_order); m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); } m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); @@ -2395,9 +2357,6 @@ private: void show_keyboard() { s_keyboard.connect(this, IDD_KEY_BOARD, m_kb_style); - c_rect kb_rect; - s_keyboard.get_screen_rect(kb_rect); - m_surface->set_frame_layer_visible_rect(kb_rect, s_keyboard.get_z_order()); s_keyboard.show_window(); } void on_touch_down(int x, int y) @@ -2528,15 +2487,15 @@ protected: } virtual void on_paint() { - c_rect rect, empty_rect; + c_rect rect; get_screen_rect(rect); switch (m_status) { case STATUS_NORMAL: if (m_z_order > m_parent->get_z_order()) { - m_surface->set_frame_layer_visible_rect(empty_rect, m_z_order); m_z_order = m_parent->get_z_order(); + m_surface->show_overlapped_rect(m_list_screen_rect, m_z_order); m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); } m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); @@ -2545,8 +2504,8 @@ protected: case STATUS_FOCUSED: if (m_z_order > m_parent->get_z_order()) { - m_surface->set_frame_layer_visible_rect(empty_rect, m_z_order); m_z_order = m_parent->get_z_order(); + m_surface->show_overlapped_rect(m_list_screen_rect, m_z_order); m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); } m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); @@ -2563,7 +2522,6 @@ protected: { m_z_order++; } - m_surface->set_frame_layer_visible_rect(m_list_screen_rect, m_z_order); m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_PRIORITY); show_list(); } diff --git a/documents/HowToWork-cn.md b/documents/HowToWork-cn.md index 9e5a63c..50019e8 100644 --- a/documents/HowToWork-cn.md +++ b/documents/HowToWork-cn.md @@ -122,7 +122,7 @@ widgets: | draw_vline | 渲染一条竖线。x:竖线的横向坐标:x;y0:竖线的上起始坐标y;y1:竖线的下结尾坐标y | | draw_line | 渲染普通直线。x1:直线左端点的坐标x;y1:直线左端点的坐标y;x2:直线右端点坐标x;y2:直线右端点坐标y | | draw_rect | 渲染矩形。x0:矩形左上角的坐标x;y0:矩形左上角的坐标y;x1:矩形右下角的坐标x;y1:矩形右下角的坐标y | -| set_frame_layer_visible_rect | 设置指定图层的可视区域(矩形),可视区域会根据图层优先级,自动进行上下叠加。rect:可视矩形的位置信息;z_order:图层的z坐标(图层坐标) | +| set_overlap_zone | 设置指定图层的可视区域(矩形),可视区域会根据图层优先级,自动进行上下叠加。rect:可视矩形的位置信息;z_order:图层的z坐标(图层坐标) | | flush_screen | 将当前surface的指定矩形区域一次性刷在显示屏上。left:surface指定区域的左边界坐标;top:surface指定区域的上边界坐标;right:surface指定区域的右边界坐标;bottom:surface指定区域的下边界坐标 | | is_valid | 判断给定位置的矩形,是否合理(是否在surface的范围内)。rect:矩形区域的坐标信息 | *** diff --git a/workspace/core_include/bitmap.h b/workspace/core_include/bitmap.h index 5927637..b20e9ba 100644 --- a/workspace/core_include/bitmap.h +++ b/workspace/core_include/bitmap.h @@ -13,38 +13,38 @@ class c_bitmap public: static void draw_bitmap(c_surface* surface, int z_order, const BITMAP_INFO *pBitmap, int x, int y, unsigned int mask_rgb = DEFAULT_MASK_COLOR) { - if (0 == pBitmap) - { - return; - } + ASSERT(pBitmap); unsigned short* lower_fb_16 = 0; unsigned int* lower_fb_32 = 0; - int lower_fb_width = surface->m_width; + int lower_fb_width = 0; + c_rect lower_fb_rect; if (z_order >= Z_ORDER_LEVEL_1) { - lower_fb_16 = (unsigned short*)surface->m_frame_layers[z_order - 1].fb; - lower_fb_32 = (unsigned int*)surface->m_frame_layers[z_order - 1].fb; + lower_fb_16 = (unsigned short*)surface->m_overlap_zones[z_order - 1].fb; + lower_fb_32 = (unsigned int*)surface->m_overlap_zones[z_order - 1].fb; + lower_fb_rect = surface->m_overlap_zones[z_order - 1].rect; + lower_fb_width = lower_fb_rect.Width(); } unsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb); int xsize = pBitmap->width; int ysize = pBitmap->height; const unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array; int color_bytes = surface->m_color_bytes; - for (int j = 0; j < ysize; j++) + for (int y_ = y; y_ < y + ysize; y_++) { - for (int i = 0; i < xsize; i++) + for (int x_ = x; x_ < x + xsize; x_++) { unsigned int rgb = *pData++; if (mask_rgb_16 == rgb) { - if (lower_fb_16) - {//restore lower layer - surface->draw_pixel(x + i, y + j, (color_bytes == 4) ? lower_fb_32[(y + j) * lower_fb_width + x + i] : GL_RGB_16_to_32(lower_fb_16[(y + j) * lower_fb_width + x + i]), z_order); + if (lower_fb_rect.PtInRect(x_, y_)) + {//show lower layer + surface->draw_pixel(x_, y_, (color_bytes == 4) ? lower_fb_32[(y_ - lower_fb_rect.m_top) * lower_fb_width + (x_ - lower_fb_rect.m_left)] : GL_RGB_16_to_32(lower_fb_16[(y_ - lower_fb_rect.m_top) * lower_fb_width + (x_ - lower_fb_rect.m_left)]), z_order); } } else { - surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(rgb), z_order); + surface->draw_pixel(x_, y_, GL_RGB_16_to_32(rgb), z_order); } } } @@ -59,31 +59,34 @@ public: unsigned short* lower_fb_16 = 0; unsigned int* lower_fb_32 = 0; - int lower_fb_width = surface->m_width; + int lower_fb_width = 0; + c_rect lower_fb_rect; if (z_order >= Z_ORDER_LEVEL_1) { - lower_fb_16 = (unsigned short*)surface->m_frame_layers[z_order - 1].fb; - lower_fb_32 = (unsigned int*)surface->m_frame_layers[z_order - 1].fb; + lower_fb_16 = (unsigned short*)surface->m_overlap_zones[z_order - 1].fb; + lower_fb_32 = (unsigned int*)surface->m_overlap_zones[z_order - 1].fb; + lower_fb_rect = surface->m_overlap_zones[z_order - 1].rect; + lower_fb_width = lower_fb_rect.Width(); } unsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb); const unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array; int color_bytes = surface->m_color_bytes; - for (int j = 0; j < height; j++) + for (int y_ = 0; y_ < height; y_++) { - const unsigned short* p = &pData[src_x + (src_y + j) * pBitmap->width]; - for (int i = 0; i < width; i++) + const unsigned short* p = &pData[src_x + (src_y + y_) * pBitmap->width]; + for (int x_ = 0; x_ < width; x_++) { unsigned int rgb = *p++; if (mask_rgb_16 == rgb) { - if (lower_fb_16) - {//restore lower layer - surface->draw_pixel(x + i, y + j, (color_bytes == 4) ? lower_fb_32[(y + j) * lower_fb_width + x + i] : GL_RGB_16_to_32(lower_fb_16[(y + j) * lower_fb_width + x + i]), z_order); + if (lower_fb_rect.PtInRect(x + x_, y + y_)) + {//show lower layer + surface->draw_pixel(x + x_, y + y_, (color_bytes == 4) ? lower_fb_32[(y + y_ - lower_fb_rect.m_top) * lower_fb_width + x + x_ - lower_fb_rect.m_left] : GL_RGB_16_to_32(lower_fb_16[(y + y_ - lower_fb_rect.m_top) * lower_fb_width + x + x_ - lower_fb_rect.m_left]), z_order); } } else { - surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(rgb), z_order); + surface->draw_pixel(x + x_, y + y_, GL_RGB_16_to_32(rgb), z_order); } } } diff --git a/workspace/core_include/display.h b/workspace/core_include/display.h index 5e9c1fd..61d10af 100644 --- a/workspace/core_include/display.h +++ b/workspace/core_include/display.h @@ -30,7 +30,7 @@ class c_display { public: inline c_display(void* phy_fb, int display_width, int display_height, int surface_width, int surface_height, unsigned int color_bytes, int surface_cnt, EXTERNAL_GFX_OP* gfx_op = 0);//multiple surface or surface_no_fb inline c_display(void* phy_fb, int display_width, int display_height, c_surface* surface);//single custom surface - inline c_surface* alloc_surface(Z_ORDER_LEVEL max_zorder);//for multiple surfaces + inline c_surface* alloc_surface(Z_ORDER_LEVEL max_zorder, c_rect overlap_rect = c_rect(0, 0, -1, -1));//for multiple surfaces inline int swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset); int get_width() { return m_width; } int get_height() { return m_height; } @@ -97,22 +97,20 @@ private: int m_surface_index; }; -class c_frame_layer +class c_overlap_zone { public: - c_frame_layer() { fb = 0; } + c_overlap_zone() { fb = 0; } void* fb; - c_rect visible_rect; + c_rect rect; }; class c_surface { friend class c_display; friend class c_bitmap; public: - c_surface(unsigned int width, unsigned int height, unsigned int color_bytes, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0) : m_width(width), m_height(height), m_color_bytes(color_bytes), m_fb(0), m_is_active(false), m_top_zorder(Z_ORDER_LEVEL_0), m_phy_fb(0), m_phy_write_index(0), m_display(0) + c_surface(unsigned int width, unsigned int height, unsigned int color_bytes, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0, c_rect overlpa_rect = c_rect(0, 0, -1, -1)) : m_width(width), m_height(height), m_color_bytes(color_bytes), m_fb(0), m_is_active(false), m_top_zorder(Z_ORDER_LEVEL_0), m_phy_fb(0), m_phy_write_index(0), m_display(0) { - memset(m_frame_layers, 0, sizeof(m_frame_layers)); - m_frame_layers[Z_ORDER_LEVEL_0].visible_rect = c_rect(0, 0, m_width, m_height); - set_surface(max_zorder); + (overlpa_rect == c_rect(0, 0, -1, -1)) ? set_surface(max_zorder, c_rect(0, 0, width - 1, height - 1)) : set_surface(max_zorder, overlpa_rect); } int get_width() { return m_width; } @@ -125,9 +123,9 @@ public: ASSERT(false); return 0; } - if (m_frame_layers[z_order].fb) + if (m_overlap_zones[z_order].fb) { - return (m_color_bytes == 4) ? ((unsigned int*)(m_frame_layers[z_order].fb))[y * m_width + x] : GL_RGB_16_to_32(((unsigned short*)(m_frame_layers[z_order].fb))[y * m_width + x]); + return (m_color_bytes == 4) ? ((unsigned int*)(m_overlap_zones[z_order].fb))[y * m_width + x] : GL_RGB_16_to_32(((unsigned short*)(m_overlap_zones[z_order].fb))[y * m_width + x]); } else if (m_fb) { @@ -151,11 +149,6 @@ public: ASSERT(false); return; } - if (0 == m_frame_layers[z_order].visible_rect.PtInRect(x, y)) - { - ASSERT(false); - return; - } if (z_order == m_max_zorder) { @@ -167,31 +160,35 @@ public: m_top_zorder = (Z_ORDER_LEVEL)z_order; } - if (m_color_bytes == 4) + if (m_overlap_zones[z_order].rect.PtInRect(x, y)) { - ((unsigned int*)(m_frame_layers[z_order].fb))[x + y * m_width] = rgb; + c_rect overlap_rect = m_overlap_zones[z_order].rect; + if (m_color_bytes == 4) + { + ((unsigned int*)(m_overlap_zones[z_order].fb))[(x - overlap_rect.m_left) + (y - overlap_rect.m_top) * overlap_rect.Width()] = rgb; + } + else + { + ((unsigned short*)(m_overlap_zones[z_order].fb))[(x - overlap_rect.m_left) + (y - overlap_rect.m_top) * overlap_rect.Width()] = GL_RGB_32_to_16(rgb); + } } - else - { - ((unsigned short*)(m_frame_layers[z_order].fb))[x + y * m_width] = GL_RGB_32_to_16(rgb); - } - + if (z_order == m_top_zorder) { return draw_pixel_on_fb(x, y, rgb); } - bool is_covered = false; + bool be_overlapped = false; for (unsigned int tmp_z_order = Z_ORDER_LEVEL_MAX - 1; tmp_z_order > z_order; tmp_z_order--) { - if (true == m_frame_layers[tmp_z_order].visible_rect.PtInRect(x, y)) + if (m_overlap_zones[tmp_z_order].rect.PtInRect(x, y)) { - is_covered = true; + be_overlapped = true; break; } } - if (!is_covered) + if (!be_overlapped) { draw_pixel_on_fb(x, y, rgb); } @@ -212,29 +209,22 @@ public: if (z_order == m_top_zorder) { int x, y; - unsigned short* mem_fb_16 = 0; - unsigned int* mem_fb_32 = 0; + c_rect overlap_rect = m_overlap_zones[z_order].rect; unsigned int rgb_16 = GL_RGB_32_to_16(rgb); for (y = y0; y <= y1; y++) { - x = x0; - if (m_color_bytes == 4) + for (x = x0; x <= x1; x++) { - mem_fb_32 = &((unsigned int*)m_frame_layers[z_order].fb)[y * m_width + x]; - } - else - { - mem_fb_16 = &((unsigned short*)m_frame_layers[z_order].fb)[y * m_width + x]; - } - for (; x <= x1; x++) - { - if (m_color_bytes == 4) + if (overlap_rect.PtInRect(x, y)) { - *mem_fb_32++ = rgb; - } - else - { - *mem_fb_16++ = rgb_16; + if (m_color_bytes == 4) + { + ((unsigned int*)m_overlap_zones[z_order].fb)[(y - overlap_rect.m_top) * overlap_rect.Width() + (x - overlap_rect.m_left)] = rgb; + } + else + { + ((unsigned short*)m_overlap_zones[z_order].fb)[(y - overlap_rect.m_top) * overlap_rect.Width() + (x - overlap_rect.m_left)] = rgb_16; + } } } } @@ -353,52 +343,24 @@ public: bool is_active() { return m_is_active; } c_display* get_display() { return m_display; } - int set_frame_layer_visible_rect(c_rect& rect, unsigned int z_order) + int show_overlapped_rect(c_rect& rect, unsigned int z_order) { - if (rect == m_frame_layers[z_order].visible_rect) - { - return 0; - } - if (rect.m_left < 0 || rect.m_left >= m_width || - rect.m_right < 0 || rect.m_right >= m_width || - rect.m_top < 0 || rect.m_top >= m_height || - rect.m_bottom < 0 || rect.m_bottom >= m_height) - { - ASSERT(false); - return -1; - } - if (!(z_order > Z_ORDER_LEVEL_0&& z_order < Z_ORDER_LEVEL_MAX)) - { - ASSERT(false); - return -2; - } - if (z_order < (unsigned int)m_top_zorder) - { - ASSERT(false); - return -3; - } - m_top_zorder = (Z_ORDER_LEVEL)z_order; + ASSERT(z_order >= Z_ORDER_LEVEL_0 && z_order < Z_ORDER_LEVEL_MAX); - c_rect old_rect = m_frame_layers[z_order].visible_rect; - //Recover the lower layer - int src_zorder = (Z_ORDER_LEVEL)(z_order - 1); - for (int y = old_rect.m_top; y <= old_rect.m_bottom; y++) + c_rect overlap_rect = m_overlap_zones[z_order].rect; + ASSERT(rect.m_left >= overlap_rect.m_left && rect.m_right <= overlap_rect.m_right && + rect.m_top >= overlap_rect.m_top && rect.m_bottom <= overlap_rect.m_bottom); + + void* fb = m_overlap_zones[z_order].fb; + int width = overlap_rect.Width(); + for (int y = rect.m_top; y <= rect.m_bottom; y++) { - for (int x = old_rect.m_left; x <= old_rect.m_right; x++) + for (int x = rect.m_left; x <= rect.m_right; x++) { - if (!rect.PtInRect(x, y)) - { - unsigned int rgb = (m_color_bytes == 4) ? ((unsigned int*)(m_frame_layers[src_zorder].fb))[x + y * m_width] : GL_RGB_16_to_32(((unsigned short*)(m_frame_layers[src_zorder].fb))[x + y * m_width]); - draw_pixel_on_fb(x, y, rgb); - } + unsigned int rgb = (m_color_bytes == 4) ? ((unsigned int*)fb)[(x - overlap_rect.m_left) + (y - overlap_rect.m_top) * width] : GL_RGB_16_to_32(((unsigned short*)fb)[(x - overlap_rect.m_left) + (y - overlap_rect.m_top) * width]); + draw_pixel_on_fb(x, y, rgb); } } - - m_frame_layers[z_order].visible_rect = rect; - if (rect.IsEmpty()) - { - m_top_zorder = (Z_ORDER_LEVEL)(z_order - 1); - } return 0; } void set_active(bool flag) { m_is_active = flag; } @@ -486,7 +448,7 @@ protected: m_phy_write_index = &display->m_phy_write_index; } - void set_surface(Z_ORDER_LEVEL max_z_order) + void set_surface(Z_ORDER_LEVEL max_z_order, c_rect overlap_rect) { m_max_zorder = max_z_order; if (m_display && (m_display->m_surface_cnt > 1)) @@ -496,9 +458,8 @@ protected: for (int i = Z_ORDER_LEVEL_0; i < m_max_zorder; i++) {//Top layber fb always be 0 - ASSERT(!m_frame_layers[i].fb); - m_frame_layers[i].fb = calloc(m_width * m_height, m_color_bytes); - ASSERT(m_frame_layers[i].fb); + ASSERT(m_overlap_zones[i].fb = calloc(overlap_rect.Width() * overlap_rect.Height(), m_color_bytes)); + m_overlap_zones[i].rect = overlap_rect; } } @@ -506,7 +467,7 @@ protected: int m_height; //in pixels int m_color_bytes; //16 bits, 32 bits only void* m_fb; //frame buffer you could see - c_frame_layer m_frame_layers[Z_ORDER_LEVEL_MAX];//Top layber fb always be 0 + c_overlap_zone m_overlap_zones[Z_ORDER_LEVEL_MAX];//Top layber fb always be 0 bool m_is_active; Z_ORDER_LEVEL m_max_zorder; Z_ORDER_LEVEL m_top_zorder; @@ -518,7 +479,7 @@ protected: class c_surface_no_fb : public c_surface {//No physical framebuffer friend class c_display; public: - c_surface_no_fb(unsigned int width, unsigned int height, unsigned int color_bytes, struct EXTERNAL_GFX_OP* gfx_op, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0) : c_surface(width, height, color_bytes, max_zorder), m_gfx_op(gfx_op) {} + c_surface_no_fb(unsigned int width, unsigned int height, unsigned int color_bytes, struct EXTERNAL_GFX_OP* gfx_op, Z_ORDER_LEVEL max_zorder = Z_ORDER_LEVEL_0, c_rect overlpa_rect = c_rect(0, 0, -1, -1)) : c_surface(width, height, color_bytes, max_zorder, overlpa_rect), m_gfx_op(gfx_op) {} protected: virtual void fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb) { @@ -610,10 +571,10 @@ inline c_display::c_display(void* phy_fb, int display_width, int display_height, (m_surface_group[0] = surface)->attach_display(this); } -inline c_surface* c_display::alloc_surface(Z_ORDER_LEVEL max_zorder) +inline c_surface* c_display::alloc_surface(Z_ORDER_LEVEL max_zorder, c_rect overlap_rect) { ASSERT(max_zorder < Z_ORDER_LEVEL_MAX && m_surface_index < m_surface_cnt); - m_surface_group[m_surface_index]->set_surface(max_zorder); + (overlap_rect == c_rect(0, 0, -1, -1)) ? m_surface_group[m_surface_index]->set_surface(max_zorder, c_rect(0, 0, m_width - 1, m_height - 1)) : m_surface_group[m_surface_index]->set_surface(max_zorder, overlap_rect); return m_surface_group[m_surface_index++]; } diff --git a/workspace/core_include/rect.h b/workspace/core_include/rect.h index 9b44913..b838deb 100644 --- a/workspace/core_include/rect.h +++ b/workspace/core_include/rect.h @@ -22,7 +22,7 @@ public: } void Empty() { - m_left = m_top = m_right = m_bottom = 0; + m_left = m_top = m_right = m_bottom = -1; } int IsEmpty() const { diff --git a/workspace/widgets_include/dialog.h b/workspace/widgets_include/dialog.h index eeedb28..1b9334f 100644 --- a/workspace/widgets_include/dialog.h +++ b/workspace/widgets_include/dialog.h @@ -40,10 +40,6 @@ public: cur_dlg->set_attr(WND_ATTRIBUTION(0)); } - c_rect rc; - p_dlg->get_screen_rect(rc); - p_dlg->get_surface()->set_frame_layer_visible_rect(rc, Z_ORDER_LEVEL_1); - p_dlg->set_attr(modal_mode ? (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_PRIORITY) : (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS)); p_dlg->show_window(); p_dlg->set_me_the_dialog(); @@ -59,9 +55,9 @@ public: return 0; } c_rect rc; - + dlg->get_screen_rect(rc); dlg->set_attr(WND_ATTRIBUTION(0)); - surface->set_frame_layer_visible_rect(rc, dlg->m_z_order); + surface->show_overlapped_rect(rc, dlg->m_z_order - 1); //clear the dialog for (int i = 0; i < SURFACE_CNT_MAX; i++) diff --git a/workspace/widgets_include/edit.h b/workspace/widgets_include/edit.h index 883bac6..81d0152 100644 --- a/workspace/widgets_include/edit.h +++ b/workspace/widgets_include/edit.h @@ -44,18 +44,17 @@ protected: } virtual void on_paint() { - c_rect rect; + c_rect rect, kb_rect; get_screen_rect(rect); - c_rect empty_rect; - empty_rect.Empty(); + s_keyboard.get_screen_rect(kb_rect); switch (m_status) { case STATUS_NORMAL: if (m_z_order > m_parent->get_z_order()) { s_keyboard.disconnect(); - m_surface->set_frame_layer_visible_rect(empty_rect, s_keyboard.get_z_order()); m_z_order = m_parent->get_z_order(); + m_surface->show_overlapped_rect(kb_rect, m_z_order); m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); } m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); @@ -65,8 +64,8 @@ protected: if (m_z_order > m_parent->get_z_order()) { s_keyboard.disconnect(); - m_surface->set_frame_layer_visible_rect(empty_rect, s_keyboard.get_z_order()); m_z_order = m_parent->get_z_order(); + m_surface->show_overlapped_rect(kb_rect, m_z_order); m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); } m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); @@ -145,10 +144,6 @@ private: void show_keyboard() { s_keyboard.connect(this, IDD_KEY_BOARD, m_kb_style); - - c_rect kb_rect; - s_keyboard.get_screen_rect(kb_rect); - m_surface->set_frame_layer_visible_rect(kb_rect, s_keyboard.get_z_order()); s_keyboard.show_window(); } void on_touch_down(int x, int y) diff --git a/workspace/widgets_include/list_box.h b/workspace/widgets_include/list_box.h index 229b4ed..fc2388d 100644 --- a/workspace/widgets_include/list_box.h +++ b/workspace/widgets_include/list_box.h @@ -62,7 +62,7 @@ protected: virtual void on_paint() { - c_rect rect, empty_rect; + c_rect rect; get_screen_rect(rect); switch (m_status) @@ -70,8 +70,8 @@ protected: case STATUS_NORMAL: if (m_z_order > m_parent->get_z_order()) { - m_surface->set_frame_layer_visible_rect(empty_rect, m_z_order); m_z_order = m_parent->get_z_order(); + m_surface->show_overlapped_rect(m_list_screen_rect, m_z_order); m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); } m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_NORMAL), m_z_order); @@ -80,8 +80,8 @@ protected: case STATUS_FOCUSED: if (m_z_order > m_parent->get_z_order()) { - m_surface->set_frame_layer_visible_rect(empty_rect, m_z_order); m_z_order = m_parent->get_z_order(); + m_surface->show_overlapped_rect(m_list_screen_rect, m_z_order); m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS); } m_surface->fill_rect(rect, c_theme::get_color(COLOR_WND_FOCUS), m_z_order); @@ -98,7 +98,6 @@ protected: { m_z_order++; } - m_surface->set_frame_layer_visible_rect(m_list_screen_rect, m_z_order); m_attr = (WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS | ATTR_PRIORITY); show_list(); }