2021-09-27

C++语言读取点阵字库

最近研究了一下点阵字库,发现网上没有很好的现成C++代码,基本上都是C语言的代码读取USDOS的点阵字库。UCDOS是很古老DOS时代的产物了,包含以下点阵字库:
ABC 英文字库文件
ASC12 ASCII字库文件12X6
ASC16 ASCII字库文件16X8
ASC48 ASCII字库文件48X24
Hzk12 汉字库宋体12X12
Hzk16 汉字库宋体16X16
hzk16F 汉字库仿宋16X16
HZK24F 汉字库仿宋24X24
HZK24H 汉字库黑体24X24
HZK24K 汉字库楷体24X24
HZK24S 汉字库宋体24X24
HZK24T 全角字符库24X24
HZK24Z 汉字库篆体24X24
HZK40S 汉字库宋体40X40
HZK40T 全角字符库40X40
HZK48S 汉字库宋体48X48
HZK48S 全角字符库48X48

没有完整的西文点阵字库,只有ASC12,16,48字库,其它大小的点阵字库未见。点阵在HZK16和HZK24以上字库中定位是不同的。HZK16的汉字起始区在第16个分区,而HZK24以上的字库则直接从第一个分区开始。HZK16的前15个分区里面存储了一些特殊符号,字母等。因此汉字所在的分区是从15号分区开始的,而HZK24以上字库不包含前面的特殊字符,第一个区就是汉字区“啊”,从0号分区开始。难道这样是为了节省存储空间(以前存储介质贵)或者是放在ABC内?我没深入研究。并且HZK16和HZK24点阵扫描方式不同,HZK16是横向,先左右后上下,HZK24是纵向先上下后左右,字模的存放方式不同。为什么要这样设置?据说当时HZK24票据打印机用得较多,是为了方便打印。
综上所述,UCDOS点阵字库存在这些问题:
1、西文字库不完整。
2、字模存放的偏移地址不同。
3、字模的读取方式不同。
现在从矢量字库提取点阵字库的方法和工具非常多了,可以得到各种字体的点阵字库。而且可以规范字模的偏移地址和读取方式,方便编程,该抛弃UCDOS点阵字库了。以下是我从微软雅黑字体提取的点阵字库;下载地址
ASC12 8X12 一般都是6X12,字体太小,我提取为8X12显示效果好一些
ASC16 10X16 一般都是8X16,字体太小,我提取为10X16显示效果好一些
ASC24 16X24
ASC32 24X32
ASC48 32X48
HZK12 12X12
HZK16 16X16
HZK24 24X24
HZK32 32X32
HZK48 48X48
显示效果:
在这里插入图片描述
具体点阵字体读取的算法网上有很多介绍,不再赘述,以下是源码,在devcpp V6.4下编译通过。



