主题:不要汉字系统显示汉字的源程序
本程序需要UCDOS的汉字库,文件名:HZK16 ,asc16
一般在屏幕上显示汉字的时候需要汉字系统的支持,但需要自己显示汉字的时候,就需要自己读汉字字库文件,把字符点阵读出来,再用绘图的办法显示到屏幕上,本文是读 UCDOS 16点字库文件的示例。
在 UCDOS 的点阵字库 HZK16 中,UCDOS 的HZK16字库是一个16*16的点阵(asc16字库是一个8*16的点阵),每个字模32个字节,如果把他化成二进制排成16行,你会看到一个汉字的雏形。
字符点阵是按照汉字内码排列的,汉字的内码从一些图形字符开始,起始编码为 A1A1H,汉字内码第一位为区码,每区为 94 个汉字,第二位为每区内的编码,每个汉字的点阵为 16点*16点 共32字节,数据按第一行 1-8点,9-16点,第二行 1-8点,9-16点...排列,每位数据 1 为要显示点,0 为不显示点。汉字点阵数据在字库中的偏移量为 ((区码-A1H)*94 + (区内编码-A1H))*32。
如果要在自己的程序中使用,可以提取部分字模在程序中使用,从而无需hzk16,asc16这两个文件!
以下是程序代码:
OPEN "asc16" FOR BINARY AS #2
OPEN "hzk16" FOR BINARY AS #1
IF LOF(1) = 0 THEN PRINT "没有汉字库! ":END
SCREEN 12
hz1$ = "微软专用操作系统安装工具"
hz 1, 100, hz1$, 11
SUB hz (x0, y0, hz.word$, hzcol)
REM 这是显示汉字的子程序
savex0 = x0: savey0 = y0
FOR now = 1 TO LEN(hz.word$)
qu = ASC(MID$(hz.word$, now, 1))
IF qu >= 161 THEN
now = now + 1
IF now > LEN(hz.word$) THEN EXIT FOR
wei = ASC(MID$(hz.word$, now, 1))
ps& = ((qu - 161) * 94& + wei - 161) * 32& + 1
SEEK #1, ps&
zimo$ = INPUT$(32, 1)
num = 1
FOR y = 0 TO 15
chr1$ = MID$(zimo$, num, 1)
num = num + 1
chr2$ = MID$(zimo$, num, 1)
num = num + 1
chr3$ = chr2$ + chr1$
LINE (x0, y0 + y)-STEP(15, 0), hzcol, , CVI(chr3$)
NEXT y
x0 = x0 + 16
ELSE
SEEK #2, qu * 16
zimo$ = INPUT$(16, 2)
FOR y = 1 TO 16
zmchr$ = CHR$(0) + MID$(zimo$, y, 1)
LINE (x0, y0 + y)-STEP(15, 0), hzcol, , CVI(zmchr$)
NEXT y
x0 = x0 + 8
END IF
NEXT now
x0 = savex0: y0 = savey0
END SUB
一般在屏幕上显示汉字的时候需要汉字系统的支持,但需要自己显示汉字的时候,就需要自己读汉字字库文件,把字符点阵读出来,再用绘图的办法显示到屏幕上,本文是读 UCDOS 16点字库文件的示例。
在 UCDOS 的点阵字库 HZK16 中,UCDOS 的HZK16字库是一个16*16的点阵(asc16字库是一个8*16的点阵),每个字模32个字节,如果把他化成二进制排成16行,你会看到一个汉字的雏形。
字符点阵是按照汉字内码排列的,汉字的内码从一些图形字符开始,起始编码为 A1A1H,汉字内码第一位为区码,每区为 94 个汉字,第二位为每区内的编码,每个汉字的点阵为 16点*16点 共32字节,数据按第一行 1-8点,9-16点,第二行 1-8点,9-16点...排列,每位数据 1 为要显示点,0 为不显示点。汉字点阵数据在字库中的偏移量为 ((区码-A1H)*94 + (区内编码-A1H))*32。
如果要在自己的程序中使用,可以提取部分字模在程序中使用,从而无需hzk16,asc16这两个文件!
以下是程序代码:
OPEN "asc16" FOR BINARY AS #2
OPEN "hzk16" FOR BINARY AS #1
IF LOF(1) = 0 THEN PRINT "没有汉字库! ":END
SCREEN 12
hz1$ = "微软专用操作系统安装工具"
hz 1, 100, hz1$, 11
SUB hz (x0, y0, hz.word$, hzcol)
REM 这是显示汉字的子程序
savex0 = x0: savey0 = y0
FOR now = 1 TO LEN(hz.word$)
qu = ASC(MID$(hz.word$, now, 1))
IF qu >= 161 THEN
now = now + 1
IF now > LEN(hz.word$) THEN EXIT FOR
wei = ASC(MID$(hz.word$, now, 1))
ps& = ((qu - 161) * 94& + wei - 161) * 32& + 1
SEEK #1, ps&
zimo$ = INPUT$(32, 1)
num = 1
FOR y = 0 TO 15
chr1$ = MID$(zimo$, num, 1)
num = num + 1
chr2$ = MID$(zimo$, num, 1)
num = num + 1
chr3$ = chr2$ + chr1$
LINE (x0, y0 + y)-STEP(15, 0), hzcol, , CVI(chr3$)
NEXT y
x0 = x0 + 16
ELSE
SEEK #2, qu * 16
zimo$ = INPUT$(16, 2)
FOR y = 1 TO 16
zmchr$ = CHR$(0) + MID$(zimo$, y, 1)
LINE (x0, y0 + y)-STEP(15, 0), hzcol, , CVI(zmchr$)
NEXT y
x0 = x0 + 8
END IF
NEXT now
x0 = savex0: y0 = savey0
END SUB