Japanese OCF Emulation:
日本語OCFフォントをCID-keyedフォントから再構成する

[Back] [2001/12/13新規] [2002/1/7,8,2/1更新]

目的および立場

  1. オペレータ (begin|end)rearrangedfont が gs|gs-cjk に実装されてない現在、OCF サポートは当面必要である
  2. オペレータ (begin|end)rearrangedfont が gs|gs-cjk に実装されたとしても、GNU/Linux ディストリビューションの中には、Adobe-official CMap なしに、日本語 PostScript 印刷を可能にする方策を求める声が存在する
    1. VFlib-patched gs (+gs-cjk)を使って欲しい。が、しかし、
    2. gs-cjk でもそのような声に答えることに最善を尽くしたい → CIDFont による OCF 構成
  3. Adobe-official CMap なしにどこまで出来るか [2002/1/1] → -H|V, -EUC-H|V, -RKSJ-H|V
  4. Adobe-official CMap を使う場合、どこまで出来るか、どこまでやるべきか [2002/1/1] → -Ext-H|V, -Ext-EUC-H|V, -Ext-RKSJ-H|V, -78-H|V, -78-EUC-H|V, -78-RKSJ-H|V
  5. OCF フォントは Adobe 公式には、日本語フォントのみ存在するので、ここでの試みはとりあえず Japanese ユーザのみをターゲットとする。しかし、非公式には、韓国語、中国語(簡体字・繁体字)のフリーフォント・商用OCFフォントは実在する。

配布

成果報告および解説

[2002/2/1] 疑似CMapデータを裁断する際、O(N) の計算量を要していた箇所を、O(log N)で済むように大幅に修正致しました。よって、インタプリタがフォント定義ファイルを読み込む際の速度が向上しております。

また、OCFを構成する際に用いられる、いわゆる.notdeffontを、以前はFontType3で作成しておりましたが、他のフォント要素と同じくFontType0 FMapType9で作成するようにしました。よって、構成されたOCFフォントで想定されていないコード領域を印字した場合の挙動が、素のCID- keyedフォントでの挙動と同等になったと思います。

[2002/1/7] 「日本語OCFフォントをCID-keyedフォントから再構成する試み」が、一応成功したみたいなので、ここで報告します。[2002/1/8追記] PostScript3 プリンタにこれらのフォント定義を送り込んで印字させてもきちんと使えているようなので、特に大きな問題はないと思います。

下記の表にあるように、使用頻度を鑑みて、Adobe-official CMapがなくてもOCFとして動作するように作成したのもあります。もっとも、現状のgs-cjkではTrueTypeフォントをCIDFontとしてを使う場合はAdobe-official CMapは必須です。よって、完全にofficial CMapなしに済ますには、Kochi CIDフォントのようなnative CIDFont(CIDFontType0, CFF OpenType等)を使う必要があります。

使い方は簡単で、gs|gs-cjkにおいて、Ryumin-Light CIDFontが(もしくは別名としてそれが)存在すれば、以下に示すファイルをgsのfontsもしくはResource/Fontに置けばすぐに使えるようになります。

FontName                Adobe-official CMap     FMapType及び摘要
--------                ----------------        ------------------------
Ryumin-Light-H|V                不要            2
Ryumin-Light-EUC-H|V            不要            2
Ryumin-Light-FMap5-EUC-H|V      不要            5       gsで動かない!
Ryumin-Light-RKSJ-H|V           不要            6, 2
Ryumin-Light-83pv-RKSJ-H        不要            6, 2
Ryumin-Light-78-H|V             必要            2
Ryumin-Light-78-EUC-H|V         必要            2
Ryumin-Light-78-RKSJ-H|V        必要            6, 2
Ryumin-Light-Ext-H|V            必要            2
Ryumin-Light-Ext-EUC-H|V        必要            5       gsで動かない!
Ryumin-Light-Ext-RKSJ-H|V       必要            6, 2
Ryumin-Light-NWP-H|V            必要            2
------------------------------------------------------------------------

