読者です 読者をやめる 読者になる 読者になる

METAFONTでUEC校章

この記事はTeX & LaTeX Advent Calendar 2013の12/7担当分です. < 12/6 は CardinalXaroさん | | 12/8 はkuroky_plusさん>

放置ブログにAdvent Calendarの火を.放置している間に,TUG2013への参加なんかがあった.参加者は感想を投稿している人も多いのだけれど,私はTeX芸人っぽいことがしたいので,それはまた別の機会に.

しかし,今回はTeXネタでなくMETAFONTネタ.電気通信大学校章のMETAFONT化をした話*1 *2

TeXLaTeXを知っていても,「METAFONT? なにそれ,美味しいの?」なんて人もいるかもしれないので,一応説明しておくと,METAFONTはTeXで使用するフォントを作成するための言語である.これの記述とTeXLaTeXで使用するまでの流れを説明をみていく.

まずは,METAFONTソース*3から(ファイル名をmyueclogo.mfとする).今回のUEC校章のものはこんな感じ.

mode_setup;
em#:= 48pt#; cap:=48pt#;

beginchar(65,48pt#,48pt#,0pt#);
path p;
gakusc# = 1/24w;
ressc# = 4pt#;
pickup pencircle scaled ressc#;
%exact res
%p := ((w-sind(6*90)*w)/2,(h-cosd(5*90)*h)/2) for k=1 upto n: ... ((w-sind(6*(360/n*k+90))*w)/2,(h-cosd(5*(360/n*k+90))*h)/2) endfor;
p:= (0,h){curl 0}...{right}(7/8w,0)...{up}(w,1/8h)..tension 1.3 ..{left}(1/4w,h)...{down}(0,3/4h)..tension 1.6 ..(1/2w,0)..tension 1.6 ..{up}(w,3/4h)...{left}(3/4w,h)..tension 1.3 ..{down}(0,1/8h)...{right}(1/8w,0)...{curl 0}(w,h);
draw p;
pickup pencircle scaled gakusc#;
%DAI-GAKU
z1 = (1/2w,7/8h); x2 = x1;
y1-y2 = 1/16h;
y3 = y4 = y5 = y6 = y2;
x3 = 1/4w; x6 = 3/4w;
x3-x4 = x4-x5 = x5-x6;
penpos7(gakusc#,90);
penpos8(gakusc#,90);
penpos9(gakusc#,90);
penpos10(gakusc#,90);
y7 = y8 = y9 = y10;
x7 =x3; x8 =x4; x9 =x5; x10 =x6;
y7 = 11/16w;

penpos11(gakusc#,0);penpos12(gakusc#,0);
z11 =z8l; z12 = z9l;
penpos14(gakusc#,0);penpos15(gakusc#,0);
penpos18(gakusc#,0);penpos19(gakusc#,0);
penpos17(gakusc#,90);
penpos20(gakusc#,90);
x13 = x7; x14 = x8; x15 = x9; x16 = x10;
y13 = y14 = y15 = y16;
x17 = x7; x18 = x8; x19 = x9; x20 = x10;
y17r = y18 = y19 = y20r;
y7l-y13 = y13-y17r;
y20 = 1/2h;
penpos21(gakusc#,90); penpos22(gakusc#,90);
z21 = z14r; z22 = z15l;


penpos23(gakusc#,90); penpos24(gakusc#,90);
z23r = z17l; z24r = z20l;
y25 = y26 = 5/16h;
x25 = x7; x26 = x10;
y27= y28 = y29 = y30 = y23l-gakusc#;
x28 = x18l; x29 = x19r;
x28-x27 = x27-x23;
x24-x30 =x30-x29;
y31 = y32; x31 = x28; x32 =x29;
y23 - y28r = y31-y33;
y33 = y34 = y25;
x33 = x27; x34 = x30;
x35 = x36 = 1/2w;
y35 = y33;
y36 = y37 = 3/16h;
x37 = x33 + gakusc#;

erase fill z3---z25---z26---z6---cycle;

erase draw z3---(x7,y7+gakusc#) withpen pencircle scaled 2gakusc#;
erase draw z6---(x10,y10+gakusc#) withpen pencircle scaled 2gakusc#;
erase draw z3---z6 withpen pencircle scaled 2gakusc#;
draw z1---z2;
draw z3---z6;
draw z3---(x7,y7+gakusc#);draw z4---(x8,y8+gakusc#);
draw z5---(x9,y9+gakusc#);draw z6---(x10,y10+gakusc#);


erase draw z7l---z11l withpen pencircle scaled 2gakusc#;
erase draw z12r---z10l withpen pencircle scaled 2gakusc#;
erase  draw z7l---z17r withpen pencircle scaled 2gakusc#;
erase  draw z10l---z20r withpen pencircle scaled 2gakusc#;
draw z7l---z11l; draw z12r---z10l;
draw z13--z14l; draw z15r---z16;
draw z17r---z18l; draw z19r---z20r;
draw z7l---z17r; draw z10l---z20r;
draw z11r---z22r; draw z21r---z12l;
draw z21l---z19l; draw z18r---z22l;

erase draw z25---z23---z24---z26 withpen pencircle scaled 2gakusc#;
erase draw z27---z33---z34---z30 withpen pencircle scaled 2gakusc#;
erase draw (x35,y35-1/2gakusc#)---z36---z37 withpen pencircle scaled 2gakusc#;
draw z25---z23---z24---z26;
draw z27---z33---z34---z30;
draw (x35,y35-1/2gakusc#)---z36---z37;
penpos28(1/2gakusc#,90); penpos29(1/2gakusc#,90);
pickup pencircle  xscaled gakusc# yscaled 1/2gakusc#;
draw z28r---z29r---z32---z31---cycle;

%penlabels(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
%penlabels(21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37);
endchar;

なげぇ.ネタなので説明はほどほどにする.

最初のmode_setupはおまじないみたいなもので,これによって,解像度の設定やら何やらの「モード」に対する設定を行っている.その下のemやcapはフォントのパラメータの設定である.

次のbeginchar(c, w, h, d);からendchar;までがひとつの文字を定義している部分.cが文字コードで,wは幅,hは高さ,dは深さを表していて,この値はTeX組版するときに使用される.長さに#が付いているのは,「実際の」と言う意味で,解像度に影響されない長さであることを示している.ちなみに,これはTeXで使われる大きさであって,実際の字形がこの幅に収まっていることは保証されない.

幾つか変数を宣言した後,リサジュー図形の描画に入る.「p:=...」の部分がパスの定義で「draw p;」で描画される.記法はTikZとかとも近いので読みやすいのではないだろうか?METAFONTのいいところは,曲線を「..」や「...」で記述できるところである.このとき,METAFONTは空気を読んで滑らかに点と点を結んでくれる.

pのパス定義の部分にコメントアウトがあるが,これは実際に計算させて本当のリサジューを描くものである.METAFONTには三角関数を計算できたりパス定義中にforループを記述できたり*4するので,実は簡単にパラメトリック曲線を記述できる.実際に書いてみたところ,「電通大のリサジューは実際のリサジューではない」というどうでもよい事実に気がついたため,書きなおした歴史がある.

その後は,「大学」と書いてある部分の描画に入る.各点の位置を定義->適当につないで描画を繰り返しているのだが,ポイントはMETAFONTの「=」は「代入」ではなく,「等式」という事実である.実際「y1-y2 = 1/16h;」のような式が記述できる.C語族などに慣れた人にはわかりにくいかもしれない.METAFONTは,与えられた連立方程式を解いて,点の位置を計算してくれるという宣言的に記述が可能な良い言語である.


これを,LaTeXで使うには次のようにすれば良い.まず,TeX組版するために必要なTFMファイルを作成する.方法は,

mktextfm myueclogo

とすればよい.LaTeX文書では

\documentclass{article}
\font\uec=myueclogo
\begin{document}
{\uec A}電気通信大学校章
\end{document}

ちなみに,この方法はLaTeXのフォント管理を突き抜けてTeXのフォント指定法を使うというダーティな方法なので,だれかLaTeX用に仕立て直してもいいのよ?

結果はというと,こんな感じ.

コミュニケーションマークは一応用意してるけど,出来が良くない.

私はこれを使って,レポートの表紙を自作して提出していた.使いたければhttps://bitbucket.org/hak7a3/myueclogo:titl=ここに置いておくので,煮るなり焼くなりするといいと思う.*5

ちなみに,やろうと思っていたTeXネタは,実はTikZで遊ぶものだったのだが,間に合わなかった……(まだ空きが合った気がしますね,Advent Calendar)

*1:UECアドベントカレンダー? 知らない子ですね

*2:これを作成したのは実は学部時代だったりする.公開し忘れていたのでこれを機に公開

*3:の一部

*4:forは式の途中につかえるという仕様

*5:所属していた研究室や関係している所のロゴとかも入っているけど気にしない