3

Stefano Chizzolini (Awesome guy : PDFClown の作成者)によって記述された Java コードを実行して、PDF Clown ライブラリを使用して PDFを解析しようとしています。このエラーが発生しましたが、これを修正するために何ができるかわかりません。

Exception in thread "main" org.pdfclown.util.parsers.ParseException: 'name' table does NOT exist.
at org.pdfclown.documents.contents.fonts.OpenFontParser.getName(OpenFontParser.java:570)
at org.pdfclown.documents.contents.fonts.OpenFontParser.load(OpenFontParser.java:221)
at org.pdfclown.documents.contents.fonts.OpenFontParser.<init>(OpenFontParser.java:205)
at org.pdfclown.documents.contents.fonts.TrueTypeFont.loadEncoding(TrueTypeFont.java:91)
at org.pdfclown.documents.contents.fonts.SimpleFont.onLoad(SimpleFont.java:118)
at org.pdfclown.documents.contents.fonts.Font.load(Font.java:738)
at org.pdfclown.documents.contents.fonts.Font.<init>(Font.java:351)
at org.pdfclown.documents.contents.fonts.SimpleFont.<init>(SimpleFont.java:62)
at org.pdfclown.documents.contents.fonts.TrueTypeFont.<init>(TrueTypeFont.java:68)
at org.pdfclown.documents.contents.fonts.Font.wrap(Font.java:253)
at org.pdfclown.documents.contents.FontResources.wrap(FontResources.java:72)
at org.pdfclown.documents.contents.FontResources.wrap(FontResources.java:1)
at org.pdfclown.documents.contents.ResourceItems.get(ResourceItems.java:119)
at org.pdfclown.documents.contents.objects.SetFont.getResource(SetFont.java:119)
at org.pdfclown.documents.contents.objects.SetFont.getFont(SetFont.java:83)
at org.pdfclown.documents.contents.objects.SetFont.scan(SetFont.java:97)
at org.pdfclown.documents.contents.ContentScanner.moveNext(ContentScanner.java:1330)
at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:626)
at org.pdfclown.tools.TextExtractor.extract(TextExtractor.java:296)
at PDFReader.FullExtract.run(FullExtract.java:71)
at PDFReader.FullExtract.main(FullExtract.java:142)

ライブラリ パッケージのクラスOpenFontParserがこのエラーをスローしていることはわかっています。これを修正するためにできることはありますか?

このコードは、ほとんどの PDF で機能します。解析できない PDF があります。私はそれがpdfの下のこの記号のためだと推測しています。

public class PDFReader extends Sample {

@Override
public void run()
{
    String filePath = new String("C:\\Users\\XYZ\\Desktop\\SomeSamplePDF.pdf");

    // 1. Open the PDF file!
    File file;
    try
    {file = new File(filePath);}
    catch(Exception e)
    {throw new RuntimeException(filePath + " file access error.",e);}

    // 2. Get the PDF document!
    Document document = file.getDocument();

    // 3. Extracting text from the document pages...
    for(Page page : document.getPages())
    {
    extract(new ContentScanner(page)); // Wraps the page contents into a scanner.

    }
    close(file);
}

private void close(File file) {
    // TODO Auto-generated method stub

}

/**
Scans a content level looking for text.
 */
/*
NOTE: Page contents are represented by a sequence of content objects,
possibly nested into multiple levels.
 */
private void extract(
        ContentScanner level
        )
{
    if(level == null)
        return;

    while(level.moveNext())
    {
        ContentObject content = level.getCurrent();
        if(content instanceof ShowText)
        {
            Font font = level.getState().getFont();
            // Extract the current text chunk, decoding it!
            System.out.println(font.decode(((ShowText)content).getText()));
        }
        else if(content instanceof Text
                || content instanceof ContainerObject)
        {
            // Scan the inner level!
            extract(level.getChildLevel());
        }
    }
}

private boolean prompt(Page page)
{
    int pageIndex = page.getIndex();
    if(pageIndex > 0)
    {
        Map<String,String> options = new HashMap<String,String>();
        options.put("", "Scan next page");
        options.put("Q", "End scanning");
        if(!promptChoice(options).equals(""))
            return false;
    }

    System.out.println("\nScanning page " + (pageIndex+1) + "...\n");
    return true;
}

public static void main(String args[])
{
    new PDFReader().run();
    }

}
4

1 に答える 1

2

問題

スタックトレースが示すように、問題は、PDF に埋め込まれた一部の TrueType フォントにname、必要なテーブルであってもテーブルが含まれていないことです。

org.pdfclown.util.parsers.ParseException: 'name' table does NOT exist.
...
at org.pdfclown.documents.contents.fonts.TrueTypeFont.loadEncoding(TrueTypeFont.java:91)

したがって、厳密に言えば、その埋め込みフォントは無効であり、結果的に埋め込み PDF も無効になります。そして、この有効性の問題により、PDFClown は例外に遭遇します。

いくつかの背景

TrueType フォント ファイルは、連結された一連のテーブルで構成されます。...

最初のテーブルはフォント ディレクトリです。これは、フォント内の他のテーブルへのアクセスを容易にする特別なテーブルです。ディレクトリの後には、フォント データを含む一連のテーブルが続きます。これらのテーブルは任意の順序で表示できます。すべてのフォントに特定のテーブルが必要です。その他は、特定のフォントに期待される機能に応じてオプションです。

必要な表は、有効な TrueType フォント ファイルに含まれている必要があります。必要なテーブルとそのタグ名を表 2 に示します。

表 2: 必要なテーブル

Tag     Table 
'cmap'  character to glyph mapping 
'glyf'  glyph data 
'head'  font header 
'hhea'  horizontal header 
'hmtx'  horizontal metrics 
'loca'  index to location 
'maxp'  maximum profile 
'name'  naming 
'post'  PostScript 

(セクションTrueType フォント ファイル: TrueType リファレンス マニュアルの第 6 章「TrueType フォント ファイル」の概要)

一方で、埋め込まれた TrueType フォントを、PDF ビューアー (最も重要な Adob​​e Reader) が必要とする最小限の要素に切り詰める PDF ジェネレーターは多数ありますが、name表は厳密には必要ないようです。

さらに、関連するフォント ディクショナリのBaseFontエントリnameからフォント名を決定することもできますが、テーブルは PDFClown で 1 つの目的にのみ使用され、問題のフォントの名前を決定します。実際には、後者のエントリはPDF 仕様で必須ですが、表のフォントエントリの PostScript 名はTTF マニュアルによるとオプションです。name

したがって、PDF フォント ディクショナリのBaseFontnameエントリを使用することは、このテーブル アクセスのより良い代替手段になります。

それを修正する

これを修正するためにできることはありますか?

問題の埋め込み TTF にテーブルを追加して、完全に有効ではない PDF を修正するか、namePDFClown にパッチを適用して、不足している不足しているテーブルを無視することができます。クラスorg.pdfclown.documents.contents.fonts.OpenFontParserでメソッドを編集しますgetName

private String getName(
  int id
  ) throws EOFException, UnsupportedEncodingException
{
  // Naming Table ('name' table).
  Integer tableOffset = tableOffsets.get("name");
  if(tableOffset == null)
    throw new ParseException("'name' table does NOT exist.");

throw new ParseException("'name' table does NOT exist.")それを に置き換えreturn nullます。

PS

OPから提供された情報だけを使用して問題を分析できますが、 @akarshadが削除した回答で提供したサンプルファイルは、分析を開始する動機をさらに高めました。

于 2014-05-22T10:32:12.100 に答える