Como salvar a cor atual no PGF/TikZ?

Como salvar a cor atual no PGF/TikZ?

No TikZ/PGF, podemos obter a largura da linha atual usando \pgflinewidth. Infelizmente não existe (até onde eu sei) \pgfstrokecolor, \pgffillcolor, \pgfstrokeopacitye \pgffillopacity.

Minha pergunta principal é: Existe alguma maneira de recuperar o desenho atual e a cor de preenchimento?

Eu sei que a última cor definida por\color pode ser recuperadocom \colorlet{saved}{.}, porque o ponto representa a última cor. E isso pode ser usado quando definimos diretamente a cor como estilo, como em \draw[red] ...(veja o código).

Já tentei hackear \pgfsetstrokecolor, \pgfsetfillcolore \pgfsetcolorde certa forma salvar a última chamada... mas sem sucesso.

No código a seguir estou procurando algum truque para salvar as cores de forma a poder reutilizá-las em outra camada.

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

insira a descrição da imagem aqui

Nota 1:No código a seguir podemos ver que a largura da linha é redefinida após o uso de pgfonlayer. Isso é um bug ou um recurso (documentado)?

Nota 2:Estranhamente a cor do texto sobrevive à mudança da camada, mas não as outras cores, nem a largura da linha.

Nota 3:Tenho a impressão de que \pgfsetcolornão é usado pelo TikZ, mas \colorsim. Se for esse o caso, por quê?


EDITAR: O código acima é apenas um exemplo funcional. Não quero resolver este caso específico sem recuperar as cores.

Responder1

Aqui está uma maneira conceitual de fazer isso. Acho que tem muita coisa para melhorar (menos macros porque só precisa dos dois últimos itens da descrição da cor, controle de expansão adequado, possibilidade de nome de macro customizado) mas não tive tempo. Eu acho que você pode continuar a partir daqui.

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

insira a descrição da imagem aqui

Responder2

A maneira mais simples é a declarativa: use pgfkeyse seu .stylemanipulador para armazenar suas preferências (cor, largura da linha, etc.) e aplicá-las múltiplas vezes.

insira a descrição da imagem aqui

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

informação relacionada