Pgf basic layer: struggling (again) with colors

colortikz-pgf

This question is linked (but not the same) to this other one.

I am trying to make the color in circuitikz more reasonable to use. Now I am struggling with managing colors at a low level. In my shapes, I need to fill parts of them with the specified fill color, and others that should always be filled with the stroke (or draw) color.
I naïvely tried this:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\pgfdeclareshape{sline}{
    \anchor{center}{\pgfpointorigin}%
    \behindbackgroundpath{
        \pgfpathmoveto{\pgfpoint{-0.3cm}{0pt}}%
        \pgfpathlineto{\pgfpoint{0.3cm}{0pt}}%
        \pgfusepath{draw}%
        % lower rectangle
        \pgfpathrectanglecorners{\pgfpoint{-0.3cm}{-4pt}}{\pgfpoint{0.3cm}{-8pt}}
        \pgfusepath{fill, draw}
        % upper rectangle
        \pgfpathrectanglecorners{\pgfpoint{-0.3cm}{4pt}}{\pgfpoint{0.3cm}{8pt}}
        % \pgfsetfillcolor{cyan}% <- works, always cyan
        \pgfsetfillcolor{pgfstrokecolor}% I expected a red color...
        \pgfusepath{draw, fill}
    }
}
\begin{document}
\color{blue} Text
\begin{tikzpicture}[]
    \draw[] (0,1)  node [sline]{} (1,1) node{aaa};
    \draw[red, fill=green] (0,0)  node [sline]{} (1,0) node{bbb};
\end{tikzpicture}
\end{document}

Which fails as:

enter image description here

So I am here again: there is a way to say: ok, from now on make the fill color equal to the draw (stroke) color? That means that in the above example, the upper rectangle should be filled in red, or in whatever color is specified in the \draw -> like the "bbb" text is doing.

###update

Thanks to Ulrike Fischer, I have more data here. It seems that the simple red, which is the same as color=red, fills the \tikz@textcolor macro but not \tikz@strokecolor, which is empty. If you specify draw=red then you have the other way around. What is strange, is that if you say red, or color=red, the stroke color is red as the text color, so I expected it filled both.

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\makeatletter
\pgfdeclareshape{sline}{
    \anchor{center}{\pgfpointorigin}%
    \behindbackgroundpath{
        \pgfpathmoveto{\pgfpoint{-0.3cm}{0pt}}%
        \pgfpathlineto{\pgfpoint{0.3cm}{0pt}}%
        \pgfusepath{draw}%
        % lower rectangle
        \pgfpathrectanglecorners{\pgfpoint{-0.3cm}{-4pt}}{\pgfpoint{0.3cm}{-8pt}}
        \pgfusepath{fill, draw}
        % upper rectangle
        \pgfpathrectanglecorners{\pgfpoint{-0.3cm}{4pt}}{\pgfpoint{0.3cm}{8pt}}
        %
        % \pgfsetfillcolor{cyan}% <- works, always cyan
        % \pgfsetfillcolor{pgfstrokecolor}% I expected a red color...
        % \pgfsetfillcolor{\tikz@strokecolor}
        \pgfcircsetfillcolorifnotempty{\tikz@strokecolor}
        % \ifdefempty\tikz@strokecolor{}{\pgfsetfillcolor{\tikz@strokecolor}}
        \typeout{COLORstroke \tikz@strokecolor}
        \typeout{COLORtext \tikz@textcolor}
        \typeout{}
        \pgfusepath{draw, fill}
    }
}
\def\pgfcircsetfillcolorifnotempty#1{%
    \ifx#1\pgfutil@empty
    \else
        \pgfsetfillcolor{#1}%
    \fi
}

\makeatother
\begin{document}
\color{blue} Text
\begin{tikzpicture}[]
    \draw[] (0,1)  node [sline]{} ++(1,0) node[draw,fill]{aaa};
    \draw[red, fill=green] (0,0)  node [sline]{} ++(1,0) node[draw,fill]{bbb};
    \draw[draw=red, fill=green] (0,-1)  node [sline]{} ++(1,0) node[draw,fill]{bbb};
    \draw[color=red, fill=green] (0,-2)  node [sline]{} ++(1,0) node[draw,fill]{bbb};
\end{tikzpicture}
\end{document}

enter image description here

and it says:

COLORstroke 
COLORtext 

COLORstroke 
COLORtext red

COLORstroke red
COLORtext 

