6

If TikZ has them it can't be all that difficult.

\documentclass{standalone}
\usepackage{circuitikz}
\makeatother
\begin{document}
\begin{circuitikz}
\node[american and port] at (0,0) {};
\node[american nand port] at (0,-2) {};
\node[american or port] at (2,0) {};
\node[american nor port] at (2,-2) {};
\node[american xor port] at (4,0) {};
\node[american xnor port] at (4,-2) {};
\end{circuitikz}
\end{document}

mwe

9

TikZ uses \pgfutil@g@addto@macro to create anchors, which are presumably saved as global macros with some undocumented naming convention. The key seems to be writing a macro (\pgf@circ@logicport@input) which will locate the anchors using only \savedanchors and one input (\pgfmathcounter).

Another problem is that the left side of various ports are curved, so one needs to be able to compute the edge location for a given y value. To simplify these computations, I used arcs instead of \pgfpathcurveto. I replaced the outer curves as well. The new shapes are not perfect matches, but they are very close. To define the left side arcs I added two new parameters, angle and inner. angle is the starting angle, and inner is the distance from the outer edge to the middle of the curve. The x and y radii are computed using \pgfmath. (Eventually I ran out of length registers and had to use macros.) OTOH, all the aaa through ddd parameters are no longer used.

As is custom for Circuitikz, one can set the number of inputs (inputs) for each type of gate using \ctikzset. I added a node parameter (number inputs) which can be set on a node by node basis. Also, this number can never be less than 2 or greater than 16.

I added origin parameter. Setting origin=0 puts the center anchor in the center of the node. The default setting is 0.8 for backward compatibility. I fixed the text anchor so that one can write part numbers etc. inside the port (if it fits).

\documentclass{standalone}
\usepackage{circuitikz}

\ctikzset{tripoles/american and port/origin/.initial=0.8}
\ctikzset{tripoles/american and port/inputs/.initial=2}

\ctikzset{tripoles/american nand port/origin/.initial=0.8}
\ctikzset{tripoles/american nand port/inputs/.initial=2}

\ctikzset{tripoles/american nor port/origin/.initial=0.8}
\ctikzset{tripoles/american nor port/inputs/.initial=2}
\ctikzset{tripoles/american nor port/angle/.initial=70}
\ctikzset{tripoles/american nor port/inner/.initial=0.3}

\ctikzset{tripoles/american or port/origin/.initial=0.8}
\ctikzset{tripoles/american or port/inputs/.initial=2}
\ctikzset{tripoles/american or port/angle/.initial=70}
\ctikzset{tripoles/american or port/inner/.initial=0.3}

\ctikzset{tripoles/american xor port/origin/.initial=0.8}
\ctikzset{tripoles/american xor port/inputs/.initial=2}
\ctikzset{tripoles/american xor port/angle/.initial=70}
\ctikzset{tripoles/american xor port/inner/.initial=0.3}

\ctikzset{tripoles/american xnor port/origin/.initial=0.8}
\ctikzset{tripoles/american xnor port/inputs/.initial=2}
\ctikzset{tripoles/american xnor port/angle/.initial=70}
\ctikzset{tripoles/american xnor port/inner/.initial=0.3}

\pgfkeys{/tikz/number inputs/.initial=0}
\pgfkeys{/tikz/number inputs/.default=0}

\makeatletter
\newcount{\pgf@circ@res@count}% reserve global register

