マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

(x)dvipdfmx が文書情報を Unicode する件に関するメモ(1)

メモメモ。

前に dvipdfmx についてチョット調べたことがあるのでそれと同じ感じで。

実験する
  • TeX Live 最新の、upTeX + dvipdfmx と XeTeX (+ xdvipdfmx) について調べた。
  • 次の文書 test.tex を用意する。
    % plain upTeX/XeTeX 文書, 文字コードUTF-8
    \nopagenumbers \null
    % ToUnicode を指定
    %\special{pdf:tounicode UTF8-UTF16}%(*)
    % 文書情報辞書にエントリを追加
    \special{pdf:docinfo <<
      /Title (☃)
      % '☃'(U+2603) は UTF-8 では 
      /Author 
      % PDF規格で無意味なキー
      /Snowman (☃)
      % 最初からBOM付UTF-16BE
      /Subject 
      % UTF-8として不正なバイト列
      /Keywords <80c0>
    >>}
    % ページオブジェクトの辞書にエントリを追加
    \special{pdf:put @thispage <<
      /CropBox [10 10 90 90]
      /Snowman (☃)
      /UTF16 
      /Bogus <80c0>
    >>}
    \bye
    
  • これを次の 2 通りの方法でコンパイルして PDF に変換する。
    • パターン“upTeX”
      uptex test
      dvipdfmx -V 4 -z o -o test_u.pdf test.dvi
    • パターン“XeTeX”
      xetex --no-pdf test
      xdvipdfmx -V 4 -z o -o test_x.pdf test.xdv
  • さらに、“ToUnicode あり”((*)の行有効)と“ToUnicode なし”((*)の行無効)のパターンを試す。
  • 出力の PDF の中の「文書情報辞書」と「(唯一の)ページオブジェクト」の記述を調べる。(## は何らかの ID 値。)
    [文書情報辞書]
    ## 0 obj
    <<
      /Creator (何か)
      /Title 【DI.Title】
      /Author 【DI.Author】
      /Snowman 【DI.Snowman】
      /Subject 【DI.Subject】
      /Keywords 【DI.Keywords】
      /Producer (何か)
      /CreationDate (何か)
    >>
    endobj
    [ページオブジェクト]
    ## 0 obj
    <<
      /CropBox[10 10 90 90]
      /Snowman 【PO.Snowman】
      /UTF16 【PO.UTF16】
      /Bogus 【PO.Bogus】
      /Resources ## 0 R
      /Type/Page
      /Parent ## 0 R
      /Contents[## 0 R]
    >>
    endobj
    【…】の部分がどうなっているかを調べる。

結果。

パターン     upTeX      XeTeX          upTeX/XeTeX
ToUnicode    なし       なし           あり
DI.Title     <e29883>   <feff2603>     <feff2603>
DI.Author    <e29883>   <feff2603>     <feff2603>
DI.Snowman   <e29883>   <feff2603>     <e29883>
DI.Subject   <feff2603> <feff2603>     <feff2603>
DI.Keywords  <80c0>     <80c0>※1      <fefffffdfffd>※2
PO.Snowman   <e29883>   <e29883>       <e29883>   
PO.UTF16     <feff2603> <feff2603>     <feff2603>
PO.Bogus     <8080>     <8080>         <8080>
※1 “Failed to convert input string to UTF16...”の警告発生。
※2 “No character mapping available.”の警告発生。
※ special が非 ASCII 文字を含む場合、upTeX の DVI および XeTeX の XDV の何れにおいても、それは UTF-8 で書き出されている。
まとめ
  • 文書情報辞書(などの“特定の場所”、詳細不明)の文字列のみが変換対象となる。
  • ToUnicode なしの dvipdfmx では変換は起こらない。
  • ToUnicode なしの xdvipdfmx の場合、UTF-8→UTF-16BE の変換を行う(UTF-8 として不正なら警告する)。ただし元から BOM 付 UTF-16BE である場合は変換しない。
  • ToUnicode ありの dvipdfmx では、“その ToUnicode マップの元”→UTF-16BE の変換を行う(不正なバイト列なら警告する)。ただし元から BOM 付 UTF-16BE である場合は変換しない。さらにこの場合、“特定のキー”(/Author*1)に限ってその値を変換対象に選ぶ。
  • ToUnicode ありの xdvipdfmx は ToUnicode ありの dvipdfmx と全く同じ動作になる。

蛇足。

  • 今回の TeX 文書の場合、upTeX と XeTeX の出力する DVI/XDV はほとんど同じになる。ただ一箇所だけ本質的に異なるのは、後者には「pdf:pagesize default」という“暗黙の special 命令”が出力されていること。*2
  • 今回は“内部が Unicode”の 2 つのエンジンを使って、その結果、DVI/XDV の special は UTF-8 で出力された。
  • ここで“入力の”文字コードだけ変えて((upTeX では -kanji オプション、自動判定、\epTeXinputencoding 命令、XeTeX では \XeTeXinputencoding 命令によって変えられる。))も、出力される DVI/XDV には影響しないので、PDF も中身も同じになる。
  • 内部の文字コードが違う(例えば、内部が sjispTeX を使う)場合は状況が違ってくるが、「どの値が変換対象になるか」は同じである。(ToUnicode の原理が解ってれば結果は容易に予想できる。)

*1:dvipdfmx のソースコード中で決め打ち。

*2:もちろん、これがあるため内部オフセット値も異なっている。