# How to check if a font exists in XeLaTeX

Is there a way to check if a font exists in XeLaTeX? I am aware of Check for missing fonts/characters in XeLaTeX?, but sadly the one answer only refers to the log. I am interested for a test via code.

Background:

I am trying to define a command that checks a series of fonts and uses the first one that it finds (similar to the CSS properties)

 p{font-family:"Times New Roman",Georgia,Serif;}


I intend to use pgf keys and here is a MWE example.

 \documentclass{article}
\usepackage{ifxetex}
% Generic defaults
\ifxetex
\usepackage{fontspec}
\defaultfontfeatures{Mapping=tex-text}
\setmainfont{Times New Roman}
\setsansfont{Minion Pro}
\else
\usepackage{mathpazo}
\usepackage[T1]{fontenc}
\fi
\usepackage{pgfkeys}
\usepackage{lipsum}
\makeatletter
% keys
\pgfkeys{/fonts/.is family}
\def\cxset{\pgfqkeys{/fonts}}
\cxset{%
serif/.code=\rmfamily,
Serif/.code=\rmfamily,
font-name/.store in =\fontname@cx,
}
\cxset{
serif,
font-name=Times New Roman,
}

\ifxetex
\defaultfontfeatures{Mapping=tex-text}
% code to be added here for iterating through list etc..
\setmainfont{\fontname@cx}
\setsansfont{Minion Pro}
\fi
\makeatother
\begin{document}
\lipsum[1]
\end{document}


Ultimately the key

font-family={Times New Roman, Some Other Font, Another Font, serif}


should iterate via all the font names. if none is found the serif value will trigger the default \rmfamily. I can code the iteration etc, but I am stuck on the test.

-
The problem here is that TeX is about exacting output, hence the fact that you don't get 'auto-substitution' of missing glyphs, etc. So I'm not sure this is that easy/doable. –  Joseph Wright Apr 26 '12 at 14:49
Check my answer on tex.stackexchange.com/questions/12567/… –  Simurgh12 Apr 26 '12 at 15:38
@JosephWright Won't you please have a look at the answers below and give us some comments, or even mangle an answer:) –  Yiannis Lazarides Apr 26 '12 at 16:51

Does this help (take from XeTeX mailing list):

\documentclass{article}
\begin{document}
\def\myfont{"Persian Modern"}% first preferred font
\def\myfallback{"XB Zar"} % if first font not avaliable
\count255=\interactionmode
\batchmode
\font\bodyfont=\myfont\space at 10pt
\ifx\bodyfont\nullfont
\font\bodyfont = \myfallback\space at 10pt
\ifx\bodyfont\nullfont
\errorstopmode
\errmessage{no suitable font found}
\else
\let\myfont=\myfallback
\fi
\fi
\interactionmode=\count255
\bodyfont
This is a test.
\end{document}

-
Thanks, it certainly does. The way I read it uses batchmode to silence the errors and then does the substitution. I can turn this into a list no issue. I will wait a bit to accept the answer. –  Yiannis Lazarides Apr 26 '12 at 15:51
The link to the discussion is very good. I might even be able to suppress the errors via \suprressfontnotfounderror, thanks again. –  Yiannis Lazarides Apr 26 '12 at 16:03

Based on Simurgh's answers here is a first attempt to check for a number of fonts. I run through the full loop for convenience, although one would need to break at the first font found.

\documentclass{article}
\usepackage{fontspec}
\def\alist{Times New Roman,Tahoma,test}
\parindent0pt
\begin{document}
\makeatletter
\count255=\interactionmode
\batchmode
\@for\next:=\alist\do{%
\expandafter\newfontfamily\csname\next\endcsname{\next}
\setbox0=\hbox{\csname\next\endcsname A}
\ifdim\ht0=0pt \next\ does not exist\\ \else \next\ does exist\\\fi
}
\interactionmode=\count255
\makeatother
\end{document}


As normal XeLaTeX can go into a few seconds of silence, looking for fonts, so be a bit patient if you run the MWE.

-
Please see my Edit2 answer: tex.stackexchange.com/questions/12567/… –  Simurgh12 Apr 28 '12 at 8:37
@Simurgh12 Thanks your second answer is a better way to also check if a font exists. If a font does not exist -> silence errors and check for A. It fails the test, certainly as used above. –  Yiannis Lazarides Apr 28 '12 at 12:38
No, test for A was an example. You actually should check a range of characters (depending on your application). –  Simurgh12 Apr 28 '12 at 13:22