java中点阵字库的解析

最近研究点阵字库的展示,搜到很多东西,而且大多都是C语言做的,作为一个Android开发的码农,整理了一篇java版的,一方面自己记录,一方面帮助有需要的人。。。

 

点阵字,顾名思义,就是用点组成一个个的字,然后展示在某些东西上,常见的有成人用品店外面的LED上面那几个字,大家都懂得。

 

点阵字库就是收集了这些字的一个库。

 

有人要问了,为毛要有这个库,在点阵上面展示个字吗不就是,自己排版一下,然后点亮的用1,不亮的用0,然后记在文件里,用到的时候读取然后展示不就行了吗。

我要说,我开始也是这么想的。

但是,GBK有6763个汉字,你怎么破?

 

有人说有点阵字库生成器,输进去就出来编码了。

我要说,那个出来的是一个文本文件,而且我找了一个生成两个文件,一个索引文件,一个字库文件,而且两个加起来有1M左右~这个在我这个做Android的人眼里是巨大的文件了。

 

而且,点阵这个东西,有12*12,16*16,24*24,32*32。。。。各种型号,这个怎么破?

 

所以我在网上各种找资源,最后确定在HZK...和ASC..这些库上面了。

这个东西是啥呢?

其实是早期的DOS系统里面为了展示文字所用的文字库,和现在win和Mac下面的.ttf文件是一个意思,就是系统的字体库。

 

 UCDOS6.0系统文件列表 

 C:\UCDOS\FNT目录下:

ASC12             12x6点阵西文字库

HZK12             12x12点阵汉字库

HZK24T            24x24点阵中文符号字库

HZK24S            24x24点阵宋体汉字库

HZK12F            24x24点阵仿宋体汉字库

HZK12H            24x24点阵黑体汉字库

HZK12K            24x24点阵楷体汉字库

ASC40             40x20点阵西文字库

HZK40T            40x40点阵中文符号字库

HZK40S            40x40点阵宋体汉字库

ASC48             48x48点阵西文字库

HZK48T            48x48点阵中文符号字库

HZK48S            48x48点阵宋体汉字库

ASCPS             11种西文轮廓字库

HZKPST            中文符号轮廓字库

HZKPSSTJ          宋体汉字库

HZKPSFSJ          仿宋体汉字库

HZKPZHTJ          黑体汉字库

HZKPSKTJ          楷体汉字库

 

ps:上面这个是网上找的~我没有验证,而且我也只用了其中几个。

 

下面说说这玩意怎么用吧,这也是字库的好处之一,就是无需索引,你直接就能找到这个字的位置。

 

字库点阵格式定义

ASC12  ' 8x12 ASCII点阵 一个字符12Byte

ASC16  ' 8x16 ASCII点阵 一个字符16Byte

ASC48  '24x48 ASCII点阵 一个字符144Byte

 

HZK12  '16x12 宋体汉字点阵  一个汉字24Byte

HZK14  '16x14 宋体汉字点阵  一个汉字28Byte

HZK16  '16x16 宋体汉字点阵  一个汉字32Byte

HZK16F '16x16 繁体宋体汉字点阵  一个汉字32Byte

 

HZK24F '24x24 仿宋汉字打印点阵  一个汉字72Byte

HZK24H '24x24 黑体汉字打印点阵  一个汉字72Byte

HZK24K '24x24 楷体汉字打印点阵  一个汉字72Byte

HZK24S '24x24 宋体汉字打印点阵  一个汉字72Byte

HZK24T '24x24 宋体符号打印点阵  一个符号72Byte

 

HZK40S '40x40 宋体汉字点阵  一个汉字200Byte

HZK40T '40x40 宋体符号点阵  一个符号200Byte

 

HZK48S '48x48 宋体汉字点阵  一个汉字288Byte

HZK48T '48x48 宋体符号点阵  一个符号288Byte

 

http://bbs.csdn.net/topics/350189831

 

