!27 Support header-only

This commit is contained in:
idea4good
2020-01-22 11:03:29 +08:00
parent 84199d4733
commit e16f90cccc
56 changed files with 7877 additions and 8361 deletions

View File

@@ -1,13 +1,87 @@
#ifndef GUILITE_CORE_INCLUDE_BITMAP_H
#define GUILITE_CORE_INCLUDE_BITMAP_H
#include "../core_include/api.h"
#include "../core_include/resource.h"
#include "../core_include/rect.h"
#include "../core_include/display.h"
#define DEFAULT_MASK_COLOR 0xFF080408
class c_surface;
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);
static void draw_bitmap(c_surface* surface, int z_order, const BITMAP_INFO* pBitmap, int x, int y, int src_x, int src_y, int width, int height, unsigned int mask_rgb = DEFAULT_MASK_COLOR);
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;
}
unsigned short* lower_fb = 0;
int lower_fb_width = surface->m_width;
if (z_order >= Z_ORDER_LEVEL_1)
{
lower_fb = surface->m_frame_layers[z_order - 1].fb;
}
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;
for (int j = 0; j < ysize; j++)
{
for (int i = 0; i < xsize; i++)
{
unsigned int rgb = *pData++;
if (mask_rgb_16 == rgb)
{
if (lower_fb)
{//restore lower layer
surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(lower_fb[(y + j) * lower_fb_width + x + i]), z_order);
}
}
else
{
surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(rgb), z_order);
}
}
}
}
static void draw_bitmap(c_surface* surface, int z_order, const BITMAP_INFO* pBitmap, int x, int y, int src_x, int src_y, int width, int height, unsigned int mask_rgb = DEFAULT_MASK_COLOR)
{
if (0 == pBitmap || (src_x + width > pBitmap->width) || (src_y + height > pBitmap->height))
{
return;
}
unsigned short* lower_fb = 0;
int lower_fb_width = surface->m_width;
if (z_order >= Z_ORDER_LEVEL_1)
{
lower_fb = surface->m_frame_layers[z_order - 1].fb;
}
unsigned int mask_rgb_16 = GL_RGB_32_to_16(mask_rgb);
const unsigned short* pData = (const unsigned short*)pBitmap->pixel_color_array;
for (int j = 0; j < height; j++)
{
const unsigned short* p = &pData[src_x + (src_y + j) * pBitmap->width];
for (int i = 0; i < width; i++)
{
unsigned int rgb = *p++;
if (mask_rgb_16 == rgb)
{
if (lower_fb)
{//restore lower layer
surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(lower_fb[(y + j) * lower_fb_width + x + i]), z_order);
}
}
else
{
surface->draw_pixel(x + i, y + j, GL_RGB_16_to_32(rgb), z_order);
}
}
}
}
};
#endif

View File

