クライアントはラベルを印刷し、これを行うために一連の記号 (?) フォントを使用しています。アプリケーションは、シングル バイト データベース (Latin-1 を使用する Oracle) を使用します。私が置き換えようとしている古いアプリケーションは、Unicode に対応していませんでした。なんとかOKになりました。私が書いている代替アプリケーションは、古いデータを処理することになっています。
chammap アプリケーションから選択された記号は、多くの場合、特定の Unicode 文字にマップされますが、マップされない場合もあります。たとえば、LAB3 フォントを使用した月のように見えるものは、実際には U+2014 (EM DASH) です。ユーザーがこの文字を Swing テキスト フィールドに貼り付けると、その文字のコード ポイントは 8212になります。これは、(Windows? Java? によって) Private Use Area に「移動」されました。この文字をデータベースに保存するとき、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;
}