% language=us

\startcomponent hybrid-fontnames

\environment hybrid-environment

\startchapter[title={The font name mess}]

\startsection [title={Introduction}]

When \TEX\ came around it shipped with its own fonts. At that moment the \TEX\
font universe was a small and well known territory. The \quote {only} hassle was
that one needed to make sure that the right kind of bitmap was available for the
printer.

When other languages than English came into the picture things became more
complex as now fonts instances in specific encodings showed up. After a couple of
years the by then standardised \TEX\ distributions carried tens of thousands of
font files. The reason for this was simple: \TEX\ fonts could only have 256
characters and therefore there were quite some encodings. Also, large \CJK\ fonts
could easily have hundreds of metric files per font. Distributions also provide
metrics for commercial fonts although I could never use them and as a result have
many extra metric files in my personal trees (generated by \TEXFONT). \footnote
{Distributions like \TEX Live have between 50.000 and 100.000 files, but
derivatives like the \CONTEXT\ minimals are much smaller.}

At the input side many problems related to encodings were solved by \UNICODE. So,
when the more \UNICODE\ aware fonts showed up, it looked like things would become
easier. For instance, no longer were choices for encodings needed. Instead one
had to choose features and enable languages and scripts and so the problem of the
multitude of files was replaced by the necessity to know what some font actually
provides. But still, for the average user it can be seen as an improvement.

A rather persistent problem remained, especially for those who want to use
different fonts and or need to install fonts on the system that come from
elsewhere (either free or commercial): the names used for fonts. You may argue
that modern \TEX\ engines and macro packages can make things easier, especially
as one can call up fonts by their names instead of their filenames, but actually
the problem has worsened. With traditional \TEX\ you definitely get an error when
you mistype a filename or call for a font that is not on your system. The more
modern \TEX's macro packages can provide fallback mechanisms and you can end up
with something you didn't ask for.

For years one of the good things of \TEX\ was its stability. If we forget about
changes in content, macro packages and|/|or hyphenation patterns, documents could
render more or less the same for years. This is because fonts didn't change.
However, now that fonts are more complex, bugs gets fixed and thereby results can
differ. Or, if you use platform fonts, your updated operating system might have
new or even different variants. Or, if you access your fonts by fontname, a
lookup can resolve differently.

The main reason for this is that fontnames as well as filenames of fonts are
highly inconsistent across vendors, within vendors and platforms. As we have to
deal with this matter, in \MKIV\ we have several ways to address a font: by
filename, by fontname, and by specification. In the next sections I will describe
all three.

\stopsection

\startsection [title={Method 1: file}]

The most robust way to specify what fonts is to be used is the filename. This is
done as follows:

\starttyping
\definefont[SomeFont][file:lmmono10-regular]
\stoptyping

A filename lookup is case insensitive and the name you pass is exact. Of course
the \type {file:} prefix (as with any prefix) can be used in font synonyms as
well. You may add a suffix, so this is also valid:

\starttyping
\definefont[SomeFont][file:lmmono10-regular.otf]
\stoptyping

By default \CONTEXT\ will first look for an \OPENTYPE\ font so in both cases you
will get such a font. But how do you know what the filename is? You can for
instance check it out with:

\starttyping
mtxrun --script font --list --file --pattern="lm*mono"
\stoptyping

This reports some information about the file, like the weight, style, width,
fontname, filename and optionally the subfont id and a mismatch between the
analysed weight and the one mentioned by the font.

\startntyping
latinmodernmonolight       light    normal   normal      lmmonolt10regular           lmmonolt10-regular.otf
latinmodernmonoproplight   light    italic   normal      lmmonoproplt10oblique       lmmonoproplt10-oblique.otf
latinmodernmono            normal   normal   normal      lmmono9regular              lmmono9-regular.otf
latinmodernmonoprop        normal   italic   normal      lmmonoprop10oblique         lmmonoprop10-oblique.otf
latinmodernmono            normal   italic   normal      lmmono10italic              lmmono10-italic.otf
latinmodernmono            normal   normal   normal      lmmono8regular              lmmono8-regular.otf
latinmodernmonolightcond   light    italic   condensed   lmmonoltcond10oblique       lmmonoltcond10-oblique.otf
latinmodernmonolight       light    italic   normal      lmmonolt10oblique           lmmonolt10-oblique.otf
latinmodernmonolightcond   light    normal   condensed   lmmonoltcond10regular       lmmonoltcond10-regular.otf
latinmodernmonolight       bold     italic   normal      lmmonolt10boldoblique       lmmonolt10-boldoblique.otf
latinmodernmonocaps        normal   italic   normal      lmmonocaps10oblique         lmmonocaps10-oblique.otf
latinmodernmonoproplight   bold     italic   normal      lmmonoproplt10boldoblique   lmmonoproplt10-boldoblique.otf
latinmodernmonolight       bold     normal   normal      lmmonolt10bold              lmmonolt10-bold.otf
latinmodernmonoproplight   bold     normal   normal      lmmonoproplt10bold          lmmonoproplt10-bold.otf
latinmodernmonoslanted     normal   normal   normal      lmmonoslant10regular        lmmonoslant10-regular.otf
latinmodernmono            normal   normal   normal      lmmono12regular             lmmono12-regular.otf
latinmodernmonocaps        normal   normal   normal      lmmonocaps10regular         lmmonocaps10-regular.otf
latinmodernmonoprop        normal   normal   normal      lmmonoprop10regular         lmmonoprop10-regular.otf
latinmodernmono            normal   normal   normal      lmmono10regular             lmmono10-regular.otf
latinmodernmonoproplight   light    normal   normal      lmmonoproplt10regular       lmmonoproplt10-regular.otf
\stopntyping

