製品開発担当の大です。こんにちは。

前回に引き続き、シーオーリポーツ for Java V3の新機能をご紹介します。
今回は、フォントのフォールバック機能です。

フォントのフォールバック機能

フォントのフォールバック機能(クリックで拡大)


V2での動作

V3のフォントのフォールバック機能を説明する前に、V2ではどのような動きでどんな問題があったのかを書きます。

シーオーリポーツドキュメント形式(RSI/RSX/CID)をActiveX版や.NET版のシーオーリポーツビュアーで表示するとき、指定されたフォントにグリフがない場合は、Windowsのフォントフォールバック/フォントリンク機能を使用して表示できるフォントを探し文字を描画します。例をあげましょう:

var rsi = new CrFileOutJob(CorDocumentType.BINARY, "V2_Fonts");
var pdf = new CrFileOutJob(CorDocumentType.PDF, "V2_Fonts");
CrPdfDocument doc = pdf.getDocument();
doc.setEmbeddingFont("Arial", "c:\\Windows\\Fonts\\arial.ttf");
doc.setEmbeddingFont("メイリオ", "c:\\Windows\\Fonts\\meiryo.ttc");

var draw = new CrDraw();
try {
    draw.startJob(rsi, pdf);
    var form = CrForm.open(draw, "Empty.cfx");
    try {

    	var fsize = 423; // 12pt相当(1/100mm単位)
    	var str = "Aアあ가俞";
        var text1 = new CrText(1000, 1000, 15000, 800, "(1) [" + str + "] フォント指定なし");
        text1.setHanFontHeight(fsize);
        text1.setZenFontHeight(fsize);
        form.draw(text1);

        var text2 = new CrText(1000, 2000, 15000, 800, "(2) [" + str + "] Arialを指定");
        text2.setHanFontName("Arial");
        text2.setZenFontName("Arial");
        text2.setHanFontHeight(fsize);
        text2.setZenFontHeight(fsize);
        form.draw(text2);

        var text3 = new CrText(1000, 3000, 15000, 800, "(3) [" + str + "] Arialとメイリオを指定");
        text3.setHanFontName("Arial");
        text3.setZenFontName("メイリオ");
        text3.setHanFontHeight(fsize);
        text3.setZenFontHeight(fsize);
        form.draw(text3);

        form.printOut();
    } finally {
    	form.close();
    }

    draw.endJob();
} catch (Exception ex) {
	draw.abortJob();
	throw ex;

} finally {
    draw.deleteInstance();
}

それぞれのテキストオブジェクトにはテスト用の「Aアあ가俞」という文字列が含まれています。出力したシーオーリポーツドキュメント(RSI)をシーオーリポーツ for Java V2のビュアー(ActiveX版)で表示すると以下のようになります。

V2のRSI

V2のRSI(クリックで拡大)

(1)のテキストオブジェクトには明示的にフォントが指定されていません。この場合、デフォルトのMS 明朝が選択されます。MS 明朝にはアルファベット、半角カナ、ひらがなは含まれていますが、ハングルやCJK統合漢字の「俞」などは含まれていません。この場合、Windowsのフォントリンク機能によりMS 明朝に関連付けられているフォントからグリフを見つけ出し、表示します。

(2)のテキストオブジェクトにはArialが指定されています。Arialは欧文フォントで、半角カナ、ひらがな、ハングル、CJK統合漢字などのグリフは含まれていません。またフォントリンクにもArialの定義はないため、Windowsのフォントフォールバック機能を使用してこれらを表示しています。

(3)のテキストオブジェクトには、半角フォントにArial、全角フォントにメイリオが指定されています。この場合、「A」はArial、「ア」はArialのフォールバックフォント、「あ」はメイリオ、「가」「俞」はメイリオのリンクフォントからそれぞれグリフが選択されます。

では、V2のPDFではどうなっているかというと、

V2のPDF

V2のPDF(クリックで拡大)


(1)はMS 明朝のため、グリフが存在する「A」「ア」「あ」は表示されますが、「가」「俞」はグリフが存在しないため表示されません。

(2)はArialのため、グリフが存在する「A」は表示されますが、「ア」「あ」「가」「俞」はグリフが存在しないため表示されません。

(3)は半角フォントに指定されているArialで「A」は表示されますが「ア」はArialにグリフが存在しないため表示されません。「あ」は全角フォントに指定されているメイリオで表示されますが、「가」「俞」はグリフが存在しないため表示されません。

という動きになっていました。つまり、

・半角フォントに欧文フォントが指定されていると半角カタカナが表示できない
・指定されたフォントにグリフが存在しなければ表示する手段がない

といった問題がありました。

V3のフォントフォールバック機能

これらの問題を解決するため、シーオーリポーツ for Java V3では独自のフォントフォールバック機能を追加しました。これはCSSのフォント指定と似た感じで、複数のフォントを指定でき、指定した順にグリフが検索され見つかったフォントで表示される機能です。サンプルソースは以下のようになります。

var rsi = new CrFileOutJob(CorDocumentType.BINARY, "V3_Fonts");
var pdf = new CrFileOutJob(CorDocumentType.PDF, "V3_Fonts");
CrPdfDocument doc = pdf.getDocument();
doc.setFontSettings("Arial", FontSettings.forEmbed("arial.ttf", CorPdfFontEmbedMode.SUBSET));
doc.setFontSettings("メイリオ", FontSettings.forEmbed("meiryo.ttc", CorPdfFontEmbedMode.SUBSET));
doc.setFontSettings("Malgun Gothic", FontSettings.forEmbed("malgun.ttf", CorPdfFontEmbedMode.SUBSET));
doc.setFontSettings("Microsoft JhengHei", FontSettings.forEmbed("msjh.ttc", CorPdfFontEmbedMode.SUBSET));

var draw = new CrDraw();
try {
    draw.startJob(rsi, pdf);
    try (var form = CrForm.open(draw, "Empty.cfx")) {
        var font1 = new CrText.Font("Arial", 120, CorUnit.POINT10);
        var font2 = new CrText.Font("メイリオ", 120, CorUnit.POINT10);
        var font3 = new CrText.Font("Malgun Gothic", 100, CorUnit.POINT10);
        var font4 = new CrText.Font("Microsoft JhengHei", 120, CorUnit.POINT10);

    	var str = "Aアあ가俞";
        var text1 = new CrText(1000, 1000, 15000, 800, "(1) [" + str + "] フォント指定なし");
        form.draw(text1);

        var text2 = new CrText(1000, 2000, 15000, 800, "(2) [" + str + "] Arialを指定");
        text2.setFont(font1);
        form.draw(text2);

        var text3 = new CrText(1000, 3000, 15000, 800, "(3) [" + str + "] Arialとメイリオを指定");
        text3.setFont(font1, font2);
        form.draw(text3);

        var text4 = new CrText(1000, 4000, 15000, 800, "(4) [" + str + "] ArialとメイリオとMalgun Gothicを指定");
        text4.setFont(font1, font2, font3);
        form.draw(text4);

        var text5 = new CrText(1000, 5000, 15000, 800, "(5) [" + str + "] ArialとメイリオとMalgun GothicとMicrosoft JhengHeiを指定");
        text5.setFont(font1, font2, font3, font4);
        form.draw(text5);

        form.printOut();
    }

    draw.endJob();
} catch (Exception ex) {
	draw.abortJob();
	throw ex;

} finally {
    draw.deleteInstance();
}

このときPDFは以下のような動きになります。

V3のPDF

V3のPDF(クリックで拡大)

(1)、(2)はV2と同じです。

(3)は、Arial→メイリオの順にグリフが検索されます。「A」はArial、「ア」「あ」はメイリオで表示されます。「가」「俞」はグリフが存在しないため表示されません。

(4)は、Arial→メイリオ→Malgun Gothicの順にグリフが検索されます。「A」はArial、「ア」「あ」はメイリオ、「가」はMalgun Gothicで表示されます。「俞」はグリフが存在しないため表示されません。(余談ですが、Malgun Gothicは同じフォントサイズでも少し大きく見えるため、ここでは他のフォントより小さい10ptで指定しています)

(5)は、Arial→メイリオ→Malgun Gothic→Microsoft JhengHeiの順にグリフが検索されます。「A」はArial、「ア」「あ」はメイリオ、「가」はMalgun Gothic、「俞」はMicrosoft JhengHeiで表示されます。

こうしてPDFでもすべての文字を表示できるようになりました!

さて、V3で出力したシーオーリポーツドキュメントはどうなっているでしょうか。シーオーリポーツドキュメントの場合は前述のとおりもともとWindowsの機能を使用してフォントフォールバックを実現しており、互換性のため従来どおりの出力となります。つまり、3つ目以降のフォントの指定は無視されます。シーオーリポーツ for Java V3のビュアー(.NET版)で表示すると以下のようになります。

V3のRSI

V3のRSI(クリックで拡大)

こちらから無料でダウンロードできる体験版でも、この動作を確認できます。ぜひお試しください。