#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; }