¿Cómo guardar el color actual en PGF/TikZ?

¿Cómo guardar el color actual en PGF/TikZ?

En TikZ/PGF, podemos obtener el ancho de línea actual usando \pgflinewidth. Desafortunadamente, no existe (hasta donde yo sé) \pgfstrokecolor, \pgffillcolor, \pgfstrokeopacityy \pgffillopacity.

Mi pregunta principal es: ¿Hay alguna forma de recuperar el dibujo actual y el color de relleno?

Sé que el último color establecido por\color se puede recuperarcon \colorlet{saved}{.}, porque el punto representa el último color. Y esto se puede usar cuando configuramos directamente el color como un estilo, como en \draw[red] ...(ver el código).

Intenté hackear \pgfsetstrokecolory \pgfsetfillcolorde \pgfsetcoloralguna manera guardar la última llamada... pero sin éxito.

En el siguiente código estoy buscando algún truco para guardar los colores de manera que pueda reutilizarlos en otra capa.

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

ingrese la descripción de la imagen aquí

Nota 1:En el siguiente código podemos ver que el ancho de línea se restablece después del uso de pgfonlayer. ¿Es esto un error o una característica (documentada)?

Nota 2:De manera extraña, el color del texto sobrevive al cambio de capa, pero no los otros colores, ni el ancho de la línea.

Nota 3:Tengo la impresión de que \pgfsetcolorTikZ no lo usa, sino que \colorlo usa. Si este es el caso, ¿por qué?


EDITAR: El código anterior es solo un ejemplo práctico. No quiero resolver este caso en particular sin recuperar los colores.

Respuesta1

A continuación se muestra una forma conceptual de hacerlo. Creo que hay muchas cosas que mejorar (menos macros porque solo necesitas los dos últimos elementos en la descripción del color, control de expansión adecuado, posibilidad de un nombre de macro personalizado) pero no tuve tiempo. Creo que puedes tomarlo desde aquí.

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

ingrese la descripción de la imagen aquí

Respuesta2

La forma sencilla es la declarativa: utilice pgfkeyssu .stylecontrolador para almacenar sus preferencias (color, ancho de línea, etc.) y aplicarlas varias veces.

ingrese la descripción de la imagen aquí

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

información relacionada