\newcommand{\pgf@circ@logicport@input}[1]% #1 = \pgfmathcounter
{%
  \pgfextracty{\pgf@circ@res@up}{\northeast}%
  \step
  \pgf@circ@res@step=\dimexpr 2\pgf@y -2\pgf@circ@res@up\relax
  \advance\pgf@y by -#1\pgf@circ@res@step\relax
}%
\long\def\pgfcircdeclarelogicport#1#2{%
    \pgfdeclareshape{american #1 port}%
    {%
    \savedmacro\resize{% automatic
      \pgf@circ@res@up = \pgfkeysvalueof{/tikz/circuitikz/tripoles/american #1 port/height}\pgf@circ@Rlen
      \pgf@circ@res@up = .5\pgf@circ@res@up
      \pgf@circ@res@down = -\pgf@circ@res@up
      \pgf@circ@res@right = \pgfkeysvalueof{/tikz/circuitikz/tripoles/american #1 port/width}\pgf@circ@Rlen
      \pgf@circ@res@right = .5\pgf@circ@res@right
      \pgf@circ@res@left = -\pgf@circ@res@right
    }%
    \savedmacro\inputs{% get number of inputs
      \pgf@circ@res@count=\pgfkeysvalueof{/tikz/number inputs}\relax%
      \ifnum\pgf@circ@res@count=0
        \pgf@circ@res@count=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american #1 port/inputs}\relax%
      \fi
      \ifnum\pgf@circ@res@count<2 \pgf@circ@res@count=2\fi
      \ifnum\pgf@circ@res@count>16 \pgf@circ@res@count=16\fi
      \def\inputs{\the\pgf@circ@res@count}%
    }%
    \savedanchor\step{% 1/2 gap at edges
      \pgf@circ@res@step = \pgfkeysvalueof{/tikz/circuitikz/tripoles/american #1 port/height}\pgf@circ@Rlen
      \divide\pgf@circ@res@step by \pgf@circ@res@count
      \pgfpoint{\pgf@circ@res@left}{\dimexpr\pgf@circ@res@up+0.5\pgf@circ@res@step}%
    }%
      \savedanchor\northeast{\pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@up}}
    \savedanchor\southwest{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@down}}
    \savedanchor\left{\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/american #1 port/port width}\pgf@circ@res@left}{0pt}}
    \savedanchor\right{\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/american #1 port/port width}\pgf@circ@res@right}{0pt}}
    \savedanchor\origin{\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/american #1 port/origin}\pgf@circ@res@right}{0pt}}

    \anchor{center}{\origin}% for backwards compatibility
    \anchor{text}{\pgfpoint{-.5\wd\pgfnodeparttextbox}{\dimexpr.5\dp\pgfnodeparttextbox-.5\ht\pgfnodeparttextbox}}

% create input anchors
    \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@american #1 port\endcsname{%
      \pgfmathloop%
      \ifnum\pgfmathcounter>\pgf@circ@res@count%
      \else%
        %\pgfutil@ifundefined{pgf@anchor@american #1 port@in \pgfmathcounter}{%
          \expandafter\xdef\csname pgf@anchor@american #1 port@in \pgfmathcounter\endcsname{%
            \noexpand\pgf@circ@logicport@input{\pgfmathcounter}% defined above
          }%
        %}{}%
      \repeatpgfmathloop%
    }

      \anchor{out}{\pgfpoint{\pgf@circ@res@right}{0pt}}

    \anchor{left}{\left}% edges of component mius leads
    \anchor{right}{\right}

    \anchor{north east}{\northeast}% see \Compass macro
    \anchor{south west}{\southwest}
    \anchor{north}{\pgfextracty{\pgf@circ@res@up}{\northeast}%
      \pgfpoint{0cm}{\pgf@circ@res@up}}
    \anchor{north west}{\pgfextracty{\pgf@circ@res@up}{\northeast}%
      \pgfextractx{\pgf@circ@res@left}{\southwest}%
      \pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@up}}
    \anchor{west}{\pgfextractx{\pgf@circ@res@left}{\sosuthwest}%
      \pgfpoint{\pgf@circ@res@left}{0cm}}
    \anchor{south}{\pgfextracty{\pgf@circ@res@down}{\southwest}%
      \pgfpoint{0cm}{\pgf@circ@res@down}}
    \anchor{south east}{\pgfextracty{\pgf@circ@res@down}{\southwest}%
      \pgfextractx{\pgf@circ@res@right}{\northeast}%
      \pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@down}}
    \anchor{east}{\pgfextractx{\pgf@circ@res@right}{\northeast}%
      \pgfpoint{\pgf@circ@res@right}{0cm}}

      \backgroundpath{          
            \pgfsetcolor{\pgfkeysvalueof{/tikz/circuitikz/color}}   
            #2
      }
    }
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% and %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfcircdeclarelogicport{and}{
  \pgfextracty{\pgf@circ@res@temp}{\step}%
  \pgf@circ@res@step = \dimexpr 2\pgf@circ@res@temp -2\pgf@circ@res@up\relax
  \pgf@circ@res@count = \inputs\relax
  \loop\ifnum\pgf@circ@res@count>0
    \advance\pgf@circ@res@temp by -\pgf@circ@res@step
      \pgfpathmoveto{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@temp}}%
    \pgfpathlineto{\pgfpoint
        {\pgfkeysvalueof{/tikz/circuitikz/tripoles/american and port/port width}\pgf@circ@res@left}
        {\pgf@circ@res@temp}}
    \advance\pgf@circ@res@count by -1
  \repeat

    \pgfpathmoveto{\pgfpoint{\pgf@circ@res@right}{0pt}}
    \pgfpathlineto{\pgfpoint
        {\pgfkeysvalueof{/tikz/circuitikz/tripoles/american and port/port width}\pgf@circ@res@right}
        {0pt}}

    \pgfusepath{draw}

    \pgfsetlinewidth{2\pgflinewidth}
  \pgf@circ@res@other=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american and port/port width}\pgf@circ@res@left

    \pgfpathmoveto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@up}}
  \pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@down}}
  \pgfpatharc{-90}{90}{-2\pgf@circ@res@other and \pgf@circ@res@up}
  \pgfpathclose
    \pgfusepath{draw}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% nand %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfcircdeclarelogicport{nand}{
    \pgfextracty{\pgf@circ@res@temp}{\step}%
  \pgf@circ@res@step = \dimexpr 2\pgf@circ@res@temp -2\pgf@circ@res@up\relax
  \pgf@circ@res@count = \inputs\relax
  \loop\ifnum\pgf@circ@res@count>0
    \advance\pgf@circ@res@temp by -\pgf@circ@res@step
      \pgfpathmoveto{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@temp}}%
    \pgfpathlineto{\pgfpoint
        {\pgfkeysvalueof{/tikz/circuitikz/tripoles/american nand port/port width}\pgf@circ@res@left}
        {\pgf@circ@res@temp}}
    \advance\pgf@circ@res@count by -1
  \repeat

    \pgfpathmoveto{\pgfpoint{\pgf@circ@res@right}{0pt}}
    \pgfpathlineto{\pgfpoint
        {\pgfkeysvalueof{/tikz/circuitikz/tripoles/american nand port/port width}\pgf@circ@res@right}
        {0pt}}

    \pgfusepath{draw}

    \pgfsetlinewidth{2\pgflinewidth}
    \pgf@circ@res@step = \pgfkeysvalueof{/tikz/circuitikz/tripoles/american nand port/circle width}\pgf@circ@res@right
    \pgf@circ@res@other = \pgfkeysvalueof{/tikz/circuitikz/tripoles/american nand port/port width}\pgf@circ@res@right
  \pgf@circ@res@temp = \dimexpr 2\pgf@circ@res@other - \pgf@circ@res@step\relax

    \pgfpathmoveto{\pgfpoint{-\pgf@circ@res@other}{\pgf@circ@res@up}}
    \pgfpathlineto{\pgfpoint{-\pgf@circ@res@other}{\pgf@circ@res@down}}
  \pgfpatharc{-90}{90}{\pgf@circ@res@temp and \pgf@circ@res@up}
  \pgfpathclose

    \pgfpathellipse
        {\pgfpoint{\pgf@circ@res@other-.5\pgf@circ@res@step}{0pt}}
        {\pgfpoint{.5\pgf@circ@res@step}{0pt}}
        {\pgfpoint{0pt}{.5\pgf@circ@res@step}}

    \pgfusepath{draw}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% nor %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfcircdeclarelogicport{nor}{
  \edef\pgf@circ@math@angle{\pgfkeysvalueof{/tikz/circuitikz/tripoles/american nor port/angle}}%
  \pgf@circ@res@other=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american nor port/inner}\pgf@circ@res@right
  \pgfmathsetlengthmacro{\pgf@circ@math@xradius}{\pgf@circ@res@other /(1 - cos(\pgf@circ@math@angle)}%
  \pgfmathsetlengthmacro{\pgf@circ@math@yradius}{\pgf@circ@res@up /sin(\pgf@circ@math@angle)}%
  \pgf@circ@res@other=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american nor port/port width}\pgf@circ@res@right
  \pgfmathsetlengthmacro{\pgf@circ@math@xorigin}{\pgf@circ@res@other + \pgf@circ@math@xradius*cos(\pgf@circ@math@angle)}%

    \pgfextracty{\pgf@circ@res@temp}{\step}%
  \pgf@circ@res@step = \dimexpr 2\pgf@circ@res@temp -2\pgf@circ@res@up\relax
  \pgf@circ@res@count = \inputs\relax
  \loop\ifnum\pgf@circ@res@count>0
    \advance\pgf@circ@res@temp by -\pgf@circ@res@step
      \pgfpathmoveto{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@temp}}%
    \pgfmathsetmacro{\pgf@circ@math@angle}{asin(\pgf@circ@res@temp/\pgf@circ@math@yradius)}%
    \pgfmathsetlength{\pgf@circ@res@other}{\pgf@circ@math@xradius*cos(\pgf@circ@math@angle)-\pgf@circ@math@xorigin}%
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@temp}}%
    \advance\pgf@circ@res@count by -1
  \repeat

  \pgf@circ@res@other=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american nor port/port width}\pgf@circ@res@right
    \pgfpathmoveto{\pgfpoint{\pgf@circ@res@right}{0pt}}
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{0pt}}

  \pgfusepath{draw}

  \pgfsetlinewidth{2\pgflinewidth}

  \edef\pgf@circ@math@angle{\pgfkeysvalueof{/tikz/circuitikz/tripoles/american nor port/angle}}%
    \pgf@circ@res@step = \pgfkeysvalueof{/tikz/circuitikz/tripoles/american nor port/circle width}\pgf@circ@res@right
  \pgf@circ@res@temp = \dimexpr 2\pgf@circ@res@other - \pgf@circ@res@step\relax
  \advance\pgf@circ@res@other by -\pgf@circ@res@step

  \pgfpathmoveto{\pgfpoint{\pgf@circ@res@other}{0pt}}% for symmetry
  \pgfpatharc{0}{90}{\pgf@circ@res@temp and \pgf@circ@res@up}%
  \pgfpatharc{\pgf@circ@math@angle}{-\pgf@circ@math@angle}{\pgf@circ@math@xradius and \pgf@circ@math@yradius}%
  \pgfpatharc{-90}{0}{\pgf@circ@res@temp and \pgf@circ@res@up}%
  \pgfpathclose

    \pgfpathellipse
        {\pgfpoint{\pgf@circ@res@other+.5\pgf@circ@res@step}{0pt}}
        {\pgfpoint{.5\pgf@circ@res@step}{0pt}}
        {\pgfpoint{0pt}{.5\pgf@circ@res@step}}

    \pgfusepath{draw}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% or %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfcircdeclarelogicport{or}{
    \edef\pgf@circ@math@angle{\pgfkeysvalueof{/tikz/circuitikz/tripoles/american or port/angle}}%
  \pgf@circ@res@other=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american or port/inner}\pgf@circ@res@right
  \pgfmathsetlengthmacro{\pgf@circ@math@xradius}{\pgf@circ@res@other /(1 - cos(\pgf@circ@math@angle)}%
  \pgfmathsetlengthmacro{\pgf@circ@math@yradius}{\pgf@circ@res@up /sin(\pgf@circ@math@angle)}%
  \pgf@circ@res@other=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american or port/port width}\pgf@circ@res@right
  \pgfmathsetlengthmacro{\pgf@circ@math@xorigin}{\pgf@circ@res@other + \pgf@circ@math@xradius*cos(\pgf@circ@math@angle)}%

    \pgfextracty{\pgf@circ@res@temp}{\step}%
  \pgf@circ@res@step = \dimexpr 2\pgf@circ@res@temp -2\pgf@circ@res@up\relax
  \pgf@circ@res@count = \inputs\relax
  \loop\ifnum\pgf@circ@res@count>0
    \advance\pgf@circ@res@temp by -\pgf@circ@res@step
      \pgfpathmoveto{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@temp}}%
    \pgfmathsetmacro{\pgf@circ@math@angle}{asin(\pgf@circ@res@temp/\pgf@circ@math@yradius)}%
    \pgfmathsetlength{\pgf@circ@res@other}{\pgf@circ@math@xradius*cos(\pgf@circ@math@angle)-\pgf@circ@math@xorigin}%
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@temp}}%
    \advance\pgf@circ@res@count by -1
  \repeat

  \pgf@circ@res@other=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american or port/port width}\pgf@circ@res@right
    \pgfpathmoveto{\pgfpoint{\pgf@circ@res@right}{0pt}}
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{0pt}}

  \pgfusepath{draw}

  \pgfsetlinewidth{2\pgflinewidth}

  \edef\pgf@circ@math@angle{\pgfkeysvalueof{/tikz/circuitikz/tripoles/american or port/angle}}%

  \pgfpathmoveto{\pgfpoint{\pgf@circ@res@other}{0pt}}% for symmetry
  \pgfpatharc{0}{90}{2\pgf@circ@res@other and \pgf@circ@res@up}%
  \pgfpatharc{\pgf@circ@math@angle}{-\pgf@circ@math@angle}{\pgf@circ@math@xradius and \pgf@circ@math@yradius}%
  \pgfpatharc{-90}{0}{2\pgf@circ@res@other and \pgf@circ@res@up}%
  \pgfpathclose

    \pgfusepath{draw}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% xor %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfcircdeclarelogicport{xor}{
  \pgfkeysgetvalue{/tikz/circuitikz/tripoles/american xor port/angle}{\pgf@circ@math@angle}%
  \pgf@circ@res@other=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american xor port/inner}\pgf@circ@res@right
  \pgfmathsetlengthmacro{\pgf@circ@math@xradius}{\pgf@circ@res@other /(1 - cos(\pgf@circ@math@angle)}%
  \pgfmathsetlengthmacro{\pgf@circ@math@yradius}{\pgf@circ@res@up / sin(\pgf@circ@math@angle))}%
  \pgf@circ@res@other=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american xor port/port width}\pgf@circ@res@right
  \pgfmathsetlengthmacro{\pgf@circ@math@xorigin}{\pgf@circ@res@other + \pgf@circ@math@xradius*cos(\pgf@circ@math@angle)}%
  \pgf@circ@res@temp=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american xor port/distance}\pgf@circ@res@right
  \pgfmathsetlengthmacro{\pgf@circ@math@distance}{\pgf@circ@res@temp}
