% pgf/tikz library
% for signal flow diagrams
%
% Author: Dr. Karlheinz Ochs, Ruhr-University of Bochum, Germany
% Version: 0.1
% Date: 2007/01/05

% Known bugs: - Anchors of source shape are not precisely positioned.
%             - Anchor border of source shape is a rectangle.
%             - The bounding box of standard text label is ignored.


%
% Styles for nodes, terminals, and operators.
%
% - building blocks
\tikzstyle{block color}%
   = [draw=\blockdrawcolor,
      fill=\blockfillcolor]
\tikzstyle{block style}%
   = [block color,
      line width=\blocklinewidth,
      text centered]
\tikzstyle{block}%
   = [rectangle,
      block style,
      minimum width=\blockwidth,
      minimum height=\blockheight,
      text width=\blocktextwidth]
\tikzstyle{filter}%
   = [rectangle,
      block style,
      minimum width=\filterwidth,
      minimum height=\filterheight,
      text width=\filtertextwidth]
\tikzstyle{source}%
   = [source shape,
      operator style]
\tikzstyle{serial parallel converter}%
   = [serial parallel converter shape,
      block style,
      minimum width=10mm,
      minimum height=20mm,
      inner sep=2mm]
\tikzstyle{parallel serial converter}%
   = [parallel serial converter shape,
      block style,
      minimum width=10mm,
      minimum height=20mm,
      inner sep=2mm]
\tikzstyle{symbol mapper}%
   = [symbol mapper shape,
      block style,
      text centered,
      minimum size=20mm,
      text width=18mm]
\tikzstyle{inverse symbol mapper}%
   = [inverse symbol mapper shape,
      block style,
      text centered,
      minimum size=20mm,
      text width=18mm]


%
% Shape of a source.
%
\newbox\pgfnodeparttextbox
\pgfdeclareshape{source shape}
{
  \savedanchor\westpoint{
    \pgf@x=\wd\pgfnodeparttextbox%
    \advance\pgf@x by\pgfshapeouterxsep%
    \pgf@y=.5\ht\pgfnodeparttextbox%
    \advance\pgf@y by-.5\dp\pgfnodeparttextbox%
  }
  \saveddimen\radius{
    \setlength\pgf@x{\pgfshapeminwidth}
  }
  \anchor{west}{\westpoint}
  \anchor{north west}{
    \pgf@process{\westpoint}
    \advance\pgf@y by\radius
  }
  \anchor{north}{%
    \pgf@process{\westpoint}
    \pgf@xa=\radius\advance\pgf@x by+0.5\pgf@xa
    \pgf@ya=\radius\advance\pgf@y by+0.866025\pgf@ya
  }
  \anchor{north east}{%
    \pgf@process{\westpoint}
    \pgf@xa=\radius\advance\pgf@x by+0.866025\pgf@xa
    \pgf@ya=\radius\advance\pgf@y by+0.5\pgf@ya
  }
  \anchor{east}{
    \pgf@process{\westpoint}
    \advance\pgf@x by\radius
    \advance\pgf@x by0.5\pgflinewidth
  }
  \anchor{south east}{%
    \pgf@process{\westpoint}
    \pgf@xa=\radius\advance\pgf@x by+0.866025\pgf@xa
    \pgf@ya=\radius\advance\pgf@y by-0.5\pgf@ya
  }
  \anchor{south}{%
    \pgf@process{\westpoint}
    \pgf@xa=\radius\advance\pgf@x by+0.5\pgf@xa
    \pgf@ya=\radius\advance\pgf@y by-0.866025\pgf@ya
  }
  \anchor{south west}{
    \pgf@process{\westpoint}
    \advance\pgf@y by-\radius
  }
  \anchor{center}{
    \pgf@process{\westpoint}
    \pgf@xa=\radius\advance\pgf@x by+0.5\pgf@xa
  }
  % node part
  \nodeparts{text}
  \anchor{text}{
    \pgf@process{\westpoint}
    \pgf@xa=\radius
    \advance\pgf@y by-.5\ht\pgfnodeparttextbox%
    \advance\pgf@x by-\wd\pgfnodeparttextbox%
    \advance\pgf@x by-0.5mm
  }
  \anchorborder{%
    \pgf@xb=\pgf@x% xb/yb is target
    \pgf@yb=\pgf@y%
    % southwest
    \westpoint\advance\pgf@y by-\radius
    \pgf@xa=\pgf@x% xa/ya is se
    \pgf@ya=\pgf@y%
    % northeast
    \westpoint\advance\pgf@x by\radius\advance\pgf@y by\radius%
    \advance\pgf@x by-\pgf@xa%
    \advance\pgf@y by-\pgf@ya%
    \pgf@xc=.5\pgf@x% x/y is half width/height
    \pgf@yc=.5\pgf@y%
    \advance\pgf@xa by\pgf@xc% xa/ya becomes center
    \advance\pgf@ya by\pgf@yc%
    \edef\pgf@marshal{%
      \noexpand\pgfpointborderrectangle
      {\noexpand\pgfpoint{\the\pgf@xb}{\the\pgf@yb}}
      {\noexpand\pgfpoint{\the\pgf@xc}{\the\pgf@yc}}%
    }%
    \pgf@process{\pgf@marshal}%
    \advance\pgf@x by\pgf@xa%
    \advance\pgf@y by\pgf@ya%
  }
  % Background path
  \backgroundpath{
  {\pgftransformreset{\pgfnodeparttextbox}}
    \westpoint \pgf@xa=\pgf@x \pgf@ya=\pgf@y
    \advance\pgf@y by\radius
    \pgfmoveto{\pgfpoint{\pgf@x}{\pgf@y}}
    \pgfpatharc{90}{-90}{\radius}
    \pgfclosepath
 }
}


