12

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.)

  • Do you need only few words? Only for some title? I suggest you to use inkscape to write it and export as pdf or ps. – Sigur Jul 26 '13 at 16:08
  • 3
    A duplicate maybe tex.stackexchange.com/questions/25221/outlined-characters – percusse Jul 26 '13 at 16:08
  • @Sigur I need a longer text. – szantaii Jul 26 '13 at 16:09
  • @percusse I've tried that, and it doesn't work with xelatex. – szantaii Jul 27 '13 at 6:44
  • You can use ttf fonts with pdftex provided you use virtual fonts. I prefer this to converting the font, even when the licence would allow it. fontinst can be used to generate most of the files you need more-or-less automatically. – cfr Nov 28 '13 at 2:20
7

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

  • This looks like you just wrote a new plain tex and latex package -- the fontoutline package. Just wonderful. – A Feldman Jun 6 '16 at 13:02
5

I know the OP wants Xelatex solutions, and here I give a pdf solution, so i don't expect any votes, but wanted to show it anyhow, because it is so less grainy than the other answer of mine.

For this different answer, I steal from our most excellent LaTeX colleague Malipivo, extracting bits of \pdfliteral code from his answer at TikZ: halo around text? that end up in my macro \outline. I then basically substitute this \outline macro for the \shadow macro in my prior answer. The surrounding \shadowfy construct allows line breaking to work (albeit without hyphenation).

EDITED to incorporate Herbert's answer to this question (the \usecolor macro), Convert color name to pdfliteral code, so that colors can be specified in the LaTeX way, rather than as RGB triplets. This also has the advantage than CMYK colors are now not a problem.

Border and fill colors are defined with \bordercolor{} and \fillcolor{}, respectively. Thickness of border defined with \def\thickness{<decimal>}, though I don't know the units of the decimal.

\documentclass{article}
\usepackage{xcolor}
\input pdf-trans
\newbox\qbox
\def\usecolor#1{\csname\string\color@#1\endcsname\space}
\newcommand\bordercolor[1]{\colsplit{1}{#1}}
\newcommand\fillcolor[1]{\colsplit{0}{#1}}
\newcommand\outline[1]{\leavevmode%
  \def\maltext{#1}%
  \setbox\qbox=\hbox{\maltext}%
  \boxgs{Q q 2 Tr \thickness\space w \fillcol\space \bordercol\space}{}%
  \copy\qbox%
}
\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{%
  \outline{#1}%
  \ifx\relax#2\else\ \shadowfywords#2\relax\fi%
}
\newcommand\colsplit[2]{\colorlet{tmpcolor}{#2}\edef\tmp{\usecolor{tmpcolor}}%
  \def\tmpB{}\expandafter\colsplithelp\tmp\relax%
  \ifnum0=#1\relax\edef\fillcol{\tmpB}\else\edef\bordercol{\tmpC}\fi}
\def\colsplithelp#1#2 #3\relax{%
  \edef\tmpB{\tmpB#1#2 }%
  \ifnum `#1>`9\relax\def\tmpC{#3}\else\colsplithelp#3\relax\fi
}
\begin{document}
\bordercolor{black}
\fillcolor{white}
\def\thickness{.1}
\newcommand\mytext{This is some sample shadow text.\par Multiple paragraphs.}%
\shadowfy{\mytext}

\def\thickness{0.15}
\bordercolor{blue!70!black}
\fillcolor{yellow}
\shadowfy{\mytext}

\bordercolor{black}
\fillcolor{white}
\def\thickness{.02}{\Huge\shadowfy{a}}
\end{document}

enter image description here enter image description here

Here is a \Huge letter "a", with the settings

\bordercolor{black}
\fillcolor{white}
\def\thickness{.02}

enter image description here

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.