//===========================
// 头文件
//==========================
#ifndef __FONT_H__
#define __FONT_H__
#include "wbtypes.h"
#include "GUI.H"
#define BIT7_MASK 0x80
#define BIT6_MASK 0x40
#define BIT5_MASK 0x20
#define BIT4_MASK 0x10
#define BIT3_MASK 0x08
#define BIT2_MASK 0x04
#define BIT1_MASK 0x02
#define BIT0_MASK 0x01
typedef enum //字库编号定义
{
USER_LIB_ID_BASE = 0,
STD_LIB_ASCII_8_8 = 0X40,//标准字库起始
STD_LIB_GBK_12_12,
STD_LIB_ASCII_12_12,
STD_LIB_GBK_16_16,
STD_LIB_ASCII_16_16,
STD_LIB_GB2312_24_24,
STD_LIB_ASCII_24_24,
STD_LIB_GB2312_32_32,
STD_LIB_ASCII_32_32,
LIB_ID_MAX //字库总数
} LIB_ID;
#define STD_LIB_START (USER_LIB_ID_BASE) //标准字库id起始
#define STD_LIB_END (STD_LIB_ASCII_32_32) //标准字库id结束
#define USER_DEFINE_LIB_START 1 //用户自定义字库id起始号
#define USER_DEFINE_LIB_END (STD_LIB_ASCII_8_8 - 1) //用户自定义字库id结束号
typedef enum //编码方式
{
ENCODE_UNICODE = 0, //UNICODE 编码
ENCODE_GB2312, //GB2312 编码
ENCODE_GBK, //GBK 编码
ENCODE_MAX
} ENCODE_MODE;
#define OPEN_LIB_MAX 8
typedef struct LIB_FD_S{
// UINT8 open_cont;
UINT8 opend_index;
INT32 opend_id[OPEN_LIB_MAX];//已打开的 lib_id
INT32 fd[LIB_ID_MAX]; //文件句柄集
}LIB_FD;
typedef struct FONT_ATTR_S
{
UINT8 lib_id; //字库ID
UINT8 lib_type; //标准字库 或 自定义字库
UINT8 EncodeMode; //编码方式
UINT8 width; //字体宽度
UINT8 height; //字体高度
UINT8 bg_flag; //背景色标志
UINT8 half_width; //半角标志
UINT16 x_pos; //x轴坐标
UINT16 y_pos; //y轴坐标
UINT16 front_color; //前景色RGB565
UINT16 bg_color; //背景色RGB565
}FONT_ATTR;
#define ERR_PARAM 0x0020 //参数错误
#define FULL_WIDTH 0 //全角
#define HALF_WIDTH 1 //半角
#define STANDARD_LIB 1
#define USERDEF_LIB 2
void DrawFont(USHORT code,FONT_ATTR *font);
void DrawSting(UINT8 *pBuf,USHORT strlen,FONT_ATTR *str);
void init_lib_fd(void);
INT LIB_GBK_ReadData(USHORT Code, FONT_ATTR *font,UINT8 *pResult, INT32 *piLen);
INT LIB_GB2312_ReadData(USHORT Code, FONT_ATTR *font,UINT8 *pResult, INT32 *piLen);
INT LIB_Unicode_ReadData(USHORT Code, FONT_ATTR *font, UINT8 *pResult, INT32 *piLen);
#endif
//======================
// font.c
//======================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "font.h"
#include "nvtfat.h"
#include "config.h"
const UINT8 bit_mask[8] =
{
BIT7_MASK,
BIT6_MASK,
BIT5_MASK,
BIT4_MASK,
BIT3_MASK,
BIT2_MASK,
BIT1_MASK,
BIT0_MASK
};
LIB_FD libfd; //句柄集
void init_lib_fd(void)
{
int i =0 ;
libfd.opend_index = 0;
for(i = 0; i< OPEN_LIB_MAX ;i++)
{
libfd.opend_id[i] = -1;
}
for(i = 0; i < LIB_ID_MAX ;i ++)
{
libfd.fd[i] = -1;
}
}
/*
*从GBK 字库中读点阵数据
*/
INT LIB_GBK_ReadData(USHORT Code, FONT_ATTR *font,UINT8 *pResult, INT32 *piLen)
{
UINT8 SectionCode;
UINT8 LocalCode;
INT32 lib_id;
INT32 lib_id1;
INT64 OffsetAddr;
UINT iFontSize;
UINT ret;
char path[64],temp_path[64];
int fd = -1;
LocalCode = Code & 0xFF;
SectionCode = Code >> 8;
if((font->width % 8) != 0)
{
iFontSize = ((font->width/8)+1) * font->height;
}
else
{
iFontSize = (font->width/8) * font->height;
}
//
if(SectionCode > 0x81 )
{
lib_id = font->lib_id;
sprintf(temp_path,"d:\\GBK_%d_%d_%d.dzk",font->lib_id,font->width,font->height);
if(LocalCode > 0x80)
{
OffsetAddr = ((SectionCode - 0x81) * 190 + (LocalCode - 0x41)) * iFontSize;
}
else
{
OffsetAddr = ((SectionCode - 0x81) * 190 + (LocalCode - 0x40)) * iFontSize;
}
}
else
{
lib_id = font->lib_id + 1;
sprintf(temp_path,"d:\\ASCII_%d_%d_%d.dzk",lib_id,font->width,font->height);
OffsetAddr = LocalCode * iFontSize;
}
fd = libfd.fd[lib_id];
if(fd < 0)
{
if(libfd.opend_id[libfd.opend_index] != -1 )
{
lib_id1 = libfd.opend_id[libfd.opend_index];
fsCloseFile(libfd.fd[lib_id1]);//关掉 已打开的 lib
libfd.opend_id[libfd.opend_index] = -1;
libfd.fd[lib_id1] = -1;
PRINT_LOG("close %d lib !!!\n",lib_id1);
}
fsAsciiToUnicode(temp_path, path, TRUE);
fd = fsOpenFile(path, 0, O_RDONLY);
if(fd < 0)
{
PRINT_LOG("font file %s open fail\n",temp_path);
return ERR_NO_FILE;
}
PRINT_LOG("font file %s open ok\n",temp_path);
libfd.opend_id[libfd.opend_index] = lib_id;
libfd.fd[lib_id] = fd;
libfd.opend_index = (libfd.opend_index + 1) % OPEN_LIB_MAX;
}
fsFileSeek(fd, OffsetAddr,SEEK_SET);
ret = fsReadFile(fd, pResult, iFontSize,piLen);
ret = ERR_NULL;
return ret;
}
/*
*从GB2312 字库中读点阵数据
*/
INT LIB_GB2312_ReadData(USHORT Code, FONT_ATTR *font,UINT8 *pResult, INT32 *piLen)
{
UINT8 SectionCode;
UINT8 LocalCode;
INT64 OffsetAddr;
UINT iFontSize;
UINT ret;
INT32 lib_id;
INT32 lib_id1;
char path[64],temp_path[64];
int fd = -1;
LocalCode = Code & 0xFF;
SectionCode = Code >> 8;
if((font->width % 8) != 0)
{
iFontSize = ((font->width/8)+1) * font->height;
}
else
{
iFontSize = (font->width/8) * font->height;
}
//
if(SectionCode > 0xA1 )
{
lib_id = font->lib_id;
sprintf(temp_path,"d:\\GB2312_%d_%d_%d.dzk",lib_id,font->width,font->height);
OffsetAddr = ((SectionCode - 0xA1) * 94 + (LocalCode - 0xA1)) * iFontSize;
}
else
{
lib_id = font->lib_id + 1;
sprintf(temp_path,"d:\\ASCII_%d_%d_%d.dzk",lib_id,font->width,font->height);
OffsetAddr = LocalCode * iFontSize;
}
fd = libfd.fd[lib_id];
if(fd < 0)
{
if(libfd.opend_id[libfd.opend_index] != -1 )
{
lib_id1 = libfd.opend_id[libfd.opend_index];
fsCloseFile(libfd.fd[lib_id1]);//关掉 已打开的 lib
libfd.opend_id[libfd.opend_index] = -1;
libfd.fd[lib_id1] = -1;
PRINT_LOG("close %d lib !!!\n",lib_id1);
}
fsAsciiToUnicode(temp_path, path, TRUE);
fd = fsOpenFile(path, 0, O_RDONLY);
if(fd < 0)
{
PRINT_LOG("font file %s open fail\n",temp_path);
return ERR_NO_FILE;
}
PRINT_LOG("font file %s open OK\n",temp_path);
libfd.opend_id[libfd.opend_index] = lib_id;
libfd.fd[lib_id] = fd;
libfd.opend_index = (libfd.opend_index + 1) % OPEN_LIB_MAX;
}
fsFileSeek(fd, OffsetAddr,SEEK_SET);
ret = fsReadFile(fd, pResult, iFontSize,piLen);
ret = ERR_NULL;
return ret;
}
/*
* 从Unicode 中读取数据
*/
INT LIB_Unicode_ReadData(USHORT Code, FONT_ATTR *font, UINT8 *pResult, INT32 *piLen)
{
char path[64],temp_path[64];
INT32 lib_id;
int fd = -1;
UINT iFontSize;
INT64 OffsetAddr;
INT ret;
if((font->width % 8) != 0)
{
iFontSize = ((font->width/8)+1) * font->height;
}
else
{
iFontSize = (font->width/8) * font->height;
}
OffsetAddr = Code * iFontSize;
fd = libfd.fd[font->lib_id];//lib_fd[font->lib_id];
if(fd < 0)
{
// 最大能同时打开 OPEN_LIB_MAX 个字库 超过了 最大打开的 个数 就要关掉 最早打开的字库
if(libfd.opend_id[libfd.opend_index] != -1 )
{
lib_id = libfd.opend_id[libfd.opend_index];
fsCloseFile(libfd.fd[lib_id]);//关掉 已打开的 lib
libfd.opend_id[libfd.opend_index] = -1;
libfd.fd[lib_id] = -1;
PRINT_LOG("close %d lib !!!\n",lib_id);
}
sprintf(temp_path,"d:\\font%d_%d_%d.dzk",font->lib_id,font->width,font->height);
fsAsciiToUnicode(temp_path, path, TRUE);
fd = fsOpenFile(path, 0, O_RDONLY);
if(fd < 0)
{
PRINT_LOG("font file %s open fail!!!\n",temp_path);
return ERR_NO_FILE;
}
PRINT_LOG("open %d lib !!!\n",font->lib_id);
libfd.opend_id[libfd.opend_index] = font->lib_id;
libfd.fd[font->lib_id] = fd;
libfd.opend_index = (libfd.opend_index + 1) % OPEN_LIB_MAX;
}
fsFileSeek(fd, OffsetAddr,SEEK_SET);
ret = fsReadFile(fd, pResult, iFontSize,piLen);
ret = ERR_NULL;
return ret;
}
/*
*从将字库中的取出的点阵数据描点到显示bUF
*/
INT (*pfontlib_read[3])(USHORT Code, FONT_ATTR *font,UINT8 *pResult, INT32 *piLen) =
{
LIB_Unicode_ReadData,
LIB_GB2312_ReadData,
LIB_GBK_ReadData
};
UINT8 dot_buf[64*48];
UINT16 dot_clolor[2] = {COLOR_BLACK,COLOR_WHITE};// {背景色,前景色}
void DrawFont(USHORT code,FONT_ATTR *font)
{
UINT8 active_width;
UINT8 active_height;
INT32 rDotLen;
//UINT32 DotLen = 0;
UINT32 i = 0,j = 0;
UINT8 offset;
UINT8 *pDotBuf = NULL;
UINT8 *tempBuf = NULL;
USHORT *targetBuf = NULL;
INT32 ret;
if((font->x_pos > PANEL_WIDTH)||(font->y_pos > PANEL_HEIGHT))
{
return ;
}
if((font->width % 8) != 0)//横向取模
{
offset = (( font->width / 8) + 1 );
}
else
{
offset = ( font->width / 8) ;
}
active_width = font->width;
active_height = font->height;
tempBuf = dot_buf;
if(tempBuf < 0)
{
ret = ERR_MALLOC_FAIL;
PRINT_LOG("errno:%d \n",ret);
return ;
}
if(font->EncodeMode >= ENCODE_MAX)
{
PRINT_LOG("please choose an encode mode!!!\n");
return;
}
ret = pfontlib_read[font->EncodeMode](code, font, tempBuf, &rDotLen);
if(ret != ERR_NULL)
{
PRINT_LOG("read lib error:%d \n",ret);
return ;
}
//获取显示缓存
targetBuf = (USHORT *)get_ready_buf();
targetBuf += (font->y_pos * PANEL_WIDTH +font->x_pos);
active_width = font->half_width ? (active_width/2) : active_width;
pDotBuf = tempBuf;
//待显示区域超出 屏部分 丢弃
if((font->x_pos + active_width) > PANEL_WIDTH )
active_width = PANEL_WIDTH - font->x_pos;
if((font->y_pos + active_height) > PANEL_HEIGHT)
active_height = PANEL_HEIGHT - font->y_pos;
if(font->bg_flag == 1)
{
for (i = 0; i < active_height; i++)
{
for (j = 0; j < active_width; j++)
{
if(*(pDotBuf+ (j/8)) & bit_mask[j % 8])
{
*(targetBuf+j) = font->front_color;
}
else
{
*(targetBuf+j) = font->bg_color;
}
}
targetBuf += PANEL_WIDTH;
pDotBuf += offset;
}
}
else
{
for (i = 0; i < active_height; i++)
{
for (j = 0; j < active_width; j++)
{
if(*(pDotBuf+ (j/8)) & bit_mask[j % 8])
{
*(targetBuf+j) = font->front_color;
}
}
targetBuf += PANEL_WIDTH;
pDotBuf += offset;
}
}
tempBuf = NULL;
}
extern UINT8 frameBuf_lock;
//显示字符串
void DrawSting(UINT8 *pBuf,USHORT strlen,FONT_ATTR *str)
{
UINT32 i = 0;
UINT16 code;
FONT_ATTR font_attr;
if((pBuf == NULL)||(strlen <=0 ))
{
sysprintf("DrawSting len error!!!\n");
frameBuf_lock = 0;
return ;
}
memcpy(&font_attr,str,sizeof(FONT_ATTR));
for( i = 0 ; i< strlen ; i++)
{
code = *pBuf++;
if((font_attr.EncodeMode == ENCODE_GB2312)||(font_attr.EncodeMode == ENCODE_GBK))
{
if( code > 0X80)//区分 汉字 和 ASCII
{
if(i < (strlen -1))
{
code <<= 8;
code += *pBuf++;
i++;
}
else
{
break;
}
font_attr.half_width = FULL_WIDTH;//全角显示
DrawFont(code,(FONT_ATTR * )&font_attr);
font_attr.x_pos += font_attr.width ;
}
else
{
font_attr.half_width = HALF_WIDTH;//半角显示
DrawFont(code,(FONT_ATTR * )&font_attr);
font_attr.x_pos += ((font_attr.width )/2);
}
}
else
{
code <<= 8;
code += *pBuf++;
i++;
font_attr.half_width = FULL_WIDTH;
DrawFont(code,(FONT_ATTR * )&font_attr);
font_attr.x_pos += (font_attr.width );
}
}
frameBuf_lock = 0;
}