COLORstroke 
COLORtext red

so maybe I have a solution…

Best Answer

Thanks to the help by users in the comments — Ulrike Fischer for providing a tool to explore things, and muzimuzhi Z for this answer and for showing me the internals of TikZ colors, I managed to find a (partial, but still) solution.

That will fail if the user change draw color mid-path, but I think it's the best option for now. Moreover, if the color is changed mid-path it will fail, as shown in the last example --- which is a bit of a pity; if the sline where all red (in the sense that the color was the one at the moment of the building of the behindbackgroundpath I'd be happier, but...).

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usepackage{circuitikz}
\usepackage{regexpatch} % for the starred-form of \xpatchcmd
\makeatletter
\let\ctikz@strokecolor\pgfutil@empty
\pgfkeys{/tikz/color/.add code={}{\edef\ctikz@strokecolor{#1}}}
% note `/tikz/.unknown/.@body` is not updated
\pgfkeysgetvalue{/tikz/.unknown/.@cmd}{\my@temp}
\xpatchcmd*\my@temp % use starred-form to replace all (two places actually)
  {\expandafter\tikz@addoption\expandafter}
    {\edef\ctikz@strokecolor{\tikz@key}%
    \expandafter\tikz@addoption\expandafter}
  {}{%
  \pgfutil@packagewarning{circuitikz}{%
    Color patch failed, expect strange colors (see manual)}}
\pgfkeyslet{/tikz/.unknown/.@cmd}{\my@temp}
%
\pgfdeclareshape{sline}{
    \anchor{center}{\pgfpointorigin}%
    \behindbackgroundpath{
        \pgfpathmoveto{\pgfpoint{-0.3cm}{0pt}}%
        \pgfpathlineto{\pgfpoint{0.3cm}{0pt}}%
        \pgfusepath{draw}%
        % lower rectangle
        \pgfpathrectanglecorners{\pgfpoint{-0.3cm}{-4pt}}{\pgfpoint{0.3cm}{-8pt}}
        \pgfusepath{fill, draw}
        % upper rectangle
        \pgfpathrectanglecorners{\pgfpoint{-0.3cm}{4pt}}{\pgfpoint{0.3cm}{8pt}}
        %
        % \pgfsetfillcolor{cyan}% <- works, always cyan
        \pgf@circ@setfillcolorasdraw
        \pgfusepath{draw, fill}
        \pgfsetcolor{black}
        \pgftext[y=10pt]{\tiny S:\tikz@strokecolor~T:\tikz@textcolor~F:\tikz@fillcolor}
        \pgftext[y=16pt]{\tiny CS:\ctikz@strokecolor}
    }
}
\def\pgf@circ@setfillcolorasdraw{%
    \ifx\tikz@strokecolor\pgfutil@empty
        \ifx\ctikz@strokecolor\pgfutil@empty
            \pgfsetfillcolor{.}
        \else
            \pgfsetfillcolor{\ctikz@strokecolor}
        \fi
    \else
        % we have strokecolor, yay!
        \pgfsetfillcolor{\tikz@strokecolor}
    \fi
}
\makeatother
\begin{document}

\color{blue} Text default is blue
\begin{tikzpicture}[baseline=2cm]
    \draw[] (0,2) node [sline]{} ++(1,0) node[draw,fill]{A} ++(1,0) node[right]{no options};
    \draw[red] (0,1) node [sline]{} ++(1,0) node[draw,fill]{B} ++(1,0) node[right]{red};
    \draw[red, fill=green] (0,0) node [sline]{} ++(1,0) node[draw,fill]{C} ++(1,0) node[right]{red, fill=green};
    \draw[color=red, fill=green] (0,-1) node [sline]{} ++(1,0) node[draw,fill]{D} ++(1,0) node[right]{color=red, fill=green};
    \draw[draw=red, fill=green] (0,-2) node [sline]{} ++(1,0) node[draw,fill]{E} ++(1,0) node[right]{draw=red, fill=green};
    \draw[text=red, fill=green] (0,-3) node [sline]{} ++(1,0) node[draw,fill]{F} ++(1,0) node[right]{text=red, fill=green};
    \draw[red] (0,-4) node [sline]{} ++(1,0) [black] node[draw,fill]{F} ++(1,0) node[right]{red, then black};
\end{tikzpicture}

\end{document}

enter image description here

Now my problem is that I am not sure if this is an enhancement from the previous state of circuitikz... I'll think a bit about it.