13

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:)
    – yannisl
    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.
    – yannisl
    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.
    – yannisl
    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.
    – yannisl
    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

You must log in to answer this question.

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