2012-10-09 29 views
2

客戶端打印標籤並使用一組符號(?)字體來執行此操作。該應用程序使用單字節數據庫(Oracle with Latin-1)。我正在替換的舊應用程序不支持Unicode。它以某種方式確定。我正在編寫的替換應用程序應該處理舊數據。如何根據使用的字體將代碼點映射到unicode字符?

從charmap應用程序中挑選的符號通常映射到特定的Unicode字符,但有時它們不會。例如,使用LAB3字體的月亮看起來像U + 2014(EM DASH)。當用戶將此字符粘貼到Swing文本字段中時,該字符的代碼點爲8212. 它被「移動」到專用區(由Windows?Java?提供)。 當把這個字符保存到數據庫時,Oracle決定它不能被安全地編碼並用可怕的¿代替它。因此,我開始將字符移動8000: - = 8000,當顯示字段時+ = 8000。不幸的是我發現其他角色沒有相同的數量。例如,在一個特定的字體中,ž的代碼點爲382,所以我將它移動了+/- 256以「固定」它。

現在我害怕發現更奇怪的偏移量,我想知道:我可以使用Java獲得此映射嗎?也許TTF字體有一個它編碼的255個字形的列表,以及那些對應的Unicode字符,我可以做到「正確」?

現在,我使用下面的雜牌組裝電腦:

static String fromDatabase(String str, String fontFamily) { 

    if (str != null && fontFamily != null) { 
    Font font = new Font(fontFamily, Font.PLAIN, 1); 

    boolean changed = false; 
    char[] chars = str.toCharArray(); 
    for (int i = 0; i < chars.length; i++) { 
     if (font.canDisplay(chars[i] + 0xF000)) { 
     // WE8MSWIN1252 + WinXP 
     chars[i] += 0xF000; 
     changed = true; 
     } 
     else if (chars[i] >= 128 && font.canDisplay(chars[i] + 8000)) { 
     // WE8ISO8859P1 + WinXP 
     chars[i] += 8000; 
     changed = true; 
     } 
     else if (font.canDisplay(chars[i] + 256)) { 
     // ž in LAB1 Eastern = 382 
     chars[i] += 256; 
     changed = true; 
     } 
    } 
    if (changed) str = new String(chars); 
    } 
    return str; 
} 

static String toDatabase(String str, String fontFamily) { 

    if (str != null && fontFamily != null) { 
    boolean changed = false; 
    char[] chars = str.toCharArray(); 
    for (int i = 0; i < chars.length; i++) { 
     int chr = chars[i]; 
     if (chars[i] > 0xF000) { 
     // WE8MSWIN1252 + WinXP 
     chars[i] -= 0xF000; 
     changed = true; 
     } 
     else if (chars[i] > 8000) { 
     // WE8ISO8859P1 + WinXP 
     chars[i] = (char) (chars[i] - 8000); 
     changed = true; 
     } 
     else if (chars[i] > 256) { 
     // ž in LAB1 Eastern = 382 
     chars[i] = (char) (chars[i] - 256); 
     changed = true; 
     } 
    } 
    if (changed) return new String(chars); 
    } 

    return str; 
} 
+0

你使用的是什麼確切的字體,它是默認的Windows或其他常用的東西? 'U + 2014 = 8212'因爲'2014'是十六進制的,代碼點沒有移動。 –

+0

這些字體似乎是爲客戶定製設計的,並且具有「LAB1 Western」,「LAB2 Cyrillic」和「LAB3 Baltish」等名稱。 –

+0

我將編輯問題並刪除有關「正在移動」的部分 - 我將其混淆兩個問題(當我的數據庫使用WE8MSWIN1252而不是WE8ISO8859P1時,我有0XF000範圍內的字符,在代碼中仍然可以看到其餘部分)。 –

回答

0

只是提供封閉,這裏就是似乎工作:

static String fromDatabase(String str, String fontFamily) { 
    if (str != null && fontFamily != null) { 
    try { 
     byte[] bytes = str.getBytes("ISO-8859-1"); // database encoding 
     if (fontFamily.startsWith("LAB")) { 
     str = new String(bytes, "Windows-1252"); 
     } 
    } 
    catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } 
    } 
    return str; 
} 

static String toDatabase(String str, String fontFamily) { 
    if (str != null && fontFamily != null) { 
    try { 
     if (fontFamily.startsWith("LAB")) { 
     str = new String(str.getBytes("Windows-1252"), "ISO-8859-1"); 
     } 
    } 
    catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } 
    } 
    return str; 
} 

public void exportFormData(EigentumsbezeichnungInformationFormData formData) throws ProcessingException { 
    super.exportFormData(formData); 
    formData.getWert().setValue(toDatabase(formData.getWert().getValue(), formData.getSchrift().getValue())); 
} 

public void importFormData(EigentumsbezeichnungInformationFormData formData) throws ProcessingException { 
    super.importFormData(formData); 
    getWertField().setValue(fromDatabase(formData.getWert().getValue(), formData.getSchrift().getValue())); 
} 

這裏是我的解釋:該數據庫採用ISO 8859-1(也稱爲拉丁1)。十年前,客戶委託了一些特意字體,故意說它們是拉丁語-1編碼,但實際上它們表現出不同的字符。注意這個例子中的歐米茄如何代替Ù!

charmap screenshot to illustrate the mapping

此外,一些未使用的Latin-1的字符也可使用。最簡單的解決方案似乎認爲正在使用相應的Windows代碼頁。這允許Java將來自數據庫「假Windows-1252」的字節轉碼爲Unicode並返回。翻譯後,Swing應用程序將使用顯示歐米茄字形的字體顯示Ù。問題解決了。」

3

字體文件肯定有從Unicode到字形的映射。不幸的是,這個雕文完全是任意的,並且不需要和它所映射的角色有任何關係,就像你在月亮/魔法破折號中找到的那樣。從單字節字符到Unicode碼位的映射大概可以在Windows Code Page 1252中找到,但這不是您想要的 - 您希望字符0x97等於月亮字形,如☽ FIRST QUARTER MOON U+263D而不是— EM DASH U+2014。不幸的是我不能建議任何東西,除了去字體中的每個字符,並將其與可用的Unicode字符進行比較。

+0

我最終強行使用Windows 1252進行錯誤編碼,並且客戶端稍後驗證了每個字形。客戶還發現那些不起作用的字形也不適用於舊的應用程序,所以就我而言,解決了這個問題。 –

相關問題