投稿者 魔界の仮面弁士  (社会人) 投稿日時 2021/11/13 12:51:51
> ★でエラーになります。
エラーになっているというより、エラーにしている箇所ですね。

より正確に言えば、「DSIG テーブルが存在しないときに、エラー扱いにしている」ものです。
DSIG とは Digital Signature。OpenType フォントのデジタル署名です。

署名の有無はこの後の解析に使用していないと思いますし、ここは単純に
 If dsigTag <> &H44534947 AndAlso dsigTag <> 0 Then  '🟨
へと変更すればよいと思います。


> 何か御存じでしたら、教えて頂きたいです。
フォント仕様については全く知りませんでしが、少し調べてみたらわかりました。
それぞれの処理の意味が分かれば、VBA でも VB.NET でも解析できますね。

構造仕様については下記を参照してみてください。
https://nazuna.sakura.ne.jp/wiki/index.php/TTC
https://docs.microsoft.com/en-us/typography/opentype/spec/otff


まずは C:\Windows\Fonts\mingliub.ttc をバイナリ エディターで開いてみます。

OpenType フォントの解析作業には、フォントの最上位テーブルのディレクトリ🔵である
TableDirectory を探ることが重要です。

フォントが 1 つしかない場合は、ファイルの先頭 0 バイト目から記されるようですが
複数のフォントを含むコレクションファイルの場合は、ファイルの先頭に TTCHeader と
いうものが置かれており、そこにそれぞれのフォントの TableDirectory の位置が記載されるとのこと。

ということで、まず大事なのは最初の 4 バイトでの識別ですが、
今回は TTC ヘッダー Version 2.0 がファイルの先頭に書かれていました。
そこから「3 つの TrueType フォントがこの 1 ファイルに含まれている」🟢と分かります。
つまり、Gekka.Text.Font.TrueType.TTC.Read(fontFile).Count も 3 になる想定。


位置      : バイナリ     : 説明
--------- : ------------ : --------------------------------------
0000-0003 : 74,74,63,66  : ttcTag = "ttcf"。TTC(True Type Collection)ヘッダー識別用の固定 ID です。
0004-0005 : 00,02        : majorVersion = 2。TTC ヘッダーの major version です。(1 または 2)
0006-0007 : 00,00        : minorVersion = 0。TTC ヘッダーの minor version です。
0008-000B : 00,00,00,03  : numFonts = 3。 3 個の TableDirectory 🔵 が含まれていることを意味します。
000C-000F : 00,00,00,24  : TableDirectory[0] が、0024 の位置から開始されます。(ファイル先頭を 0 とする位置)
0010-0013 : 00,00,01,50  : TableDirectory[1] が、0150 の位置から開始されます。
0014-0017 : 00,00,02,7C  : TableDirectory[2] が、027C の位置から開始されます。
 TTC ヘッダー 1.0 ならここまでですが、今回は TTC ヘッダー 2.0 なので
 この後に DISG テーブルの情報が 12 バイト分続きます。
0018-001B : 00,00,00,00  : dsigTag = null。DSIG テーブルの有無を示すタグ🟨です。
                         : ここが 0x44534947 (String の "DSIG")であれが「存在する」
                         : ここが 0x00000000 であれば「存在しない」ということです。
                         : Gekka さんのコードでは、電子署名の無いファイルを解析エラーにしています。
001C-001F : 00,00,00,00  : dsigLength = 0。DSIG テーブルの長さを表します。
                         : ただし dsigTag = 0x44534947 の時は未使用(0x00000000)です。
0020-0023 : 00,00,00,00  : dsigOffset = 0。DSIG テーブルの位置を表します。(ファイル先頭を 0 とする位置)
                         : ただし dsigTag = 0x44534947 の時は未使用(0x00000000)です。
 TTC ヘッダー 2.0 はここまでです。
 ここからは TableDirectory[0] 🔵の内容です。
0024-0027 : 00,01,00,00  : version = 0x00010000。OpenType フォントのバージョン情報です。
                         : 0x4F54544F("OTTO") なら CFF/PostScript アウトラインを含む OpenType フォント
                         : 0x00010000 の場合は TrueType アウトラインを含む OpenType フォントです。
                         : Apple仕様の TrueType フォントである 0x74727565("true") や
                         : 0x74797031("typ1") は使うことができないようです。知らんけど。
0028-0029 : 00,12        : numTables = 0x12。つまり、18 個の TableRecord テーブルがあるということです。
002A-002B : 01,00        : searchRange = 0x100。「numTables 以下の最大の 2 の累乗値」を 16 倍した値です。
                         : numTables = 10 なら、2³≦numTables<2⁴ なので 2³*16 = 0x0030 が記録されます。
                         : numTables = 18 ゆえ、2⁴≦numTables<2⁵ なので 2⁴*16 = 0x0100 が記録されます。
                         : numTables = 32 なら、2⁵≦numTables<2⁶ なので 2⁵*16 = 0x0200 が記録されます。
002C-002D : 00,04        : entrySelector = 0x0004。「numTables 以下の最大の 2 の累乗値」の二進対数値です。
                         : numTables = 10 なら、Log₂(2³) となるため 3 が記録されます。
                         : numTables = 18 なら、Log₂(2⁴) となるため 4 が記録されます。
                         : numTables = 32 なら、Log₂(2⁵) となるため 5 が記録されます。
002E-002F : 00,20        : rangeShift = 0x0020。「numTables * 16 - searchRange」です。
                         : searchRange, entrySelector, rangeShift の値は、テーブル検索用の
                         : パラメータなので、解析時には使わなくても問題ありません。
0030-014F : (省略)       : TableRecord [0..numTables] な配列データが続きます。
 ここまでが TableDirectory[0] の内容です。残りは同様。
0150- は TableDirectory[1] 🔵で、テーブル数が 0x12 個の TrueType と記録されています。
0280- は TableDirectory[2] 🔵で、テーブル数が 0x12 個の TrueType と記録されています。