1

別の ObjectX で、同じ PDF ページに次の内容があります。

最初

[(some text)] TJ ET Q
[(some other text)] TJ ET Q

これまでのところ、非常にシンプルで基本的な...

第二

[( H T M L   E x a m p l e)] TJ ET Q
[( S o m e   s p e c i a l   c h a r a c t e r s :   <   ¬   ¬   ¬   &   ט   ט   ©   >   \\ s l a s h   \\ \\ d o u b l e - s l a s h   \\ \\ \\ t r i p l e - s l a s h  )] TJ ET Q

注: 上記のテキストでは目立ちませんが、

「HTMLE xampl e」は実際には0H0T0M0L 0[32] 0E0x0a0m0p0l0eであり、各 0 はリテラル値 0 == ((char)0)なので、すべての 0 値を無視すると、これは実際には上の例のようになります...

いくつかのバイト:

htmlexample == [0, 72, 0, 84, 0, 77, 0, 76, 0, 32, 0, 69, 0, 120, 0, 97, 0, 109, 0, 112, 0, 108, 0, 101]
<content>  == [0, 32, 32, -84, 0, 32, 32, -84, 0, 32, 32, -84, 0, 32, 0, 38, 0, 32, 0, -24, 0, 32, 0, -24, 0, 32, 0, -87, 0, 32, 0]

しかし、次の行では、次の理由により、2 バイトごとに 1 つの文字に結合する必要があります。

< ¬ ¬ ¬...> は実際には <0[32][32]¬0[32][32]¬0[32][32]¬...> で、[32]¬ の組み合わせは €< /p>

私が直面している問題は、私が使用する変換自体ではありません: new String(sb.toString().getBytes("UTF-8"),"UTF-16BE")

問題は、それをいつ適用し、いつ UTF-8 を維持するかを知ることです。

==更新==

問題のあるオブジェクトに使用されているフォントは次のとおりです。

