--> -->

skimemo


skimemo - 日記/2013-11-04

_ Android PDF Writerが遅い件

PDF Writerを使って開発を進めていたのですが、1ページのオブジェクト量が多くなると、生成に非常に時間がかかる事が分かりました。

改ページすると超速いのですが、オブジェクトを追加していくとどんどん遅くなります。

コードを追ってみると、不要と思われる処理、適切で無いと思われる処理がありましたので修正したところ、20倍ぐらい(体感)速くなりましたのでメモとして上げます。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 
 
 
 
 
 
!
|
-
 
!
|
-
 
!
|
|
|
|
|
|
|
!
|
-
|
!
|
-
|
|
|
|
|
|
|
|
|
-
 
 
 
 
 
 
 
 
 
!
|
-
Index: EnclosedContent.java
===================================================================
--- EnclosedContent.java    (revision 17)
+++ EnclosedContent.java    (working copy)
@@ -48,6 +48,10 @@
         return mContent.toString();
     }
 
+    public int getContentLength() {
+        return mContent.length();
+    }
+
     public void addContent(String Value) {
         mContent.append(Value);
     }
 
Index: IndirectObject.java
===================================================================
--- IndirectObject.java    (revision 17)
+++ IndirectObject.java    (working copy)
@@ -92,10 +92,17 @@
         return mStreamContent.getContent();
     }
     
+    public int getStreamContentLength() {
+        return mStreamContent.getContentLength();
+    }
+    
     protected String render() {
         StringBuilder sb = new StringBuilder();
         sb.append(mID.toPDFString());
 
Index: Page.java
===================================================================
--- Page.java    (revision 21)
+++ Page.java    (working copy)
@@ -97,9 +97,11 @@
     
     private void addContent(String content) {
         mPageContents.addStreamContent(content);
-        String streamContent = mPageContents.getStreamContent();
-        mPageContents.setDictionaryContent("  /Length " + Integer.toString(streamContent.length()) + "\n");
-        mPageContents.setStreamContent(streamContent);
+// 長さを取るためだけにtoString()をすると大量にGCが発生し遅くなる。getStreamContentLengthを新設して代用。
+//        String streamContent = mPageContents.getStreamContent();
+        mPageContents.setDictionaryContent("  /Length " + Integer.toString(mPageContents.getStreamContentLength()) + "\n");
+// 上の行でaddしているので同じものを詰め替える必要なし
+//        mPageContents.setStreamContent(streamContent);
     }
     
     public void addRawContent(String rawContent) {


元凶の1つ目は41行目。この中で長大なStringBuilderをtoString()しており、そのたびに(実際は数回に1度)GCが走ってパフォーマンスが落ちています。
ここで欲しいのは長さだけなので、getStreamContentLength()という関数を作ります。
getStreamContentLength()の中身はその上の9〜11、25〜27行目の通り。

元凶の2つ目は43行目のsetStreamContent()。40行目で作ったStringBuilderを、何故か再度newして作り直しています。というわけでコメントアウト。

なんだかこれで良いのか若干不安ですが、私の利用範囲では動いているのでよしとします。
ご利用はあくまで自己責任で(^^;。

Category: [android] - 16:48:48


_ PDFWriter(apwlibrary)で日本語出力を

androidでPDFファイルを作成するためにぐぐったところ、PDFWriterが良いという事がわかりました。ただ、日本語に対応していません。

とりあえずダウンロードしてソースを確認すると、意外とシンプルです。
サンプルのデモも付いており、動作を確認してみると、テキストが出力されるようになっています。

ん? PDFなのにテキスト?

と思っていろいろ調べてみると、どうやらPDFファイルというのはテキストで記述できることが分かりました。(超わかりやすい参考文献

それらを参考に、日本語フォント指定をできるようにしてみました。
ただし、かなりなんちゃってなので、以下の制限があります。

  • フォントは埋め込まない(方法が分からなかった)
  • フォント幅も結構適当(埋め込まないと等幅になるらしい)
  • エンコードはSJIS(90ms-RKSJ-H)固定(Unicodeにトライしたけど何故かうまくいかなかった)
  • androidの標準(のはずの)Droid Sans Japaneseが指定できない(トライしたけど何故か表示されなかった)

一応以下のフォント指定が可能ですが、PDFファイル内の属性として指定可能なだけで、フォント幅はすべて一定です。

フォント名指定文字列
MSゴシックMS_GOTHIC
MS明朝MS_MINCHO
MSPゴシックMSP_GOTHIC
MSP明朝MSP_MINCHO
メイリオMEIRYO


使用例:

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
-
!
-
!
 
-
!
    // PDF作成(A4ヨコ)
    PDFWriter  mPDFWriter = new PDFWriter(PaperSize.A4_HEIGHT, PaperSize.A4_WIDTH);
    // フォント指定
    mPDFWriter.setFont(JapaneseFonts.MEIRYO);
    mPDFWriter.addTextAsHex(X, Y, fontSize, JapaneseFonts.stringToSjisHex("abcihjk全角もじれつ"));
    // ファイルに出力
            :


出力例:

zenkakumojiretsu.png


_ 必要なもの

  1. apwlibraryをダウンロード
  2. 以下のファイルを追加・置き換える

以上です。フォントファイルを埋め込もうと頑張りましたが挫折しました。PDFのフォーマット難しい・・・。
なお、apwlibraryはBSDライセンスです。(上記ソースもBSDライセンスです)

参考文献:
 手書きPDF入門 - http://www.kobu.com/docs/pdf/pdfxhand.htm
 Portable document format(Adobe) - http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf

Category: [android] - 11:57:23


 
Last-modified: 2013-11-04 (月) 11:57:25 (3825d)