% this compensates for the effect of the line width on the gap between the arcs
  \pgfmathsetlengthmacro{\pgf@circ@math@yradiusA}{\pgf@circ@math@yradius -2\pgflinewidth}%
  \pgfmathsetlengthmacro{\pgf@circ@math@xradiusA}{\pgf@circ@math@xradius -2\pgflinewidth}%

    \pgfextracty{\pgf@circ@res@temp}{\step}%
  \pgf@circ@res@step = \dimexpr 2\pgf@circ@res@temp -2\pgf@circ@res@up\relax
  \pgf@circ@res@count = \inputs\relax
  \loop\ifnum\pgf@circ@res@count>0
    \advance\pgf@circ@res@temp by -\pgf@circ@res@step
      \pgfpathmoveto{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@temp}}%
    \pgfmathsetmacro{\pgf@circ@math@angle}{asin(\pgf@circ@res@temp  / \pgf@circ@math@yradiusA)}%
    \pgfmathsetlength{\pgf@circ@res@other}{\pgf@circ@math@xradiusA*cos(\pgf@circ@math@angle)-\pgf@circ@math@xorigin}%
    \advance\pgf@circ@res@other by -\pgf@circ@math@distance
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@temp}}%
    \advance\pgf@circ@res@count by -1
  \repeat

    \pgf@circ@res@other=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american xor port/port width}\pgf@circ@res@right
    \pgfpathmoveto{\pgfpoint{\pgf@circ@res@right}{0pt}}
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{0pt}}

    \pgfusepath{draw}

  \pgfsetlinewidth{2\pgflinewidth}

  \edef\pgf@circ@math@angle{\pgfkeysvalueof{/tikz/circuitikz/tripoles/american xor port/angle}}%

  \pgfpathmoveto{\pgfpoint{\pgf@circ@res@other}{0pt}}% for symmetry
  \pgfpatharc{0}{90}{2\pgf@circ@res@other and \pgf@circ@res@up}%
  \pgfpatharc{\pgf@circ@math@angle}{-\pgf@circ@math@angle}{\pgf@circ@math@xradius and \pgf@circ@math@yradius}%
  \pgfpatharc{-90}{0}{2\pgf@circ@res@other and \pgf@circ@res@up}%
  \pgfpathclose

  \pgfmathsetlength{\pgf@circ@res@temp}{(\pgf@circ@math@yradiusA)*sin(\pgf@circ@math@angle)}%

  \pgfpathmoveto{\pgfpoint{-\pgf@circ@res@other-\pgf@circ@math@distance}{\pgf@circ@res@temp}}% first arc
  \pgfpatharc{\pgf@circ@math@angle}{-\pgf@circ@math@angle}{\pgf@circ@math@xradiusA and \pgf@circ@math@yradiusA}%

    \pgfusepath{draw}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% xnor %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfcircdeclarelogicport{xnor}{
  \pgfkeysgetvalue{/tikz/circuitikz/tripoles/american xnor port/angle}{\pgf@circ@math@angle}%
  \pgf@circ@res@other=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american xnor port/inner}\pgf@circ@res@right
  \pgfmathsetlengthmacro{\pgf@circ@math@xradius}{\pgf@circ@res@other /(1 - cos(\pgf@circ@math@angle)}%
  \pgfmathsetlengthmacro{\pgf@circ@math@yradius}{\pgf@circ@res@up / sin(\pgf@circ@math@angle))}%
  \pgf@circ@res@other=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american xnor port/port width}\pgf@circ@res@right
  \pgfmathsetlengthmacro{\pgf@circ@math@xorigin}{\pgf@circ@res@other + \pgf@circ@math@xradius*cos(\pgf@circ@math@angle)}%
  \pgf@circ@res@temp=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american xor port/distance}\pgf@circ@res@right
  \pgfmathsetlengthmacro{\pgf@circ@math@distance}{\pgf@circ@res@temp}
