ぱるちのものおき2.0

主にLaTeXや数学のお話をするブログです。

(u)pLaTeXでMSゴシックを強制的に太字にした

この記事は,「(u)pLaTeXで太字を入力したい」というトライアンドエラーをまとめた日記です。

特に合成太字に関する話です。
(サムネイルの画像は記事末にあります。)

詳しい動機

TeXで太字を出力したい!という場合には\textbf{}を使えば手っ取り早いでしょう。数式ではbmパッケージの\bm{}を使えば太字にすることが出来ます。

和文の太さにもウェイトが欲しい!という人はotfパッケージをdeluxeオプションで読み込み,適切な設定をすればよいです。

ではMSゴシックを太字にしたい!という場合にはどうすればよいだろうか,という旨の質問を頂きました。

その時に僕は,「うーん,少なくとも僕にはできん!」という結論を出してしまい後悔していたのですが,今週(2020年10月15日ぐらい)になって同様の質問を頂いたこともあり,再度いろいろ調べていくことにしました。

今回はMSゴシックを太字にすることを目標にしたトライアンドエラーを,時系列順にまとめました。

前提:仮定している環境
  • TeXLive2020
  • (u)pLaTeX
  • jsclasses

前提:TeX和文フォント

和文フォントに関する基本的なことをおさらいしておきます。

【デフォルトでは2種類のフォントが使える】
 TeXのデフォルトでは明朝体とゴシック体の2種類のフォントが用意されます。例えばTeXLive2020以降ですと原ノ味フォントが既定に,2019以前ですとIPAフォントが既定になっています。
 いずれの場合でも〈明朝体 \mcfamily〉と〈ゴシック体\gtfamily〉の2種類のフォントが用意されています。

【フォントを気軽に指定したければPXchfon
 (u)pLaTeX の文書の標準のフォント(明朝・ゴシック)を簡単に指定できるパッケージとして,PXchfonパッケージがあります。詳しいことは PXchfon パッケージ ~pLaTeX文書のフォントを簡単に変更~ [電脳世界の奥底にて] もしくは

texdoc pxchfon

を参照しましょう。今回は,

\usepackage[noalphabet]{pxchfon}
\setminchofont[0]{msmincho.ttc} %% MS明朝
\setgothicfont[0]{msgothic.ttc} %% MSゴシック

としています。

【使えるフォントの数を増やしたければotf
 もしも2種類では飽き足らぬ,という場合は,otfパッケージをdeluxeオプションを付けて,pxchfonより先に読み込んでおきましょう。例えば自分のPCにヒラギノがインストールされている場合ですと,

\usepackage[deluxe,jis2004]{otf}
\usepackage[hiragino-pron]{pxchfon}

などとすればヒラギノの7書体*1で文書が作れます。やはりこれも上述のPXchfonパッケージのマニュアルを参照ください。


Poor Man's Bold】(合成太字)
 今回の記事における諸悪の根源です。Poor Man's Bold とは,同じフォントを3回重ね打ちして太字に見せた文字のことを言います*2
 例えばWordを使うときに,文章を太字にする[B]オプションがあります。游ゴシック Regular を[B]オプションで記述すると 游ゴシック Bold になります。

f:id:f_d0123:20201102061832p:plain
游ゴシックで作ったWord文書をpdfにエクスポートしたらこうなる

 このように[B]オプションでは,“本物の”太字フォントに置き換えてくれることが多いです。

 今度は MSゴシック を[B]オプションで太字にしようとします。しかしMSゴシックには太字フォントは存在しないため,Word が勝手に太字を作成するのです。

f:id:f_d0123:20201102062111p:plain
MSゴの場合,埋め込まれているフォントにボールド体はない

 結果として"Poor Man's Bold"と呼ばれる合成太字(貧民ボールド)でごまかしているのです。
 MSゴシックを太字にすることは禁忌と言われ,デザイン界でそれをやると追放されてしまいます(要出典)。

~~~~

ここまでの話を前提に,日記をつけていきます。

最初(2020/07)のやり取り

太字に関して最初に質問を受けたのは7月中旬です。ざっくりと質問の趣旨をまとめますと,「学会発表のために,和文フォントをMS明朝とMSゴでpdfを作成しなければならない。通常の文字はMS明朝,強調やセクションなどはMSゴの太字(ボールド文字)で作りたい。が,MSゴを太らせる方法が分からない」的な感じです。

そのときは僕の回答として,

  • そもそもMSゴシックには太字の概念が存在しない
  • Wordでは“擬似ボールド”といって,文字に文字を重ねることで太字を作っている
  • TeXで,擬似ボールドをやる方法はわからない(調べたことがない)

という回答をしました。
参考:Wordの正しい使い方 - 情報教育Wiki

当時の僕が思いついた策としては,

  • HGゴシックのボールド体を用いる(レギュレーション違反だが,見た目だけならほとんど差がない)
  • 擬似ボールドされた後のフォントファイルがあれば,それをpxchfonパッケージで読み込む