1.点阵字库

       点阵字库是把每一个汉字都分成16×16或24×24个点,然后用每个点的虚实来表示汉字的轮廓,常用来作为显示字库使用,这类点阵字库汉字最大的缺点是不能放大,一旦放大后就会发现文字边缘的锯齿。 

矢量字库保存的是对每一个汉字的描述信息,比如一个笔划的起始、终止坐标,半径、弧度等等。在显示、打印这一类字库时,要经过一系列的数学运算才能输出结果,但是这一类字库保存的汉字理论上可以被无限地放大,笔划轮廓仍然能保持圆滑,打印时使用的字库均为此类字库.

2.点阵字库结构

      在汉字的点阵字库中,每个字节的每个位都代表一个汉字的一个点,每个汉字都是由一个矩形的点阵组成,0代表没有,1代表有点,将0和1分别用不同颜色画出,就形成了一个汉字,常用的点阵矩阵有12*12, 14*14, 16*16三种字库。  字库根据字节所表示点的不同有分为横向矩阵和纵向矩阵,目前多数的字库都是横向矩阵的存储方式(用得最多的应该是早期UCDOS字库),纵向矩阵一般是因为有某些液晶是采用纵向扫描显示法,为了提高显示速度,于是便把字库矩阵做成纵向,省得在显示时还要做矩阵转换。我们接下去所描述的都是指横向矩阵字库。

       对于16*16的矩阵来说,它所需要的位数共是16*16=256个位,每个字节为8位,因此,每个汉字都需要用256/8=32个字节来表示。  即每两个字节代表一行的16个点,共需要16行,显示汉字时,只需一次性读取32个字节,并将每两个字节为一行打印出来,即可形成一个汉字.

//解析16*16的点阵字库
public class Font16 {  
    private Context context;  
  
    public Font16(Context context) {  
        this.context = context;  
    }  
  
    private final static String ENCODE = "GB2312";  
    private final static String ZK16 = "HZK16";  
  
    private boolean[][] arr;  
    int all_16_32 = 16;  
    int all_2_4 = 2;  
    int all_32_128 = 32;  
  
    public boolean[][] drawString(String str) {  
        byte[] data = null;  
        int[] code = null;  
        int byteCount;  
        int lCount;  
  
        arr = new boolean[all_16_32][all_16_32];  
        for (int i = 0; i < str.length(); i++) {  
            if (str.charAt(i) < 0x80) {  
                continue;  
            }  
            code = getByteCode(str.substring(i, i + 1));  
            data = read(code[0], code[1]);  
            byteCount = 0;  
            for (int line = 0; line < all_16_32; line++) {  
                lCount = 0;  
                for (int k = 0; k < all_2_4; k++) {  
                    for (int j = 0; j < 8; j++) {  
                        if (((data[byteCount] >> (7 - j)) & 0x1) == 1) {  
                            arr[line][lCount] = true;  
                            System.out.print("@");  
                        } else {  
                            System.out.print(" ");  
                            arr[line][lCount] = false;  
                        }  
                        lCount++;  
                    }  
                    byteCount++;  
                }  
                System.out.println();  
            }  
        }  
        return arr;  
    }  
  
    protected byte[] read(int areaCode, int posCode) {  
        byte[] data = null;  
        try {  
            int area = areaCode - 0xa0;  
            int pos = posCode - 0xa0;  
  
            InputStream in = context.getResources().getAssets().open(ZK16);  
            long offset = all_32_128 * ((area - 1) * 94 + pos - 1);  
            in.skip(offset);  
            data = new byte[all_32_128];  
            in.read(data, 0, all_32_128);  
            in.close();  
        } catch (Exception ex) {  
        }  
        return data;  
    }  
  
    protected int[] getByteCode(String str) {  
        int[] byteCode = new int[2];  
        try {  
            byte[] data = str.getBytes(ENCODE);  
            byteCode[0] = data[0] < 0 ? 256 + data[0] : data[0];  
            byteCode[1] = data[1] < 0 ? 256 + data[1] : data[1];  
        } catch (Exception ex) {  
            ex.printStackTrace();  
        }  
        return byteCode;  
    }  
  
}  

 

 

你可能感兴趣的:(java)