fo:external-graphic

fo:external-graphicについてちょっと片寄った紹介をします.fo:external-graphicはsrc属性で画像を指定します.画像といってもいろいろあって、PDFに出力するときは閲覧用のPDFだったらJPEGPNG、GIFなどがポピュラーです.PDFでも製本するための版下を作るような場合だと、TIFFやPDFが一般的です.ラスター画像はCMYKフォーマットのTIFFを使い、ベクター画像はPDFを使います.なぜPDFを作るときにPDFなのかというと、PDFには内部に別個のPDFを埋め込める機能があり、これがAdobeの製品のかつてのネイティブフォーマットだったEPSを処理するよりはるかに楽だからです.(今ではイラストレータの保存もPDFが使われていますが...)あとXMLの世界ではそれ自身の中に記述してしまうことも多いのですが、SVGとかMathMLなどもFormatterでは画像として扱えます.

マニュアルなどの技術文書では、イラストレータで機器のイラストを描いたり、PCでの操作画面のハードコピーをとったり、機器を操作する実際の場面を撮影したりと結構苦労して画像を作ります.こうしてマニュアルの中に画像を置いて行くわけですが、お客様のところで組版してみて最後に来るカウンターパンチが「エリアオーバーフロー」です.
画像は始めからページに収まるように作成するわけですが、左インデントがリストなどで深くなるとfo:region-bodyの右側をはみ出してしまうときがあります.こういう場合、また画像を作り直したりと結構大変な作業です.もちろん左インデントに関係なく(左インデント=0で画像を配置するならあまりこういう苦労はないでしょう)
で、この前会社のメーリングリストで、「オーバーフローしたら自動的に縮小できないか?」という話が出ました.考えてみればしごく当たり前の話で、XML⇒XSL-FOは自動組版をうたっているのですからそれくらい簡単にできないと困ります.ところが恥ずかしながら私が作ったスタイルシートではその機能を使っていませんでした.お客様には結構迷惑をかけていた訳です.さてその機能は、fo:external-graphicのcontent-width属性で"scale-down-to-fit"と指定してやることです.元のサイズで収まればそのまま、収まらなければ縮小してくれます.でもそのまま指定しただけでは、うまく「効いて」くれません.以下にfo:block-containerと組み合わせて指定する例を示します.ここで使っている木蓮の花の画像は結構大きくて2048×1536ピクセルあります.これを左インデントを考慮してfo:region-bodyにぴったりに収めます.
 
イメージ 1
 
<fo:list-item space-before="5mm" relative-align="baseline" >
  <fo:list-item-label end-indent="label-end()">
    <fo:block>1.</fo:block>
  </fo:list-item-label>
  <fo:list-item-body start-indent="body-start()" space-before="5mm">
    <fo:block>春の花
      <fo:block>庭に咲いた白木蓮の花です.</fo:block>
      <fo:block-container border="2pt red solid">
        <fo:block text-align="center" start-indent="0mm">
          <fo:external-graphic src="url(hakumokuren.jpg)"
                               content-width="scale-down-to-fit"
                width="100%"/>
        </fo:block>
      </fo:block-container>
    </fo:block>
  </fo:list-item-body>
</fo:list-item>
 
fo:external-graphic自身はインラインオブジェクトです.ですから、ブロックレベルの画像にするためにはそれをfo:blockで囲んでやる必要があります.width="100%"で外側のfo:block-containerいっぱいに画像が広まります.(fo:block-containerがないと悲惨な結果にになります.⇒わかりやすいようにfo:block-containerに赤のボーダーをつけてあります.)そしてcontent-width="scale-down-to-fit"で、収まらないときに縮小することを指定します.画像をかえて、もっと小さい画像にした場合も示します.同じ書き方でこちらもOKです.
 
イメージ 2
 
今度お客様にオーバーフローの頻度を聞いて、この方法を提案してみたいと思います.