2

I am designing a poster with XeLaTeX and want a word with custom letter spacing and where each letter is a different colour. The example below shows the problem: the first word is spaced as I want but with no colour, the second word is coloured as I want but letter spacing is now ignored. How can I achieve both?

\documentclass{article}
\usepackage{fontspec}
\usepackage{xcolor}

\pagestyle{empty}
\setlength\parindent{0pt}

\setmainfont[
    Scale=10,
    LetterSpace=-15
]{Comfortaa Light}

\begin{document}
{\centering
    WOW \par
    {\color{red}W}{\color{blue}O}{\color{green}W} \par
}
\end{document}

Two words 'WOW' with colouring/spacing issues

  • Imho you will have to insert negative space between the chars manually. Btw: LetterSpace is not a length but a factor. – Ulrike Fischer Nov 18 '14 at 12:35
  • My guess is that when you put the second row of letters inside LaTeX commands, they are spaced by the normal TeX spacing algorithms, and the custom letterspacing from fontspec is not applied. – musarithmia Nov 18 '14 at 12:42
  • @UlrikeFisher - corrected my example, thanks. – Ian Nov 18 '14 at 17:01
  • I've gone with the answer from @AndrewCashner as I only needed to solve this problem in one small place in my document and his answer seemed simplest. However the answer from StevenBSegletes seems a more complete solution for the general case. – Ian Nov 28 '14 at 11:06
0

You can define commands to apply the colors and add a negative kern between them. Putting the "magic number" of your letterspacing inside a macro makes it easier to adjust.

(I didn't have your font so I used one in the TeXLive distribution.)

\documentclass{article}
\usepackage{fontspec}
\usepackage{xcolor}
\pagestyle{empty}
\setlength{\parindent}{0pt}

\setmainfont[Scale=10,LetterSpace=-15pt]{TeX Gyre Heros}

\newlength{\letterspace}
\setlength{\letterspace}{-15pt}
\newcommand{\colorchar}[2]{\expandafter\color{#1}\relax#2}
\newcommand{\smush}{\kern \letterspace}

\begin{document}
\centering
WOW

\colorchar{red}{W}\smush\colorchar{blue}{O}\smush\colorchar{green}{W}

\end{document}

enter image description here

2

Here, I introduce \spaceout{} where the argument can contain text, \color macros, and any other macro intercepts you build in (for demo purposes, I intercept \label as well). The parameter defined by \def\theLetterSpace{-15pt} determines the additional kern applied to interletter-space.

The last of the lines in my output is the product of \spaceout with color applied.

One quirk is that, if intercepted macros (like \color or \label) occur at space boundaries in the argument to \spaceout, place the intercepted macro after the space, not before, as in \spaceout{test \color{green}of}.

\documentclass{article}
\usepackage{fontspec}
\usepackage{xcolor}
\pagestyle{empty}
\setlength\parindent{0pt}
\setmainfont[Scale=10,LetterSpace=-15]{Calibri}
\def\theLetterSpace{-15pt}
\def\spaceout#1{\spaceouthelpA#1{} \relax\relax}
\def\spaceouthelpA#1 #2\relax{%
  \spaceouthelpB#1\relax\relax%
  \ifx\relax#2\relax\else\ \kern\theLetterSpace\spaceouthelpA#2\relax\fi
}
\def\spaceouthelpB#1#2\relax{%
  \ifx\relax#2\relax#1\else
  \ifx#1\color\interceptColor#2\relax\relax\else
  \ifx#1\label\interceptLabel#2\relax\relax\else
      #1\kern\theLetterSpace\spaceouthelpB#2\relax%
  \fi\fi\fi%
}
\def\interceptColor#1#2\relax{%
  \color{#1}%
  \ifx\relax#2\else%
    \spaceouthelpB#2\relax%
  \fi%
}
\def\interceptLabel#1#2\relax{%
  \label{#1}%
  \ifx\relax#2\else%
    \spaceouthelpB#2\relax%
  \fi%
}
\begin{document}
\centering
    WOW \par
    {\color{red}W\color{blue}O\color{green}W} \par
    \spaceout{WOW} \par
    \spaceout{\color{red}W\color{blue}O\color{green}W}\par
\end{document}

enter image description here

The algorithm does word wrapping, and I demonstrate that here, along with the use of \label inside the argument to \spaceout.

\documentclass{article}
\usepackage{xcolor}
\setlength\parindent{0pt}
\def\theLetterSpace{2pt}
\def\spaceout#1{\spaceouthelpA#1{} \relax\relax}
\def\spaceouthelpA#1 #2\relax{%
  \spaceouthelpB#1\relax\relax%
  \ifx\relax#2\relax\else\ \kern\theLetterSpace\spaceouthelpA#2\relax\fi
}
\def\spaceouthelpB#1#2\relax{%
  \ifx\relax#2\relax#1\else
  \ifx#1\color\interceptColor#2\relax\relax\else
  \ifx#1\label\interceptLabel#2\relax\relax\else
      #1\kern\theLetterSpace\spaceouthelpB#2\relax%
  \fi\fi\fi%
}
\def\interceptColor#1#2\relax{%
  \color{#1}%
  \ifx\relax#2\else%
    \spaceouthelpB#2\relax%
  \fi%
}
\def\interceptLabel#1#2\relax{%
  \label{#1}%
  \ifx\relax#2\else%
    \spaceouthelpB#2\relax%
  \fi%
}
\begin{document}
\section{\spaceout{Spaced Out Heading \color{blue!40}in Blue\label{s:X}}}

I will now perform a {\spaceout{spaceout test \color{red}of red that
will show that the macro works with word wrapping}} in section \ref{s:X}.
\end{document}

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.