PDF 内部構造 CMap 新しいページはコチラ

提供: yonewiki
移動: 案内, 検索
(beginbfchar ~ endbfchar)
 
1行: 1行:
 
[[PDF 内部構造 テキスト#/ToUnicode|PDF 内部構造 テキスト]]へ戻る。
 
[[PDF 内部構造 テキスト#/ToUnicode|PDF 内部構造 テキスト]]へ戻る。
 
== '''概要''' ==
 
== '''概要''' ==
 CMapは、グリフの番号のGID(フォントファイルに格納されている順番の番号)と文字番号のCID(文字コードの意味をもつ番号)とを解決する割り当て表みたいなものです。PDFでは特殊なCMapはストリームとして記述して、内部に埋め込む必要があります。以下が埋め込みの例です。
+
 CMapは、グリフの番号のGID(フォントファイルに格納されている順番の番号)と文字番号のCID(文字コードの意味をもつ番号)とを解決する割り当て表みたいなものです。[https://adobe-type-tools.github.io/font-tech-notes/pdfs/5014.CIDFont_Spec.pdf 仕様書PDFはコチラ]から入手可能。PDFでは特殊なCMapはストリームとして記述して、内部に埋め込む必要があります。以下がPDFにおけるTo Unicode部としてのCMap情報の埋め込みの例です。CMapファイルを構成する場合はもっと多くの辞書定義が必須となります。
<Syntaxhighlight2 lang="text">
+
 
 +
<Syntaxhighlight2 lang="text" line=1>
 
15 0 obj
 
15 0 obj
 
<< >>
 
<< >>
9行: 10行:
 
       12 dict begin  
 
       12 dict begin  
 
         begincmap  
 
         begincmap  
        /CIDSystemInfo  
+
            /CIDSystemInfo  
 
             <<  
 
             <<  
 
               /Registry (Adobe)  
 
               /Registry (Adobe)  
48行: 49行:
  
  
[[PDF 内部構造 テキスト]]へ戻る。
+
 CMapファイルの仕様書を読んでみました。英語ですが、100ページくらいに同じようなことを繰り返し解説している部分を含めたものになっていて、実質50ページくらいの感じです。繰り返すことで、わかりやすくなっています。CMapファイルそのものは、それほど難しいものではないということです。読み込んではいないので、全てのキーワードについて深い理解をしたわけではないですが、ひも解いていきましょう。
 +
 
 +
 
 +
 まず、最初のこれは
 +
 
 +
 
 +
/CIDInit /ProcSet findresource begin
 +
 
 +
 
 +
 いまからCMapの内容を書くので、PostScript言語を動かすプログラム資源を見つけて準備をしてくれって感じなんですね。用意したもを使ってファイルの最後の40行目のendまで処理するということを記述しています。仕様書の付録Aにやんわりと書かれています。PostScriptの初期化では以下のようなファイルを動かすんだそうです。
 +
 
 +
 
 +
*Sys/Start
 +
*Resource/ProcSet/CIDInit
 +
*FS/Level1
 +
*FS/Level2
 +
*fonts/NotDefFont
 +
 
 +
 
 +
Sys/Startはプリンタで印刷するときに動かすようなsysの下のstart.psっていうのを動かすそうです。Windowsの場合はそんなディレクトリはないので、違うところにあるんでしょう。DisplayPostScript™システムはdpsstartup.psと呼ばれるファイルを使用をするということも書かれています。PostScriptには「PostScript Level1」(1984年)、「PostScript Level2」(1990年)、「PostScript3」(1996年)の3種類がありますので、FS/Level1とか、FS/Level2というのは、古いPostScriptを動かす時に使うとかということも書いてあります。実際には書いてないレベルの違うものを紹介しているだけ。Level1とか2の背景を知っていれば、どういう意味か予想できる。現在はどうなってるのかわからんね。Adobe Acrobatのフォルダにはreesourceというフォルダとその中にcmapやcidfontやfontってフォルダはあるので、AcrobatReaderでPDFを使うときにCIDFontを使うとこのあたりのファイルが使われたりするんだと思う。GhoostScriptでPostScriptを動かすとまた違うものが使われたりするんだと思います。
 +
 
 +
 
 +
 /CIDInit に対して /ProcSet という辞書で指定できる値を設定、準備して動かすのがCMap定義のはじまりの通常のあり方です。Adobeが準備した(WindowsならC:\Program Files\Adobe\Acrobat DC\resource\cmapにあるのがAcrobatReader向けの標準CMap)全てのCMapファイルも同じようになっています。
 +
 
 +
 
 +
 この後に辞書が始まるという意味で
 +
 
 +
 
 +
12 dict begin
 +
 
 +
 
 +
 のようなキーワードを記述します。今から定義される実際の辞書の個数よりも大きい数値として、12 になっています。5個くらいは大きめにしておくのが普通らしいです。少ないとdictfullエラーというのが返されるそうです。これに対応する終了部分が39行目のendです。この区間の中でcmapが記述できます。cmapの始まりとして
 +
 
 +
 
 +
begincmap
 +
 
 +
 
 +
 を記述します。対応する終了部分が38行目のendcmapです。
 +
 
 +
 
 +
 この例ではCMap記述部分に以下の情報が記述されています。
 +
 
 +
 
 +
*/CIDSystemInfo
 +
*/CMapName
 +
*begincodespacerange
 +
*beginbfchar
 +
 
 +
 
 +
 順番に意味を説明します。
 +
 
 +
 
 +
==== '''/CIDSystemInfo''' ====
 +
 ここにCIDFontの情報を記述します。必須の情報です。説明の要素が強い情報です。PDFのビューワーから、この情報にアクセスして、どんなCIDFontが使われているのかを知る術になっているようです。
 +
 
 +
 
 +
この中に3つの辞書を設定します。
 +
 
 +
 
 +
*/Registry
 +
: このCID情報の登録者文字列を設定します。個人でフォントを登録することは少ないので会社名であることが多いようです。よく使われるのが (Adobe) です。文字列です。
 +
 
 +
*/Ordering
 +
: 文字のエンコーディング方式名を設定します。Identityならそのまま、UCSはユニコードシーケンス。といった具合です。(Japan1) ならAdobeJapan1です。
 +
 
 +
*/Supplement
 +
: 補足です。ここには文字のエンコーディング方式の世代番号のようなものを登録します。整数です。0~65535くらいまで設定できます。AdobeJapan1の場合は登録文字数によって 0~7 に分けられています。7はUnicode文字セットのほとんどを収録しているようなフォントになります。
 +
 
 +
 
 +
設定した最後には def という文字が必要です。これは全ての辞書に共通することです。
 +
 
 +
 
 +
/辞書名文字列 設定値 def
 +
 
 +
/辞書名文字列 << /辞書名文字列1 設定値 /辞書名文字列2 設定値 ...  /辞書名文字列n 設定値 >> def
 +
 
 +
 
 +
のようになります。
 +
 
 +
 
 +
==== '''/CMapName''' ====
 +
 CMapFont名の任意の辞書文字列を設定します。CIDFont名の正式名称ような形式になっていることが多いです。例では /Adobe-Identity-UCS となっています。
 +
 
 +
 
 +
==== '''/CMapType''' ====
 +
 CMapの形式を指定します。後ろのオペランドに整数をとります。
 +
 
 +
 
 +
0 = CMapファイルとしての機能。
 +
 
 +
1 = CID への変換。※PDFのFont構造のCIDtoGIDMap向け
 +
 
 +
2 = Unicode への変換。※PDFのFont構造のToUnicode向け
 +
 
 +
==== '''begincodespacerange ~ endcodespacerange''' ====
 +
 辞書ではないので def を最後につける必要はありませんが、終了の対になっている値のあるオペレータです。オペレータは、前置オペランド 開始オペレーターbeginXxx 後置オペランド (前置オペランド)xm 終了オペレーターbeginXxx 後置オペランド のような形式です。
 +
 
 +
 
 +
 CMap文字コード設定をする範囲を指定しています。beginやendを省いて分解すると、codespeceのrangeと解釈できるものです。
 +
 
 +
 
 +
 前置オペランドや後置オペランドを必要とするオペレータで、オペランドは引数とも呼べます。このオペレータの場合、仕様書の中では以下のように表現されます。
 +
 
 +
 
 +
 int begincodespacerange -
 +
 
 +
 srcCodeLo serCodeHi endcodespacerange -
 +
 
 +
 
 +
<Syntaxhighlight2 lang="text">
 +
1 beginbfchar
 +
    <0000> <FFFF>
 +
endcodespacerange
 +
</Syntaxhighlight2> 
 +
 
 +
 
 +
 int が 1 という整数に対応していて、終了オペレータの前にあるオペランドの数に対応しています。<0000> <FFFF>の1回分になっています。
 +
 
 +
 
 +
 srcCodeLoが<0000>、srcCodeHiが<FFFF>に対応します。Loは範囲の始まり、Hiは範囲の終わりです。0000~FFFFの65536種類がコード領域だと定義していることになります。
 +
 
 +
 
 +
 通常はきちんとコードスペースを定義して、余計なところのコードに関するCMap情報を無視するという役目を果たします。日本語のコードスペースとして
 +
 
 +
<Syntaxhighlight2 lang="text">
 +
  <00>  <80>
 +
  <8140> <9ffc>
 +
  <a0>  <de>
 +
  <e040> <fbec>
 +
</Syntaxhighlight2>
 +
 
 +
 
 +
 のように特定のシングルバイト範囲と特定のダブルバイト範囲だけを有効にしたりする方が、有用です。
 +
 
 +
 
 +
 
 +
==== '''beginbfchar ~ endbfchar''' ====
 +
 PDFやアプリケーション側が指定するグリフコード対応するコード番号を返却するものです。PDFのFont構造の中の/ToUnicodeに対応する参照にCMapを指定した場合。第一オペランドで指定されたコードがUnicode文字での第二オペランドのコード番号の対応になります。この番号が指定されていればPDFでテキストを範囲指定してコピーしたものを各種エディタに貼りつけるときに各種文字コードにエンコードして貼り付けたりすることができるようになります。第一オペランドに指定したようなグリフIDだけではコピーペーストができません。
 +
 
 +
 
 +
 CMapとして使う場合はuseFontというオペレータが必須です。これはフォントの再配置におけるフォント番号をオペランドとして保持するオペレータです。複数あるフォントのうち何番目のフォント図柄を対応させるかという意味になります。複数ない場合でも1 useFontのように定義されているはずです。ToUnicodeに対応するCMapでは必須ではないです。
 +
 
 +
 
 +
 int beginbfchar -
 +
 
 +
 srcCode dstCode endcodespacerange -
 +
 
 +
 
 +
<Syntaxhighlight2 lang="text">
 +
17 beginbfchar
 +
  <0003> <0020> %
 +
  <0030> <004D> %M
 +
  <0036> <0053> %S
 +
  <0838> <3044> %い
 +
  <084B> <3057> %し
 +
  <0862> <306E> %の
 +
  <089B> <30A9> %ォ
 +
  <08A1> <30AF> %ク
 +
  <08A6> <30B4> %ゴ
 +
  <08A9> <30B7> %シ
 +
  <08B5> <30C3> %ッ
 +
  <08BA> <30C8> %ト
 +
  <08C7> <30D5> %フ
 +
  <08E5> <30F3> %ン
 +
  <0B61> <4E16> %世
 +
  <23FA> <754C> %界
 +
  <2A3E> <7F8E> %美
 +
endbfchar
 +
</Syntaxhighlight2>
 +
 
 +
 
 +
 ここからは上記のサンプルで使わなかったオペレータと/辞書名文字列を紹介していきます。
 +
 
 +
==== '''beginbfrange ~ endbfrange''' ====
 +
 一定の範囲を一括で同じグリフに割り当てるオペレータです。endbfrangeの最初の2つのオペランドで指定した入力範囲に対して、3番目に指定した番号を先頭としたグリフIDを連番で指定するものです。出力に配列名と辞書名文字を使うパターンも使うかもしれないです。
 +
 
 +
 int beginbfrange -
 +
 
 +
 srcCodeLo srcCodeHi dstCodeLo endbfrange -
 +
 
 +
or
 +
 
 +
 srcCodeLo srcCodeHi [/dstCharName 1 .. /dstCharName n] endbfrange -
 +
 
 +
 
 +
<Syntaxhighlight2 lang="text">
 +
1 beginbfrange
 +
    <00>  <1F>  <20>
 +
endbfrange
 +
</Syntaxhighlight2> 
 +
 
 +
 
 +
<Syntaxhighlight2 lang="text">
 +
1 beginbfrange
 +
    <20>  <23>  [/space /exclam /quotedbl /numbersign]
 +
endbfrange
 +
</Syntaxhighlight2> 
 +
 
 +
 
 +
 のような使い方になるでしょう。
 +
 
 +
==== '''begincidchar ~ endcidchar''' ====
 +
 出力に10進数のグリフ番号を使うパターンです。
 +
 
 +
 int begincidchar -
 +
 
 +
 srcCode dstCID  endcidchar -
 +
 
 +
<Syntaxhighlight2 lang="text">
 +
1 beginbfrange
 +
    <20>  32  %space
 +
endbfrange
 +
</Syntaxhighlight2> 
 +
 
 +
 のような使い方になるでしょう。
 +
 
 +
==== '''begincidrange ~ endcidrange''' ====
 +
 領域を一括して指定するものです。endcidrangeの最初の2つのオペランドで指定した入力値に対して10進数で指定したのグリフ番号を先頭に連番で使うパターンです。
 +
 
 +
 int begincidrange -
 +
 
 +
 srcCode dstCID  dstCIDLo endcidrange -
 +
 
 +
<Syntaxhighlight2 lang="text">
 +
1 beginbfrange
 +
    <20>  <7e>  231  %space 
 +
endbfrange
 +
</Syntaxhighlight2> 
 +
 
 +
 のような使い方になるでしょう。
 +
 
 +
==== '''beginnotdefchar ~ endnotdefchar''' ====
 +
 notdefは未定義値の意味です。Glyph未定義値の結果としてどのグリフ番号を使うかというものです。PDFでもよく文字化けしたような文字で□が使われることがありますが、これもフォントの動作として指定されているということです。何も設定しなければcodespaceの範囲外の無効な値はGlyph番号 0が使われます。
 +
 
 +
 int endnotdefchar -
 +
 
 +
 srcCode dstCID  endnotdefchar -
 +
 
 +
<Syntaxhighlight2 lang="text">
 +
1 beginbfrange
 +
    <01>  1   
 +
endbfrange
 +
</Syntaxhighlight2> 
 +
 
 +
 のような使い方になるでしょう。
 +
==== '''beginnotdefrange ~ endnotdefrange''' ====
 +
 Glyph未定義値の結果としてどのグリフ番号を使うかというものの一括版です。何も設定しなければ
 +
 
 +
 int endnotdefrange -
 +
 
 +
 srcCodeLo srcCodeHi dstCID  endnotdefrange -
 +
 
 +
<Syntaxhighlight2 lang="text">
 +
1 beginbfrange
 +
    <01>  <1F>  1   
 +
endbfrange
 +
</Syntaxhighlight2> 
 +
 
 +
 のような使い方になるでしょう。
 +
 
 +
==== '''beginrearrangedfont ~ endrearrangedfont''' ====
 +
 再配置したフォントを1つにまとめて使う場合の定義です。どのフォントからどれを使うかはこれまでに紹介した方法で定義する必要があります。割り当てを定義するオペレータを使う都度、usefontオペレータで対象のフォントを配列にしていた順番で割り当てられる番号で指定する必要があります。
 +
 
 +
 
 +
 /newFontName [component fonts array] beginrearrangedfont -
 +
 
 +
 srcCodeLo srcCodeHi dstCID  endnotdefrange -
 +
 
 +
<Syntaxhighlight2 lang="text">
 +
/Jun101-Light-K-G-R-83pv-RKSJ-H
 +
[
 +
  /Jun101-Light-83pv-RKSJ-H
 +
  /Poetica-ChanceryIV
 +
  /ShinseiKai-CBSK1-83pv-RKSJ-H
 +
  /FutoGoB101-Bold-83pv-RKSJ-H
 +
  /FutoMinA101-Bold-83pv-RKSJ-H
 +
  /HSMinW3Gai30
 +
] beginrearrangefont
 +
</Syntaxhighlight2> 
 +
 
 +
 のような使い方になるでしょう。5つのCIDフォントが再配置されて、/Jun101-Light-K-G-R-83pv-RKSJ-Hとして機能することを意味しています。
 +
 
 +
==== '''beginusematrix ~ endusematrix''' ====
 +
 フォントを移動拡大縮小回転歪み変形させる処理です。斜体文字を演算によって作り出すだけの手法はCMapによって実現できます。実際は専用の斜体文字の見た目の良さには勝てません。文字の詰め方や斜体独特の文字のつぶれ方の補完を実施したほうが美しいと感じます。
 +
 
 +
 
 +
 fontID beginusematrix
 +
 
 +
 [a b c d tx ty]  endusematrix 
 +
 
 +
<Syntaxhighlight2 lang="text">
 +
1 beginusematrix % 1はフォント番号
 +
[1 0 0 1 0 0.15] beginrearrangefont
 +
</Syntaxhighlight2> 
 +
 
 +
 のような使い方になるでしょう。配列の0.15にあたる部分は縦方向の移動量を示していて1が1000emとなるような単位系です。emとは何かについては[[METAFONT 単位|フォントの作成について説明した記事]]で説明済なので説明しません。配列は行列を使った移動拡大縮小のメカニズムで[[PDF_内部構造_グラフィックス#平行移動・拡大縮小・回転|PDF内部構造のグラフィックの部分]]で説明済なので、ここでは説明しません。
 +
 
 +
 
 +
 
 +
[[PDF 内部構造 テキスト#/ToUnicode|PDF 内部構造 テキスト]]へ戻る。

2022年8月11日 (木) 00:00時点における最新版



個人用ツール
名前空間

変種
操作
案内
ツールボックス