をあげましたが,改善には至っていません。

今月(2020/10/15)の話

先ほどとは別の友人とTeX関連の話をしていたとき,なんだかんだで太字の話になりました。7月の時とは違って時間に余裕があったので,TeXで太字を再現するための諸々について調べていきました。以下の知見を得ることが出来ました。

  • bmパッケージは疑似ボールドである:そもそもTeXには疑似ボールドを叶えるコマンドとして,\pmb{}コマンドがあり,それを改良したのが\bm{}です。\pmbでは,文字を3回重ねることで合成文字を得ます。\bmも同様に3回重ねることで太字を得ます。
texdoc bm
  • xfakebold.styというパッケージの存在を知る:xfakebold.styの紹介 - Qiita にて紹介されていました。このパッケージでは,縁取りを用いて文字を太くしています。また,TeXで縁取りをするためのコマンドとして,\special{}というものを知りました。\specialはdvi独自の命令をpdfに反映させるコマンドのようです。tikz.styhyperref.styでは裏で\specialが働いています。
texdoc xfakebold
縁取りを使用

今回の用途としてはゴシック体を太字にするということもあり,縁取りの方を採用することにしました。

ただしxfakebold.styをそのまま読み込むだけでは(u)pLaTeXでは使えませんので,少し工夫しなければなりません。

xfakebold.sty を (u)pLaTeX + dvipdfmx に対応させてみた - TeX Alchemist Online では,(u)pLaTeXでも使えるように改変されています。そのためなにも考えなければ上記サイトの物を使えばよいでしょう。

ただ,今回は文字サイズが変わったときにその縁取り線のサイズも比例して変えたいため,やや変化させなければなりません。

例えばLuaLaTeXを使っている場合ですと,xfakebold.styの紹介 - Qiita の後半の例にあるように,\directluaを使うことで相対的に縁取り線のサイズを変更できています。

10月時点では(u)pLaTeXでどうすればよいかは分かりませんでした。

しょうがないのでバージョン0.1として,特定のフォントサイズを指定したときのみ限定で相対的に変更できるように定義しました。

