そのフォントサイズほんとに9pt?―jsclassesのフォントサイズ指定について

いよいよもって冬らしくなってきたこの頃ですがTUTの皆さんはいかがお過ごしでしょうか。 TUT Advent Calendar 2017 6日目を担当する@akahana_1です。 普段はコンピュータクラブでコンテキストに多分に依存した雑談をしたり、年に非負整数回発行される部誌『とよぎぃ通信』の編集をしたりしています。

さて、学部4年生の方々はそろそろ卒論の提出(あるいはもうすでに終わっている?)や卒研発表等に追われる忙しい時期ですね。 中にはTeXを使って原稿を制作する人もいるでしょう。そういう原稿にはなぜだかフォントサイズの指定がなされていたります。 というわけで、そんな人達のために使える小話を一つ

結論

  • LaTeX + js~~で指定できるフォントサイズは基本的に欧文のもの、和文はそれに合わせてやや小さくなる
  • ただしいくつかの和文フォントサイズは指定可能
  • TeXのフォントサイズは他のソフトウェアのものよりやや小さくなるので、他のソフトウェアと完全に同じ出力を実現することはそのままでは難しい。

前フリ

LaTeXで日本語文章を作成する時に皆さんが使われるクラスファイルといえばjsの接頭辞で始まるクラスファイル群(以下jsclassesと呼ぶ)だと思います。 jsclassesではドキュメントクラスの読み込み時にクラスオプションを指定することで本文のフォントサイズを変更することが出来ます。 例えば、本文を9ptにしたいときは

\documentclass[a4paper, 9pt]{jsarticle}

と指定しますね。

ところでこの時指定される9ptって日本語の9ptですか?

というわけでちょっと確かめてみましょう。

次に示す二つの例は、それぞれpLaTeX(w/jsclasses)でフォントサイズに10ptを指定した時の出力結果と、Adobe Indesign CCでフォントサイズに10ptを指定した時の出力結果です。

f:id:akahana_1:20171206232458p:plain f:id:akahana_1:20171206232512p:plain

おや?よく見るとpLaTeXを用いた出力結果のほうがややフォントサイズが小さくなっていますね。 なんでこうなってるんでしょうか?

答えは単純です。なぜならば 『jsclassesで指定できるフォントサイズは欧文フォントのサイズで和文フォントのサイズではない』 からです。 どういうことなのか具体的に見ていきましょう。

jsclassesにおけるフォントサイズ決定について

さて、jsclassesにおけるフォントサイズ指定では欧文フォントのサイズが指定されるということを明らかにしましたが、だとしても疑問が残ります。

1 : 欧文フォントサイズの指定だったとして和文フォントのサイズはどうやって決定されるの?

2 : 和文フォントサイズを思い通りにする方法はないの?

あたりが定番じゃないでしょうか。 順を追って解説していきます。

まずはじめに、jsclassesでは指定された欧文フォントのサイズに対して和文フォントのサイズをやや小さくすると言う処理を行っています。 なぜ、そのようなことになっているのでしょうか?

皆さんご存知のことと思いますが、pLaTeXエンジンではフォントファイルをそのまま取り扱うことはしません。 代わりにtfm(TeX font metric)ファイルを参照して文字の幅を取得して、文字を配置していきます。 配置された文字が実際のフォントに置き換わるのはdviファイルをdviドライバによって変換したタイミングです。 このことから、TeXで日本語を取り扱うためにはまず日本語文字に対応するtfmファイルが必要なことがわかります。

そのようなtfmファイルとして作成されたものの一つがmin10.tfmです。これはpTeXのさらに前身である「アスキー日本語TeX」向けに作られたtfmファイルです。 そして、このtfmファイルに定義される10pt指定で出力されるフォントのサイズが9.62216ptとなっています。*1 TeXが取り扱う1ptの大きさは1/72.27inchですから*2 、9.62216 / 72.27 * 25.4 = 3.3818mmが実際に出力されるサイズとなっていました。 現在ではmin10.tfmファイルによるメトリックは用いられていませんが、jsclassesで用いられているjisフォントメトリックでも同様に10ptでは9.62216ptで出力されるようになっています。