% this compensates for the effect of the line width on the gap between the arcs
  \pgfmathsetlengthmacro{\pgf@circ@math@yradiusA}{\pgf@circ@math@yradius -2\pgflinewidth}%
  \pgfmathsetlengthmacro{\pgf@circ@math@xradiusA}{\pgf@circ@math@xradius -2\pgflinewidth}%

    \pgfextracty{\pgf@circ@res@temp}{\step}%
  \pgf@circ@res@step = \dimexpr 2\pgf@circ@res@temp -2\pgf@circ@res@up\relax
  \pgf@circ@res@count = \inputs\relax
  \loop\ifnum\pgf@circ@res@count>0
    \advance\pgf@circ@res@temp by -\pgf@circ@res@step
      \pgfpathmoveto{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@temp}}%
    \pgfmathsetmacro{\pgf@circ@math@angle}{asin(\pgf@circ@res@temp  / \pgf@circ@math@yradiusA)}%
    \pgfmathsetlength{\pgf@circ@res@other}{\pgf@circ@math@xradiusA*cos(\pgf@circ@math@angle)-\pgf@circ@math@xorigin}%
    \advance\pgf@circ@res@other by -\pgf@circ@math@distance
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@temp}}%
    \advance\pgf@circ@res@count by -1
  \repeat

    \pgf@circ@res@other=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american xnor port/port width}\pgf@circ@res@right
    \pgfpathmoveto{\pgfpoint{\pgf@circ@res@right}{0pt}}
    \pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{0pt}}

    \pgfusepath{draw}

  \pgfsetlinewidth{2\pgflinewidth}

  \edef\pgf@circ@math@angle{\pgfkeysvalueof{/tikz/circuitikz/tripoles/american xnor port/angle}}%
  \pgf@circ@res@step = \pgfkeysvalueof{/tikz/circuitikz/tripoles/american xnor port/circle width}\pgf@circ@res@right
  \pgf@circ@res@temp = \dimexpr 2\pgf@circ@res@other - \pgf@circ@res@step\relax
  \advance\pgf@circ@res@other by -\pgf@circ@res@step

  \pgfpathmoveto{\pgfpoint{\pgf@circ@res@other}{0pt}}% for symmetry
  \pgfpatharc{0}{90}{\pgf@circ@res@temp and \pgf@circ@res@up}%
  \pgfpatharc{\pgf@circ@math@angle}{-\pgf@circ@math@angle}{\pgf@circ@math@xradius and \pgf@circ@math@yradius}%
  \pgfpatharc{-90}{0}{\pgf@circ@res@temp and \pgf@circ@res@up}%
  \pgfpathclose

    \pgfpathellipse
        {\pgfpoint{\pgf@circ@res@other+.5\pgf@circ@res@step}{0pt}}
        {\pgfpoint{.5\pgf@circ@res@step}{0pt}}
        {\pgfpoint{0pt}{.5\pgf@circ@res@step}}

  \pgf@circ@res@other=\pgfkeysvalueof{/tikz/circuitikz/tripoles/american xnor port/port width}\pgf@circ@res@left
  \pgfmathsetlength{\pgf@circ@res@temp}{(\pgf@circ@math@yradiusA)*sin(\pgf@circ@math@angle)}%

  \pgfpathmoveto{\pgfpoint{\pgf@circ@res@other-\pgf@circ@math@distance}{\pgf@circ@res@temp}}% first arc
  \pgfpatharc{\pgf@circ@math@angle}{-\pgf@circ@math@angle}{\pgf@circ@math@xradiusA and \pgf@circ@math@yradiusA}%

    \pgfusepath{draw}
}
\makeatother
\begin{document}
\begin{circuitikz}
\node[american and port] at (0,0) {};
\node[american nand port,number inputs=3] at (0,-2) {};
\node[american or port,number inputs=4] at (2,0) {};
\node[american nor port,number inputs=5] at (2,-2) {};
\node[american xor port,number inputs=6] at (4,0) {};
\node[american xnor port,number inputs=7] at (4,-2) {};
\end{circuitikz}
\end{document}

