torutkのブログ

ソフトウェア・エンジニアのブログ

Windows/JDK6のデフォルトフォントの変更と、論理フォントに対応する物理フォントをプログラム上で取得

JDK6 u26がこの6月にリリースされており、本日u25をアンインストールしu26をインストールしました。

Windows版JDK6は、デフォルトで論理フォントにMS ゴシックMS 明朝を使用する設定となっています。この設定(のソース)は以下ファイルです。

  • \jre\lib\fontconfig.properties.src

例えば、論理フォントSerifに対応する英字・日本語フォントの記述を抜粋すると、以下です。(bold, italicの指定は省略)

serif.plain.alphabetic=Times New Roman
serif.plain.japanese=MS Mincho

論理フォントSerifが指定されたとき、日本語ロケールでの優先度は

sequence.serif.windows-31j=alphabetic,japanese,dingbats,symbol

とalphabeticが優先となっています。この場合、英文字はTimes New Romanが使われ、日本語文字はMS Mincho(MS 明朝)が使われます。名前の指定は、実際のフォント名と空白を含めて一致している必要があります。

さらに、フォントファイル名の指定も行っています。

filename.Times_New_Roman=TIMES.TTF
filename.MS_Mincho=MSMINCHO.TTC

フォント名Time New Romanに対してTIMES.TTFフォントファイルが、MS Minchoに対してMSMINCHO.TTCが使われています。フォント名のうち、空白文字がここではアンダースコアに置き換わっています。現在のJavaの実装の制約で、フォント名にアンダースコアが入っていると困ったことになります。

ここで指定されているMSフォントは、ビットマップフォントを組み込んだアウトライン(TrueType)フォントで、ふつうに使うサイズ(12ポイントや14ポイントあたり)の表示ではビットマップが使われます。ビットマップはClearTypeアンチエイリアス)されないので、「ぎざぎざ」します。

そこで、fontconfig.properties.srcをもとに、日本語で使用するフォントをMS ゴシックMS 明朝ではなく、どのサイズでもアンチエイリアスされるフォント(メイリオ等)に置き換えると、論理フォントを変えることができます。置き換えたファイルは、fontconfig.propertiesの名前にしておくと、バイナリ化せず、かつすでにあるフォント設定ファイルより優先されます。

fontconfig.properties記述サンプル

ゴシック系フォントにMeiryo UI、明朝系フォントにIPAex明朝、等幅英字フォントにConsolasを使う場合のfontconfig.propertiesの記述(JDK6u26標準添付のfontconfig.properties.srcとのdiff)を以下に示します。

$ diff -u fontconfig.properties.src fontconfig.properties
--- fontconfig.properties.src   2011-06-27 21:54:15.365398300 +0900
+++ fontconfig.properties       2011-06-27 23:09:00.755992900 +0900
@@ -25,140 +25,140 @@
 serif.plain.chinese-ms950=MingLiU
 serif.plain.chinese-ms950-extb=MingLiU-ExtB
 serif.plain.hebrew=David
-serif.plain.japanese=MS Mincho
+serif.plain.japanese=IPAexMincho
 serif.plain.korean=Batang
 
 serif.bold.alphabetic=Times New Roman Bold
 serif.bold.chinese-ms950=PMingLiU
 serif.bold.chinese-ms950-extb=PMingLiU-ExtB
 serif.bold.hebrew=David Bold
-serif.bold.japanese=MS Mincho
+serif.bold.japanese=IPAexMincho
 serif.bold.korean=Batang
 
 serif.italic.alphabetic=Times New Roman Italic
 serif.italic.chinese-ms950=PMingLiU
 serif.italic.chinese-ms950-extb=PMingLiU-ExtB
 serif.italic.hebrew=David
-serif.italic.japanese=MS Mincho
+serif.italic.japanese=IPAexMincho
 serif.italic.korean=Batang
 
 serif.bolditalic.alphabetic=Times New Roman Bold Italic
 serif.bolditalic.chinese-ms950=PMingLiU
 serif.bolditalic.chinese-ms950-extb=PMingLiU-ExtB
 serif.bolditalic.hebrew=David Bold
-serif.bolditalic.japanese=MS Mincho
+serif.bolditalic.japanese=IPAexMincho
 serif.bolditalic.korean=Batang
 
 sansserif.plain.alphabetic=Arial
 sansserif.plain.chinese-ms950=MingLiU
 sansserif.plain.chinese-ms950-extb=MingLiU-ExtB
 sansserif.plain.hebrew=David
-sansserif.plain.japanese=MS Gothic
+sansserif.plain.japanese=Meiryo UI
 sansserif.plain.korean=Gulim
 
 sansserif.bold.alphabetic=Arial Bold
 sansserif.bold.chinese-ms950=PMingLiU
 sansserif.bold.chinese-ms950-extb=PMingLiU-ExtB
 sansserif.bold.hebrew=David Bold
-sansserif.bold.japanese=MS Gothic
+sansserif.bold.japanese=Meiryo UI
 sansserif.bold.korean=Gulim
 
 sansserif.italic.alphabetic=Arial Italic
 sansserif.italic.chinese-ms950=PMingLiU
 sansserif.italic.chinese-ms950-extb=PMingLiU-ExtB
 sansserif.italic.hebrew=David
-sansserif.italic.japanese=MS Gothic
+sansserif.italic.japanese=Meiryo UI
 sansserif.italic.korean=Gulim
 
 sansserif.bolditalic.alphabetic=Arial Bold Italic
 sansserif.bolditalic.chinese-ms950=PMingLiU
 sansserif.bolditalic.chinese-ms950-extb=PMingLiU-ExtB
 sansserif.bolditalic.hebrew=David Bold
-sansserif.bolditalic.japanese=MS Gothic
+sansserif.bolditalic.japanese=Meiryo UI
 sansserif.bolditalic.korean=Gulim
 
-monospaced.plain.alphabetic=Courier New
+monospaced.plain.alphabetic=Consolas
 monospaced.plain.chinese-ms950=MingLiU
 monospaced.plain.chinese-ms950-extb=MingLiU-ExtB
 monospaced.plain.hebrew=David
-monospaced.plain.japanese=MS Gothic
+monospaced.plain.japanese=Meiryo UI
 monospaced.plain.korean=GulimChe
 
-monospaced.bold.alphabetic=Courier New Bold
+monospaced.bold.alphabetic=Consolas Bold
 monospaced.bold.chinese-ms950=PMingLiU
 monospaced.bold.chinese-ms950-extb=PMingLiU-ExtB
 monospaced.bold.hebrew=David Bold
-monospaced.bold.japanese=MS Gothic
+monospaced.bold.japanese=Meiryo UI
 monospaced.bold.korean=GulimChe
 
-monospaced.italic.alphabetic=Courier New Italic
+monospaced.italic.alphabetic=Consolas Italic
 monospaced.italic.chinese-ms950=PMingLiU
 monospaced.italic.chinese-ms950-extb=PMingLiU-ExtB
 monospaced.italic.hebrew=David
-monospaced.italic.japanese=MS Gothic
+monospaced.italic.japanese=Meiryo UI
 monospaced.italic.korean=GulimChe
 
-monospaced.bolditalic.alphabetic=Courier New Bold Italic
+monospaced.bolditalic.alphabetic=Consolas Bold Italic
 monospaced.bolditalic.chinese-ms950=PMingLiU
 monospaced.bolditalic.chinese-ms950-extb=PMingLiU-ExtB
 monospaced.bolditalic.hebrew=David Bold
-monospaced.bolditalic.japanese=MS Gothic
+monospaced.bolditalic.japanese=Meiryo UI
 monospaced.bolditalic.korean=GulimChe
 
 dialog.plain.alphabetic=Arial
 dialog.plain.chinese-ms950=MingLiU
 dialog.plain.chinese-ms950-extb=MingLiU-ExtB
 dialog.plain.hebrew=David
-dialog.plain.japanese=MS Gothic
+dialog.plain.japanese=Meiryo UI
 dialog.plain.korean=Gulim
 
 dialog.bold.alphabetic=Arial Bold
 dialog.bold.chinese-ms950=PMingLiU
 dialog.bold.chinese-ms950-extb=PMingLiU-ExtB
 dialog.bold.hebrew=David Bold
-dialog.bold.japanese=MS Gothic
+dialog.bold.japanese=Meiryo UI
 dialog.bold.korean=Gulim
 
 dialog.italic.alphabetic=Arial Italic
 dialog.italic.chinese-ms950=PMingLiU
 dialog.italic.chinese-ms950-extb=PMingLiU-ExtB
 dialog.italic.hebrew=David
-dialog.italic.japanese=MS Gothic
+dialog.italic.japanese=Meiryo UI
 dialog.italic.korean=Gulim
 
 dialog.bolditalic.alphabetic=Arial Bold Italic
 dialog.bolditalic.chinese-ms950=PMingLiU
 dialog.bolditalic.chinese-ms950-extb=PMingLiU-ExtB
 dialog.bolditalic.hebrew=David Bold
-dialog.bolditalic.japanese=MS Gothic
+dialog.bolditalic.japanese=Meiryo UI
 dialog.bolditalic.korean=Gulim
 
-dialoginput.plain.alphabetic=Courier New
+dialoginput.plain.alphabetic=Consolas
 dialoginput.plain.chinese-ms950=MingLiU
 dialoginput.plain.chinese-ms950-extb=MingLiU-ExtB
 dialoginput.plain.hebrew=David
-dialoginput.plain.japanese=MS Gothic
+dialoginput.plain.japanese=Meiryo UI
 dialoginput.plain.korean=Gulim
 
-dialoginput.bold.alphabetic=Courier New Bold
+dialoginput.bold.alphabetic=Consolas Bold
 dialoginput.bold.chinese-ms950=PMingLiU
 dialoginput.bold.chinese-ms950-extb=PMingLiU-ExtB
 dialoginput.bold.hebrew=David Bold
-dialoginput.bold.japanese=MS Gothic
+dialoginput.bold.japanese=Meiryo UI
 dialoginput.bold.korean=Gulim
 
-dialoginput.italic.alphabetic=Courier New Italic
+dialoginput.italic.alphabetic=Consolas Italic
 dialoginput.italic.chinese-ms950=PMingLiU
 dialoginput.italic.chinese-ms950-extb=PMingLiU-ExtB
 dialoginput.italic.hebrew=David
-dialoginput.italic.japanese=MS Gothic
+dialoginput.italic.japanese=Meiryo UI
 dialoginput.italic.korean=Gulim
 
-dialoginput.bolditalic.alphabetic=Courier New Bold Italic
+dialoginput.bolditalic.alphabetic=Consolas Bold Italic
 dialoginput.bolditalic.chinese-ms950=PMingLiU
 dialoginput.bolditalic.chinese-ms950-extb=PMingLiU-ExtB
 dialoginput.bolditalic.hebrew=David Bold
-dialoginput.bolditalic.japanese=MS Gothic
+dialoginput.bolditalic.japanese=Meiryo UI
 dialoginput.bolditalic.korean=Gulim
 
 # Search Sequences
@@ -202,7 +202,7 @@
 
 sequence.serif.windows-31j=alphabetic,japanese,dingbats,symbol
 sequence.sansserif.windows-31j=alphabetic,japanese,dingbats,symbol
-sequence.monospaced.windows-31j=japanese,alphabetic,dingbats,symbol
+sequence.monospaced.windows-31j=alphabetic,japanese,dingbats,symbol
 sequence.dialog.windows-31j=alphabetic,japanese,dingbats,symbol
 sequence.dialoginput.windows-31j=alphabetic,japanese,dingbats,symbol
 
@@ -243,6 +243,11 @@
 filename.Courier_New_Italic=COURI.TTF
 filename.Courier_New_Bold_Italic=COURBI.TTF
 
+filename.Consolas=CONSOLA.TTF
+filename.Consolas_Bold=CONSOLAB.TTF
+filename.Consolas_Italic=CONSOLAI.TTF
+filename.Consolas_Bold_Italic=CONSOLAZ.TTF
+
 filename.Times_New_Roman=TIMES.TTF
 filename.Times_New_Roman_Bold=TIMESBD.TTF
 filename.Times_New_Roman_Italic=TIMESI.TTF
@@ -266,6 +271,12 @@
 filename.MS_Gothic=MSGOTHIC.TTC
 filename.MS_PGothic=MSGOTHIC.TTC
 
+filename.IPAexMincho=IPAEXM.TTF
+filename.Meiryo_UI=MEIRYO.TTC
+filename.Meiryo_UI_Bold=MEIRYOB.TTC
+filename.Meiryo_UI_Italic=MEIRYO.TTC
+filename.Meiryo_UI_Bold_Italic=MEIRYOB.TTC
+
 filename.Gulim=gulim.TTC
 filename.Batang=batang.TTC
 filename.GulimChe=gulim.TTC

論理フォントが対応する物理フォントを調べる

先のfontconfig.propertiesを最初に記述したとき、スペルミスがあり、意図したフォントが使われませんでした。
そこで、JavaVMがこのプロパティファイルの設定をもとに、どう論理フォントから物理フォントを割り当てているかを調べる方法を探してみました。

にサンプルコード(断片)がありました。
FontManagerは、JDK6のJavadocに存在せず、調べてみると、sun.font.FontManager ということが分かりました。
JDKの特定の実装系依存ですが、論理フォントから物理フォントを調べる手段がありました。

import sun.font.FontManager;
import sun.font.CompositeFont;
import sun.font.Font2D;
import sun.font.PhysicalFont;
import java.util.Locale;

   :(略)

  Font2D[] fonts = FontManager.getRegisteredFonts();
  for (Font2D font : fonts) {
      if (font instanceof CompositeFont) {
          PhysicalFont physical = ((CompositeFont)font).getSlotFont(1); // 0の場合英字フォントが返る
          System.out.println("論理フォント:" + font.getFontName(Locale.JAPANESE) + 
                             ", 物理フォント:" + physical.getFamilyName(Locale.JAPANESE));
      }
 } 

FontManager.getRegisteredFonts()で取得できるのは、すべてのフォント(論理、物理)です。論理フォントは、CompositeFontになります。