Chinaunix首页 | 论坛 | 博客
  • 博客访问: 355667
  • 博文数量: 101
  • 博客积分: 4714
  • 博客等级: 大校
  • 技术积分: 1725
  • 用 户 组: 普通用户
  • 注册时间: 2006-10-01 04:51
文章分类

全部博文(101)

文章存档

2011年(1)

2010年(98)

2008年(2)

分类: Java

2008-03-26 09:42:48

这里是用在游戏汉化移植。
对于在其他没有汉字字符,或者只有有限字体、固定大小的平台,也许比较有用。
 
FontExporter.java

用FontExporter 导出字体。只导出用到的字体,节省空间。这里需要jxl包,考虑到从excel里面获取文本。

显示字体时候,使用PicFont.java,Lib.java

/**
 * FontExporter.
 * Not well designed, only for common use.
 * No copyright.
 */


package util.loc;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.ArrayList;
import java.io.*;
import jxl.*;

class FontExporter {

    int fontSize = 12;
    int fontPadding = 2;
    String fontName = "";
    int fontStyle = Font.PLAIN;
    BufferedImage bi;
    Graphics bg;

    String stringToExport = null;

    int[] buf;
    int[] zeroBuf;

    ArrayList fontData = new ArrayList();

    /**
     * Used much disk...
     */

    void saveDataAsVector(int[] data, int scanWidth){

        int len = 0, line;
        for (int off = 0; off < data.length; off++){

            if (off % scanWidth == 0) len = 0;
            line = off / scanWidth;
            
            if (data[off] == 0){

                if (len > 0) System.out.println((off / scanWidth) + ": " + (off % scanWidth-len) + ", " + len);
                len = 0;
            } else len++;
        }
    }

    void clearBuf(){

        System.arraycopy(zeroBuf, 0, buf, 0, buf.length);
    }

    int[] dataAsMap(int[] data, int scanWidth, int height){

        int maxW = Math.min(scanWidth, 32);
        int[] result = new int[height];
        
        int off;
        for (int row = 0; row < height; row++){
            
            off = row * scanWidth;
            for (int col = 0; col < maxW; col++){

                if (data[off+col] != 0) result[row] |= 1 << col;
            }
        }
        return result;
    }

    String removeDupChars(String str){

        if (str == null) return null;

        StringBuffer result = new StringBuffer(0x1000);
        char tmp;
        for (int i=0; i < str.length(); i++){

            tmp = str.charAt(i);
            if (tmp > 0xFF && result.indexOf(String.valueOf(tmp)) == -1) result.append(tmp);
        }

        return result.toString();
    }

    /**
     * Still something to do
     */

    void adjustFontPadding(){

        if (fontSize > 28) fontPadding = 6;
        else if (fontSize > 22) fontPadding = 4;
        else if (fontSize > 16) fontPadding = 3;
        else if (fontSize > 12) fontPadding = 3;
        else if (fontSize > 9) fontPadding = 2;
        else fontPadding = 1;
    }

    public FontExporter(String fontName, int fontStyle, int fontSize){

        this.fontSize = fontSize;
        this.fontName = fontName;
        this.fontStyle = fontStyle;

        init();
    }

    public void init(){

        bi = new BufferedImage(fontSize, fontSize, BufferedImage.TYPE_4BYTE_ABGR);
        bg = bi.getGraphics();

        bg.setFont(new Font(fontName, fontStyle, fontSize));
        buf = new int[bi.getWidth() * bi.getHeight()];

        zeroBuf = new int[buf.length];
        adjustFontPadding();
    }

    int[] charData(char ch){

        bi.setRGB(0, 0, bi.getWidth(), bi.getHeight(), zeroBuf, 0, bi.getWidth());
        bg.drawString(String.valueOf(ch), 0, fontSize-fontPadding);
        bi.getRGB(0, 0, bi.getWidth(), bi.getHeight(), buf, 0, bi.getWidth());

//        saveDataAsVector(buf, bi.getWidth());


/** Display & adjust
        Graphics g = btnExit.getGraphics();
        g.drawImage(bi, 2, 2, btnExit);
//*/

        return dataAsMap(buf, bi.getWidth(), fontSize);
    }

    public void export(String outFileName){

        if (stringToExport == null){ System.out.println("Nothing to export."); return; }
        
        fontData.clear();

        for (int i = 0; i < stringToExport.length(); i++)
            fontData.add(charData(stringToExport.charAt(i)));
        
        doExport(outFileName);
    }

