知りませんでした。解決法を教えて下さると助かります。
dvipdfmx のグリフ名読込の処理に不具合があると思われます。
read_v2_post_names() 関数]
indices = NEW(post->numberOfGlyphs, USHORT);
post->count = 0;
for (i = 0;
i < post->numberOfGlyphs; i++) {
idx = sfnt_get_ushort(sfont);
if (idx >= 258) {
if (idx > 32767) {
/* Although this is strictly speaking out of spec, it seems to work
and there are real-life fonts that use it.
We show a warning only once, instead of thousands of times */
static char warning_issued = 0;
if (!warning_issued) {
WARN("TrueTypes post table name index %u > 32767", idx);
warning_issued = 1;
}
/* In a real-life large font, (x)dvipdfmx crashes if we use
nonvanishing idx in the case of idx > 32767.
If we set idx = 0, (x)dvipdfmx works fine for the font and
created pdf seems fine. The post table may not be important
in such a case */
idx = 0;
}
post->count++;
}
indices[i] = idx;
}
(以下、某ブログ記事の用語に従う。)
上の処理では「独自グリフ名のリスト」の長さ(post->count)を「グリフ名インデクスの値が 258 以上であるグリフの個数」と一致していると仮定しています。確かに、「独自グリフ名のリスト」にある名前が全部残らず用いられている(旧版の IPAex フォントではこれが成り立つ)ならその仮定が成り立ちますが、新しい IPAex フォントでは成立していません(「独自グリフ名のリスト」はインデクス 12511 相当まであるが、12499(GID12230)はどのグリフでも使われていない。)そのせいで、「独自グリフ名のリスト」が途中までしか読み込まれず、「グリフ名インデクスが有効範囲を超えている」と誤って判定されています。
「独自グリフ名のリスト」を本当に最後まで読みきろうとすると、post テーブルの末端を把握する必要があります。(今のコードではしていない。)しかし、今の場合、「実際に使われているグリフ名インデクスの最大値」を求めて、「最大値 + 1 − 258」を「独自グリフ名のリスト」の長さとすれば十分なはずです。
ありがとうございます。以下で動いています。
int maxidx = 257;
for (i = 0; i < post->numberOfGlyphs; i++) {
idx = sfnt_get_ushort(sfont);
if (idx >= 258) {
if (idx > maxidx)
maxidx = idx;
if (idx > 32767) {
/* Although this is strictly speaking out of spec, it seems to work
and there are real-life fonts that use it.
We show a warning only once, instead of thousands of times */
static char warning_issued = 0;
if (!warning_issued) {
WARN("TrueTypes post table name index %u > 32767", idx);
warning_issued = 1;
}
/* In a real-life large font, (x)dvipdfmx crashes if we use
nonvanishing idx in the case of idx > 32767.
If we set idx = 0, (x)dvipdfmx works fine for the font and
created pdf seems fine. The post table may not be important
in such a case */
idx = 0;
}
}
indices[i] = idx;
}
post->count = maxidx - 257;