%
% Shape of a serial to parallel converter.
%
\newbox\pgfnodepartSbox
\newbox\pgfnodepartPbox
\pgfdeclareshape{serial parallel converter shape}
{
  % inherit from rectangle
  \inheritsavedanchors[from=rectangle]
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{south east}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchorborder[from=rectangle]
  \inheritanchorborder[from=rectangle]
  \inheritbackgroundpath[from=rectangle]
  % terminal anchors
  \anchor{in}{%
    \northeast
    \pgf@ya=0.5\pgf@y
    \southwest
    \pgf@y=0.5\pgf@y
    \advance\pgf@y by+\pgf@ya%
  }
  \anchor{out1}{
    \southwest
    \pgf@ya=0.9\pgf@y
    \northeast
    \pgf@y=0.1\pgf@y
    \advance\pgf@y by\pgf@ya%
  }
  \anchor{out2}{
    \southwest
    \pgf@ya=0.7\pgf@y
    \northeast
    \pgf@y=0.3\pgf@y
    \advance\pgf@y by\pgf@ya%
  }
  \anchor{outl}{
    \southwest
    \pgf@ya=0.1\pgf@y
    \northeast
    \pgf@y=0.9\pgf@y
    \advance\pgf@y by\pgf@ya%
  }
  \anchor{dots}{
    \southwest
    \pgf@ya=0.4\pgf@y
    \northeast
    \pgf@y=0.6\pgf@y
    \advance\pgf@y by\pgf@ya%
    \setlength{\pgf@xa}{\xspace}
    \advance\pgf@x by.5\pgf@xa%
  }
  % node parts
  \nodeparts{S,P}
  \anchor{S}{
    \southwest
    \pgf@xa=\pgf@x
    \northeast
    \pgf@x=\pgf@xa
    \advance\pgf@y by-\ht\pgfnodepartSbox%
    \advance\pgf@y by-.5\dp\pgfnodepartSbox%
    \advance\pgf@x by+\pgfshapeinnerxsep%
    \advance\pgf@y by-\pgfshapeinnerysep%
  }
  \anchor{P}{
    \northeast
    \pgf@xa=\pgf@x
    \southwest
    \pgf@x=\pgf@xa
    \advance\pgf@x by-\wd\pgfnodepartPbox%
    \advance\pgf@x by-\pgfshapeinnerxsep%
    \advance\pgf@y by+\pgfshapeinnerysep%
  }
  % diagonal line S/P
  \foregroundpath{%
    \pgfpathmoveto{\pgfpointadd{\southwest}{\pgfpoint{\pgfshapeouterxsep}{\pgfshapeouterysep}}}
    \pgfpathlineto{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfshapeouterxsep}{\pgfshapeouterysep}}}}
  }
}

%
% Shape of a parallel to serial converter.
%
\newbox\pgfnodepartSbox
\newbox\pgfnodepartPbox
\pgfdeclareshape{parallel serial converter shape}
{
  % inherit from rectangle
  \inheritsavedanchors[from=rectangle]
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{south east}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchorborder[from=rectangle]
  \inheritanchorborder[from=rectangle]
  \inheritbackgroundpath[from=rectangle]
  % terminal anchors
  \anchor{out}{%
    \southwest
    \pgf@ya=0.5\pgf@y
    \northeast
    \pgf@y=0.5\pgf@y
    \advance\pgf@y by+\pgf@ya%
  }
  \anchor{in1}{
    \northeast
    \pgf@ya=0.1\pgf@y
    \southwest
    \pgf@y=0.9\pgf@y
    \advance\pgf@y by\pgf@ya%
  }
  \anchor{in2}{
    \northeast
    \pgf@ya=0.3\pgf@y
    \southwest
    \pgf@y=0.7\pgf@y
    \advance\pgf@y by\pgf@ya%
  }
  \anchor{inl}{
    \northeast
    \pgf@ya=0.9\pgf@y
    \southwest
    \pgf@y=0.1\pgf@y
    \advance\pgf@y by\pgf@ya%
  }
  \anchor{dots}{
    \northeast
    \pgf@ya=0.6\pgf@y
    \southwest
    \pgf@y=0.4\pgf@y
    \advance\pgf@y by\pgf@ya%
    \setlength{\pgf@xa}{\xspace}
    \advance\pgf@x by-.5\pgf@xa%
  }
  % node parts
  \nodeparts{P,S}
  \anchor{P}{
    \southwest
    \pgf@xa=\pgf@x
    \northeast
    \pgf@x=\pgf@xa
    \advance\pgf@y by-\ht\pgfnodepartPbox%
    \advance\pgf@y by-.5\dp\pgfnodepartPbox%
    \advance\pgf@x by+\pgfshapeinnerxsep%
    \advance\pgf@y by-\pgfshapeinnerysep%
  }
  \anchor{S}{
    \northeast
    \pgf@xa=\pgf@x
    \southwest
    \pgf@x=\pgf@xa
    \advance\pgf@x by-\wd\pgfnodepartSbox%
    \advance\pgf@x by-\pgfshapeinnerxsep%
    \advance\pgf@y by+\pgfshapeinnerysep%
  }
  % diagonal line S/P
  \foregroundpath{%
    \pgfpathmoveto{\pgfpointadd{\southwest}{\pgfpoint{\pgfshapeouterxsep}{\pgfshapeouterysep}}}
    \pgfpathlineto{\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfshapeouterxsep}{\pgfshapeouterysep}}}}
  }
}


