チケット #28187

登録: 2012-04-27 21:19

最終更新: 2016-06-18 18:02

SumatraPDFでRyumin-LightがMSゴシックになる

報告者:abenori担当者:(未割り当て)
優先度:5 - 中マイルストーン:(未割り当て)
チケットの種類:バグ重要度:5 - 中
コンポーネント:(未割り当て)状況:完了
解決法リマインド

チケットの詳細

バグ……じゃないかもしれませんが. LuaTeX-jaでフォント非埋め込みのPDFをSumatraPDFで開くとフォントがすべてMSゴシックになります. SumatraPDFのソースを見ると,

if(fontdesc->flags & PDF_FD_SERIF)serif = 1;
とあって,serifが1だとMS明朝,そうでなければゴシックが選ばれるようです.(ちなみにPDF_FD_SERIF = 2)

kmaedaさんに教えてもらったことによれば,ほとんどハードコーティングされているらしいので,この値を変更するのは難しいようです.がんばればできる可能性があるかもしれませんが,LuaTeX-jaががんばるのはお門違いな気もします.

どうするのがよいでしょう?

以下kmaedaさんに教えてもらったことです.

writefont.w の do_pdf_font() ですが,ここに font_encodingbytes(f) が 2 だったら仮想的な font map entry を作るという処理が書いてあります. そして,

fm->fd_flags = 4; /* can perhaps be done better */

となっています.

となると,次に考えられるのは ltj-rmlgbm.lua で fontdata.encodingbytes=1 とやって,適切なマップファイルを与えてやることなんですが,さてどうすればよいのでしょうか(そもそもできるのか)?

添付ファイル

添付ファイルリスト
luatex-twobyte-fdflags.patch (3KB)
h7k によって 2012-04-28 13:07 に登録されました [File ID: 4728]
ファイルの説明: fd_flags についての適当なパッチ
luatex-twobyte-mapline.patch (1KB)
kmaeda によって 2012-04-29 02:41 に登録されました [File ID: 4729]
ファイルの説明: encodingbytes==2 なフォントの fd_flags を pdf.mapline() で指定するためのパッチ
新規添付ファイル追加
添付ファイルの追加添付ファイルの追加にはログインが必要です

チケットの履歴 - 17 件中 3 件表示 [古い履歴も表示する]

2012-04-27 21:19 更新者: abenori

  • 新しいチケット "SumatraPDFでRyumin-LightがMSゴシックになる" が作成されました

2012-04-27 23:33 更新者: h7k

コメント

「調べる」とかいっといて,全然実際に調べてないですが……,

次に考えられるのは ltj-rmlgbm.lua で fontdata.encodingbytes=1 とやって,適切なマップファイルを与えてやる

これってできるのかなあ.writefont.w 中の do_pdf_font() を見ると,

