目的
- ソースコードの文字を座標を指定して描画する
- それぞれの文字がどの座標に存在するかを確認できるようにする
利用するツール
- iText : JavaでPDFファイルを出力するライブラリ
- PDFBox : PDF文書から文字とその文字のページ上の出現位置を取り出すために利用
手順
- iTextのインストールと利用方法の確認
- PDFBoxのインストールと利用方法の確認
- ソースコードの提示方法の設定
- 1件のコードにたいして実装
- N件のコード用に処理を自動化
1. iTextのインストール
Gradleで依存関係を処理する
- ここでGradleの書き方を調べる:https://mvnrepository.com/
- 作成したGradle projectの依存関係に以下を追加
// https://mvnrepository.com/artifact/com.itextpdf/itextpdf
compile group: 'com.itextpdf', name: 'itextpdf', version: '5.0.6'
Error 1
Exception in thread "main" com.itextpdf.text.DocumentException: Font 'KozMinPro-Regular' with 'UniJIS-UCS2-H' is not recognized.
at com.itextpdf.text.pdf.BaseFont.createFont(BaseFont.java:699)
at com.itextpdf.text.pdf.BaseFont.createFont(BaseFont.java:606)
at com.itextpdf.text.pdf.BaseFont.createFont(BaseFont.java:441)
at iText.IndexAction.createPdf(IndexAction.java:29)
at iText.Main.main(Main.java:12)
- 原因 : 'KozMinPro-Regular'が認識できていないこと
- 解決法 : 使用するFontを以下のように変更
BaseFont bf1 = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);
iTextのページサイズの指定は"pt"を利用する
- 1mm = 2.83pt
- 1pt = 0.35mm
- したがって,横幅を350mmにしたければ, 350[mm] * 2.83[pt/mm] = 992.1275 に設定
// define page size as 35x25cm
// iText use "pt" thus we need to transform "mm" to "pt"
// with multiplying "2.83465"
float PAGESIZE_X = (float) (350 * 2.83465);
float PAGESIZE_Y = (float) (250 * 2.83465);
2. PDFBoxのインストールと利用方法の確認
Gradleで依存関係を処理する
- 作成したGradle projectの依存関係に以下を追加
- 参考にしている記事と同じv1.8.0を利用する
// https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox
compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '1.8.0'
PDFのテキストの座標を取得する
- テキスト抽出にはPDFBoxのExtractTextを利用する
- ExtractTextクラスではpdfbox.util.PDFTextStripperを呼び出して,実際にPDF文書からテキストを取り出している.したがって,PDFTextStripperのサブクラスを作成し、processTextPositionメソッドをoverrideすることで追加情報(文字列の座標)を取得する.
- 参考:PDF文書から文字とその文字のページ上の出現位置を取り出す (http://www.my-notebook.net/8fd35020-e079-4856-b9bd-d4d5af86d885.html)
@Override
protected void processTextPosition(TextPosition text) {
StringBuffer sb = new StringBuffer();
super.processTextPosition(text);
sb.append(text.getCharacter()).append(",");
// sb.append("pageIndex=" + pageIndex).append(",");
sb.append("x=" + text.getX()).append(",");
sb.append("y=" + text.getY()).append(",");
sb.append("width=" + text.getWidth()).append(",");
sb.append("height=" + text.getHeight());
printWriter.println(sb.toString());
}
3. ソースコードの提示形式の設定
提示形式は以下のとおり
- 描画領域のサイズ:35x25 cm
- 文字色:白
- 文字サイズ:0.8x0.8 cm
- 行間 : デフォルト
- 背景色 : マイルドな黒 #7f7f7f
4. 1件のコードにたいして実装
- ERROR : tab文字を読み込まない
- 対処 : tabを空白に変換する
ソースコードの行数に応じて上下のマージンを調整する
コードブロックはParagraphとして格納している
BaseFontを使って文字のAscent, Decentを計算できる
以下のコードによってフォントのHeightを計算できる.
ascentは正の値,descentは負の値で返されるので,両者の差を取るとフォントのHeightになる.
float ascent = bf.getAscentPoint(text, FONTSIZE);
float descent = bf.getDescentPoint(text, FONTSIZE);
float height = ascent - descent;
- 参考:"How to calculate the height of an element?" http://developers.itextpdf.com/ja/node/3132
PsychoPyで利用するためにPDFをJPEG画像化する
その他
Eclipseのformatterをgoogle style guideに変更
1行の折り返し文字数が気に入らないので,google のものに変更
手順
- google style guideのrepositoryをcloneしてくる(https://github.com/google/styleguide)
- Eclipseの環境設定で"formatter"と検索して出てきた窓からcloneしたファイルをインポート
- 参考:http://sgrit.hatenablog.com/entry/2014/11/24/015715
EclipseのKeybindをEmacsに変更
空白文字列のCheckにはApache Commons LangのStringUtilsクラスが便利。
- 参考:http://arison.jp/blog/2013/02/06/java-stringutils-null-space-check/
- 以下をGradle buildに追加して利用する
// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.0'
参考文献
- JavaでPDFファイルを出力する(iTextライブラリ)【準備編】(http://d.hatena.ne.jp/MoonMtLab/20130913/1379021689)
- JavaでPDFファイルを出力する(iTextライブラリ)【出力編】(http://d.hatena.ne.jp/MoonMtLab/20130914/1379114572)
- PDFBox ( https://pdfbox.apache.org/ )
- PDF文書から文字とその文字のページ上の出現位置を取り出す (http://www.my-notebook.net/8fd35020-e079-4856-b9bd-d4d5af86d885.html)