#7 0# {
    'Name' : "F4"
    'BaseFont' : "AAAAAE+DejaVuSans-Bold"
    'Subtype' : "Type0"
    'ToUnicode' : #41 0# {
        'Filter' : "FlateDecode"
        'Length' : 1679.0f
    } + Stream(5771 bytes)
    'Encoding' : "Identity-H"
    'DescendantFonts' : [#42 0# {
        'FontDescriptor' : #43 0# {
            'MaxWidth' : 2016.0f
            'AvgWidth' : 573.0f
            'FontBBox' : [-1069.0f, -415.0f, 1975.0f, 1174.0f]
            'MissingWidth' : 600.0f
            'FontName' : "AAAAAE+DejaVuSans-Bold"
            'Type' : "FontDescriptor"
            'CapHeight' : 729.0f
            'StemV' : 60.0f
            'Leading' : 0.0f
            'FontFile2' : #34 0# {
                'Filter' : "FlateDecode"
                'Length1' : 83036.0f
                'Length' : 34117.0f
            } + Stream(83036 bytes)
            'Ascent' : 928.0f
            'Descent' : -236.0f
            'XHeight' : 547.0f
            'StemH' : 26.0f
            'Flags' : 32.0f
            'ItalicAngle' : 0.0f
        }
        'Subtype' : "CIDFontType2"
        'W' : [32.0f, [348.0f, 456.0f, 521.0f, 838.0f, 696.0f, 1002.0f, 872.0f, 306.0f, 457.0f, 457.0f, 523.0f, 838.0f, 380.0f, 415.0f, 380.0f, 365.0f], 48.0f, 57.0f, 696.0f, 58.0f, 59.0f, 400.0f, 60.0f, 62.0f, 838.0f, 63.0f, [580.0f, 1000.0f, 774.0f, 762.0f, 734.0f, 830.0f, 683.0f, 683.0f, 821.0f, 837.0f, 372.0f, 372.0f, 775.0f, 637.0f, 995.0f, 837.0f, 850.0f, 733.0f, 850.0f, 770.0f, 720.0f, 682.0f, 812.0f, 774.0f, 1103.0f, 771.0f, 724.0f, 725.0f, 457.0f, 365.0f, 457.0f, 838.0f, 500.0f, 500.0f, 675.0f, 716.0f, 593.0f, 716.0f, 678.0f, 435.0f, 716.0f, 712.0f, 343.0f, 343.0f, 665.0f, 343.0f, 1042.0f, 712.0f, 687.0f, 716.0f, 716.0f, 493.0f, 595.0f, 478.0f, 712.0f, 652.0f, 924.0f, 645.0f, 652.0f, 582.0f, 712.0f, 365.0f, 712.0f, 838.0f], 160.0f, [348.0f, 456.0f, 696.0f, 696.0f, 636.0f, 696.0f, 365.0f, 500.0f, 500.0f, 1000.0f, 564.0f, 646.0f, 838.0f, 415.0f, 1000.0f, 500.0f, 500.0f, 838.0f, 438.0f, 438.0f, 500.0f, 736.0f, 636.0f, 380.0f, 500.0f, 438.0f, 564.0f, 646.0f], 188.0f, 190.0f, 1035.0f, 191.0f, 191.0f, 580.0f, 192.0f, 197.0f, 774.0f, 198.0f, [1085.0f, 734.0f], 200.0f, 203.0f, 683.0f, 204.0f, 207.0f, 372.0f, 208.0f, [838.0f, 837.0f], 210.0f, 214.0f, 850.0f, 215.0f, [838.0f, 850.0f], 217.0f, 220.0f, 812.0f, 221.0f, [724.0f, 738.0f, 719.0f], 224.0f, 229.0f, 675.0f, 230.0f, [1048.0f, 593.0f], 232.0f, 235.0f, 678.0f, 236.0f, 239.0f, 343.0f, 240.0f, [687.0f, 712.0f, 687.0f, 687.0f, 687.0f, 687.0f, 687.0f], 247.0f, [838.0f, 687.0f], 249.0f, 252.0f, 712.0f, 253.0f, [652.0f, 716.0f]]
        'Type' : "Font"
        'BaseFont' : "AAAAAE+DejaVuSans-Bold"
        'CIDSystemInfo' : {
            'Supplement' : 0.0f
            'Ordering' : "Identity" + Stream(8 bytes)
            'Registry' : "Adobe" + Stream(5 bytes)
        }
        'DW' : 600.0f
        'CIDToGIDMap' : #44 0# {
            'Filter' : "FlateDecode"
            'Length' : 10200.0f
        } + Stream(131072 bytes)
    }]
    'Type' : "Font"
}

フォントのエンコーディングタイプへの指示はありません。

==更新==

ToUnicode オブジェクトに関しては、これらのフォントの場合は必要ありませんが、Identity-H である必要がありますが、代わりに X == X マッピングです。FFFF から FFFF までの例を次に示します。

<0000> <00ff> <0000>
<0100> <01ff> <0100>
<0200> <02ff> <0200>
<0300> <03ff> <0300>
<0400> <04ff> <0400>
<0500> <05ff> <0500>
<0600> <06ff> <0600>
<0700> <07ff> <0700>
<0800> <08ff> <0800>
<0900> <09ff> <0900>
<0a00> <0aff> <0a00>
<0b00> <0bff> <0b00>
<0c00> <0cff> <0c00>
<0d00> <0dff> <0d00>
<0e00> <0eff> <0e00>
<0f00> <0fff> <0f00>
<1000> <10ff> <1000>
<1100> <11ff> <1100>
....
....
....
<fc00> <fcff> <fc00>
<fd00> <fdff> <fd00>
<fe00> <feff> <fe00>
<ff00> <ffff> <ff00>

したがって、マッピングは ToUnicode オブジェクトにはありませんが、それでも他のレンダラーはうまくレンダリングできます!

何か案は?

4

2 に答える 2

4

私が使用する: new String(sb.toString().getBytes("UTF-8"),"UTF-16BE")

問題は、UTF-8 を適用するタイミングと UTF-8 を維持するタイミングを知ることです。

