From Evernote: |
全Linux生活:第7天(2) - EUDC.TTE |
這其實不是我日常生活會遇到的問題,而是工作上的需要,只是剛好也是跟非Windows環境(AIX&Linux)有關的議題。最近我們正在進行的一個提案,需要在AIX與Linux環境下進行"難字"列印,其實說穿了就是所謂的"使用者造字"。目前常見的是使用滿天星公司的字霸系統,我沒去研究字霸有沒有AIX或Linux版,可是這個客戶的字霸是Windows版,我們以前的系統雖然Server端是AIX系統,但至少客戶端都還是Windows,因此難字的顯示與列印全交給Windows與字霸就好了。但這次這個提案的作法從頭到尾都沒有Windows,這時候如果列印資料中有難字該如何列印呢?
我們稍微研究了一下字霸的作法發現一件事,那就是其實字霸採用的是標準Windows使用者造字的模式,也就是它會在Windows掛一個EUDC.TTE的字型檔在系統中:
[HKEY_CURRENT_USER\EUDC\950]
"SystemDefaultEUDCFont"="C:\\WINDOWS\\EUDC.tte"
只是這副檔名有點怪,*.TTE是什麼鬼?這個檔其實是個標準的truetype字型檔,如果把副檔名TTE改成TTF,可以發現Windows是認得這個檔的,檔案點兩下甚至可以開得起來。
所以接下來要做的事就比較簡單了。我們只要把這個檔讀出來,把我們要的字畫出來問題就解決了。講到這裡,我只能說Java真是佛心來的!針對Truetype的處理Java早就內建了,我們只要用就好了,以下是大致的用法:
private Font eudc;
private Font eudc24;
private Font eudc24;
public boolean reloadEudcFont() {
try {
File eudcFile = new File(eudcFontPath);
if (eudcFile.exists()) {
eudc = Font.createFont(Font.TRUETYPE_FONT, eudcFile);
eudc24 = eudc.deriveFont(Font.PLAIN, 24);
return true;
}
eudc = null;
eudc24 = null;
} catch (Throwable t) {
t.printStackTrace();
}
return false;
}
try {
File eudcFile = new File(eudcFontPath);
if (eudcFile.exists()) {
eudc = Font.createFont(Font.TRUETYPE_FONT, eudcFile);
eudc24 = eudc.deriveFont(Font.PLAIN, 24);
return true;
}
eudc = null;
eudc24 = null;
} catch (Throwable t) {
t.printStackTrace();
}
return false;
}
接下來,要抓某個難字的bitmap大致可以這樣做:
public int[] grepUdcImage(int width, int height, char c) {
try {
int w = width;
int h = height;
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
if (regularFont.canDisplay(c))
g.setFont(regularFont);
else
g.setFont(eudc24);
g.setColor(Color.WHITE);
g.drawString("" + c, 0, h - 5);
int[] pixels = new int[w * h];
PixelGrabber pg = new PixelGrabber(image, 0, 0, w, h, pixels, 0, w);
try {
pg.grabPixels();
} catch (InterruptedException e) {
logger.error("Interrupted waiting for pixels!");
}
if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
logger.error("Image fetch aborted or errored!");
}
return pixels;
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
try {
int w = width;
int h = height;
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
if (regularFont.canDisplay(c))
g.setFont(regularFont);
else
g.setFont(eudc24);
g.setColor(Color.WHITE);
g.drawString("" + c, 0, h - 5);
int[] pixels = new int[w * h];
PixelGrabber pg = new PixelGrabber(image, 0, 0, w, h, pixels, 0, w);
try {
pg.grabPixels();
} catch (InterruptedException e) {
logger.error("Interrupted waiting for pixels!");
}
if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
logger.error("Image fetch aborted or errored!");
}
return pixels;
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
要注意一點,這個TTE檔內部的編碼是Unicode,所以要找出我們要的難字,你必須知道那個字的Unicode。因為我們沒有MS950(BIG5)跟Unicode的對照表(這部份其實是字霸另一個主要功能),所以只要先有人幫我們把該轉的碼先轉好,到我們這邊的處理就沒有問題了,關於這點,倒是不用擔心,因為我們要列印的字,在使用者鍵入難字的時候早就把難字轉成Unicode了,畢竟目前使用者日常操作的電腦百分之兩百一定是Windows,如果萬一真的不是Windows,比方說是手機或iPad(或Android),反正它也打不出難字,所以也不用擔心。
No comments:
Post a Comment