if (font_encodingbytes(f) == 2) {
...
  set_cidkeyed(fm);
  create_cid_fontdictionary(pdf, f);
...
} else {
  /* by now |font_map(f)|, if any, should have been set via |pdf_init_font()| */
  if ((fm = font_map(f)) == NULL
    || (fm->ps_name == NULL && fm->ff_name == NULL))
    writet3(pdf, f);
  else
    create_fontdictionary(pdf, f);
}
とあり,じゃあ,create_fontdictionary() はどうなっているか,というと
static void create_fontdictionary(PDF pdf, internal_font_number f)
{
    fo_entry *fo = new_fo_entry();
    fm_entry *fm = font_map(f);
    get_char_range(fo, f);      /* set |fo->first_char| and |fo->last_char| from |f| */
    if (fo->last_char > 255)
        fo->last_char = 255;    /* added 9-4-2008, mantis \#25 */
のように lasr_char <=255 制限があるので,うまくいかないという直感が.

本家に素直に機能をリクエストしてみるのがよいと思います.

2012-04-27 23:56 更新者: kmaeda

コメント

lasr_char <=255 制限があるので,うまくいかないという直感が.

あのコメントを書いた時点でその手の問題があってうまく動かないのではないか,と思っていたのですが,やはりその可能性が高いのですね.

リクエストをするなら,どう書きましょうかね…….

2012-04-28 13:07 更新者: h7k

  • 添付ファイル luatex-twobyte-fdflags.patch (File ID: 4728) が付加されました

2012-04-28 13:14 更新者: h7k

コメント

luatex-twobyte-fdflags.patch として,font.fonts[n]fdflags フィールドを追加するパッチを作ってみました.本来はencodingbytes=1 の場合も考慮しないといけないのかもしれませんが,よくわからないのでそっちの場合は放置してあります.デフォルト値は FD_FLAGS_DEFAULT_TWOBYTES (=4) とし,動作をあわせています.

このパッチ適用後,ltj-rmlgbm.lua で fontdata.fdflags = 6 をしたら,きちんと /Flags 6 になってくれました.

2012-04-28 19:21 更新者: abenori

コメント

luatex-twobyte-fdflags.patch として,font.fonts[n]fdflags フィールドを追加するパッチを作ってみました.

すばらしいです.こいつを本家に送りつける,というのがよいでしょうか.encodingbytes=1の時をきちんと考えるべき?

2012-04-28 20:07 更新者: kmaeda

コメント

encodingbytes=1の時

encodingbytes=2 のときしか効かないよ,でもいいかもしれませんが,encodingbytes の値によらず効く仕様となると, fdflags フィールドのデフォルト値は -1 (nil でもいい?)などの「未設定」にしておいて, 設定されているときは従来の仕様で決定される値を上書きする,というのが自然ではないでしょうか. encodingbytes=1 のときにマップファイルなどで決まる値を優先となると,設定できる意味がないですし.

2012-04-28 20:43 更新者: kmaeda

コメント

fdflags フィールドのデフォルト値は -1 (nil でもいい?)などの「未設定」にしておいて

ああ,でもフォントのテーブルの初期値から encodingbytes=1 のフォントの fdflags の値を得たい,ということも考えられますね. そもそもそういう使い道があるのかどうか知りませんけれども.

# この機能の CJK フォント非埋め込み以外の用途を知らないので適当なことを書いています.

2012-04-28 21:30 更新者: h7k

コメント

fdflags フィールドのデフォルト値は -1 (nil でもいい?)などの「未設定」にしておいて

フォントのテーブルの初期値から encodingbytes=1 のフォントの fdflags の値を得たい

たぶんそれは厳しそう.フォントに対して pdf/pdffont.w 中の pdf_init_font() でマップファイルとの対応をつける (font_map(f) = fm;) ようですが,それはページが shipout される時(or 後?)に行われるようです.あくまでも「-1: 自動設定のまま」とすることになる?

1バイトフォントだと,pdfTeX の段階で fd_flags を

\pdfmapline{=ptmri8r Times-Italic 66<8r.enc <utmri8a.pfb}
(Lua からなら pdf.mapline())と指定できるのが中途半端なところです.

2012-04-28 22:20 更新者: h7k

コメント

「TeX の内部フォント番号は違うが,実フォントは同じ」場合を考えると,今のままでは怪しいことがわかってきました.

安直に font.fonts[].fdflags のデフォルト値を -1 とし,writefont.w 中の create_fontdictionary() に

    fm_entry *fm = font_map(f);
+   fm->fd_flags = (font_fd_flags(f) != FD_FLAGS_NOT_SET_IN_MAPLINE) ?
+       font_fd_flags(f) : fm->fd_flags;
のような変更をしてみました.

そして,以下のソースを走らせ,PDF 中で実際にどうなっているかを調べました:

\pdfcompresslevel=0
\input luaotfload.sty
\pdfmapline{=ptmri8r Times-Italic 42<8r.enc <utmri8a.pfb}
\pdfmapline{=ptmr8r Times-Roman   42<8r.enc <utmr8a.pfb}
\pdfmapline{=ptmb8r Times-Bold    42<8r.enc <utmr8a.pfb} % 実フォントだけ共通

\directlua{local dr_orig = fonts.define.read
function fonts.define.read(name, size, id)
  local a = dr_orig(name, size, id)
  if math.floor(id/2)*2==id then a.fdflags=id*2 end
  return a
end}

\font\g=ptmri8r\g a         % id: 51 => -1
\font\h=ptmr8r\h b          % id: 52 => 104
\font\a=ptmr8r at 14pt\a b  % id: 53 => -1
\font\b=ptmb8r at 14pt\b b  % id: 54 => 108
\font\c=file:ipam.ttf at 12pt\c b  % id: 55 => -1
\font\d=file:ipam.ttf at 14pt\d b  % id: 56 => 108

%\directlua{
%for i,v in font.each() do
%  if i>=51 then print(' >>> : ',i,font.fonts[i].fdflags) end
%end}
\end
すると,IPA 明朝と utmr8a.pfb について
<</Type/FontDescriptor/FontName/EHDIYH+IPAMincho/Flags 4/FontBBox[0 -96 1000 773]/Ascent 773/CapHeight 750/Descent -96/ItalicAngle 0/StemV 86/XHeight 524/FontFile2 14 0 R/CIDSet 13 0 R>> % 7 0 obj
<</Type/FontDescriptor/FontName/SANKRU+NimbusRomNo9L-Regu/Flags 108/FontBBox[-168 -281 1000 924]/Ascent 690/CapHeight 690/Descent -209/ItalicAngle 0/StemV 85/XHeight 461/CharSet(/b)/FontFile 24 0 R>> % 27 0 obj
という結果になりました.「fdflags と実際に PDF で使われる値が食い違う」症状が起きていることになります.

一番いいのは mapline が2バイトフォントに対応してくれることですが…….

2012-04-29 02:41 更新者: kmaeda

  • 添付ファイル luatex-twobyte-mapline.patch (File ID: 4729) が付加されました

2012-04-29 02:48 更新者: kmaeda

コメント

「TeX の内部フォント番号は違うが,実フォントは同じ」場合

そうか,psname(psname がなければ fullname)が同じフォントは出力 PDF では1つのフォントとして扱われてしまうんでしたっけ. となると,単純にフォントのテーブルに fdflags フィールドを追加するのはよろしくない,ということになりますかね.

一番いいのは mapline が2バイトフォントに対応してくれることですが…….

無思慮な危ないパッチを作ってみました (luatex-twobyte-mapline.patch).今のところ Flags 以外は無視しています. "ExtendFont" とか "SlantFont" とかいうのも扱うべきなのだろうか(これらはフォントテーブルに対応するパラメータがあるのだけれども).

\documentclass{ltjsarticle}
\pdfcompresslevel=0
\usepackage{luacode}
\begin{luacode}
local dr_orig = fonts.define.read
function fonts.define.read(name, size, id)
    f = dr_orig(name, size, id)
    if type(f) == 'table' and f.embedding == 'no' then
        pdf.mapline(f.name .. ' ' .. f.psname .. ' 6')
    end
    return f
end
\end{luacode}
\begin{document}
\large % 再定義後の fonts.define.read で Ryumin-Light を定義させる
あ
\end{document}

もはや map とか関係ない使い方な気がしますが,一応これで /Flags 6 になっていると思います.

2012-04-29 03:04 更新者: kmaeda

コメント

おっと,なんか CMR10 が Type 3 になってるなぁ,と思っていたら,サンプルコード中の pdf.mapline() 引数先頭の = が抜けていました.

-        pdf.mapline(f.name .. ' ' .. f.psname .. ' 6')
+        pdf.mapline('=' .. f.name .. ' ' .. f.psname .. ' 6')

2012-04-29 08:44 更新者: h7k

コメント

"ExtendFont" とか "SlantFont" とかいうのも扱うべきなのだろうか(これらはフォントテーブルに対応するパラメータがあるのだけれども).

マップ中の SlantFont と font.fonts[].slant の関係を見ていたら,これも「pdf_init_font 実行後に値が変わる」ようです.

%#!luatex
\pdfmapline{=ptmr8r Times-Roman ".5 SlantFont" <8r.enc <utmr8a.pfb}
\font\g=ptmr8r\g aiueo
\font\h=ptmb8r\h aiueo % 比較用
%\vfill\eject
\directlua{
for i,v in font.each() do
  if i>=51 then print(' >>> : ',i,font.fonts[i].slant, font.fonts[i].fdflags) end
end}
\end

上のソースで \vfill\eject の有無で,font.fonts[51].slant の値が変わります.


なお,dvipdfmx には,tt_aux.c

  /* Flags */
  if (os2->fsSelection & (1 << 0))
    flag |= ITALIC;
  if (os2->fsSelection & (1 << 5))
    flag |= FORCEBOLD;
  if (((os2->sFamilyClass >> 8) & 0xff) != 8)
    flag |= SERIF;
  if (((os2->sFamilyClass >> 8) & 0xff) == 10)
    flag |= SCRIPT;
  if (post->isFixedPitch)
    flag |= FIXEDWIDTH;
というコードがあります.


ここで悩むより,とにかく「2バイトフォントの fd_flags を 4 以外にできない?」と上流に投げた方が早く解決される……かな?

2012-04-30 05:47 更新者: abenori

コメント

ここで悩むより,とにかく「2バイトフォントの fd_flags を 4 以外にできない?」と上流に投げた方が早く解決される……かな?

さんせーい.

2015-10-18 10:11 更新者: h7k

  • 解決法なし から リマインド に更新されました

2016-06-18 18:02 更新者: h7k

  • チケット完了時刻2016-06-18 18:02 に更新されました
  • 状況オープン から 完了 に更新されました

コメント

症状自体は直っていないと思いますが,標準和文フォントが IPAex になったので実際に問題になる場面は少ないと思います.


追記/更新 #28187 (SumatraPDFでRyumin-LightがMSゴシックになる)

ログインしていません。ログインしていない状態では、コメントに記載者の記録が残りません。 » ログインする