さて、話がここで終われば単純ですが、まだ続きます。 和文組版では一般的にptの代わりに級(Q)という単位を使います。1Q=0.25mmとして定義されています。 jisフォントメトリックでは10ptの欧文に対して9.62216ptの和文となっていましたが、jsclassesではさらにこれを13Q相当に縮小して用いています。 ということは3.3818mm / 0.25mm = 13.527Qとなるので、13 / 13.527 = 0.961倍すればよいことになります。 よって、jsclassesでは標準設定となる10pt指定の和文フォントサイズは13Q、おおよそ9.24ptとなります。 これはTeXにおけるptの定義を用いているので、他のソフトウェアで用いられる定義の1/72inchを用いてptに換算すれば9.21ptということになります。

1.の解答は 「jsclassesでは欧文10ptに対して和文が0.962216 * 0.961 = 0.9247倍されたフォントサイズになる」

ということになります。 そして解説の中で明らかにしましたが、TeXのptは他のソフトウェアで扱うptよりもやや小さい」ということもわかります。 というわけで、フォント指定がなされているタイプの原稿を執筆する時に厳密に他のソフトウェアでの出力にTeXを追従させようとする試みはかなり難しいといえます。 ちなみに、タイトルで取り上げている9ptも同じように換算してみると10pt * 0.913 * 0.9247 = 8.4425ptとなります。 クラスオプションで9ptを指定したつもりが本文の和文は8ptのほうが近い値で組まれることになってしまいますね。

おや?今9ptの換算をしたつもりなのに、なぜか10ptを元にして計算を行い謎の係数を乗じてますね。この謎については後で答えることにして、次の疑問を解決します。

jsclassesでクラスオプションに指定したフォントサイズは欧文のフォントサイズを指すことがわかり、それに比べて和文のフォントサイズはやや小さくなるということがわかりました。 では、和文のフォントサイズを指定してしまう方法はないのでしょうか。

これについてもjsclassesのクラスオプションに用意されています。 具体的には次のフォントサイズで和文を出力するように設定することが可能です。

  • pt指定のもの
    • 10ptj
    • 10.5ptj
    • 11ptj
    • 12ptj
  • 級数指定のもの
    • 12Q
    • 14Q

これらのフォントサイズについては和文のフォントサイズを指定することになります。この時、和文のフォントサイズに合わせて先ほどとは反対に欧文のフォントサイズがやや大きくなります。 というわけで2.の解答は

「一部のフォントサイズであれば和文のフォントサイズを指定することができる」

となります。 あっさりしたものですね。

ただし、まだ一つだけ疑問が残っています。 先程、和文フォントサイズが欧文フォントサイズに対してやや小さくなると言う説明をして、9ptでも換算してみた時に登場した謎の係数0.913は一体何なのでしょうか。 そして、tfmファイルには文字の幅が記録されていると言いましたが、そのままだと複数のフォントサイズ向けに複数のtfmファイルを用意する必要があるように見えます。 ところがjisフォントメトリックを用いる時に利用するtfmファイルは二つだけ(jis.tfmおよびjisg.tfm)です。 どうやって様々なフォントサイズを実現しているのでしょうか。

というわけで3つ目の疑問はこれです。

3 : pLaTeX + jsclassesにおいて複数のフォントサイズの切り替えをどうやって実現しているのか

先に結論だけを言うと組版時に用紙サイズを任意に拡大(縮小)してから10ptで組版を行い、それを元の用紙サイズになるように縮小(拡大)して指定のフォントサイズを実現します」

どういうことなのか、詳しく説明します。 jis.tfmおよびjisg.tfmに記載されているフォントメトリックは10pt指定時のものです。このままでは他のフォントサイズを取り扱うことが出来ません。 しかし、現実にはそのような複数のフォントサイズを取り扱う需要があるわけです。 この解決方法はふたつ考えられます。

  • フォントサイズごとに異なるフォントメトリックを用意する
  • フォントメトリックを固定して何らかの方法でフォントサイズを実現する

前者の方法はjisメトリックの前身であるmin10を始めとするフォントメトリックで用いられていた方法です。 しかしjisメトリックを利用するjsclassesでは後者の何とかする方法を採用します。

これを実現するのがTeXプリミティブとして用意されている\mag命令です。この命令は引数に取る数値の1000分率の割合で組版を行う版面を拡大します。 つまり\mag 1414と書かれていれば、版面が1.414倍拡大された状態になります。そしてjsclassesではこれを利用して10pt設定のフォントメトリックを用いて所望のフォントサイズを得ています。 このような組版を行っているのは世界広しといえどもjsclassesくらいのものなようです。

というわけで先程の換算で出現した0.913と言う謎の係数はこの\magにおける拡大率になります。 そしてこの\magにおける拡大縮小はすべてのフォントサイズ指定に関わってきます。

次の画像を見てください。 どちらもソースファイルのプリアンブルを除くと同じ

\begin{document}
\section{これがLargeサイズ}
Windowsでコンピューターの世界が広がります
\end{document}

です。

f:id:akahana_1:20171206233447p:plain f:id:akahana_1:20171206233459p:plain

見比べると下の画像のほうが上の画像よりも全体的にフォントサイズが大きくなっていることがわかりますね。 というのも上の画像ではプリアンブルが

\documentclass[a4paper, 9pt]{jsarticle}

なのに対して、下の画像ではプリアンブルが

\documentclass[a4paper, 10pt]{jsarticle}

となっているためです。

つまり\magによる版面拡大縮小の影響は本文フォント以外のフォントも影響を受けます。 TeXとフォントサイズの変更で検索すると本文フォントに対して\Largeなどが何ptであるか記載されている例がありますが、あくまでも欧文10ptの時に他のフォントサイズ指定が欧文でどのptに相当するかを書いているだけであって、jsclassesのクラスオプションでフォントサイズを変更した場合は連動して変わりうるということです。

まとめ

卒論や修論、あるいは発表予稿などを書く時に役に立つかもしれないTeXの豆知識について書いてみました。 \magの解説についてはかなり怪しい部分があると思うので、詳細な動作を知っている方がいらっしゃいましたら教えていただけると幸いです。 それでは皆様よきTeXライフを。

また、僕も編集に関わっている豊橋技術科学大学コンピュータクラブ部誌『とよぎぃ通信』が冬のコミックマーケット93で頒布される予定です。 C93初日東ク-34aで皆様をお待ちしています。

さて、明日は@_Nnwww氏の音楽についての記事です。氏は現代音楽が好みであることを存じているので、どんな飛び道具がやってくるのか期待しています。

参考文献

*1:10ptは欧文における標準のフォントサイズです

*2:ちなみにPostScriptの1ポイントは1/72inchです。このことからもTeXのptのほうがそれ以外のソフトでの出力よりやや小さくなることがわかります。

Ubuntuでターミナルエミュレータにtmux-256colorを使う

TL;DR

ncurses-termパッケージをaptでインストールしろ。

Ubuntuはtmuxパッケージのdependsにncurses-termを設定しろ。

環境

  • Linux : 4.10.0(x86_64)
  • Ubuntu : 17.04(Zesty Zapus)
  • tmux : 2.3
  • ncurses : 6.0+20160625-1ubuntu1

メモ

ターミナルを複数画面に分割して利用できるターミナルマルチプレクサとして tmuxを愛用している。 tmuxは起動時に~/.tmux.confを参照して、内部で起動するターミナルエミュレータの種類を変更できる。

256色カラーを有効化するときにはscreen-256colorを指定しろという記述はあちらこちらに見つかるが、 tmux - ArchWiki によればtmux-256colorというtmux向けのターミナルエミュレータの利用が推奨されている。

しかし、Ubuntuにおいてtmuxをインストールしたあとにinfocmp tmux-256colorをしても、tmux-256colorというターミナルエミュレータの設定は見当たらない。 ということをTwitterで愚痴っていたら次のアドバイスをもらった。

どうやらncurses>=20150502ならばtmux-256colorはすでにインストールされているという。 矛盾した事象が起きているので色々探してみると次の記事が見つかった。

chakku.hatenablog.com

この記事の内容に従ってncurses-termをインストールするとtmux-256colorが現れた。

Raspberry Pi2 + FFmpegでMPEG2TSをハードウェアエンコード

TL;DR

  • Raspberry Pi2にハードウェアアクセラレーションを有効化したFFmpegを導入した
  • ハードウェアエンコードのみで20fpsを、ハードウェアデコード及びエンコードの有効化で26fpsの処理速度が得られた
  • ハードウェアでコード及びエンコードを用いれば、30fpsの動画をほぼ等速で処理可能になる

