refactor frame_layer

This commit is contained in:
idea4good 2020-06-21 22:48:26 +08:00
parent d2b1d4514f
commit 7a6e5d071f
8 changed files with 178 additions and 266 deletions

218
GuiLite.h
View File

@ -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();
}

View File

@ -122,7 +122,7 @@ widgets:
| draw_vline | 渲染一条竖线。x竖线的横向坐标xy0竖线的上起始坐标yy1竖线的下结尾坐标y |
| draw_line | 渲染普通直线。x1直线左端点的坐标xy1直线左端点的坐标yx2直线右端点坐标xy2直线右端点坐标y |
| draw_rect | 渲染矩形。x0矩形左上角的坐标xy0矩形左上角的坐标yx1矩形右下角的坐标xy1矩形右下角的坐标y |
| set_frame_layer_visible_rect | 设置指定图层的可视区域矩形可视区域会根据图层优先级自动进行上下叠加。rect可视矩形的位置信息z_order图层的z坐标图层坐标 |
| set_overlap_zone | 设置指定图层的可视区域矩形可视区域会根据图层优先级自动进行上下叠加。rect可视矩形的位置信息z_order图层的z坐标图层坐标 |
| flush_screen | 将当前surface的指定矩形区域一次性刷在显示屏上。leftsurface指定区域的左边界坐标topsurface指定区域的上边界坐标rightsurface指定区域的右边界坐标bottomsurface指定区域的下边界坐标 |
| is_valid | 判断给定位置的矩形是否合理是否在surface的范围内。rect矩形区域的坐标信息 |
***

View File

@ -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);
}
}
}

View File

@ -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++];
}

View File

@ -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
{

View File

@ -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++)

View File

@ -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)

View File

@ -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();
}