demo

  • I hope that your solution some day will be included into package :) – Zarko Jun 3 '17 at 0:48
  • Do you have a similar code for the European ports at hand? – TeXnician Sep 12 '18 at 10:38
  • @TeXnician - No, but it would not be too difficult. They are all just boxes with different symbols inside.. – John Kormylo Sep 12 '18 at 14:32
  • @JohnKormylo Not too difficult is always a good answer. I tried my best to port your solution, see the new answer (is kind of completely different because European ports work differently). – TeXnician Sep 12 '18 at 15:27
  • @TeXnician - I've been working on it, but keep getting an error I cannot track down, even by deleting sections of code. – John Kormylo Sep 12 '18 at 16:55
4

Here is my version of the European gates. Due to size, I am entering this as a separate answer. There is some duplication with the American answer: \pgf@circ@res@count, \pgf@circ@logicport@input and the pgfkey /tikz/number inputs.

\documentclass{standalone}
\tracingmacros=1
\usepackage{circuitikz}

\ctikzset{tripoles/european and port/origin/.initial=0.8}
\ctikzset{tripoles/european and port/inputs/.initial=2}

\ctikzset{tripoles/european nand port/origin/.initial=0.8}
\ctikzset{tripoles/european nand port/inputs/.initial=2}

\ctikzset{tripoles/european or port/origin/.initial=0.8}
\ctikzset{tripoles/european or port/inputs/.initial=2}

\ctikzset{tripoles/european nor port/origin/.initial=0.8}
\ctikzset{tripoles/european nor port/inputs/.initial=2}

\ctikzset{tripoles/european xor port/origin/.initial=0.8}
\ctikzset{tripoles/european xor port/inputs/.initial=2}

\ctikzset{tripoles/european xnor port/origin/.initial=0.8}
\ctikzset{tripoles/european xnor port/inputs/.initial=2}

\ctikzset{tripoles/european not port/origin/.initial=0.8}
\ctikzset{tripoles/european not port/inputs/.initial=1}

\pgfkeys{/tikz/number inputs/.initial=0}
\pgfkeys{/tikz/number inputs/.default=0}

\makeatletter
\newcount{\pgf@circ@res@count}% reserve global register

