J2me 游戏点阵字库引擎(四)之汉字库知识初步

最近由于项目需要,研究了下点阵字库。在这里分享下,以便同样有此问题的同仁们参考。
我用的字库是标准的GB2312的16大小的汉字。(懒的自己做字库,直接用标准的)先分析下字库吧。
点阵字说白了就是用画点的方式画出一个字。一个点占一位,一共是16*16,那么一个16的字所占大小是32byte。每个汉字都有自己的区位码,一个汉字是由两个扩展ASCII码组成的。第一个是区码,第二个是位码。在GB2312标准中,将所有汉字分成94个区,每个区有94个位可以存放94个汉字,形成了人们常说的区位码,这样总共就有94*94=8836 个汉字。点阵字库中,汉字的点阵数据就是按照区位的顺序储存的。比如“你”字就是由c4和e3组成的。在汉字的内码中,汉字区位码的存放是在扩展 ASCII 基础上存放的,并且将区码和位码都加上了32,然后存放在两个扩展 ASCII 码中。具体是:
第一个扩展ASCII码 = 128+32 + 汉字区码

第二个扩展ASCII码 = 128+32 + 汉字位码
那么汉字的存放区位就能知道了:
汉字区码 = 第一个扩展ASCII码-128-32
汉字位码 = 第二个扩展ASCII吗-128-32
按照这个,“你”字的区位码就是36和67。
同时我们也可以找到我们想要的数据了。公式是:((区码-1) * 94 + 位码) * 一个点阵字占用的字节数

数据找到了,在j2me中把点画出来就是点阵字了。
代码如下:

import Java.io.InputStream;
import javax.microedition.lcdui.Graphics;
/*
* CustomFont.java
*
* Created on 2008年9月23日, 上午9:41
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
/**
*
* 点阵字库的加载和绘制,针对GB2312编码的16*16的标准汉字
* by killer
*/
public class CustomFont {
    
    public final static int[] mask = {128, 64, 32, 16, 8, 4, 2, 1};
    public final static String ZK_PATH = "/font/HZK16";
    public final static String ENCODE = "GB2312";
    
    /** Creates a new instance of CustomFont */
    public CustomFont() {
    }
    
    /**
     *绘制点阵中文汉字,gb2312,16字
     *@param g 画笔
     *@param str 需要绘制的文字
     *@param x 屏幕显示位置x
     *@param y 屏幕显示位置y
     *@param color 文字颜色
     *
     */
    protected void drawString(Graphics g,String str,int x,int y,int color){
        byte[] data = null;
        int[] code = null;
        int byteCount;//到点阵数据的第几个字节了
        int lCount;//控制列
        g.setColor(color);
        for(int i = 0;i < str.length();i ++){
            if(str.charAt(i) < 0x80){//非中文
                g.drawString(str.substring(i,i+1),x+(i<<4),y,0);
                continue;
            }
            code = getByteCode(str.substring(i,i+1));
            data = read(code[0],code[1]);
            byteCount = 0;
            for(int line = 0;line < 16;line ++){
                lCount = 0;
                for(int k = 0;k < 2;k ++){
                    for(int j = 0;j < 8;j ++){
                        if((data[byteCount]&mask[j])==mask[j]){
                            g.drawLine(x+lCount+(i<<4),y+line,x+lCount+(i<<4),y+line);
                        }
                        lCount++;
                    }
                    byteCount ++;
                }
            }
        }
    }
        
    /**
     *读取文字信息
     *@param areaCode 区码
     *@param posCode 位码
     *@return 文字数据
     */
    protected byte[] read(int areaCode,int posCode){
        byte[] data = null;
        try{
            int area = areaCode-0xa0;//获得真实区码
            int pos  = posCode-0xa0;//获得真实位码
            
            InputStream in = getClass().getResourceAsStream(ZK_PATH);
            long offset = 32*((area-1)*94+pos-1);
            in.skip(offset);
            data = new byte[32];
            in.read(data,0,32);
            in.close();
        }catch(Exception ex){
        }
        return data;
    }
    
    /**
     *获得文字的区位码
     *@param str
     *@return int[2]
     */
    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){
        }
        return byteCode;
    }
    
}

 引用于http://dev.10086.cn/cmdn/wiki/index.php?doc-view-4995.html。它讲的很好!对汉字字库有深入的研究。

但是,在实际的开发中,要是将全部字库都加载到程序中,在N73还是会卡的。这个卡的原因,字库本身很庞大,导致检索很慢。为此我们只能将部分字库加载到游戏内存中,这里就有一个策略问题??我们应该如何设计??

你可能感兴趣的:(j2me)