summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/yquant/yquant-draw.tex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2020-03-24 20:57:29 +0000
committerKarl Berry <karl@freefriends.org>2020-03-24 20:57:29 +0000
commit2788d9fb9b228a993b9396b91c9fcd4845635b64 (patch)
tree134367b5ecbcd84d94aa0946a6aa94be11b92027 /Master/texmf-dist/tex/latex/yquant/yquant-draw.tex
parent5de4049c3701b77b230e19cd22c0f1b0e3ac762e (diff)
yquant (24mar20)
git-svn-id: svn://tug.org/texlive/trunk@54527 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/yquant/yquant-draw.tex')
-rw-r--r--Master/texmf-dist/tex/latex/yquant/yquant-draw.tex422
1 files changed, 422 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-draw.tex b/Master/texmf-dist/tex/latex/yquant/yquant-draw.tex
new file mode 100644
index 00000000000..baaac6ac0d2
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/yquant/yquant-draw.tex
@@ -0,0 +1,422 @@
+% BEGIN_FOLD Actual drawing at shipout
+\newcount\yquant@draw@@currentcontroltype%
+
+\protected\def\yquant@draw@group#1#2#3#4#5{%
+ \begingroup%
+ \def\yquant@draw@@x{#1}%
+ \ifx F#2%
+ \yquant@draw@@currentcontroltype=0 %
+ \else%
+ \yquant@draw@@currentcontroltype=\yquant@register@get@type{#2}\relax%
+ \fi%
+ \let\yquant@circuit@extendcontrolline@cmd=\empty%
+ \let\yquant@circuit@extendcontrolline@prev=\relax%
+ \yquant@langhelper@list@attrs%
+ % If the quotes library is loaded, activate it. (else, this is by default \relax)
+ \tikz@enable@node@quotes%
+ \yquant@set{#3}%
+ \def\yquant@draw@@style{#4}%
+ \def\yquant@draw@@content{#5}%
+ \def\yquant@draw@@idx@content{0}%
+ \def\yquant@draw@@idx@pcontrol{0}%
+ \def\yquant@draw@@idx@ncontrol{0}%
+}
+
+\protected\def\yquant@draw@endgroup#1#2#3{%
+ \unless\ifx F#1%
+ \yquant@draw@cline%
+ \fi%
+ \ifcase#3\relax%
+ \or%
+ \yquant@draw@alias@ctrl{#2}n%
+ \or%
+ \yquant@draw@alias@ctrl{#2}p%
+ \or%
+ \yquant@draw@alias@ctrl{#2}p%
+ \yquant@draw@alias@ctrl{#2}n%
+ \or%
+ \yquant@draw@alias{#2}%
+ \or%
+ \yquant@draw@alias{#2}%
+ \yquant@draw@alias@ctrl{#2}n%
+ \or%
+ \yquant@draw@alias{#2}%
+ \yquant@draw@alias@ctrl{#2}p%
+ \or%
+ \yquant@draw@alias{#2}%
+ \yquant@draw@alias@ctrl{#2}p%
+ \yquant@draw@alias@ctrl{#2}n%
+ \fi%
+ \endgroup%
+}
+
+\protected\long\def\yquant@draw@single#1#2{%
+ \let\idx=\yquant@draw@@idx@content%
+ \edef\cmd{%
+ \noexpand\path (\yquant@draw@@x, \yquant@register@get@y{#1})%
+ node[/yquant/every operator, \yquant@draw@@style, /yquant/this operator,%
+ name prefix=, name suffix=, name=yquantbox]%
+ {\unexpanded\expandafter{\yquant@draw@@content}};%
+ }%
+ \cmd%
+ \ifpgfpointshapexproj{yquantbox}%
+ \yquant@circuit@extendwire{#1}%
+ \fi%
+ \yquant@circuit@extendcontrolline\yquant@draw@@currentcontroltype\yquant@draw@@x%
+ % check for empty name parameter
+ \if\relax\detokenize{#2}\relax%
+ \else%
+ \pgfnodealias{\tikz@pp@name{#2}}{yquantbox}%
+ \fi%
+ \numdef\yquant@draw@@idx@content{\yquant@draw@@idx@content+1}%
+}
+
+\protected\long\def\yquant@draw@multi#1#2#3#4#5{%
+ \let\idx=\yquant@draw@@idx@content%
+ % We need to somehow extract the y radius
+ \edef\cmd{%
+ \noexpand\path (\yquant@draw@@x, \the\dimexpr.5\dimexpr%
+ \yquant@register@get@y{#1}+\yquant@register@get@y{#2}\relax%
+ \relax)%
+ node[/yquant/every operator, \yquant@draw@@style, /yquant/this operator,%
+ y radius/.expanded=\the\dimexpr.5\dimexpr\yquant@register@get@ydist{#1}{#2}\relax\relax+%
+ .5*\noexpand\pgfkeysvalueof{/tikz/y radius},%
+ name prefix=, name suffix=, name=yquantbox]%
+ {\unexpanded\expandafter{\yquant@draw@@content}};
+ }%
+ \cmd%
+ \ifpgfpointshapexproj{yquantbox}%
+ \let\do=\yquant@circuit@extendwire%
+ \dolistloop{#4}%
+ \fi%
+ \yquant@circuit@extendcontrolline\yquant@draw@@currentcontroltype\yquant@draw@@x%
+ % check for empty name parameter
+ \if\relax\detokenize{#5}\relax%
+ \else%
+ \pgfnodealias{\tikz@pp@name{#5}}{yquantbox}%
+ \fi%
+ \numdef\yquant@draw@@idx@content{\yquant@draw@@idx@content+1}%
+}
+
+\protected\long\def\yquant@draw@multiinit#1#2#3#4#5{%
+ \let\idx=\yquant@draw@@idx@content%
+ % We need to somehow extract the y radius
+ \edef\cmd{%
+ \noexpand\path[/yquant/every operator, \yquant@draw@@style,%
+ /yquant/every multi label, /yquant/this operator]%
+ (\yquant@draw@@x, \yquant@register@get@y{#1}) --%
+ (\yquant@draw@@x, \yquant@register@get@y{#2})%
+ node[name prefix=, name suffix=, name=yquantbox]%
+ {\unexpanded\expandafter{\yquant@draw@@content}};
+ }%
+ \cmd%
+ % no wire extension (we are still at the initial position), no control line (init doesn't allow for those, so just save the no-op)
+ % check for empty name parameter
+ \if\relax\detokenize{#5}\relax%
+ \else%
+ \pgfnodealias{\tikz@pp@name{#5}}{yquantbox}%
+ \fi%
+ \numdef\yquant@draw@@idx@content{\yquant@draw@@idx@content+1}%
+}
+
+\protected\def\yquant@draw@control#1#2#3{%
+ \edef\cmd{%
+ \noexpand\path (\yquant@draw@@x, \yquant@register@get@y{#2})%
+ node[/yquant/every control, /yquant/every #1 control, /yquant/this control,%
+ name prefix=, name suffix=, name=yquantbox]%
+ {};%
+ }%
+ \cmd%
+ \ifpgfpointshapexproj{yquantbox}%
+ \yquant@circuit@extendwire{#2}%
+ \fi%
+ \yquant@draw@@currentcontroltype=\yquant@register@get@type{#2}\relax%
+ \yquant@circuit@extendcontrolline\yquant@draw@@currentcontroltype\yquant@draw@@x%
+ % check for empty name parameter
+ \if\relax\detokenize{#3}\relax%
+ \else%
+ \pgfnodealias{\tikz@pp@name{#3}}{yquantbox}%
+ \fi%
+}
+
+\protected\def\yquant@draw@pcontrol#1#2{%
+ \let\idx=\yquant@draw@@idx@pcontrol%
+ \yquant@draw@control{positive}{#1}{#2}%
+ \numdef\yquant@draw@@idx@pcontrol{\yquant@draw@@idx@pcontrol+1}%
+}
+
+\protected\def\yquant@draw@ncontrol#1#2{%
+ \let\idx=\yquant@draw@@idx@ncontrol%
+ \yquant@draw@control{negative}{#1}{#2}%
+ \numdef\yquant@draw@@idx@ncontrol{\yquant@draw@@idx@ncontrol+1}%
+}
+
+\protected\def\yquant@draw@cline{%
+ \edef\cmd{%
+ \noexpand\path[/yquant/every control line]%
+ \yquant@circuit@extendcontrolline@cmd;
+ }%
+ \cmd%
+}
+
+\protected\def\yquant@draw@alias#1{%
+ \pgfnodealias{\tikz@pp@name{#1}}{\tikz@pp@name{#1-0}}%
+}
+
+\protected\def\yquant@draw@alias@ctrl#1#2{%
+ \pgfnodealias{\tikz@pp@name{#1-#2}}{\tikz@pp@name{#1-#20}}%
+}
+% END_FOLD
+
+% BEGIN_FOLD Preparation of drawing a generic shape
+% Most drawing operations will be realized through nodes
+\let\yquant@draw@callback@box=\@gobble
+\let\yquant@draw@callback@wire=\@gobble
+
+\def\yquant@draw@sort#1#2{%
+ \yquant@draw@sort@aux#1\relax#2\relax%
+ \expandafter\@firstoftwo%
+ \else%
+ \expandafter\@secondoftwo%
+ \fi%
+}
+
+\def\yquant@draw@sort@aux#1#2#3\relax#4#5#6\relax{%
+ \unless\ifnum#2>#5\relax%
+}
+
+% generic shape of an operator
+% #1: value
+% #2: tikz options that select the correct shape
+% #3: positive controls
+% #4: negative controls
+% #5: targets
+\protected\long\def\yquant@draw#1#2#3#4#5{%
+ % setup the required macros
+ \yquant@circuit@operator{#3}{#4}{#5}%
+ \yquant@draw@{#1}{#2}%
+}
+
+\protected\long\def\yquant@draw@#1#2{%
+ \yquant@sort@clear%
+ \def\idx{0}%
+ \dimen2=\yquant@config@operator@minimum@width%
+ % BEGIN_FOLD register
+ \def\do##1{%
+ \ifx\yquant@lang@attr@name\empty%
+ \let\nodename=\empty%
+ \else%
+ \edef\nodename{\yquant@lang@attr@name-\idx}%
+ \fi%
+ \ifyquant@firsttoken\yquant@register@multi{##1}{%
+ \yquant@draw@@multi{#1}{#2}{##1}%
+ }{%
+ \yquant@draw@@single{#1}{#2}{##1}%
+ }%
+ \expandafter%
+ \endpgfinterruptboundingbox%
+ \expandafter\dimen\expandafter0\expandafter=%
+ \the\dimexpr\pgf@picmaxx-\pgf@picminx\relax\relax%
+ \ifdim\dimen0>\dimen2 %
+ \dimen2=\dimen0 %
+ \fi%
+ \numdef\idx{\idx+1}%
+ % TODO
+% \yquant@draw@callback@box\nodename%
+ }%
+ \dolistloop\yquant@circuit@operator@targets%
+ % END_FOLD
+ % BEGIN_FOLD controls
+ \ifyquant@circuit@operator@hasControls%
+ \def\do##1{%
+ \ifx\yquant@lang@attr@name\empty%
+ \let\nodename=\empty%
+ \else%
+ \edef\nodename{\yquant@lang@attr@name-\yquant@draw@controlprefix\idx}%
+ \fi%
+ \yquant@sort@eadd{%
+ \expandafter\noexpand\csname yquant@draw@\yquant@draw@controlprefix control\endcsname%
+ {##1}% register index
+ {\nodename}%
+ }%
+ \unless\ifdefined\yquant@draw@controltype%
+ \edef\yquant@draw@controltype{##1}%
+ \fi%
+ \numdef\idx{\idx+1}%
+ }
+ \def\yquant@draw@controlprefix{p}%
+ \def\idx{0}%
+ \dolistloop\yquant@circuit@operator@pctrls%
+ \def\yquant@draw@controlprefix{n}%
+ \def\idx{0}%
+ \dolistloop\yquant@circuit@operator@nctrls%
+ \unless\ifdefined\yquant@draw@controltype%
+ \PackageError{yquant.sty}{Assertion failure}%
+ {Internal inconsistency in yquant: Controlled action detected, but no controls were found.}%
+ \fi%
+ \fi%
+ % END_FOLD
+ % We now know the dimensions of all the registers (though we didn't bother with the height of the control knobs [if present], we just assume they are too small to change this).
+ \protected\def\idx{}%
+ \protected@edef\yquant@draw@append{%
+ \noexpand\yquant@draw@group%
+ {\the\dimexpr\yquant@circuit@operator@x+.5\dimen2\relax}% mid x position
+ \ifyquant@circuit@operator@hasControls%
+ \yquant@draw@controltype%
+ \else%
+ F%
+ \fi% if-switch whether controls are present
+ {\yquant@attrs@remaining}% custom style
+ {#2}% operator style
+ {#1}%
+ }%
+ \yquant@sort\yquant@draw@sort%
+ \advance \dimen2 by \yquant@circuit@operator@x\relax%
+ % BEGIN_FOLD shipout
+ \ifyquant@circuit@operator@hasControls%
+ % If we draw a control line, all intermediate registers are affected in their position so that the line is never crossed.
+ \yquant@for \yquant@i := \yquant@circuit@operator@minctrl to \yquant@circuit@operator@maxctrl {%
+ \yquant@register@set@x\yquant@i{\the\dimen2}%
+ }%
+ \fi%
+ \def\do##1{%
+ \appto\yquant@draw@append{##1}%
+ \yquant@draw@finalize@ctrl##1%
+ }%
+ \yquant@sort@dolistloop%
+ \csxappto{\yquant@prefix draw}{%
+ \unexpanded\expandafter{\yquant@draw@append}%
+ \noexpand\yquant@draw@endgroup%
+ \ifyquant@circuit@operator@hasControls%
+ T%
+ \else%
+ F%
+ \fi%
+ \ifx\yquant@lang@attr@name\empty%
+ {}0%
+ \else%
+ {\yquant@lang@attr@name}%
+ \ifnum\yquant@circuit@operator@numtarget=1 %
+ \ifnum\yquant@circuit@operator@numpctrl=1 %
+ \ifnum\yquant@circuit@operator@numnctrl=1 %
+ 7%
+ \else%
+ 6%
+ \fi%
+ \else%
+ \ifnum\yquant@circuit@operator@numnctrl=1 %
+ 5%
+ \else%
+ 4%
+ \fi%
+ \fi%
+ \else%
+ \ifnum\yquant@circuit@operator@numpctrl=1 %
+ \ifnum\yquant@circuit@operator@numnctrl=1 %
+ 3%
+ \else%
+ 2%
+ \fi%
+ \else%
+ \ifnum\yquant@circuit@operator@numnctrl=1 %
+ 1%
+ \else%
+ 0%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ }%
+ % END_FOLD
+}
+
+\protected\def\yquant@draw@@single#1#2#3{%
+ \yquant@sort@eadd{%
+ \yquant@draw@single%
+ {#3}% register index
+ {\nodename}%
+ }%
+ % determine the actual dimensions by a virtual draw command
+ \pgfinterruptboundingbox%
+ \yquant@env@virtualize@path%
+ \path%
+ (0pt, 0pt)
+ node[/yquant/every operator, #2, /yquant/this operator,%
+ name prefix=, name suffix=, name=] {#1};%
+ \yquant@register@update@height{#3}{%
+ \the\dimexpr\pgf@picmaxy-\pgf@picminy\relax%
+ }%
+}
+
+\protected\def\yquant@draw@@multi#1#2#3{%
+ \yquant@sort@eadd{%
+ \yquant@draw@multi%
+ #3%
+ {\nodename}%
+ }%
+ % Determining the actual height is a problem - where to store its value? We just assume that there is always enough space for such a control, since it anyway already spans multiple registers. (TODO?)
+ \pgfinterruptboundingbox%
+ \yquant@env@virtualize@path%
+ % Here, we just set a dummy height, as we don't know the actual height yet. As the width of most/all shapes should not depend on their height, it does not matter.
+ \path%
+ (0pt, 0pt)
+ node[/yquant/every operator, #2, /yquant/this operator, y radius=1cm,%
+ name prefix=, name suffix=0, name=] {#1};
+}
+
+\protected\def\yquant@draw@@multiinit#1#2#3{%
+ \yquant@sort@eadd{%
+ \yquant@draw@multiinit%
+ #3%
+ {\nodename}%
+ }%
+ % Determining the actual height is a problem - where to store its value? We just assume that there is always enough space for such a control, since it anyway already spans multiple registers. (TODO?)
+ \pgfinterruptboundingbox%
+ \yquant@env@virtualize@path%
+ % Here, we just set a dummy height, as we don't know the actual height yet. As the width of most/all shapes should not depend on their height, it does not matter.
+ \path%
+ (0pt, 0pt)
+ node[/yquant/every operator, #2, /yquant/every multi label, y radius=1cm,%
+ name prefix=, name suffix=0, name=] {#1};
+}
+
+\def\yquant@draw@finalize@ctrl#1{%
+ \ifx\yquant@draw@multi#1%
+ \expandafter\yquant@draw@finalize@ctrl@multi%
+ \else%
+ \ifx\yquant@draw@multiinit#1%
+ \expandafter\expandafter\expandafter\yquant@draw@finalize@ctrl@multi%
+ \else%
+ \expandafter\expandafter\expandafter\yquant@draw@finalize@ctrl@single%
+ \fi%
+ \fi%
+}
+
+\protected\def\yquant@draw@finalize@ctrl@single#1#2{%
+ \unless\ifyquant@circuit@operator@hasControls%
+ \yquant@register@set@x#1{\the\dimen2}%
+ \fi%
+ \eappto\yquant@draw@append{%
+ \yquant@draw@callback@wire{#1}%
+ }%
+}
+
+\protected\def\yquant@draw@finalize@ctrl@multi#1#2#3#4#5{%
+ \unless\ifyquant@circuit@operator@hasControls{%
+ % \yquant@for uses \loop...\repeat and hence redefines \body, which would destroy an outer loop.
+ % if we did not draw a control line, the x position has not yet been set. A multi-qubit register might visually extend over multiple registers that are not even part, hence we update them all.
+ \yquant@for \yquant@i := #1 to #2 {%
+ \yquant@register@set@x\yquant@i{\the\dimen2}%
+ }%
+ }\fi%
+ % this is called from a do loop itself, so preserve \do (but do not enter grouping)
+ \let\yquant@draw@update@x@multi@@olddo=\do%
+ \def\do##1{%
+ \eappto\yquant@draw@append{%
+ \yquant@draw@callback@wire{##1}%
+ }%
+ }%
+ \dolistloop{#4}%
+ \let\do=\yquant@draw@update@x@multi@@olddo%
+}
+% END_FOLD \ No newline at end of file