\newcommand{\pgf@circ@logicport@input}[1]% #1 = \pgfmathcounter
{%
  \pgfextracty{\pgf@circ@res@up}{\northeast}%
  \step
  \pgf@circ@res@step=\dimexpr 2\pgf@y -2\pgf@circ@res@up\relax
  \advance\pgf@y by -#1\pgf@circ@res@step\relax
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% #1 - name
% #2 - text inside
% #3 - number of inputs
% #4 = is it a not?

\long\def\pgfcircdeclareeurologicport#1#2#3#4{
    \pgfdeclareshape{european #1 port}
    {
    \savedmacro\resize{% automatic
      \pgf@circ@res@up = \pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/height}\pgf@circ@Rlen
      \pgf@circ@res@up = .5\pgf@circ@res@up
      \pgf@circ@res@down = -\pgf@circ@res@up
      \pgf@circ@res@right = \pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/width}\pgf@circ@Rlen
      \pgf@circ@res@right = .5\pgf@circ@res@right
      \pgf@circ@res@left = -\pgf@circ@res@right
    }%
    \savedmacro\inputs{% get number of inputs
      \pgf@circ@res@count=\pgfkeysvalueof{/tikz/number inputs}\relax%
      \ifnum\pgf@circ@res@count=0
        \pgf@circ@res@count=\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/inputs}\relax%
      \fi
      \ifnum\pgf@circ@res@count<2 \pgf@circ@res@count=2\fi
      \ifnum\pgf@circ@res@count>16 \pgf@circ@res@count=16\fi
      \def\inputs{\the\pgf@circ@res@count}%
    }%
    \savedanchor\step{% 1/2 gap at edges
      \pgf@circ@res@step = \pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/height}\pgf@circ@Rlen
      \divide\pgf@circ@res@step by #3
      \pgfpoint{\pgf@circ@res@left}{\dimexpr\pgf@circ@res@up+0.5\pgf@circ@res@step}%
    }%
    \savedanchor\northeast{\pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@up}}%
    \savedanchor\southwest{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@down}}%
    \savedanchor\left{\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/reserved}\pgf@circ@res@left}{0pt}}%
    \savedanchor\right{\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/reserved}\pgf@circ@res@right}{0pt}}%
    \savedanchor\origin{\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/origin}\pgf@circ@res@right}{0pt}}%

    \anchor{center}{\origin}% for backwards compatibility
    % the text anchor overlaps the logic symbol
    \anchor{text}{\pgfpoint{-.5\wd\pgfnodeparttextbox}{\dimexpr.5\dp\pgfnodeparttextbox-.5\ht\pgfnodeparttextbox}}%
    % create input anchors
    \ifnum#3=1\relax
      \anchor{in}{\pgfpoint{\pgf@circ@res@left}{0pt}}% or \step
    \else 
      \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@european #1 port\endcsname{%
      \pgfmathloop%
        \ifnum\pgfmathcounter>#3%
        \else%
          %\pgfutil@ifundefined{pgf@anchor@european #1 port@in \pgfmathcounter}{% redundant
            \expandafter\xdef\csname pgf@anchor@european #1 port@in \pgfmathcounter\endcsname{%
              \noexpand\pgf@circ@logicport@input{\pgfmathcounter}% defined above
            }%
          %}{}%
        \repeatpgfmathloop%
      }
    \fi
    \anchor{out}{\pgfpoint{\pgf@circ@res@right}{0pt}}

    \anchor{left}{\left}% edges of component minus leads
    \anchor{right}{\right}

    \anchor{north east}{\northeast}% see \Compass macro
    \anchor{south west}{\southwest}
    \anchor{north}{\pgfextracty{\pgf@circ@res@up}{\northeast}%
      \pgfpoint{0cm}{\pgf@circ@res@up}}
    \anchor{north west}{\pgfextracty{\pgf@circ@res@up}{\northeast}%
      \pgfextractx{\pgf@circ@res@left}{\southwest}%
      \pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@up}}
    \anchor{west}{\pgfextractx{\pgf@circ@res@left}{\sosuthwest}%
      \pgfpoint{\pgf@circ@res@left}{0cm}}
    \anchor{south}{\pgfextracty{\pgf@circ@res@down}{\southwest}%
      \pgfpoint{0cm}{\pgf@circ@res@down}}
    \anchor{south east}{\pgfextracty{\pgf@circ@res@down}{\southwest}%
      \pgfextractx{\pgf@circ@res@right}{\northeast}%
      \pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@down}}
    \anchor{east}{\pgfextractx{\pgf@circ@res@right}{\northeast}%
      \pgfpoint{\pgf@circ@res@right}{0cm}}

      \backgroundpath{          
            \pgfsetcolor{\pgfkeysvalueof{/tikz/circuitikz/color}}   
            \ifnum#3=1\relax
        \pgfpathmoveto{\pgfpoint{\pgf@circ@res@left}{0pt}}%
        \pgfpathlineto{\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/reserved}\pgf@circ@res@left}{0pt}}%
      \else
        \pgfextracty{\pgf@circ@res@temp}{\step}%
        \pgf@circ@res@step = \dimexpr 2\pgf@circ@res@temp -2\pgf@circ@res@up\relax
        %\pgf@circ@res@count = #3\relax% redundant
        \loop\ifnum\pgf@circ@res@count>0
          \advance\pgf@circ@res@temp by -\pgf@circ@res@step
            \pgfpathmoveto{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@temp}}%
          \pgfpathlineto{\pgfpoint
              {\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/reserved}\pgf@circ@res@left}
              {\pgf@circ@res@temp}}
          \advance\pgf@circ@res@count by -1
        \repeat
            \fi
            %
            \pgfpathmoveto{\pgfpoint{\pgf@circ@res@right}{0pt}}
            \pgfpathlineto{%
                \pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/reserved}\pgf@circ@res@right}{0pt}}
            %
            \edef\pgf@temp{not}
            \edef\pgf@circ@temp{#4}
            \ifx\pgf@temp\pgf@circ@temp % is a not
                \pgfpathmoveto{\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/not width}\pgf@circ@res@right}{0pt}}
                \pgfpathlineto{\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/reserved}\pgf@circ@res@right}%
          {\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/not height}\pgf@circ@res@up}}
            \fi
            %
            \pgfusepath{draw}
            %
            \pgfpathmoveto{\pgfpointorigin}
            \pgftext{#2}
            %
            \pgfsetlinewidth{2\pgflinewidth}
            \pgfpathrectanglecorners
                {\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/reserved}\pgf@circ@res@left}{\pgf@circ@res@up}}
                {\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/reserved}\pgf@circ@res@right}{\pgf@circ@res@down}}
            \pgfusepath{draw}