@@ -1,13 +1,14 @@
#ifndef GUILITE_CORE_INCLUDE_CMD_TARGET_H
#define GUILITE_CORE_INCLUDE_CMD_TARGET_H
class c_cmd_target;
#include "../core_include/api.h"
#define MSG_TYPE_INVALID 0xFFFF
#define MSG_TYPE_WND 0x0001
#define MSG_TYPE_USR 0x0002
#define USR_MSG_MAX 32
class c_cmd_target;
typedef void (c_cmd_target::*msgCallback)(int, int);
struct GL_MSG_ENTRY
@@ -41,10 +42,92 @@ const GL_MSG_ENTRY theClass::m_msg_entries[] = \
class c_cmd_target
{
public:
static int handle_usr_msg(int msg_id, int resource_id, int param);
static int handle_usr_msg(int msg_id, int resource_id, int param)
{
int i;
c_cmd_target* p_wnd = 0;
for (i = 0; i < ms_user_map_size; i++)
{
if (msg_id == ms_usr_map_entries[i].msgId)
{
p_wnd = (c_cmd_target*)ms_usr_map_entries[i].object;
(p_wnd->*ms_usr_map_entries[i].callBack)(resource_id, param);
}
}
return 1;
}
protected:
void load_cmd_msg();
const GL_MSG_ENTRY* find_msg_entry(const GL_MSG_ENTRY *pEntry, int msgType, int msgId);
void load_cmd_msg()
{
const GL_MSG_ENTRY* p_entry = get_msg_entries();
if (0 == p_entry)
{
return;
}
bool bExist = false;
while (MSG_TYPE_INVALID != p_entry->msgType)
{
if (MSG_TYPE_WND == p_entry->msgType)
{
p_entry++;
continue;
}
bExist = false;
for (int i = 0; i < ms_user_map_size; i++)
{
//repeat register, return.
if (p_entry->msgId == ms_usr_map_entries[i].msgId
&& ms_usr_map_entries[i].object == this)
{
bExist = true;
break;
}
}
if (true == bExist)
{
p_entry++;
continue;
}
if (MSG_TYPE_USR == p_entry->msgType)
{
ms_usr_map_entries[ms_user_map_size] = *p_entry;
ms_usr_map_entries[ms_user_map_size].object = this;
ms_user_map_size++;
if (USR_MSG_MAX == ms_user_map_size)
{
ASSERT(false);
}
}
else
{
ASSERT(false);
break;
}
p_entry++;
}
}
const GL_MSG_ENTRY* find_msg_entry(const GL_MSG_ENTRY *pEntry, int msgType, int msgId)
{
if (MSG_TYPE_INVALID == msgType)
{
return 0;
}
while (MSG_TYPE_INVALID != pEntry->msgType)
{
if ((msgType == pEntry->msgType) && (msgId == pEntry->msgId))
{
return pEntry;
}
pEntry++;
}
return 0;
}
private:
static GL_MSG_ENTRY ms_usr_map_entries[USR_MSG_MAX];
static unsigned short ms_user_map_size;

View File

@@ -1,31 +1,778 @@
#ifndef GUILITE_CORE_INCLUDE_DISPLAY_H
#define GUILITE_CORE_INCLUDE_DISPLAY_H
#include "../core_include/api.h"
#include "../core_include/rect.h"
#include "../core_include/cmd_target.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define SURFACE_CNT_MAX 6//root + pages
class c_hid_pipe;
class c_surface;
typedef enum
{
Z_ORDER_LEVEL_0,//view/wave/page
Z_ORDER_LEVEL_1,//dialog
Z_ORDER_LEVEL_2,//editbox/spinbox/listbox/keyboard
Z_ORDER_LEVEL_MAX
}Z_ORDER_LEVEL;
struct EXTERNAL_GFX_OP
{
void(*draw_pixel)(int x, int y, unsigned int rgb);
void(*fill_rect)(int x0, int y0, int x1, int y1, unsigned int rgb);
};
class c_surface;
class c_display {
friend class c_surface;
public:
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);
c_surface* alloc_surface(Z_ORDER_LEVEL max_zorder);
int swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y2, int offset);
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);
inline c_surface* alloc_surface(Z_ORDER_LEVEL max_zorder);
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; }
void* get_updated_fb(int* width, int* height, bool force_update = false);
int snap_shot(const char* file_name);
void* get_updated_fb(int* width, int* height, bool force_update = false)
{
if (width && height)
{
*width = get_width();
*height = get_height();
}
if (force_update)
{
return m_phy_fb;
}
if (m_phy_read_index == m_phy_write_index)
{//No update
return 0;
}
m_phy_read_index = m_phy_write_index;
return m_phy_fb;
}
int snap_shot(const char* file_name)
{
if (!m_phy_fb)
{
return -1;
}
int width = get_width();
int height = get_height();
//16 bits framebuffer
if (m_color_bytes == 2)
{
return build_bmp(file_name, width, height, (unsigned char*)m_phy_fb);
}
//32 bits framebuffer
unsigned short* p_bmp565_data = new unsigned short[width * height];
unsigned int* p_raw_data = (unsigned int*)m_phy_fb;
for (int i = 0; i < width * height; i++)
{
unsigned int rgb = *p_raw_data++;
p_bmp565_data[i] = GL_RGB_32_to_16(rgb);
}
int ret = build_bmp(file_name, width, height, (unsigned char*)p_bmp565_data);
delete[]p_bmp565_data;
return ret;
}
private:
int m_width; //in pixels
int m_height; //in pixels
int m_color_bytes; //16 bits, 32 bits only
void* m_phy_fb;
void* m_phy_fb;
int m_phy_read_index;
int m_phy_write_index;
c_surface* m_surface_group[SURFACE_CNT_MAX];
c_surface* m_surface_group[SURFACE_CNT_MAX];
int m_surface_cnt;
int m_surface_index;
};
class c_frame_layer
{
public:
c_frame_layer() { fb = 0; }
unsigned short* fb;
c_rect visible_rect;
};
#define GL_ROUND_RGB_32(rgb) (rgb & 0xFFF8FCF8) //make RGB32 = RGB16
class c_surface {
friend class c_display; friend class c_bitmap;
public:
int get_width() { return m_width; }
int get_height() { return m_height; }
unsigned int get_pixel(int x, int y, unsigned int z_order)
{
if (x >= m_width || y >= m_height || x < 0 || y < 0 ||
z_order >= Z_ORDER_LEVEL_MAX)
{
ASSERT(false);
return 0;
}
if (z_order == m_max_zorder)
{
if (m_fb)
{
return (m_color_bytes == 4) ? ((unsigned int*)m_fb)[y * m_width + x] : GL_RGB_16_to_32(((unsigned short*)m_fb)[y * m_width + x]);
}
else if (m_phy_fb)
{
return (m_color_bytes == 4) ? ((unsigned int*)m_phy_fb)[y * m_width + x] : GL_RGB_16_to_32(((unsigned short*)m_phy_fb)[y * m_width + x]);
}
return 0;
}
unsigned short rgb_16 = ((unsigned short*)(m_frame_layers[z_order].fb))[y * m_width + x];
return GL_RGB_16_to_32(rgb_16);
}
void draw_pixel(int x, int y, unsigned int rgb, unsigned int z_order)
{
if (x >= m_width || y >= m_height || x < 0 || y < 0)
{
return;
}
if (z_order > (unsigned int)m_max_zorder)
{
ASSERT(false);
return;
}
rgb = GL_ROUND_RGB_32(rgb);
if (z_order == m_max_zorder)
{
return draw_pixel_on_fb(x, y, rgb);
}
if (z_order > (unsigned int)m_top_zorder)
{
m_top_zorder = (Z_ORDER_LEVEL)z_order;
}
if (0 == m_frame_layers[z_order].visible_rect.PtInRect(x, y))
{
ASSERT(false);
return;
}
((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;
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))
{
is_covered = true;
break;
}
}
if (!is_covered)
{
draw_pixel_on_fb(x, y, rgb);
}
}
void fill_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order)
{
x0 = (x0 < 0) ? 0 : x0;
y0 = (y0 < 0) ? 0 : y0;
x1 = (x1 > (m_width - 1)) ? (m_width - 1) : x1;
y1 = (y1 > (m_height - 1)) ? (m_height - 1) : y1;
rgb = GL_ROUND_RGB_32(rgb);
if (z_order == m_max_zorder)
{
return fill_rect_on_fb(x0, y0, x1, y1, rgb);
}
if (z_order == m_top_zorder)
{
int x, y;
unsigned short* mem_fb;
unsigned int rgb_16 = GL_RGB_32_to_16(rgb);
for (y = y0; y <= y1; y++)
{
x = x0;
mem_fb = &((unsigned short*)m_frame_layers[z_order].fb)[y * m_width + x];
for (; x <= x1; x++)
{
*mem_fb++ = rgb_16;
}
}
return fill_rect_on_fb(x0, y0, x1, y1, rgb);
}
for (; y0 <= y1; y0++)
{
draw_hline(x0, x1, y0, rgb, z_order);
}
}
void draw_hline(int x0, int x1, int y, unsigned int rgb, unsigned int z_order)
{
for (; x0 <= x1; x0++)
{
draw_pixel(x0, y, rgb, z_order);
}
}
void draw_vline(int x, int y0, int y1, unsigned int rgb, unsigned int z_order)
{
for (; y0 <= y1; y0++)
{
draw_pixel(x, y0, rgb, z_order);
}
}
void draw_line(int x1, int y1, int x2, int y2, unsigned int rgb, unsigned int z_order)
{
int dx, dy, e;
dx = x2 - x1;
dy = y2 - y1;
if ((dx >= 0) && (dy >= 0))
{
if (dx >= dy)
{
e = dy - dx / 2;
for (; x1 <= x2; x1++, e += dy)
{
draw_pixel(x1, y1, rgb, z_order);
if (e > 0) { y1++; e -= dx; }
}
}
else
{
e = dx - dy / 2;
for (; y1 <= y2; y1++, e += dx)
{
draw_pixel(x1, y1, rgb, z_order);
if (e > 0) { x1++; e -= dy; }
}
}
}
else if ((dx >= 0) && (dy < 0))
{
dy = -dy;
if (dx >= dy)
{
e = dy - dx / 2;
for (; x1 <= x2; x1++, e += dy)
{
draw_pixel(x1, y1, rgb, z_order);
if (e > 0) { y1--; e -= dx; }
}
}
else
{
e = dx - dy / 2;
for (; y1 >= y2; y1--, e += dx)
{
draw_pixel(x1, y1, rgb, z_order);
if (e > 0) { x1++; e -= dy; }
}
}
}
else if ((dx < 0) && (dy >= 0))
{
dx = -dx;
if (dx >= dy)
{
e = dy - dx / 2;
for (; x1 >= x2; x1--, e += dy)
{
draw_pixel(x1, y1, rgb, z_order);
if (e > 0) { y1++; e -= dx; }
}
}
else
{
e = dx - dy / 2;
for (; y1 <= y2; y1++, e += dx)
{
draw_pixel(x1, y1, rgb, z_order);
if (e > 0) { x1--; e -= dy; }
}
}
}
else if ((dx < 0) && (dy < 0))
{
dx = -dx;
dy = -dy;
if (dx >= dy)
{
e = dy - dx / 2;
for (; x1 >= x2; x1--, e += dy)
{
draw_pixel(x1, y1, rgb, z_order);
if (e > 0) { y1--; e -= dx; }
}
}
else
{
e = dx - dy / 2;
for (; y1 >= y2; y1--, e += dx)
{
draw_pixel(x1, y1, rgb, z_order);
if (e > 0) { x1--; e -= dy; }
}
}
}
}
void draw_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order, unsigned int size = 1)
{
for (unsigned int offset = 0; offset < size; offset++)
{
draw_hline(x0 + offset, x1 - offset, y0 + offset, rgb, z_order);
draw_hline(x0 + offset, x1 - offset, y1 - offset, rgb, z_order);
draw_vline(x0 + offset, y0 + offset, y1 - offset, rgb, z_order);
draw_vline(x1 - offset, y0 + offset, y1 - offset, rgb, z_order);
}
}
void draw_rect(c_rect rect, unsigned int rgb, unsigned int size, unsigned int z_order)
{
draw_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, rgb, z_order, size);
}
void fill_rect(c_rect rect, unsigned int rgb, unsigned int z_order)
{
fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, rgb, z_order);
}
int flush_screen(int left, int top, int right, int bottom)
{
if (left < 0 || left >= m_width || right < 0 || right >= m_width ||
top < 0 || top >= m_height || bottom < 0 || bottom >= m_height)
{
ASSERT(false);
}
if (!m_is_active || (0 == m_phy_fb) || (0 == m_fb))
{
return -1;
}
int display_width = m_display->get_width();
int display_height = m_display->get_height();
left = (left >= display_width) ? (display_width - 1) : left;
right = (right >= display_width) ? (display_width - 1) : right;
top = (top >= display_height) ? (display_height - 1) : top;
bottom = (bottom >= display_height) ? (display_height - 1) : bottom;
for (int y = top; y < bottom; y++)
{
void* s_addr = (char*)m_fb + ((y * m_width + left) * m_color_bytes);
void* d_addr = (char*)m_phy_fb + ((y * display_width + left) * m_color_bytes);
memcpy(d_addr, s_addr, (right - left) * m_color_bytes);
}
*m_phy_write_index = *m_phy_write_index + 1;
return 0;
}
bool is_valid(c_rect rect)
{
if (rect.m_left < 0 || rect.m_top < 0)
{
return false;
}
if (rect.m_right >= m_width || rect.m_bottom >= m_height)
{
return false;
}
return true;
}
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)
{
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;
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++)
{
if (!rect.PtInRect(x, y))
{
unsigned int rgb = ((unsigned short*)(m_frame_layers[src_zorder].fb))[x + y * m_width];
draw_pixel_on_fb(x, y, GL_RGB_16_to_32(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; }
protected:
virtual void fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb)
{
int display_width = m_display->get_width();
int display_height = m_display->get_height();
if (m_color_bytes == 4)
{
int x;
unsigned int* fb, * phy_fb;
for (; y0 <= y1; y0++)
{
x = x0;
fb = m_fb ? &((unsigned int*)m_fb)[y0 * m_width + x] : 0;
phy_fb = &((unsigned int*)m_phy_fb)[y0 * display_width + x];
*m_phy_write_index = *m_phy_write_index + 1;
for (; x <= x1; x++)
{
if (fb)
{
*fb++ = rgb;
}
if (m_is_active && (x < display_width) && (y0 < display_height))
{
*phy_fb++ = rgb;
}
}
}
}
else if (m_color_bytes == 2)
{
int x;
unsigned short* fb, * phy_fb;
rgb = GL_RGB_32_to_16(rgb);
for (; y0 <= y1; y0++)
{
x = x0;
fb = m_fb ? &((unsigned short*)m_fb)[y0 * m_width + x] : 0;
phy_fb = &((unsigned short*)m_phy_fb)[y0 * display_width + x];
*m_phy_write_index = *m_phy_write_index + 1;
for (; x <= x1; x++)
{
if (fb)
{
*fb++ = rgb;
}
if (m_is_active && (x < display_width) && (y0 < display_height))
{
*phy_fb++ = rgb;
}
}
}
}
}
virtual void draw_pixel_on_fb(int x, int y, unsigned int rgb)
{
if (m_fb)
{
(m_color_bytes == 4) ? ((unsigned int*)m_fb)[y * m_width + x] = rgb : ((unsigned short*)m_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb);
}
int display_width = m_display->get_width();
int display_height = m_display->get_height();
if (m_is_active && (x < display_width) && (y < display_height))
{
if (m_color_bytes == 4)
{
((unsigned int*)m_phy_fb)[y * (m_display->get_width()) + x] = rgb;
}
else
{
((unsigned short*)m_phy_fb)[y * (m_display->get_width()) + x] = GL_RGB_32_to_16(rgb);
}
*m_phy_write_index = *m_phy_write_index + 1;
}
}
void set_surface(Z_ORDER_LEVEL max_z_order)
{
m_max_zorder = max_z_order;
if (m_display->m_surface_cnt > 1)
{
m_fb = calloc(m_width * m_height, m_color_bytes);
}
for (int i = Z_ORDER_LEVEL_0; i < m_max_zorder; i++)
{//Top layber fb always be 0
m_frame_layers[i].fb = (unsigned short*)calloc(m_width * m_height, sizeof(unsigned short));
ASSERT(0 != m_frame_layers[i].fb);
}
}
c_surface(c_display* display, unsigned int width, unsigned int height, unsigned int color_bytes) : m_width(width), m_height(height), m_color_bytes(color_bytes), m_fb(0), m_is_active(false), m_max_zorder(Z_ORDER_LEVEL_0), m_top_zorder(Z_ORDER_LEVEL_0), m_phy_fb(0), m_phy_write_index(0), m_display(0)
{
if (display)
{
m_display = display;
m_phy_fb = display->m_phy_fb;
m_phy_write_index = &display->m_phy_write_index;
}
m_frame_layers[Z_ORDER_LEVEL_0].visible_rect = c_rect(0, 0, m_width, m_height);
}
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
bool m_is_active;
Z_ORDER_LEVEL m_max_zorder;
Z_ORDER_LEVEL m_top_zorder;
void* m_phy_fb;
int* m_phy_write_index;
c_display* m_display;
};
class c_surface_no_fb : public c_surface {//No physical framebuffer
friend class c_display;
c_surface_no_fb(c_display* display, unsigned int width, unsigned int height, unsigned int color_bytes, struct EXTERNAL_GFX_OP* gfx_op) :
c_surface(display, width, height, color_bytes) {
m_gfx_op = gfx_op;
}
protected:
virtual void fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb)
{
if (!m_gfx_op)
{
return;
}
if (m_gfx_op->fill_rect)
{
return m_gfx_op->fill_rect(x0, y0, x1, y1, rgb);
}
if (m_gfx_op->draw_pixel && m_is_active)
{
for (int y = y0; y <= y1; y++)
{
for (int x = x0; x <= x1; x++)
{
m_gfx_op->draw_pixel(x, y, rgb);
}
}
}
if (!m_fb) { return; }
if (m_color_bytes == 4)
{
unsigned int* fb;
for (int y = y0; y <= y1; y++)
{
fb = &((unsigned int*)m_fb)[y0 * m_width + x0];
for (int x = x0; x <= x1; x++)
{
*fb++ = rgb;
}
}
}
else if (m_color_bytes == 2)
{
unsigned short* fb;
rgb = GL_RGB_32_to_16(rgb);
for (int y = y0; y <= y1; y++)
{
fb = &((unsigned short*)m_fb)[y0 * m_width + x0];
for (int x = x0; x <= x1; x++)
{
*fb++ = rgb;
}
}
}
}
virtual void draw_pixel_on_fb(int x, int y, unsigned int rgb)
{
if (m_gfx_op && m_gfx_op->draw_pixel && m_is_active)
{
m_gfx_op->draw_pixel(x, y, rgb);
}
if (!m_fb) { return; }
if (m_color_bytes == 4)
{
((unsigned int*)m_fb)[y * m_width + x] = rgb;
}
else if (m_color_bytes == 2)
{
((unsigned short*)m_fb)[y * m_width + x] = GL_RGB_32_to_16(rgb);
}
}
struct EXTERNAL_GFX_OP* m_gfx_op;//Rendering by external method
static c_surface_no_fb mcu_surface;//Reserve one for avoiding new operation, new operation maybe crash program on Keil platform sometimes.
};
inline c_display::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)
{
if (color_bytes != 2 && color_bytes != 4)
{
log_out("Support 16 bits, 32 bits color only!");
ASSERT(false);
}
m_width = display_width;
m_height = display_height;
m_color_bytes = color_bytes;
m_phy_fb = phy_fb;
m_phy_read_index = m_phy_write_index = 0;
memset(m_surface_group, 0, sizeof(m_surface_group));
m_surface_index = 0;
m_surface_cnt = surface_cnt;
ASSERT(m_surface_cnt <= SURFACE_CNT_MAX);
if ((m_surface_cnt == 1) && (gfx_op))
{// Avoid new operation for MCU, new operation maybe crash program on Keil platform sometimes.
c_surface_no_fb::mcu_surface.m_display = this;
c_surface_no_fb::mcu_surface.m_width = surface_width;
c_surface_no_fb::mcu_surface.m_height = surface_height;
c_surface_no_fb::mcu_surface.m_color_bytes = color_bytes;
c_surface_no_fb::mcu_surface.m_gfx_op = gfx_op;
m_surface_group[0] = &c_surface_no_fb::mcu_surface;
return;
}
for (int i = 0; i < m_surface_cnt; i++)
{
m_surface_group[i] = phy_fb ? new c_surface(this, surface_width, surface_height, color_bytes) : new c_surface_no_fb(this, surface_width, surface_height, color_bytes, gfx_op);
}
}
inline c_surface* c_display::alloc_surface(Z_ORDER_LEVEL max_zorder)
{
if (max_zorder >= Z_ORDER_LEVEL_MAX || m_surface_index >= m_surface_cnt)
{
ASSERT(false);
return 0;
}
int i = m_surface_index++;
m_surface_group[i]->set_surface(max_zorder);
return m_surface_group[i];
}
inline int c_display::swipe_surface(c_surface* s0, c_surface* s1, int x0, int x1, int y0, int y1, int offset)
{
int surface_width = s0->get_width();
int surface_height = s0->get_height();
if (offset < 0 || offset > surface_width || y0 < 0 || y0 >= surface_height ||
y1 < 0 || y1 >= surface_height || x0 < 0 || x0 >= surface_width || x1 < 0 || x1 >= surface_width)
{
ASSERT(false);
return -1;
}
int width = (x1 - x0 + 1);
if (width < 0 || width > surface_width || width < offset)
{
ASSERT(false);
return -1;
}
x0 = (x0 >= m_width) ? (m_width - 1) : x0;
x1 = (x1 >= m_width) ? (m_width - 1) : x1;
y0 = (y0 >= m_height) ? (m_height - 1) : y0;
y1 = (y1 >= m_height) ? (m_height - 1) : y1;
if (m_phy_fb)
{
for (int y = y0; y <= y1; y++)
{
//Left surface
char* addr_s = ((char*)(s0->m_fb) + (y * (s0->get_width()) + x0 + offset) * m_color_bytes);
char* addr_d = ((char*)(m_phy_fb)+(y * m_width + x0) * m_color_bytes);
memcpy(addr_d, addr_s, (width - offset) * m_color_bytes);
//Right surface
addr_s = ((char*)(s1->m_fb) + (y * (s1->get_width()) + x0) * m_color_bytes);
addr_d = ((char*)(m_phy_fb)+(y * m_width + x0 + (width - offset)) * m_color_bytes);
memcpy(addr_d, addr_s, offset * m_color_bytes);
}
}
else if (m_color_bytes == 4)
{
void(*draw_pixel)(int x, int y, unsigned int rgb) = ((c_surface_no_fb*)s0)->m_gfx_op->draw_pixel;
for (int y = y0; y <= y1; y++)
{
//Left surface
for (int x = x0; x <= (x1 - offset); x++)
{
draw_pixel(x, y, ((unsigned int*)s0->m_fb)[y * m_width + x + offset]);
}
//Right surface
for (int x = x1 - offset; x <= x1; x++)
{
draw_pixel(x, y, ((unsigned int*)s1->m_fb)[y * m_width + x + offset - x1 + x0]);
}
}
}
else if (m_color_bytes == 2)
{
void(*draw_pixel)(int x, int y, unsigned int rgb) = ((c_surface_no_fb*)s0)->m_gfx_op->draw_pixel;
for (int y = y0; y <= y1; y++)
{
//Left surface
for (int x = x0; x <= (x1 - offset); x++)
{
draw_pixel(x, y, GL_RGB_16_to_32(((unsigned short*)s0->m_fb)[y * m_width + x + offset]));
}
//Right surface
for (int x = x1 - offset; x <= x1; x++)
{
draw_pixel(x, y, GL_RGB_16_to_32(((unsigned short*)s1->m_fb)[y * m_width + x + offset - x1 + x0]));
}
}
}
m_phy_write_index++;
return 0;
}
#endif