配布アーカイブには、それぞれに対応するGothicBBB-Medium-*も同梱されています(他に必要なエンコーディングの種類等があればご連絡下さい)。

また、FMapType5で構成されたOCF(Ryumin-Light-FMap5-EUC-H|V, Ryumin-Light-Ext-EUC-H|V)は、現在[2002/1/7]のgs|gs-cjkでは正しく動作しません。

次に、典型的な2例の、CIDFontで構成されたOCFの構造を以下に示します。

[ISO2022 94^2コードセット系]
------------------------------------------------------------------------
Ryumin-Light-H          FontType 0      FMapType 2      FDepVector [
  .notdeffont           FontType 0	FMapType 9(nil CMap)
  Ryumin-Light-H21      FontType 0      FMapType 9
        :
  Ryumin-Light-H28
  Ryumin-Light-H30
        :
  Ryumin-Light-H74
]
------------------------------------------------------------------------
[ShiftJIS系]
------------------------------------------------------------------------
Ryumin-Light-RKSJ-H             FontType 0      FMapType 6      FDepVector [
  Ryumin-Light-RKSJ-HS00        FontType 0      FMapType 9
  .notdeffont                   FontType 0	FMapType 9(nil CMap)
  Ryumin-Light-RKSJ-H81-9F      FontType 0      FMapType 2      FDepVector [
    Ryumin-Light-RKSJ-H81       FontType 0      FMapType 9
        :
    Ryumin-Light-RKSJ-H84
    Ryumin-Light-RKSJ-H88
        :
    Ryumin-Light-RKSJ-H9F
  ]
  Ryumin-Light-RKSJ-HSA0        FontType 0      FMapType 9
  Ryumin-Light-RKSJ-HE0-EA      FontType 0      FMapType 2      FDepVector [
    Ryumin-Light-RKSJ-HE0       FontType 0      FMapType 9
        :
    Ryumin-Light-RKSJ-HEA
  ]
  .usrdeffont           FontType 0	FMapType 9(nil CMap)      (=.notdeffont)
  .notdeffont           FontType 0	FMapType 9(nil CMap)
] SubsVector <00 80 01 1f 40 10 0c>
------------------------------------------------------------------------

このように、伝統的なJapanese OCFとほぼ同等の構成になっております。

この「CID-keyedフォントからOCFフォントの再構成」の技術は、片山氏のfixeucfont[1]を参考にさせて頂きましたが、fixeucfontでは、FontType3でCIDFont+CMap composefont (or OCF)をくるんでそれをデセンダフォントとして構成しており、一方こちらは、CIDFont+CMap composefontそのものをデセンダフォントとしています。理由は単に目的の違いですが、そのため、いわゆるひとつのCMapデータセットをコードレンジ毎に『裁断』して、Subset CMapデータ群を作成しています。上で示した例で言えば、「RKSJ-HS00, RKSJ-H81 .. RKSJ-H9F, RKSJ-HSA0」は真にCMap辞書の名前を表しています。伝統的なJapanese OCFのベースフォント名ではこれらは、「Roman, sr81 .. sr9F, SuppK」というようなサフィックスに対応しています。

もっとよい方法があるかもしれませんが、「もしJapanese以外のOCF再構成の要望があったら?」という懸念材料があったので、そのようなプログラム構造になってしまっています。よって、Japanese以外や他のエンコーディングへ応用したければ、Ryumin-Light-78-H|Vを改造すれば、それほど難しくなく他の言語等に応用できると思います。[2002/2/1追記] さらにその「汎用性」を徹底しました。ここで用いられている疑似CMapのパーサに、usual Adobe CMapのすべてを処理させても問題がないようなので、Japanese以外でのOCF emulationにも簡単に応用できるようになったと思います。

