使用自定义字体创建文本形状

使用自定义字体创建文本形状

我正在尝试使用自定义字体绘制不同形状的文本。

在...的帮助下史蒂文,我能够让大多数我需要的文本形状正常工作。请参阅问题这里

一切都运行良好,除了使用自定义字体。我使用带有自定义字体的fontspecXeLaTeX。下面是我用来生成最终输出的内容:

\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}

当我不使用自定义字体(即删除线条)时,此方法很有效\setmainfont

使用自定义字体时,字体的左侧会被截断。以下是 Helvetica 的示例:

以 Helvetica 为例

Helvetica 还不错,但其他一些字体就更糟糕了,比如耐嚼

以 Chewy 为例

答案1

在这里,我尝试列出工作中的问题。对于我的 MWE,我只对论点进行 10 次垂直切片,因为我认为看到实际切片有助于直观地了解这里的问题。

参数文本在保存框中设置\mytext。根据定义,保存框的宽度仅与分配给字形的空间一样宽。通常(某些字体比其他字体更甚),字形会超出其分配的保存框的水平边缘。在这种情况下,字形的悬垂部分会被截断。

我的 MWE 的第一行显示了这一点,其中我人为地使内核缓冲区1pt小于参数的实际宽度。

在我对另一个问题的原始回答中,我在.2pt参数 ( \savebox{\mytext}{\kern.2pt#5\kern.2pt}) 之前和之后添加了一个小的空间缓冲区,以尝试避免这种截断。对于某些字体,OP 发现该缓冲区不够用。因此,在我上面的评论中,我建议创建一个长度,这里称为 ,\bufferzone用户可以以字体相关的方式设置该长度以添加该空间缓冲区。但这有两个复杂之处:

  1. 文本向右移动了 ,并且后面\bufferzone有一个死区(这在我的 MWE 输出的第二行和第三行中显示,其中分别设置为和);并且\bufferzone\bufferzone5pt50pt

  2. 缓冲区也要进行切片和切块,因此剩余切片的分辨率会降低,因为一些切片会浪费在空白处。

上述第 1 项的修正是在切片过程之前和之后撤消缓冲区,这是我\bufferzonecorrection在 MWE 中执行的操作。这是我的 MWE 输出的第 4 行和第 5 行执行的操作。在确信此方法正确后,我建议\bufferzonecorrection在我的 MWE 中将其替换为-\bufferzone

上面的第 2 项无法修复,但可以通过\bufferzone为所选字体选择适当的值来将其影响最小化。因此,输出的第 4 行和第 5 行不是“优化的”,因为在空白(但不可见)空间上浪费了几个切片,结果与第 1 行的输出明显不同。

\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}

在此处输入图片描述

相关内容