画像をオーバーフローさせずにページに収める.(2)

画像がページの縦方向(ブロックの進行方向)にオーバーフローするのを防止するのにはどうしたら良いのでしょうか?実は横方向(インラインの進行方向)の場合、max-width="100%"としてやればすみました.これは次のようなものになります.つまり左インデントされた位置から目いっぱい取ってくれるのがmax-width="100%"なのです.

イメージ 1


でもこれと同じで縦方向の場合、max-height="100%"としたらどうなってしまうでしょうか?画像が配置されようとする位置から、ページ下部に向かって目いっぱい確保するのはmax-height="100%"になってしまいます.つまり、画像の配置される縦位置で画像の高さはどうにでも変わってしまうのです.

イメージ 2

これは非常にまずいです.私たちが欲しいのはたぶん以下の様なものです.

- 本文領域(fo:region-body)の高さに収まらなければ、その高さまで縮小する.
- そもそも画像の開始の縦位置から入らなければ改ページして本文領域の高さに収める.

本文領域の高さを表すのはビューポート領域の高さになります.それはFormatterの拡張である"vh"(Viewport Height)という表記で表されます.つまり結論から言いますと、次のようなFOで対応可能でした.

<fo:block-container>
  <fo:block start-indent="0mm" line-height="1" font-size="0mm">
     <fo:external-graphic src="url(flower_tate.jpg)"
                          scaling="uniform"
                          content-width="scale-down-to-fit"
                          max-width="100%"
                          content-height="scale-down-to-fit"
                          max-height="100vh"/>
  </fo:block>
</fo:block-container>

ここでfo:external-graphicを囲むfo:blockにline-height="1"、font-size="0mm"とある点に注意が必要です.これがないとまたオーバーフローしてしまうのです.理由は以下の様なものです.

- line-heightは上位から継承されます.フォントサイズが決まっていると、その上下にハーフレディング(half-leading)というアキ領域が取られます.これがオーバーフローの原因となります.line-height="1"とすることで、これを抑制します.
- font-size="0mm"は一般に画像がベースラインの上に乗る形で取られてしまい、フォントサイズのベースラインの下の分がオーバーフローするのを防ぐ目的でこの値を指定します.この仕組みは以下の図を見ていただければご理解いただけるでしょうか?

イメージ 3


という訳で、画像がページの縦方向(ブロックの進行方向)にオーバーフローするのを防止するのは結構ややこしい仕組みが必要でした.私もXSL-FOの勉強になりました.