%
%
      }
    }
}
\pgfcircdeclareeurologicport{and}{$\&$}{\pgf@circ@res@count}{}
\pgfcircdeclareeurologicport{or}{$\ge 1$}{\pgf@circ@res@count}{}
\pgfcircdeclareeurologicport{xor}{$=1$}{\pgf@circ@res@count}{}
\pgfcircdeclareeurologicport{not}{$1$}{1}{not}
\pgfcircdeclareeurologicport{nand}{$\&$}{\pgf@circ@res@count}{not}
\pgfcircdeclareeurologicport{nor}{$\ge 1$}{\pgf@circ@res@count}{not}
\pgfcircdeclareeurologicport{xnor}{$=1$}{\pgf@circ@res@count}{not}
\makeatother

\begin{document}
\begin{circuitikz}
\node[european and port] (A) at (0,0) {};
\node[european nand port,number inputs=3] at (0,-2) {};
\node[european or port,number inputs=4] at (2,0) {};
\node[european nor port,number inputs=5] at (2,-2) {};
\node[european xor port,number inputs=6] at (4,0) {};
\node[european xnor port,number inputs=7] at (4,-2) {};
\node[european not port] (B) at (0,-4) {};
\draw[red] (A.center) -- (B.center);

\end{circuitikz}
\end{document}

demo

  • This is great (+1). Maybe you should suggest the author to include this code in the package (at github.com/circuitikz/circuitikz/issues I guess). If you don't want to do this, but would agree to I could open an issue. – TeXnician Sep 12 '18 at 19:38
  • Of course, they would no longer be tripoles. – John Kormylo Sep 13 '18 at 2:07
  • That's probably something the developer should decide. I have opened an issue at github.com/circuitikz/circuitikz/issues/105. – TeXnician Sep 13 '18 at 7:43
  • @TeXnician John Kormylo I am trying to collect all the enhancement and doing pull requests through my fork... would you mind if I add your code? I would need an "A U Thor <author@example.com> attribution for the patch... – Rmano Nov 4 '18 at 8:07
  • 1
    @Rmano I'll try to look at it over the weekend. I'll respond to your comment on GitHub then. – TeXnician Feb 21 at 17:48
2

Just for those who are interested in the European ports, here is an adaption of the American ports created by John Kormylo (I hope I did not mess it up completely).

european ports

\documentclass{standalone}
\usepackage{circuitikz}

\ctikzset{tripoles/european and port/origin/.initial=0.8}
\ctikzset{tripoles/european and port/inputs/.initial=2}

\ctikzset{tripoles/european nand port/origin/.initial=0.8}
\ctikzset{tripoles/european nand port/inputs/.initial=2}

\ctikzset{tripoles/european nor port/origin/.initial=0.8}
\ctikzset{tripoles/european nor port/inputs/.initial=2}

\ctikzset{tripoles/european or port/origin/.initial=0.8}
\ctikzset{tripoles/european or port/inputs/.initial=2}

\ctikzset{tripoles/european xor port/origin/.initial=0.8}
\ctikzset{tripoles/european xor port/inputs/.initial=2}

\ctikzset{tripoles/european xnor port/origin/.initial=0.8}
\ctikzset{tripoles/european xnor port/inputs/.initial=2}

\pgfkeys{/tikz/number inputs/.initial=0}
\pgfkeys{/tikz/number inputs/.default=0}

\makeatletter
\newcount{\pgf@circ@res@count}% reserve global register
\newcommand{\pgf@circ@logicport@input}[1]% #1 = \pgfmathcounter
{%
  \pgfextracty{\pgf@circ@res@up}{\northeast}%
  \step
  \pgf@circ@res@step=\dimexpr 2\pgf@y -2\pgf@circ@res@up\relax
  \advance\pgf@y by -#1\pgf@circ@res@step\relax
}