View File

@@ -1,20 +1,42 @@
#ifndef GUILITE_CORE_INCLUDE_RECT_H
#define GUILITE_CORE_INCLUDE_RECT_H
#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))
class c_rect
{
public:
c_rect(){Empty();}
c_rect(int left, int top, int right, int bottom){m_left = left;m_top = top;m_right = right;m_bottom = bottom;};
void SetRect( int left, int top, int right, int bottom);
c_rect(const c_rect&);
c_rect& operator=(const c_rect&);
void Empty();
void Offset(int x, int y);
int IsEmpty() const ;
bool PtInRect(int x, int y) const ;
int operator==(const c_rect& ) const;
c_rect operator&(const c_rect& aRect) const;
void SetRect(int Left, int Top, int Right, int Bottom)
{
m_left = MIN(Left, Right);
m_top = MIN(Top, Bottom);
m_right = MAX(Left, Right);
m_bottom = MAX(Top, Bottom);
}
c_rect(const c_rect& rect)
{
SetRect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom);
}
void Empty()
{
m_left = m_top = m_right = m_bottom = 0;
}
int IsEmpty() const
{
return m_top == m_bottom || m_left == m_right;
}
bool PtInRect(int x, int y) const
{
return x >= m_left && x <= m_right && y >= m_top && y <= m_bottom;
}
int operator==(const c_rect& rect) const
{
return (m_left == rect.m_left) && (m_top == rect.m_top) &&
(m_right == rect.m_right) && (m_bottom == rect.m_bottom);
}
int Width() const {return m_right - m_left + 1;}
int Height() const {return m_bottom - m_top + 1;}

View File

@@ -1,85 +0,0 @@
#ifndef GUILITE_CORE_INCLUDE_SURFACE_H
#define GUILITE_CORE_INCLUDE_SURFACE_H
class c_frame_layer
{
public:
c_frame_layer() { fb = 0;}
unsigned short* fb;
c_rect visible_rect;
};
typedef enum
{
Z_ORDER_LEVEL_0,//view/wave/page
Z_ORDER_LEVEL_1,//dialog
Z_ORDER_LEVEL_2,//editbox/spinbox/listbox/keyboard
Z_ORDER_LEVEL_MAX
}Z_ORDER_LEVEL;
struct EXTERNAL_GFX_OP
{
void(*draw_pixel)(int x, int y, unsigned int rgb);
void(*fill_rect)(int x0, int y0, int x1, int y1, unsigned int rgb);
};
class c_display;
class c_surface {
friend class c_display; friend class c_bitmap;
public:
int get_width() { return m_width; }
int get_height() { return m_height; }
unsigned int get_pixel(int x, int y, unsigned int z_order);
void draw_pixel(int x, int y, unsigned int rgb, unsigned int z_order);
void fill_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order);
void draw_hline(int x0, int x1, int y, unsigned int rgb, unsigned int z_order);
void draw_vline(int x, int y0, int y1, unsigned int rgb, unsigned int z_order);
void draw_line(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order);
void draw_rect(int x0, int y0, int x1, int y1, unsigned int rgb, unsigned int z_order, unsigned int size = 1);
inline void draw_rect(c_rect rect, unsigned int rgb, unsigned int size, unsigned int z_order)
{
draw_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, rgb, z_order, size);
}
inline void fill_rect(c_rect rect, unsigned int rgb, unsigned int z_order)
{
fill_rect(rect.m_left, rect.m_top, rect.m_right, rect.m_bottom, rgb, z_order);
}
int flush_screen(int left, int top, int right, int bottom);
bool is_valid(c_rect rect);
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);
void set_active(bool flag){m_is_active = flag;}
protected:
virtual void fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb);
virtual void draw_pixel_on_fb(int x, int y, unsigned int rgb);
void set_surface(Z_ORDER_LEVEL max_z_order);
c_surface(c_display* display, unsigned int width, unsigned int height, unsigned int color_bytes);
int m_width; //in pixels
int m_height; //in pixels
int m_color_bytes; //16 bits, 32 bits only
void* m_fb; //Top frame buffer you could see
c_frame_layer m_frame_layers[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;
void* m_phy_fb;
int* m_phy_write_index;
c_display* m_display;
};
class c_surface_no_fb : public c_surface {//No physical framebuffer, memory fb is 32 bits
friend class c_display;
c_surface_no_fb(c_display* display, unsigned int width, unsigned int height, unsigned int color_bytes, struct EXTERNAL_GFX_OP* gfx_op) :
c_surface(display, width, height, color_bytes) {m_gfx_op = gfx_op;}
protected:
virtual void fill_rect_on_fb(int x0, int y0, int x1, int y1, unsigned int rgb);
virtual void draw_pixel_on_fb(int x, int y, unsigned int rgb);
struct EXTERNAL_GFX_OP* m_gfx_op;//Rendering by external method
};
#endif

View File

@@ -1,6 +1,10 @@
#ifndef GUILITE_CORE_INCLUDE_THEME_H
#define GUILITE_CORE_INCLUDE_THEME_H
#include "../core_include/api.h"
#include "../core_include/rect.h"
#include "../core_include/resource.h"
typedef struct struct_font_info FONT_INFO;
typedef struct struct_color_rect COLOR_RECT;
typedef struct struct_bitmap_info BITMAP_INFO;
@@ -16,6 +20,7 @@ enum FONT_TYPE
FONT_CUSTOM4,
FONT_CUSTOM5,
FONT_CUSTOM6,
FONT_MAX
};
@@ -52,14 +57,67 @@ enum COLOR_TYPE
class c_theme
{
public:
static int add_font(FONT_TYPE index, const FONT_INFO* font);
static const FONT_INFO* get_font(FONT_TYPE index);
static int add_bitmap(BITMAP_TYPE index, const BITMAP_INFO* bmp);
static const BITMAP_INFO* get_bmp(BITMAP_TYPE index);
static int add_color(COLOR_TYPE index, const unsigned int color);
static const unsigned int get_color(COLOR_TYPE index);
static int add_font(FONT_TYPE index, const FONT_INFO* font)
{
if (index >= FONT_MAX)
{
ASSERT(false);
return -1;
}
s_font_map[index] = font;
return 0;
}
static const FONT_INFO* get_font(FONT_TYPE index)
{
if (index >= FONT_MAX)
{
ASSERT(false);
return 0;
}
return s_font_map[index];
}
static int add_bitmap(BITMAP_TYPE index, const BITMAP_INFO* bmp)
{
if (index >= BITMAP_MAX)
{
ASSERT(false);
return -1;
}
s_bmp_map[index] = bmp;
return 0;
}
static const BITMAP_INFO* get_bmp(BITMAP_TYPE index)
{
if (index >= BITMAP_MAX)
{
ASSERT(false);
return 0;
}
return s_bmp_map[index];
}
static int add_color(COLOR_TYPE index, const unsigned int color)
{
if (index >= COLOR_MAX)
{
ASSERT(false);
return -1;
}
s_color_map[index] = color;
return 0;
}
static const unsigned int get_color(COLOR_TYPE index)
{
if (index >= COLOR_MAX)
{
ASSERT(false);
return 0;
}
return s_color_map[index];
}
private:
static const FONT_INFO* s_font_map[FONT_MAX];
static const BITMAP_INFO* s_bmp_map[BITMAP_MAX];
static unsigned int s_color_map[COLOR_MAX];
};
#endif

View File

@@ -1,6 +1,13 @@
#ifndef GUILITE_CORE_INCLUDE_WND_H
#define GUILITE_CORE_INCLUDE_WND_H
#include "../core_include/api.h"
#include "../core_include/rect.h"
#include "../core_include/cmd_target.h"
#include "../core_include/resource.h"
#include "../core_include/bitmap.h"
#include "../core_include/display.h"
typedef struct struct_font_info FONT_INFO;
typedef struct struct_color_rect COLOR_RECT;
@@ -51,23 +58,130 @@ class c_wnd : public c_cmd_target
{
friend class c_dialog;
public:
c_wnd();
c_wnd() : m_status(STATUS_NORMAL), m_attr((WND_ATTRIBUTION)(ATTR_VISIBLE | ATTR_FOCUS)), m_parent(0), m_top_child(0), m_prev_sibling(0), m_next_sibling(0),
m_str(0), m_font_color(0), m_bg_color(0), m_id(0), m_z_order(Z_ORDER_LEVEL_0), m_focus_child(0), m_surface(0) {};
virtual ~c_wnd() {};
virtual int connect(c_wnd *parent, unsigned short resource_id, const char* str,
short x, short y, short width, short height, WND_TREE* p_child_tree = 0);
void disconnect();
short x, short y, short width, short height, WND_TREE* p_child_tree = 0)
{
if (0 == resource_id)
{
ASSERT(false);
return -1;
}
m_id = resource_id;
set_str(str);
m_parent = parent;
m_status = STATUS_NORMAL;
if (parent)
{
m_z_order = parent->m_z_order;
m_surface = parent->m_surface;
}
if (0 == m_surface)
{
ASSERT(false);
return -2;
}
/* (cs.x = x * 1024 / 768) for 1027*768=>800*600 quickly*/
m_wnd_rect.m_left = x;
m_wnd_rect.m_top = y;
m_wnd_rect.m_right = (x + width - 1);
m_wnd_rect.m_bottom = (y + height - 1);
c_rect rect;
get_screen_rect(rect);
ASSERT(m_surface->is_valid(rect));
pre_create_wnd();
if (0 != parent)
{
parent->add_child_2_tail(this);
}
if (load_child_wnd(p_child_tree) >= 0)
{
load_cmd_msg();
on_init_children();
}
return 0;
}
void disconnect()
{
if (0 == m_id)
{
return;
}
if (0 != m_top_child)
{
c_wnd* child = m_top_child;
c_wnd* next_child = 0;
while (child)
{
next_child = child->m_next_sibling;
child->disconnect();
child = next_child;
}
}
if (0 != m_parent)
{
m_parent->unlink_child(this);
}
m_focus_child = 0;
m_id = 0;
}
virtual void on_init_children() {}
virtual void on_paint() {}
virtual void show_window();
virtual void show_window()
{
if (ATTR_VISIBLE == (m_attr & ATTR_VISIBLE))
{
on_paint();
c_wnd* child = m_top_child;
if (0 != child)
{
while (child)
{
child->show_window();
child = child->m_next_sibling;
}
}
}
}
unsigned short get_id() const { return m_id; }
int get_z_order() { return m_z_order; }
c_wnd* get_wnd_ptr(unsigned short id) const;
c_wnd* get_wnd_ptr(unsigned short id) const
{
c_wnd* child = m_top_child;
while (child)
{
if (child->get_id() == id)
{
break;
}
child = child->m_next_sibling;
}
return child;
}
unsigned int get_attr() const { return m_attr; }
void set_str(const char* str) { m_str = str; }
void set_attr(WND_ATTRIBUTION attr) { m_attr = attr; }
bool is_focus_wnd() const;
bool is_focus_wnd() const
{
return ((m_attr & ATTR_VISIBLE) && (m_attr & ATTR_FOCUS)) ? true : false;
}
void set_font_color(unsigned int color) { m_font_color = color; }
unsigned int get_font_color() { return m_font_color; }
@@ -76,33 +190,325 @@ public:
void set_font_type(const FONT_INFO *font_type) { m_font_type = font_type; }
const FONT_INFO* get_font_type() { return m_font_type; }
void set_wnd_pos(short x, short y, short width, short height);
void get_wnd_rect(c_rect &rect) const;
void get_screen_rect(c_rect &rect) const;
void set_wnd_pos(short x, short y, short width, short height)
{
m_wnd_rect.m_left = x;
m_wnd_rect.m_top = y;
m_wnd_rect.m_right = x + width - 1;
m_wnd_rect.m_bottom = y + height - 1;
}
void get_wnd_rect(c_rect &rect) const { rect = m_wnd_rect; }
void get_screen_rect(c_rect &rect) const
{
rect.SetRect(0, 0, (m_wnd_rect.Width() - 1), (m_wnd_rect.Height() - 1));
wnd2screen(rect);
}
c_wnd* set_child_focus(c_wnd *focus_child);
c_wnd* set_child_focus(c_wnd *focus_child)
{
ASSERT(0 != focus_child);
ASSERT(focus_child->m_parent == this);
c_wnd* old_focus_child = m_focus_child;
if (focus_child->is_focus_wnd())
{
if (focus_child != old_focus_child)
{
if (old_focus_child)
{
old_focus_child->on_kill_focus();
}
m_focus_child = focus_child;
m_focus_child->on_focus();
}
}
return m_focus_child;
}
c_wnd* get_parent() const { return m_parent; }
c_wnd* get_last_child() const;
int unlink_child(c_wnd *child);
c_wnd* get_last_child() const
{
if (0 == m_top_child)
{
return 0;
}
c_wnd* child = m_top_child;
while (child->m_next_sibling)
{
child = child->m_next_sibling;
}
return child;
}
int unlink_child(c_wnd *child)
{
if ((0 == child)
|| (this != child->m_parent))
{
return -1;
}
if (0 == m_top_child)
{
return -2;
}
bool find = false;
c_wnd* tmp_child = m_top_child;
if (tmp_child == child)
{
m_top_child = child->m_next_sibling;
if (0 != child->m_next_sibling)
{
child->m_next_sibling->m_prev_sibling = 0;
}
find = true;
}
else
{
while (tmp_child->m_next_sibling)
{
if (child == tmp_child->m_next_sibling)
{
tmp_child->m_next_sibling = child->m_next_sibling;
if (0 != child->m_next_sibling)
{
child->m_next_sibling->m_prev_sibling = tmp_child;
}
find = true;
break;
}
tmp_child = tmp_child->m_next_sibling;
}
}
if (true == find)
{
if (m_focus_child == child)
{
m_focus_child = 0;
}
child->m_next_sibling = 0;
child->m_prev_sibling = 0;
return 1;
}
else
{
return 0;
}
}
c_wnd* get_prev_sibling() const { return m_prev_sibling; }
c_wnd* get_next_sibling() const { return m_next_sibling; }
void notify_parent(int msg_id, int param);
void notify_parent(int msg_id, int param)
{
if (!m_parent)
{
return;
}
const GL_MSG_ENTRY* entry = m_parent->find_msg_entry(m_parent->get_msg_entries(), MSG_TYPE_WND, msg_id);
if (0 == entry)
{
return;
}
(m_parent->*(entry->callBack))(m_id, param);
}
virtual void on_touch(int x, int y, TOUCH_ACTION action);
virtual void on_key(KEY_TYPE key);
virtual void on_touch(int x, int y, TOUCH_ACTION action)
{
c_wnd* model_wnd = 0;
c_wnd* tmp_child = m_top_child;
while (tmp_child)
{
if ((tmp_child->m_attr & ATTR_PRIORITY) && (tmp_child->m_attr & ATTR_VISIBLE))
{
model_wnd = tmp_child;
break;
}
tmp_child = tmp_child->m_next_sibling;
}
if (model_wnd)
{
return model_wnd->on_touch(x, y, action);
}
x -= m_wnd_rect.m_left;
y -= m_wnd_rect.m_top;
c_wnd* child = m_top_child;
while (child)
{
if (child->is_focus_wnd())
{
c_rect rect;
child->get_wnd_rect(rect);
if (true == rect.PtInRect(x, y))
{
return child->on_touch(x, y, action);
}
}
child = child->m_next_sibling;
}
}
virtual void on_key(KEY_TYPE key)
{
c_wnd* model_wnd = 0;
c_wnd* tmp_child = m_top_child;
while (tmp_child)
{
if ((tmp_child->m_attr & ATTR_PRIORITY) && (tmp_child->m_attr & ATTR_VISIBLE))
{
model_wnd = tmp_child;
break;
}
tmp_child = tmp_child->m_next_sibling;
}
if (model_wnd)
{
return model_wnd->on_key(key);
}
if (!is_focus_wnd())
{
return;
}
if (key != KEY_BACKWARD && key != KEY_FORWARD)
{
if (m_focus_child)
{
m_focus_child->on_key(key);
}
return;
}
// Move focus
c_wnd* old_focus_wnd = m_focus_child;
// No current focus wnd, new one.
if (!old_focus_wnd)
{
c_wnd* child = m_top_child;
c_wnd* new_focus_wnd = 0;
while (child)
{
if (child->is_focus_wnd())
{
new_focus_wnd = child;
new_focus_wnd->m_parent->set_child_focus(new_focus_wnd);
child = child->m_top_child;
continue;
}
child = child->m_next_sibling;
}
return;
}
// Move focus from old wnd to next wnd
c_wnd* next_focus_wnd = (key == KEY_FORWARD) ? old_focus_wnd->m_next_sibling : old_focus_wnd->m_prev_sibling;
while (next_focus_wnd && (!next_focus_wnd->is_focus_wnd()))
{// Search neighbor of old focus wnd
next_focus_wnd = (key == KEY_FORWARD) ? next_focus_wnd->m_next_sibling : next_focus_wnd->m_prev_sibling;
}
if (!next_focus_wnd)
{// Search whole brother wnd
next_focus_wnd = (key == KEY_FORWARD) ? old_focus_wnd->m_parent->m_top_child : old_focus_wnd->m_parent->get_last_child();
while (next_focus_wnd && (!next_focus_wnd->is_focus_wnd()))
{
next_focus_wnd = (key == KEY_FORWARD) ? next_focus_wnd->m_next_sibling : next_focus_wnd->m_prev_sibling;
}
}
if (next_focus_wnd)
{
next_focus_wnd->m_parent->set_child_focus(next_focus_wnd);
}
}
c_surface* get_surface() { return m_surface; }
void set_surface(c_surface* surface) { m_surface = surface; }
protected:
virtual void pre_create_wnd() {};
void add_child_2_tail(c_wnd *child);
void add_child_2_tail(c_wnd *child)
{
if (0 == child)return;
if (child == get_wnd_ptr(child->m_id))return;
void wnd2screen(int &x, int &y) const;
void wnd2screen(c_rect &rect) const;
if (0 == m_top_child)
{
m_top_child = child;
child->m_prev_sibling = 0;
child->m_next_sibling = 0;
}
else
{
c_wnd* last_child = get_last_child();
if (0 == last_child)
{
ASSERT(false);
}
last_child->m_next_sibling = child;
child->m_prev_sibling = last_child;
child->m_next_sibling = 0;
}
}
int load_child_wnd(WND_TREE *p_child_tree);
void wnd2screen(int &x, int &y) const
{
c_wnd* parent = m_parent;
c_rect rect;
x += m_wnd_rect.m_left;
y += m_wnd_rect.m_top;
while (0 != parent)
{
parent->get_wnd_rect(rect);
x += rect.m_left;
y += rect.m_top;
parent = parent->m_parent;
}
}
void wnd2screen(c_rect &rect) const
{
int l = rect.m_left;
int t = rect.m_top;
wnd2screen(l, t);
int r = (l + rect.Width() - 1);
int b = (t + rect.Height() - 1);
rect.SetRect(l, t, r, b);
}
int load_child_wnd(WND_TREE *p_child_tree)
{
if (0 == p_child_tree)
{
return 0;
}
int sum = 0;
WND_TREE* p_cur = p_child_tree;
while (p_cur->p_wnd)
{
if (0 != p_cur->p_wnd->m_id)
{//This wnd has been used! Do not share!
ASSERT(false);
return -1;
}
else
{
p_cur->p_wnd->connect(this, p_cur->resource_id, p_cur->str,
p_cur->x, p_cur->y, p_cur->width, p_cur->height, p_cur->p_child_tree);
}
p_cur++;
sum++;
}
return sum;
}
void set_active_child(c_wnd* child) { m_focus_child = child; }
virtual void on_focus() {};

