上面的徐明说得很对 1个汉字占2个字节 可是上面问的是主要问的是什么是点阵字节 那我就说一说16的点阵字节
#include <stdioh>
#include <alloch>
#include <ctypeh>
#include <dosh>
#include <dirh>
#include <ioh>
#include <graphicsh>
#define GETADR(n,str) (str ) calloc (n,sizeof(str)) // 申请N个指定字符串长度的地址
#define W16 16
#define C16 32
unsigned char bit[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
FILE fi;
char dot,str[20];
main(int argc,char argv[])
{
int i,j,nn,xc,yc,MaxX,MaxY,menul[1000];
int graphdriver=DETECT,graphmode;
if(argc!=2){ //检测是否输入了2个参数
puts("LT16<N4>");
exit(0);
}
dot=GETADR(C16,char); //获取16个char长度的内存地址
fnmerge(str,"","",argv[1],"N4"); //建立str 为路径 ,文件名是 第一个参数N4 的文件(这里可能有bug,str没初始化)
if((fi=fopen(str,"r"))==NULL){ //打开这个文件用于输入
puts("Can't open DATA");
exit(0);
}
fscanf(fi,"%d",&nn); //读取一个整数
if(nn<=0||nn>1000) //这个数字必须在 0~1000之间
exit(0);
for (i=0;i<nn;i++)
fscanf(fi,"%d",&menul[i]); //根据这个数字来决定继续读取的数字数量
fclose(fi);
if((fi=fopen("CLIB16DOT","rb"))==NULL){ //打开 CLIB16DOT 这个文件
puts("Can't open CLIB16DOT");
exit(0);
}
initgraph(&graphdriver,&graphmode,""); // 初始化图形模式
MaxX=getmaxx(); // 获得屏幕最大坐标范围
MaxY=getmaxy();
xc=0;
yc=20;
for(j=0;j<nn;j++){
i=readlibdot(menul[j]); //读取点阵数据
putchar16(xc,yc); //显示到对应的坐标系
xc+=20;
if(xc>MaxX-20){
yc+=20;
xc=0;
if(yc>MaxY-20){
getch();
clearviewport();
yc=0;
}
}
}
getch(); //按任意键继续
closegraph(); //关闭图形模式
}
readlibdot(int j)
{
int i0,j1,j2;
long order,k1;
j1=j/100;
j2=j-j1100;
if(j1>=9)
j1=j1-6;
k1=94j1+j2-95;
order=C16k1;
fseek(fi,order,SEEK_SET);
i0=fread(dot,C16,1,fi);
return(i0);
}
putchar16(int bx,int by) //显示readlibdot 得到的汉字(保存在dot 里面)的每个象素点阵
{
int i,j,kk,k,x1,y1;
unsigned char marker;
kk=0;
y1=by;
for(i=0;i<16;i++,y1++){
for(j=0;j<2;j++){
x1=bx+j8;
marker=(dot+kk);
kk++;
for(k=0;k<8;k++){
if(!(marker&bit[k]))
continue;
putpixel(x1+k,y1,YELLOW);
}
}
}
return;
}
点阵字库
一般我们使用1616的点阵宋体字库,所谓1616,是每一个汉字在纵、横各16点的区域内显示的。
不过后来又有了HZK12、HZK24,HZK32和HZK48字库及黑体、楷体和隶书字库。
虽然汉字库种类繁多,但都是按照区位的顺序排列的。前一个字节为该汉字的区号,后一个字节为该字的位号。
每一个区记录94个汉字,位号则为该字在该区中的位置。
因此,汉字在汉字库中的具体位置计算公式为:94(区号-1)+位号-1。
减1是因为数组是以0为开始而区号位号是以1为开始的。
这仅为以汉字为单位该汉字在汉字库中的位置,那么,如何得到以字节为单位得到该汉字在汉字库中的位置呢?
只需乘上一个汉字字模占用的字节数即可,
即:(94(区号-1)+位号-1)一个汉字字模占用字节数,而按每种汉字库的汉字大小不同又会得到不同的结果。
以1616点阵字库为例,计算公式则为:(94(区号-1)+(位号-1))32。
汉字库文该从该位置起的32字节信息即记录了该字的字模信息。
了解点阵汉字及汉字库的构成原理后,显示汉字就变得简单。以1616点阵字库为例,
通常的方法是:将文件工作指针移到需要的汉字字模处、将汉字库文件读入一216数组再用for循环一位位地显示。
#include "graphicsh"
#include "stdioh"
main()
{ int i=VGA,j=VGAHI,k;
unsigned char mat[16][2],chinease[3]="我";
FILE HZK;
if((HZK=fopen("hzk16","rb"))==NULL)exit(0);
initgraph(&i,&j,"");
i=chinease[0]-0xa0;j=chinease[1]-0xa0; /获得区码与位码/
fseek(HZK,(94(i-1)+(j-1))32l,SEEK_SET);
fread(mat,32,1,HZK);
for(j=0;j<16;j++)
for(i=0;i<2;i++)
for(k=0;k<8;k++)
if(mat[j][i]&(0x80>>k)) /测试为1的位则显示/
putpixel(i8+k,j,WHITE);
getch();
closegraph();
fclose(HZK);
分类: 电脑/网络 >> 程序设计 >> 其他编程语言
问题描述:
如何提取字体中每个字在不同字号时的宽度与高度?字体文件是一个什么样的结构?我们编程时,如何取得它里边有关信息(如上:宽高)?
请不要给我API或MFC库中的函数或类,我只想知道信息在哪,什么格式存放,我好有办法提取出来,因为我现在在设计一个跨平台的窗口界面引擎,输入文字时每个字的输出间距等信息无法掌握,不一定是在WINDOWS系统上用,所以想知道数据存放格式,这里先谢谢大家了!!
解析:
这得看你想用什么字库:
A、矢量字库的结构及字模读取方法
UCDOS30提供五种矢量字库:图形符号字库(HZKSLT)和宋体、楷体、黑体、仿
宋体(HZKSLSTJ,HZKSLKTJ,HZKSLHTJ,HZKSLFSJ)
及01区到15区的图形符号和16区到87区的汉字是分开存放的,但它门的结构是一样的。
每种矢量字库是由两部分组成:一是每个汉字的索引信息,ê鹤肿中卧谧挚庵
的偏移地址及长度,放在字库的前面;二是汉字的字形数据,它包括汉字每个组成点
的坐标,放在字库的后面部分。
1、字形存储的偏移地址
在矢量字库中每个汉字的索引信息是定长,为6个字节,其中前4个字节为偏移
地址,后2个字节为长度。国标规定汉字由内码表示,内码为两个字节,且最高位为
1,假设某个汉字内码为ddff,则该汉字的索引信息在字库中的首址就可由下式计算
出来:
汉字的索引信息首址=((dd-0xa0-16)94+(ff-0xa0-1))6
符号的索引信息首址=((dd-0xa0-1)94+(ff-0xa0-1))6
2、字形数据的还原
字形数据是由标识码和相邻点的相对位置组成。标识码占两位,位于字节的高端,
即7、6位,共有四种状态:00,01,10,11,每种状态后面跟随不同的编
码,其编码方式为:
11---表示该字节为笔划多边形的起点字节,余下的5-0位加上第二字节
的位7组成起始点的X值,第二字节的6-0位为Y值,以该点为起点,作各点相对
位置的增减,这里规定:增加为正,即表示符号的位为0,减少为负,即表示符号的
位为1。
10---该字节5-4位分为3种状态;为00时,位3为X增量的符号,位
2-0为X的增量,下一字节的高位为Y增量的符号,其余7位为Y增量;为01时,
位3为Y增量的符号,位2-0为Y的增量,下一字节的高位为X增量的符号,其余
7位为X增量;为10、11时,下一字节的高位为X增量的符号,其余7位为X增
量值,再下一字节的高位为Y增量的符号,其余7位为Y增量值。
01---该字节5-4位为随后的X,Y增量的符号h,后面的4位为计数n,
表示后面有n个字节,每个字节前4位为X增量值,后4位为Y增量值,各增量的符
号取决于h;当h为00时,X、Y增量均为正;当h为01时,X为负Y为正;当h为
10时,X、Y增量均为负;当h为11时,X为正Y为负。
00---本字节其余位为计数n,随后n个字节中,每个字节的第七位为X增量
6-4位为X增量值,位3为Y增量符号,2-0位为Y增量值。
根据汉字的内码,按照汉字索引信息首址的计算公式,取出字形数据的偏移地址
及长度信息,从字形数据部分读出相应的数据信息还原后就可以得到汉字笔划各端点
的坐标了,也就得到了字模。
B点阵字库
在屏幕上写汉字点阵可利用TURBO C的如下两种方法:
1画点函数:void far _Cdecl putpixel(int x, int y, int color);
2自定义填充函数:
void far _Cdecl setfillpattern(char far upattern, int color);
void far _Cdecl bar(int left, int top, int right, int bottom);
利用前者比后者慢一些,但后者代码麻烦。自定义填充模式函数setfillpattern和
画直方图函数bar配合使用时,它总是从坐标x和y为8的整数倍的屏幕位置开始填充。
如果起始显示位置坐标x和y恰好为8的整数倍时,字模中点的填充顺序不用作任何调
整,否则需作调整才能正确显示汉字。
upattern为8字节序列的指针,每个字节对应于填充模式中的8个像素,若字节中的
某位为1,则对应的像素点以颜色color被画出,否则对应的像素点仍为原来的颜色。
16点阵字模可分成4个8*8点阵的填充模式,24点阵字模可分成9个8*8点
阵的填充直方图。
此程序以UCDOS的汉字库为例。
利用24点阵字库,将其字模的所有点分别向左右及上下延伸即成空心字;若要进行立
体投影,要根据投影的方向把字模向不同的方向加点,然后再去掉字模上的点为保证字
模边框的点不被去掉,需保留边框上的点
C绘图矢量字库
plotter000为汉字矢量字库,每个汉字按区位码存放,一个笔划一条记录,每条记录34个
字节长,前30个字节为点线位置信息,随后4个字节为此汉字的下一笔划在文件中的存放位
置(记录号),每一笔划包含15条线,即30个点,15条线的始点和终点按序存放,每个字节的前
4位为x位置值,后4位为y位置值
汉字的区位码值=(汉字首位码-160)100+(第二位码-160)
汉字的首记录号=区位码值-(区位码值/1006)-1504
实现的主要功能是从点阵字库(FONT)中提取某个汉字或者提取某段汉字另外为
矢量字库通过一些软件可转为点阵字库
#include <stdioh>#include <stdlibh>
#include <stringh>
#include <pshpack2h>
#include <iostream>
#define size 32
#define sum (sizesize/8)
void convert(unsigned char qh,unsigned char wh);
void Snapshot( BYTE pData, int width, int height, char filename );
typedef long LONG;
typedef unsigned char BYTE;
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef struct {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BMPFILEHEADER_T;
struct BMPFILEHEADER_S{
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
};
typedef struct{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BMPINFOHEADER_T;
int main()
{
//提取某段汉字
for (unsigned char i=16;i<=16;i++)
{
for (unsigned char j=1;j<=3;j++)
{
convert(i,j);
}
}
//提取某个汉字
unsigned char incode[3] = "我";
unsigned char qh = incode[0] - 0xa0; //获得区码
unsigned char wh = incode[1] - 0xa0; //获得位码
convert(qh,wh);
return 0;
}
void convert(unsigned char qh,unsigned char wh)
{
unsigned long offset = 0;
unsigned char mat[sum][size/8] = {0} ; //mat[sum][2]
struct {
BYTE b;
BYTE g;
BYTE r;
} pRGB[size][size]; // 定义位图数据
memset( pRGB, 0, sizeof(pRGB) ); // 设置背景为黑色
char hz[64];
FILE HZK = NULL;
sprintf(hz , "HZK%d" , size);
HZK = fopen(hz , "rb");
offset = (94(qh-1)+(wh-1))sum; //得到偏移位置
if( HZK == NULL)
//fail to open file
{
printf("Can't Open hzk%d\n" , size);
getchar();
return ;
}
fseek(HZK, offset, SEEK_SET);
fread(mat, sum , 1, HZK);
fclose(HZK);
int col=0;
int row=0;
//显示
for(int i=0; i<size; i++) //16
{
for(int j=0; j<size/8; j++) //2
{
for(int k=0; k<8 ; k++) //8bits , 1 byte
{
if( mat[i][j] & (0x80>>k))
{//测试为1的位则显示
//汉字颜色
//printf("1");
pRGB[size-1-row][col-sizerow]r = 0xff;//bmp中的行坐标倒序
pRGB[size-1-row][col-sizerow]g = 0xff;
pRGB[size-1-row][col-sizerow]b = 0xff;
}
else
{ //背景色
//printf("0");
pRGB[size-1-row][col-sizerow]r = 0x00;//bmp中的行坐标倒序
pRGB[size-1-row][col-sizerow]g = 0x00;
pRGB[size-1-row][col-sizerow]b = 0x00;
}
col++;
}//for
}//for
//printf("\n");
row++;
}//for
char filename[9];
sprintf(filename,"%2d%2dbmp",qh,wh);
if (wh<10)
filename[2]='0';
if (qh<10)
filename[0]='0';
Snapshot( ( BYTE)pRGB, size, size, filename);
}
void Snapshot( BYTE pData, int width, int height, char filename )
{
int bmpsize = widthheight3; // 每个像素点3个字节
// 位图第一部分,文件信息
BMPFILEHEADER_T bfh;
bfhbfType = 0x4d42; //bm
bfhbfSize = bmpsize // data size
+ sizeof( BMPFILEHEADER_T ) // first section size
+ sizeof( BMPINFOHEADER_T ) // second section size
;
bfhbfReserved1 = 1; // reserved
bfhbfReserved2 = 0; // reserved
bfhbfOffBits = bfhbfSize - bmpsize;
// 位图第二部分,数据信息
BMPINFOHEADER_T bih;
bihbiSize = sizeof(BMPINFOHEADER_T);
bihbiWidth = width;
bihbiHeight = height;
bihbiPlanes = 1;
bihbiBitCount = 24;
bihbiCompression = 0;
bihbiSizeImage = bmpsize;
bihbiXPelsPerMeter = 0;
bihbiYPelsPerMeter = 0;
bihbiClrUsed = 0;
bihbiClrImportant = 0;
FILE fp = fopen(filename,"wb");
if( !fp ) return;
fwrite( &bfh, 1, sizeof(BMPFILEHEADER_T), fp );
fwrite( &bih, 1, sizeof(BMPINFOHEADER_T), fp );
fwrite( pData, 1, bmpsize, fp );
fclose( fp );
}
Q: 汉字字型以点阵方式存储,点阵的多少决定汉字的 : 大小
汉字的点阵存储方式是指把汉字的结构,例如笔画、点、线等,用一定的方式存储在计算机中。每一个汉字都有一套点阵,这套点阵由多个点组成,每个点都有一个坐标,表示这个点在汉字中的位置,以及是否需要打印出来。这套点阵的多少决定了汉字的大小,一般来说,点阵越多,汉字的大小也就越大。
一个汉字需用16×16点阵显示,一个字节(Byte)有8位(bit),一位代表一个点,一个字节只能表示8个点;
一个16×16点阵的汉字要占32 Byte(16x16=256bit 8bit=1Byte 所以16x16x1/8=32Byte)
3755个一级汉字共需3755×32=120160个字节。而1KB=1024Byte,所以一级汉字字库需占117KB存储空间,取2的整数次方,答案为128KB
例如:
一个字的点阵需要占空间:1616/8=32字节
3755字占空间:323755=120160字节=120160/1024K=117k
扩展资料:
一个点阵可以还原为一系列平行的阵点行列(简称阵列),或一系列的平行的阵点平面(简称阵面)。可用由一组基矢所确定的坐标系来描述某一组特定的阵列或阵面族的取向。我们选取通过原点的阵列上任意阵点的三个坐标分量,约化为互质的整数u、v、w作为阵列方向的指标,可用符号uvw来表示。
为了标志某一特定阵面族的方向,可选择最靠近但不通过原点的阵面,读取它在三个坐标轴上截距的倒数,将这三个数约化为互质的数h、k、l就得该阵面旋的方向指标,可用符号(hkl)来表示。这就是阵面族的密勒指数。
参考资料来源:百度百科-点阵
不知道你横向字模的点阵是以什么方式给出的,是二维数组么?
如果是的,可以在vb工程中引用excel对象,
dim ExlApp as new excelapplication
arr = exlapptranspose(arr)
这样就可以简单实现横纵坐标变换
如果你觉得这样不好,我可以帮你写一个转换的函数
以上就是关于在16*16点阵的字库中,存储一个汉字的点阵需占用全部的内容,包括:在16*16点阵的字库中,存储一个汉字的点阵需占用、谁了解字体数据结构、求助汉字转换点阵编程等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)