2

I'm trying to draw text in different shapes using a custom font.

With the help of Steven, I was able to get most of the text shapes I needed working well. See the question here

Everything works well, except when using custom fonts. I'm using the fontspec package with XeLaTeX for custom fonts. Below is what I'm using to generate the final output:

\documentclass[11pt]{article}

\usepackage{ifthen,trimclip,calc,fp,graphicx}
\usepackage[active, tightpage]{preview}
\usepackage[usenames,dvipsnames,svgnames,table]{xcolor}
\usepackage{fontspec}
\usepackage[document]{ragged2e}

\setlength\PreviewBorder{0.2pt}%

\title{bidPress}
\author{bidPress}
\date{September 2016}

\setmainfont[ExternalLocation=/path/to/fonts/]{"HelveticaLTStd-Roman.ttf"}

\newsavebox\mytext
\newcounter{mycount}
\newlength\clipsize

\newcommand\parabtext[5][0]{%
  \edef\neck{#3}% percent to depress the amplitude
  \def\cuts{#4}% Number of cuts
  \savebox{\mytext}{\kern.2pt#5\kern.2pt}% TEXT
  \FPeval{\myprod}{1/cuts}%
  \clipsize=\myprod\wd\mytext\relax%
  \setcounter{mycount}{0}%
  \whiledo{\value{mycount}<\cuts}{%
    \stepcounter{mycount}%
    \edef\NA{\themycount}%
    \edef\NB{\the\numexpr\cuts-\themycount\relax}%
    \FPeval{\myprod}{(\NA-.5)*(\NB+.5)*4/\cuts/\cuts}%
    \ifnum0#1=0\relax%
      \FPeval{\myprod}{1 - \neck*(\myprod)}%
    \else%
      \FPeval{\myprod}{1 - \neck*(1-\myprod)}%
    \fi%
    \clipbox{%
      \value{mycount}\clipsize-\clipsize\relax{} %
      -1pt %
      \wd\mytext-\value{mycount}\clipsize\relax{} %
      -1pt%
    }{\raisebox{#2\dimexpr\ht\mytext-\myprod\ht\mytext}{%
        \scalebox{1}[\myprod]{\usebox{\mytext}}}}%
  }%
}


\makeatletter
\ifdefined\XeTeXversion
  \def\@cliptoboxdim#1{%
    \setbox #1=\hbox{%
      \Gin@defaultbp\WIDTH{\wd #1}%
      \Gin@defaultbp \DEPTH {\dp #1}%
      \@tempdima \ht #1%
      \advance\@tempdima\dp#1%
      \Gin@defaultbp \TOTALHEIGHT {\@tempdima }%
      \special{pdf:literal q}% 
      \special{pdf:literal 0 -\DEPTH \space \WIDTH \space \TOTALHEIGHT \space re W n }%
      \rlap{\copy #1}%
      \special {pdf:literal Q}%
      \hskip\wd#1%
    }%
  }
\fi
\makeatother


\begin{document}
\begin{preview}
\begin{center}

\special{pdf:bcolor [0.0 0.0 0.0] }

\parabtext{0}{.7}{100}{\large TEST TEST TEST}

\end{center}
\end{preview}
\end{document}

This works well when I don't use a custom font, i.e. removing the \setmainfont line.

With a custom font the left side of the fonts are chopped off. Below is an example with Helvetica:

Example with Helvetica

Helvetica isn't so bad, but it gets worse with some other fonts like Chewy

Example with Chewy

7
  • 2
    For the readers, I would link this question, tex.stackexchange.com/questions/331780/…, as it was a XeLaTeX problem directly related to the prior question. Oct 17, 2016 at 23:21
  • 2
    My guess is the line, \savebox{\mytext}{\kern.2pt#5\kern.2pt}% needs to have the .2pt values increased. That was supposed to account for glyph overhang beyond the bounding box. Oct 17, 2016 at 23:23
  • @StevenB.Segletes if I increased it to something like 5pt will it have any side effects? Oct 18, 2016 at 13:25
  • It will change the before/after kerning by that amount. However, you could compensate for that by undoing that kern on either side of the \whiledo loop. I would add that the slicing process equally subdivides the \mytext savebox. Thus, your resolution decreases slightly, as well, as some slices may be devoted to the blank space in the pre/post kern. Oct 18, 2016 at 13:33
  • How would you suggest compensating, because not all fonts will have similar values that are required. Oct 18, 2016 at 13:45

1 Answer 1

1

Here, I try to lay out the issues at work. For my MWE, I only perform 10 vertical slices across the argument, since seeing the actual slices helps, I think, visualize the issue here.

The argument text is set in the \mytext savebox. By definition, the box is only as wide as the space allocated for the glyphs. Often (some fonts more than others), glyphs extend past the horizontal edges of their allocated boxes. In this case, the overhanging part of the glyph gets truncated.

The first line of my MWE shows this, where I have artificially made the kern buffer 1pt less than the actual width of the argument.

In my original answer from the other question, I added a small .2pt space buffer before and after the argument (\savebox{\mytext}{\kern.2pt#5\kern.2pt}), to try to avoid this truncation. For some fonts, the OP has found, that buffer is not enough. So, in my comments above, I proposed creating a length, here called \bufferzone that the user can set in a font-dependent way to add that space buffer. But there are two complications of this:

  1. The text gets shifted to the right by \bufferzone and has a \bufferzone dead space following it (this is shown in the 2nd and 3rd lines of output in my MWE, where \bufferzone has been set to 5pt and 50pt, respectively); and

  2. The buffer zone is also subject to slicing and dicing, and so thre resolution of the remaining slices are decreased as some slices are wasted on empty space.

The correction for item 1 above is to undo the bufferzone, before and after the slicing process, which I do with \bufferzonecorrection in my MWE. This is done for lines 4 and 5 of the output of my MWE. After one becomes convinced on the rightness of this approach, I recommend just replacing \bufferzonecorrection in my MWE with -\bufferzone.

Item 2 above is not fixable, but its effect can be minimized by selecting \bufferzone to the proper value for the selected font. As such, lines 4 and 5 of the ouput are not "optimized", since several slices are wasted on empty (but non-visible) space, and the result is significantly different from the line 1 output.

\documentclass[11pt]{article}

\usepackage{ifthen,trimclip,calc,fp,graphicx}
\usepackage[active, tightpage]{preview}
\usepackage[usenames,dvipsnames,svgnames,table]{xcolor}
%\usepackage{fontspec}
%\usepackage[document]{ragged2e}

\setlength\PreviewBorder{0.2pt}%

%\title{bidPress}
%\author{bidPress}
%\date{September 2016}

%\setmainfont[ExternalLocation=/path/to/fonts/]{"HelveticaLTStd-Roman.ttf"}

\newsavebox\mytext
\newcounter{mycount}
\newlength\clipsize
\newlength\bufferzone
\newlength\bufferzonecorrection
\bufferzone=.2pt\relax

\newcommand\parabtext[5][0]{%
  \edef\neck{#3}% percent to depress the amplitude
  \def\cuts{#4}% Number of cuts
  \savebox{\mytext}{\kern\bufferzone#5\kern\bufferzone}% TEXT
  \FPeval{\myprod}{1/cuts}%
  \clipsize=\myprod\wd\mytext\relax%
  \setcounter{mycount}{0}%
  \hspace{\bufferzonecorrection}% STEVEN SUGGESTS SETTING TO -\bufferzone
  \whiledo{\value{mycount}<\cuts}{%
    \stepcounter{mycount}%
    \edef\NA{\themycount}%
    \edef\NB{\the\numexpr\cuts-\themycount\relax}%
    \FPeval{\myprod}{(\NA-.5)*(\NB+.5)*4/\cuts/\cuts}%
    \ifnum0#1=0\relax%
      \FPeval{\myprod}{1 - \neck*(\myprod)}%
    \else%
      \FPeval{\myprod}{1 - \neck*(1-\myprod)}%
    \fi%
    \clipbox{%
      \value{mycount}\clipsize-\clipsize\relax{} %
      -1pt %
      \wd\mytext-\value{mycount}\clipsize\relax{} %
      -1pt%
    }{\raisebox{#2\dimexpr\ht\mytext-\myprod\ht\mytext}{%
        \scalebox{1}[\myprod]{\usebox{\mytext}}}}%
  }%
  \hspace{\bufferzonecorrection}% STEVEN SUGGESTS SETTING TO -\bufferzone
}


\makeatletter
\ifdefined\XeTeXversion
  \def\@cliptoboxdim#1{%
    \setbox #1=\hbox{%
      \Gin@defaultbp\WIDTH{\wd #1}%
      \Gin@defaultbp \DEPTH {\dp #1}%
      \@tempdima \ht #1%
      \advance\@tempdima\dp#1%
      \Gin@defaultbp \TOTALHEIGHT {\@tempdima }%
      \special{pdf:literal q}% 
      \special{pdf:literal 0 -\DEPTH \space \WIDTH \space \TOTALHEIGHT \space re W n }%
      \rlap{\copy #1}%
      \special {pdf:literal Q}%
      \hskip\wd#1%
    }%
  }
\fi
\makeatother
\begin{document}
\begin{preview}
\bufferzone=-1pt\relax%
\parabtext{0}{.7}{10}{\large TEST TEST TEST}\rule{5pt}{5pt}

\bufferzone=5pt\relax%
\parabtext{0}{.7}{10}{\large TEST TEST TEST}\rule{5pt}{5pt}

\bufferzone=50pt\relax%
\parabtext{0}{.7}{10}{\large TEST TEST TEST}\rule{5pt}{5pt}

\bufferzone=5pt\relax%
\bufferzonecorrection=-\bufferzone\relax
\parabtext{0}{.7}{10}{\large TEST TEST TEST}\rule{5pt}{5pt}

\bufferzone=50pt\relax%
\bufferzonecorrection=-\bufferzone\relax
\parabtext{0}{.7}{10}{\large TEST TEST TEST}\rule{5pt}{5pt}
\end{preview}
\end{document}

enter image description here

You must log in to answer this question.

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