    void doExport(String outFileName) {

        System.out.println("*********** Summary **************");
        System.out.println("Font-size: " + fontSize);
        System.out.println("Char-count: " + fontData.size());
//        System.out.println("chars: " + stringToExport);

//        System.out.println("********* font data: *********");


        int[] tempBuf;
/** Test and adjust
        for (int idx=0; idx < fontData.size(); idx++){

            tempBuf = (int[])fontData.get(idx);
            for (int i = 0; i < tempBuf.length; i++){
                System.out.println(Lib.binFormat(Integer.toBinaryString(tempBuf[i]), fontSize));
            }
        }
//*/

        DataOutputStream out = null;
        try{
            
            out = new DataOutputStream(new FileOutputStream(new File(outFileName)));
            out.writeInt(fontSize);
            out.writeInt(fontData.size());

            for (int i = 0; i < stringToExport.length(); i++)
                out.writeChar(stringToExport.charAt(i));

            for (int idx=0; idx < fontData.size(); idx++){

                tempBuf = (int[])fontData.get(idx);
                for (int i = 0; i < tempBuf.length; i++){

                    if (fontSize <= 16) out.writeShort(tempBuf[i]);
                    else out.writeInt(tempBuf[i]);
                }
            }
            out.flush();

        } catch (Exception e){

            e.printStackTrace();
        } finally {

            try{
                out.close();
            }
            catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    void loadTextFile(String fileName){

        String result= null;
        DataInputStream in = null;
        try{
            
            in = new DataInputStream(new FileInputStream(new File(fileName)));
            byte[] buf = new byte[in.available()];
            in.read(buf);

            result = new String(buf, "UTF-8");
        } catch (Exception e){

            System.out.println("PicFont load failed.");
        } finally {

            try{
                in.close();
            }
            catch (Exception e){
                e.printStackTrace();
            }

        }

        stringToExport = removeDupChars(result);
    }

    void loadXlsFile(String fileName, int column){

        StringBuffer result = new StringBuffer(5000);

        Workbook wb = null;
        try {
    
            wb = Workbook.getWorkbook(new File(fileName));
            Sheet[] sheets = wb.getSheets();
            int rowCount;
            for (int i = 1; i < sheets.length; i++){
                
                System.out.println("***************** Exporting sheet: " + sheets[i].getName());
                
                rowCount = sheets[i].getRows();
                for (int row = 1; row < rowCount; row++)
                    result.append(sheets[i].getCell(column, row).getContents());
            }
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
        finally {
            try {
                wb.close();
            } catch (Exception e){
                e.printStackTrace();
            }
        }
        
        stringToExport = removeDupChars(result.toString());
    }
    
    public static void main(String[] args) throws Exception
    {
        System.out.println("Created by pal, no copyright, use or improve it for free.");
        System.out.println("Usage: java -cp \"jxl.jar;picfont.jar\" util.loc.FontExporter");
        System.out.println("This program takes exactly 5 parameters.");
        System.out.println("params: ");
        System.out.println("eg: Arial 12 abc.xls 2 FL12");
        
        int fontSize = Integer.parseInt(args[1]);
        int textColumn = Integer.parseInt(args[3]);

        FontExporter fontExporter = new FontExporter(args[0], Font.PLAIN, fontSize);

        if (args[2].endsWith(".xls")) fontExporter.loadXlsFile(args[2], textColumn);
        else fontExporter.loadTextFile(args[2]);
        
        fontExporter.export(args[4]);
    }
}

/**
 * PicFont.java
 * Not well designed, only for common use.
 * No copyright. Anyone can use or improve it freely.
 *
 * Created by pal 2008-3-25
 * 2008-3-28 pal bugfix: drawLine go on looping when fontsize == 16 or 32
 * 2008-4-2 pal bugfix:
 *
 *    The old versions use readUTF/writeUTF to store chars in font-file, changed to writeChar/readChar.
 *
 * For Motorola V600, as in.available() is always 0, you should change some code:
 * loaded = in.available() == buf.length; --> loaded=true;
 *
 * 2008-4-2 pal add drawCharImg, which use buffered image to draw font,
 *        that will improve spreed but also take up more memory: _fontSize*_maxBit
 *
 * 2008-4-8 pal bugfix: color get from g.getColor() do not has alpha bits, you should set it
 *         yourself. Or you will draw nothing (all transparent) in the real phone.
 */


import java.io.*;
import javax.microedition.lcdui.*;

class PicFont
{
    char[] chars;
    int _fontSize;
    int _maxBit;
    short[] fontMapSmall;
    int[] fontMapLarge;
    boolean _fontMapShort;
    boolean loaded;
    int[] _fontImgBuf;
    
    boolean _useImgFont = true;
    
    boolean _useGradualColor = true; // Special effects. You can try other image effects here.


    public int fontSize(){

        return _fontSize;
    }

    public void setUseImgFont(boolean useImageFont){

        _useImgFont = useImageFont;
    }

    public void setUseGradualColor(boolean useGradualColor){

        _useGradualColor = useGradualColor;
    }
    
    public void load(InputStream is){
        
        DataInputStream in = null;
        try{
            
            in = new DataInputStream(is);
            _fontSize = in.readInt();
            int charCount = in.readInt();
            
            chars = new char[charCount];
            for (int i = 0; i < charCount; i++)
                chars[i] = in.readChar();

            _fontMapShort = _fontSize <= 16;
            _maxBit = _fontMapShort ? 16 : 32;

            byte[] buf = new byte[charCount * _fontSize * (_fontMapShort ? 2 : 4)];

            int bytesReaded = in.read(buf);
            loaded = bytesReaded == buf.length;
            if (!loaded) return;

            if (_fontMapShort) fontMapSmall = Lib.arrayByteToShort(buf);
            else fontMapLarge = Lib.arrayByteToInteger(buf);

            if (_useImgFont) _fontImgBuf = new int[_fontSize*_fontSize];

        } catch (Exception e){

            System.out.println("PicFont load failed.");
        } finally {

            try{
                in.close();
            }
            catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * Find char index in char-map.
     */

    private int getCharMapIndex(char ch){

        int idx = -1;
        for (int i = 0; i < chars.length; i++) if (chars[i] == ch){ idx = i; break; };
        
        return idx > 0 ? idx * _fontSize : idx;
    }

    private void drawLine(Graphics g, int pixelBytes, int x, int y ){

        int offsetX = 0;
        for (int startBit=0, len = 0; startBit < _maxBit; startBit++){

            if ((pixelBytes & (1 << startBit)) == 0){        

                if (len > 0) g.fillRect(x + offsetX, y, len, 1);
                len = 0;
            } else {

                if (len++ == 0) offsetX = startBit;
                if (startBit >= _maxBit-1) g.fillRect(x + offsetX, y, len, 1);
            }
        }
    }

    private void drawCharLine(Graphics g, int start, int x, int y){

        for (int i = start; i < start + _fontSize; i++)
            drawLine(g, _fontMapShort ? fontMapSmall[i] : fontMapLarge[i], x, y++);
    }

    private void drawCharImg(Graphics g, int start, int x, int y){

        int color = g.getColor() | 0xff000000;
        int line = 0;
        for (int i = start; i < start + _fontSize; i++){

            int pixel = _fontMapShort ? fontMapSmall[i] : fontMapLarge[i];
            for (int bit = 0; bit < _fontSize; bit++) _fontImgBuf[line+bit] = (pixel & (1 << (bit))) != 0 ? color : 0;

            line += _fontSize;
        }
        
        if (_useGradualColor) FontEffect.gradualEffect(_fontImgBuf, _fontSize, _fontSize, color);

        g.drawRGB(_fontImgBuf, 0, _fontSize, x, y, _fontSize, _fontSize, true);
    }

    public void drawChar(Graphics g, char c, int x, int y ){

        if (!loaded) return;
        
        int start = getCharMapIndex(c);

        if (start < 0) return;

        try {

            if (_useImgFont) drawCharImg(g, start, x, y);
            else drawCharLine(g, start, x, y);
        } catch (Exception e){
            
            e.printStackTrace();
        }
    }
}

class FontEffect {

    private static int gradSingleColor(int r, int bits){

        r = (r >> bits) & 0xff;
        r = r > 5 ? (r-5) : r;
        return r << bits;
    }

    private static int gradualColor(int color){

        int r = gradSingleColor(color, 16);
        int g = gradSingleColor(color, 8);
        int b = gradSingleColor(color, 0);

        return (color & 0xFF000000) | r | g | b;
    }

    public static void gradualEffect(int[] buf, int width, int height, int color){

        int line = 0;
        int lineColor = color;
        for (int h = 0; h < height; h++){

            for (int w = 0; w < width; w++) buf[line+w] = (buf[line+w] & 0xFF000000) == 0 ? 0 : lineColor;
            
            lineColor = gradualColor(lineColor);
            line += width;
        }
    }
}

阅读(2117) | 评论(2) | 转发(0) |
0

上一篇:无助

下一篇:卡马克。。

给主人留下些什么吧!~~

chinaunix网友2008-06-18 18:01:29

修改后的。。 /** * PicFont.java * Not well designed, only for common use. * No copyright. Anyone can use or improve it freely. * * Created by ak 2008-3-25 * 2008-3-28 ak bugfix: drawLine go on looping when fontsize == 16 or 32 * 2008-4-2 ak bugfix: * * The old versions use readUTF/writeUTF to store chars in font-file, changed to writeChar/readChar. * * For Motorola V600, as in.available() is always 0, you should change some code: * loaded = in.available() == buf.length;

chinaunix网友2008-03-31 11:36:26

//bugfix: drawLine go on looping when fontsize == 16 or 32 public void drawLine(Graphics g, int pixelBytes, int x, int y ){ int offsetX = 0; for (int startBit=0, len = 0; startBit < _maxBit; startBit++){ if ((pixelBytes & (1 << startBit)) == 0){ if (len > 0){ System.out.println(y + "-drawChar: "); g.fillRect(x + offsetX, y, len, 1); } len = 0; } else { if (len++ == 0) offsetX = startBit; if (startBit >= _maxBit-1) g.fillRect(x + offsetX, y, len, 1);