[Tex/LaTex] Small caps in fontspec on XeLaTeX

fontspecsmall-capsxetex

I'm trying to typeset my document with Times with XeLaTeX.
Because Times does not include small caps,
I want to use TeX Gyre Termes only for small caps.
I tried this method,
but it didn't work.
A warning is issued and the output is not small caps.

The question:

  • What is wrong?
  • How can I do this?

Here's a MWE:

\documentclass{article}
\usepackage{fontspec}
\setmainfont[
  SmallCapsFont={TeX Gyre Termes},
  SmallCapsFeatures={Letters=SmallCaps},
]{Times}
\begin{document}
Hello!
\textsc{Hello!}
\end{document}

and the warning:

*************************************************
* fontspec warning: "aat-feature-not-exist-in-font"
* 
* AAT feature 'Letters=SmallCaps' (3,3) not available in font 'TeX Gyre
* Termes'.
*************************************************

What I've tried:

  • I tried typesetting with LuaLaTeX and the result was fine with no warnings.
  • I replaced Times with Times New Roman and there was no problem.
  • I added Renderer=ICU and the warning changed to icu-feature-not-exist-in-font.
    It seems that fontspec can use .dfont with ICU?
  • I replaced Times with another .dfont font Helvetica Neue and the problem disappeared.
    Thus not all .dfont font cause the problem….

I'm using MacTeX 2013 on OS X Mountain Lion.

Update

Following a suggestion from @KhaledHosny,
I tried adding \the\XeTeXfonttype\font before and after \textsc{,
and both returned 1 (AAT font).
With Render=ICU they returned 2 (OpenType font), but I got no small caps.
It seems that XeTeX can treat Times as OpenType, but even then SmallCapsFeatures doesn't work.

Best Answer

I found that this can be achieved with NFSS.

First, Times and TeX Gyre Termes are loaded separately. Then the definition of small caps of Times in NFSS is overwritten so that it redirects to small caps of TeX Gyre Termes.

\documentclass{article}

\usepackage{fontspec}
\setmainfont{Times}

\newfontfamily\tgtermes{TeX Gyre Termes}
\makeatletter
  \begingroup
    \tgtermes
    \DeclareFontShape{\f@encoding}{\rmdefault}{m}{sc}{%
      <-> ssub * \f@family/m/sc}{}
    \DeclareFontShape{\f@encoding}{\rmdefault}{bx}{sc}{%
      <-> ssub * \f@family/bx/sc}{}
  \endgroup
\makeatother

\begin{document}

Hello!
\textsc{Hello!}

\end{document}
Related Question