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()
の辺り。
で、実際にいじってみた。うまく行ったっぽい。
(補足)コレは違う方法で出してますが……。
今日の一冊 | |
|
2007-07-21 08:05
nice!(0)
コメント(0)
トラックバック(0)
コメント 0