嵌入式HZK16字库显示

Linux下gcc编译:

#include <stdio.h>  
#include <string.h>  
#include <errno.h>

void read_hzk16(const unsigned char *s, char* chs)    
{    
    const char* path = "hzk16";
    FILE *fp = fopen(path,"r");
    if (!fp)
    {
        printf("failed to fopen %s: %s\n", path, strerror(errno));
        return;
    }       
    int size = 32;
    unsigned long offset=((s[0]-0xa1)*94+(s[1]-0xa1))*size; //找出汉字在HZK16中的偏移位置   
    fseek(fp,offset,SEEK_SET); //文件指针偏移到要找的汉字处     
    fread(chs,1,size,fp);    //读取该汉字的字模     
    fclose(fp);    
}    

void display_hzk16(const char* chs)    
{    
    int size = 32; // 一个汉字所占字节数
    int i = 0;
    int j = 0;    
        
    for (i = 0; i < size; i++)//显示     
    {    
        if (i % 2 == 0)
        {
            printf("\n");   //每行两字节,16X16点阵  
        }  
        for (j = 7; j >= 0; j--)    
        {    
            if (chs[i]&(0x1<<j))
            {
                printf("X"); //由高到低,为1则输出'X',反之输出'-';  
            }       
            else    
            {
                printf("_"); 
            }   
        }    
    } 
    printf("\n");  
}  

void read_asc16(const unsigned char *s, char* asc)    
{    
    const char* path = "asc16";
    FILE *fp = fopen(path,"r");
    if (!fp)
    {
        printf("failed to fopen %s: %s\n", path, strerror(errno));
        return;
    }       
    
    unsigned long offset=s[0]*16;  
    fseek(fp,offset,SEEK_SET);      
    fread(asc,16,1,fp);    
    fclose(fp);    
} 

void display_asc16(const char* asc)    
{    
    int i = 0;
    int j = 0;    
        
    for (i = 0; i < 16; i++)//显示     
    {    
        printf("\n");   //每行一字节,8X16点阵  
        for (j = 7; j >= 0; j--)    
        {    
            if (asc[i]&(0x1<<j))
            {
                printf("X"); //由高到低,为1则输出'X',反之输出'-';  
            }       
            else    
            {
                printf("_"); 
            }   
        }    
    } 
    printf("\n");   
} 

int main(int argc, char** argv)
{
    unsigned char s[]="我们的asgs"; //要显示的汉字   
    char tmp[32];
    const unsigned char* p = s;
    int len = strlen(s);
    while(len > 0)
    {
        if (*p > 0x80) // 区号大于0x80的为汉字
        {
            memset(tmp, 0, sizeof(tmp));
            read_hzk16(p,tmp);   //去字库中读取汉字字模     
            display_hzk16(tmp);  //在屏幕上显示这个汉字
            p += 2;
            len -= 2;
        }
        else
        {
            memset(tmp, 0, sizeof(tmp));
            read_asc16(p,tmp);   //去字库中读取字模     
            display_asc16(tmp);  
            p++;
            len--;
        }
    }
    
    return 0;
}
升级版本,支持放大、包边
</pre><pre name="code" class="cpp">#include <stdio.h>  
#include <string.h>  
#include <errno.h>
#include <assert.h>


#define BLACK 'X'
#define WHITE '-'
#define EDGE 'o'


// gb2312 简体 16x16
void read_hzk16(const unsigned char *s, char* chs)    
{   
    int ret = -1;
    const char* path = "gb2312.dzk";
    FILE *fp = fopen(path,"r");
    if (!fp)
    {
        printf("failed to fopen %s: %s\n", path, strerror(errno));
        return;
    }       
    int size = 32;
    unsigned long offset=((s[0]-0xa1)*94+(s[1]-0xa1))*size; //找出汉字在HZK16中的偏移位置   
    
    ret = fseek(fp,offset,SEEK_SET); //文件指针偏移到要找的汉字处
    assert(ret == 0);
    
    ret = fread(chs,1,size,fp);    //读取该汉字的字模
    assert(ret == size);
    
    fclose(fp);    
}


// gb2312 繁体(简转繁) 16x16
void read_fanti_hzk16(const unsigned char *s, char* chs)    
{    
    int ret = -1;
    const char* path = "gb2312_fanti.dzk";
    FILE *fp = fopen(path,"r");
    if (!fp)
    {
        printf("failed to fopen %s: %s\n", path, strerror(errno));
        return;
    }       
    int size = 32;
    unsigned long offset=((s[0]-0xa1)*94+(s[1]-0xa1))*size; //找出汉字在HZK16中的偏移位置 
    
    ret = fseek(fp,offset,SEEK_SET); //文件指针偏移到要找的汉字处  
    assert(ret == 0);   
    
    ret = fread(chs,1,size,fp);    //读取该汉字的字模
    assert(ret == size);
    
    fclose(fp);    
}


// gbk 字库 16x16 兼容gb2312简体 扩展了繁体
void read_gbk16(const unsigned char *s, char* chs)    
{   
    int ret = -1;
    const char* path = "gbk.dzk";
    FILE *fp = fopen(path,"r");
    if (!fp)
    {
        printf("failed to fopen %s: %s\n", path, strerror(errno));
        return;
    }       
    int size = 32;
    int qh = s[0] - 0x81;
    int wh = (s[1] < 0x7f) ? (s[1] - 0x40) : (s[1] - 0x41);
    unsigned long offset=(qh*190+wh)*size; //找出汉字在字库中的偏移位置 
    
    ret = fseek(fp,offset,SEEK_SET); //文件指针偏移到要找的汉字处
    assert(ret == 0);   
    
    ret = fread(chs,1,size,fp);    //读取该汉字的字模
    assert(ret == size);
    
    fclose(fp);    
}     


// ascii 16x8
void read_asc16(const unsigned char *s, char* asc)    
{  
    int ret = -1;
    const char* path = "asc16.dzk";
    FILE *fp = fopen(path,"r");
    if (!fp)
    {
        printf("failed to fopen %s: %s\n", path, strerror(errno));
        return;
    }       
    int size = 16;
    unsigned long offset=s[0]*size;  
    
    ret = fseek(fp,offset,SEEK_SET); 
    assert(ret == 0);   
    
    ret = fread(asc,1,size,fp); 
    assert(ret == size);
    
    fclose(fp);    
} 


void show(const char* p, int row, int col)
{
    int i = 0;
    for (i = 0; i < row*col; i++)
    {
        if (i%col == 0)
        {
            printf("\n");
        }
        printf("%c", p[i]);
    }
    printf("\n\n");
}


void bit2char(const char* chs, int size, char* font) 
{       
    int i = 0;
    int j = 0;
    int idx = 0;
        
    for (i = 0; i < size; i++)   
    {     
        for (j = 7; j >= 0; j--)    
        {    
            if (chs[i]&(0x1<<j))
            {
                font[idx++] = BLACK; 
            }       
            else    
            {
                font[idx++] = WHITE;
            }   
        }    
    } 
}  


// 四周再包一个像素
void add_edge(const char* src, int row, int col, char* dst)    
{  
    row += 2;
    col += 2;
    memset(dst, WHITE, row*col);
    
    int i = 0;
    int j = 0;
    int k = 0;
    
    for (i = 1; i < row-1; i++)
    {
        for (j = 1; j < col-1; j++)
        {
            int idx = i*col+j;
            dst[idx] = src[k++];
        }
    }
    
    for (i = 1; i < row-1; i++)
    {
        for (j = 1; j < col-1; j++)
        {   
            int idx = i*col+j;
            if (dst[idx] == BLACK)
            {
                int top_idx = idx - col;
                int bottom_idx = idx + col;
                int left_idx = idx - 1;
                int right_idx = idx + 1;
                //printf("ij[%d %d] idx: %d, top_idx: %d, bottom_idx: %d, left_idx: %d, right_idx: %d\n", i ,j, idx, top_idx, bottom_idx, left_idx, right_idx);
                
                dst[top_idx] = (dst[top_idx] == BLACK) ? BLACK : EDGE; 
                dst[bottom_idx] = (dst[bottom_idx] == BLACK) ? BLACK : EDGE; 
                dst[left_idx] = (dst[left_idx] == BLACK) ? BLACK : EDGE; 
                dst[right_idx] = (dst[right_idx] == BLACK) ? BLACK : EDGE;
                //printf("dst[top_idx] %c, dst[bottom_idx] %c, dst[left_idx] %c, dst[right_idx] %c\n", dst[top_idx], dst[bottom_idx], dst[left_idx], dst[right_idx]);
            } 
        }
    }
}  


// 字体等比放大2倍,size放大了4倍(一个字节变为4个字节)
void zoom2times(const char* font16x16, int row, int col, char* font32x32)    
{    
    int i = 0;
    int j = 0;    
        
    for (i = 0; i < row; i++)
    {  
        for (j = 0; j < col; j++)
        {
            char c = font16x16[i*col+j];
            int x = i*2;
            int y = j*2;
            int dst_col = col*2;
            int idx = x*dst_col+y;
            
            font32x32[idx] = c; //top
            font32x32[idx+1] = c; // right
            font32x32[idx+dst_col] = c; // bottom
            font32x32[idx+dst_col+1] = c; // right and bottom
        }
    }  
}  


int main(int argc, char** argv)
{
    unsigned char s[]="漢汉a"; //要显示的汉字   
    char tmp[32];   
    const unsigned char* p = s;
    int len = strlen(s);
    while(len > 0)
    {
        if (*p > 0x80) // 区号大于0x80的为汉字
        {
            printf("chinese 0x%02x 0x%02x\n", *p, *(p+1));
            memset(tmp, 0, sizeof(tmp));
            //read_hzk16(p,tmp);   //去字库中读取汉字字模
            //read_fanti_hzk16(p,tmp);
            read_gbk16(p,tmp);
            
            char font16x16[16*16];
            bit2char(tmp, 32, font16x16);
            show(font16x16, 16, 16);
            
            char font18x18[18*18];
            add_edge(font16x16, 16, 16, font18x18);
            show(font18x18, 18, 18);
            
            char font32x32[32*32];
            zoom2times(font16x16, 16, 16, font32x32);
            show(font32x32, 32, 32);
            
            char font34x34[34*34];
            add_edge(font32x32, 32, 32, font34x34);
            show(font34x34, 34, 34);
            
            p += 2;
            len -= 2;
        }
        else
        {
            printf("ascii 0x%02x\n", *p);
            memset(tmp, 0, sizeof(tmp));
            read_asc16(p,tmp);   //去字库中读取字模
            
            char font16x8[16*8];
            bit2char(tmp, 16, font16x8);
            show(font16x8, 16, 8);
            
            char font18x10[18*10];
            add_edge(font16x8, 16, 8, font18x10);
            show(font18x10, 18, 10);
            
            char font32x16[32*16];
            zoom2times(font16x8, 16, 8, font32x16);
            show(font32x16, 32, 16);
              
            p++;
            len--;
        }
    }
    
    return 0;
}

 


字库文件下载:http://download.csdn.net/detail/codeheng/9545664

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值