JDK1.5.0 在Linux下字體文件的處理
apache的batik是一個處理svg的庫, 本人本打算拿它來作一個過濾的servlet,在瀏覽器不支援svg的情況下,自動畫個png圖形送到客戶端。本來以為是很簡單的事情,但是....鬱悶,這個問題搞掉了我2天時間, 現在回想起來, 這個問題前後出錯的原因不一樣,但是導致的問題缺相似,導致我主觀的認為兩個錯誤是同樣原因引起的, 浪費了大量時間去檢查. 一開始畫圖,中文是??? ,不用說,一定是中文編碼問題, fix了, 然後又繪圖,看上去正常了,不過正式運行以後發現,圖形中部分中文文字顯示不出來,為"口口", 我以為還是編碼問題, 埋頭扎進batik, 檢查了半天,沒有看到哪對編碼作了不當處理, 最後一路檢查到graphics2d.drawXXX, 實在是沒有辦法了, 再下去就是native code了, 於是我回頭又檢查了一遍,還是不行,幾乎放棄了。 今天早上來心情好,突然想到會不會是jdk的bug, 於是動手寫了個jsp,代碼如下
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
String fontNames[] = ge.getAvailableFontFamilyNames();
String path=application.getRealPath("/client")+"/test";
// Iterate the font family names
for (int i = 0; i < fontNames.length; i++) {
String fontName = fontNames[i];
out.print(fontName);
BufferedImage bufferedImage = new BufferedImage(400,400,BufferedImage.TYPE_3BYTE_BGR);
Graphics big = bufferedImage.createGraphics();
big.setFont(new Font(fontName,Font.PLAIN,30));
big.drawString("你好,發送到A",100,100);
OutputStream os=new FileOutputStream(path+"/"+fontName+".jpg");
JPEGImageEncoder encoder=JPEGCodec.createJPEGEncoder(os);
encoder.encode(bufferedImage);
os.close();
}
用系統列出來所有字體畫一遍圖,然後一個一個看,果然,問題找到了
1沒有simsun字體!汗~~~,原來能畫出來的那些部分中文用的不知道是什麼字體。
2 情況和batik一樣,部分中文繪製不出來,為方框
上網google了一下, 發現原來jdk5.0在linux下和以前的版本還不一樣,默認不支援中文字體的。得手動去搞一個fontconfig配置, 此文件在$JAVA_HOME/jre/lib/下, 果然有一大堆fontconfig.XX.properties, 官方的解釋在這裡, 懶得看那麼多,直接搞一個自己的,先從windows上拷貝simsun.ttc到lib下面的fonts目錄下
然後自己編一個簡單的
# @(#)linux.fontconfig.SuSE.properties 1.2 03/10/17
#
# Copyright 2003 Sun Microsystems, Inc. All rights reserved.
#
# Version
version=1
# Component Font Mappings
serif.plain.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
serif.bold.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
serif.italic.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
serif.bolditalic.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
sansserif.plain.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
sansserif.bold.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
sansserif.italic.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
sansserif.bolditalic.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
monospaced.plain.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
monospaced.bold.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
monospaced.italic.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
monospaced.bolditalic.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
dialog.plain.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
dialog.bold.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
dialog.italic.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
dialog.bolditalic.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
dialoginput.plain.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
dialoginput.bold.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
dialoginput.italic.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
dialoginput.bolditalic.zh-1=Simsun GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
# Search Sequences
sequence.allfonts=zh-1
# Exclusion Ranges
# Font File Names
取名為fontconfig.RedHat.properties 中間的名字是作業系統名,如Redhat系統的就保存為fontconfig.RedHat.properties,WindowsXP的就保存為fontconfig.XP.properties,以此類推。
重新啟動java, 搞定
教訓
不要輕易使用不熟悉的第三方庫
遇到問題,不要專牛角尖,適當的時候放一放
google不好用的時候不要調試第三方庫
http://big5.ccidnet.com:89/gate/big5/java.ccidnet.com/art/297/20060319/483191_1.html
