Ghostscript 9.19 を使用して PDF/A 互換 PDF (1.4) を作成した顧客から入手した PDF に特有の問題があります。LocationTextExtractionStrategy を使用してそこからテキストを抽出したいのですが、ほとんどのテキストを逆の順序で取得し、スペースを追加します。
予想: abc
取得: cba
コンテンツ ストリームでは、これは [a,1,b,1,c] TJ のようになります
この問題は以前に Stackoverflow に投稿されていましたが、独自の抽出戦略をハックするよりもさらに問題を掘り下げました。使用されているフォントのフォント幅がすべてゼロであり、メトリックも hMetrics マップも塗りつぶされていないことに気付きました。iTextSharp 5.5.4 を使用していましたが、5.5.9 にも同じ問題があります。
これはフォントです:
/Subtype /Type0
/BaseFont /VGOQEA+SegoeUI
/Type /Font
/Encoding 33 0 R
/ToUnicode 48 0 R
/DescendantFonts [35 0 R]
オブジェクト 33 は CMap です。
/CIDSystemInfo 32 0 R
/Filter /FlateDecode
/Length 266
/CMapName /OneByteIdentityH
/Type /CMap
オブジェクト48はストリームであり、偶然にもCMapでもあります
オブジェクト 35 には、最終的にいくつかの幅の定義があります
/DW 539
/CIDSystemInfo 32 0 R
/Subtype /CIDFontType2
/BaseFont /VGOQEA+SegoeUI
/FontDescriptor 26 0 R
/Type /Font
/W [0, [646], 32, [274], 40, [302, 302], 44, [217, 400, 217], 48, [539, 539, 539, 539], 53, [539, 539, 539, 539], 58, [217], 64, [955, 645, 573], 68, [701, 506], 72, [710, 266], 75, [580, 471, 898], 80, [560], 82, [598, 531], 85, [687], 87, [934], 90, [570], 97, [509, 588, 462, 589, 523, 313, 589, 566, 242], 107, [497, 242, 861, 566, 586, 588], 114, [348, 424, 339, 566], 119, [723], 122, [452], 220, [687], 228, [509], 246, [586], 252, [566]]
/CIDToGIDMap 47 0 R
iTextSharp が CMapAwareDocumentFont を初期化する順序で、最初にベース DocumentFont が初期化されます。次に、コンストラクターは以下をチェックします。
if (PdfName.TYPE1.Equals(subType) || PdfName.TRUETYPE.Equals(subType))
どちらでもありません。
else if (PdfName.TYPE3.Equals(subType))
そうではありません。次に、次の else ブランチに入ります。
PdfName encodingName = font.GetAsName(PdfName.ENCODING);
if (encodingName == null)
ただし、encoding は間接参照として指定されるため、encodingName は null です。したがって、この Type0 フォントの処理は処理されません。
ライブラリ コードでこのビットを変更しましたが、ProcessType0(font) メソッドが呼び出されても、幅の値がフォント定義に反映されませんでした。つまり、すべてゼロのままでした。これはおそらく予想通りです。最後に、メトリクス ハッシュ マップを埋めましたが、使用されているすべての文字をカバーしていませんでした。つまり、状況は少し良くなりましたが、すべてが良いわけではありません:
代わりに: abc -> cba
私は今得ました: abc -> acb
現在の問題に対する私の唯一の機能するハックな解決策は、 processor.DisplayPdfString((PdfString)entryObj) をハックして、textMatrix を一定量調整することでした。ただし、これは一般的な解決策ではなく、フォントが正しく機能することを望んでいます。私が試すべき他の提案はありますか?
編集: iText 7 .Net を使用して問題を再検討しましたが、テスト ファイルからテキストを読み取ろうとすると NullReferenceException が発生します。
var reader = new iText.Kernel.Pdf.PdfReader(@"itextsharp_sample_locationtext_extraction_reversing_characters(1).pdf");
var extractionStrategy = new LocationTextExtractionStrategy();
var doc = new PdfDocument(reader);
var page = doc.GetFirstPage();
var test = PdfTextExtractor.GetTextFromPage(doc.GetFirstPage());
Console.WriteLine(test);
これは私が使用したファイルです: https://drive.google.com/file/d/0B1RdIg0_Pbd_aTlOT2VmbnFlaTQ/view?usp=sharing
コードは他の PDF ファイルでは機能しますが、このファイルでは機能しません。
更新 mkl のおかげで、根底にある問題はフォント エンコーディング ストリームにあることがわかりました。悲しいことに、これはロードマップにないというメッセージを iText セールス チームから受け取りました。彼らは、これは奇妙な外れ値であると主張しています。他のほとんどの人は、フォント エンコーディング ストリームのサポートを必要としません。したがって、これを読んでサポートが不足しているという問題がある場合は、電子メールでお知らせください。