SSブログ

iTextを使ってPDF作成 - 振り仮名 - [プログラミング]

(PDFファイルを作成するためのJava用ライブラリ)「iText」を使ってPDFを作っているわけなのですが、漢字に振り仮名(ルビ)を振る機能が無い。

そこで、自分で振り仮名を出力することにします。

って、前回(ページ番号出力)と全く同じ書き出しな訳ですが、実装する内容も前回同様、座標を指定して文字(振り仮名)を出力することになります。

ただ、ページ番号と違って、振り仮名は出力する座標が固定ではないと言う事で…。

ここで、チャンク(本文を幾つかに分けたパーツだと思えばいいのだろうか…)のタグ機能を使うことにします。
Chunk#setGenericTag()に適当な文字列を指定すると、このチャンクを出力した後にPdfWriter#setPageEvent()で指定したハンドラ(PdfPageEvent#onGenericTag)が呼び出されます。チャンクを出力した座標と共に。

これで、振り仮名を出力することが出来ました。

PdfPageEvent#onGenericTagには任意のデータを渡せないので、振り仮名はタグに含めています。

import java.io.*;
import com.lowagie.text.*;
import com.lowagie.text.pdf.*;

public class Sample
{
    // ルビのフォントサイズ
    static private final int RUBY_FONT_SIZE = 6;

    static public void main(String[] args)
    {
        BufferedReader in = null;

        final Document doc = new Document();
        try {
            final PdfWriter writer =
                PdfWriter.getInstance(doc, new FileOutputStream("sample.pdf"));

            doc.open();

            // 本文のフォント
            final Font font = new Font(BaseFont.createFont("HeiseiKakuGo-W5",
                                                           "UniJIS-UCS2-H",
                                                           BaseFont.NOT_EMBEDDED));

            // ルビのフォント
            final BaseFont ruby_font = BaseFont.createFont("HeiseiKakuGo-W5",
                                                           "UniJIS-UCS2-H",
                                                           BaseFont.NOT_EMBEDDED);

           // ----- ここらへんから、ルビ出力のための仕組み

            writer.setPageEvent(new PdfPageEventHelper() {
                // タグの指定があったチャンクを出力した時に呼び出される。
                public void onGenericTag(PdfWriter writer, Document document, Rectangle rect, String text)
                {
                    if (text.startsWith("ruby:")) {
                        text = text.substring(5);
                        if (text.length() == 0)
                            return;

                        final PdfContentByte cb = writer.getDirectContent();
                        cb.saveState();

                        cb.beginText();
                        cb.setFontAndSize(ruby_font, RUBY_FONT_SIZE);

                        // ルビのY座標。元の文字の直ぐ上。
                        final float y = rect.top();

                        // ルビの文字幅
                        final float text_width = ruby_font.getWidthPoint(text, RUBY_FONT_SIZE);
                        // ルビが必要な原文の幅
                        final float area_width = rect.width();
                        if (text.length() > 1 && text_width < area_width) {
                            // 文字の間に余白を入れる
                            cb.setCharacterSpacing((area_width - text_width)/(text.length()));
                        }
                        cb.showTextAligned(PdfContentByte.ALIGN_CENTER,
                                           text,
                                           (rect.right() + rect.left())/2,
                                           y, 0);
                        cb.endText();
                        cb.restoreState();
                    }
                }
            });

            // ----- ここらへんまで、ルビ出力のための仕組み


            Phrase phrase = new Phrase(24, "", font);
            // ルビを出力する為に行間を広げる(24pt)

            phrase.add("あああ");                  // ルビの要らない文字

            Chunk box = new Chunk("いいい");       // ルビを付けたい文字
            box.setGenericTag("ruby:振り仮名");    // ルビ
            phrase.add(box);

            phrase.add("ううう");
        
            add(new Paragraph(phrase));

        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null)
                    in.close();
            } catch (IOException e) {
            }
        }

        doc.close();
    }
}

ぬはーーーーっ!。

振り仮名が付けられる本文の方が途中で改行すると、改行前と改行後の両方に振り仮名が振られる(3行に渡ると3回)。

これに対処するには、iTextに手を入れなければならないと思う。
多分 PdfChunk#split() の辺り。

で、実際にいじってみた。うまく行ったっぽい。

(補足)コレは違う方法で出してますが……。

[船] 今日の一冊
ぶらんでぃっしゅ?

ぶらんでぃっしゅ?

  • 作者: 清涼院 流水
  • 出版社/メーカー: 幻冬舎
  • 発売日: 2005/11
  • メディア: 単行本

タグ:iText Java
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。