```cpp
#include<graphics.h>
#include<iostream>
#include <fstream>
#include <string>
#include<sstream>

using namespace std;
void Latticefont(string hzstr, int x, int y, int Fontsize, int color); /*点阵字库显示函数*/

int	main()	{
	initgraph(800, 600);	//初始化窗口大小
	setcaption("点阵字体输出");	//设置窗口标题
	string text = "hello,你好,world,世界";
	Latticefont("hello,你好,world,世界", 10, 60, 12, 0xFF0000); /*显示12点阵字库*/
	Latticefont(text, 10, 80, 12, 0xFF0000);
	Latticefont("hello,你好,world,世界", 10, 100, 16, 0xFF0000); /*显示16点阵字库*/
	Latticefont(text, 10, 120, 16, 0xFF0000);
	Latticefont("hello,你好,world,世界", 10, 160, 24, 0xFF0000); /*显示24点阵字库*/
	Latticefont(text, 10, 200, 24, 0xFF0000);
	Latticefont("hello,你好,world,世界", 10, 240, 32, 0xFF0000); /*显示32点阵字库*/
	Latticefont(text, 10, 280, 32, 0xFF0000);
	Latticefont("hello,你好,world,世界", 10, 340, 48, 0xFF0000); /*显示48点阵字库*/
	Latticefont(text, 10, 400, 48, 0xFF0000);
	system("pause");
}



void Latticefont(string hzstr, int x, int y, int Fontsize, int color) {
	unsigned int QM, WM;
	long int pointer, record;
	register int i, j, k;
	long int CFL = 0, EFL = 0; /*中英文字模的长度*/
	int CFBL = 0, EFBL = 0, L = 0; /*中英文点阵宽度占用字节,L不显示英文无点的空白区*/
	char hz16buf[288], d = 0; /*点阵单个汉字缓冲区按最大字体48分配字节,d为字间距*/
	char asc16buf[144]; /*点阵单个英文缓冲区按最大字体48分配字节*/
	unsigned char *hzp = (unsigned char*)hzstr.c_str();
	ifstream HZKfile, ASCfile;
	if (Fontsize == 12) {
		HZKfile.open("hzk12", ios::in | ios::binary);
		if (! HZKfile.is_open()) {
			cout << "字库文件hzk12打开失败!" << endl;/*打开12点阵汉字库文件*/
			exit (1);
		}
		ASCfile.open("asc12", ios::binary);
		if (! ASCfile.is_open()) {
			cout << "字库文件asc12打开失败!" << endl;/*打开12点阵西文字库文件*/
			exit (1);
		}
		CFL = 24, EFL = 12, CFBL = 2, EFBL = 1;
	}
	if (Fontsize == 16) {
		HZKfile.open("hzk16", ios::in | ios::binary);
		if (! HZKfile.is_open()) {
			cout << "字库文件hzk16打开失败!" << endl;/*打开16点阵汉字库文件*/
			exit (1);
		}
		ASCfile.open("asc16", ios::binary);
		if (! ASCfile.is_open()) {
			cout << "字库文件asc16打开失败!" << endl;/*打开16点阵西文字库文件*/
			exit (1);
		}
		CFL = 32, EFL = 32, CFBL = 2, EFBL = 2;
	}
	if (Fontsize == 24) {
		HZKfile.open("hzk24", ios::in | ios::binary);
		if (! HZKfile.is_open()) {
			cout << "字库文件hzk24打开失败!" << endl;/*打开24点阵汉字库文件*/
			exit (1);
		}
		ASCfile.open("asc24", ios::binary);
		if (! ASCfile.is_open()) {
			cout << "字库文件asc24打开失败!" << endl;/*打开24点阵西文字库文件*/
			exit (1);
		}
		CFL = 72, EFL = 48, CFBL = 3, EFBL = 2;
	}
	if (Fontsize == 32) {
		HZKfile.open("hzk32", ios::in | ios::binary);
		if (! HZKfile.is_open()) {
			cout << "字库文件hzk32打开失败!" << endl;/*打开32点阵汉字库文件*/
			exit (1);
		}
		ASCfile.open("asc32", ios::binary);
		if (! ASCfile.is_open()) {
			cout << "字库文件asc32打开失败!" << endl;/*打开32点阵西文字库文件*/
			exit (1);
		}
		CFL = 128, EFL = 96, CFBL = 4, EFBL = 3;
	}
	if (Fontsize == 48) {
		HZKfile.open("hzk48", ios::in | ios::binary);
		if (! HZKfile.is_open()) {
			cout << "字库文件hzk48打开失败!" << endl;/*打开48点阵汉字库文件*/
			exit (1);
		}
		ASCfile.open("asc48", ios::binary);
		if (! ASCfile.is_open()) {
			cout << "字库文件asc48打开失败!" << endl;/*打开48点阵西文字库文件*/
			exit (1);
		}
		CFL = 288, EFL = 192, CFBL = 6, EFBL = 4;
	}
	while (*hzp) { /*显示串中所有字符*/
		if (*hzp >= 160) { /*汉字*/
			QM = (*hzp - 0xa1) & 0x07f; /*区号*/
			WM = (*(hzp + 1) - 0xa1) & 0x7f; /*位号*/
			record = (QM) * 94 + WM; /*字模信息在字库中记录号*/
			pointer = record * CFL; /*点阵字模偏移*/
			HZKfile.seekg(pointer);
			HZKfile.read(hz16buf, CFL); /*从文件读字模信息到缓冲区*/
			for (i = 0; i < Fontsize; i++) /*点阵行数*/
				for (j = 0; j < CFBL; j++) /*每行字节数*/
					for (k = 0; k < 8; k++) /*每字节8位二进制*/
						if (hz16buf[CFBL * i + j] >> (7 - k) & 1) /*若该位非空白*/
							putpixel(x + j * 8 + k, y + i, color); /*画点*/
			x += Fontsize + d; /*横坐标增加字间距,以显示下一个汉字*/
			hzp += 2;  /*下一汉字指针*/
		} else { /*若字符为西文*/
			record = *hzp++; /*西文记录号*/
			pointer = record * EFL; /*偏移*/
			ASCfile.seekg(pointer);
			ASCfile.read(asc16buf, EFL); /*从文件读字模信息到缓冲区*/
			for (i = 0; i < Fontsize; i++) /*点阵行数*/
				for (j = 0; j < EFBL; j++) /*每行字节数*/
					for (k = 0; k < 8; k++) /*每行8位*/
						if (asc16buf[EFBL * i + j] >> (7 - k) & 1) { /*若该位非空*/
							putpixel(x + j * 8 + k, y + i, color); /*画点*/
							if (j * 8 + k > L) L = j * 8 + k; /*英文非等宽,记录最宽画点的位置*/
						}
			x += L + 2 + d; /*下一个字符的横坐标*/
			L = 0;
		}
	}
	HZKfile.close();/*显示完毕后关闭字库文件*/
	ASCfile.close();
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值