| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2579 人关注过本帖
标题:TC2.0显示汉字的例子
只看楼主 加入收藏
hoodlum1980
Rank: 2
来 自:浙江大学
等 级:论坛游民
威 望:2
帖 子:289
专家分:23
注 册:2008-2-24
收藏
 问题点数:0 回复次数:6 
TC2.0显示汉字的例子
我们已经知道如何根据汉字库文件,在图形模式下显示汉字,但这里,类似我以前的做法,我提供一个简单的头文件。使它使用起来更方便一些。需要注意的是不同字库主要要注意两点差别:(1)文件中第一个字的起始编码不同,即文件定位方式会有差别,(2)不同字库的扫描序不同,例如12*12和16*16属于按行扫描,而24*24属于按列扫描,这导致输出汉字的代码有差别。(具体的细节不详述了)

显示汉字部分的代码参考了(1)《C高级实用程序设计》(王士元)(清华大学出版社),(2)《C高级编程技术.pdf》,以及(3)《信电系C语言大型作业参考资料.doc》(浙江大学,韩 雁,霍明旭,1999年5月)。GetBit和PutChn12的代码主要借鉴和选用了资料(3)中提供的代码,即该部分代码非我的原创。

头文件TEXTOUT.H如下:我们可以把它放到TC的INCLUDE文件夹,这样就像使用其他头文件一样方便了。如果不这样,需要include的时候同时写出它所在的路径。