\long\def\pgfcircdeclareeurologicport#1#2#3#4{
    \pgfdeclareshape{european #1 port}
    {
    \savedmacro\resize{% automatic
      \pgf@circ@res@up = \pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/height}\pgf@circ@Rlen
      \pgf@circ@res@up = .5\pgf@circ@res@up
      \pgf@circ@res@down = -\pgf@circ@res@up
      \pgf@circ@res@right = \pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/width}\pgf@circ@Rlen
      \pgf@circ@res@right = .5\pgf@circ@res@right
      \pgf@circ@res@left = -\pgf@circ@res@right
    }%
    \savedmacro\inputs{% get number of inputs
      \pgf@circ@res@count=\pgfkeysvalueof{/tikz/number inputs}\relax%
      \ifnum\pgf@circ@res@count=0
        \pgf@circ@res@count=\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/inputs}\relax%
      \fi
      \ifnum\pgf@circ@res@count<2 \pgf@circ@res@count=2\fi
      \ifnum\pgf@circ@res@count>16 \pgf@circ@res@count=16\fi
      \def\inputs{\the\pgf@circ@res@count}%
    }%
    \savedanchor\step{% 1/2 gap at edges
      \pgf@circ@res@step = \pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/height}\pgf@circ@Rlen
      \divide\pgf@circ@res@step by \pgf@circ@res@count
      \pgfpoint{\pgf@circ@res@left}{\dimexpr\pgf@circ@res@up+0.5\pgf@circ@res@step}%
    }%
    \savedanchor\northwest{%
      \pgf@y=\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/height}\pgf@circ@Rlen
      \pgf@y=.5\pgf@y
      \pgf@x=-\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/width}\pgf@circ@Rlen
      \pgf@x=.5\pgf@x
    } 
    \savedanchor\northeast{\pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@up}}
    \savedanchor\southwest{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@down}}
    \savedanchor\left{\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/reserved}\pgf@circ@res@left}{0pt}}
    \savedanchor\right{\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/reserved}\pgf@circ@res@right}{0pt}}
    \savedanchor\origin{\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/origin}\pgf@circ@res@right}{0pt}}
      %
    \anchor{center}{\origin}% for backwards compatibility
    \anchor{text}{\pgfpoint{-.5\wd\pgfnodeparttextbox}{\dimexpr.5\dp\pgfnodeparttextbox-.5\ht\pgfnodeparttextbox}}
        %
      \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@european #1 port\endcsname{%
      \pgfmathloop%
      \ifnum\pgfmathcounter>\pgf@circ@res@count%
      \else%
        %\pgfutil@ifundefined{pgf@anchor@american #1 port@in \pgfmathcounter}{%
          \expandafter\xdef\csname pgf@anchor@european #1 port@in \pgfmathcounter\endcsname{%
            \noexpand\pgf@circ@logicport@input{\pgfmathcounter}% defined above
          }%
        %}{}%
      \repeatpgfmathloop%
    }
    %
    \anchor{out}{\pgfpoint{\pgf@circ@res@right}{0pt}}
        %
    \anchor{left}{\left}% edges of component mius leads
    \anchor{right}{\right}
        %
    \anchor{north east}{\northeast}% see \Compass macro
    \anchor{south west}{\southwest}
    \anchor{north}{\pgfextracty{\pgf@circ@res@up}{\northeast}%
      \pgfpoint{0cm}{\pgf@circ@res@up}}
    \anchor{north west}{\pgfextracty{\pgf@circ@res@up}{\northeast}%
      \pgfextractx{\pgf@circ@res@left}{\southwest}%
      \pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@up}}
    \anchor{west}{\pgfextractx{\pgf@circ@res@left}{\sosuthwest}%
      \pgfpoint{\pgf@circ@res@left}{0cm}}
    \anchor{south}{\pgfextracty{\pgf@circ@res@down}{\southwest}%
      \pgfpoint{0cm}{\pgf@circ@res@down}}
    \anchor{south east}{\pgfextracty{\pgf@circ@res@down}{\southwest}%
      \pgfextractx{\pgf@circ@res@right}{\northeast}%
      \pgfpoint{\pgf@circ@res@right}{\pgf@circ@res@down}}
    \anchor{east}{\pgfextractx{\pgf@circ@res@right}{\northeast}%
      \pgfpoint{\pgf@circ@res@right}{0cm}}
      \backgroundpath{          
            \pgfsetcolor{\pgfkeysvalueof{/tikz/circuitikz/color}}   
            \northwest
            \pgf@circ@res@up = \pgf@y 
            \pgf@circ@res@down = -\pgf@y
            \pgf@circ@res@right = -\pgf@x
            \pgf@circ@res@left = \pgf@x
            \def\pgf@temp{1}
            \def\pgf@circ@temp{#3}
            \pgfextracty{\pgf@circ@res@temp}{\step}%
          \pgf@circ@res@step = \dimexpr 2\pgf@circ@res@temp -2\pgf@circ@res@up\relax
          \pgf@circ@res@count = \inputs\relax
          \loop\ifnum\pgf@circ@res@count>0
            \advance\pgf@circ@res@temp by -\pgf@circ@res@step
          \pgfpathmoveto{\pgfpoint{\pgf@circ@res@left}{\pgf@circ@res@temp}}%
            \pgfpathlineto{\pgfpoint
                {\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/reserved}\pgf@circ@res@left}
              {\pgf@circ@res@temp}}
            \advance\pgf@circ@res@count by -1
          \repeat
            %
            \pgfpathmoveto{\pgfpoint{\pgf@circ@res@right}{0pt}}
            \pgfpathlineto{
                \pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/reserved}\pgf@circ@res@right}{0pt}}
            %
            \edef\pgf@temp{not}
            \edef\pgf@circ@temp{#4}
            \ifx\pgf@temp\pgf@circ@temp % is a not
                \pgfpathmoveto{\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/not width}\pgf@circ@res@right}{0pt}}
                \pgfpathlineto{\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/reserved}\pgf@circ@res@right}{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/not height}\pgf@circ@res@up}}
            \fi
            %
            \pgfusepath{draw}
            %
            \pgfpathmoveto{\pgfpointorigin}
            \pgftext{#2}
            %
            \pgfsetlinewidth{2\pgflinewidth}
            \pgfpathrectanglecorners
                {\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/reserved}\pgf@circ@res@left}{\pgf@circ@res@up}}
                {\pgfpoint{\pgfkeysvalueof{/tikz/circuitikz/tripoles/european #1 port/reserved}\pgf@circ@res@right}{\pgf@circ@res@down}}
            \pgfusepath{draw}
      }
    }
}

\pgfcircdeclareeurologicport{and}{$\&$}{2}{}
\pgfcircdeclareeurologicport{or}{$\ge 1$}{2}{}
\pgfcircdeclareeurologicport{xor}{$=1$}{2}{}
\pgfcircdeclareeurologicport{not}{$1$}{1}{not}
\pgfcircdeclareeurologicport{nand}{$\&$}{2}{not}
\pgfcircdeclareeurologicport{nor}{$\ge 1$}{2}{not}
\pgfcircdeclareeurologicport{xnor}{$=1$}{2}{not}
\makeatother
\begin{document}
\begin{circuitikz}
\node[european and port] at (0,0) {};
\node[european nand port,number inputs=3] at (0,-2) {};
\node[european or port,number inputs=4] at (2,0) {};
\node[european nor port,number inputs=5] at (2,-2) {};
\node[european xor port,number inputs=6] at (4,0) {};
\node[european xnor port,number inputs=7] at (4,-2) {};
\end{circuitikz}
\end{document}
  • What are angle and inner used for? – John Kormylo Sep 12 '18 at 16:53
  • @JohnKormylo They are not needed, I removed them as well as the saved anchor \inOne. – TeXnician Sep 12 '18 at 16:57
  • You also need to work on the not port. – John Kormylo Sep 12 '18 at 17:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.