%
% Shape of a symbol mapper.
%
\pgfdeclareshape{symbol mapper shape}
{
  % rectangle anchors
  \inheritsavedanchors[from=rectangle]
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{south east}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchorborder[from=rectangle]
  % terminal anchors
  \anchor{out}{%
    \southwest
    \pgf@ya=0.5\pgf@y
    \northeast
    \pgf@y=0.5\pgf@y
    \advance\pgf@y by+\pgf@ya%
  }
  \anchor{in1}{
    \northeast
    \pgf@ya=0.1\pgf@y
    \southwest
    \pgf@y=0.9\pgf@y
    \advance\pgf@y by\pgf@ya%
  }
  \anchor{in2}{
    \northeast
    \pgf@ya=0.3\pgf@y
    \southwest
    \pgf@y=0.7\pgf@y
    \advance\pgf@y by\pgf@ya%
  }
  \anchor{dots}{
    \northeast
    \pgf@ya=0.6\pgf@y
    \southwest
    \pgf@y=0.4\pgf@y
    \advance\pgf@y by\pgf@ya%
    \setlength{\pgf@xa}{\xspace}
    \advance\pgf@x by-.5\pgf@xa%
  }
  \anchor{inl}{
    \northeast
    \pgf@ya=0.9\pgf@y
    \southwest
    \pgf@y=0.1\pgf@y
    \advance\pgf@y by\pgf@ya%
  }
  % rectangle shaped frame
  \backgroundpath{
    \pgfpathrectanglecorners
    {\pgfpointadd{\southwest}{\pgfpoint{\pgfshapeouterxsep}{\pgfshapeouterysep}}}
    {\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfshapeouterxsep}{\pgfshapeouterysep}}}}
  }

  \inheritbackgroundpath[from=rectangle]
}


%
% Shape of an inverse symbol mapper.
%
\pgfdeclareshape{inverse symbol mapper shape}
{
  % rectangle anchors
  \inheritsavedanchors[from=rectangle]
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{south east}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchorborder[from=rectangle]
  % terminal anchors
  \anchor{in}{%
    \northeast
    \pgf@ya=0.5\pgf@y
    \southwest
    \pgf@y=0.5\pgf@y
    \advance\pgf@y by+\pgf@ya%
  }
  \anchor{out1}{
    \southwest
    \pgf@ya=0.9\pgf@y
    \northeast
    \pgf@y=0.1\pgf@y
    \advance\pgf@y by\pgf@ya%
  }
  \anchor{out2}{
    \southwest
    \pgf@ya=0.7\pgf@y
    \northeast
    \pgf@y=0.3\pgf@y
    \advance\pgf@y by\pgf@ya%
  }
  \anchor{outl}{
    \southwest
    \pgf@ya=0.1\pgf@y
    \northeast
    \pgf@y=0.9\pgf@y
    \advance\pgf@y by\pgf@ya%
  }
  \anchor{dots}{
    \southwest
    \pgf@ya=0.4\pgf@y
    \northeast
    \pgf@y=0.6\pgf@y
    \advance\pgf@y by\pgf@ya%
    \setlength{\pgf@xa}{\xspace}
    \advance\pgf@x by.5\pgf@xa%
  }
  % rectangle shaped frame
  \backgroundpath{
    \pgfpathrectanglecorners
    {\pgfpointadd{\southwest}{\pgfpoint{\pgfshapeouterxsep}{\pgfshapeouterysep}}}
    {\pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\pgfshapeouterxsep}{\pgfshapeouterysep}}}}
  }

  \inheritbackgroundpath[from=rectangle]
}

\endinput
