Beamer 块的透明阴影破解是否被破坏?

Beamer 块的透明阴影破解是否被破坏?

我用过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}

以下是我现在得到的:

第二个 Beamer 块的阴影几何形状错误

任何帮助都值得感激!日志文件是这里

答案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@shadowhorzbmb@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 中。

答案2

以下是该问题的答案,由山姆·卡特其他地方:只要你仍在使用 PGF 版本 3.1.5b 或更早版本,此破解仍然有效。这些版本可能这里

如果有人具备 PGF 的适当知识,可以将其更新到较新的版本,那就太好了。

相关内容