357 lines
9.2 KiB
C
357 lines
9.2 KiB
C
#include "mywin_inc.h"
|
||
|
||
// 使用点阵显示字体
|
||
static u32 WIN_DrawCharAtCommon(char c, int x, int y);
|
||
static u32 WIN_DrawWordAtCommon(char *c, int x, int y);
|
||
|
||
// 使用透明度显示字体
|
||
static u32 WIN_DrawCharAtNormal(char c, int x, int y);
|
||
static u32 WIN_DrawWordAtNormal(char *c, int x, int y);
|
||
|
||
// 返回字体高度
|
||
int WIN_GetFontHight(void) { return WIN_GetWinStruct()->font.TxtH; }
|
||
|
||
// 返回字体宽度
|
||
int WIN_GetFontWidth(void) { return WIN_GetWinStruct()->font.TxtW; }
|
||
|
||
// 设置字体模式,1,填充背景,0,不填充背景
|
||
int WIN_SetFontMode(int mode) {
|
||
WIN_GetWinStruct()->lcd->setDrawMode(!mode);
|
||
return 0;
|
||
}
|
||
|
||
//-------------------------字形缓冲区--------------------------------------
|
||
|
||
typedef struct {
|
||
int word;
|
||
u32 data_size;
|
||
u8 *data;
|
||
} _font_data;
|
||
|
||
typedef struct {
|
||
u32 buff_size; // 总大小
|
||
u32 buff_used; // 使用了多少
|
||
_font_data *font_data;
|
||
} WIN_FontBuffStruct;
|
||
|
||
// 定义字形缓冲池的个数
|
||
#define FONT_NUM 200
|
||
static WIN_FontBuffStruct *g_font;
|
||
|
||
// 创建一个指定大小的字形缓冲区
|
||
WIN_FontBuffStruct *WIN_CreatFontBuff(u32 size) {
|
||
WIN_FontBuffStruct *ret = mycalloc(sizeof(WIN_FontBuffStruct));
|
||
if (ret == 0)
|
||
return ret;
|
||
|
||
ret->font_data = mymalloc_exm(sizeof(_font_data) * size);
|
||
if (ret->font_data == 0) {
|
||
myfree(ret);
|
||
ret = 0;
|
||
return ret;
|
||
}
|
||
mymemset(ret->font_data, 0, sizeof(_font_data) * size);
|
||
ret->buff_size = size;
|
||
return ret;
|
||
}
|
||
|
||
// 删除一个字形缓冲区
|
||
void WIN_DeleteFontBuff(WIN_FontBuffStruct *font) {
|
||
if (font) {
|
||
WIN_FontDrawFunStruct *fn = &WIN_GetWinStruct()->font;
|
||
for (int i = 0; i < font->buff_used; i++) {
|
||
_font_data *font_data = &font->font_data[i];
|
||
if (font_data->data)
|
||
fn->free(font_data->data);
|
||
}
|
||
myfree(font->font_data);
|
||
myfree(font);
|
||
}
|
||
}
|
||
|
||
// 在index的位置留出插入新字符的空间
|
||
int WIN_InsertFont(WIN_FontBuffStruct *font, _font_data *data, int index) {
|
||
if (font == 0)
|
||
return 0;
|
||
if (index > font->buff_used)
|
||
return 0;
|
||
WIN_FontDrawFunStruct *fn = &WIN_GetWinStruct()->font;
|
||
int num = font->buff_used - index;
|
||
_font_data *font_data = &font->font_data[index];
|
||
|
||
// index之后的向后移
|
||
if (font->buff_used >= font->buff_size) {
|
||
// 缓冲池已满,删除最后一个
|
||
_font_data *end = &font->font_data[font->buff_used - 1];
|
||
fn->free(end->data);
|
||
} else {
|
||
font->buff_used++;
|
||
}
|
||
// 直接向后移
|
||
for (int i = num; i > 0; i--) {
|
||
_font_data *end = &font_data[i];
|
||
_font_data *first = &font_data[i - 1];
|
||
mymemcpy(end, first, sizeof(_font_data));
|
||
}
|
||
// 插入新的字符
|
||
mymemcpy(font_data, data, sizeof(_font_data));
|
||
return 1;
|
||
}
|
||
|
||
// 添加字形数据
|
||
int WIN_AddFontData(WIN_FontBuffStruct *font, u8 size, int word, u8 *buff,
|
||
u32 buff_size) {
|
||
if (font) {
|
||
_font_data font_data = {0};
|
||
font_data.word = (size << 24) | word;
|
||
font_data.data = buff;
|
||
font_data.data_size = buff_size;
|
||
if (WIN_InsertFont(font, &font_data, font->buff_used / 2) == 0)
|
||
printf("%s:insert font err \r\n", __func__);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
_font_data *WIN_FontUsed(WIN_FontBuffStruct *font, int index) {
|
||
_font_data *font_data = 0;
|
||
font_data = &font->font_data[index];
|
||
if (index != 0) {
|
||
_font_data *font_temp = mymalloc(sizeof(_font_data));
|
||
_font_data *font_first = &font->font_data[index - 1];
|
||
mymemcpy(font_temp, font_data, sizeof(_font_data));
|
||
mymemcpy(font_data, font_first, sizeof(_font_data));
|
||
mymemcpy(font_first, font_temp, sizeof(_font_data));
|
||
myfree(font_temp);
|
||
font_data = font_first;
|
||
}
|
||
return font_data;
|
||
}
|
||
|
||
// 搜索缓冲区中的字形数据
|
||
u8 *WIN_SearchFontData(WIN_FontBuffStruct *font, u8 size, int word,
|
||
u32 *buff_size) {
|
||
u8 *ret = 0;
|
||
if (font) {
|
||
int temp = (size << 24) | word; // 定义字形数据
|
||
for (int i = 0; i < font->buff_used; i++) {
|
||
int index = i;
|
||
_font_data *font_data = 0;
|
||
font_data = &font->font_data[index];
|
||
if (font_data->word == temp) {
|
||
// 使用了一次,排位靠前
|
||
font_data = WIN_FontUsed(font, index);
|
||
ret = font_data->data;
|
||
if (buff_size)
|
||
*buff_size = font_data->data_size;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
// 获取字形数据,缓冲区有就提取缓冲区的数据
|
||
// 缓冲区中没有就调用获取字形函数
|
||
u8 *WIN_GetFontData(WIN_FontBuffStruct *font, int word, u32 *buff_size) {
|
||
u8 *buff = 0;
|
||
WIN_FontDrawFunStruct *fn = &WIN_GetWinStruct()->font;
|
||
buff = WIN_SearchFontData(font, fn->TxtSize, word, buff_size);
|
||
if (buff == 0) {
|
||
buff = fn->malloc(*buff_size);
|
||
WIN_GetWordData(fn->TxtSize, fn->TxtType, buff, word, *buff_size);
|
||
WIN_AddFontData(font, fn->TxtSize, word, buff, *buff_size);
|
||
}
|
||
return buff;
|
||
}
|
||
|
||
// 设置字体尺寸
|
||
int WIN_SetFontSize(int size) {
|
||
WIN_FontDrawFunStruct *font = &WIN_GetWinStruct()->font;
|
||
int ret = font->TxtSize;
|
||
u8 set_size = size;
|
||
|
||
font->TxtSize = set_size;
|
||
font->TxtH = set_size;
|
||
font->TxtW = set_size;
|
||
if (font->TxtType == 0) {
|
||
font->drawChar = WIN_DrawCharAtCommon;
|
||
font->drawWord = WIN_DrawWordAtCommon;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
// 设置字体类型
|
||
int WIN_SetFontType(int type) {
|
||
|
||
WIN_FontDrawFunStruct *font = &WIN_GetWinStruct()->font;
|
||
int ret = font->TxtType;
|
||
font->TxtType = type ? WIN_FONT_TYPE_NORMAL : WIN_FONT_TYPE_BITMAP;
|
||
|
||
// 如果切换了显示类型,以前缓冲区的字体不能用了
|
||
if (font->TxtType != ret) {
|
||
WIN_DeleteFontBuff(g_font);
|
||
}
|
||
if (font->TxtType == WIN_FONT_TYPE_BITMAP) {
|
||
font->drawChar = WIN_DrawCharAtCommon;
|
||
font->drawWord = WIN_DrawWordAtCommon;
|
||
} else {
|
||
font->drawChar = WIN_DrawCharAtNormal;
|
||
font->drawWord = WIN_DrawWordAtNormal;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
//-------------------------绘制字体回调函数--------------------------------------
|
||
|
||
// 通用的绘制英文字符
|
||
static u32 WIN_DrawCharAtCommon(char c, int x, int y) {
|
||
u8 size = WIN_GetWinStruct()->font.TxtSize;
|
||
u8 wid = size / 2;
|
||
u8 hit = size;
|
||
s8 off_left = 0;
|
||
s8 off_up = 0;
|
||
u8 w_byte = wid / 8 + 1;
|
||
if (wid % 8)
|
||
w_byte++;
|
||
u8 h_byte = hit;
|
||
u32 all_byte = w_byte * h_byte + 5;
|
||
u32 ret = 0;
|
||
u8 *buff = 0;
|
||
|
||
// 获取字模
|
||
if (g_font == 0)
|
||
g_font = WIN_CreatFontBuff(FONT_NUM);
|
||
buff = WIN_GetFontData(g_font, c, &all_byte);
|
||
|
||
wid = buff[all_byte - 5];
|
||
hit = buff[all_byte - 4];
|
||
w_byte = buff[all_byte - 3];
|
||
off_left = buff[all_byte - 2];
|
||
off_up = (size - buff[all_byte - 1]) - size / 10;
|
||
|
||
// 显示字模
|
||
for (int j = 0; j < hit + 0; j++) {
|
||
for (int i = 0; i < wid + 0; i++) {
|
||
WIN_DrawPointSafe(x + i + off_left, y + j + off_up,
|
||
(buff[j * w_byte + i / 8] << (i % 8)) & 0x80);
|
||
}
|
||
}
|
||
ret = WIN_GetFontWidth() / 2;
|
||
|
||
return ret;
|
||
}
|
||
|
||
// 通用的绘制中文字符
|
||
static u32 WIN_DrawWordAtCommon(char *c, int x, int y) {
|
||
u8 size = WIN_GetWinStruct()->font.TxtSize;
|
||
u8 wid = size;
|
||
u8 hit = size;
|
||
s8 off_left = 0;
|
||
s8 off_up = 0;
|
||
u8 w_byte = wid / 8 + 1;
|
||
if (wid % 8)
|
||
w_byte++;
|
||
u8 h_byte = hit;
|
||
u32 all_byte = w_byte * h_byte + 5;
|
||
u32 ret = 0;
|
||
u8 *buff = 0;
|
||
|
||
// 获取字模
|
||
if (g_font == 0)
|
||
g_font = WIN_CreatFontBuff(FONT_NUM);
|
||
// 汉字utf8一般是3个字节
|
||
buff = WIN_GetFontData(g_font, (c[0] << 8) | (c[1] << 0), &all_byte);
|
||
|
||
wid = buff[all_byte - 5];
|
||
hit = buff[all_byte - 4];
|
||
w_byte = buff[all_byte - 3];
|
||
off_left = buff[all_byte - 2];
|
||
off_up = (size - buff[all_byte - 1]) - size / 10;
|
||
|
||
// 显示字模
|
||
for (int j = 0; j < hit + 0; j++) {
|
||
for (int i = 0; i < wid + 0; i++) {
|
||
WIN_DrawPointSafe(x + i + off_left, y + j + off_up,
|
||
(buff[j * w_byte + i / 8] << (i % 8)) & 0x80);
|
||
}
|
||
}
|
||
ret = WIN_GetFontWidth();
|
||
|
||
return ret;
|
||
}
|
||
|
||
// 通用的绘制英文字符
|
||
static u32 WIN_DrawCharAtNormal(char c, int x, int y) {
|
||
u8 size = WIN_GetWinStruct()->font.TxtSize;
|
||
u8 wid = size / 2;
|
||
u8 hit = size;
|
||
s8 off_left = 0;
|
||
s8 off_up = 0;
|
||
u8 w_byte = wid;
|
||
u8 h_byte = hit;
|
||
u32 all_byte = w_byte * h_byte + 5;
|
||
u32 ret = 0;
|
||
u8 *buff = 0;
|
||
|
||
// 获取字模
|
||
if (g_font == 0)
|
||
g_font = WIN_CreatFontBuff(FONT_NUM);
|
||
buff = WIN_GetFontData(g_font, c, &all_byte);
|
||
|
||
wid = buff[all_byte - 5];
|
||
hit = buff[all_byte - 4];
|
||
w_byte = buff[all_byte - 3];
|
||
off_left = buff[all_byte - 2];
|
||
off_up = (size - buff[all_byte - 1]) - size / 10;
|
||
|
||
// 显示字模
|
||
u16 color = WIN_GetLcdColor16();
|
||
for (int j = 0; j < hit + 0; j++) {
|
||
for (int i = 0; i < wid + 0; i++) {
|
||
WIN_DrawPointSafeColorAlpha(x + i + off_left, y + j + off_up, color,
|
||
buff[j * wid + i] >> 3);
|
||
}
|
||
}
|
||
ret = WIN_GetFontWidth() / 2;
|
||
|
||
return ret;
|
||
}
|
||
|
||
// 通用的绘制中文字符
|
||
static u32 WIN_DrawWordAtNormal(char *c, int x, int y) {
|
||
u8 size = WIN_GetWinStruct()->font.TxtSize;
|
||
u8 wid = size;
|
||
u8 hit = size;
|
||
s8 off_left = 0;
|
||
s8 off_up = 0;
|
||
u8 w_byte = wid;
|
||
u8 h_byte = hit;
|
||
u32 all_byte = w_byte * h_byte + 5;
|
||
u32 ret = 0;
|
||
u8 *buff = 0;
|
||
|
||
// 获取字模
|
||
if (g_font == 0)
|
||
g_font = WIN_CreatFontBuff(FONT_NUM);
|
||
buff = WIN_GetFontData(g_font, (c[0] << 8) | (c[1] << 0), &all_byte);
|
||
|
||
wid = buff[all_byte - 5];
|
||
hit = buff[all_byte - 4];
|
||
w_byte = buff[all_byte - 3];
|
||
off_left = buff[all_byte - 2];
|
||
off_up = (size - buff[all_byte - 1]) - size / 10;
|
||
|
||
// 显示字模
|
||
u16 color = WIN_GetLcdColor16();
|
||
for (int j = 0; j < hit + 0; j++) {
|
||
for (int i = 0; i < wid + 0; i++) {
|
||
WIN_DrawPointSafeColorAlpha(x + i + off_left, y + j + off_up, color,
|
||
buff[j * wid + i] >> 3);
|
||
}
|
||
}
|
||
ret = WIN_GetFontWidth();
|
||
|
||
return ret;
|
||
}
|