FO.NET


FO.NET という .NET Framework の XSL-FO 処理系があるようです。

サンプルがあるので,まず font-family を日本語対応の TrueType フォントにしてみたらそのフォントでちゃんと表示されました。次に表示文字列を「こんにちは、世界!」に変えて実行してみると,表示がうまくいきません。フォントを変えてみても同じです。どうやら埋め込まれている文字が ANSI のみであることが原因のようです。

Wiki によれば Unicode 文字を埋め込むには PdfRendererOptions.FontTypeEmbed もしくは Subset にしてやれば良いようです。

font-family="MS Pゴシック" 試したところ両方でうまく言ったのですが, font-family="IPA Pゴシック" では Embed はフォント埋め込みに成功して日本語表示ができたのですが, Subset だと以下の例外が出ました。

ハンドルされていない例外: System.SystemException: System.ArgumentException:
Cannot locate table 'cvt'
パラメータ名: tableName
   場所 Fonet.Pdf.Gdi.Font.FontFileReader.GetTable(String tableName)
   場所 Fonet.Pdf.Gdi.Font.FontSubset.Generate(MemoryStream output)
   場所 Fonet.Render.Pdf.Fonts.Type2CIDSubsetFont.get_FontData()
   場所 Fonet.Pdf.PdfFontCreator.CreateCIDFont(String pdfFontID, Font font,
CIDFont cidFont)
   場所 Fonet.Pdf.PdfFontCreator.MakeFont(String pdfFontID, Font font)
   場所 Fonet.Render.Pdf.FontSetup.AddToResources(PdfFontCreator fontCreator,
PdfResources resources)
   場所 Fonet.Render.Pdf.PdfRenderer.StopRenderer()
   場所 Fonet.Fo.FOTreeBuilder.Parse(XmlReader reader)
   場所 Fonet.FonetDriver.FireFonetError(String message)
   場所 Fonet.Fo.FOTreeBuilder.Parse(XmlReader reader)
   場所 Fonet.FonetDriver.Render(XmlReader inputReader, Stream outputStream)
   場所 Test.Main()

フォントのことはよくわからないのですが,当該フォントにこれらのテーブルがないのがエラーの原因のようです。ちなみに font-family="IPA モナー Pゴシック" で試したところ, cvt ではなく fpgm のテーブルで "Cannot locate table" の例外が出ました。

ソースは以下です。

using Fonet;
using Fonet.Render.Pdf;

class Test
{
	static void Main()
	{
		FonetDriver driver = FonetDriver.Make();
		// サンプルに書いてあるが Renderer というプロパティは存在しない
		//driver.Renderer = RendererEngine.PDF;
		PdfRendererOptions options = new PdfRendererOptions();
		//options.FontType = FontType.Embed;
		options.FontType = FontType.Subset;
		driver.Options = options;
		driver.Render("hello.fo", "hello.pdf");
	}
}

FOP より FO.NET の方が簡単で使いやすそうなのですが, IPA フォントを使えないのが残念です。 Apache FOP だと IPA フォントでもサブセット埋め込みができるので,こちらを使うか, IPA フォントをあきらめて MS フォントを用いるかですね。もしくは何か回避方法があるのかもしれません。