GB2312和ASCII码点阵字库HZK, ASC说明使用心得,全

这几天接了一个项目,需要制作点阵文字,所以接触了字库这东西,由于网上字库挺多的,但是不全,有的字库全,但是字库的读取代码只有一部分,所以还是花费了一天时间搞这东西。现在整理了一份叫全的字体,并配上每种字体的读取代码。下载地址:>>
网上介绍概念的文章有很多,这里我就引用一下了。>>这里包含了HZK字库和ASC字库,写了两个类进行读取,代码如下

HZK:

import java.io.FileInputStream;
import java.io.IOException;


public class Char2Mat {
    private int font_size = 48;
    private int font_height = font_size;
    private int font_width = font_size;
    private int size_step = 8;
    private char word = '我';
    private byte[] cbuf;
    private char[] key = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};

    Char2Mat(int font_size, char word) {
        this.font_size = font_size;
        this.font_height = font_size;
        if (font_size != 12)
            this.font_width = font_size;
        else
            this.font_width = 16;
        this.word = word;
    }

    public void getMat() {
        try {
            int sizeof_byte = size_step;
            int offset_step = font_width * font_height / sizeof_byte;

            byte[] incode = String.valueOf(word).getBytes("GB2312");
            int t1 = (int) (incode[0] & 0xff);
            int t2 = (int) (incode[1] & 0xff);
            int offset = 0;

            // calculate offset for different size font
            if (t1 > 0xa0) {
                if (font_size == 40 || font_size == 48) {
                    // 这里暂不处理t1 < 0xa1 + 0x0f的部分,注意大于24的字体都是倒立了的
                    offset = ((t1 - 0xa1 - 0x0f) * 94 + (t2 - 0xa1))
                            * offset_step;
                } else if (font_size == 12 || font_size == 16 || font_size == 24 || font_size == 32) {
                    offset = ((t1 - 0xa1) * 94 + (t2 - 0xa1)) * offset_step;
                }
            } else {
                offset = (t1 + 156 - 1) * offset_step;
            }

            cbuf = new byte[offset_step];
            FileInputStream inputStream = new FileInputStream("HZK"
                    + String.valueOf(font_size));
            inputStream.skip(offset);
            if (inputStream.read(cbuf, 0, offset_step) < 0) {
                System.out.println("read failed!");
                return;
            }

            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void print() {
        if (font_size == 40 || font_size == 48) {
            for (int i = 0; i < font_size; i++) {
                for (int j = 0; j < font_size; j++) {
                    int index = i * font_width + j;
                    int flag = cbuf[index / size_step] & key[index % size_step];
                    System.out.print(flag > 0 ? "●" : "○");
                }
                System.out.println();
            }
        } else if (font_size == 12 || font_size == 16 || font_size == 24 || font_size == 32) {
            for (int i = 0; i < font_size; i++) {
                for (int j = 0; j < font_size; j++) {
                    int index = j * font_width + i;
                    int flag = cbuf[index / size_step] & key[index % size_step];
                    System.out.print(flag > 0 ? "●" : "○");
                }
                System.out.println();
            }
        }
    }
}

ASC:

// 只用于95个可显示ASCII符号

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;


public class Num2Mat {
    private int font_width = 8;
    private int font_height = 12;
    private int size_step = 8;
    private char char_num = '1';
    private byte[] cbuf;
    private char[] key = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};

    Num2Mat(int font_height, int font_width, char char_num) {
        this.font_height = font_height;
        this.font_width = font_width;
        this.char_num = char_num;
    }

    public void getMat() {
        int sizeof_byte = size_step;
        int offset_step = font_width * font_height / sizeof_byte;

        int ascii = (int) char_num;
        if (ascii > 127 || ascii < 32) {
            System.out.println("input char is invaild!");
            return;
        }
        int offset = (ascii - 32) * offset_step;

        try {

            cbuf = new byte[offset_step];
            FileInputStream inputStream = inputStream = new FileInputStream(
                    "ASC" + String.valueOf(font_height) + "_" + String.valueOf(font_width));
            inputStream.skip(offset);
            if (inputStream.read(cbuf, 0, offset_step) < 0) {
                System.out.println("read failed!");
                return;
            }

            inputStream.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void print() {
        if (font_height == 12 || font_height == 48) {
        // 横向取字
        for (int i = 0; i < font_height; i++) {
            for (int j = 0; j < font_width; j++) {
                int index = i * font_width + j;
                int flag = cbuf[index / size_step] & key[index % size_step];
                System.out.print(flag > 0 ? "●" : "○");
            }
            System.out.println();
        }
        } else {
            // 纵向取字
        for (int i = 0; i < font_height; i++) {
            for (int j = 0; j < font_width; j++) {
                    int index = j * font_height + i;
                int flag = cbuf[index / size_step] & key[index % size_step];
                System.out.print(flag > 0 ? "●" : "○");
            }
            System.out.println();
        }
        }
    }
}

调用示例:

import java.io.*;

public class Font {
    public static void main(String[] args) {
        Char2Mat cm = new Char2Mat(16, '我');
        cm.getMat();
        cm.print();

        Num2Mat nm = new Num2Mat(48, 24, 'A');
        nm.getMat();
        nm.print();
    }
}

注意点:

  1. GB2312
    包含12*12, 16*16, 24*24, 32*32, 40*40, 48*48五个尺寸
    • HZK12 显示是按12*12点阵显示,但是存储的时候由于计算机是按8位整数倍储存,所以实际这个字库是按12*16储存的,多了4列,所以显示的时候有特别处理
    • 12,16,24,32尺寸的字库都是按列取值的,40,48都是按行取值的
    • 40,48尺寸的字库把汉字库和全角字符库分开了,因为我们只需汉字库,所以在计算这两个吃出汉字库的offset时,需要多减去0x0f
  2. ASCII
    包含12*8, 16*8, 24*12, 32*16, 48*24
    • 所有的ASC字库都只存储了可显示的ASCII字符,所以计算offset时,要减去32
    • 12*8和48*24的字库是按行取值,其他是按列取值
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值