{"id":3619,"date":"2015-12-14T14:42:44","date_gmt":"2015-12-14T19:42:44","guid":{"rendered":"http:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/?p=3619"},"modified":"2022-07-01T14:13:34","modified_gmt":"2022-07-01T18:13:34","slug":"importing-ttf-fonts-into-latex-with-kerning-ligatures","status":"publish","type":"post","link":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/2015\/12\/importing-ttf-fonts-into-latex-with-kerning-ligatures\/","title":{"rendered":"Importing TTF Fonts Into LaTeX With Kerning &#038; Ligatures"},"content":{"rendered":"<p>This past weekend\u00a0I spent some time\u00a0revamping the styling of some of my work and\u00a0gaming documents. Generally\u00a0I write all of these in <a href=\"https:\/\/en.wikipedia.org\/wiki\/LaTeX\">LaTeX<\/a>. Long story short, for the uninitiated, it&#8217;s a typesetting markup language. Somewhat\u00a0similar to HTML, you write a text document peppered with commands and then run it through a compiler which produces a beautiful PDF or\u00a0similar\u00a0output. Even a marginally trained eye can identify the difference versus output from a\u00a0word processor or web page, but most people will instinctively feel that\u00a0the document is\u00a0more professional.<\/p>\n<p>Some of the\u00a0foundations of LaTeX are a\u00a0antiquated though. \u00a0The initial release of the underlying engine (<a href=\"https:\/\/en.wikipedia.org\/wiki\/TeX\">TeX<\/a>) dates to 1978. I wasn&#8217;t even born yet, and I&#8217;m an old man with a child of my own now! An oft cited\u00a0trouble area remains\u00a0fonts.\u00a0The compiler doesn&#8217;t just hook into your system fonts, and you can&#8217;t just dump any old font file into a folder and have it work.<\/p>\n<p>Fortunately working with fonts\u00a0has gotten vastly better in the ~16 years I&#8217;ve been using LaTeX. The needed supporting programs are included\u00a0in the major TeX\/LaTeX distributions now, and\u00a0a few short notes are around for using TrueType Fonts (TTF)\u00a0that will mostly work with\u00a0<code>pdflatex<\/code>, <a href=\"http:\/\/math.stanford.edu\/~jyzhao\/latexfonts.php\">such as this post<\/a>. If you&#8217;re using\u00a0XeTeX or LuaTeX then you probably have an easier ride, but are on your own.<\/p>\n<h2>Kerning &amp; Ligatures<\/h2>\n<p>Sadly though, even in this utopic\u00a0typesetting future\u00a0of ours, there&#8217;s still always a gotcha!\u00a0It&#8217;s not widely remarked, but that commonly cited process <a href=\"http:\/\/latex-community.org\/forum\/viewtopic.php?f=48&amp;t=6481&amp;p=46920\">does not carry over kerning and ligatures<\/a>.<\/p>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Typographic_ligature\">Ligatures<\/a> are letter and symbol combos that are handled specially by a font, e.g., an &#8216;f&#8217; followed by an &#8216;i&#8217; combined to have the dot of the &#8216;i&#8217; (formally <a href=\"https:\/\/en.wikipedia.org\/wiki\/Tittle\">the\u00a0tittle<\/a> of the &#8216;i&#8217;)\u00a0be the drop tail of the &#8216;f&#8217; (formally the hood).<\/p>\n<div id=\"attachment_3620\" style=\"width: 316px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3620\" class=\"wp-image-3620 size-full\" src=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/ligatures.png\" alt=\"Commonly cited and used ligatures. (image from Wikipedia)\" width=\"306\" height=\"240\" srcset=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/ligatures.png 306w, https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/ligatures-300x235.png 300w, https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/ligatures-60x47.png 60w\" sizes=\"auto, (max-width: 306px) 100vw, 306px\" \/><p id=\"caption-attachment-3620\" class=\"wp-caption-text\">Commonly cited and used ligatures. (image from Wikipedia)<\/p><\/div>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Kerning\">Kerning<\/a> is\u00a0adjustments to the inter-symbol spacing between characters, e.g., a &#8216;V&#8217; followed by an &#8216;A&#8217; should be pushed together to avoid creating a large visual space.<\/p>\n<div id=\"attachment_3621\" style=\"width: 330px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3621\" class=\"wp-image-3621 size-full\" src=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/kerning.png\" alt=\"Commonly cited and used kerning examples. (image from Wikipedia)\" width=\"320\" height=\"223\" srcset=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/kerning.png 320w, https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/kerning-300x209.png 300w, https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/kerning-60x42.png 60w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><p id=\"caption-attachment-3621\" class=\"wp-caption-text\">Commonly cited and used kerning examples. (image from Wikipedia)<\/p><\/div>\n<p>That&#8217;s exactly\u00a0how I realized the kerning of my fancy TTF fonts was not being carried through into LaTeX, when I saw this untidily spaced output:<\/p>\n<div id=\"attachment_3622\" style=\"width: 364px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3622\" class=\"size-full wp-image-3622\" src=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/kerning-fail.png\" alt=\"Kerning fail!\" width=\"354\" height=\"69\" srcset=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/kerning-fail.png 354w, https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/kerning-fail-300x58.png 300w, https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/kerning-fail-60x12.png 60w\" sizes=\"auto, (max-width: 354px) 100vw, 354px\" \/><p id=\"caption-attachment-3622\" class=\"wp-caption-text\">Kerning fail!<\/p><\/div>\n<p>At first I thought maybe the font, having gone through the wringer of one shady font website after another, didn&#8217;t\u00a0include kerning and ligatures. But a quick check in <a href=\"https:\/\/fontforge.github.io\/en-US\/\">FontForge<\/a> revealed all was\u00a0well with the font.<\/p>\n<div id=\"attachment_3624\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3624\" class=\"size-medium wp-image-3624\" src=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/kerning-inspection-300x259.png\" alt=\"Inspecting kerning in FontForge.\" width=\"300\" height=\"259\" srcset=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/kerning-inspection-300x259.png 300w, https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/kerning-inspection-60x52.png 60w, https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/kerning-inspection.png 535w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><p id=\"caption-attachment-3624\" class=\"wp-caption-text\">Inspecting kerning in FontForge.<\/p><\/div>\n<h2>Conversion<\/h2>\n<p>Long story short, in the still awful machinery\u00a0that is TeX fonts,\u00a0the compiler can only read shapes from the TTF font files. The metrics&#8212;height, width, baseline, etc.&#8212;need to be extracted out to a separate TFM file.<\/p>\n<div id=\"attachment_3623\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3623\" class=\"size-medium wp-image-3623\" src=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/glyph_metrics-300x169.png\" alt=\"Font metrics. Oh hell yeah. (image from Apple Developer)\" width=\"300\" height=\"169\" srcset=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/glyph_metrics-300x169.png 300w, https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/glyph_metrics-768x433.png 768w, https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/glyph_metrics-1024x577.png 1024w, https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/glyph_metrics-60x34.png 60w, https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/glyph_metrics.png 1596w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><p id=\"caption-attachment-3623\" class=\"wp-caption-text\">Font metrics. Oh hell yeah. (image from Apple Developer)<\/p><\/div>\n<p>That TFM format can capture kerning and ligatures, but the standard conversion tools don&#8217;t\u00a0include them. Instead you need to:<\/p>\n<ul>\n<li>From the actual original <code>.TTF<\/code> font, generate one kind of\u00a0virtual font file, a <code>.VPL<\/code>, along with the font metrics, <code>.TFM<\/code>.<\/li>\n<li>Generate another kind of virtual font, <code>.VF<\/code>, and a second set of font metrics, <code>.TFM<\/code>, from that virtual font <code>.VPL<\/code>.<\/li>\n<li>Provide a proper\u00a0file index pointing\u00a0LaTeX to the original <code>.TTF<\/code>, both <code>.TFM<\/code> files, and the <code>.VF<\/code>, as a <code>.FD<\/code> font definition file.<\/li>\n<li>Don&#8217;t screw up along the way.<\/li>\n<\/ul>\n<p>Really easy ways to screw up include breaking underlying assumptions about filenames. The suite of tools involved in that font conversion process and LaTeX itself employ a bunch of conventions\u00a0about extensions, precedence, and lowercasing. So it seems best just to keep your filenames really simple, without capitalization, spaces, special characters, etc.. And don&#8217;t leave any extraneous files laying around, e.g., font metrics from the virtual file with the same name as the\u00a0original file, because that\u00a0will be used in the wrong place and not work&#8230;<\/p>\n<p>In any event, here are the detailed steps. Throughout, you should replace &#8216;custom&#8217; with whatever simple name you want to give your font. All of this is simply operating from the working directory for simplicity.<\/p>\n<p>Make sure the filename has no special characters, or uppercase letters.<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\ncp MyCrazyFont_v7..ttf custom.ttf\r\n<\/pre>\n<p>Download or locate <code>T1-WGL4.enc<\/code> (<a href=\"http:\/\/math.stanford.edu\/~jyzhao\/T1-WGL4.enc\">here<\/a>, or possibly already on your machine at <code>\/usr\/share\/texmf-dist\/fonts\/enc\/ttf2pk\/base\/T1-WGL4.enc<\/code> or similar) and use it to generate a TFM and a VPL:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nttf2tfm custom.ttf -p T1-WGL4.enc -v custom.vpl\r\n<\/pre>\n<p>Generate another TFM and a VF, noting that these are now using a different file basename so the original <code>TFM<\/code>\u00a0remains\u00a0accessible:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nvptovf custom.vpl virtcustom.vf virtcustom.tfm\r\n<\/pre>\n<p>Copy the following mapping into <code>t1custom.fd<\/code>, changing the references in the code and filename itself to whatever you&#8217;re using instead of <code>custom<\/code>, but keeping the <code>t1<\/code> filename prefix derived from the encoding type:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n\\ProvidesFile{t1custom.fd}\r\n\\DeclareFontFamily{T1}{custom}{}\r\n\\DeclareFontShape{T1}{custom}{m}{n}{ &lt;-&gt; virtcustom}{}\r\n\\pdfmapline{+custom\\space &lt;custom.ttf\\space &lt;T1-WGL4.enc}\r\n<\/pre>\n<p>Note that this mapping points to the original shape file (<code>custom<\/code>), but the second virtual font &amp; metrics (<code>virtcustom<\/code>)!<\/p>\n<p>Use the following command in your LaTeX to switch to the font:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n\\usefont{T1}{custom}{m}{n}\r\n<\/pre>\n<p>After all that, the kernings will be done up nice and proper. Good luck!<\/p>\n<div id=\"attachment_3626\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3626\" class=\"size-medium wp-image-3626\" src=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/kerning-success-300x65.png\" alt=\"Kerning success!\" width=\"300\" height=\"65\" srcset=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/kerning-success-300x65.png 300w, https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/kerning-success-60x13.png 60w, https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-content\/uploads\/2015\/12\/kerning-success.png 320w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><p id=\"caption-attachment-3626\" class=\"wp-caption-text\">Kerning success!<\/p><\/div>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This past weekend\u00a0I spent some time\u00a0revamping the styling of some of my work and\u00a0gaming documents. Generally\u00a0I write all of these in LaTeX. Long story short, for the uninitiated, it&#8217;s a typesetting markup language. Somewhat\u00a0similar to HTML, you write a text document peppered with commands and then run it through a compiler which produces a beautiful &hellip; <a href=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/2015\/12\/importing-ttf-fonts-into-latex-with-kerning-ligatures\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":3624,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[58],"tags":[257,303,304,90],"class_list":["post-3619","post","type-post","status-publish","format-standard","hentry","category-code","tag-featured","tag-fonts","tag-latex","tag-typography"],"_links":{"self":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts\/3619","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/comments?post=3619"}],"version-history":[{"count":10,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts\/3619\/revisions"}],"predecessor-version":[{"id":3646,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts\/3619\/revisions\/3646"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/media\/3624"}],"wp:attachment":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/media?parent=3619"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/categories?post=3619"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/tags?post=3619"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}