\stopsection

\startsection [title={Method 1: name}]

Instead of lookup by file, you can also use names. In the font database we store
references to the fontname and fullname as well as some composed names from
information that comes with the font. This permits rather liberal naming and the
main reason is that we can more easily look up fonts. In practice you will use
names that are as close to the filename as possible.

\starttyping
mtxrun --script font --list --name --pattern="lmmono*regular" --all
\stoptyping

This gives on my machine:

\startntyping
lmmono10regular         lmmono10regular         lmmono10-regular.otf
lmmono12regular         lmmono12regular         lmmono12-regular.otf
lmmono8regular          lmmono8regular          lmmono8-regular.otf
lmmono9regular          lmmono9regular          lmmono9-regular.otf
lmmonocaps10regular     lmmonocaps10regular     lmmonocaps10-regular.otf
lmmonolt10regular       lmmonolt10regular       lmmonolt10-regular.otf
lmmonoltcond10regular   lmmonoltcond10regular   lmmonoltcond10-regular.otf
lmmonoprop10regular     lmmonoprop10regular     lmmonoprop10-regular.otf
lmmonoproplt10regular   lmmonoproplt10regular   lmmonoproplt10-regular.otf
lmmonoslant10regular    lmmonoslant10regular    lmmonoslant10-regular.otf
\stopntyping

It does not show from this list but with name lookups first \OPENTYPE\ fonts are
checked and then \TYPEONE. In this case there are \TYPEONE\ variants as well but
they are ignored. Fonts are registered under all names that make sense and can be
derived from its description. So:

\starttyping
mtxrun --script font --list --name --pattern="latinmodern*mono" --all
\stoptyping

will give:

\startntyping
latinmodernmono                      lmmono9regular              lmmono9-regular.otf
latinmodernmonocaps                  lmmonocaps10oblique         lmmonocaps10-oblique.otf
latinmodernmonocapsitalic            lmmonocaps10oblique         lmmonocaps10-oblique.otf
latinmodernmonocapsnormal            lmmonocaps10oblique         lmmonocaps10-oblique.otf
latinmodernmonolight                 lmmonolt10regular           lmmonolt10-regular.otf
latinmodernmonolightbold             lmmonolt10boldoblique       lmmonolt10-boldoblique.otf
latinmodernmonolightbolditalic       lmmonolt10boldoblique       lmmonolt10-boldoblique.otf
latinmodernmonolightcond             lmmonoltcond10oblique       lmmonoltcond10-oblique.otf
latinmodernmonolightconditalic       lmmonoltcond10oblique       lmmonoltcond10-oblique.otf
latinmodernmonolightcondlight        lmmonoltcond10oblique       lmmonoltcond10-oblique.otf
latinmodernmonolightitalic           lmmonolt10oblique           lmmonolt10-oblique.otf
latinmodernmonolightlight            lmmonolt10regular           lmmonolt10-regular.otf
latinmodernmononormal                lmmono9regular              lmmono9-regular.otf
latinmodernmonoprop                  lmmonoprop10oblique         lmmonoprop10-oblique.otf
latinmodernmonopropitalic            lmmonoprop10oblique         lmmonoprop10-oblique.otf
latinmodernmonoproplight             lmmonoproplt10oblique       lmmonoproplt10-oblique.otf
latinmodernmonoproplightbold         lmmonoproplt10boldoblique   lmmonoproplt10-boldoblique.otf
latinmodernmonoproplightbolditalic   lmmonoproplt10boldoblique   lmmonoproplt10-boldoblique.otf
latinmodernmonoproplightitalic       lmmonoproplt10oblique       lmmonoproplt10-oblique.otf
latinmodernmonoproplightlight        lmmonoproplt10oblique       lmmonoproplt10-oblique.otf
latinmodernmonopropnormal            lmmonoprop10oblique         lmmonoprop10-oblique.otf
latinmodernmonoslanted               lmmonoslant10regular        lmmonoslant10-regular.otf
latinmodernmonoslantednormal         lmmonoslant10regular        lmmonoslant10-regular.otf
\stopntyping

Watch the 9 point version in this list. It happens that there are 9, 10 and 12
point regular variants but all those extras come in 10 point only. So we get a
mix and if you want a specific design size you really have to be more specific.
Because one font can be registered with its fontname, fullname etc.\ it can show
up more than once in the list. You get what you ask for.

With this obscurity you might wonder why names make sense as lookups. One
advantage is that you can forget about special characters. Also, Latin Modern
with its design sizes is probably the worst case. So, although for most fonts a
name like the following will work, for Latin Modern it gives one of the design
sizes:

\starttyping
\definefont[SomeFont][name:latinmodernmonolightbolditalic]
\stoptyping

But this is quite okay:

\starttyping
\definefont[SomeFont][name:lmmonolt10boldoblique]
\stoptyping

So, in practice this method will work out as well as the file method but
you can best check if you get what you want.

\stopsection

\startsection [title={Method 1: spec}]

We have now arrived at the third method, selecting by means of a specification.
This time we take the familyname as starting point (although we have some
fallback mechanisms):

\starttyping
\definefont[SomeSerif]          [spec:times]
\definefont[SomeSerifBold]      [spec:times-bold]
\definefont[SomeSerifItalic]    [spec:times-italic]
\definefont[SomeSerifBoldItalic][spec:times-bold-italic]
\stoptyping

The patterns are of the form:

\starttyping
spec:name-weight-style-width
spec:name-weight-style
spec:name-style
\stoptyping

When only the name is used, it actually boils down to:

\starttyping
spec:name-normal-normal-normal
\stoptyping

So, this is also valid:

\starttyping
spec:name-normal-italic-normal
spec:name-normal-normal-condensed
\stoptyping

Again we can consult the database:

\starttyping
mtxrun --script font --list --spec lmmono-normal-italic
\stoptyping

This prints the following list. The first column is the familyname, the fifth
column the fontname:

\startntyping
latinmodernmono       normal   italic   normal   lmmono10italic        lmmono10-italic.otf
latinmodernmonoprop   normal   italic   normal   lmmonoprop10oblique   lmmonoprop10-oblique.otf
lmmono10              normal   italic   normal   lmmono10italic        lmtti10.afm
lmmonoprop10          normal   italic   normal   lmmonoprop10oblique   lmvtto10.afm
lmmonocaps10          normal   italic   normal   lmmonocaps10oblique   lmtcso10.afm
latinmodernmonocaps   normal   italic   normal   lmmonocaps10oblique   lmmonocaps10-oblique.otf
\stopntyping

Watch the \OPENTYPE\ and \TYPEONE\ mix. As we're just investigating here, the
lookup looks at the fontname and not at the familyname. At the \TEX\ end you use
the familyname:

\starttyping
\definefont[SomeFont][spec:latinmodernmono-normal-italic-normal]
\stoptyping

So, we have the following ways to access this font:

\starttyping
\definefont[SomeFont][file:lmmono10-italic]
\definefont[SomeFont][file:lmmono10-italic.otf]
\definefont[SomeFont][name:lmmono10italic]
\definefont[SomeFont][spec:latinmodernmono-normal-italic-normal]
\stoptyping

As \OPENTYPE\ fonts are prefered over \TYPEONE\ there is not much chance of a
mixup.

As mentioned in the introduction, qualifications are somewhat inconsistent. Among
the weight we find: black, bol, bold, demi, demibold, extrabold, heavy, light,
medium, mediumbold, regular, semi, semibold, ultra, ultrabold and ultralight.
Styles are: ita, ital, italic, roman, regular, reverseoblique, oblique and
slanted. Examples of width are: book, cond, condensed, expanded, normal and thin.
Finally we have alternatives which can be anything.

When doing a lookup, some normalizations takes place, with the default always
being \quote {normal}. But still the repertoire is large:

\startntyping
helveticaneue medium     normal normal    helveticaneuemedium           HelveticaNeue.ttc index:  0
helveticaneue bold       normal condensed helveticaneuecondensedbold    HelveticaNeue.ttc index:  1
helveticaneue black      normal condensed helveticaneuecondensedblack   HelveticaNeue.ttc index:  2
helveticaneue ultralight italic thin      helveticaneueultralightitalic HelveticaNeue.ttc index:  3
helveticaneue ultralight normal thin      helveticaneueultralight       HelveticaNeue.ttc index:  4
helveticaneue light      italic normal    helveticaneuelightitalic      HelveticaNeue.ttc index:  5
helveticaneue light      normal normal    helveticaneuelight            HelveticaNeue.ttc index:  6
helveticaneue bold       italic normal    helveticaneuebolditalic       HelveticaNeue.ttc index:  7
helveticaneue normal     italic normal    helveticaneueitalic           HelveticaNeue.ttc index:  8
helveticaneue bold       normal normal    helveticaneuebold             HelveticaNeue.ttc index:  9
helveticaneue normal     normal normal    helveticaneue                 HelveticaNeue.ttc index: 10
helveticaneue normal     normal condensed helveticaneuecondensed        hlc_____.afm   conflict: roman
helveticaneue bold       normal condensed helveticaneueboldcond         hlbc____.afm
helveticaneue black      normal normal    helveticaneueblackcond        hlzc____.afm   conflict: normal
helveticaneue black      normal normal    helveticaneueblack            hlbl____.afm   conflict: normal
helveticaneue normal     normal normal    helveticaneueroman            lt_50259.afm   conflict: regular
\stopntyping

\stopsection

\startsection[title={The font database}]

In \MKIV\ we use a rather extensive font database which in addition to bare
information also contains a couple of hashes. When you use \CONTEXT\ \MKIV\ and
install a new font, you have to regenerate the file database. In a next \TEX\ run
this will trigger a reload of the font database. Of course you can also force a
reload with:

\starttyping
mtxrun --script font --reload
\stoptyping

As a summary we mention a few of the discussed calls of this script:

\startntyping
mtxrun --script font --list somename (== --pattern=*somename*)

mtxrun --script font --list --name somename
mtxrun --script font --list --name --pattern=*somename*

mtxrun --script font --list --spec somename
mtxrun --script font --list --spec somename-bold-italic
mtxrun --script font --list --spec --pattern=*somename*
mtxrun --script font --list --spec --filter="fontname=somename"
mtxrun --script font --list --spec --filter="familyname=somename,weight=bold,style=italic,width=condensed"

mtxrun --script font --list --file somename
mtxrun --script font --list --file --pattern=*somename*
\stopntyping

The lists shown in before depend on what fonts are installed and
their version. They might not reflect reality at the time you read
this.

\stopsection

\startsection[title={Interfacing}]

Regular users never deal with the font database directly. However, if you write
font loading macros yourself, you can access the database from the \TEX\ end.
First we show an example of an entry in the database, in this case TeXGyreTermes
Regular.

\starttyping
{
    designsize = 100,
    familyname = "texgyretermes",
    filename = "texgyretermes-regular.otf",
    fontname = "texgyretermesregular",
    fontweight = "regular",
    format = "otf",
    fullname = "texgyretermesregular",
    maxsize = 200,
    minsize = 50,
    rawname = "TeXGyreTermes-Regular",
    style = "normal",
    variant = "",
    weight = "normal",
    width = "normal",
}
\stoptyping

Another example is Helvetica Neue Italic:

\starttyping
{
    designsize = 0,
    familyname = "helveticaneue",
    filename = "HelveticaNeue.ttc",
    fontname = "helveticaneueitalic",
    fontweight = "book",
    format = "ttc",
    fullname = "helveticaneueitalic",
    maxsize = 0,
    minsize = 0,
    rawname = "Helvetica Neue Italic",
    style = "italic",
    subfont = 8,
    variant = "",
    weight = "normal",
    width = "normal",
}
\stoptyping

As you can see, some fields can be meaningless, like the sizes. As using the low
level \TEX\ interface assumes some knowledge, we stick here to an example:

\starttyping
\def\TestLookup#1%
  {\dolookupfontbyspec{#1}
   pattern: #1, found: \dolookupnoffound
   \blank
   \dorecurse {\dolookupnoffound} {%
     \recurselevel:~\dolookupgetkeyofindex{fontname}{\recurselevel}%
     \quad
   }%
   \blank}

\TestLookup{familyname=helveticaneue}
\TestLookup{familyname=helveticaneue,weight=bold}
\TestLookup{familyname=helveticaneue,weight=bold,style=italic}
\stoptyping

You can use the following commands:

\starttyping
\dolookupfontbyspec    {key=value list}
\dolookupnoffound
\dolookupgetkeyofindex {key}{index}
\dolookupgetkey        {key}
\stoptyping

First you do a lookup. After that there can be one or more matches and you can
access the fields of each match. What you do with the information is up to
yourself.

\stopsection

\startsection[title={A few remarks}]

The fact that modern \TEX\ engines can access system fonts is promoted as a
virtue. The previous sections demonstrated that in practice this does not really
free us from a name mess. Of course, when we use a really small \TEX\ tree, and
system fonts only, there is not much that can go wrong, but when you have extra
fonts installed there can be clashes.

We're better off with filenames than we were in former times when operating
systems and media forced distributors to stick to 8 characters in filenames. But
that does not guarantee that today's shipments are more consistent. And as there
are still some limitations in the length of fontnames, obscure names will be with
us for a long time to come.

\stopsection

\stopchapter

\stopcomponent
