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?
\definefont[SerifS]["Gentium Book Basic" at \smallfontsize]
input GentiumGentium
... as well askpathsea: Invalid fontname '[Gentium]Gentium', contains '['
.