Skip to content

Instantly share code, notes, and snippets.

@jason-s
Last active April 1, 2020 16:18
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save jason-s/ebea0a9d5fae9a7d7f5eae2f9620f98e to your computer and use it in GitHub Desktop.
prototype for circuitikz logic gate shapes matching IEEE 91-1984 recommendations, using https://tex.stackexchange.com/a/372996/46076 example as baseline
\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}
\documentclass[border=1mm]{standalone}
\usepackage{circuitikz}
\ctikzset{tripoles/american and port/width/.initial=1.4}
\ctikzset{tripoles/american or port/width/.initial=1.4}
\ctikzset{tripoles/american xor port/width/.initial=1.4}
% not sure how this relates to shape behavior
\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=60} %% changed
\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=60} %% changed
\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
\newdimen\pgf@circ@res@horz % horizontal point
\newdimen\pgf@circ@res@horzb % horizontal point
\newdimen\pgf@circ@res@horzc % horizontal point
\newcommand{\pgf@circ@logicportANSI@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\pgfcircdeclarelogicportANSI#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@logicportANSI@input{\pgfmathcounter}% defined above
}%
%}{}%
\repeatpgfmathloop%
}
% why does commenting this out still work?
%\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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfcircdeclarelogicportANSI{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
\pgf@circ@res@horz=\dimexpr\pgf@circ@res@other+1.4615\pgf@circ@res@up
% 19:26 ratio of width:height
\pgfpathmoveto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@up}}
\pgfpathlineto{\pgfpoint{\pgf@circ@res@other}{\pgf@circ@res@down}}
\pgfpathlineto{\pgfpoint{\pgf@circ@res@horz}{\pgf@circ@res@down}}
\pgfpatharc{-90}{90}{\pgf@circ@res@up}
\pgfpathclose
\pgfusepath{draw}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% nand %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfcircdeclarelogicportANSI{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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfcircdeclarelogicportANSI{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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfcircdeclarelogicportANSI{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}{2\pgf@circ@res@up}%
\pgfmathsetlengthmacro{\pgf@circ@math@yradius}{2\pgf@circ@res@up}%
\pgf@circ@res@other=1.22\pgf@circ@res@right
%% not sure how to compute the right number
\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
% help! not sure how to compute this
\pgf@circ@res@other=0.75\pgf@circ@res@right
\pgf@circ@res@horz=\dimexpr\pgf@circ@res@other - 1.732\pgf@circ@res@up
\pgf@circ@res@horzb=\dimexpr\pgf@circ@res@other - 2.732\pgf@circ@res@up
% 1:2 ratio of width:height
\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{30}{90}{2\pgf@circ@res@up}%
\pgfpathlineto{\pgfpoint{\pgf@circ@res@horzb}{\pgf@circ@res@up}}
\pgfpatharc{30}{-30}{2\pgf@circ@res@up}%
\pgfpathlineto{\pgfpoint{\pgf@circ@res@horz}{\pgf@circ@res@down}}
\pgfpatharc{-90}{-30}{2\pgf@circ@res@up}%
\pgfpathclose
\pgfusepath{draw}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% xor %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfcircdeclarelogicportANSI{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}{2\pgf@circ@res@up}%
\pgfmathsetlengthmacro{\pgf@circ@math@yradius}{2\pgf@circ@res@up}%
\pgf@circ@res@other=1.11\pgf@circ@res@right
%% not sure how to compute the right number
\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
% help! not sure how to compute this
\pgf@circ@res@other=0.75\pgf@circ@res@right
\pgf@circ@res@horz=\dimexpr\pgf@circ@res@other - 1.732\pgf@circ@res@up
\pgf@circ@res@horzb=\dimexpr\pgf@circ@res@other - 2.732\pgf@circ@res@up
% 1:2 ratio of width:height
\pgf@circ@res@horzc=\dimexpr\pgf@circ@res@other - 3.116\pgf@circ@res@up
% 5/26 ratio of xor gap: height
\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{30}{90}{2\pgf@circ@res@up}%
\pgfpathlineto{\pgfpoint{\pgf@circ@res@horzb}{\pgf@circ@res@up}}
\pgfpatharc{30}{-30}{2\pgf@circ@res@up}%
\pgfpathlineto{\pgfpoint{\pgf@circ@res@horz}{\pgf@circ@res@down}}
\pgfpatharc{-90}{-30}{2\pgf@circ@res@up}%
\pgfpathclose
\pgfpathmoveto{\pgfpoint{\pgf@circ@res@horzc}{\pgf@circ@res@up}}
\pgfpatharc{30}{-30}{2\pgf@circ@res@up}%
\pgfusepath{draw}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% xnor %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfcircdeclarelogicportANSI{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] (U1) at (0,0) {\sffamily U1};
\node[american or port] (U2) at (0,1.5) {\sffamily U2};
\node[american xor port] (U3) at (0,3) {\sffamily U3};
\node[american or port,number inputs=4] at (2,0) {};
\node[american xor port,number inputs=6] at (4,0) {};
\node[] at (0,-1) {\sffamily Circuitikz 1.0.2:};
\node[american nand port,number inputs=3] at (0,-2) {};
\node[american nor port,number inputs=5] at (2,-2) {};
\node[american xnor port,number inputs=7] at (4,-2) {};
\draw[-, red] (U1.out) -- (U2.in 1);
\draw[-, red] (U2.out) -- (U3.in 1);
\draw[-, red] (U3.out) -- (U1.in 1);
\end{circuitikz}
\end{document}
@jason-s
Copy link
Author

jason-s commented Apr 1, 2020

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment