1.1多分辨率顯示系統的挑戰與解決方案
1.1.1 分辨率適配的核心問題
在嵌入式系統中,同時支持不同分辨率的 LCD(如 240×160、320×480 等)面臨以下挑戰:
布局適配:同一界面元素在不同分辨率下需要調整大小和位置
字體顯示:小分辨率屏幕需要更小的字體,而大分辨率需要更清晰的字體
內存占用:高分辨率屏幕需要更多顯存,而低分辨率需要優化內存使用
渲染性能:高分辨率屏幕渲染壓力更大,需要優化渲染算法
針對這些問題, 采用以下解決方案:
抽象顯示接口:定義統一的顯示操作接口,屏蔽底層硬件差異
相對布局系統:使用百分比或相對單位定義界面元素位置和大小
字體動態縮放:根據屏幕分辨率動態調整字體大小
資源按需加載:根據當前屏幕分辨率選擇合適的圖片和字體資源
1.1.2 單色屏與彩屏的兼容性設計
同時支持單色屏和彩屏時,需要解決以下問題:
顏色表示:單色屏只有黑白兩色,而彩屏支持多種顏色
圖形渲染:彩屏支持漸變、陰影等復雜效果,單色屏需要簡化
交互反饋:彩屏可通過顏色變化提供反饋,單色屏需依賴對比度或閃爍
解決方案包括:
顏色抽象層:定義顏色映射表,將 RGB 顏色映射到單色屏的黑白值
渲染策略分離:為單色屏和彩屏分別實現不同的渲染算法
交互反饋統一:使用統一的交互反饋接口,底層根據屏幕類型實現
1.2 統一顯示抽象層設計
1.2.1 顯示接口定義
我們首先定義一個抽象的顯示接口,屏蔽不同分辨率和類型的 LCD 差異:
c
/**
* 顯示抽象層接口定義
* 支持不同分辨率和類型的LCD
*/
#ifndef DISPLAY_ABSTRACTION_H
#define DISPLAY_ABSTRACTION_H
#include <stdint.h>
#include <stdbool.h>
/* 顏色定義 - 采用RGB565格式 */
typedef uint16_t color_t;
/* 標準顏色常量 */
#define COLOR_BLACK 0x0000
#define COLOR_WHITE 0xFFFF
#define COLOR_RED 0xF800
#define COLOR_GREEN 0x07E0
#define COLOR_BLUE 0x001F
#define COLOR_YELLOW 0xFFE0
#define COLOR_CYAN 0x07FF
#define COLOR_MAGENTA 0xF81F
/* 顯示區域結構體 */
typedef struct
{
uint16_t x;
uint16_t y;
uint16_t width;
uint16_t height;
} rect_t;
/* 顯示設備能力結構體 */
typedef struct
{
uint16_t width; /* 屏幕寬度 */
uint16_t height; /* 屏幕高度 */
uint8_t bits_per_pixel; /* 每像素位數 */
bool color_support; /* 是否支持彩色 */
uint16_t max_font_size; /* 最大支持字體大小 */
uint16_t min_font_size; /* 最小支持字體大小 */
} display_capabilities_t;
/* 顯示接口函數指針結構體 */
typedef struct
{
/* 基本操作 */
void (*init)(void);
void (*clear)(color_t color);
void (*refresh)(void);
/* 繪制基本圖形 */
void (*draw_pixel)(uint16_t x, uint16_t y, color_t color);
void (*draw_line)(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, color_t color);
void (*draw_rect)(uint16_t x, uint16_t y, uint16_t width, uint16_t height, color_t color);
void (*fill_rect)(uint16_t x, uint16_t y, uint16_t width, uint16_t height, color_t color);
void (*draw_circle)(uint16_t x, uint16_t y, uint16_t radius, color_t color);
void (*fill_circle)(uint16_t x, uint16_t y, uint16_t radius, color_t color);
/* 文本繪制 */
void (*set_font_size)(uint8_t size);
void (*set_text_color)(color_t color, color_t background);
void (*draw_char)(uint16_t x, uint16_t y, char c);
void (*draw_string)(uint16_t x, uint16_t y, const char* str);
/* 圖像繪制 */
void (*draw_image)(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t* data);
/* 獲取顯示能力 */
void (*get_capabilities)(display_capabilities_t* caps);
} display_interface_t;
/* 獲取當前顯示接口實例 */
display_interface_t* get_display_interface(void);
/* 設置當前顯示接口實例 */
void set_display_interface(display_interface_t* display);
#endif /* DISPLAY_ABSTRACTION_H */
1.2.2 顯示接口實現
下面是顯示接口的基礎實現,提供了統一的操作入口:
/**
* 顯示抽象層實現
*/
#include "display_abstraction.h"
/* 當前顯示接口實例 */
static display_interface_t* current_display = NULL;
/* 獲取當前顯示接口實例 */
display_interface_t* get_display_interface(void)
{
return current_display;
}
/* 設置當前顯示接口實例 */
void set_display_interface(display_interface_t* display)
{
current_display = display;
}
/* 通用繪制函數 - 使用當前顯示接口 */
void display_clear(color_t color)
{
if (current_display && current_display->clear)
{
current_display->clear(color);
}
}
void display_refresh(void)
{
if (current_display && current_display->refresh)
{
current_display->refresh();
}
}
void display_draw_pixel(uint16_t x, uint16_t y, color_t color)
{
if (current_display && current_display->draw_pixel)
{
current_display->draw_pixel(x, y, color);
}
}
// 其他通用繪制函數實現...
1.3 相對布局系統設計
1.3.1 布局管理器設計
為了實現跨分辨率的 GUI 適配,我們設計一個相對布局管理器:
/**
* 相對布局管理器
* 支持基于百分比的界面元素布局
*/
#ifndef LAYOUT_MANAGER_H
#define LAYOUT_MANAGER_H
#include "display_abstraction.h"
/* 對齊方式枚舉 */
typedef enum
{
ALIGN_LEFT,
ALIGN_CENTER,
ALIGN_RIGHT,
ALIGN_TOP,
ALIGN_MIDDLE,
ALIGN_BOTTOM
} alignment_t;
/* 相對位置結構體 */
typedef struct
{
float x_percent; /* X坐標百分比 (0.0-1.0) */
float y_percent; /* Y坐標百分比 (0.0-1.0) */
float width_percent; /* 寬度百分比 (0.0-1.0) */
float height_percent; /* 高度百分比 (0.0-1.0) */
alignment_t h_align; /* 水平對齊方式 */
alignment_t v_align; /* 垂直對齊方式 */
} relative_position_t;
/* GUI元素基類 */
typedef struct gui_element
{
char* id; /* 元素ID */
relative_position_t position; /* 相對位置 */
bool visible; /* 是否可見 */
/* 繪制函數 */
void (*draw)(struct gui_element* element);
/* 事件處理函數 */
bool (*handle_event)(struct gui_element* element, void* event);
/* 布局計算函數 */
void (*calculate_layout)(struct gui_element* element, rect_t* parent_rect);
/* 實際屏幕位置 */
rect_t screen_rect;
/* 指向下一個元素的指針 */
struct gui_element* next;
} gui_element_t;
/* 布局管理器 */
typedef struct
{
gui_element_t* elements; /* 元素鏈表 */
display_interface_t* display; /* 顯示接口 */
rect_t root_rect; /* 根區域 */
} layout_manager_t;
/* 初始化布局管理器 */
void layout_manager_init(layout_manager_t* manager, display_interface_t* display);
/* 添加GUI元素 */
void layout_manager_add_element(layout_manager_t* manager, gui_element_t* element);
/* 移除GUI元素 */
void layout_manager_remove_element(layout_manager_t* manager, gui_element_t*