![Beamer 块的透明阴影破解是否被破坏?](https://linux22.com/image/422324/Beamer%20%E5%9D%97%E7%9A%84%E9%80%8F%E6%98%8E%E9%98%B4%E5%BD%B1%E7%A0%B4%E8%A7%A3%E6%98%AF%E5%90%A6%E8%A2%AB%E7%A0%B4%E5%9D%8F%EF%BC%9F.png)
我用过Beamer 阻止透明阴影破解很长一段时间了(更具体地说,最后一个答案提供了两个修改过的 Beamer 文件以在本地安装)。然而,似乎最近(可能是在升级到 TeX Live 2020 之后;Beamer 现在为 2020/07/22 v3.59),黑客被破解了。
据我所知,似乎第一个块获得了正确的阴影,但之后,阴影几何形状似乎被冻结了,并且任何后续块都会获得与第一个块大小相同的阴影。
以下是重现该问题的最简单的示例:
\documentclass{beamer}
\setbeamertemplate{blocks}[rounded][shadow=true]
\begin{document}
\begin{frame}
\begin{columns}[t]
\begin{column}{.25\textwidth}
\begin{block}{First block}
This is the first block.
\end{block}
\end{column}
\begin{column}{.75\textwidth}
\begin{block}{Second block}
This is the second block.
\end{block}
\end{column}
\end{columns}
\end{frame}
\end{document}
以下是我现在得到的:
任何帮助都值得感激!日志文件是这里。
答案1
问题在于 pgf 修正了其代码中的拼写错误。
\ifx \csname pgfsmaks@#1\endcsname \relax \pgf@sys@pdf@install@mask % old working pgf
^^^ typo
\ifx \csname pgfsmask@#1\endcsname \relax \pgf@sys@pdf@install@mask % new failing pgf
这个拼写错误有一个副作用,如果你声明了两个同名的淡入淡出或阴影,你仍然会在 pdf 中得到两个阴影对象。更正后,这种情况不再有效。
beamer hack 依赖于这个副作用 - 它使用名称bmb@shadowhorz
和bmb@shadowvert
所有垂直阴影。
为了纠正这个问题,必须引入唯一的名称,例如通过添加数字
% this assumes that the local beamerbasebox.sty is used!!!!
\documentclass{beamer}
\makeatletter
\def\pgfutil@insertatbegincurrentpagefrombox#1{%
\edef\pgf@temp{\the\wd\pgfutil@abb}%
\global\setbox\pgfutil@abb\hbox{%
\unhbox\pgfutil@abb%
\hskip\dimexpr2in-2\hoffset-\pgf@temp\relax% changed
#1%
\hskip\dimexpr-2in-2\hoffset\relax% new
}%
}
\newcount\pgf@shadingboxcnt
\def\endbeamerboxesrounded{%
\end{minipage}\egroup%
\bmb@temp=\dp\bmb@box%
\advance\bmb@temp by.5pt%
\setbox\bmb@box=\hbox{\raise\bmb@temp\hbox{\box\bmb@box}}%
\dp\bmb@box=0pt%
\bmb@boxwidth=\bmb@width%
\bmb@boxheight=\ht\bmb@box%
\advance\bmb@boxheight by4bp%
\advance\bmb@boxheight by\bmb@prevheight%
\ifbmb@shadow%
\global\advance \pgf@shadingboxcnt by 1
\pgfdeclareradialshading{bmb@shadowball}{\pgfpointorigin}
{%
color(0bp)=(pgftransparent!50);
color(4bp)=(pgftransparent!100)
}%
\pgfdeclareradialshading{bmb@shadowballlarge}{\pgfpointorigin}
{%
color(0bp)=(pgftransparent!0);
color(8bp)=(pgftransparent!100)
}%
\pgfdeclarehorizontalshading{bmb@shadowhorz\the\pgf@shadingboxcnt}{\bmb@boxheight-6bp}
{%
color(0bp)=(pgftransparent!0);
color(8bp)=(pgftransparent!100)
}%
\pgfdeclareverticalshading{bmb@shadowvert\the\pgf@shadingboxcnt}{\bmb@boxwidth-4bp}
{%
color(0bp)=(pgftransparent!100);
color(8bp)=(pgftransparent!0)
}%
\pgfdeclarefading{bmb@shadowmask\the\pgf@shadingboxcnt}
{%
\begin{pgfpicture}
\pgftext[at=\pgfpoint{4bp}{4bp}]{\pgfuseshading{bmb@shadowball}}
\pgftext[at=\pgfpoint{\bmb@boxwidth}{8bp}]{\pgfuseshading{bmb@shadowballlarge}}
\pgftext[at=\pgfpoint{\bmb@boxwidth+4bp}{\bmb@boxheight+2bp}]{\pgfuseshading{bmb@shadowball}}
\pgftext[left, at=\pgfpoint{4bp}{4bp}]{\pgfuseshading{bmb@shadowvert\the\pgf@shadingboxcnt}}
\pgftext[base, at=\pgfpoint{\bmb@boxwidth+4bp}{8bp}]{\pgfuseshading{bmb@shadowhorz\the\pgf@shadingboxcnt}}
%
% clipping is needed because shadow is typeset on top of box
\begin{pgfscope}
\pgfsetcolor{black}
\pgfpathrectangle{\pgfpoint{4bp}{8bp}}{\pgfpoint{\[email protected]}{\bmb@boxheight-2bp}}
\pgfusepath{fill}
\end{pgfscope}
\end{pgfpicture}
}%
\fi%
\bmb@temp=\bmb@width%
\bmb@dima=\bmb@temp\advance\bmb@dima by2.2bp%
\bmb@dimb=\bmb@temp\advance\bmb@dimb by4bp%
\hbox{%
\begin{pgfpicture}{0bp}{0bp}{0bp}{0bp}
\ifbmb@shadow%
\begin{pgfscope}
\pgfpathrectangle{\pgfpoint{0bp}{-7bp}}
{\pgfpoint{\bmb@boxwidth+8bp}{\bmb@boxheight+6bp}}
\pgfsetfading{bmb@shadowmask\the\pgf@shadingboxcnt}{%
\pgftransformshift{\pgfpoint{0.5\bmb@boxwidth+6bp}{0.5\bmb@boxheight-4bp}}}
\pgfusepath{fill}
\end{pgfscope}
\fi%
\unhbox\bmb@colorbox%
\pgfpathqmoveto{-4bp}{1bp}
\pgfpathqcurveto{-4bp}{-1.2bp}{-2.2bp}{-3bp}{0bp}{-3bp}
\pgfpathlineto{\pgfpoint{\the\bmb@temp}{-3bp}}
\pgfpathcurveto%
{\pgfpoint{\the\bmb@dima}{-3bp}}%
{\pgfpoint{\the\bmb@dimb}{-1.2bp}}%
{\pgfpoint{\the\bmb@dimb}{1bp}}%
{
\bmb@dima=\ht\bmb@box%
\pgfpathlineto{\pgfpoint{\bmb@dimb}{\bmb@dima}}
\pgfpathlineto{\pgfpoint{-4bp}{\bmb@dima}}
\pgfusepath{fill}
}
\end{pgfpicture}%
\box\bmb@box%
}%
\ifbmb@shadow%
\vskip4bp minus 2bp%
\else%
\vskip2bp%
\fi%
\egroup% of \vbox\bgroup
}
\makeatother
\setbeamertemplate{background canvas}{\includegraphics[height=\paperheight]{example-image}}
\setbeamertemplate{blocks}[rounded][shadow=true]
\begin{document}
\begin{frame}
\begin{columns}[t]
\begin{column}{.25\textwidth}
\begin{block}{First block}
This is the first block.
\end{block}
\end{column}
\begin{column}{.75\textwidth}
\begin{block}{Second block}
This is the second block.
\end{block}
\end{column}
\end{columns}
\end{frame}
\end{document}
经过此修正,该样式在 xelatex 中也适用,因此在不久的将来它可能会被添加到 beamer 中。