View File

@@ -1,23 +1,303 @@
#ifndef GUILITE_CORE_INCLUDE_WORD_H
#define GUILITE_CORE_INCLUDE_WORD_H
#include "../core_include/api.h"
#include "../core_include/rect.h"
#include "../core_include/resource.h"
#include "../core_include/display.h"
#include <string.h>
#include <stdio.h>
#define BUFFER_LEN 16
class c_surface;
class c_word
{
public:
static void draw_string(c_surface* surface, int z_order, const char *s, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT);
static void draw_string_in_rect(c_surface* surface, int z_order, const char *s, c_rect rect, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT);
static void draw_value(c_surface* surface, int z_order, int value, int dot_position, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT);
static void draw_value_in_rect(c_surface* surface, int z_order, int value, int dot_position, c_rect rect, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT);
static void value_2_string(int value, int dot_position, char* buf, int len);
static void draw_string(c_surface* surface, int z_order, const char *s, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT)
{
if (0 == s)
{
return;
}
static int get_str_size(const char *s, const FONT_INFO* font, int& width, int& height);
int offset = 0;
unsigned int utf8_code;
while (*s)
{
s += get_utf8_code(s, utf8_code);
offset += draw_single_char(surface, z_order, utf8_code, (x + offset), y, font, font_color, bg_color);
}
}
static void draw_string_in_rect(c_surface* surface, int z_order, const char *s, c_rect rect, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT)
{
if (0 == s)
{
return;
}
int x, y;
get_string_pos(s, font, rect, align_type, x, y);
draw_string(surface, z_order, s, rect.m_left + x, rect.m_top + y, font, font_color, bg_color, ALIGN_LEFT);
}
static void draw_value(c_surface* surface, int z_order, int value, int dot_position, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT)
{
char buf[BUFFER_LEN];
value_2_string(value, dot_position, buf, BUFFER_LEN);
draw_string(surface, z_order, buf, x, y, font, font_color, bg_color, align_type);
}
static void draw_value_in_rect(c_surface* surface, int z_order, int value, int dot_position, c_rect rect, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color, unsigned int align_type = ALIGN_LEFT)
{
char buf[BUFFER_LEN];
value_2_string(value, dot_position, buf, BUFFER_LEN);
draw_string_in_rect(surface, z_order, buf, rect, font, font_color, bg_color, align_type);
}
static void value_2_string(int value, int dot_position, char* buf, int len)
{
memset(buf, 0, len);
switch (dot_position)
{
case 0:
sprintf(buf, "%d", value);
break;
case 1:
sprintf(buf, "%.1f", value * 1.0 / 10);
break;
case 2:
sprintf(buf, "%.2f", value * 1.0 / 100);
break;
case 3:
sprintf(buf, "%.3f", value * 1.0 / 1000);
break;
default:
ASSERT(false);
break;
}
}
static int get_str_size(const char *s, const FONT_INFO* font, int& width, int& height)
{
if (0 == s || 0 == font)
{
width = height = 0;
return -1;
}
int lattice_width = 0;
unsigned int utf8_code;
int utf8_bytes;
while (*s)
{
utf8_bytes = get_utf8_code(s, utf8_code);
const LATTICE* p_lattice = get_lattice(font, utf8_code);
lattice_width += p_lattice ? p_lattice->width : font->height;
s += utf8_bytes;
}
width = lattice_width;
height = font->height;
return 0;
}
private:
static int draw_single_char(c_surface* surface, int z_order, unsigned int utf8_code, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color);
static void draw_lattice(c_surface* surface, int z_order, int x, int y, int width, int height, const unsigned char* p_data, unsigned int font_color, unsigned int bg_color);
static int draw_single_char(c_surface* surface, int z_order, unsigned int utf8_code, int x, int y, const FONT_INFO* font, unsigned int font_color, unsigned int bg_color)
{
unsigned int error_color = 0xFFFFFFFF;
if (font)
{
const LATTICE* p_lattice = get_lattice(font, utf8_code);
if (p_lattice)
{
draw_lattice(surface, z_order, x, y, p_lattice->width, font->height, p_lattice->pixel_gray_array, font_color, bg_color);
return p_lattice->width;
}
}
else
{
error_color = GL_RGB(255, 0, 0);
}
//lattice/font not found, draw "X"
int len = 16;
for (int y_ = 0; y_ < len; y_++)
{
for (int x_ = 0; x_ < len; x_++)
{
int diff = (x_ - y_);
int sum = (x_ + y_);
(diff == 0 || diff == -1 || diff == 1 || sum == len || sum == (len - 1) || sum == (len + 1)) ?
surface->draw_pixel((x + x_), (y + y_), error_color, z_order) : surface->draw_pixel((x + x_), (y + y_), 0, z_order);
}
}
return len;
}
static void draw_lattice(c_surface* surface, int z_order, int x, int y, int width, int height, const unsigned char* p_data, unsigned int font_color, unsigned int bg_color)
{
unsigned int r, g, b, rgb;
unsigned char blk_value = *p_data++;
unsigned char blk_cnt = *p_data++;
b = (GL_RGB_B(font_color) * blk_value + GL_RGB_B(bg_color) * (255 - blk_value)) >> 8;
g = (GL_RGB_G(font_color) * blk_value + GL_RGB_G(bg_color) * (255 - blk_value)) >> 8;
r = (GL_RGB_R(font_color) * blk_value + GL_RGB_R(bg_color) * (255 - blk_value)) >> 8;
rgb = GL_RGB(r, g, b);
for (int y_ = 0; y_ < height; y_++)
{
for (int x_ = 0; x_ < width; x_++)
{
ASSERT(blk_cnt);
if (0x00 == blk_value)
{
if (GL_ARGB_A(bg_color))
{
surface->draw_pixel(x + x_, y + y_, bg_color, z_order);
}
}
else
{
surface->draw_pixel((x + x_), (y + y_), rgb, z_order);
}
if (--blk_cnt == 0)
{//reload new block
blk_value = *p_data++;
blk_cnt = *p_data++;
b = (GL_RGB_B(font_color) * blk_value + GL_RGB_B(bg_color) * (255 - blk_value)) >> 8;
g = (GL_RGB_G(font_color) * blk_value + GL_RGB_G(bg_color) * (255 - blk_value)) >> 8;
r = (GL_RGB_R(font_color) * blk_value + GL_RGB_R(bg_color) * (255 - blk_value)) >> 8;
rgb = GL_RGB(r, g, b);
}
}
}
}
static const LATTICE* get_lattice(const FONT_INFO* font, unsigned int utf8_code);
static void get_string_pos(const char *s, const FONT_INFO* font, c_rect rect, unsigned int align_type, int &x, int &y);
static const LATTICE* get_lattice(const FONT_INFO* font, unsigned int utf8_code)
{
int first = 0;
int last = font->count - 1;
int middle = (first + last) / 2;
while (first <= last)
{
if (font->lattice_array[middle].utf8_code < utf8_code)
first = middle + 1;
else if (font->lattice_array[middle].utf8_code == utf8_code)
{
return &font->lattice_array[middle];
}
else
{
last = middle - 1;
}
middle = (first + last) / 2;
}
return 0;
}
static void get_string_pos(const char *s, const FONT_INFO* font, c_rect rect, unsigned int align_type, int &x, int &y)
{
int x_size, y_size;
get_str_size(s, font, x_size, y_size);
int height = rect.m_bottom - rect.m_top + 1;
int width = rect.m_right - rect.m_left + 1;
x = y = 0;
switch (align_type & ALIGN_HMASK)
{
case ALIGN_HCENTER:
//m_text_org_x=0
if (width > x_size)
{
x = (width - x_size) / 2;
}
break;
case ALIGN_LEFT:
x = 0;
break;
case ALIGN_RIGHT:
//m_text_org_x=0
if (width > x_size)
{
x = width - x_size;
}
break;
default:
ASSERT(0);
break;
}
switch (align_type & ALIGN_VMASK)
{
case ALIGN_VCENTER:
//m_text_org_y=0
if (height > y_size)
{
y = (height - y_size) / 2;
}
break;
case ALIGN_TOP:
y = 0;
break;
case ALIGN_BOTTOM:
//m_text_org_y=0
if (height > y_size)
{
y = height - y_size;
}
break;
default:
ASSERT(0);
break;
}
}
static int get_utf8_code(const char* s, unsigned int& output_utf8_code)
{
static unsigned char s_utf8_length_table[256] =
{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1
};
unsigned char* us = (unsigned char*)s;
int utf8_bytes = s_utf8_length_table[*us];
switch (utf8_bytes)
{
case 1:
output_utf8_code = *us;
break;
case 2:
output_utf8_code = (*us << 8) | (*(us + 1));
break;
case 3:
output_utf8_code = (*us << 16) | ((*(us + 1)) << 8) | *(us + 2);
break;
case 4:
output_utf8_code = (*us << 24) | ((*(us + 1)) << 16) | (*(us + 2) << 8) | *(us + 3);
break;
default:
ASSERT(false);
break;
}
return utf8_bytes;
}
};
#endif