11

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.

3
  • 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, 2012 at 14:49
  • Check my answer on tex.stackexchange.com/questions/12567/…
    – Simurgh12
    Apr 26, 2012 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:) Apr 26, 2012 at 16:51

2 Answers 2

6

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}
2
  • 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. Apr 26, 2012 at 15:51
  • The link to the discussion is very good. I might even be able to suppress the errors via \suprressfontnotfounderror, thanks again. Apr 26, 2012 at 16:03
1

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.

3
  • Please see my Edit2 answer: tex.stackexchange.com/questions/12567/…
    – Simurgh12
    Apr 28, 2012 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. Apr 28, 2012 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, 2012 at 13:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.