Home About Contact
FOP , Ubuntu , XML

Apache FOP で日本語フォントを使用した fo を pdf に変換する

fop コマンドが既にあるとして、fo から pdf への変換は、 fop src.fo result.pdf するだけの話。 詳細は このページ を参照のこと。
しかし日本語文字列を含んだ fo を処理すると、日本語部分が意図通りには出力されない。 これを解消してみます。

こんにちは世界

なお、OS は Ubuntu 20.04, fop のバージョンは 2.6 で試しています。

一番簡単な fo を準備

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
  <fo:simple-page-master margin="0cm" page-width="40mm" page-height="15mm" master-name="rectangle">
    <fo:region-body/>
  </fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="rectangle">
  <fo:flow flow-name="xsl-region-body">
    <fo:block-container width="40mm" height="15mm" left="0mm" top="0mm" position="absolute" border="none" background-color="#FDF6E3" font-size="14pt">
      <fo:block>Hello, World!</fo:block>
    </fo:block-container>
  </fo:flow>
</fo:page-sequence>
</fo:root>

変換:

$ fop src.fo result.pdf

結果:

Hello, World!

日本語文字列に変更する

今度は <fo:block>Hello, World!</fo:block><fo:block>こんにちは世界!</fo:block> に変更して実行する。

結果:

こんにちは世界

日本語文字が # に置き換わってしまっています。

日本語フォントを明示的に指定

fop で変換したときにコンソールに以下のようなメッセージが出ていました。

Jun 28, 2021 7:49:50 AM org.apache.fop.events.LoggingEventListener processEvent
WARNING: Glyph "こ" (0x3053, kohiragana) not available in font "Helvetica".

自動判定でフォントは Helvetica を使うことになっていて、Helvetica にはそのグリフはない、ということのようです。 問題を解消するには、該当部分に日本語フォントを明示的に指定すればよさそうです。

日本語フォント設定に入る前に、環境に日本語フォントが存在している必要があります。 そこで IPA フォントをインストールします。

$ sudo apt install fonts-ipafont

その後、fc-list で確認:

$ fc-list |grep japanese
/usr/share/fonts/truetype/fonts-japanese-mincho.ttf: IPAMincho,IPA明朝:style=Regular
/usr/share/fonts/truetype/fonts-japanese-gothic.ttf: IPAGothic,IPAゴシック:style=Regular

フォントが配置されたパスとフォント名が得られました。

これを 自前の fop.xconf に設定します。

デフォルトの fop.xconf は fop がインストールされたディレクトリの conf/fop.xconf あたりにあります。それをコピーして使います。

設定すべきは fonts セクションです。

<fonts>
  <font kerning="yes" embed-url="file:///usr/share/fonts/truetype/fonts-japanese-gothic.ttf">
    <font-triplet name="IPAGothic" style="normal" weight="normal"/>
  </font>
  <!--<auto-detect/>-->
</fonts>

元からある <auto-detect/> は無効にしておきましょう。

あとは、fo の修正です。日本語文字列を記述した fo:block 要素の属性に IPAGothic を指定。

<fo:block font-family="IPAGothic">こんにちは世界!</fo:block>

これで変換します。この時、デフォルトの fop.xconf ではなく、フォント部分をカスタマイズした自前の fop.xconf を明示的に指すのをお忘れなく。

fop src.fo result.pdf -c ./fop.xconf

結果:

こんにちは世界

やったできました。意外に簡単です。

それでは、ゴシックと明朝の両方を使えるようにしてみましょう。 fop.xconf の fonts セクションに IPAMincho を指定した font 要素を追記:

<fonts>
  <font kerning="yes" embed-url="file:///usr/share/fonts/truetype/fonts-japanese-mincho.ttf">
    <font-triplet name="IPAMincho" style="normal" weight="normal"/>
  </font>
  <font kerning="yes" embed-url="file:///usr/share/fonts/truetype/fonts-japanese-gothic.ttf">
    <font-triplet name="IPAGothic" style="normal" weight="normal"/>
  </font>
  <!--<auto-detect/>-->
</fonts>

fo ファイルにも mincho を指定した fo:block 要素を追記:

<fo:block font-family="IPAGothic">こんにちは世界!</fo:block>
<fo:block font-family="IPAMincho">こんにちは世界!</fo:block>

fop src.fo result.pdf -c fop.xconf した結果:

こんにちは世界

完成した src.fo

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
  <fo:simple-page-master margin="0cm" page-width="40mm" page-height="15mm" master-name="rectangle">
    <fo:region-body/>
  </fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="rectangle">
  <fo:flow flow-name="xsl-region-body">
    <fo:block-container width="40mm" height="15mm" left="0mm" top="0mm" position="absolute" border="none" background-color="#FDF6E3" font-size="14pt">
      <fo:block font-family="IPAGothic">こんにちは世界!</fo:block>
      <fo:block font-family="IPAMincho">こんにちは世界!</fo:block>
    </fo:block-container>
  </fo:flow>
</fo:page-sequence>
</fo:root>

まとめ

日本語 TrueType フォントを用意すれば、思ったより簡単に日本語対応できました。 もちろん、fo:block に都度フォントファミリー設定するとかでなく、デフォルトのフォント指定はどうやるのか?とか まだ課題はありますが、とりあえず今日はこれまで。