OPは、おそらくいくつかのサンプルPDFファイルを調べた後、PDFコンテンツストリームの文字列がUTF-8またはUTF-16BEのいずれかを使用してエンコードされていると想定しています。

この仮定は間違っています。

PDF では、いくつかの標準的なシングルバイト エンコーディング ( MacRomanEncodingMacExpertEncoding、およびWinAnsiEncoding ) を使用できますが、いずれも UTF-8 ではありません (異なるエンコーディング、特に ASCII、Latin1、および UTF-8 の間の関係により、直面したときに互いに混同される可能性があります)。限定サンプル付き)。さらに、事前定義された多数のマルチバイト エンコーディングも許可されており、その中には実際に UTF-16 関連のものもあります。

しかし、PDF では、シングルバイトとマルチバイトの両方の完全にカスタムのエンコーディングも使用できます。

たとえば、このテキスト描画操作

(ABCCD) Tj

このエンコーディングの単純なフォントの場合:

<<
 /Type /Encoding
 /Differences [ 65 /H /e /l /o ] 
>>

Hello !という単語が表示されます。

これは人為的に作成された例のように見えるかもしれませんが、このようなカスタム エンコーディングを作成する手順 (つまり、ある開始値から、ページまたはドキュメントで最初に出現する順序でグリフにコードを割り当てることによる) はかなり簡単です。頻繁に使用されます。

さらに、OPの現在のソリューション

フォント オブジェクトに CMap がある場合は UTF-16 として扱いますが、そうでない場合は扱いません。

非常に少数のドキュメントでのみ機能します。

a) 単純なフォント (シングルバイト エンコーディングを使用) もToUnicode CMap を提供できます。b) 複合フォントの CMap も UTF ライクである必要はありませんが、代わりに混合マルチバイト エンコーディングを使用できます。

したがって、使用されているフォント情報の詳細な分析を回避する方法はありません。PDF 仕様ISO 32000-1の 9.5..9.9 。

PS OPによるいくつかのコメントについて:

this: new String(sb.toString().getBytes("UTF-8"),"UTF-16BE")は、解決策ではなく問題がどのように解決されるかの例です! データを 16 ビットまたは 8 ビットとして扱うかどうかに関係なく、グリフをフェッチしている間に解決策が実行されます。

ToUnicode マップはキーごとに 16 ビット (私が見た唯一のもの) です。

データは混合データである可能性があります。たとえば、Adobe CMap および CIDFont Files Specificationを参照してください。ここでは、CMap の例 9 に次のセクションが含まれています。

4 begincodespacerange
<00> <80>
<8140> <9ffc>
<a0> <de>
<e040> <fbec>
endcodespacerange

意味すると説明されている

図 6 は、この例のコード空間定義が、コードの 2 つの 1 バイト線形範囲 ( <00>to<80>および<A0>to <DF>) と 2 つの 2 バイト長方形コード範囲 ( <8140>to<9FFC>および<E040>to <FBFC>) で構成されていることを示しています。最初の 2 バイト領域は、81 から 9F までの最初のバイト値と 40 から FC までの 2 番目のバイト値によって区切られたすべてのコードで構成されます。<86A9>したがって、両方のバイトが境界内にあるため、入力コードは領域内にあります。そのコードは有効です。入力コード<8210>は、最初のバイトが 81 から 9F の間にありますが、2 番目のバイトが境界内にないため、領域内にありません。そのコードは無効です。2 番目の 2 バイト領域も同様に制限されています。

図 6 83pv-RKSJ-H 文字セット エンコーディングのコード空間範囲

于 2014-10-15T10:55:30.003 に答える
0

OK、これは複雑なようで、このバグの理由は特に私の側ではばかげていますが、いつ文字をUTF-16として扱うべきか、そうでないかに関して学ぶべき教訓があります。

私の問題は、フォントの解析中ではなく、レンダリング中にありました。Font オブジェクトで指定された詳細に従って、フォントのタイプを判断し、正しいロジックを適用できます。

于 2014-10-15T00:00:01.107 に答える