📄 font_cvt.c
字号:
#include "ecrsys.h"
#include "Font.h"
/*----------------------------------------------------------------------------*
取 > 0x80 的特殊西文字符
由于目前只有9*17的点阵描述了这些特殊字符,
其他字体如果也需要显示这些特殊字符, 需要扩充相应的字库.
另外, 还是希望能够将同一类型的点阵字库放在连续的地址空间.
*----------------------------------------------------------------------------*/
void Get_Font_Addr(byte ch, dword *src)
{
byte i;
for(i = 0; i< 0x80; i++)
{
if(Symbol_Font_List_Ex[i] == 0xff)//查到结束字符处
return;
if(ch == Symbol_Font_List_Ex[i])//在表中找到相应字符, 退出
break;
}
if(i >= 0x80)
return;
*src =(dword)acFont8x16_Ex[i];//返回新的字库地址
}
/*-----------------------------------------------------------------------
判断是不是区码
是, 返回TRUE
否, 返回FALSE
------------------------------------------------------------------------*/
byte Judge_Qu(byte qu)
{
#if COUNTRY == CHINA//GB 码, 从0xb0a1开始
if(qu >= 0xa1)
return TRUE;
#elif COUNTRY == HONGKONG//BIG-5码, 从0x8041开始
if(qu >= 0x80)
return TRUE;
#elif COUNTRY == KOREA//韩文字库, 从0xb3a1开始
if(qu >= 0xb3)
return TRUE;
#else//西文码, 没有区码
return FALSE;
#endif
return FALSE;
}
/*-----------------------------------------------------------------------
判断是不是位码
是, 返回TRUE
否, 返回FALSE
------------------------------------------------------------------------*/
byte Judge_Wei(byte wei)
{
#if COUNTRY == CHINA//GB 码, 从0xb0a1开始
if(wei >= 0xa1)
return TRUE;
#elif COUNTRY == HONGKONG//BIG-5码, 从0x8000开始
return TRUE;
#elif COUNTRY == KOREA//韩文字库, 从0xb3a1开始
if(wei >= 0xa1)
return TRUE;
#else//西文码, 没有区码
return FALSE;
#endif
return FALSE;
}
/*----------------------------------------------------------------------------*
* 函数说明:
* 返回字符对应点阵的位置, 根据语言的不同, 需要作出不同的处理
* 目前暂时按照区域不同大致划分点阵布局
* 中国地区只用GB_2312_80码
* 字库分布特征为: 区码从0xb0 开始连续分布, 位码从0xa1开始连续分布
* 计算方式为: (qu-0xb0)*(0x100-0xa1) + (wei - 0xa1)
*
* 香港地区使用BIG-5码
* 1> 繁体汉字字库实质从0x8040 开始, 后面的代码全部是汉字, 其中包含一些汉字类型的标点符号.
* 2> 繁体汉字字库代码的分布: 在区码从0x80开始,到0xfe结束; 位码范围从0x40~0x7f和0xa1~0xfe.
* 3> 非空白的汉字代码范围, 在满足上面描述的代码分布基础上, 其分布为:
* 0xA140 ~ 0xA3BF 汉字符号区 (其中, 0xa140为空字)
* 0xA440 ~ 0xC67f 通用汉字区
* 0xC940 ~ 0xF9FE 不常用汉字区
* 其余区域代码均为空字.
* 4> 共13502个汉字,每个汉字转化成点阵需要72byte, 点阵占 0xED580BYTE, 约950K, 需要7个扇区.
* 5> 计算公式较为复杂, 看程序计算
* 6> 返回: 对应字符存储于点阵字库的位置( 0 ~~ 13501)
*
* 韩国使用韩文字码
* 字库分布特征为: 区码从0xb3 开始连续分布, 位码从0xa1开始连续分布
* 计算方式为: (qu-0xb3)*(0x100-0xa1) + (wei - 0xa1)
*
* 西欧地区使用ASCII码为主, 增加一些转义字符插入显示
* 计算方式为: (dat - 0x20)*FONT_DOT_BASE
*---------------------------------------------------------------------------
* 函数描述:
* qu : 如果为汉字, 区码; 如果为西文字符, 0
* wei: 如果为汉字, 位码; 如果为西文字符, ASCII码
* 函数返回:
* 返回字符在点阵中的相对位置(0~0xffff)
* 注意函数主要是针对汉字字库的点阵位置确定.
* 如果是西文字符, 建议还是直接查找.
*----------------------------------------------------------------------------*/
word Font_Search_Offset(byte qu, byte wei)
{
word quwei;
if(!qu)
return (wei - 0x20);
if(Judge_Wei(wei) == FALSE)
return 0;
#if COUNTRY == CHINA
quwei = ((word)qu - 0xb0) * 94UL + (wei - 0xa1);
#elif COUNTRY == HONGKONG//0xa140 为一个空字
#define FONT_PARA1 0x198 //(a140~a3bf)
#define FONT_PARA2 0x16b1 //(0x1519+FONT_PARA1)
#define FONT_PARA3 0x34BE //(0x1E0D +0x16b1)
#define FONT_PART 0x9d //0xff-0xa1+0x7f-0x40 = 0x9d
if((wei >= 0x40)&&(wei <= 0x7e))
{
wei -= 0x40;
}
else if((wei >= 0xa1)&&(wei <= 0xfe))
{
if(((qu == 0xa3)&&(wei > 0xbf))||(qu == 0xc6))
{
qu = 0xa1;
wei = 0;
}
else
wei -= 0xa1-(0x7f-0x40);
}
else//wrong code, set as a null font
{
qu = 0xa1;
wei = 0;
}
if((qu >= 0xa1)&&(qu <= 0xa3))
{
qu -= 0xa1;
quwei = wei + (word)FONT_PART*qu ;
}
else if((qu >= 0xa4)&&(qu <= 0xc6))
{
qu -= 0xa4;
quwei = wei + (word)FONT_PART*qu + FONT_PARA1 ;
}
else if((qu >= 0xc9)&&(qu <= 0xf9))
{
qu -= 0xc9;
quwei = wei + (word)FONT_PART*qu + FONT_PARA2 ;
}
else//空字符.
{
qu = 0;
quwei = 0;
}
#elif COUNTRY == KOREA
quwei = (word)(qu - 0xb3) * 94UL + (wei - 0xa1);
#else//西文字符
quwei = wei - 0x20;
#endif
return quwei;
}
/*-----------------------------------------------------------------------------*
将需要显示的字符按要求扩大其显示倍数
*dst ---- 点阵显示缓冲区, 存放准备显示的点阵
*dot_src- 字符的点阵字库位置
dot_inc - 点阵标准宽度
hor_elg - 横向扩大倍数
*-----------------------------------------------------------------------------*/
void TFT_Font_Dot_ELg(byte *dst, byte *dot_src, word dot_inc, byte hor_elg)
{
byte src_inc;
byte i, j, k;
src_inc = (dot_inc+7)>>3;/*取单行点阵所占字符宽度*/
if (hor_elg == 1)//如果是单倍字宽, 直接取点阵
{
memcpy(dst, dot_src, src_inc);
}
else if (hor_elg == 2)//双倍字宽
{
for (i = 0; i < src_inc; i++)
{
memcpy(dst, Elg_2_Table[*dot_src], 2);
dst += 2;
dot_src++;
}
}
else if (hor_elg == 3)// 3倍字宽
{
for (i = 0; i < src_inc; i++)
{
memcpy(dst, Elg_3_Table[*dot_src], 3);
dst += 3;
dot_src++;
}
}
else if (hor_elg == 4)// 4倍字宽
{
for (i = 0; i < src_inc; i++)
{
memcpy(dst, Elg_2_Table[Elg_2_Table[*dot_src][0]], 2);
dst += 2;
memcpy(dst, Elg_2_Table[Elg_2_Table[*dot_src][1]], 2);
dst += 2;
dot_src++;
}
}
else if (hor_elg == 5)
{
for (i = 0; i < src_inc; i++)
{
memcpy(dst, Elg_5_Table[*dot_src], 5);
dst += 5;
dot_src++;
}
}
else if (hor_elg == 6)
{
for (i = 0; i < src_inc; i++)
{
memcpy(dst, Elg_3_Table[Elg_2_Table[*dot_src][0]], 3);
dst += 3;
memcpy(dst, Elg_3_Table[Elg_2_Table[*dot_src][1]], 3);
dst += 3;
dot_src++;
}
}
else if (hor_elg == 7)
{
for (i = 0; i < src_inc; i++)
{
memcpy(dst, Elg_5_Table[*dot_src], 5);
dst += 5;
dot_src++;
}
}
else if (hor_elg == 8)
{
for (i = 0; i < src_inc; i++)
{
memcpy(dst, Elg_2_Table[Elg_2_Table[Elg_2_Table[*dot_src][0]][0]], 2);
dst += 2;
memcpy(dst, Elg_2_Table[Elg_2_Table[Elg_2_Table[*dot_src][0]][1]], 2);
dst += 2;
memcpy(dst, Elg_2_Table[Elg_2_Table[Elg_2_Table[*dot_src][1]][0]], 2);
dst += 2;
memcpy(dst, Elg_2_Table[Elg_2_Table[Elg_2_Table[*dot_src][1]][1]], 2);
dst += 2;
dot_src++;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -