如何在 PGF/TikZ 中保存当前颜色?

如何在 PGF/TikZ 中保存当前颜色?

在 TikZ/PGF 中,我们可以使用 获取当前线宽。不幸的是,\pgflinewidth据我所知,没有\pgfstrokecolor\pgffillcolor和。\pgfstrokeopacity\pgffillopacity

我的主要问题是:有什么方法可以恢复当前的绘制和填充颜色?

我知道最后的颜色是由\color 可以恢复\colorlet{saved}{.},因为点代表最后一种颜色。这可以在我们直接将颜色设置为样式时使用,就像在\draw[red] ...(参见代码)中一样。

我尝试进行破解\pgfsetstrokecolor\pgfsetfillcolor\pgfsetcolor以某种方式保存最后一个通话...但没有成功。

在下面的代码中,我正在寻找一些技巧来保存颜色,以便能够在另一个图层中重复使用它们。

\documentclass[varwidth,border=50]{standalone}
\usepackage{tikz}

\pgfdeclarelayer{foreground}
\pgfsetlayers{main,foreground}

\begin{document}
  \begin{tikzpicture}[green, draw=red, ultra thick, fill=yellow, text=purple]
    \filldraw (-.5,-.5) rectangle +(1,1) node[midway]{A};
    \pgfmathsetlengthmacro{\savedpgflinewidth}{\pgflinewidth}
    \colorlet{saved}{.}
    \def\pgfstrokecolor{red} % <- to be replaced by \strokecolorlet
    \def\pgffillcolor{yellow} % <- to be replaced by \fillcolorlet

    \begin{pgfonlayer}{foreground}
      \draw (0,0) rectangle +(1,1) node[midway]{B};
      \color{saved} % <- restore the color set by \color{green}
      \pgfsetlinewidth{\savedpgflinewidth} % <- restore the line width
      \draw (.5,.5) rectangle +(1,1) node[midway]{C};
      \pgfsetstrokecolor{\pgfstrokecolor} % <- restore the draw color
      \pgfsetfillcolor{\pgffillcolor} % <- restore the fill color
      \filldraw (1,1) rectangle +(1,1) node[midway]{D};
    \end{pgfonlayer}

    \filldraw (1.5,1.5) rectangle +(1,1) node[midway]{E}; % <- line width reset after pgfonlayer !
  \end{tikzpicture}
\end{document}

在此处输入图片描述

注1:在下面的代码中,我们可以看到使用后线宽被重置pgfonlayer。这是一个错误还是(记录的)功能?

笔记2:奇怪的是,文本颜色会随着图层变化而变化,但其他颜色和线宽却不会变化。

注3:我的印象是\pgfsetcolorTikZ 没有使用 ,而是\color使用了 。如果是这样,为什么?


编辑:上面的代码只是一个工作示例。我不想在不恢复颜色的情况下解决这个特殊情况。

答案1

这是概念性的做法。我认为有很多地方需要改进(更少的宏,因为您只需要颜色描述中的最后两项、适当的扩展控制、自定义宏名称的可能性),但我没有时间。我想你可以从这里开始。

\documentclass[varwidth,border=50]{standalone}
\usepackage{tikz}
\makeatletter
\tikzset{get stroke color/.code={%
    \expandafter\global% Jump over, now we have \global
    \expandafter\let% Jump over now we have \global\let
    \expandafter\pgfsavedstrokecolor% Jump we have \global\let\pgf...
    \csname\string\color@pgfstrokecolor\endcsname% Finally expand this and put it at the end 
    },                                           % \global\let\pgf...{} in expanded form 
    restore stroke color/.code={\pgf@setstrokecolor#1},
}


\begin{document}
  \begin{tikzpicture}[green, draw=yellow!20!blue, ultra thick, fill=yellow, text=purple]
    \tikzset{get stroke color}% <-- Gets the drive-dependent low-level desc of y!20!b
    \show\pgfsavedstrokecolor% <-- Look at the log
    \filldraw (0,0) rectangle +(1,1) node[midway]{A};
    \pgfsetstrokecolor{orange} % <-- Change the drawing color to orange
    \draw (0.5,0.5) rectangle +(1,1) node[midway]{B}; % <-- Draw something to verify
    \tikzset{restore stroke color/.expand once=\pgfsavedstrokecolor} % <-- Restore it back
    \draw (1,1) rectangle +(1,1) node[midway]{C}; % <-- Verify
  \end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

简单的方法是声明式的方式:使用pgfkeys及其.style处理程序来存储您的偏好(颜色、线宽等)并多次应用它们。

在此处输入图片描述

\documentclass[varwidth,border=50]{standalone}
\usepackage{tikz}

\pgfdeclarelayer{foreground}
\pgfsetlayers{main,foreground}

\begin{document}
\tikzset{my preferecences/.style={green, draw=red, ultra thick,fill=yellow, text=purple}}
\begin{tikzpicture}[my preferecences]
    \filldraw (-.5,-.5) rectangle +(1,1) node[midway]{A};
    \begin{pgfonlayer}{foreground}
      \begin{scope}[my preferecences]
      \draw (0,0) rectangle +(1,1) node[midway]{B};
      \draw (.5,.5) rectangle +(1,1) node[midway]{C};
      \filldraw (1,1) rectangle +(1,1) node[midway]{D};
      \end{scope}
    \end{pgfonlayer}

    \filldraw (1.5,1.5) rectangle +(1,1) node[midway]{E}; % <- line width reset after pgfonlayer !
  \end{tikzpicture}
\end{document}

相关内容