5

I'm running ConTeXt/XeTeX on a file that uses the Gentium Book Basic font. The problem I'm having is that XeTeX appears to spend a large amount of time trying over and over again to create that font or associated auxiliary files (using mktexmf and mktextfm). As far as I can tell, the font is working fine otherwise.

In summary, when I run XeTeX, I get lots of output like this:

(./macros/pagenohead.tex) (./data/front-matter-all.tex
kpathsea: Running mktextfm GentiumBookBasic
/usr/local/texlive/2012/texmf/web2c/mktexnam: Could not map source abbreviation  for GentiumBookBasic.
/usr/local/texlive/2012/texmf/web2c/mktexnam: Need to update ?
mktextfm: Running mf-nowin -progname=mf \mode:=ljfour; mag:=1; nonstopmode; input GentiumBookBasic
This is METAFONT, Version 2.718281 (TeX Live 2012)

kpathsea: Running mktexmf GentiumBookBasic

! I can't find file `GentiumBookBasic'.
<*> ...mag:=1; nonstopmode; input GentiumBookBasic

Please type another input file name
! Emergency stop.
<*> ...mag:=1; nonstopmode; input GentiumBookBasic

Transcript written on mfput.log.
grep: GentiumBookBasic.log: No such file or directory
mktextfm: `mf-nowin -progname=mf \mode:=ljfour; mag:=1; nonstopmode; input GentiumBookBasic' failed to make GentiumBookBasic.tfm.
kpathsea: Appending font creation commands to missfont.log.

kpathsea: Running mktextfm GentiumBookBasic

I actually get this repeated almost 1700 times in a 16-page document... presumably it's happening every time I try to use the font GentiumBookBasic. As a result, it takes about 10 minutes to render this to PDF on a decent server. When I switch to a standard built-in font like "Serif", the document renders in under 9 seconds!

If we try to render our whole 1200-page book without fixing this problem, it might take on the order of 12 hours!

Incidentally, when the PDF eventually comes out the other end, the text that's supposed to be in Gentium looks like it was rendered perfectly well in the Gentium font. So the result is correct; it's just taking much longer and doing much more futile work than it should.

What can I do to get TeX to recognize the font properly and stop trying to recreate its associated files every time the font is used?

The details:

  • ConTeXt ver: 2012.05.30 11:26 MKII fmt: 2012.11.5
  • XeTeX, Version 3.1415926-2.4-0.9998 (TeX Live 2012)

We need to use a font that doesn't come with TeXLive: Gentium Book Basic. So I needed to find out how to get XeTeX to find a 3rd-party font.

I read here that "XeTEX and LuaTEX can use any font installed on the system, not just those in the TEX trees". By contrast, "[Integrating 3rd-party fonts] is unfortunately a messy topic. Forget about it unless you want to delve into many details of the TEX installation. ...A possible alternative is to use XeTEX or LuaTEX (see section 2.4), which let you use operating system fonts without any installation in TEX. "

So apparently all I need to do is install Gentium Book Basic in the OS (CentOS Linux in my case), and XeTeX should be able to find it.

In order to install Gentium Book Basic onto the system, I followed the instructions on pages like this:

  • ls Gen*

GenBasBI.ttf GenBasB.ttf GenBasI.ttf GenBasR.ttf GenBkBasBI.ttf GenBkBasB.ttf GenBkBasI.ttf GenBkBasR.ttf

  • mkdir /usr/share/fonts/TTF
  • cp Gen*.ttf /usr/share/fonts/TTF
  • fc-cache -f -v
  • fc-list | grep Gentium

The latter gives:

 Gentium Basic:style=Bold Italic
 Gentium Book Basic:style=Bold
 Gentium Book Basic:style=Italic
 Gentium Basic:style=Regular
 Gentium Book Basic:style=Bold Italic
 Gentium Book Basic:style=Regular
 Gentium Basic:style=Italic
 Gentium Basic:style=Bold

So it looks to me like Gentium is successfully installed in the OS.

The TeXLive installation docs say the following:

On Windows, fonts shipped with TEX Live are made available to XeTEX automatically. But if you have installed the xetex package on a Unix-compatible system, you need to configure your system to be able to find the fonts shipped with TEX Live via system name lookup, and not just filename lookup.

To facilitate this, when the xetex package is installed (either at initial installation or later), the necessary configuration file is created in TEXMFSYSVAR/fonts/conf/texlive-fontconfig.conf.

To set up the TEX Live fonts for system-wide use (assuming you have suitable privileges), proceed as follows:

Copy the texlive-fontconfig.conf file to /etc/fonts/conf.d/09-texlive.conf.
Run fc-cache -fsv.

I find this confusing. Is it concerned with letting XeTeX see fonts that didn't come with TeXLive, or letting the rest of the system see fonts that came with TeXLive? It seems to say both. Nevertheless, I supposed it couldn't hurt, so I followed the above instructions, and fc-cache reported that it completed successfully.

Now to how I'm referencing the font in a ConTeXt document. I have fonts defined as follows:

\definefont[SerifS][GentiumBookBasic at \smallfontsize]
\definefont[SerifLB][GentiumBookBasic-Bold at \largefontsize]

etc. These are used in styles as follows:

% 'Small' Italic (8.1pt)
\def\IT#1{{\SerifSI#1}}

% 'Big' Bold (9.2pt)
\def\BO#1{{\SerifLB#1}}

which are referenced in the .tex files:

\IT{Class: }
\BO{Previous Editions}

Now, comparing the above \definefont with the font names reported by fc-list, it's apparent that the former uses names without spaces ("GentiumBookBasic") while the latter uses names with spaces ("Gentium Book Basic"). Could that be a source of the problem?

The command reference page for \definefont in ConTeXt has little to say. The section on \definefontsynonym in the fonts manual says the spaces in the 2nd argument should be stripped out. But I tried it anyway:

\definefont[SerifS][Gentium Book Basic at \smallfontsize]

etc. However the results were no better:

kpathsea: Running mktextfm GentiumGentium
/usr/local/texlive/2012/texmf/web2c/mktexnam: Could not map source abbreviation  for GentiumGentium.

etc.

Kudos to anyone who took time to browse through the above. Any help you can offer is appreciated!

P.S.: I also tried changing the font definitions in our .tex file to use the actual TTF file names (w/o extension) instead of the full font names; e.g.

\definefont[SerifS][GenBkBasR at \smallfontsize]

and even for good measure:

\definefont[SerifS][GenBkBasR.ttf at \smallfontsize]

This didn't seem to make any difference. I still get errors like "I can't find file `GenBkBasR'." (The extension is stripped, when I provide it.)

I even tried using file: as shown in http://context.aanhet.net/svn/contextman/context-reference/en/co-fonts.pdf page 2:

\definefont[SerifS][file:GenBkBasR at \smallfontsize]

and following examples in the typescripts module that Aditya mentioned, I tried

\definefont[SerifS][\s!file:GenBkBasR at \smallfontsize]

(though I don't know what the \s! is for). But in both cases I got this "worse" error:

kpathsea: Invalid fontname `[GenBkBasR]', contains '['

before getting the usual

kpathsea: Running mktextfm GenBkBasR

/usr/local/texlive/2012/texmf/web2c/mktexnam: Could not map source abbreviation  for GenBkBasR.

etc. And unlike before, TeX failed to complete the render in these cases.

Update

Let me try to pull this question into focus...

  • Why is Xetex (or whatever component of the system) trying to call mktexnam, mktextfm, mktexmf, etc. on Gentium Book Basic - is it because it perceives that some TeX auxiliary files for that font have not been created? Is it failing, each time, to create those files? Yet the font is being rendered properly, so ultimately the system succeeds in getting the data it needs. Is there something I can do to cause TeX to successfully write the auxiliary data files it needs, so it doesn't painstakingly "stumble" over this every time the font is referenced? I've been treating utils like mktex* as "under the hood", and I would like to keep them there, but maybe I'm going to have to understand how they work in order to solve the problem.

  • The first error, mktexnam: Could not map source abbreviation for GentiumBookBasic - is that something I can directly fix, by providing an explicit mapping? How?

3
  • 1
    Did you try quotes? \definefont[SerifS]["Gentium Book Basic" at \smallfontsize]
    – egreg
    Nov 8, 2012 at 21:02
  • @egreg: Nope. Will give it a try.
    – LarsH
    Nov 8, 2012 at 21:46
  • @egreg: No dice. I get more output like when I had spaces w/o quotes: input GentiumGentium ... as well as kpathsea: Invalid fontname '[Gentium]Gentium', contains '['.
    – LarsH
    Nov 8, 2012 at 21:55

4 Answers 4

5

Wow. I didn't think this would have such a huge effect.

Reading this,

In these two systems, ConTEXt first attempts to find the font using the official font name. If that doesn't work, then it tries to use the font by file name as a fallback. Since this is not very efficient and also because it may generate —harmless, but alarming looking— warnings it is possible to force ConTEXt into one or the other mode by using a prefix, so you will most often see synonym definitions like this:

\definefontsynonym [MSTimes] [name:TimesNewRoman] [features=default] \definefontsynonym [Iwona-Regular] [file:Iwona-Regular] [features=default]

I decided to try [name:GentiumBookBasic ...] instead of just [GentiumBookBasic ...]. (As shown in my edited question, I had already tried [file:GenBkBasR ...], with no success.) I didn't think using name: would make much difference, if any, since according to the above, the official font name is tried first anyway.

But it made all the difference in the world.

All the warning messages I had seen disappeared. I searched the output in vain for any mention of mktexnam, mktextmf, etc.

And more importantly, the render time went from 9 minutes down to 13.5 seconds!

Soli Deo Gloria

I'm still puzzled as to why I was having the "not very efficient" (i.e. 40 to 60x slowdown!) problem before I started using name:. I suppose ConTEXt was searching for the font by filename first instead of by official font name first, contrary to the documentation (which might refer to a different version). Still, should it have taken that long?

Lessons learned:

  • The warnings I was seeing were apparently due to the fact that ConTeXt was first trying to look up the font by filename--and trying to create auxiliary files for a font with that filename, which didn't exist--before looking for a font with that official font name. The latter worked as a fallback, but the former took a huge amount of time.

  • Always (or at least when these warnings appear) specify, in font definitions, whether you're trying to describe the font by font name or by file name.

  • Yes, XeTeX really does work with fonts that are just installed in the OS, if you reference the font by official name, but apparently not if you try to reference the font by filename.

  • If you need to add attributes like 'italic' to the name of a font in \definefont, you can do it like this: \definefont[SerifLI][name:GentiumBookBasic-Italic at \largefontsize], even though there is no font whose name is "GentiumBookBasic-Italic". This corresponds to a font face that fc-list lists as Gentium Book Basic:style=Italic. This syntax is not unexpected, but the draft fonts chapter didn't seem to explain whether Palatino-Italic was more than just a monolithic font name. So the question of whether I had it right or not was an additional dimension of uncertainty during debugging.

8
  • BTW even though I accepted my own answer, I can't (AFAIK) award myself the bounty. So I'll be happy to award it to someone who can contribute additional informative, well-supported insights into what happened.
    – LarsH
    Nov 13, 2012 at 3:39
  • 1
    Wow, interesting story. This is pure guesswork, but have you taken permission problems into account? You've put your font map in a system location. Now if one of the font-building commands is unable to save its output, or saves it but is unable to update the font map file, there might be no indication later that the pipeline was already tried and failed. (Or the building process might just not consider failure an option...)
    – alexis
    Nov 13, 2012 at 20:44
  • @alexis: good question. Yes, I considered that problem, and ran most or all of the tests with sudo, but it didn't make any difference.
    – LarsH
    Nov 13, 2012 at 20:52
  • 1
    Oh well. Here's another idea you didn't mention trying: Make a short LaTeX document (not ConTeXt) with a couple of pages of text in Gentium Book Basic, and see what happens. It'll tell you whether the problem is in ConTeXt or is not in ConTeXt.
    – alexis
    Nov 13, 2012 at 20:55
  • 1
    @alexis: Do you know what would be the LaTeX equivalents (if any) to \definefont[ID][FooBookBasic] and \definefont[ID][name:FooBookBasic]? I have not used LaTeX in the last 13 years. On the other hand, it does seem to me that if the ConTeXt docs say "ConTeXt does X" (checking by font name before falling back to file name) but ConTeXt isn't doing X, it's pretty safe to say the problem is in ConTeXt. But I could be mistaken.
    – LarsH
    Nov 13, 2012 at 21:35
4

Why don't you simply use Wolfgang Schuster's typescripts module which is part of the ConTeXt standalone distribution as well as TeX Live and comes with a typescript for Gentium.

Gentium font package is part of TeX Live as well as ConTeXt minimals, and comes with a typescript for Genetium. You can use it as follows:

\usetypescriptfile[type-gentium]
\usetypescript[gentium]
\setupbodyfont[gentium]

\starttext
\input knuth
\stoptext

After I compile the document using context --xetex filename or texexec --xetex filename, pdffonts filename.pdf tells

name                                 type              encoding         emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
EBJEYZ+Gentium                       CID TrueType      Identity-H       yes yes yes      5  0

Note: The typescripts module is tuned to the Gentium font distributed as part of the ConTeXt standalone and Tex Live. I don't know if there is a difference between that at "Gentium Book Basic".

4
  • Thank you for this suggestion. Yes there is a difference ... Gentium Basic and Book Basic "are font families based on the original Gentium design, but with additional weights. The 'Book' family is slightly heavier." scripts.sil.org/cms/scripts/… Could I add Gentium Book Basic to Schuster's typescripts module?
    – LarsH
    Nov 9, 2012 at 15:29
  • So you know where I'm coming from ... I'm not a TeXnician; I'm working at a different level, generating code and trying to just tweak the TeX process to run right. The server that someone else set up to run this process in the past is no longer available, so I'm trying to configure a new one to work without modifying the existing TeX documents, as much as possible. I can modify them, but it's a learning curve. Your help is much appreciated.
    – LarsH
    Nov 9, 2012 at 15:31
  • Also, when I follow the link to the module, I see no mention of Gentium (let alone Gentium Book Basic), though I do see Charis SIL.
    – LarsH
    Nov 12, 2012 at 14:28
  • 1
    Sorry, the type-gentium file is part of the gentium module, not the typescripts module. You can find the file at: tex.ac.uk/tex-archive/fonts/gentium/tex/context/third/gentium
    – Aditya
    Nov 13, 2012 at 3:46
2

My previous answer was on Gentium Basic, and this answer explains how to use Gentium Book Basic.

Step 1: Download and install Gentium Book Basic.

I am using the fonts installed as part of TeX Live (I share the TeX Live fonts directory with my ConTeXt minimals installation as well).

$ls -l /usr/share/texmf-dist/fonts/truetype/public/gentium 
total 3464
-rw-r--r-- 1 root root 315860 Jun 26 01:46 GenAI102.ttf
-rw-r--r-- 1 root root 364056 Jun 26 01:46 GenAR102.ttf
-rw-r--r-- 1 root root 250668 Jun 26 01:46 GenBasBI.ttf
-rw-r--r-- 1 root root 271648 Jun 26 01:46 GenBasB.ttf
-rw-r--r-- 1 root root 263504 Jun 26 01:46 GenBasI.ttf
-rw-r--r-- 1 root root 269048 Jun 26 01:46 GenBasR.ttf
-rw-r--r-- 1 root root 249924 Jun 26 01:46 GenBkBasBI.ttf
-rw-r--r-- 1 root root 271832 Jun 26 01:46 GenBkBasB.ttf
-rw-r--r-- 1 root root 266156 Jun 26 01:46 GenBkBasI.ttf
-rw-r--r-- 1 root root 272460 Jun 26 01:46 GenBkBasR.ttf
-rw-r--r-- 1 root root 314476 Jun 26 01:46 GenI102.ttf
-rw-r--r-- 1 root root 362664 Jun 26 01:46 GenR102.ttf

The GenBk... fonts are the Book Basic fonts. I want to test the fonts with both MkIV and XeTeX MkII, so I also update the MkIV font database:

mtxrun --script fonts --reload

(I don't know how to update the font database in XeTeX, but normally the installation programs do that for me).

Step 2: Create a typescript for Gentium Book Basic

(This is needed for XeTeX only. With LuaTeX, there is a simpler method, see below).

Gentium font comes with a typescript file, but that uses Gentium rather than Gentium Book. So, I change the appropriate filenames to create a typescript for Gentium Book and save the file as type-gentium-book.tex (the filename could be anything, but I follow the usual convention in ConTeXt). Save the file somewhere ConTeXt can find it (current directory, or somewhere in the tex/context/ subtree in TDS).

\starttypescript [serif] [gentium-book]
  \definefontsynonym [Gentium-Roman]       [file:GenBkBasR]  [features=default]
  \definefontsynonym [Gentium-Italic]      [file:GenBkBasI]  [features=default]
  \definefontsynonym [Gentium-Bold]        [file:GenBkBasB]  [features=default]
  \definefontsynonym [Gentium-BoldItalic]  [file:GenBkBasBI] [features=default]
  \definefontsynonym [Gentium-Slanted]     [Gentium-Italic]
  \definefontsynonym [Gentium-BoldSlanted] [Gentium-BoldItalic]
\stoptypescript

\starttypescript [serif] [gentium-book] [name]
  \definefontsynonym [Serif]            [Gentium-Roman]
  \definefontsynonym [SerifItalic]      [Gentium-Italic]
  \definefontsynonym [SerifBold]        [Gentium-Bold]
  \definefontsynonym [SerifBoldItalic]  [Gentium-BoldItalic]
  \definefontsynonym [SerifSlanted]     [Gentium-Slanted]
  \definefontsynonym [SerifBoldSlanted] [Gentium-BoldSlanted]
  \definefontsynonym [SerifCaps]        [Serif]
  \definefontsynonym [OldStyle]         [Serif]
\stoptypescript

\starttypescript [gentium-book]
  \definetypeface [gentium-book] [rm] [serif] [gentium-book] [default] [features=default]
\stoptypescript

Note that, this typescript is for fonts distributed with TeX Live. Therefore, I use the file:.. option. (Most likely this may not work if the file is not part of the TeX Directory structure).

The above typescript will not work with pdftex engine. Since the question only asks about using TTF fonts, I'll not go into how to set up typescript for type1 fonts (which is much more complicated).

Step 3: Test file for XeTeX (MkII)

\usetypescriptfile[type-gentium-book]
\usetypescript[gentium-book]

\setupbodyfont[gentium-book]

\starttext
\input knuth
\stoptext

Compile with texexec --xetex filename and test that the fonts are used:

name                                 type              encoding         emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
TGAVQL+GentiumBookBasic              CID TrueType      Identity-H       yes yes yes      5  0

Step 4: Test with MkIV (the hard way)

Once you have created the typescript, it should also work with MkIV. ConTeXt MkIV automatically searches for typescript files, so the test file is simpler:

\setupbodyfont[gentium-book]

\starttext
\input knuth
\stoptext

Compile using context filename and check that the fonts are used:

name                                 type              encoding         emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
FDSIOE+GentiumBookBasic              CID TrueType      Identity-H       yes yes yes     18  0

Step 5: Test with MkIV (easy way)

If you are not interested in a XeTeX solution, then there is no need to create a typescript file. Use the Simplefonts module instead:

\usemodule[simplefonts]
\setmainfont[Gentium Book Basic]                                                                    

\starttext
\input knuth
\stoptext
0
1
+50

Here's a minimal LaTeX document that you could run through XeLaTeX to see if it's the fault of ConTeXt or of something in your configuration. (I don't have Gentium Book Basic, but I made sure this runs with Lucida Sans Unicode: it never tried to build anything.)

\documentclass{article}

\usepackage{fontspec}
\setmainfont{Gentium Book Basic}

% nonsense text; or just paste in your own text below
\usepackage{lipsum} 

\begin{document}
\section{Lots and lots of text}
\lipsum

\end{document}
7
  • What would be the simplest way, in this LaTeX file, to invoke the use of Gentium Book Basic very many times? E.g. foo \gentium{bar} foo \gentium{bar} etc. I think that will be necessary in order to make speed differences clear.
    – LarsH
    Nov 14, 2012 at 11:51
  • I'll look it up later; but why not just run it a couple of times and then check the log; if it doesn't launch mktextfm, it hasn't got the problem.
    – alexis
    Nov 14, 2012 at 15:03
  • OK, that will be helpful. Although I'd also like to know empirically whether the same performance impact occurred.
    – LarsH
    Nov 14, 2012 at 15:24
  • When I run xelatex test-fonts.tex I get the output kpathsea: Running mktexfmt xelatex.fmt and I can't find the format file 'xelatex.fmt'! Any advice? The same message persists even after sudo fmtutil-sys --all. I'm not even sure if I have LaTeX installed... If xelatex exists, then do I have LaTeX?
    – LarsH
    Nov 14, 2012 at 15:32
  • You must have latex, even if xelatex isn't included in your distribution. But no clue what could be wrong, I'm using Miktex. I did have to update everything from CTAN (I used the Miktex update wizard), because this stuff is very much cutting-edge, in flux and changing even in backward-incompatible ways. So do make sure you've got the latest version of everything, and figure out how to add xelatex for your distribution. If xelatex isn't present, I'm not surprised the more marginal ConTeXt is having problems! The build pipeline might even rely on xelatex components.
    – alexis
    Nov 14, 2012 at 15:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .