50

I am aware of the following questions and answers about font fallback in XeTeX (or LuaLaTeX):

  1. Unicode in XeTeX with automatic font substitution?
  2. Font substitution with XeLaTeX
  3. Define fallback font for specific Unicode characters in LuaLaTeX
  4. Setting a fallback font for non-Arabic charset not supported by a certain Arabic font

From these I learnt that:

  1. XeTeX can't automatically find a font that includes a given character, but ucharclasses can be used to assign fonts to specific unicode ranges
  2. XeTex can be set up to transition from one font to the next based on character classes (interchar tokens).
  3. \newunicodechar can be used to assign a font to a given character.
  4. Polyglossia can be used to mark sections of the text in various languages.

However, none of these covers the following question, as far as I can tell:

How do I tell XeTeX to use a specific font "A", but fall back to another font "B" when a character isn't available in "A" (and so on with "C", and "D", etc.)?

In other words, I know exactly which fonts I want to use, and in which priority order; I don't need XeTeX to look for a font on my system: I can tell it exactly which ones to use. And ucharclasses won't work, because my font "A" covers parts of many classes, but for the rest of these classes I want to use "B".

From https://tug.org/pipermail/xetex/2011-November/022321.html, I know that it's possible to write a macro that detects whether a character is in a font. Thus, I can wrap each character in my document in this macro, test whether the character is in font "A", and use font "B" if it is not (and "C", and "D", until I find one in the list that contains the character).

10
  • 1
    In the intervening time since this question was first posted, fontspec has had an upgrade that may be partially useful. The macro is \IfFontExistsTF{whichfont}{true branch}{false branch}. Note that this test is based only on whether the font is installed, not on whether it has a particular character. But if you already know which fonts have which characters, it might be helpful. Be sure that your fontspec manual is up to date.
    – user103221
    Mar 27, 2017 at 0:34
  • Can you give an example? I can see why this might be useful for maths symbols, but for text, it seems wrong-headed. You really do not want to end up with words where each character comes from a different font. Even if they end up coming from the same font, wrapping each in a macro may not give good results. I'm not sure, but I'd imagine it likely to prevent kerning and, certainly, ligatures.
    – cfr
    Mar 27, 2017 at 1:20
  • 2
    @cfr: Indeed, I'd like to avoid the wrapping up, if possible. Think of it as similar to CSS's font declarations. The context that this first popped up in was syntax-highlighted code snippets using non-ASCII symbols.
    – Clément
    Mar 27, 2017 at 15:47
  • Really, an example would be helpful here. Your comment seems not quite the same as your question. The latter says every character in the document, whereas your comment talks about a specific context involving special symbols and mark-up. Thinking of it as similar to CSS font declarations won't help me much. I do at least know what they are, vaguely, but I certainly have no knowledge of them applied character-by-character.
    – cfr
    Mar 27, 2017 at 21:16
  • 7
    @cfr css font choice always works per character which is why I can drop in 🦆 and it will switch fonts and find one that supports that, if you have such a font. May 11, 2017 at 22:36

2 Answers 2

7

As long as font fallback is not implemented in *TeX some dirty hacks or manual tuning should be made. Here is another dirty hack:

You can use Font Forge python - it has really nice methods for automatically editing fonts. For example for font fallback you can use mergeFonts method. Good code example that can be adapted can be found here - see merge_fonts function definition. Part of interest is:

merged = fontforge.open(destination)
merged.sfnt_names = []
merged.fontname = fontname
merged.familyname = familyname
merged.fullname = fullname
merged.mergeFonts(fallback.path)
merged.generate(destination)

Using it several times will produce new font that pulled into itself characters in the specified fallback order.

PS. I guess it's better to use it with ucharclasses *TeX package and manually specify some Unicode blocks (like CJK).

3
  • I guess this idea can be turned to python module / CLI app that creates temporary fallback font. It even can have some option for font transformations (Font Forge is awesome) so that fonts can be scaled. Feb 7, 2018 at 6:03
  • Welcome to TeX.SE! This is IMO a great solution to the problem, or at least no worse (at least along some dimensions) than the other solutions proposed so far. Feb 7, 2018 at 7:54
  • 1
    @ShreevatsaR Thanks. The funny thing is that I first answered this question. Then I was asked what I mean by fall back font in LaTeX and... I found out that there is no automatic and convenient solution for a font fallback problem in LaTeX. Luckily I've resently written a specification for new Open Mono font so I'm aware of FontForge awesomeness (Monospacifier is also great). Feb 7, 2018 at 9:27
6
+100

In theory one could something like this:

  • Create the list of fonts
  • Check if the fonts exist
  • Wade through all unicode and test in which fonts the glyphs are
  • Assign charclasses according the results of this test
  • Setup transitions similar to the one in ucharclasses

In practice this has imho a number of drawbacks. The main that is probably horribly slow (even if it is probably faster than doing tests on all glyphs in a document). So one would have to add some intelligence, e.g. ignore some unicode block which are not used by the document, or run test on "typical glyphs" from a block (but accents will need special attention), or setup some fonts directly for which you already know the needed font, or run the test only on a set of known problematic glyphs, or store the result in some file so that it can be reused.

I have some doubts that it worth the time to go this route. It sounds like a lot of work for something I never really needed. I always knew which font I want/can to use for a unicode block.

2
  • 8
    “I always knew which font I want/can to use for a unicode block.”. I don't : e.g. I have a bibliography entry that is mostly in Latin script, except for the location, which is Αθήνα, Ελλάδα. I suppose I could include font-switching commands in the bib file, but that sounds awful.
    – Evpok
    Aug 25, 2017 at 7:47
  • @Evpok But this doesn't need an automatic fallback system for all unicode. It is enough to use ucharclass and setup a transition font for the greek unicode block code in the preamble. That's three lines of code. Aug 25, 2017 at 8:08

You must log in to answer this question.

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