[Tex/LaTex] Outline text using TrueType fonts

fontsfontspectext-decorationstruetypexetex

I'd like to write outlined text. Here is a minimal example, what I'd like to achieve.

Outline text

\documentclass[a4paper]{minimal}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\usepackage{xcolor}
\usepackage{pdfrender}
\usepackage{anyfontsize}

\usepackage[active, tightpage]{preview}
\setlength{\PreviewBorder}{10pt}

\newcommand{\outline}[1]{%
    \textpdfrender{%
        TextRenderingMode=Stroke,%
        FillColor=gray,%
        LineWidth=0.1pt,%
    }{#1}%
}

\begin{document}
\begin{preview}
\fontsize{500}{500}\selectfont%
\outline{a}
\end{preview}
\end{document}

The only problem is, that I need to use TrueType fonts. So that means that I have to use fontspec and xelatex, but the pdfrender package – which I used in this example – does not support xelatex.

Can anyone help me, how to make outlined text using TrueType fonts? (Something like in the example.)

Best Answer

Here is a pdflatex (as well as XeLaTeX) approach. I create a macro \shadowfy that can span paragraphs, but can't handle macros in its arguments. The approach may not be efficient, but it is simple. It parses the argument, eventually letter by letter, and then stacks a bunch (N, S, E, W, NE, SE, SW, NW) of +/-kerned and raised/lowered \secondarycolor copies of the letter, finally laying an unkerned, unraised \primarycolor copy of the letter atop it. With the use of \def\useanchorwidth{T} in the \shadow definition, it will preserve the letter width of the original letters. If you comment that line out, the letter spacing will increase to account for the horizontal offset.

The user may set these parameters:

\setlength\shadowHoffset{.16pt}
\setlength\shadowVoffset{.08pt}
\def\primarycolor{white}
\def\secondarycolor{black}

Here is the MWE. Because of a "quirk" that I could fix with added code, the value of \shadowHoffset should be set to double the value of \shadowVoffset if a uniform horizontal/vertical shadow effect is desired. As you can see, the thickness of the shadow line can be controlled, as well as the colors.

\documentclass{article}
\usepackage{stackengine,xcolor}

\newcommand\shadowfy[1]{\expandafter\shadowfypars#1\par\relax\relax}
\long\def\shadowfypars#1\par#2\relax{%
  \ifx#1\relax\else
    \shadowfywords#1 \relax\relax%
  \fi%
  \ifx\relax#2\else\par\shadowfypars#2\relax\fi%
}
\def\shadowfywords#1 #2\relax{%
  \ifx#1\relax\else
    \shadowfyletters#1\relax\relax%
  \fi%
  \ifx\relax#2\else\ \shadowfywords#2\relax\fi%
}
\def\shadowfyletters#1#2\relax{%
  \shadow{#1}%
  \ifx\relax#2\else\shadowfyletters#2\relax\fi}

\newlength\shadowHoffset
\newlength\shadowVoffset
\setlength\shadowHoffset{.2pt}
\setlength\shadowVoffset{.1pt}
\def\primarycolor{white}
\def\secondarycolor{black}

\def\shadow#1{\setstackgap{L}{0pt}\def\stacktype{L}%
\def\useanchorwidth{T}% CAN BE COMMENTEDD FOR MORE INTERLETTER SPACE.
\Longstack{%
\raisebox{0pt}{\textcolor{\primarycolor}{#1}} 
\kern.7\shadowHoffset\raisebox{.7\shadowVoffset}{\textcolor{\secondarycolor}{#1}}
\kern-.7\shadowHoffset\raisebox{.7\shadowVoffset}{\textcolor{\secondarycolor}{#1}}
\kern\shadowHoffset\raisebox{0pt}{\textcolor{\secondarycolor}{#1}}
\kern-\shadowHoffset\raisebox{0pt}{\textcolor{\secondarycolor}{#1}}
\kern.7\shadowHoffset\raisebox{-.7\shadowVoffset}{\textcolor{\secondarycolor}{#1}}
\kern-.7\shadowHoffset\raisebox{-.7\shadowVoffset}{\textcolor{\secondarycolor}{#1}}
\kern0pt\raisebox{\shadowVoffset}{\textcolor{\secondarycolor}{#1}}
\kern0pt\raisebox{-\shadowVoffset}{\textcolor{\secondarycolor}{#1}}%
}}
\begin{document}
\newcommand\mytext{%
This is some sample shadow text.

Multiple paragraphs.
}%
\shadowfy{\mytext}

\setlength\shadowHoffset{.4pt}
\setlength\shadowVoffset{.2pt}
\def\primarycolor{yellow!70}
\def\secondarycolor{blue!80!black}
\shadowfy{\mytext}


\end{document}

enter image description here

enter image description here

Related Question