はじめに

Raspberry Piにはカメラ接続端子が搭載されていることはよく知られている。 そして、カメラの入力を取り扱うためにハードウェアエンコーダが搭載されている事もまた知られている。 ところでこのハードウェアエンコーダはMPEG2をネイティブで取り扱うことができるので、これを転用してMPEG2TSをハードウェアエンコードしたいという考えが生まれる。

少し前までであればこのようなハードウェアエンコードにはgstreamerを使うのが定番だったが、 gstreamerは動画エンコードを目的としたツールではないため、大量のオプションが必要だったりとやや不便なツールだった。 ここ最近になって、FFmpegRaspberry Piのハードウェアエンコードに対応したので、ビルドしてこれを利用する。 また、ハードウェアエンコードによる処理速度の向上を他の環境と比較する。

準備編

はじめにMPEG2用のライセンスを手に入れておく。

これについては、すでに複数の参考文献があるためここでは割愛する 基本的には購入ページに書いてある指示と、ライセンスキーが記載されたメールに書いてある指示に従えば有効化できる。 有効になっていると、次のコマンドを実行した時に結果がenabledとなる。

vcgencmd codec_enabled MPG2

次にビルド環境を整える。 Raspberry Piをセットアップした直後であれば、様々なツールが揃っていないと思われるが、とりあえず下記のコマンドを実行すると良い。

apt install build-essential raspberrypi-kernel-headers libomxil-bellagio-dev git

build-essentialは基本的なビルドツール(makegcc)がインストールできる。 raspberrypi-kernel-headersはMMALを利用するためのヘッダーファイルmmal.hをインストールする。 *1 libomxil-bellagio-devはハードウェアエンコードに必要なOpenMAX ILのライブラリを提供している。

また、今回はFFmpegのgitリポジトリからソースコードを取ってくるためgitをインストールする。

