几个月前,我记得读过一篇文章,其中 LaTeX 的元类型系统用于使文档从一种字体淡入另一种字体。该示例有几页衬线文本,在文档末尾慢慢过渡到无衬线字体 - 这种变化很微妙,不易察觉,但最终效果却相当引人注目(衬线与无衬线)。
问题是,我如何在自己的文档中执行此操作?我尝试在 CTAN 上搜索,但没有找到结果。
是否有一个软件包可以让我实现这个目标?
编辑:
我能找到最接近这个描述的东西是
[摘自道格拉斯·R·霍夫施塔特的《元字体、元数学和形而上学:对唐纳德·克努斯的《元字体的概念》的评论》。重印于图 12.1超魔法主题,第 241 页。本文作为第 13 章收录在同一合集中,并附有后记。示例来自 Knuth 的论文可视化语言16.1(1982),可作为PDF来自期刊的在线档案。但如果您的网速较慢,请不要点击该链接!]
类似这样的内容可以应用于较长的文本吗?
答案1
方法 1
我认为,这只是拙劣的模仿,无法达到预期效果。它不是通过演变字体结构来实现的,而是通过两种固定字体之间的渐变机制来实现的。因此,在中间状态中,存在可见的叠加。
通过设置\fadefrom
和\fadeto
,您可以选择起始和最终目的地,正如我下面所做的三次。目前,结果的字母宽度是两种字体中较宽的字体,因此更改为宽度相差很大的字体效果不佳。
这使用了一种\FadeAfter{<length>}{<text>}
语法。
\documentclass{article}
\usepackage{xcolor,stackengine,tikz}
\newcommand\fadefrom{}
\newcommand\fadeto{\textsf}
\newcommand\fade[1]{%
\edef\antitwo{\the\numexpr100-#2\relax}%
\ifnum\antitwo>99\relax\def\antitwo{99}\else%
\ifnum\antitwo<10\relax\edef\antitwo{0\antitwo}\else%
\ifnum\antitwo<1\relax\def\antitwo{1}\fi\fi\fi%
\ifnum#2>50\relax
\stackengine{0pt}%
{\tikz\node[inner sep=0pt, opacity=1]{%
\textcolor{black!\antitwo}{\strut\fadeto{#1}}};}%
{\tikz\node[inner sep=0pt, opacity=1]{\textcolor{black!#2}{\strut\fadefrom{#1}}};}%
{O}{c}{F}{F}{L}%
\else%
\stackengine{0pt}%
{\tikz\node[inner sep=0pt, opacity=1]{\textcolor{black!#2}{\strut\fadefrom{#1}}};}%
{\tikz\node[inner sep=0pt, opacity=1]{%
\textcolor{black!\antitwo}{\strut\fadeto{#1}}};}%
{O}{c}{F}{F}{L}%
\fi%
}
%%%
\usepackage{ifthen}
\newcounter{tmpcounter}
\newlength\critlength
\newlength\tmplength
\newcount\mynum
\newcount\myden
\makeatletter
\newcommand\FadeAfter[1]{%
\critlength=#1\relax%
\def\cumstring{}\fahelp{#1}{#2}}
\newcommand\fahelp[1]{\fahelper#2 \relax\relax}
\def\fahelper#1 #2\relax{%
\global\protected@edef\cumstring{\cumstring#1\ }%
\setbox0=\hbox{\cumstring}%
\tmplength=.01\critlength\relax%
\mynum=\wd0\relax%
\myden=\tmplength\relax%
\divide\mynum by\myden%
\setcounter{tmpcounter}{\numexpr100-\the\mynum}%
\ifnum\thetmpcounter<0\setcounter{tmpcounter}{0}\fi%
\fadehelperB{\thetmpcounter}#1\relax\ %
\ifx\relax#2\relax\else\fahelp{\critlength}{#2\relax}\fi%
}
\def\fadehelperB#1#2#3\relax{%
\fade{#2}{#1}\ifx\relax#3\relax\else\fadehelperB{#1}#3\relax\fi%
}
\makeatother
\parskip 1ex
\begin{document}
\sloppypar
\FadeAfter{10in}{%
Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal.}
\def\fadefrom{\ttfamily}
\def\fadeto{\fontfamily{pcr}\selectfont}
\FadeAfter{24in}{%
Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this.}
\def\fadefrom{}
\def\fadeto{\fontfamily{ppl}\selectfont}
\FadeAfter{60in}{%
But, in a larger sense, we can not dedicate {{---}} we can not consecrate {{---}} we can not hallow {{---}} this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us {{---}} that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion {{---}} that we here highly resolve that these dead shall not have died in vain {{---}} that this nation, under God, shall have a new birth of freedom {{---}} and that government of the people, by the people, for the people, shall not perish from the earth.}
\end{document}
第一段从罗马字体淡化为 CM 的无衬线字体。
第二段从 CM 淡入
\ttfamily
到 PCR(Courier)字体。第三段从 CM roman 逐渐变为 Palatino roman。
下面,我尝试
\newcommand\fadefrom{\edef\tmp{\the\numexpr\antitwo/3\relax}%
\ifnum\tmp<10\edef\tmp{0\tmp}\fi%
\scalebox{1.\tmp}[1]}
\newcommand\fadeto{\edef\tmp{\the\numexpr\antitwo/2\relax}%
\ifnum\tmp<10\edef\tmp{0\tmp}\fi%
\sffamily\scalebox{1.\tmp}[1]}
我可以实现结果的逐步延伸。
飞涨:
方法 2
通过替换\fadehelperB
宏,并使用像 Bruno 的\slantbox
(剪切变换一个“盒子”) 和 Malipivo 的 pdf 特刊 (TikZ:文本周围有光晕?),我可以生成不涉及叠加字体的结果。但是,它并不代表两种任意字体之间的真正转换。相反,它以 3 种方式同时连续地转换单个字体:
改变水平拉伸;
改变字体粗细;以及
改变字体倾斜度
在下面的例子中,字体轮廓厚度(pdfliteral 参数)从 0.66 变为 0;水平拉伸从 1.75 变为 1;倾斜度从 0.25 变为 0。
\documentclass{article}
\usepackage{xcolor,tikz}
%%%
\usepackage{ifthen}
\newcounter{tmpcounter}
\newlength\critlength
\newlength\tmplength
\newcount\mynum
\newcount\myden
\makeatletter
\newcommand\FadeAfter[2]{%
\critlength=#1\relax%
\def\cumstring{}\fahelp{#1}{#2}}
\newcommand\fahelp[2]{\fahelper#2 \relax\relax}
\def\fahelper#1 #2\relax{%
\global\protected@edef\cumstring{\cumstring#1\ }%
\setbox0=\hbox{\cumstring}%
\tmplength=.01\critlength\relax%
\mynum=\wd0\relax%
\myden=\tmplength\relax%
\divide\mynum by\myden%
\setcounter{tmpcounter}{\numexpr100-\the\mynum}%
\ifnum\thetmpcounter<1\setcounter{tmpcounter}{1}\fi%
\fadehelperB{\thetmpcounter}#1\relax\ %
\ifx\relax#2\relax\else\fahelp{\critlength}{#2\relax}\fi%
}
\def\fadehelperB#1#2\relax{%
\def\tmp{\the\numexpr2*#1/3\relax}% FONT OUTLINE THICKNESS VARIES FROM .66 TO 0
\ifnum\tmp<1\relax\def\tmp{1}\fi%
\ifnum\tmp<10\relax\def\thickness{.0\tmp}\else\def\thickness{.\tmp}\fi%
\edef\tmp{\the\numexpr3*#1/4\relax}% H-STRETCH VARIES FROM 1.75 TO 1
\ifnum\tmp<10\edef\tmp{0\tmp}\fi%
\edef\tmpC{\the\numexpr#1/4\relax}% SLANT VARIES FROM .25 TO 0
\ifnum\tmpC<10\edef\tmpC{0\tmpC}\fi%
\scalebox{1.\tmp}[1]{\slantbox[.\tmpC]{\outline{#2}}}}
%%% MALIPIVO's PDF SPECIAL TO CHANGE FONT OUTLINE THICKNESS/COLOR
% https://tex.stackexchange.com/questions/18472/tikz-halo-around-text/169549#169549
\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%
}
\makeatother
\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
}
\bordercolor{black}
\fillcolor{black}
%%% BRUNO's \slantbox
% https://tex.stackexchange.com/questions/63179/shear-transform-a-box/63188#63188
\newsavebox\foobox
\newcommand{\slantbox}[2][.2]{\mbox{%
\sbox{\foobox}{#2}%
\hskip\wd\foobox
\pdfsave
\pdfsetmatrix{1 0 #1 1}%
\llap{\usebox{\foobox}}%
\pdfrestore
}}
%%%
\parskip 1ex
\begin{document}
\sloppypar
\FadeAfter{10in}{%
Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal.}
\FadeAfter{24in}{%
Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this.}
\FadeAfter{60in}{%
But, in a larger sense, we can not dedicate {{---}} we can not consecrate {{---}} we can not hallow {{---}} this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us {{---}} that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion {{---}} that we here highly resolve that these dead shall not have died in vain {{---}} that this nation, under God, shall have a new birth of freedom {{---}} and that government of the people, by the people, for the people, shall not perish from the earth.}
\end{document}