[code/************************************************************/
/* Desc:    用于TC下的VGA模式下输出汉字字符串                                    */
/* By:        hoodlum1980                                                                                */
/* Email: jinfd@                                                                         */
/* QQ:         17777538                                                                                     */
/* Date:    2008-09-11                                                                                */
/* Blog:    http://                                */
/************************************************************/
#ifndef __TEXTOUT_H_INCLUDED
#define __TEXTOUT_H_INCLUDED

#include <graphics.h>
#include <stdio.h>

/*HZK12的全路径*/
char PATH_HZK12[256];
char PATH_HZK16[256];
char PATH_HZK24[256];

/*函数列表*/
char* GetFontPath(int size, int *byteslength);
void     SetFontPath(int size, char *filename);
int     GetBit(unsigned char byte,int bit);
int     GetBitByPos(int size, unsigned char *bytes, int x, int y);
void     PutChn(int size, int left, int top, unsigned char *bytes, int color);
void     PutChnWithBorder(int size, int left, int top, unsigned char *bytes, int fillcolor, int bordercolor);
int     TextOut12(char *string , int x, int y);
int     TextOut16(char *string , int x, int y);
int     TextOut24(char *string , int x, int y);
int     TextOut(char *string, int size, int x, int y, int gap, int fillcolor, int bordercolor);

/*根据size获取路径字符串的地址, 并返回字模字节数组大小 */
char* GetFontPath(int size, int *byteslength)
{
    /* byteslength = (size+7)/8*size; */
    if(size < (12+16)/2)
    {
        if(byteslength!=NULL)    *byteslength = 24;
        return PATH_HZK12;
    }
    else if(size < (16+24)/2)
    {
        if(byteslength!=NULL)    *byteslength = 32;
        return PATH_HZK16;
    }
    else
    {
        if(byteslength!=NULL)    *byteslength = 72;
        return PATH_HZK24;
    }
}
/*设置12*12汉字库的文件路径!*/
void SetFontPath(int size, char *filename)
{
    strcpy(GetFontPath(size, NULL), filename);
}

/*获取一个字节中的某个位(bit)*/
int GetBit(unsigned char byte,int bit)
{
    if(bit<0 || bit>7)
            return 0;
    return (byte>>bit)& 0x1;
}

/*给出一个字模的大小,字模字节数组,点在字模中的坐标,返回字模中该点的值(0或者1)*/
/*size: 汉字尺寸 = 12,16,24,...*/
int GetBitByPos(int size, unsigned char *bytes, int x, int y)
{
    int index, bit;
    if(x<0 || x>size-1 || y<0 || y>size-1)
        return 0;
    /*如果是按行扫描的*/
    if(size<=16)
    {
        index = (size+7)/8 * y + x/8; /*数组索引,位于哪一个byte*/
        bit= 7 - (x%8);    /*位于该byte的第几位*/
    }
    else
    {
        /*按列扫描*/
        index = (size+7)/8 *x + y/8;
        bit= 7 - (y%8);
    }
    return GetBit(bytes[index], bit);
}

/*通用的绘制方法,传入字的大小,左上角坐标,字模,颜色*/
void PutChn(int size, int left, int top, unsigned char *bytes, int color)
{
    int i,j;
    for(i=0;i<size;i++)
        for(j=0;j<size;j++)
            if(GetBitByPos(size, bytes, i, j))
                putpixel(left+i, top+j, color);
}

/*绘制汉字,并且绘制汉字边缘!*/
void PutChnWithBorder(int size, int left, int top, unsigned char *bytes, int fillcolor, int bordercolor)
{
    int i,j,k;
    char pos[8][2]={-1,-1, 0,-1, 1,-1,  -1,0, 1,0,  -1,1, 0,1, 1,1};
    for(i=0;i<size;i++)
    {
        for(j=0;j<size;j++)
        {
            if(GetBitByPos(size, bytes, i,j))
            {
                /*绘制像素点*/
                if(fillcolor>=0)
                    putpixel(left+i, top+j, fillcolor);
                /*绘制边缘*/
                for(k=0;k<8;k++)
                {
                    if(!GetBitByPos(size, bytes, i+pos[k][0], j+pos[k][1]))
                        putpixel(left+i+pos[k][0], top+j+pos[k][1], bordercolor);
                }
            }
        }
    }
}

/*给出一个汉字的12_12字模入口地址,在指定位置输出这个汉字 */
/*bytes是汉字的字模字节数组,12_12像素字库是按行扫描的。*/
/*
void PutChn12(int x, int y, unsigned char* bytes, int color)
{
    int i, j, bit;
    for(i=0; i<12; i++)
        for(j=0; j<2; j++)
            for(bit=0; bit<8 && (j*8+bit)<12; bit++)
                if( GetBit(bytes[i*2+j], 7-bit) )
                    putpixel( x + j*8 + bit, y + i, color);
}
*/

/*默认的绘制12*12字符串*/
int TextOut12(char *string , int x, int y)
{
    return TextOut(string, 12, x, y, 2, getcolor(), -1);
}
/*默认的绘制16*16字符串*/
int TextOut16(char *string , int x, int y)
{
    return TextOut(string, 16, x, y, 2, getcolor(), -1);
}
/*默认的绘制24*24字符串*/
int TextOut24(char *string , int x, int y)
{
    return TextOut(string, 24, x, y, 2, getcolor(), -1);
}
/*在指定位置输出一行中文字符串, string必须是汉字组成的字符串*/
/*x,y:字符串的左上角位置。color:颜色。gap:相邻汉字之间的像素间距*/
/*返回输出的字符数量*/
int TextOut(char *string, int size, int x, int y, int gap, int fillcolor, int bordercolor)
{
    unsigned char qh, wh, qhbase, *pChar; /*区号,位号, 起始区号*/
    unsigned long offset;    /*文件偏移地址*/
    unsigned char *bytes[72];    /*当前字模字节数组*/
    char text[2]={0x00,0x00};    /*这是为了输出英文字符*/
    char pos[8][2]={-1,-1, 0,-1, 1,-1,  -1,0, 1,0,  -1,1, 0,1, 1,1};
    int i,originColor, left=x, count=0, k, byteslength;    /*left是当前字的X坐标, count是字符数量计数*/
    FILE *stream;
    
    qhbase=(size<=16)? 0:15;    /*起始区号*/
    stream=fopen(GetFontPath(size, &byteslength), "rb");
    if(stream==NULL)
        return 0;    
        
    /*把char[]当作无符号字符*/
    pChar=(unsigned char*)string;
    /*保存现有的颜色*/
    originColor=getcolor();

    /*依次输出每个汉字*/
    for(i=0;  i<strlen(string);  i++, count++)
    {
        /*判断是字符是否是英文字符*/
        if(pChar[i] < 0xa1)
        {
            /*输出英文字符*/
            text[0]=pChar[i];
            if(bordercolor>=0)
            {
                setcolor(bordercolor);
                for(k=0;k<8;k++)
                    outtextxy(left+pos[k][0], y+size/2-3+pos[k][1], text);
            }
            setcolor(fillcolor>=0? fillcolor: getbkcolor());
            outtextxy(left, y+size/2-3, text); /*默认字体比较扁些*/                        
            left += (6+gap);
        }
        else
        {
            /*输出汉字字符*/
            qh=(pChar[i  ]-0xa1)&0x07F; /*得到区号*/
            wh=(pChar[i+1]-0xa1)&0x07F; /*得到位号*/
            offset = (94*(qh-qhbase)+wh)*((unsigned long)byteslength); /*得到偏移位置,对于12字库,每个汉字24个字节*/
            fseek(stream, offset, SEEK_SET); /*移文件指针到要读取的汉字字模处*/
            fread(bytes, byteslength, 1, stream); /*读取24 bytes的汉字字模*/
            /*输出这个汉字*/
            if(bordercolor<0)
                PutChn(size,left,y,bytes,fillcolor);
            else
                PutChnWithBorder(size, left, y, bytes, fillcolor, bordercolor);/*输出这个汉字*/
            left += (size+gap);
            i++;/*因为每个汉字占用2个字节,因此跳过下一个字节*/
        }
    }
    setcolor(originColor);/*复原前景色*/
    fclose(stream);
    return count; /*返回输出字符数*/
}

#endif /* END OF ifndef __TEXTOUT_H_INCLUDED */[/code]

下面的代码示范了如何使用这个头文件。

#include <textout.h>
#include <dir.h>

void main()
{
    int gdriver=DETECT,gmode;
    char filename[256];
    char string[]="Hello_这是一个如何使用的例子__by_hoodlum";
    /*设置汉字库文件的路径*/
    getcwd(filename, sizeof(filename));
    strcat(filename, "\\HZK12");
    SetFontPath(12, filename);
    initgraph(&gdriver, &gmode, "");
    TextOut(
                    string,    /*要输出的字符串*/
                    12,        /*字体大小*/
                    10, 100,   /*左上角坐标*/
                    2,         /*字符间距*/
                    LIGHTGRAY, /*字体颜色*/
                    -1         /*边缘颜色*/
                    );
    getch();
    closegraph();
}

我们做的第一步是指明汉字库文件所在的路径,第二步即可调用TextOut函数输出一个中文字符串。它的参数表示的分别是字符串地址,输出位置左上角的坐标,相邻汉字间距,颜色。当然调用这个函数之前,应该先进入TC的图形模式。

下面是说明文件的内容:

INCLUDE\ TEXTOUT.H

    
    重要函数:
    void     SetFontPath(int size, char *filename);

        设置汉字库的文件路径;size=12,16,或24;

    int     TextOut(char *string, int size, int x, int y, int gap, int fillcolor, int bordercolor);
        
                     输出一个字符串,x,y指定左上角坐标,gap为相邻汉字字符间距,
        fillcolor为字体填充颜色,bordercolor为边缘颜色。

TEXTOUTDEMO.C

    示范如何使用textout.h的文件。

HZK12

    12*12像素的汉字库文件,它是按行扫描的。下图为汉字“啊”的字模数组的存储方式。
    ##请注意12*12和16*16都是按行扫描的,而24*24是按列扫描的。
    []内数字为字节数组的索引。○为字节中未使用的位。□表示0,■表示1.

------------------------------------------
bit  7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
------------------------------------------
[00] □□■□□□□□□□■□○○○○ [01]
[02] ■■■■■■■■■■■■○○○○ [03]
[04] ■□■□■□■□□□■□○○○○ [05]
[06] ■□■□■■■■■□■□○○○○ [07]
[08] ■□■□■□■□■□■□○○○○ [09]
[10] ■□■□■■■□■□■□○○○○ [11]
[12] ■□■□■□■□■□■□○○○○ [13]
[14] ■■■□■□■■■□■□○○○○ [15]
[16] ■□■□■■□□□□■□○○○○ [17]
[18] □□□□■□□□□□■□○○○○ [19]
[20] □□□□■□□□■□■□○○○○ [21]
[22] □□□□■□□□□■■□○○○○ [23]
------------------------------------------


unsigned char bytes[24]=
{
0x20, 0x20, 0xFF, 0xF0, 0xAA, 0x20,
0xAF, 0xA0, 0xAA, 0xA0, 0xAE, 0xA0,
0xAA, 0xA0, 0xEB, 0xA0, 0xAC, 0x20,
0x08, 0x20, 0x08, 0xA0, 0x08, 0x60
};

附件中是代码,可执行文件和12*12像素的汉字库文件。截图效果省略了。

[[it] 本帖最后由 hoodlum1980 于 2008-10-7 20:41 编辑 [/it]]

TextOutDemo.rar (542.16 KB) 代码和汉字库文件



textout.jpg (22.43 KB)
图片附件: 游客没有浏览图片的权限,请 登录注册
搜索更多相关主题的帖子: 汉字 例子 
2008-09-11 23:37
xianshizhe111
Rank: 1
等 级:新手上路
帖 子:1451
专家分:0
注 册:2007-12-8
收藏
得分:0 
TC还是这样充满魅力,先顶一个。
2008-09-11 23:42
qfyzy
Rank: 2
等 级:论坛游民
威 望:1
帖 子:380
专家分:86
注 册:2008-2-17
收藏
得分:0 
好久不来,貌似克灵顿的头像换了。。。

当对C的经验增加时,它会显的很好用.----Dennis M Ritche如是说
2008-09-11 23:57
forestmeng
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2010-4-22
收藏
得分:0 
谢谢LZ,很是有用!
2010-07-23 10:37
xdh0817
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:193
专家分:195
注 册:2011-10-20
收藏
得分:0 
谢谢~~
2011-11-16 22:35
mechess
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2012-4-9
收藏
得分:0 
不错,这个代码很厉害!
2012-04-09 19:30
快速回复:TC2.0显示汉字的例子
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018488 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved