役に立ちそうもないTips移転版

俺得なTipsを書き連ねるだけのブログ。

JasperReportsと日本語フォント

というと「はいはいiTextAsian.jar足してPDFFontName」ってな手あかのついたネタだが、
iReportとか使ってみると分かるように「fontタグのPDF関連属性はオワコン(deprecated)、Font extensionを使え」ってのが公式の言い分らしく。
ぐぐってみても「PDFのフォント指定がうまくいかないよ?」って質問には「PDFFontNameとか使うなFont extension使え」とばっさりな回答がついてることがしばしば。
……よろしいならばFont extensionだ、でどーすればいいのさと試行錯誤してみた結果。
※注:この記事を書いた時点では「どうしてこれでうまくいくのか」よく分かってないので、もしぐぐってここを見つけた方がおられましたらその点ご注意を。

環境: JasperReportsのバージョンは4.8.0、Javaランタイムは1.7.0_09(x64)、OSはWindows 7 Ultimate SP1 x64。フォントは後述の理由でMS 明朝とか使えなかったのでIPA明朝を使用。
1. まず適当なTrueTypeフォントを用意します。ただし、拡張子がttfであること。(後述の制限のため)
2. フォント設定ファイルを記述。公式サンプルではfonts.xmlとしているが多分ファイル名自体は下記のプロパティファイルの記述と合致してればよいと思われる。

<?xml version="1.0" encoding="UTF-8"?>

<fontFamilies>

	<fontFamily name="適当なフォント名">
		<normal>フォントファイルへのパス。クラスパス配下の相対パスで</normal>
<!--イタリックなフォントファイルとかあったら<italic>タグも書いておくと幸せになれるかも -->
		<pdfEncoding>Identity-H</pdfEncoding> <!-- UniJIS-UCS2-Hではなぜかだめ。後述 -->
		<pdfEmbedded>true</pdfEmbedded>
	</fontFamily>

</fontFamilies>

3. jasperreports_extension.propertiesファイルを(当然クラスパスの通ったところに)用意して、
net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.フォントファミリ名=2.のフォント設定ファイルへのパス(クラスパスからの相対パスであるべき?)
を記述。
4. あとはjrxmlファイルのfontタグで普通に2.のfontFamilyタグのname属性に書いた名前を使うだけ。ここでPDFFontName属性は書かない。

……で、引っかかった点とかいろいろ。
ttcとかotfは使えないっぽい。というのも、SimpleFontFace.getInstance()で「指定名が.ttfで終わっていればファイル名とみなし、そうでなければフォント名とみなしてAWTに照会する」という処理をしてるので。
 (で、msmincho.ttcなんて「名前の」フォントあるかぼけー、とか例外が飛んでくる)
・pdfEncodingはUniJIS-UCS2-Hかと思いきや、こう書くと文字列をバイトエンコーディングするとき、iTextのPdfEncodingsがそのままString#getBytes()にエンコーディング名として渡してくれるのでUnsupportedEncodingExceptionが飛んでくる。一応、Identity-Hで文字化けは起きてないよーだけど……なして?