非常に短く簡単な紹介
PDF のフォントはPDF オブジェクト-Font辞書であり、グリフを選択し、それらを表示し、コンテンツ抽出のために文字コードを論理 (Unicode) 表現に変換するために必要な多数のパラメーターとサブ辞書を含みます。平たく言えば、フォント(*.ttf または *.pfb ファイルと見なされる) は、埋め込みまたは外部のフォント プログラムFontと呼ばれ、オブジェクトのサブディクショナリの 1 つによって参照されます。
Fonts次の 2 つのグループに分けられます。
- テキスト表示演算子によって表示される文字列から取得された 1 バイト文字コードによってグリフが選択される単純なフォント (Type1、Type3、または TrueType)。コードからグリフへのマッピングは、フォントのエンコーディングと呼ばれます。これは、フォント プログラムに組み込まれているか、
Fontオブジェクトによって (定義済みの名前または明示的に) 定義されているか、特別な状況下では、ビューア アプリケーションによって定義された規則に従って構築されます。
問題のファイルには単純なフォントが含まれていないため、これ以上説明しません。
- 複合フォント (Type0)。文字コードが可変長 (最大 4 バイト) で、256 コードポイントに制限されていないテキストを表示するために使用されます。Type0フォントには常に 1 つの子孫があり、これはと呼ばれるフォントのようなオブジェクト
CIDFontであり、単純なフォントのエンコーディングと同様に、CMap文字コードを文字セレクターにマップするオブジェクトであり、PDF では常にCIDs65536 までの整数です。
現在、文字セレクター ( CID) は、通常、フォント プログラムからグリフを選択するために直接使用されることはありません。タイプの辞書には、明らかにグリフ識別子にマップされるエントリが含まれてCIDFontいます。最後に、これらは埋め込みフォント プログラム(フォントの場合はTrueTypeフォント プログラムです ( TrueTypeのオブジェクトと混同しないでください))からグリフを選択するために使用されます。CIDFontType2CIDToGIDMapCIDGIDsCIDFontType2Font Subtype
FontオブジェクトはToUnicode、索引付け、検索、および抽出のために CID を Unicode 値にマップするリソースを持つことができます。ToUnicode Cmap(同様の構文に従うため) と呼ばれますがCMap、上記のオブジェクトと混同しないでください。
私が単純なケースと呼んでいるもの (そして、賢明な決定だと思います)CMapは定義済みの Identity-H名でCIDToGIDMapあり、定義済みのIdentity名であるため、文字列から抽出された文字コード (演算子を示すテキストへの引数) は常に 2 です。 - 埋め込まれたTrueTypeプログラムからグリフを効果的に直接選択するバイト数。私の経験からすると、これは最も一般的なシナリオであり、一般的なソフトウェアがテストされるケースです。
しかし、問題のファイルはそうではありません。
(短く簡単な紹介の終わり)
私たちのファイルでは、演算子を示すテキストは、事実上、次の文字列を取得します。
0x000a 0x000a 0x000a 0x20 0x0020 0x0020 0x0020 0x20 0x0025 0x0025 0x0025
もちろん、「グループ」はありませんCMap。2 つの範囲が含まれていることに基づいて作成したため、ここにあります。
<20> <20>
<0000> <19FF>
簡単に言うと、 で文字コードをCMap検索して CID を取得し、次に CIDCIDToGIDMapを検索して GID を取得し、埋め込まれたDavid-Boldフォントで GID を検索して Unicode 値を取得すると、次の表になります。
Code CID GID Unicode Name
0x000a 10 180 05EA tav
0x0020 32 159 05D5 vav
0x0025 37 154 05D0 alef
0x20 228 03 0020 space
これで、推測するのに十分な情報が得られました。ビューアアプリケーションを混乱させるものは何ですか
私の最初の試みで、スペース以外の文字に使用されるのは32コード(および)であることを提案しました(上記のコメントを参照)。この仮定は、数年前、(古いバージョンの) Acrobat が文字列の末尾にあるときにコードでCID文字を表示しなかった場合に基づいていました。 (単純なフォントの)別の文字でした。0x20space
私はこれを変更しました:
0x00200x0004コンテンツ ストリーム内へ。
- バイト 08 と 09 は
CIDToGIDMapGID=159 に。
WidthsCID=4 から 'vav' 幅の配列の値。
ToUnicode cmapそれに応じて調整されました。
- (+後で
<0020> 32文字列を削除しようとしCMAPました-ファイルに反映されず、コメントにリンクされています)
まあ、それは役に立ちましたが、残念ながら、一部のビューアはまだ仕様に準拠することを拒否していました.
それから、おそらく可変文字コード幅が問題だと思いました。
元のファイルに戻って、これを変更しました。
0x200x00e4コンテンツ ストリーム内へ。
<20> 228に; <00e4> 228_CMAP
codespacerange <20> <20>CMAP削除されました。
codespacerange <20> <20>でToUnicode Cmap削除。
このファイルは、元の質問と以下のコメントで言及されているすべてのビューアで完全に開くように見えます。奇跡的に、0x0020コードと32 CID干渉しません。
結論としては、次のようになると思います。
現在の状況を考えると、PDF の作成者は、フォント エンコーディングでシングル バイト コードとダブル バイト コードを混在させることはお勧めできませんCMAP( )。