%\usepackage{ifthen}
%\makeatletter
\newcommand{\femph}[1]{%
\ifthenelse{\lengthtest{\f@size pt = 5pt}}{\special{pdf:literal direct q 0.1 w 2 Tr}}{%tiny
\ifthenelse{\lengthtest{\f@size pt = 7pt}}{\special{pdf:literal direct q 0.14 w 2 Tr}}{%scriptsize
\ifthenelse{\lengthtest{\f@size pt = 8pt}}{\special{pdf:literal direct q 0.16 w 2 Tr}}{%footnotesize
\ifthenelse{\lengthtest{\f@size pt = 9pt}}{\special{pdf:literal direct q 0.18 w 2 Tr}}{%small
\ifthenelse{\lengthtest{\f@size pt = 10pt}}{\special{pdf:literal direct q 0.20 w 2 Tr}}{%normalsize
\ifthenelse{\lengthtest{\f@size pt = 12pt}}{\special{pdf:literal direct q 0.24 w 2 Tr}}{%large
\ifthenelse{\lengthtest{\f@size pt = 14.4pt}}{\special{pdf:literal direct q 0.288 w 2 Tr}}{%Large
\ifthenelse{\lengthtest{\f@size pt = 17.28pt}}{\special{pdf:literal direct q 0.3456 w 2 Tr}}{%LARGE
\ifthenelse{\lengthtest{\f@size pt = 20.74pt}}{\special{pdf:literal direct q 0.4148 w 2 Tr}}{%huge
\ifthenelse{\lengthtest{\f@size pt = 24.88pt}}{\special{pdf:literal direct q 0.4976 w 2 Tr}}{%Huge
\@latex@error{femphコマンドが想定してないサイズだよ!}%
}}}}}}}}}}%
\emph{#1}%
\special{pdf:literal direct Q}%
}
%\makeatother

フォントサイズが10ptのときに,縁取りサイズを0.2ptにしよう!とした理由は,ただただ目視でWordの太字と比較したものです。暫定的に。。

とりあえず,なにかしら代替案が思いつくまではこれで我慢すればよいかな…という気持ちで作成したので,大いに罵倒してください。

追記1(2021/02/08)

(u)pLaTeXでも任意の文字サイズに対して\femphが適用できるように,定義を改良してみました。バージョン1.0です。

%\usepackage{calc} %小数の掛け算をするために入れざるを得なかった
%\makeatletter
%\newdimen\f@keemph
\newcommand{\femph}[1]{%
\f@keemph=0.04pt % 係数の初期化
\setlength{\f@keemph}{\f@keemph*\real{\f@size}}%現在の文字サイズに比例するように係数を調整
\special{pdf:literal direct q \begingroup\the\f@keemph\endgroup w 2 Tr}% 合成太字モードon
\emph{#2}%
\special{pdf:literal direct Q}% 太字モードoff 
}
%\makeatother

この定義でやっていることは,xfakebold.styの紹介 - Qiita に着想を得て,計算を(u)pLaTeXが自動でやってくれないか?ということで作って見ました。\begingroup\endgroupはとても強いということが分かりました。(戒め)

追記2(2021/02/14)

追記1で作った文書に関して,とあるクレームが来ました。

「エラー起きなかったけど,何も表示されなかった」

なんで?!僕の環境では大丈夫なはずだったんだけど???!!!と思い色々検証してもらったところ,追記1での定義がマズいことに気が付きました。というのも,

\special{pdf:literal direct q 0.20 w 2 Tr}

ならば問題なく出力できていたのですが,

\special{pdf:literal direct q 0.20pt w 2 Tr}

だと,Viewerによってpdfの見た目が変わってしまう現象が発生しました。具体的には,

  • VSCode上では問題なく太字化できていた
  • Chrome上では太字化されていなかった
  • AdobeReaderでは真っ白になっていた

という報告がありました。

つまりptを外さなければいけないのですね。

じゃあptを外すにはどうすればええんだ。。。と思って諸々調べていたら,

\expandafter\strip@pt\AAA

すればいいよ!!というのをcalculatorパッケージから教えてもらいました。

長かったですが,これが最後の定義です。バージョン1.1ということにしましょう。

%\makeatletter
% \M@LTIPLYコマンドの定義
\newdimen\f@keboldsize
\def\M@LTIPLY#1#2#3{\f@keboldsize=#1\p@\relax
 \f@keboldsize=#2\f@keboldsize\relax
 \edef#3{\expandafter\strip@pt\f@keboldsize}\ignorespaces}

%%% \femph の定義ここから %%%
\newcommand{\femph}[2][\f@keemph]{%
\M@LTIPLY{\f@size}{0.04}{\f@keemph} %現在の文字サイズに比例するように係数を調整
\special{pdf:literal direct q #1 w 2 Tr}% 合成太字モードon
\emph{#2}%
\special{pdf:literal direct Q}% 太字モードoff 
}
%%% \femph の定義ここまで %%%
%\makeatother

前回からの改善点として,calcパッケージではptのような単位がないと掛け算できなかったのですが,掛け算を再定義することで,単位無しの結果を出力するようにしました。

サンプルは以下です。

\documentclass[dvipdfmx]{jsarticle}

\makeatletter
% \M@LTIPLYコマンドの定義
\newdimen\f@keboldsize
\def\M@LTIPLY#1#2#3{\f@keboldsize=#1\p@\relax
 \f@keboldsize=#2\f@keboldsize\relax
 \edef#3{\expandafter\strip@pt\f@keboldsize}\ignorespaces}

%%% \femph の定義ここから %%%
\newcommand{\femph}[2][\f@keemph]{%
\M@LTIPLY{\f@size}{0.04}{\f@keemph} %現在の文字サイズに比例するように係数を調整
\special{pdf:literal direct q #1 w 2 Tr}% 合成太字モードon
\emph{#2}%
\special{pdf:literal direct Q}% 太字モードoff 
}
%%% \femph の定義ここまで %%%

%%% 実験用コマンド 
\newcommand{\tekitounabunsyou}{%
\emph{ほげほげ。}\femph{ほげほげ。}\\
文字サイズ:\f@size pt, 縁取りサイズ:\f@keemph pt
\bigskip
}
\makeatother

\begin{document}
{\tiny \tekitounabunsyou}

{\scriptsize \tekitounabunsyou}

{\small \tekitounabunsyou}

{\normalsize \tekitounabunsyou}

{\large \tekitounabunsyou}

{\Large \tekitounabunsyou}

{\LARGE \tekitounabunsyou}

{\fontsize{25.25pt}{30pt}\selectfont
\tekitounabunsyou}

\end{document}

Overleafでも閲覧できるようにしておきます。

ja.overleaf.com



まとめ

MS明朝やMSゴシックを使うのはやめよう。
令和の時代にMSゴを太字にするとか舐め腐ってるんですかぁ?

おまけ

今回紹介した縁取りの方法を用いれば,こんなこともできます。

\special{pdf:bcolor [1] [0]}%
\special{pdf:literal direct q 0.2 w 2 Tr}%
咲き誇る花は散るからこそに美しい
\special{pdf:literal direct Q}%
\special{pdf:ecolor}%
f:id:f_d0123:20201101001746p:plain
前略、道の上より(MSゴ)
f:id:f_d0123:20201101001433p:plain
前略、道の上より(ヒラギノ角ゴ W3)

やっぱりヒラギノが良いよなあ。

そのうち,\specialでできることを列挙したい。。。

*1:Macヒラギノに関して6書体しか入っていないので注意。7書体目を指定して文章を書くとエラーになる。

*2:現在のWordでもこのようにして合成太字を作成しているのかは,調べても分かりませんでした。もしかしたらAdobeなどのように縁取りで合成太字を作っているかもしれません。要調査。