FFmpegソースコードは次のコマンドで取得する。 今回はgithubに上がっているミラー(https://github.com/FFmpeg/FFmpeg)を利用することにした。

git clone https://github.com/FFmpeg/FFmpeg --depth 1

取得に成功したらディレクトリを移動してビルドを進めていく

cd ~/FFmpeg
./configure --arch=armel --target-os=linux --enable-mmal --enable-gpl --enable-omx --enable-omx-rpi --enable-nonfree --prefix=$HOME/usr/local

最小限でビルドするとこの形になる。--prefixは標準のインストール先にインストールしても良いなら指定しなくて構わない。 --enable-omx-rpi--enable-mmalを指定することで、Raspberry Piでのハードウェアアクセラレーションを有効にする。 この設定ではlibx264libmp3lameなどは利用できないので、必要ならば別途用意してビルド時に指定をする。

make -j4 #ここは実コア数に応じて変更する。

を実行し、生成されたバイナリでハードウェアエンコーディングが有効になっているか確かめる。 有効になっていれば、次のコマンドを実行した時にそれぞれハードウェアアクセラレーションを利用するデコーダ・エンコーダが表示される。

# デコーダの表示
./ffmpeg -decoders 2> /dev/null | grep mmal
 V..... h264_mmal            h264 (mmal) (codec h264)
 V..... mpeg2_mmal           mpeg2 (mmal) (codec mpeg2video)
 V..... mpeg4_mmal           mpeg4 (mmal) (codec mpeg4)
 V..... vc1_mmal             vc1 (mmal) (codec vc1)
# エンコーダの表示
./ffmpeg -encoders 2> /dev/null | grep omx
 V..... h264_omx             OpenMAX IL H.264 video encoder (codec h264)

これらが表示されていれば、ハードウェアアクセラレーションが有効になっているので、あとはインストールすれば簡単に利用できる。

make install

テスト

実際にビルドしたFFmpegを使って、適当なMPEG2TSファイルをH.264/AACのmp4ファイルにエンコードする。 また、ハードウェアアクセラレーションの効果を確認するために、幾つかの設定を変更してエンコードを試みる。

入力ファイルとして、今回はERBラボが提供しているサンプルストリームisdbt18.tsを利用する。 isdbt18.tsは1分間の実写動画であり、ストリームの形式はMPEG2/AACとなっている。 ffprobeを用いて表示したストリーム情報を以下に示す。

Input #0, mpegts, from 'isdbt188.ts':
  Duration: 00:01:00.87, start: 109.851700, bitrate: 17304 kb/s
  Program 23664
    Metadata:
      service_name    : ?ERB?|ニ・1
      service_provider:
    Stream #0:0[0x200]: Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p(tv, top first), 1440x1080 [SAR 4:3 DAR 16:9], 16712 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0:1[0x201]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 186 kb/s

まずはハードウェアエンコーディングだけを利用してエンコードする。オプションは次の形になる。

ffmpeg -fflags +discardcorrupt -i isdbt18.ts -c:a copy -bsf:a aac_adtstoasc -c:v h264_omx -b:v 5000k -y out.mp4

-bsf:a aac_adtstoasc-fflags +discardcorruptの指定はオーディオストリームをコピーするときに発生するエラーを抑止するために指定する。 これがないとmp4への変換時にaac bitstream errorが発生する。

そして、出力のビデオコーデックとしてh264_omxを指定する。これによってエンコード時にハードウェアを利用する。

また、ビットレートを指定しておかないと非常に低いビットレートで変換されることになり、出力結果が目も当てられなくなるのでそれなりの値を指定しておくと良い。

この時、ストリームの入出力間での対応は次のようになる。

Stream mapping:
  Stream #0:0 -> #0:0 (mpeg2video (native) -> h264 (h264_omx))
  Stream #0:1 -> #0:1 (copy)

これを見ればわかるようにデコード時にハードウェアが利用されておらず、エンコード時にのみハードウェアが利用されている。 この時のCPU使用率は100%手前から150%程度となる。また、処理速度は20fpsとなり、ファイル実時間に対しておおよそ3/2倍の時間でエンコードが完了する。

次にデコード・エンコードともにハードウェアアクセラレーションを有効化する。

ffmpeg -fflags +discardcorrupt -c:v mpeg2_mmal -i isdbt.ts -c:a copy -bsf:a aac_adtstoasc -c:v h264_omx -b:v 5000k -y out.mp4

先ほどとの違いはオプションに-c:v mpeg2_mmalが追加されている点で、これでハードウェアデコードが行われる。 *2

この時のCPU使用率はおおよそ50%程度となり、ハードウェアエンコードのみの場合に比べるとかなりCPU負荷が軽減されていることがわかる。 処理速度は26fpsとなり、先程に比べるとやや処理速度が向上していることがわかる。 これならば、ほぼ等速といって差し支えない程度になるため、かなり実用的ではないだろうか。

おまけ

どれくらいの速度が出ているのか実際他の環境でも比較してみる

その1

の場合

実行コマンドは

ffmpeg -fflags +discardcorrupt -i isdbt18.ts -c:a copy -bsf:a aac_adtstoasc -c:v h264 -b:v 5000k -y out.mp4

この時の処理速度は92fpsということは、ファイル実時間に対して約1/3倍の時間でエンコードできる。 さすが現行のAMDハイエンドCPUの面目躍如といったところ。

その2

実行コマンドはその1と同様。 この時の処理速度は13fpsで、ファイル実時間に対しておおよそ2倍の時間でエンコードすることになる。 ハードウェアアクセラレーションを有効化したRaspberry Pi2であれば、Sandy Bridge世代のCeleronよりも高速に動画処理ができるという結果になった。

まとめ

Raspberry PiのハードウェアエンコーダとMMALを用いた支援によって、30fps程度のエンコード能力を得られることがわかった。 これによって、地上デジタル放送などの録画ファイルを適当にRaspberry Piエンコードするという目論見が、時間に対してもそこまで辛くなさそうということがわかってきた。 今回はGPUメモリを128MB割り当てた設定で行っているので、割当を増やした場合の処理についてもテストする必要があると感じる。

また、言うまでもないことだが

等を試すと、CPU処理が挟まる形になるため、処理速度が大幅に低下する。 あくまでも、MPEG2TSをH.264形式に変換するだけに使えると思っておいたほうが良いだろう。

参考資料

orumin.blogspot.jp

qiita.com

www.reddit.com

stackoverflow.com

superuser.com

*1:なくてもビルドできるかもしれない。[要出典]

*2:この時、入力のストリームを見ると解像度が320 * 240とワンセグ相当に見えるが、エンコードが終わると1440 * 1080の動画を得ることができる