技術メモ

  1. [2002/2/1] 疑似CMapデータ処理に、簡易的に「2分探索木」を採用しました。まじめになるならより良い手法は他にあるのですが、このテーマではここまででよいでしょう。
  2. CID空間での標準CMap CIDsの連続性の調査
    [2002/1/1] 案の定、-H|V, -EUC-H|V, -RKSJ-H|V のコードとCIDsの関係は、ほぼ連続性が仮定できるので、その関係をフォントファイルに埋め込むのは容易である。一方、それ以外の -78- H|V や -Ext-H|V は Adobe-official CMap なしにはその関係を得ることは面倒である。
  3. 各種OCFのFMapType, Encodingの調査
  4. FontName        possible FMapType       possible Encoding       possible (SubsVector and/or)FDepVector
    --------        --------                --------                --------
    -78-EUC-H       5                       JIS12-97-CF             no, r21..r28, 78.r30..78.r73, no
    -78-EUC-V       5                       JIS12-97-CF             same above except for r21v, r24v, r25v
    -78-H           2                       JIS12-88-CF             no, r21..r28, 78.r30..78.r73, no
    -78-V           2                       JIS12-88-CF             same above except for r21v, r24v, r25v
    -78-RKSJ-H      6                       [0 1 2 3 4 5 6]         (00 80 01 1F 40 10 0C).Roman, no, -78-SuppA-H, .SuppK, -78-SuppB-HV, UserGaiji, no
    -78-RKSJ-V      6                       [0 1 2 3 4 5 6]         same above except for -78-SuppA-V
    -78-SJ-H        2                       ShiftJIS12-88-CF        no, sr81..sr84, 78.sr88..78.srEA
    -78-SJ-V        2                       ShiftJIS12-88-CF        same above except for sr81v..sr83v
    -78-SuppA-H     2                       ShiftJIS-A-CF           no, sr81..sr84, 78.sr88..78.sr9F
    -78-SuppA-V     2                       ShiftJIS-A-CF           same above except for sr81v..sr83v
    -78-SuppB-HV    2                       ShiftJIS-B-CF           78.srE0..78.srEA
    -83pv-RKSJ-H    6                       [0 1 2 3 4 5 6]         (00 80 01 1F 40 10 0C)A Roman, no, -83pv-SuppA-H, .SuppK, -83pv-SuppB-H, UserGaiji, no
    -83pv-SuppA-H   2                       ExtShiftJIS-A-CF        no, sr81..sr84, Ext.sr85..Ext.sr88, sr89..sr9F
    -83pv-SuppB-H   2                       [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0] no, srE0..srEA, sr81v..sr83v, Ext.sr87v
    -EUC-H          5                       JIS12-97-CF             no, r21..r28, r30..r74
    -EUC-V          5                       JIS12-97-CF             same above except for r21v, r24v, r25v
    -Ext-EUC-H      5                       ExtJIS12-97-CF          maybe complex
    -Ext-EUC-V      5                       ExtJIS12-97-CF          maybe complex
    -Ext-H          2                       ExtJIS12-88-CF          maybe complex
    -Ext-V          2                       ExtJIS12-88-CF          maybe complex
    -Ext-RKSJ-H     6                       [0 1 2 3 4 5 6]         (00 80 01 1F 40 10 0C).Roman, no, -Ext-SuppA-H, .SuppK, -Ext-SuppB-HV, UserGaiji, no
    -Ext-RKSJ-V     6                       [0 1 2 3 4 5 6]         same above except for -Ext-SuppA-V
    -Ext-SJ-H       2                       ExtShiftJIS12-88-CF     maybe complex
    -Ext-SJ-V       2                       ExtShiftJIS12-88-CF     maybe complex
    -Ext-SuppA-H    2                       ExtShiftJIS-A-CF        maybe complex
    -Ext-SuppA-V    2                       ExtShiftJIS-A-CF        maybe complex
    -Ext-SuppB-HV   2                       ShiftJIS-B-CF           maybe complex
    -H              2                       JIS12-88-CF             no, r21..r28, r30..r74
    -V              2                       JIS12-88-CF             same above except for r21v, r24v, r25v
    -NWP-H          2                       ExtJIS12-88-CF          maybe complex
    -NWP-V          2                       ExtJIS12-88-CF          maybe complex
    -RKSJ-H         6                       [0 1 2 3 4 5 6]         (00 80 01 1F 40 10 0C).Roman, no, -SuppA-H, .SuppK, -SuppB-HV, UserGaiji, no
    -RKSJ-V         6                       [0 1 2 3 4 5 6]         same above except for -SuppA-V
    -SJ-H           2                       ShiftJIS12-88-CF        no, sr81..sr84, sr88..sr9F, srE0..srEA
    -SJ-V           2                       ShiftJIS12-88-CF        same above except for sr81v..sr83v
    -SuppA-H        2                       ShiftJIS-A-CF           no, sr81..sr84, sr88..sr9F
    -SuppA-V        2                       ShiftJIS-A-CF           same above except for sr81v..sr83v
    -SuppB-HV       2                       ShiftJIS-B-CF           no, srE0..srEA
    --------  

    (注) Level2日本語PostScriptプリンタから見えるfonts/*, Resource/Encoding/*資源のファイル名、及び、VFlib-patched gsから見えるfonts/*資源のファイル名を参考にしてます。

    Encoding        
    --------        
    JIS12-88-CF     [
                      16#00 1 16#20 { pop 0 } for
                      16#21 1 16#28 { 16#20 sub } for
                      16#29 1 16#2F { pop 0 } for
                      16#30 1 16#74 { 16#27 sub } for
                      16#75 1 16#FF { pop 0 } for
                    ]
    JIS12-97-CF     [
                      16#00 1 16#20 { pop 0 0 } for
                      16#21 1 16#28 { 16#20 sub 0 exch } for
                      16#29 1 16#2F { pop 0 0 } for
                      16#30 1 16#74 { 16#27 sub 0 exch } for
                      16#75 1 16#FF { pop 0 0 } for
                    ]
    ShiftJIS-A-CF   [
                      16#81 1 16#84 { 16#80 sub } for
                      16#85 1 16#87 { pop 0 } for
                      16#88 1 16#9f { 16#83 sub } for
                    ]
    ShiftJIS-B-CF   [
                      16#e0 1 16#ea { 16#df sub } for
                      16#eb 1 16#ef { pop 0 } for
                    ]
    ExtJIS12-88-CF  [
                      16#00 1 16#20 { pop 0 } for
                      16#21 1 16#74 { 16#20 sub } for
                      16#75 1 16#FF { pop 0 } for
                    ]
    ExtJIS12-97-CF  [
                      16#00 1 16#20 { pop 0 0 } for
                      16#21 1 16#74 { 16#20 sub 0 exch } for
                      16#75 1 16#FF { pop 0 0 } for
                    ]
    ShiftJIS-A-CF   [
                      16#81 1 16#9f { 16#80 sub } for
                    ]
    --------  

    (注) VFlib-patched gsのソースを参考にしてます。

参考文献

  1. 片山 紀生, ``fixeucfont,'' http://research.nii.ac.jp/~katayama/homepage/fixeucfont/, Oct 1999.
  2. Adobe Systems (野中 浩一 訳), ``ページ記述言語 PostScript チュートリアル&クックブック,'' アスキー出版局, pp. 241--271, Jun 1989.
  3. Ken Lunde, ``CJKV Information Processing,'' O'Reilly, pp. 281--335, Jan 1999.
    この文献のこのページの範囲の中に、OCF, CID-keyedフォントに関わる大切な情報が書いてあります。が、OCFとCID-Keyedフォントを両立させる方法等に関してはなんら触れられていません。やはり OCF フォントは obsolete なのでしょう。
  4. suzuki toshiya and gs-cjk project, ``gs/doc/CJK.htm: Features to support CJK CID-keyed font in Ghostscript,'' gs-cjk-merged GNU Ghostscript documents, Dec 2001.
    gs-cjk projectの鈴木俊哉さんが、特にCJKユーザやgs-cjkに関わるPostScriptフォントの諸情報を、このドキュメントにまとめて下さいました。この文書は、非 CJKV ghostscript の開発者やユーザへの、CJKV フォントを取り巻く諸問題のとても重要な啓蒙となることでしょう。
Copyright (C) 2001,2002 Taiji Yamada and gs-cjk project.