diff options
-rw-r--r-- | Master/texmf-dist/doc/latex/yquant/README.md | 2 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/yquant/yquant-doc.pdf | bin | 994303 -> 1015316 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/yquant/yquant-doc.tex | 469 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/yquant/yquant-circuit.tex | 70 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/yquant/yquant-config.tex | 275 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/yquant/yquant-draw.tex | 561 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/yquant/yquant-env.tex | 13 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/yquant/yquant-lang.tex | 10 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/yquant/yquant-prepare.tex | 134 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/yquant/yquant-registers.tex | 12 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/yquant/yquant-shapes.tex | 524 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/yquant/yquant-tools.tex | 140 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/yquant/yquant.sty | 8 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/yquant/yquantlanguage-groups.sty | 93 |
14 files changed, 1579 insertions, 732 deletions
diff --git a/Master/texmf-dist/doc/latex/yquant/README.md b/Master/texmf-dist/doc/latex/yquant/README.md index 93e177ca280..d8f4ff4a262 100644 --- a/Master/texmf-dist/doc/latex/yquant/README.md +++ b/Master/texmf-dist/doc/latex/yquant/README.md @@ -6,6 +6,8 @@ yquant is a pure-LaTeX solution - i.e., it requires no external program - that i It builds on and interacts with TiKZ, which brings an enourmous flexibility for customization of individual circuit. Important features in the latest updates (for a much more complete list, see the documentation): +- Support for vertical circuit layout (since 0.7) +- Support for a simplified drawing pipeline (since 0.7) - Support the `beamer` package (since 0.6) - New `text` gate, which replaces the common `[draw=none] box` situation (since 0.6) - Integration of all qpic examples in the manual, showcasing some very advanced circuits (since 0.6) diff --git a/Master/texmf-dist/doc/latex/yquant/yquant-doc.pdf b/Master/texmf-dist/doc/latex/yquant/yquant-doc.pdf Binary files differindex 9fefce4faf2..20229feff75 100644 --- a/Master/texmf-dist/doc/latex/yquant/yquant-doc.pdf +++ b/Master/texmf-dist/doc/latex/yquant/yquant-doc.pdf diff --git a/Master/texmf-dist/doc/latex/yquant/yquant-doc.tex b/Master/texmf-dist/doc/latex/yquant/yquant-doc.tex index ac027a7101e..3af9c17196d 100644 --- a/Master/texmf-dist/doc/latex/yquant/yquant-doc.tex +++ b/Master/texmf-dist/doc/latex/yquant/yquant-doc.tex @@ -16,7 +16,7 @@ \usepackage[english]{babel} \usepackage[colorlinks, linkcolor=darkblue, bookmarksdepth=paragraph]{hyperref} \usepackage[compat=newest]{yquant} -\usepackage{braket,hyphenat,microtype,hologo,minted,import,ragged2e} +\usepackage{braket,hyphenat,microtype,hologo,minted,import,ragged2e,booktabs} \usetikzlibrary{quotes,fit,shapes.symbols,backgrounds,quantikz} \useyquantlanguage{qasm,groups} \usepackage{amsmath,adjustbox,cleveref} @@ -219,7 +219,7 @@ This document outlines the scope and usage of the \Yquant{} package. It contains both a reference and a huge number of examples. \Yquant{} is a package that makes typesetting quantum circuits easy; the package is available on CTAN. - This beta version~0.6 \emph{should} be stable and interfaces are not very likely to change in an incompatible way in the future. + This beta version~0.7 \emph{should} be stable and interfaces are not very likely to change in an incompatible way in the future. \compat{New in 0.4}Sometimes, backwards\hyp incompatible changes are required or advisable, in which case a compatibility setting will allow to revert back to the old behavior (rather, to maximize compatibility, this is an opt\hyp in setting: unless you choose the new behavior, you will get the old one). Please do report all issues and desirable additions on \href{https://github.com/projekter/yquant/issues}{GitHub}. @@ -394,6 +394,9 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); Deviations are noted in this manual. Valid values for + \begingroup% + % since v2.6 of minted, \PYG is no longer universally defined, so bring it into scope + \minted@defstyle{\minted@get@opt{style}{default}}% \begin{BVerbatim}[commandchars=\\\{\}] \PYG{n+ni}{?command?} \end{BVerbatim} @@ -416,7 +419,7 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); \begin{BVerbatim}[commandchars=\\\{\}] \PYG{l+s+s2}{\PYGZdq{}+\PYGZdq{}} \end{BVerbatim} - ). + ).\endgroup \subsection{Registers}\label{sec:registers} Every quantum circuit is structured by means of \emph{registers}. @@ -628,14 +631,31 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); Note that the backend interface changed in version~0.4. For the declaration of custom shapes, see \texttt{yquant-shapes.tex} for examples. + \subsection[The flow of time: horizontal and vertical layout]{\compat{New in 0.7}The flow of time: horizontal and vertical layout} + By default, quantum circuits are oriented \emph{horizontally}, i.e., time flows from left to right. + Sometimes, this is problematic when printed on a portrait page layout and a \emph{vertical} layout would be better suited. + \Yquant{} supports this by simply passing the configuration option \style{/yquant/vertical} to the circuit (this can even be done globally, so that all circuits are rendered vertically). + + The vertical layout is supposed to work exactly as the horizontal layout; however, most testing occurs for horizontal mode only (basically, for every release, the examples in this manual comprise the testsuite). + Hence, if something weird happens in vertical mode, please file a bug report. + + Most of the internal and exposed nomenclature in \Yquant{} is designed for the horizontal case (names such as ``height'' or ``width''). + For some of the exposed configuration options, synonyms are provided which are more meaningful in vertical mode or that are more orientation\hyp agnostic. + These synonyms are merely conveniences, they do not provide any new functionality. + As a general rule of thumb, everything that was ``atop'' becomes ``left.'' + + Some relevant \TikZ{} options refer to a fixed direction, namely \texttt{[x|y] radius} and \texttt{[inner|outer] [x|y]sep}. + If you think that maybe you want to change the orientation of your circuit at some point, you should never use the original \TikZ{} styles---their meaning would depend on the current orientation. + Instead, consider using the \Yquant{} alternatives \texttt{[time|space] radius} and \texttt{[inner|outer] [time|space]sep}. + \section{Configuration}\label{sec:config} \Yquant{} uses \pkg{pgfkeys} to control its options, which are located in the path \texttt{/yquant}. The following list contains all options and styles that are recognized, apart from gate arguments. Those are listed together with their operations. \subsection{Circuit layout}\unskipOpt - \begin{option}[Changed in 0.4]{register/minimum height}!1.5mm! - \Yquant{} automatically determines the height (extent from wire to top boundary) of a register as the height of the largest operation. + \begin{option}[Changed in 0.7, 0.4]{register/minimum height}!1.5mm! + \Yquant{} automatically determines the height (extent from wire to top boundary; in vertical mode: from wire to left boundary) of a register as the height of the largest operation. This might be too small for two reasons: \begin{itemize} \item if the register is used only with small gates (e.g., only as a control, or as a swap), and it does not have a label (or one containing only x\hyp height letters). @@ -645,31 +665,57 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); This key provides an easy alleviation of the problem by requiring a minimal height for every register. As the value of this key is relevant at the time of register declaration, it can also be changed for each register individually. + Note that in vertical mode, the default of this setting is \tex!2.5mm!. + Note that this key is affected by the \texttt{compat} setting. Before version \texttt{0.4}, there was no \style{/yquant/register/minimum depth} key. In this compatibility setting, passing the value $x$ to this key will set both height and depth to $\frac x2$. The default for $x$ is then \texttt{3mm}. \end{option} - \begin{option}[New in 0.4]{register/minimum depth}!1.5mm! + \begin{option}[Changed in 0.4\\New in 0.4]{register/minimum depth}!1.5mm! \emph{see} \style{/yquant/register/minimum height} - This key allows to specify a minimum depth (extent from wire to bottom boundary) for a register. + This key allows to specify a minimum depth (extent from wire to bottom boundary; in vertical mode: from wire to right boundary) for a register. + + Note that in vertical mode, the default of this setting is \tex!2.5mm!. Note that this key is affected by the \texttt{compat} setting. Before version \texttt{0.4}, this key will not be available. \end{option} + \begin{option}[New in 0.7]{register/minimum left}!1.5mm! + This is a synonym for \style{/yquant/register/minimum height}, as this naming makes more sense for vertical circuits. + \end{option} + + \begin{option}[New in 0.7]{register/minimum right}!1.5mm! + This is a synonym for \style{/yquant/register/minimum depth}, as this naming makes more sense for vertical circuits. + \end{option} + + \begin{option}[New in 0.7]{register/minimum before}!1.5mm! + This is a synonym for \style{/yquant/register/minimum height}, which provides a naming that makes sense in both horizontal and vertical mode. + \end{option} + + \begin{option}[New in 0.7]{register/minimum after}!1.5mm! + This is a synonym for \style{/yquant/register/minimum depth}, which provides a naming that makes sense in both horizontal and vertical mode. + \end{option} + \begin{option}{register/separation}!1mm! This key controls the amount of vertical space that is inserted between two successive registers. Half of this value is also the length that multi\hyp\gate{init} or multi\hyp\gate{output} braces extend beyond the mid position of the register. \end{option} - \begin{option}{operator/minimum width}!3mm! - \Yquant{} automatically determines the width of an operator according to its content. + \begin{option}[Changed in 0.7]{operator/minimum width}!5mm! + \Yquant{} automatically determines the width (in vertical mode: the vertical extent) of an operator according to its content. However, single\hyp letter boxes are among the most common operators, and giving them slightly different widths would result in a very uneven spacing, as \Yquant{} does not use a grid layout but stacks the operators horizontally one after each other. Hence, this key provides a minimum width that will be set for every operator. This does not imply that the \emph{visual} appearance (i.e., the \texttt{x radius} key) is enlarged, but that operators of a smaller actual width will be centered in a virtual box of the minimum width. + + Note that in vertical mode, the default of this setting is \tex!3mm!. + \end{option} + + \begin{option}[New in 0.7]{operator/minimum extent}!3mm! + This is a synonym for \style{/yquant/operator/minimum width}, which provides a naming that makes sense in both horizontal and vertical mode. \end{option} \begin{option}{operator/separation}!1mm! @@ -682,6 +728,22 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); You may disable this warning globally, on a per\hyp circuit, or even on a per\hyp gate basis. \end{option} + \begin{option}[New in 0.7]{drawing mode}!quality! + This key determines which drawing pipeline is enabled. + For more details, see \cref{sec:pipeline}. + The option should not be changed within a circuit (though only the last value will be relevant). + Allowed values are \texttt{quality} for the default clipping\hyp based pipeline, and \texttt{size} of the filling\hyp based one. + Note that choosing \texttt{quality} will set \style{/yquant/default background} to \texttt{none}; choosing \texttt{size} will set it to \texttt{white} (though this can be changed after setting the option). + \end{option} + + \begin{option}[New in 0.7]{default background}!none! + This key contains the default color that is used to fill all gates with a nonempty interior. + \end{option} + + \begin{option}[New in 0.7]{default fill}!fill/.expanded=\pgfkeysvalueof{/yquant/default background}! + Use this style if you want to apply the default filling to a user\hyp defined gate. + \end{option} + \subsection{Register creation}\unskipOpt \begin{option}{register/default name}!\regidx! The printed name that is used by default if a new register is created explicitly (\gate{qubit}, \gate{cbit}, \gate{qubits}; not used for \gate{nobit} or for implicit declarations) and no value is specified. @@ -700,18 +762,20 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); Note that this default setting is not used when the register is created via an \gate{init} gate---its value always overwrites the default. \end{option} - \begin{option}[Changed in 0.4]{every label}!shape=yquant-init, anchor=center, align=right, outer xsep=2pt, /yquant/operator/if multi={draw, decoration={gapped brace, mirror, raise=2pt}, decorate}! + \begin{option}[Changed in 0.7, 0.4]{every label}!shape=yquant-init, anchor=center, align/.expanded=\ifyquanthorz{right}{center}, outer timesep=2pt, /yquant/operator/if multi={draw, decoration={gapped brace, raise=2pt, \ifyquanthorz{mirror}{}}, decorate}! This style is installed for every single register name label (i.e., upon creation and when used with the \gate{init} gate). The default style allows to use line breaks in the labels. - The node shape, \texttt{yquant-init}, will generate a path at its right side, which is replaced by the \texttt{gapped brace} decoration if the gate is used in a multi\hyp register fashion. + The node shape, \texttt{yquant-init}, will generate a path at its right side (in vertical mode: at its bottom side), which is replaced by the \texttt{gapped brace} decoration if the gate is used in a multi\hyp register fashion. The decoration is similar to \TikZ's \texttt{brace} decoration, but additionally allows specify the regions in which a line should be drawn by using the \texttt{/tikz/decoration/from to} key, which expects a comma\hyp separated list of dimension ranges, and which is automatically populated by \Yquant. Note that if the \texttt{compat} key is below \texttt{0.3}, the multi options are instead read from \style{/yquant/every multi label}. \end{option} - \begin{option}{every initial label}!anchor=east! + \begin{option}[Changed in 0.7]{every initial label}!anchor/.expanded=\ifyquanthorz{east}{south}, /yquant/internal/autorotate init! This style is installed for every single register name label at the left border of the circuit. \compat{Changed in 0.4}It is therefore used if a label is specified upon declaration and also for the \gate{init} gate if it happens to be the first gate on an unlabelled register (use a zero\hyp width \gate{hspace} gate before if you want to suppress this). + + \compat{New in 0.7}The automatic rotation will be set up by using the \style{/yquant/vertical} style with an argument; by default, it is empty. \end{option} \begin{option}{every qubit label}!! @@ -740,12 +804,14 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); \end{option} \subsection{Register outputs}\unskipOpt - \begin{option}[Changed in 0.4]{every output}!shape=yquant-output, anchor=west, align=left, outer xsep=2pt, /yquant/operator/if multi={draw, decoration={gapped brace, raise=2pt}, decorate}! + \begin{option}[Changed in 0.7, 0.4]{every output}!shape=yquant-output, anchor/.expanded=\ifyquanthorz{west}{north}, align/.expanded=\ifyquanthorz{left}{center}, outer timesep=2pt, /yquant/operator/if multi={draw, decoration={gapped brace, raise=2pt, \ifyquanthorz{}{mirror}}, decorate}, /yquant/internal/autorotate output! This style is installed for every \gate{output} label at the end of the circuit. The default style allows to use line breaks in the labels. - The node shape, \texttt{yquant-output}, will generate a path at its left side, which is replaced by the \texttt{gapped brace} decoration in the case of multi\hyp register usage. + The node shape, \texttt{yquant-output}, will generate a path at its left side (in vertical mode: at its top side), which is replaced by the \texttt{gapped brace} decoration in the case of multi\hyp register usage. See \style{/yquant/every label} for a more detailed explanation. + + \compat{New in 0.7}The automatic rotation will be set up by using the \style{/yquant/vertical} style with an argument; by default, it is empty. \end{option} \begin{option}{every qubit output}!! @@ -806,7 +872,7 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); This style is installed for every positive control (i.e., one that conditions on the register being in state $\ket1$ or $1$). \end{option} - \begin{option}{every negative control}!draw! + \begin{option}[Changed in 0.7]{every negative control}!draw, /yquant/default fill! This style is installed for every negative control (i.e., one that conditions on the register being in state $\ket0$ or $0$). \end{option} @@ -861,6 +927,58 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); Only access it via \style{/yquant/operators/subcircuit/seamless}. \end{option} + \begin{option}[New in 0.7]{circuit/orientation}!horizontal! + This setting allows two possible values, \texttt{horizontal} and \texttt{vertical}. + It must only be changed before a circuit or at latest with the option arguments to the \tex!yquant! environment, but not within a circuit. + + In the default \texttt{horizontal} mode, time flows from left to right and registers will be created from top to bottom. + In the alternative \texttt{vertical} mode, time flows from top to bottom and registers will be created from left to right. + + Note that this setting influences the behavior of various macros and styles: + \begin{center} + \begin{tabular}{lrr} + \toprule + Macro/Style & \texttt{horizontal} meaning & \texttt{vertical} meaning \\\midrule + \tex!\ifyquanthorz{a}{b}! & \tex!a! & \tex!b! \\ + \texttt{/tikz/time radius} & \texttt{/tikz/x radius} & \texttt{/tikz/y radius} \\ + \texttt{/tikz/space radius} & \texttt{/tikz/y radius} & \texttt{/tikz/x radius} \\ + \texttt{/tikz/inner timesep} & \texttt{/tikz/inner xsep} & \texttt{/tikz/inner ysep} \\ + \texttt{/tikz/inner spacesep} & \texttt{/tikz/inner ysep} & \texttt{/tikz/inner xsep} \\ + \texttt{/tikz/outer timesep} & \texttt{/tikz/outer xsep} & \texttt{/tikz/outer ysep} \\ + \texttt{/tikz/outer spacesep} & \texttt{/tikz/outer ysep} & \texttt{/tikz/outer xsep} \\ + \bottomrule + \end{tabular} + \end{center} + Additionally, this setting influences the default values of various \Yquant{} styles---note that if a style was once overwritten, the user\hyp supplied value will be never be changed! + Here, we use the orientation\hyp independent names of the styles, although all their synonyms are equivalent. + \begin{center} + \begin{tabular}{lrr} + \toprule + Style & \texttt{horizontal} def. & \texttt{vertical} def. \\\midrule + \style{/yquant/register/minimum before} & \tex!1.5mm! & \tex!2.5mm! \\ + \style{/yquant/register/minimum after} & \tex!1.5mm! & \tex!2.5mm! \\ + \style{/yquant/operator/minimum extent} & \tex!5mm! & \tex!3mm! \\ + \bottomrule + \end{tabular} + \end{center} + \end{option} + + \begin{option}[New in 0.7]{horizontal} + This style is a shorthand that sets \style{/yquant/circuit/orientation} to the \texttt{horizontal} value (which is the default). + \end{option} + + \begin{option}[New in 0.7]{vertical}!0! + This style is a shorthand that sets \style{/yquant/circuit/orientation} to the \texttt{vertical} value. + Additionally, it accepts a parameter which should be an angle value (in degrees) between \tex!-180! and \tex!180!. + This is a rotation that is automatically applied to the text in every \gate{init} gate at the beginning of a circuit; the inverse rotation is automatically applied to the text in every \gate{output} gate at the end of a circuit. + + Note that the gates themselves are \emph{not} rotated. + This would be counterproductive for multi\hyp qubit gates that contain braces---those should still be orthogonal to the wire lines. + In order to achieve this, the macro will use internal \TikZ{} details and exploit that the \texttt{execute at begin node} key is directly followed by the braced content of the node. + Hence, it will add a corresponding \tex!\adjustbox{rotate=#1}! to this style. + Therefore, \Yquant{} will raise a warning if the argument is used and the \pkg{adjustbox} package is not loaded, in which case the rotation is just ignored. + \end{option} + \begin{option}[New in 0.4]{every post measurement control}!indirect! This style determines the default arrangement of measurements that are followed by positive controls. @@ -899,7 +1017,7 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); Note that with the \texttt{compat} key set before \texttt{0.4}, this style instead defaults to \tex!/yquant/operators/subcircuit/frameless, /yquant/register/default name=!. \end{option} - \begin{option}{operators/every dmeter}!shape=yquant-dmeter, x radius=2mm, y radius=2mm, fill=white, draw! + \begin{option}[Changed in 0.7]{operators/every dmeter}!shape=yquant-dmeter, time radius=2mm, space radius=2mm, draw, /yquant/default fill! This style is installed for every \gate{dmeter} gate. The \texttt{yquant-dmeter} shape consists of a rectangle whose right side is replaced by a circle, resembling the letter ``D.'' \end{option} @@ -908,12 +1026,12 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); This style is installed for every \gate{h} (Hadamard) operator. \end{option} - \begin{option}{operators/every inspect}!shape=yquant-output, align=left, outer xsep=.3333em, y radius=2.47mm, /yquant/operator/if multi={draw, decoration={gapped brace, raise=2pt}, decorate}! + \begin{option}[Changed in 0.7]{operators/every inspect}!shape=yquant-output, align/.expanded=\ifyquanthorz{left}{center}, outer timesep=.3333em, space radius=2.47mm, /yquant/default fill, /yquant/operator/if multi={draw, decoration={gapped brace, raise=2pt, \ifyquanthorz{}{mirror}}, decorate}! This style is installed for every \gate{inspect} gate. - It does not have any shape on its own, apart from multi\hyp register uses, in which it will contain a brace on its left. + It does not have any shape on its own, apart from multi\hyp register uses, in which it will contain a brace on its left (in vertical mode: on its top). \end{option} - \begin{option}{operators/every measure}!shape=yquant-measure, x radius=4mm, y radius=2.5mm, draw! + \begin{option}[Changed in 0.7]{operators/every measure}!shape=yquant-measure, x radius=4mm, y radius=2.5mm, draw, /yquant/default fill! This style is installed for every \gate{measure} gate. The \texttt{yquant-measure} shape is a rectangle that contains a ``meter'' symbol. It allows for a text to be put inside (e.g., a basis), which then shifts the meter symbol accordingly. @@ -937,7 +1055,7 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); This style is installed for every \gate{phase} gate $\ketbra00 + \ee^{\ii\phi} \ketbra11$. \end{option} - \begin{option}[New in 0.6]{operators/every rectangular box}!shape=yquant-rectangle, draw, align=center, inner xsep=1mm, x radius=2mm, y radius=2.47mm! + \begin{option}[Changed in 0.7\\New in 0.6]{operators/every rectangular box}!shape=yquant-rectangle, draw, align=center, inner timesep=1mm, time radius=2mm, space radius=2.47mm, /yquant/default fill! This style is not associated to any particular gate, but will be inherited by a lot of gates that have a rectangular box frame with some text. This style should not be used with a \texttt{compat} setting strictly smaller than~\texttt{0.6}. \end{option} @@ -951,7 +1069,7 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); Note that all styles given here will also apply to every element in the subcircuit; in a way, this is an addition to \style{/yquant/every circuit} (which is also again put into effect at the beginning of a subcircuit). \end{option} - \begin{option}[New in 0.2]{operators/every subcircuit box}!/yquant/operators/every box! + \begin{option}[New in 0.2]{operators/every subcircuit box}!/yquant/operators/every rectangular box, fill=none! This style is installed for every \gate{subcircuit}. Note that in contrast to all other styles such as \style{/yquant/operators/every subcircuit} or \style{/yquant/this operator}, this style is only applied to the ``container'' node of the subcircuit, but not to the elements in the subcircuit themselves. Also note that the box style by default contains an \texttt{inner xsep} that will be added as an inside padding. @@ -1020,7 +1138,7 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); The \texttt{yquant-swap} shape consists of a single cross. \end{option} - \begin{option}[New in 0.6]{operators/every text}!shape=yquant-rectangle, align=center, inner xsep=1mm, x radius=2mm, y radius=2.47mm! + \begin{option}[Changed in 0.7\\New in 0.6]{operators/every text}!shape=yquant-rectangle, align=center, inner timesep=1mm, time radius=2mm, space radius=2.47mm, /yquant/default fill! This style is installed for every \gate{text} gate. \end{option} @@ -1032,7 +1150,7 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); This style is installed for every Pauli operator $\sigma_x$, i.e., \gate{x}. \end{option} - \begin{option}{operators/every xx}!shape=yquant-rectangle, radius=.75mm, draw! + \begin{option}[Changed in 0.7]{operators/every xx}!shape=yquant-rectangle, radius=.75mm, draw, /yquant/default fill! This style is installed for every \gate{xx} gate in symmetrized notation ($\ketbra{++}{++} + \ketbra{+-}{+-} + \ketbra{-+}{-+} - \ketbra{--}{--}$). \end{option} @@ -1107,6 +1225,30 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); \end{itemize} \end{itemize} + \compat{New in 0.7}Note that \Yquant{} also supports a simplified drawing pipeline which does not involve clipping paths. + It can be enabled by setting the \style{/yquant/drawing mode} option to \texttt{size}. + The simplified pipeline has the following benefits: + \begin{itemize} + \item \TeX{} has to compute a bit less, so the compilation process can be sped up. + \item PDF readers may render the circuit faster. + \item The size of the output files is decreased. + \item Compatibility with very simplistic clients that don't support clipping well is improved (this may be an issue for some PDF to image converters, for example). + \item Theoretically, you may use any kind of predefined shape in this mode (from \TikZ{} or other packages), since the clipping paths are no longer required. + \end{itemize} + However, with it come certain drawbacks: + \begin{itemize} + \item Gates are no longer transparent, but filled with some fixed background color, so if transparency is important for you, this just does not work. + \item \Yquant{} relies on \TikZ's layering capabilities; if you use layers by yourself, you have to pay some attention to do it correctly. + \item The z\hyp order may not be as you expect it; in particular: + All the gates will be drawn on the \texttt{main} layer; all the wires on the \texttt{wires} layer, which is behind \texttt{main}; so if you don't use layers by yourself, everything that you draw will overshadow the wires, but not necessarily the gates. + \item If you were to fill a subcircuit, this would then erase all the internal wires. + Hence, the box of a subcircuit is drawn on the \texttt{behindwires} layer; but this implies that also the \emph{frame} of the box is drawn behind the wires and that this box is also overshadowed by any of your drawing. + \item Wires that visually cross gates which are not part of the gate may be displayed differently from the standard pipeline. + \end{itemize} + Unless you use \tex!\pgfsetlayers! to add the layers \texttt{wires} and \texttt{behindwires} manually, \Yquant{} will automatically place the \texttt{wires} layer directly before \texttt{main}; then it will place \texttt{behindwires} directly before \texttt{wires}. + This in particular ensures full compatibility with the \texttt{backgrounds} library: the background layer is still the very first in the layer list. + In contrast to \pkg{pgfplots}, this automatism should work even if the \Yquant{} environment is placed within groups. + \subsection{Overwriting the height and depth calculation} \Yquant{} automatically takes care of calculating the height and depth of all registers, so that their final vertical positions are chosen without overlap. This is almost always advisable, but it has some weaknesses: @@ -1138,8 +1280,8 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); \begin{itemize} \item \texttt{true} (default if no value given, combines \texttt{multi}, \texttt{height}, and \texttt{depth}), \item \texttt{multi} (short \texttt{m}), - \item \texttt{height} (short \texttt{ht}, \texttt{h}), - \item \texttt{depth} (short \texttt{dp}, \texttt{d}), + \item \texttt{height} (short \texttt{ht}, \texttt{h}), equivalent to \texttt{left} (short \texttt{l}) and \texttt{before} (short \texttt{bef}, \texttt{b}), which sound more meaningful for vertical and generic circuit orientations, + \item \texttt{depth} (short \texttt{dp}, \texttt{d}), equivalent to \texttt{right} (short \texttt{r}) and \texttt{after} (short \texttt{aft}, \texttt{a}), which sound more meaningful for vertical and generic circuit orientations, \item \texttt{single} (short \texttt{s}, combines \texttt{height} and \texttt{depth}), and \item \texttt{false} (useless, default if attribute not given). \end{itemize} @@ -1340,7 +1482,7 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] ); It may only be specified once per register. It may span multiple registers, but does not allow for controls. The style \style{/yquant/every output} is installed, and also the style \texttt{/yquant/every <type> output}, where \texttt{<type>} is the type of the affected register (at the time of printout). - \compat{New in 0.6}Note that while outputs can be named, the name will only become available after the \texttt{yquant} environment itself was ended (but of course before the outer \texttt{tikzpicture} was closed). + \compat{New in 0.6}Note that while outputs can be named, the name will only become available after the \tex!yquant! environment itself was ended (but of course before the outer \texttt{tikzpicture} was closed). \emph{Possible attributes:} \begin{itemize} @@ -2437,7 +2579,6 @@ qubit {$\ket{q_{\idx}} = \Ifcase\idx\relax \ket\psi \Else \ket0 \Fi$} q[3]; \end{codeexample} We support measurements with vertical outputs, but only if they replace the positive control of some action. Here, we fake this behavior by introducing an invisible register at the bottom, which will contain the outputs. - In order to disable the line around the \gate{box}es, we used the \style{/yquant/operators/every box} style, which here was most convenient, as the only \gate{box}es in use are those without an outline. Note that if we were to give style options to the \gate{text}s, they would also affect the measurements. The reason for this is that internally, the measurement will be nested within the same scope that draws the \gate{text}---so the options given to the \gate{text} will be inherited by the \gate{measure}ment. As an operator style overwrites default styles, this will also apply to the measurements. @@ -3387,7 +3528,7 @@ $=$ Since they will always follow in this order, we also define a \tex!\cnotBlock! abbreviation that executes these configurations together with their intermediate \gate{barrier}. We do not include the final barrier, since it is not present in the last block. - Now, we start the \texttt{yquant} environment. + Now, we start the \tex!yquant! environment. We give some options for a nicer spacing and initialize the registers. In the \pkg{qpic} example, the registers are $1$\hyp indexed, so we use \tex!\The\numexpr\idx+1! to give back the value of the current register index (\tex!\idx!) plus one; we also conditionally color the register name in red if the index coincides with the parameter. Note that here we use \Yquant's shorthand for \tex!\protect\the!, \tex!\protect\ifnum!, and \tex!\protect\fi!, which are \tex!\The!, \tex!\Ifnum!, and \tex!\Fi!, to get the correct expansion behavior. @@ -3462,25 +3603,24 @@ $=$ \paragraph{2.3 Example 3: Shor's Algorithm}\leavevmode \begingroup% \mdfapptodefinestyle{bdBox}{% - leftmargin=-.12\linewidth, - rightmargin=-.12\linewidth + leftmargin=-.04\linewidth, + rightmargin=-.02\linewidth }% - \begin{example} + \begin{example}<Updated in 0.7> \begin{codeexample*} -\begin{tikzpicture}[rotate=-90, yscale=-1, every node/.append style={rotate=90, xscale=-1}] +\begin{tikzpicture} \def\explain#1#2{% \yquant - [anchor=east] text {#1} explainLeft; - [anchor=west] text {$\displaystyle#2$} explainRight; + [anchor=east, overlay=right] text {#1} explainLeft; + [anchor=west, overlay=left] text {$\displaystyle#2$} explainRight; align -; } - \begin{yquant}[every initial label/.style={anchor=south}, - every output/.style={anchor=north}, + \begin{yquant}[vertical, every control/.append style={radius=1.5mm}, operators/every slash/.append style={x radius=3mm, y radius=1.5mm}, operators/every box/.append style={y radius=4mm}, operators/every measure/.append style={y radius=4mm}, - operator/minimum width=1.32cm] + operator/minimum extent=1.32cm] nobit explainLeft; qubit {$\ket{0\dotsm0}$} x; slash x; qubit {$\ket{0\dotsm0}$} y; slash y; @@ -3509,27 +3649,14 @@ $=$ \end{tikzpicture} \end{codeexample*} Once again, this is a very interesting example. - \Yquant{} does not support a vertical circuit layout \emph{officially}. - However, \Yquant{} is built on top of \TikZ, so we can certainly try to emulate a vertical layout by means of rotations. - First of all, we rotate the whole \texttt{tikzpicture}, saying \tex!rotate=-90!, so that the circuit grows downwards. - While this is very straightforward, it leads to two immediate problems: - \begin{itemize} - \item The registers were declared in top\hyp to\hyp bottom order; if we rotate everything, this becomes a right\hyp to\hyp left order. - In order to change this to a left\hyp to\hyp right order, we must mirror every horizontal coordinate; due to the rotation, this corresponds to \tex!yscale=-1! (not \tex!xscale!). - \item The gates themselves should not be rotated. - In fact, no text should be rotated. - However, as by default, the \style{/yquant/every circuit} style will install the \texttt{transform shape} option to every node as of version~0.4, the nodes will also be rotated. - The first idea to disable \texttt{transform shape} does not turn out to work well, as the spacings are somehow messed up. - Instead, we just undo the rotation and scaling (note that now we need \tex!xscale=-1!, as after the reverse rotation, we are back to the ``proper'' coordinate system). - \end{itemize} - Then, there are some minor issues regarding the anchors of initial labels and output. - The default settings for them, \texttt{east} and \texttt{west} are of course inappropriate in a rotated layout, so those must be changed. - All the rest of the options that are given to the \texttt{yquant} environment just serve to match the appearance given in the \pkg{qpic} manual: we enlarge the \gate{slash}, the \gate{box}es and the \gate{measure}ments, and we also increase the global value of \style{/yquant/operator/minimum width}. - Remember that this is the minimum ``width'' (in the rotated scenario, it becomes a height) that \Yquant{} reserves for every single operator (unless it is larger), and it will center the operator within an invisible rectangle of this width if it is smaller. - So by matching this value to the largest height that occurs in the explanations in the circuit, we achieve an approximate vertical centering. - - Finally, there is some repetitive structure within the circuit, which we defer to a custom macro \tex!\explain!: We always want to draw a \gate{text} gate in our first invisible register \yquant!explainLeft!; however, this should not be centered, but rather aligned to the right, so we give the proper \tex!anchor=east!. - We also need the same thing on the right, just mirrored and with a \tex!\displaystyle! math environment; and after all the explanations are done, we \gate{align} all registers (if the minimum width/height was chosen to be exactly larger or equal to the actual height of every gate, this would not be necessary; but with two decimals, this is probably not precisely the case). + The circuit itself is very standard (though it is the first one in vertical mode). + In order to output the explanations, we define two invisible wires together with a macro that populates the corresponding \gate{text} gates on those wires. + Note that usually, in a vertical layout, all gates would be center\hyp aligned. + In order to align the left explanations to the right and the right explanations to the left, we just redefine the \texttt{anchor}s of the gates. + However, since \Yquant{} expects the gates to connect at the \texttt{center} anchor and hence equally distributes the required space for the wire to its left and right, this would lead to a very large gap between the explanations and the circuit itself. + Here, we don't need \Yquant's wire extent calculations at all---the explanation wires are invisible and at the border of the circuit. + Therefore, we just disable the calculations using the \texttt{overlay} attribute. + After all the explanations are done, we \gate{align} all registers (if the minimum extent was chosen to be exactly larger or equal to the actual vertical extent of every gate, this would not be necessary; but with two decimals, this is probably not precisely the case). Note that the code example above would work exactly in this way in traditional \LaTeX{} documents; however, this document is set with \pkg{unicode-math}. This leads to a problem when using \tex!\bmod!, which has to be \tex!\protect!ed---or, as we did here, just say \tex!\robustify\bmod! somewhere before its usage and after loading all the packages. @@ -3538,60 +3665,62 @@ $=$ \clearpage \paragraph{2.4 Example 4: Teleportation} - \begin{example} + \begin{example}<Updated in 0.7> \begin{codeexample*} -\begin{tikzpicture}[rotate=-90, yscale=-1, every node/.append style={rotate=90, xscale=-1}] - \begin{yquant}[every initial label/.style={anchor=south}, - every output/.style={anchor=north}, - operators/every barrier/.append style={rotate=-90}] - nobit explainLeft; +\begin{tikzpicture} + \newcommand\leftExplain[2][]{ + \yquantsecondpass{ + \draw[decoration={brace, mirror}, decorate, #1] + let \p1=(leftComments), \p2=(explainTop-0.north), \p3=(explainBottom-0.south) in + (\x1, \y2) -- (\x1, \y3) node[midway, left=2pt, align=right] {#2}; + } + } + \newcommand\rightExplain[2][]{ + \yquantsecondpass{ + \draw[decoration=brace, decorate, #1] + let \p1=(rightComments), \p2=(explainTop-0.north), \p3=(explainBottom-0.south) in + (\x1, \y2) -- (\x1, \y3) node[midway, right=2pt, align=left] {#2}; + } + } + \begin{yquant}[vertical] + [name=leftComments] nobit explainLeft; qubit {\color{red}$\ket\phi$} q; qubit {$\ket0$} q[+2]; - nobit explainRight; + [name=rightComments] nobit explainRight; setstyle {red} q[0]; + [name=explainTop] h q[1]; + [name=explainBottom] cnot q[2] | q[1]; + \rightExplain{Alice and Bob form an\\entangled pair of qubits} setstyle {red} q[1]; setstyle {blue} q[2]; - [y radius=5mm, anchor=west] - inspect {Alice and Bob form an\\entangled pair of qubits} (explainRight); - [operator/separation=0pt] barrier (q); - align -; - [style=red, operator/separation=0pt] cnot q[1] | q[0]; + [style=red, operator/separation=0pt, name=explainTop] cnot q[1] | q[0]; [red] h q[0]; - [red] measure q[0, 1]; - [red, y radius=9mm, anchor=east, align=right, shape=yquant-init, decoration={mirror}] - inspect {Alice entangles\\and measures} (explainLeft); - align -; + [red, name=explainBottom] measure q[0, 1]; + \leftExplain[red]{Alice entangles\\and measures} - [style=blue] x q[2] | q[1]; - [style=blue] z q[2] | q[0]; + [style=blue, name=explainTop] x q[2] | q[1]; + [style=blue, name=explainBottom] z q[2] | q[0]; discard q[0, 1]; - [blue, y radius=5.5mm, anchor=west] - inspect {Bob applies gates based on\\Alice's measurements} (explainRight); + \rightExplain[blue]{Bob applies gates based on\\Alice's measurements} output {\color{blue}$\ket\phi$} q[2]; \end{yquant} \end{tikzpicture} \end{codeexample*} - Again, we ignore that it is not possible to render the circuit in this way and do it anyway. - The structure is similar to what we previously did. - For some reason, the \gate{barrier} shape is not content with the back\hyp rotation and we must again rotate it. - - We now use \gate{inspect} gates to mimic the state information. - This gate will automatically draw curly braces as soon as it encounters a multi\hyp register use; hence, despite the fact that \yquant!explainRight! and \yquant!explainLeft! are single registers, we use them in a multi\hyp register fashion. - Next, the brace would only be high enough to incorporate the text (since it knows nothing about what goes on in the rest of the circuit); hence, we manually give it a \texttt{y radius} value that has to be determined appropriately. - - Since the default operator separation before and after the \gate{barrier} look a bit large, we set them to zero (\style{/yquant/operator/separation} will always affect the distance of the current operator to the previous one, so we need this for the \gate{barrier} and for the first \gate{cnot} gate after the \gate{barrier}). - - The \gate{inspect} gate on the left\hyp hand side needs some special attention. - In a horizontal layout, the brace will of course always be drawn left to the text, as the \gate{inspect} gate is supposed to denote the current state of the registers. - Therefore, we need to mirror the brace itself (\tex!decoration={mirror}!), and we also need to put it to the right\hyp hand side. - Coincidentally, the \texttt{yquant-init} style has the brace at its right\hyp hand side, so we just choose to change the style. - Using the \gate{init} gate instead would directly have invoked the correct \texttt{shape}; however, semantically, it is wrong, it would have changed the wire type to something visible (requiring a \gate{discard} directly afterwards) and it is also not scalable via \texttt{y radius}. + This example shows a different way of providing explanations along the circuit, which this time also works for hints encompassing more than a single gate. + We define the macros \tex!\leftExplain! and \tex!\rightExplain!, which in the circuit will do the job. + They rely on the existent of a couple of named nodes: The node \texttt{leftComments} (or \texttt{rightComments}) is the named node created at the beginning of the circuit when declaring the two invisible wires. + They will serve with their horizontal position. + Additionally, we require the named gates \texttt{explainTop} and \texttt{explainBottom}, which should correspond to the first and last gate that is supposed to be enclosed in the brace. + We then use \TikZ's \texttt{let} functionality in order to extract the required coordinates and draw the nodes. + Note that the macros \tex!\p!, \tex!\x!, and \tex!\y! come into existence only when the \tex!\draw! command is executed; hence, just writing the \tex!\draw! call would lead to an error: \Yquant{} would first try to add (using \tex!\protected@edef!) the content of the macro to its output routine for the second pass, then call it in the first pass. + We don't need the execution in the first pass---though it would not do harm---but we cannot allow for the expansion at this stage. + Hence, we wrap the whole command in \tex!\yquantsecondpass! (which automatically restarts the parser afterwards, so we don't have to do this). \end{example} \subsubsection{3.1 Wires} @@ -3790,16 +3919,16 @@ $=$ \begin{example} \begin{codeexample} -\begin{tikzpicture}[rotate=-90] - \begin{yquant*}[every initial label/.style={anchor=east}] - box {\rotatebox{90}{$M$}} (c, b) | a; - box {\rotatebox{90}{GATE}} (-); - box {\rotatebox{90}{$M^{-1}$}} (c, b) | a; - \end{yquant*} +\begin{tikzpicture} + \begin{yquant}[vertical=-90] + qubit a; qubit b; qubit c; + box {$M$} (c, b) | a; + box {GATE} (-); + box {$M^{-1}$} (c, b) | a; + \end{yquant} \end{tikzpicture} \end{codeexample} - Remember that \Yquant{} doesn't really support vertical layout, so it is always a bit of an experiment to make this work. - Multi\hyp register gates don't work too well when trying to apply the back\hyp rotation trick of before. + Here, we use the automatic rotation feature that the \style{/yquant/vertical} style provides. \end{example} \begin{example} @@ -3881,30 +4010,31 @@ $=$ \subsubsection{3.3 Attributes} \paragraph{Size Attributes} - \begin{example} - \begin{codeexample} + \begin{example}<Changed in 0.7> + \begin{codeexample*} \begin{tikzpicture} \begin{yquant*} [y radius=20pt] box {HIGH} (a, b); [x radius=20pt] box {WIDE} (-); + [time radius=20pt] box {LONG} (-); + [space radius=20pt] box {BROAD} (-); \end{yquant*} \end{tikzpicture} - \end{codeexample} - Note that \texttt{LONG} and \texttt{BROAD} do not make sense, as \Yquant{} does not support vertical layout. + \end{codeexample*} + In horizontal mode, \texttt{time radius} is a synonym for \texttt{x radius}, while \texttt{space radius} is a synonym for \texttt{y radius}. \end{example} - \begin{example} + \begin{example}<Changed in 0.7> \begin{codeexample} -\begin{tikzpicture}[rotate=-90, yscale=-1, every node/.append style={yscale=-1}] - \begin{yquant*}[every initial label/.style={rotate=45, anchor=east, shift={(.15, .15)}}] - [x radius=20pt] - box {\rotatebox{90}{HIGH}} (a, b); - [y radius=20pt] - box {\rotatebox{90}{WIDE}} (a, b); +\begin{tikzpicture} + \begin{yquant*}[vertical=45] + [y radius=20pt] box {HIGH} (a, b); + [x radius=20pt] box {WIDE} (-); + [time radius=20pt] box {LONG} (-); + [space radius=20pt] box {BROAD} (-); \end{yquant*} \end{tikzpicture} \end{codeexample} - Again, trying to properly adjust the position of the initial labels is more trial\hyp and\hyp error than anything else, and very fragile with respect to changes in the circuit. \end{example} \begin{example} @@ -4638,7 +4768,7 @@ $=$ The background path deserves more attention. We draw the two circles and the vertical and horizontal lines; but note that we disable the \pkg{pgf}'s size protocol for all but the right circle. Hence, when this shape is used, \TeX{} and \Yquant{} will actually think that it only occupies space for the right circle; the left one will protrude in the margin. - (Actually, we could wrap this in a test such as \tex!\ifdefined\yquant@prefix! to only discard protocoling within a \texttt{yquant} environment, so that the shape is properly usable outside.) + (Actually, we could wrap this in a test such as \tex!\ifdefined\yquant@prefix! to only discard protocoling within a \tex!yquant! environment, so that the shape is properly usable outside.) Next, we must take care of re\hyp inserting this ``lost'' margin whenever the gate is used; and we also define a style that appropriately uses the shape: \begin{codeexample*} @@ -4685,7 +4815,7 @@ $=$ We append the style that we just defined to the list of attributes, and execute the gate preparation. Finally, we also declare the attributes that this gate takes---no required and no optional attributes. - After all this work, which can be saved in some shared document and used whenever necessary, we can come to the application, which is now very straightforward. + After all this work, which can be saved in some shared document and used whenever necessary, we can come to the application, which is now very straightforward (however, note that our gate declaration was too simplistic for vertical mode; but an adaptation is not difficult). \begin{codeexample} \begin{tikzpicture} @@ -4731,7 +4861,7 @@ $=$ \compat{New in 0.3}\Yquant{} not only understands its own language, but also others. \compat{New in 0.5}Although we refer to ``foreign languages,'' additional extension packages of the \Yquant{} language itself are also covered in this section and can be loaded by the same syntax. - \subsection[groups]{\compat{New in 0.5}groups}\label{sec:foreign:groups} + \subsection[groups]{\compat{Updated in 0.7\\New in 0.5}groups}\label{sec:foreign:groups} By saying \tex!\useyquantlanguage{groups}! in the preamble after loading \Yquant{} itself, additional support for groups of \Yquant{} circuits is loaded. Various circuits in a group share a common set of registers, are appropriately aligned horizontally if on the same line and can also be aligned vertically among multiple lines. The main intended use is for circuit equations. @@ -4834,59 +4964,74 @@ $=$ Typically, you will not want to refer to named gates in a circuit on a different page; remember that if you need this feature, you must pass the \texttt{remember picture} key in the \style{/yquant/preamble} option, as this is a reference to another \tex!tikzpicture!. Also don't forget to use the (\TikZ) \texttt{overlay} key on the corresponding path that references the node in order not to mess up with the bounding box (see the \TikZ{} documentation for those two keys). - \subsubsection{Configuration} - Loading the \pkg{groups} language extension will define several new configuration keys. + \subsubsection{Configuration} + Loading the \pkg{groups} language extension will define several new configuration keys. - \begin{option}{group/every group}!! - Style that is installed for every \tex!yquantgroup! and \tex!yquantgroup*! environment, as if it had been given as an option. - The style's default path is \texttt{/tikz}. - \end{option} + \begin{option}{group/every group}!! + Style that is installed for every \tex!yquantgroup! and \tex!yquantgroup*! environment, as if it had been given as an option. + The style's default path is \texttt{/tikz}. + \end{option} - \begin{option}{group/line separation}!5mm! - This is the default vertical line separation that is inserted whenever a new line is issued in a \tex!yquantgroup!. - \end{option} + \begin{option}{group/line separation}!5mm! + This is the default vertical line separation that is inserted whenever a new line is issued in a \tex!yquantgroup!. + \end{option} + + \begin{option}{group/aligned}!false! + This boolean flag defines whether \tex!\shiftright! is automatically issued after \tex!\\! and the starred page breaking commands. + \end{option} + + \begin{option}{preamble}!! + This style may only be passed to the \tex!yquantgroup! alignment directly as an option; it is not available via \tex!\yquantset! and the like. + It is only relevant if the \tex!yquantgroup! is not contained in a \tex!tikzpicture!. + The content of this style will be given as an optional argument to the \tex!tikzpicture!; this is the recommended way to specify \TikZ{} options, as they are automatically preserved among page breaks. + \end{option} - \begin{option}{group/aligned}!false! - This boolean flag defines whether \tex!\shiftright! is automatically issued after \tex!\\! and the starred page breaking commands. - \end{option} + \begin{option}{operators/every group circuit}!/yquant/operators/every subcircuit, /yquant/operators/subcircuit/frameless, /yquant/operators/subcircuit/name mangling=transparent! + This style is installed for the \gate{subcircuit} that implicitly wraps each \tex!\circuit!. + Note that some magic is carried out to ensure that the name mangling setting only applies to the \emph{direct} content of the \tex!\circuit!; any \gate{subcircuit}s within the \tex!\circuit! will use the default name mangling scheme. + \end{option} - \begin{option}{preamble}!! - This style may only be passed to the \tex!yquantgroup! alignment directly as an option; it is not available via \tex!\yquantset! and the like. - It is only relevant if the \tex!yquantgroup! is not contained in a \tex!tikzpicture!. - The content of this style will be given as an optional argument to the \tex!tikzpicture!; this is the recommended way to specify \TikZ{} options, as they are automatically preserved among page breaks. - \end{option} + \begin{option}[Changed in 0.7]{operators/every group equals}!shape=yquant-rectangle, align=center, anchor/.expanded=\ifyquanthorz{center}{north west}, inner xsep=1mm, x radius=2mm, y radius=2.47mm! + This style is installed for every \tex!\equals!, which is internally realized similarly to a \gate{box} gate. + \end{option} - \begin{option}{operators/every group circuit}!/yquant/operators/every subcircuit, /yquant/operators/subcircuit/frameless, /yquant/operators/subcircuit/name mangling=transparent! - This style is installed for the \gate{subcircuit} that implicitly wraps each \tex!\circuit!. - Note that some magic is carried out to ensure that the name mangling setting only applies to the \emph{direct} content of the \tex!\circuit!; any \gate{subcircuit}s within the \tex!\circuit! will use the default name mangling scheme. - \end{option} + \subsubsection{Gates and operations} + No gates or operations may be used directly within the \tex!yquantgroup! environment, but all the usual \Yquant{} gates and operations are available within \tex!\registers! and \tex!\circuit!. + Additionally, within \tex!\circuit!, the \gate{import} gate is available. - \begin{option}{operators/every group equals}!shape=yquant-rectangle, align=center, inner xsep=1mm, x radius=2mm, y radius=2.47mm! - This style is installed for every \tex!\equals!, which is internally realized similarly to a \gate{box} gate. - \end{option} + \paragraph*{\yquant!import!}\label{gate:import}\leavevmode\\ + Syntax: \yquant!import <target>;! \\ + This is a pseudo\hyp gate that makes all the outer registers given in \tex!<target>! available in the current circuit. + Consequently, the register names that are specified in \tex!<target>!, also ranges, do not refer to the registers in the \emph{current} \tex!\circuit!, but instead to those defined via \tex!\registers!. + Therefore, it is for example possible to import all outer registers at once using \yquant!import -;!. + Vector registers can also be imported partially. - \subsubsection{Gates and operations} - No gates or operations may be used directly within the \tex!yquantgroup! environment, but all the usual \Yquant{} gates and operations are available within \tex!\registers! and \tex!\circuit!. - Additionally, within \tex!\circuit!, the \gate{import} gate is available. + If additional content (\TeX{} commands such as \TikZ{} paths, non\hyp creation gates) is used within \tex!\registers!, everything that comes \emph{before} the declaration of a register will be copied into the \tex!\circuit! when the register is imported; for a vector, this refers to the index zero. + Additionally, any additional content that comes \emph{after} the declaration of the last register will be copied directly after the last register was imported. - \paragraph*{\yquant!import!}\label{gate:import}\leavevmode\\ - Syntax: \yquant!import <target>;! \\ - This is a pseudo\hyp gate that makes all the outer registers given in \tex!<target>! available in the current circuit. - Consequently, the register names that are specified in \tex!<target>!, also ranges, do not refer to the registers in the \emph{current} \tex!\circuit!, but instead to those defined via \tex!\registers!. - Therefore, it is for example possible to import all outer registers at once using \yquant!import -;!. - Vector registers can also be imported partially. + \begin{warning}[Out-of-order importing] + Note that it is principle possible to import registers out\hyp of\hyp order. + Since matching outer and inner wires in subcircuits is done in the order in which they appear, this will lead to inner registers with names that do not match their outer registers and is probably highly undesirable. + \end{warning} - If additional content (\TeX{} commands such as \TikZ{} paths, non\hyp creation gates) is used within \tex!\registers!, everything that comes \emph{before} the declaration of a register will be copied into the \tex!\circuit! when the register is imported; for a vector, this refers to the index zero. - Additionally, any additional content that comes \emph{after} the declaration of the last register will be copied directly after the last register was imported. + Usually, this gate will not be needed as \Yquant{} will automatically import an outer register upon its first use. - \begin{warning}[Out-of-order importing] - Note that it is principle possible to import registers out\hyp of\hyp order. - Since matching outer and inner wires in subcircuits is done in the order in which they appear, this will lead to inner registers with names that do not match their outer registers and is probably highly undesirable. - \end{warning} + \emph{Possible attributes:} none - Usually, this gate will not be needed as \Yquant{} will automatically import an outer register upon its first use. + \subsubsection[Vertical layout]{\compat{New in 0.7}Vertical layout} + This library is aware of vertical circuits. + Note that the layout \emph{between} the circuits will always be the same, irrespective of the actual circuit orientation: Circuit will be set from left to right, and line breaks will always lead to a vertical shift and a reset of the horizontal position. - \emph{Possible attributes:} none + That said, the circuits may \emph{internally} be set in vertical mode. + Every invocation of \tex!\circuit! will then always restart a new \tex!yquant! environment. + While the content will still be put in a lonely \gate{subcircuit}---to keep consistency in the styling options---no inter\hyp circuit wire alignment will be carried out. + + There is an additional complication regarding the vertical alignment of circuit and equality signs within one ``line.'' + Now, the circuits can very well have a varying height, so vertically centering the circuits with respect to each other would not lead to a satisfying layout. + We might desire to vertically center the equality sign between its two enclosing circuits. + However, what if the line contains more than a two circuits and they all have different heights? + Then, the equality signs would be at different positions. + For this reason, all \tex!\circuit!s and \tex!\equals! will be aligned at their top. \subsection{qasm}\label{sec:foreign:qasm} By saying \tex!\useyquantlanguage{qasm}! in the preamble after loading \Yquant{} itself, the parser for \pkg{qasm} (not OpenQASM) is loaded. @@ -4985,7 +5130,7 @@ $=$ \emph{Symptom:} Unexpected error messages \item Does the macro depend on other macros defined \emph{within} the circuit? The double pass may lead to problems. - If possible, define your macros outside of the \texttt{yquant} environment. + If possible, define your macros outside of the \tex!yquant! environment. If this is not possible, make sure the definitions are expandable, then at measurement stage, \Yquant{} will do the expansion, so that you get the correct results. \\ \emph{Symptom:} Only the latest assignment will show up whenever the macro is used; the vertical spacing (for subcircuits, possibly also the horizontal spacing) may even be screwed. \item Does the macro create output, using its own font? @@ -5160,5 +5305,13 @@ $=$ New configuration: \style{/yquant/register/default lazy name} \\ Documentation: Replace the wishlist by a section on integration with other packages. \\ Documentation: Include the examples of \pkg{qpic} in this manual. + + \subsection*{2022-02-05: Version 0.7} + New: Support for vertical layout. \\ + Various bugfixes. \\ + Internal change of the loading order of the package files. \\ + Fix \href{https://github.com/projekter/yquant/issues/18}{\#18}: Subcircuit boxes don't render in \texttt{groups} environment. + Now, styles can properly modify the \style{/yquant/operators/this subcircuit box} style without affecting the content of the subcircuit, only the box. \\ + New: Support for a simplified drawing pipeline without clipping paths. %END_FOLD \end{document}
\ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-circuit.tex b/Master/texmf-dist/tex/latex/yquant/yquant-circuit.tex index 14f6a1f77bc..c4c99eceb2c 100644 --- a/Master/texmf-dist/tex/latex/yquant/yquant-circuit.tex +++ b/Master/texmf-dist/tex/latex/yquant/yquant-circuit.tex @@ -6,16 +6,18 @@ \edef\wirexpos{\the\dimen0}% \else% \pgfpointanchor{yquantbox}{#2}% - \edef\wirexpos{\the\pgf@x}% + \edef\wirexpos{\the\yquant@pgf@x}% \fi% - \ifdim\wirexpos>0pt % may be negative for init gates + \ifdim\yquant@orientation@plus\wirexpos>0pt % may be negative for init gates \yquant@register@get@typeywire{#1}\wiretype\wireypos\wirelast% \edef\wirexprevpos{\expandafter\@firstoffour\wirelast}% \ifnum\wiretype=\yquant@register@type@none% % the clippings of the previous operator will for sure not be needed, but the type might be turned into an active one, so we need the last clipping. \yquant@register@set@lastwire{#1}{% {\wirexprevpos}{\wirexpos}{}% - {\unexpanded\expandafter{\pgfshapeclippathhorzresult}}% + {\ifyquant@config@draw@quality% + \unexpanded\expandafter{\pgfshapeclippathhorzresult}% + \fi}% }% \else% % append the previous `last' clipping to the old list and insert the new one @@ -25,7 +27,9 @@ \expandafter\@thirdandfourthoffour\wirelast% }% }% - {\unexpanded\expandafter{\pgfshapeclippathhorzresult}}% + {\ifyquant@config@draw@quality% + \unexpanded\expandafter{\pgfshapeclippathhorzresult}% + \fi}% }% \fi% \fi% @@ -41,10 +45,14 @@ % to have a symmetric situation, we extend again one separation at the end, unless this is supposed to be seamless and we don't have outputs (for seamless circuits with outputs, extend - since this extension will be between last register and output) \ifyquant@env@seamless{% \expandafter\unless\expandafter\ifx\csname\yquant@prefix outputs\endcsname\relax% - \dimdef\yquant@circuit@endwires@x{\yquant@circuit@endwires@x+\yquant@config@operator@sep}% + \dimdef\yquant@circuit@endwires@x{% + \yquant@circuit@endwires@x\yquant@orientation@plus\yquant@config@operator@sep% + }% \fi% }{% - \dimdef\yquant@circuit@endwires@x{\yquant@circuit@endwires@x+\yquant@config@operator@sep}% + \dimdef\yquant@circuit@endwires@x{% + \yquant@circuit@endwires@x\yquant@orientation@plus\yquant@config@operator@sep% + }% }% \let\yquant@circuit@endwires@finalize=\relax% \yquant@for \yquant@circuit@endwires@i := 1 to \csname\yquant@prefix registers\endcsname {% @@ -52,9 +60,15 @@ \ifcsname\yquant@prefix registermap@\yquant@circuit@endwires@i\endcsname% \xifinlistcs\yquant@circuit@endwires@i{\yquant@prefix inonly}{% % however, the wire is to be discarded after this circuit - \edef\storedleft{\the\pgf@picminx}% - \yquant@draw@wire\yquant@circuit@endwires@i1% - \global\pgf@picminx=\storedleft% + \ifyquanthorz{% + \edef\storedleft{\the\pgf@picminx}% + \yquant@draw@wire\yquant@circuit@endwires@i1% + \global\pgf@picminx=\storedleft% + }{% + \edef\storedtop{\the\pgf@picmaxy}% + \yquant@draw@wire\yquant@circuit@endwires@i1% + \global\pgf@picmaxy=\storedtop% + }% \eappto\yquant@circuit@endwires@finalize{% \yquant@register@set@type% \yquant@circuit@endwires@i\noexpand\yquant@register@type@none% @@ -84,9 +98,11 @@ % BEGIN_FOLD Drawing control lines % populates a drawing macro with the current control line with style #1 at position #2. Assumes a node called yquantbox is set up, and the \pgfshapeclippathvertresult was set up appropriately for this node. At the first call, \yquant@circuit@extendcontrolline@cmd must be \let to \empty and \yquant@circuit@extendcontrolline@prev to \relax. \protected\def\yquant@circuit@extendcontrolline#1#2{% - \eappto\yquant@circuit@extendcontrolline@clip{% - \unexpanded\expandafter{\pgfshapeclippathvertresult}% - }% + \ifyquant@config@draw@quality% + \eappto\yquant@circuit@extendcontrolline@clip{% + \unexpanded\expandafter{\pgfshapeclippathvertresult}% + }% + \fi% \begingroup% \tikzset{/yquant/every control line}% \expandafter% @@ -100,7 +116,7 @@ \unless\ifx\yquant@circuit@extendcontrolline@prev\relax% \eappto\yquant@circuit@extendcontrolline@cmd{% \expandafter\@secondofthree\yquant@circuit@extendcontrolline@prev% - -- (#2,\the\pgf@y)% + -- \yquant@coords(#2,\the\yquant@pgf@y)% }% \fi% \yquant@circuit@extendcontrolline@store{#2}% @@ -110,9 +126,9 @@ \unless\ifx\yquant@circuit@extendcontrolline@prev\relax% \eappto\yquant@circuit@extendcontrolline@cmd{% \expandafter\@firstofthree\yquant@circuit@extendcontrolline@prev% - -- (\the\dimexpr#2-2\@tempdima\relax,\the\pgf@y)% + -- \yquant@coords(\the\dimexpr#2-2\@tempdima\relax,\the\yquant@pgf@y)% \expandafter\@thirdofthree\yquant@circuit@extendcontrolline@prev% - -- (\the\dimexpr#2+2\@tempdima\relax,\the\pgf@y)% + -- \yquant@coords(\the\dimexpr#2+2\@tempdima\relax,\the\yquant@pgf@y)% }% \fi% \yquant@circuit@extendcontrolline@store{#2}% @@ -122,11 +138,11 @@ \unless\ifx\yquant@circuit@extendcontrolline@prev\relax% \eappto\yquant@circuit@extendcontrolline@cmd{% \expandafter\@firstofthree\yquant@circuit@extendcontrolline@prev% - -- (\the\dimexpr#2-2\@tempdima\relax,\the\pgf@y)% + -- \yquant@coords(\the\dimexpr#2-2\@tempdima\relax,\the\yquant@pgf@y)% \expandafter\@secondofthree\yquant@circuit@extendcontrolline@prev% - -- (\the\dimexpr#2\relax,\the\pgf@y)% + -- \yquant@coords(\the\dimexpr#2\relax,\the\yquant@pgf@y)% \expandafter\@thirdofthree\yquant@circuit@extendcontrolline@prev% - -- (\the\dimexpr#2+2\@tempdima\relax,\the\pgf@y)% + -- \yquant@coords(\the\dimexpr#2+2\@tempdima\relax,\the\yquant@pgf@y)% }% \fi% \yquant@circuit@extendcontrolline@store{#2}% @@ -138,9 +154,9 @@ \protected\def\yquant@circuit@extendcontrolline@store#1{% \edef\yquant@circuit@extendcontrolline@prev{% - {(\the\dimexpr#1-2\@tempdima\relax,\the\pgf@y)}% - {(\the\dimexpr#1\relax,\the\pgf@y)}% - {(\the\dimexpr#1+2\@tempdima\relax,\the\pgf@y)}% + {\yquant@coords(\the\dimexpr#1-2\@tempdima\relax,\the\yquant@pgf@y)}% + {\yquant@coords(\the\dimexpr#1\relax,\the\yquant@pgf@y)}% + {\yquant@coords(\the\dimexpr#1+2\@tempdima\relax,\the\yquant@pgf@y)}% }% } @@ -150,18 +166,20 @@ \tikzset{/yquant/every multi line}% \expandafter% \endgroup% - \eappto\yquant@circuit@extendmultiline@clip{% - \unexpanded\expandafter{\pgfshapeclippathvertresult}% - }% + \ifyquant@config@draw@quality% + \eappto\yquant@circuit@extendmultiline@clip{% + \unexpanded\expandafter{\pgfshapeclippathvertresult}% + }% + \fi% \expandafter\@tempdima\the\pgflinewidth% \pgfpointanchor{yquantbox}{center}% \unless\ifx\yquant@circuit@extendmultiline@prev\relax% \eappto\yquant@circuit@extendmultiline@cmd{% - \yquant@circuit@extendmultiline@prev -- (#1,\the\pgf@y)% + \yquant@circuit@extendmultiline@prev -- \yquant@coords(#1,\the\yquant@pgf@y)% }% \fi% \edef\yquant@circuit@extendmultiline@prev{% - (\the\dimexpr#1\relax,\the\pgf@y)% + \yquant@coords(\the\dimexpr#1\relax,\the\yquant@pgf@y)% }% } % END_FOLD diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-config.tex b/Master/texmf-dist/tex/latex/yquant/yquant-config.tex index a50b2a4792c..ab07830929f 100644 --- a/Master/texmf-dist/tex/latex/yquant/yquant-config.tex +++ b/Master/texmf-dist/tex/latex/yquant/yquant-config.tex @@ -26,18 +26,99 @@ register/minimum height/.code=% {\dimdef\yquant@config@register@minimum@height{#1}},% register/minimum depth/.code=% - {\dimdef\yquant@config@register@minimum@depth{#1}}% + {\dimdef\yquant@config@register@minimum@depth{#1}},% + register/minimum left/.forward to=/yquant/register/minimum height,% + register/minimum right/.forward to=/yquant/register/minimum depth,% + register/minimum before/.forward to=/yquant/register/minimum height,% + register/minimum after/.forward to=/yquant/register/minimum after% } \fi +\def\yquant@config@draw@ensurelayers@addwires#1,main,#2\yquant@stop{% + \ifstrempty{#2}{% + % main was the last item in the list, so we needed to add the comma + \edef\pgf@layerlist{\@gobble#1,wires,main}% + }{% + % there were more items in the list, so we have a spurious comma in #2 + \expandafter\yquant@config@draw@ensurelayers@addwires@% + \expandafter,\pgf@layerlist\yquant@stop% + }% +} +\def\yquant@config@draw@ensurelayers@addwires@#1,main,#2\yquant@stop{% + \edef\pgf@layerlist{\@gobble#1,wires,main,#2}% +} +\def\yquant@config@draw@ensurelayers@haswires#1,wires,#2\yquant@stop{% + \ifstrempty{#2}{% + % wires not present yet, take action + \expandafter\yquant@config@draw@ensurelayers@addwires% + \expandafter,\pgf@layerlist,\yquant@stop% + }\relax% +} +\def\yquant@config@draw@ensurelayers@addbehindwires#1,wires,#2\yquant@stop{% + \ifstrempty{#2}{% + % wires was the last item in the list, so we needed to add the comma (should never happen) + \edef\pgf@layerlist{\@gobble#1,behindwires,wires}% + \PackageWarning{yquant.sty}{The wires layer was set on top of the main layer - expect undesirable outcomes.}% + }{% + % there were more items in the list, so we have a spurious comma in #2 + \expandafter\yquant@config@draw@ensurelayers@addbehindwires@% + \expandafter,\pgf@layerlist\yquant@stop% + }% +} +\def\yquant@config@draw@ensurelayers@addbehindwires@#1,wires,#2\yquant@stop{% + \edef\pgf@layerlist{\@gobble#1,behindwires,wires,#2}% +} +\def\yquant@config@draw@ensurelayers@hasbehindwires#1,behindwires,#2\yquant@stop{% + \ifstrempty{#2}{% + % wires not present yet, take action + \expandafter\yquant@config@draw@ensurelayers@addbehindwires% + \expandafter,\pgf@layerlist,\yquant@stop% + }\relax% +} +\def\yquant@config@draw@ensurelayers{% + \expandafter\yquant@config@draw@ensurelayers@haswires% + \expandafter,\pgf@layerlist,wires,\yquant@stop% + \expandafter\yquant@config@draw@ensurelayers@hasbehindwires% + \expandafter,\pgf@layerlist,behindwires,\yquant@stop% + \ifyquant@config@draw@quality% + % maybe the option was set outside of a tikzpicture, then we need to keep this + \global\let\endpgfpicture=\yquant@old@endpgfpicture% + \global\yquant@config@requirelayersfalse% + \fi% +} + \pgfqkeys{/yquant}{% register/separation/.code=% {\dimdef\yquant@config@register@sep{#1}},% operator/minimum width/.code=% {\dimdef\yquant@config@operator@minimum@width{#1}},% + operator/minimum extent/.forward to=/yquant/operator/minimum width,% operator/separation/.code=% {\dimdef\yquant@config@operator@sep{#1}},% operator/multi warning/.is if=% - yquant@config@operator@multi@warn% + yquant@config@operator@multi@warn,% + drawing mode/.is choice,% + drawing mode/quality/.code=% + {\yquant@config@draw@qualitytrue% + \pgfkeysalso{/yquant/default background=none}% + \unless\ifpgfpicture% + % we do not reset the special layer injection (there may be multiple yquant environments, and only one of them had the "size" drawing mode; then, we still need the layers), unless this is actually set outside of a tikzpicture + \ifdefined\yquant@old@endpgfpicture% only if we changed before + \global\let\endpgfpicture=\yquant@old@endpgfpicture% + \global\yquant@config@requirelayersfalse% + \fi% + \fi},% + drawing mode/size/.code=% + {\yquant@config@draw@qualityfalse% + \pgfkeysalso{/yquant/default background=white}% + \unless\ifyquant@config@requirelayers% + \global\let\yquant@old@endpgfpicture=\endpgfpicture% + \gpreto\endpgfpicture\yquant@config@draw@ensurelayers% + \fi% + \global\yquant@config@requirelayerstrue},% + default background/.initial=% + {none},% + default fill/.style={% + fill/.expanded=\pgfkeysvalueof{/yquant/default background}} }% % END_FOLD % BEGIN_FOLD Register creation @@ -50,20 +131,22 @@ \ifnum\yquant@compat<2 % \pgfqkeys{/yquant}{% every label/.style=% - {shape=yquant-init, anchor=center, align=right, outer xsep=2pt},% + {shape=yquant-init, anchor=center,% + align/.expanded=\ifyquanthorz{right}{center}, outer timesep=2pt},% every multi label/.style=% - {draw, decoration={gapped brace, mirror, raise=2pt}, decorate}% + {draw, decoration/.expanded={gapped brace, raise=2pt, \ifyquanthorz{mirror}{}}, decorate}% } \else \pgfqkeys{/yquant}{% every label/.style=% - {shape=yquant-init, anchor=center, align=right, outer xsep=2pt,% - /yquant/operator/if multi={draw, decoration={gapped brace, mirror, raise=2pt}, decorate}}% + {shape=yquant-init, anchor=center,% + align/.expanded=\ifyquanthorz{right}{center}, outer timesep=2pt,% + /yquant/operator/if multi={draw, decoration/.expanded={gapped brace, raise=2pt, \ifyquanthorz{mirror}{}}, decorate}}% } \fi \pgfqkeys{/yquant}{ every initial label/.style=% - {anchor=east},% + {anchor/.expanded=\ifyquanthorz{east}{south}, /yquant/internal/autorotate init},% every qubit label/.style=% {},% every cbit label/.style=% @@ -82,15 +165,19 @@ \ifnum\yquant@compat<2 % \pgfqkeys{/yquant}{% every output/.style=% - {shape=yquant-output, anchor=west, align=left, outer xsep=2pt},% + {shape=yquant-output, anchor/.expanded=\ifyquanthorz{west}{north},% + align/.expanded=\ifyquanthorz{left}{center}, outer timesep=2pt,% + /yquant/internal/autorotate output},% every multi output/.style=% - {draw, decoration={gapped brace, raise=2pt}, decorate}% + {draw, decoration/.expanded={gapped brace, raise=2pt, \ifyquanthorz{}{mirror}}, decorate}% } \else \pgfqkeys{/yquant}{% every output/.style=% - {shape=yquant-output, anchor=west, align=left, outer xsep=2pt,% - /yquant/operator/if multi={draw, decoration={gapped brace, raise=2pt}, decorate}}% + {shape=yquant-output, anchor/.expanded=\ifyquanthorz{west}{north},% + align/.expanded=\ifyquanthorz{left}{center}, outer timesep=2pt,% + /yquant/operator/if multi={draw, decoration/.expanded={gapped brace, raise=2pt, \ifyquanthorz{}{mirror}}, decorate},% + /yquant/internal/autorotate output}% } \fi \pgfqkeys{/yquant}{% @@ -129,7 +216,7 @@ every positive control/.style=% {fill=black},% every negative control/.style=% - {draw},% + {draw, /yquant/default fill},% every operator/.style=% {anchor=center},% every multi line/.style=% @@ -152,6 +239,41 @@ operator/if multi/.code=% {\ifyquant@config@operator@multi\pgfkeysalso{#1}\fi},% circuit/seamless/.is if=yquant@config@circuit@seamless,% + circuit/orientation/.is choice,% + circuit/orientation/horizontal/.code={% + \ifyquant@config@circuitsetup% + \pgfkeysalso{/yquant/internal/autorotate init/.style={},% + /yquant/internal/autorotate output/.style={}}% + \yquant@config@circuit@orientation@horizontal% + \else% + \PackageError{yquant.sty}{`circuit/orientation' can only be modified in the environment options or globally.}{Don't modify this within a circuit.}% + \fi% + },% + circuit/orientation/vertical/.code={% + \ifyquant@config@circuitsetup% + \yquant@config@circuit@orientation@vertical% + \else% + \PackageError{yquant.sty}{`circuit/orientation' can only be modified in the environment options or globally.}{Don't modify this within a circuit.}% + \fi% + },% + horizontal/.forward to=/yquant/circuit/orientation/horizontal,% + vertical/.code={% + \pgfkeysalso{/yquant/circuit/orientation/vertical}% + \unless\ifdim#1 pt=0pt % + \ifdefined\adjustbox% + \pgfkeysalso{% + /yquant/internal/autorotate init/.style={% + /tikz/execute at begin node={\adjustbox{rotate=#1}}% + }, /yquant/internal/autorotate output/.style={% + /tikz/execute at begin node={\adjustbox{rotate=-#1}}% + }% + }% + \else% + \PackageWarning{yquant.sty}{In order to use the automatic rotation of initial labels for vertical circuits, you need to load the `adjustbox' package.}% + \fi% + \fi% + },% + vertical/.default=0,% every post measurement control/.is choice, every post measurement control/indirect/.code={% \undef\yquant@lang@attr@directcontrol% @@ -175,7 +297,7 @@ \fi \pgfqkeys{/yquant}{% operators/every text/.style=% - {shape=yquant-rectangle, align=center, inner xsep=1mm, x radius=2mm, y radius=2.47mm}% + {shape=yquant-rectangle, align=center, inner timesep=1mm, time radius=2mm, space radius=2.47mm, /yquant/default fill}% } \ifnum\yquant@compat<3 % \pgfqkeys{/yquant}{% @@ -183,12 +305,12 @@ operators/every rectangular box/.style=% {/yquant/operators/every box},% operators/every box/.style=% - {shape=yquant-rectangle, draw, align=center, inner xsep=1mm, x radius=2mm, y radius=2.47mm}% + {shape=yquant-rectangle, draw, align=center, inner timesep=1mm, time radius=2mm, space radius=2.47mm, /yquant/default fill}% } \else \pgfqkeys{/yquant}{% operators/every rectangular box/.style=% - {shape=yquant-rectangle, draw, align=center, inner xsep=1mm, x radius=2mm, y radius=2.47mm},% + {shape=yquant-rectangle, draw, align=center, inner timesep=1mm, time radius=2mm, space radius=2.47mm, /yquant/default fill},% operators/every box/.style=% {/yquant/operators/every rectangular box}% } @@ -206,17 +328,18 @@ \fi \pgfqkeys{/yquant}{% operators/every dmeter/.style=% - {shape=yquant-dmeter, x radius=2mm, y radius=2mm, draw}, + {shape=yquant-dmeter, time radius=2mm, space radius=2mm, draw, /yquant/default fill}, % every h is implicitly defined during gate declaration operators/every inspect/.style=% - {shape=yquant-output, align=left, outer xsep=.3333em, y radius=2.47mm,% - /yquant/operator/if multi={draw, decoration={gapped brace, raise=2pt}, decorate}},% + {shape=yquant-output, align/.expanded=\ifyquanthorz{left}{center}, + outer timesep=.3333em, space radius=2.47mm, /yquant/default fill,% + /yquant/operator/if multi={draw, decoration/.expanded={gapped brace, raise=2pt, \ifyquanthorz{}{mirror}}, decorate}},% operators/every measure/.style=% - {shape=yquant-measure, x radius=4mm, y radius=2.5mm, draw},% + {shape=yquant-measure, x radius=4mm, y radius=2.5mm, draw, /yquant/default fill},% operators/every measure meter/.style=% {draw, -{Latex[length=2.5pt]}},% operators/every not/.style=% - {shape=yquant-oplus, radius=1.3mm, draw},% + {shape=yquant-oplus, radius=1.3mm, draw, /yquant/default fill},% operators/every pauli/.style=% {/yquant/operators/every rectangular box},% operators/every phase/.style=% @@ -226,7 +349,7 @@ operators/every subcircuit/.style=% {},% operators/every subcircuit box/.style=% - {/yquant/operators/every rectangular box},% + {/yquant/operators/every rectangular box, fill=none},% subcircuit box style/.style=% {/yquant/operators/every subcircuit box/.append style={#1}},% operators/this subcircuit box/.style=% @@ -260,7 +383,7 @@ {shape=yquant-circle, radius=.5mm, fill},% % every x is implicitly defined during gate declaration operators/every xx/.style=% - {shape=yquant-rectangle, radius=.75mm, draw},% + {shape=yquant-rectangle, radius=.75mm, draw, /yquant/default fill},% % every y is implicitly defined during gate declaration % every z is implicitly defined during gate declaration operators/every zz/.style=% @@ -277,6 +400,10 @@ \fi}, internal/multi main/.is if=% yquant@config@internal@multi@main,% + internal/setup done/.code=% + {\yquant@config@circuitsetupfalse},% + internal/autorotate init/.style={},% + internal/autorotate output/.style={},% } \ifnum\yquant@compat<2 % \pgfqkeys{/yquant}{% @@ -291,13 +418,105 @@ \fi % END_FOLD +\protected\def\yquant@config@circuit@orientation@horizontal{% + \let\ifyquanthorz=\@firstoftwo% + \tikzset{% + % in principle, these are all /.forward to handlers, but we want them non-accumulative + time radius/.code={\pgfkeys{/tikz/x radius={##1}}},% + space radius/.code={\pgfkeys{/tikz/y radius={##1}}},% + inner timesep/.code={\pgfkeys{/tikz/inner xsep={##1}}},% + inner spacesep/.code={\pgfkeys{/tikz/inner ysep={##1}}},% + outer timesep/.code={\pgfkeys{/tikz/outer xsep={##1}}},% + outer spacesep/.code={\pgfkeys{/tikz/outer ysep={##1}}}% + }% + \def\yquant@config@register@minimum@height@default{1.5mm}% + \def\yquant@config@register@minimum@depth@default{1.5mm}% + \def\yquant@config@operator@minimum@width@default{5mm}% + \let\yquant@pgf@picminx=\pgf@picminx% + \let\yquant@pgf@picmaxx=\pgf@picmaxx% + \let\yquant@pgf@picminy=\pgf@picminy% + \let\yquant@pgf@picmaxy=\pgf@picmaxy% + \let\yquant@pgf@x=\pgf@x% + \let\yquant@pgf@y=\pgf@y% + \let\yquant@pgf@pt@x=\pgf@pt@x% + \let\yquant@pgf@pt@y=\pgf@pt@y% + \let\yquant@pgfqpoint=\pgfqpoint% + \let\yquant@coords=\empty% + \let\pgfshapeclippath=\yquant@pgfshapeclippath@horz% + \def\yquant@orientation@x{x}% + \def\yquant@orientation@y{y}% + \def\yquant@orientation@plus{+}% + \def\yquant@orientation@minus{-}% +} + +\protected\def\yquant@config@circuit@orientation@vertical{% + \let\ifyquanthorz=\@secondoftwo% + \tikzset{% + % in principle, these are all /.forward to handlers, but we want them non-accumulative + time radius/.code={\pgfkeys{/tikz/y radius={##1}}},% + space radius/.code={\pgfkeys{/tikz/x radius={##1}}},% + inner timesep/.code={\pgfkeys{/tikz/inner ysep={##1}}},% + inner spacesep/.code={\pgfkeys{/tikz/inner xsep={##1}}},% + outer timesep/.code={\pgfkeys{/tikz/outer ysep={##1}}},% + outer spacesep/.code={\pgfkeys{/tikz/outer xsep={##1}}}% + }% + \def\yquant@config@register@minimum@height@default{2.5mm}% + \def\yquant@config@register@minimum@depth@default{2.5mm}% + \def\yquant@config@operator@minimum@width@default{3mm}% + \let\yquant@pgf@picminx=\pgf@picminy% + \let\yquant@pgf@picmaxx=\pgf@picmaxy% + \let\yquant@pgf@picminy=\pgf@picminx% + \let\yquant@pgf@picmaxy=\pgf@picmaxx% + \let\yquant@pgf@x=\pgf@y% + \let\yquant@pgf@y=\pgf@x% + \let\yquant@pgf@pt@x=\pgf@pt@y% + \let\yquant@pgf@pt@y=\pgf@pt@x% + \def\yquant@pgfqpoint##1##2{\pgfqpoint{##2}{##1}}% + \def\yquant@coords(##1,##2){({##2},{##1})}% + \let\pgfshapeclippath=\yquant@pgfshapeclippath@vert% + \def\yquant@orientation@x{y}% + \def\yquant@orientation@y{x}% + \def\yquant@orientation@plus{-}% + \def\yquant@orientation@minus{+}% +} + +\let\yquant@pgfshapeclippath@horz=\pgfshapeclippath +\let\yquant@pgfshapeclippath@vert=\pgfshapeclippath +\patchcmd\yquant@pgfshapeclippath@vert{% + \global\let\pgfshapeclippathhorzresult=\pgfshapeclippathresult% + \ifcsname pgf@sh@clipvert@\csname pgf@sh@ns@#1\endcsname\endcsname% + % different clipping in vertical direction + \pgfsyssoftpath@setcurrentpath\pgfutil@empty% + \csname pgf@sh@clipvert@\csname pgf@sh@ns@#1\endcsname\endcsname% + \pgfsyssoftpath@getcurrentpath\pgfshapeclippathresult% + \pgfprocessround{\pgfshapeclippathresult}{\pgfshapeclippathresult}% + \fi% + \global\let\pgfshapeclippathvertresult=\pgfshapeclippathresult% +}{% + \global\let\pgfshapeclippathvertresult=\pgfshapeclippathresult% + \ifcsname pgf@sh@clipvert@\csname pgf@sh@ns@#1\endcsname\endcsname% + % different clipping in vertical direction + \pgfsyssoftpath@setcurrentpath\pgfutil@empty% + \csname pgf@sh@clipvert@\csname pgf@sh@ns@#1\endcsname\endcsname% + \pgfsyssoftpath@getcurrentpath\pgfshapeclippathresult% + \pgfprocessround{\pgfshapeclippathresult}{\pgfshapeclippathresult}% + \fi% + \global\let\pgfshapeclippathhorzresult=\pgfshapeclippathresult% +}{}{% + \PackageError{yquant.sty}{Unable to path \string\pgfshapeclippath}% + {Vertical layout will not work.}% +} + \def\yquant@config@register@default@name{\regidx} \let\yquant@config@register@default@lazyname=\empty -\def\yquant@config@register@minimum@height{1.5mm} -\def\yquant@config@register@minimum@depth{1.5mm} +\def\yquant@config@register@minimum@height{\yquant@config@register@minimum@height@default} +\def\yquant@config@register@minimum@height@default{1.5mm} +\def\yquant@config@register@minimum@depth{\yquant@config@register@minimum@depth@default} +\def\yquant@config@register@minimum@depth@default{1.5mm} \def\yquant@config@register@sep{1mm} \def\yquant@config@operator@sep{1mm} -\def\yquant@config@operator@minimum@width{5mm} +\def\yquant@config@operator@minimum@width{\yquant@config@operator@minimum@width@default} +\def\yquant@config@operator@minimum@width@default{5mm} \newif\ifyquant@config@internal@multi@main% \yquant@config@internal@multi@maintrue \newif\ifyquant@config@operator@multi@warn @@ -310,6 +529,12 @@ \newif\ifyquant@config@operator@subcircuit@manglingreset \yquant@config@operator@subcircuit@manglingresettrue \newif\ifyquant@config@operator@multi +\newif\ifyquant@config@circuitsetup +\yquant@config@circuitsetuptrue +\yquant@config@circuit@orientation@horizontal +\newif\ifyquant@config@draw@quality +\yquant@config@draw@qualitytrue +\newif\ifyquant@config@requirelayers \protected\def\yquant@config@operator@subcircuit@mangling@set#1{% \ifyquant@config@operator@subcircuit@manglingreset% diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-draw.tex b/Master/texmf-dist/tex/latex/yquant/yquant-draw.tex index 574a45eec19..6f509418099 100644 --- a/Master/texmf-dist/tex/latex/yquant/yquant-draw.tex +++ b/Master/texmf-dist/tex/latex/yquant/yquant-draw.tex @@ -62,19 +62,19 @@ \ifyquant@env@seamless{% \unless\ifdim\yquant@draw@@x=\yquant@draw@subcircuit@leftpos% \dimdef\yquant@draw@@x{% - \yquant@draw@@x+\yquant@config@operator@sep% + \yquant@draw@@x\yquant@orientation@plus\yquant@config@operator@sep% }% \fi% }{% \dimdef\yquant@draw@@x{% - \yquant@draw@@x+\yquant@config@operator@sep% + \yquant@draw@@x\yquant@orientation@plus\yquant@config@operator@sep% }% }% \ifyquant@config@operator@position@advance% - \dimdef\newx{\yquant@draw@@x+#1}% + \dimdef\newx{\yquant@draw@@x\yquant@orientation@plus#1}% \forlistloop\yquant@draw@group@advance{#6}% \fi% - \dimdef\yquant@draw@@x{\yquant@draw@@x+.5\dimexpr#1\relax}% + \dimdef\yquant@draw@@x{\yquant@draw@@x\yquant@orientation@plus.5\dimexpr#1\relax}% \fi% } @@ -157,9 +157,11 @@ \fi% \edef\process{% \endgroup% - \def\noexpand\yquant@circuit@extendcontrolline@clip{% - \unexpanded\expandafter{\yquant@circuit@extendcontrolline@clip}% - }% + \ifyquant@config@draw@quality% + \def\noexpand\yquant@circuit@extendcontrolline@clip{% + \unexpanded\expandafter{\yquant@circuit@extendcontrolline@clip}% + }% + \fi% \def\noexpand\yquant@circuit@extendcontrolline@prev{% \unexpanded\expandafter{\yquant@circuit@extendcontrolline@prev}% }% @@ -196,13 +198,15 @@ \let\idx=\yquant@draw@@idx@content% \yquant@config@operator@multifalse% \edef\cmd{% - \noexpand\path (\yquant@draw@@x, \yquant@register@get@y{#1})% + \noexpand\path \yquant@coords(\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}};% - \pgfshapeclippath{yquantbox}% - {/yquant/every operator, \yquant@draw@@style,% - /yquant/this operator}% + \ifyquant@config@draw@quality% + \pgfshapeclippath{yquantbox}% + {/yquant/every operator, \yquant@draw@@style,% + /yquant/this operator}% + \fi% }% \cmd% \yquant@circuit@extendwire{#1}{center}% @@ -239,18 +243,20 @@ \protected\def\yquant@draw@multi@contiguous#1#2#3{% % We need to somehow extract the y radius \edef\cmd{% - \noexpand\path (\yquant@draw@@x, \the\dimexpr.5\dimexpr% + \noexpand\path \yquant@coords(\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,% /yquant/internal/multi main=\ifnum#3=1 true\else false\fi\unless\ifnum#1=#2 ,% - y radius/.expanded=\the\dimexpr.5\dimexpr\yquant@register@get@ydist{#1}{#2}\relax\relax+% - .5*\noexpand\pgfkeysvalueof{/tikz/y radius}\fi,% + space radius/.expanded=\the\dimexpr.5\dimexpr\yquant@register@get@ydist{#1}{#2}\relax\relax+% + .5*\noexpand\pgfkeysvalueof{/tikz/\yquant@orientation@y\space radius}\fi,% name prefix=, name suffix=, name=yquantbox]% {\unexpanded\expandafter{\yquant@draw@@content}};% - \pgfshapeclippath{yquantbox}% - {/yquant/every operator, \yquant@draw@@style,% - /yquant/this operator}% + \ifyquant@config@draw@quality% + \pgfshapeclippath{yquantbox}% + {/yquant/every operator, \yquant@draw@@style,% + /yquant/this operator}% + \fi% }% \cmd% \yquant@for \i := #1 to #2 {% @@ -271,7 +277,7 @@ \protected\def\yquant@draw@multiinit#1#2#3#4#5{% \let\idx=\yquant@draw@@idx@content% - \@tempdima=-.5\dimexpr\yquant@config@register@sep\relax% + \@tempdima=\yquant@orientation@minus.5\dimexpr\yquant@config@register@sep\relax% \dimdef\yquant@draw@multiinit@@min{\yquant@register@get@y{#1}-\@tempdima}% \dimdef\yquant@draw@multiinit@@max{\yquant@register@get@y{#2}+\@tempdima}% \dimdef\yquant@draw@multiinit@@total{% @@ -285,19 +291,21 @@ \yquant@config@operator@multitrue% % We need to somehow extract the y radius \edef\cmd{% - \noexpand\path (\yquant@draw@@x, \the\dimexpr.5\dimexpr% + \noexpand\path \yquant@coords(\yquant@draw@@x, \the\dimexpr.5\dimexpr% \yquant@draw@multiinit@@min+\yquant@draw@multiinit@@max\relax% \relax)% node[/yquant/every operator, \yquant@draw@@style, \ifnum\yquant@compat<2 /yquant/every multi label,\fi% /yquant/this operator,% - y radius=\yquant@abs{\the\dimexpr.5\dimexpr\yquant@draw@multiinit@@total\relax\relax},% + space radius=\yquant@abs{\the\dimexpr.5\dimexpr\yquant@draw@multiinit@@total\relax\relax},% name prefix=, name suffix=, name=yquantbox]% {\unexpanded\expandafter{\yquant@draw@@content}};% - \pgfshapeclippath{yquantbox}% - {/yquant/every operator, \yquant@draw@@style,% - \ifnum\yquant@compat<2 /yquant/every multi label,\fi% - /yquant/this operator}% + \ifyquant@config@draw@quality% + \pgfshapeclippath{yquantbox}% + {/yquant/every operator, \yquant@draw@@style,% + \ifnum\yquant@compat<2 /yquant/every multi label,\fi% + /yquant/this operator}% + \fi% }% \cmd% \yquant@for \i := #1 to #2 {% @@ -353,20 +361,22 @@ \let\idx=\yquant@draw@@idx@content% \yquant@config@operator@multifalse% \edef\cmd{% - \noexpand\path (\yquant@circuit@endwires@x, \yquant@register@get@y{#1})% + \noexpand\path \yquant@coords(\yquant@circuit@endwires@x, \yquant@register@get@y{#1})% node[\ifnum\yquant@compat>1 /yquant/every operator,\fi% /yquant/every output,% /yquant/every \yquant@register@type@tostring{\yquant@register@get@type{#1}} output,% \yquant@draw@@style, /yquant/this operator,% name prefix=, name suffix=, name=yquantbox]% {\unexpanded\expandafter{\yquant@draw@@content}};% - \ifdefined\yquant@parent% - \pgfshapeclippath{yquantbox}% - {\ifnum\yquant@compat>1 /yquant/every operator,\fi% - /yquant/every output,% - /yquant/every \yquant@register@type@tostring{\yquant@register@get@type{#1}} output,% - \yquant@draw@@style,% - /yquant/this operator}% + \ifyquant@config@draw@quality% + \ifdefined\yquant@parent% + \pgfshapeclippath{yquantbox}% + {\ifnum\yquant@compat>1 /yquant/every operator,\fi% + /yquant/every output,% + /yquant/every \yquant@register@type@tostring{\yquant@register@get@type{#1}} output,% + \yquant@draw@@style,% + /yquant/this operator}% + \fi% \fi% }% \cmd% @@ -383,7 +393,7 @@ \protected\long\def\yquant@draw@output@multi#1#2#3#4#5{% \let\idx=\yquant@draw@@idx@content% - \@tempdima=-.5\dimexpr\yquant@config@register@sep\relax% + \@tempdima=\yquant@orientation@minus.5\dimexpr\yquant@config@register@sep\relax% \dimdef\yquant@draw@multiinit@@min{\yquant@register@get@y{#1}-\@tempdima}% \dimdef\yquant@draw@multiinit@@max{\yquant@register@get@y{#2}+\@tempdima}% \dimdef\yquant@draw@multiinit@@total{% @@ -397,22 +407,24 @@ \yquant@config@operator@multitrue% % We need to somehow extract the y radius \edef\cmd{% - \noexpand\path (\yquant@circuit@endwires@x, \the\dimexpr.5\dimexpr% + \noexpand\path \yquant@coords(\yquant@circuit@endwires@x, \the\dimexpr.5\dimexpr% \yquant@draw@multiinit@@min+\yquant@draw@multiinit@@max\relax% \relax)% node[\ifnum\yquant@compat>1 /yquant/every operator,\fi /yquant/every output,% \yquant@draw@@style,% \ifnum\yquant@compat<2 /yquant/every multi output,\fi% /yquant/this operator,% - y radius=\yquant@abs{\the\dimexpr.5\dimexpr\yquant@draw@multiinit@@total\relax\relax},% + space radius=\yquant@abs{\the\dimexpr.5\dimexpr\yquant@draw@multiinit@@total\relax\relax},% name prefix=, name suffix=, name=yquantbox]% {\unexpanded\expandafter{\yquant@draw@@content}};% - \ifdefined\yquant@parent% - \pgfshapeclippath{yquantbox}% - {\ifnum\yquant@compat>1 /yquant/every operator,\fi /yquant/every output,% - \yquant@draw@@style, - \ifnum\yquant@compat<2 /yquant/every multi output,\fi% - /yquant/this operator}% + \ifyquant@config@draw@quality% + \ifdefined\yquant@parent% + \pgfshapeclippath{yquantbox}% + {\ifnum\yquant@compat>1 /yquant/every operator,\fi /yquant/every output,% + \yquant@draw@@style, + \ifnum\yquant@compat<2 /yquant/every multi output,\fi% + /yquant/this operator}% + \fi% \fi% }% \cmd% @@ -449,15 +461,16 @@ \global\cslet\yquant@draw@subcircuit@nodelist\empty% % \pgfinterruptboundingbox, but just for y \begingroup% - \edef\pgf@interrupt@savemaxy{\the\pgf@picmaxy}% - \edef\pgf@interrupt@saveminy{\the\pgf@picminy}% - \pgf@picmaxy=-16000pt % - \pgf@picminy=16000pt % + \edef\pgf@interrupt@savemaxy{\the\yquant@pgf@picmaxy}% + \edef\pgf@interrupt@saveminy{\the\yquant@pgf@picminy}% + \yquant@pgf@picmaxy=-16000pt % + \yquant@pgf@picminy=16000pt % \pgf@size@hookedfalse% \let\pgf@path@size@hook=\pgfutil@empty% % now we must take care of extending all the wires appropriately until the beginning of the box. #4 contains width of this box, #5 contains registers affected by this box. Note that for subcircuits, x extension by the group is disabled. \dimdef\newx{% - \yquant@draw@@x-.5\dimexpr\@secondofthree#4\relax% + \yquant@draw@@x\yquant@orientation@minus% + .5\dimexpr\@secondofthree#4\relax% }% \dimen0=\newx% \let\yquant@draw@subcircuit@leftpos=\newx% seamless subcircuits: do not add another separation if we are there @@ -465,7 +478,9 @@ \forlistloop\yquant@draw@move@loop{#5}% % but the new positions are not at the beginning of the box, but inside (with possible margin) \dimdef\newx{% - \yquant@draw@@x-.5\dimexpr\@firstofthree#4\relax-\@thirdofthree#4% + \yquant@draw@@x\yquant@orientation@minus% + .5\dimexpr\@firstofthree#4\relax\yquant@orientation@minus% + \@thirdofthree#4% }% \forlistloop\yquant@draw@group@advance{#5}% \setbox\yquant@prepare@subcircuit@box=\hbox{{% @@ -509,53 +524,55 @@ /yquant/this operator, /yquant/internal/multi main=true,% }% \expandafter\tikzset\expandafter{\yquant@draw@subcircuit@style}% + % #18: The styles may have set this subcircuit box again, but we disallow this. The "this" style is only supposed to effect the actual box and nothing else, so it should not permeat in the inner of the circuit. This is what every subcircuit box is for! + \pgfkeys{/yquant/operators/this subcircuit box/.style={}}% \begingroup% \csname\yquant@prefix draw\endcsname% \endgroup% % BEGIN_FOLD bounding box % Completely empty wires did not yet affect the bounding box - % Problem: we compare an user-mode TikZ position (register y position) with a system-level pgf position (picture boundary box). If shifts or scalings are in effect, we must first transform the point appropriately. Note that negative scalings may upset our assumption of which is the minimum and which is the maximum! If additionally rotations are in effect, we must even consider those transformations for the leftmost and the rightmost point, which makes all of this far more complicated than it should be. For this reason, we have a shortcut in action in case no nontranslation transformations are present. + % Problem: we compare a user-mode TikZ position (register y position) with a system-level pgf position (picture boundary box). If shifts or scalings are in effect, we must first transform the point appropriately. Note that negative scalings may upset our assumption of which is the minimum and which is the maximum! If additionally rotations are in effect, we must even consider those transformations for the leftmost and the rightmost point, which makes all of this far more complicated than it should be. For this reason, we have a shortcut in action in case no nontranslation transformations are present. \ifpgf@pt@identity% - \dimen0=\dimexpr\yquant@register@get@y1+\pgf@pt@y\relax% - \ifdim\dimen0>\pgf@picmaxy % - \global\pgf@picmaxy=\dimen0 % + \dimen0=\dimexpr\yquant@register@get@y1+\yquant@pgf@pt@y\relax% + \ifdim\dimen0>\yquant@pgf@picmaxy % + \global\yquant@pgf@picmaxy=\dimen0 % \fi% - \dimen0=\dimexpr\yquant@register@get@y{\csname\yquant@prefix registers\endcsname}+\pgf@pt@y\relax% - \ifdim\dimen0<\pgf@picminy % - \global\pgf@picminy=\dimen0 % + \dimen0=\dimexpr\yquant@register@get@y{\csname\yquant@prefix registers\endcsname}+\yquant@pgf@pt@y\relax% + \ifdim\dimen0<\yquant@pgf@picminy % + \global\yquant@pgf@picminy=\dimen0 % \fi% \else% % first wire, left end - \pgfpointtransformed{\pgfqpoint{\yquant@draw@@x-.5\dimexpr\@firstofthree#4\relax}{\yquant@register@get@y1\relax}}% - \ifdim\pgf@y>\pgf@picmaxy % - \global\pgf@picmaxy=\pgf@y % + \pgfpointtransformed{\yquant@pgfqpoint{\yquant@draw@@x-.5\dimexpr\@firstofthree#4\relax}{\yquant@register@get@y1\relax}}% + \ifdim\yquant@pgf@y>\yquant@pgf@picmaxy % + \global\yquant@pgf@picmaxy=\yquant@pgf@y % \fi% - \ifdim\pgf@y<\pgf@picminy % negative scaling - \global\pgf@picminy=\pgf@y % + \ifdim\yquant@pgf@y<\yquant@pgf@picminy % negative scaling + \global\yquant@pgf@picminy=\yquant@pgf@y % \fi% % first wire, right end - \pgfpointtransformed{\pgfqpoint{\yquant@draw@@x+.5\dimenxpr\@firstofthree#4\relax}{\yquant@register@get@y1\relax}}% - \ifdim\pgf@y>\pgf@picmaxy % - \global\pgf@picmaxy=\pgf@y % + \pgfpointtransformed{\yquant@pgfqpoint{\yquant@draw@@x+.5\dimenxpr\@firstofthree#4\relax}{\yquant@register@get@y1\relax}}% + \ifdim\yquant@pgf@y>\yquant@pgf@picmaxy % + \global\yquant@pgf@picmaxy=\yquant@pgf@y % \fi% - \ifdim\pgf@y<\pgf@picminy % negative scaling - \global\pgf@picminy=\pgf@y % + \ifdim\yquant@pgf@y<\yquant@pgf@picminy % negative scaling + \global\yquant@pgf@picminy=\yquant@pgf@y % \fi% % last wire, left end - \pgfpointtransformed{\pgfqpoint{\yquant@draw@@x-.5\dimexpr\@firstofthree#4\relax}{\yquant@register@get@y{\csname\yquant@prefix registers\endcsname}\relax}}% - \ifdim\pgf@y>\pgf@picmaxy % - \global\pgf@picmaxy=\pgf@y % + \pgfpointtransformed{\yquant@pgfqpoint{\yquant@draw@@x-.5\dimexpr\@firstofthree#4\relax}{\yquant@register@get@y{\csname\yquant@prefix registers\endcsname}\relax}}% + \ifdim\yquant@pgf@y>\yquant@pgf@picmaxy % + \global\yquant@pgf@picmaxy=\yquant@pgf@y % \fi% - \ifdim\pgf@y<\pgf@picminy % negative scaling - \global\pgf@picminy=\pgf@y % + \ifdim\yquant@pgf@y<\yquant@pgf@picminy % negative scaling + \global\yquant@pgf@picminy=\yquant@pgf@y % \fi% % last wire, right end - \pgfpointtransformed{\pgfqpoint{\yquant@draw@@x+.5\dimenxpr\@firstofthree#4\relax}{\yquant@register@get@y{\csname\yquant@prefix registers\endcsname}\relax}}% - \ifdim\pgf@y>\pgf@picmaxy % - \global\pgf@picmaxy=\pgf@y % + \pgfpointtransformed{\yquant@pgfqpoint{\yquant@draw@@x+.5\dimenxpr\@firstofthree#4\relax}{\yquant@register@get@y{\csname\yquant@prefix registers\endcsname}\relax}}% + \ifdim\yquant@pgf@y>\yquant@pgf@picmaxy % + \global\yquant@pgf@picmaxy=\yquant@pgf@y % \fi% - \ifdim\pgf@y<\pgf@picminy % negative scaling - \global\pgf@picminy=\pgf@y % + \ifdim\yquant@pgf@y<\yquant@pgf@picminy % negative scaling + \global\yquant@pgf@picminy=\yquant@pgf@y % \fi% \fi% % END_FOLD @@ -581,46 +598,57 @@ \fi% }}% \ifpgf@pt@identity% - \dimen0=\dimexpr.5\pgf@picminy+.5\pgf@picmaxy-\pgf@pt@y\relax% - \dimen2=\dimexpr\pgf@picmaxy-\pgf@picminy\relax% + \dimen0=\dimexpr.5\yquant@pgf@picminy+.5\yquant@pgf@picmaxy-\yquant@pgf@pt@y\relax% + \dimen2=\dimexpr\yquant@pgf@picmaxy-\yquant@pgf@picminy\relax% \else% \begingroup% \pgftransforminvert% \pgfpointtransformed{\pgfqpoint{\pgf@picminx}{\pgf@picminy}}% - \@tempdima=\pgf@y% + \@tempdima=\yquant@pgf@y% \pgfpointtransform{\pgfqpoint{\pgf@picmaxx}{\pgf@picmaxy}}% - \edef\cmd{\@tempdima=\the\@tempdima\space\@tempdimb=\the\@tempdimb\space}% + \edef\cmd{\@tempdima=\the\@tempdima\space\@tempdimb=\the\yquant@pgf@y\space}% \expandafter% \endgroup% \cmd% - \pgfpointtransformed{\pgfqpoint{\yquant@draw@@x}% - {.5\dimexpr\@tempdima+\@tempdimb\relax}}% - \dimen0=\pgf@y% - \pgfpointtransformed{\pgfqpoint{\yquant@draw@@x}% - {\dimexpr\@tempdimb-\@tempdima\relax}}% - \dimen2=\pgf@y% + \pgfpointtransformed{\yquant@pgfqpoint{\yquant@draw@@x}% + {.5\dimexpr\@tempdima+\@tempdimb\relax}}% + \dimen0=\yquant@pgf@y% + \pgfpointtransformed{\yquant@pgfqpoint{\yquant@draw@@x}% + {\dimexpr\@tempdimb-\@tempdima\relax}}% + \dimen2=\yquant@pgf@y% \fi% \edef\cmd{% - \noexpand\path (\yquant@draw@@x, \the\dimen0)% + \noexpand\path \yquant@coords(\yquant@draw@@x, \the\dimen0)% node[/yquant/every operator, \yquant@draw@@style,% /yquant/operators/every subcircuit box, /yquant/this operator,% /yquant/operators/this subcircuit box,% /yquant/internal/multi main=true,% name prefix=, name suffix=, name=yquantbox]% - {\vbox to \the\dimen2 {\hbox to \@firstofthree#4 {}}};% + {\ifyquanthorz{\vbox to \the\dimen2 {\hbox to \@firstofthree#4 {}}}% + {\hbox to \the\dimen2 {\vbox to \@firstofthree#4 {}}}};% }% - \cmd% + \ifyquant@config@draw@quality% + \cmd% + \else% + % we draw the box on the behindwires layer. In this way, the box can even be filled without overshadowing the wires. However, this implies that the frame of the box will also be drawn behind the wires. If the color of the frame is different from the color of the wires, this may not be desired. In this case, there's no alternative to the quality layout. + \begingroup% + \let\pgfonlayer@assert@is@active=\relax% + \pgfonlayer{behindwires}% + \cmd% + \endpgfonlayer% + \endgroup% + \fi% \unhbox\yquant@prepare@subcircuit@box% % \endpgfinterruptboundingbox + increase - \ifdim\pgf@interrupt@savemaxy>\pgf@picmaxy% - \global\pgf@picmaxy=\pgf@interrupt@savemaxy% + \ifdim\pgf@interrupt@savemaxy>\yquant@pgf@picmaxy% + \global\yquant@pgf@picmaxy=\pgf@interrupt@savemaxy% \fi% - \ifdim\pgf@interrupt@saveminy<\pgf@picminy% - \global\pgf@picminy=\pgf@interrupt@saveminy% + \ifdim\pgf@interrupt@saveminy<\yquant@pgf@picminy% + \global\yquant@pgf@picminy=\pgf@interrupt@saveminy% \fi% \endgroup% % Now that the subcircuit is finished, we need advance all the wires - \dimdef\newx{\yquant@draw@@x+.5\dimexpr\yquant@draw@@width\relax}% + \dimdef\newx{\yquant@draw@@x\yquant@orientation@plus.5\dimexpr\yquant@draw@@width\relax}% \forlistloop\yquant@draw@group@advance{#5}% % name mangling \ifcase\yquant@config@operator@subcircuit@mangling\relax% @@ -679,18 +707,29 @@ \protected\long\def\yquant@draw@subcircuit@single#1#2#3#4#5{% \yquant@config@operator@multifalse% \yquant@draw@subcircuit@prepare{#2}{#3}{#4}{#5}{#1}% - \edef\cmd{% - \pgfshapeclippath{yquantbox}{% - /yquant/every operator, \yquant@draw@@style,% - /yquant/operators/every subcircuit box, /yquant/this operator,% - /yquant/operators/this subcircuit box,% + \ifyquant@config@draw@quality% + \edef\cmd{% + \pgfshapeclippath{yquantbox}{% + /yquant/every operator, \yquant@draw@@style,% + /yquant/operators/every subcircuit box, /yquant/this operator,% + /yquant/operators/this subcircuit box,% + }% }% - }% - \cmd% - % see comment in draw@subcircuit@multi - \yquant@softpath@extractmaxxat\pgfshapeclippathhorzresult{\yquant@register@get@y{#1}}% - \let\pgfshapeclippathhorzresult=\empty% - \yquant@circuit@extendwire{#1}*% + \cmd% + % see comment in draw@subcircuit@multi + \yquant@softpath@extractmaxxat\pgfshapeclippathhorzresult{\yquant@register@get@y{#1}}% + \let\pgfshapeclippathhorzresult=\empty% + \yquant@circuit@extendwire{#1}*% + \else% + \ifyquanthorz{% + \pgfpointanchor{yquantbox}{east}% + \dimen0=\pgf@x% + }{% + \pgfpointanchor{yquantbox}{south}% + \dimen0=\pgf@y% + }% + \yquant@circuit@extendwire{#1}*% + \fi% \expandafter\yquant@circuit@extendcontrolline\expandafter% {\the\yquant@draw@@currentcontroltype}\yquant@draw@@x% % check for empty name parameter @@ -704,30 +743,48 @@ \yquant@config@operator@multitrue% % there is no contiguous slicing for subcircuits, as they may have all kinds of wire operations that can extend beyond the individual slices, let alone ancillas \yquant@draw@subcircuit@prepare{#5}{#6}{#7}{#8}{#4}% - \edef\cmd{% - \pgfshapeclippath{yquantbox}{% - /yquant/every operator, \yquant@draw@@style,% - /yquant/operators/every subcircuit box, /yquant/this operator,% - /yquant/operators/this subcircuit box,% - /yquant/internal/multi main=true,% + \ifyquant@config@draw@quality% + \edef\cmd{% + \pgfshapeclippath{yquantbox}{% + /yquant/every operator, \yquant@draw@@style,% + /yquant/operators/every subcircuit box, /yquant/this operator,% + /yquant/operators/this subcircuit box,% + /yquant/internal/multi main=true,% + }% }% - }% - \cmd% - % install the clippings - but only on wires that are visually between the first and list while not being part of the circuit. - \let\nonaffectedpgfshapeclippathhorzresult=\pgfshapeclippathhorzresult% - \yquant@for \i := #1 to #2 {% - \xifinlist{\i}{#4}{% - % Usually, we always begin with a wire from the center of the operator shape and clip the inner parts away. This can't be done here, as the wire needs to be drawn _inside_ of the outer box operator here. Instead of clipping against the clip path, we extract its maximum x position at the position of the wire (which is an overkill for simple shapes, but allows to specify even more complicated ones) and place the wire at this position without clipping. - % Note: this works very well for lines joining at perpendicular angles; but if the shape of the box is more fancy, while the position will be calculated correctly, the wire has a rectangular (or rounded, depending on the line cap) shape that is drawn on top of the operator. While \yquant@softpath@extractmaxxat could without much effort determine exactly the segment of the path that corresponds to the rightmost line, we would then have to convert this single line into a closed path that fills the linewidth and clip against it to get proper joiners. Since most likely, no-one will ever need this, we don't do it. But file a feature request if desired. - \yquant@softpath@extractmaxxat\nonaffectedpgfshapeclippathhorzresult% - {\yquant@register@get@y\i}% - \let\pgfshapeclippathhorzresult=\empty% - \yquant@circuit@extendwire\i*% + \cmd% + % install the clippings - but only on wires that are visually between the first and list while not being part of the circuit. + \let\nonaffectedpgfshapeclippathhorzresult=\pgfshapeclippathhorzresult% + \yquant@for \i := #1 to #2 {% + \xifinlist{\i}{#4}{% + % Usually, we always begin with a wire from the center of the operator shape and clip the inner parts away. This can't be done here, as the wire needs to be drawn _inside_ of the outer box operator here. Instead of clipping against the clip path, we extract its maximum x position at the position of the wire (which is an overkill for simple shapes, but allows to specify even more complicated ones) and place the wire at this position without clipping. + % Note: this works very well for lines joining at perpendicular angles; but if the shape of the box is more fancy, while the position will be calculated correctly, the wire has a rectangular (or rounded, depending on the line cap) shape that is drawn on top of the operator. While \yquant@softpath@extractmaxxat could without much effort determine exactly the segment of the path that corresponds to the rightmost line, we would then have to convert this single line into a closed path that fills the linewidth and clip against it to get proper joiners. Since most likely, no-one will ever need this, we don't do it. But file a feature request if desired. + \yquant@softpath@extractmaxxat\nonaffectedpgfshapeclippathhorzresult% + {\yquant@register@get@y\i}% + \let\pgfshapeclippathhorzresult=\empty% + \yquant@circuit@extendwire\i*% + }{% + \let\pgfshapeclippathhorzresult=\nonaffectedpgfshapeclippathhorzresult% + \yquant@circuit@extendwire\i{center}% + }% + }% + \else% + % we don't fill subcircuits, so the nonaffected wires will be drawn through (we deliberatly fill the subcircuit on the behindwires layer, so that the wires within a subcircuit will be visible despite the filling; but we cannot differentiate between "good" internal and "bad" nonaffected wires). If such a constellation arises, better use the quality layout + \ifyquanthorz{% + \pgfpointanchor{yquantbox}{east}% + \dimen0=\pgf@x% }{% - \let\pgfshapeclippathhorzresult=\nonaffectedpgfshapeclippathhorzresult% - \yquant@circuit@extendwire\i{center}% + \pgfpointanchor{yquantbox}{south}% + \dimen0=\pgf@y% }% - }% + \yquant@for \i := #1 to #2 {% + \xifinlist{\i}{#4}{% + \yquant@circuit@extendwire\i*% + }{% + \yquant@circuit@extendwire\i{center}% + }% + }% + \fi% \expandafter\yquant@circuit@extendcontrolline\expandafter% {\the\yquant@draw@@currentcontroltype}\yquant@draw@@x% \ifstrempty{#6}\relax{% @@ -738,13 +795,15 @@ \protected\def\yquant@draw@control#1#2#3{% \edef\cmd{% - \noexpand\path (\yquant@draw@@x, \yquant@register@get@y{#2})% + \noexpand\path \yquant@coords(\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]% {};% - \pgfshapeclippath{yquantbox}% - {/yquant/every control, /yquant/every #1 control,% - /yquant/this control}% + \ifyquant@config@draw@quality% + \pgfshapeclippath{yquantbox}% + {/yquant/every control, /yquant/every #1 control,% + /yquant/this control}% + \fi% }% \cmd% \yquant@circuit@extendwire{#2}{center}% @@ -769,31 +828,50 @@ \numdef\yquant@draw@@idx@ncontrol{\yquant@draw@@idx@ncontrol+1}% } +\protected\long\def\yquant@draw@onwires#1{% + \begingroup% + \let\pgfonlayer@assert@is@active=\relax% + \pgfonlayer{wires}% + #1% + \endpgfonlayer% + \endgroup% +} + \protected\def\yquant@draw@cline{% - \pgfscope% - % install the clipping - \pgfsyssoftpath@setcurrentpath\yquant@circuit@extendcontrolline@clip% - % and invert it. It is sufficient to cover the current bounding box, as the wire will be drawn between existing operators. - \ifyquantdebug% - \pgfsetfillcolor{teal}% - \pgfsetfillopacity{.3}% - \pgfusepathqfill% - \else% - \begingroup% - \pgftransformreset% - \pgfpathrectanglecorners% - {\pgfqpoint{\pgf@picminx}{\pgf@picminy}}% - {\pgfqpoint{\pgf@picmaxx}{\pgf@picmaxy}}% - \pgfseteorule% even-odd to properly invert the clipping - \pgfusepathqclip% - \endgroup% - \fi% - \edef\cmd{% - \noexpand\path[/yquant/every control line]% - \yquant@circuit@extendcontrolline@cmd;% + \ifyquant@config@draw@quality% + \pgfscope% + % install the clipping + \pgfsyssoftpath@setcurrentpath\yquant@circuit@extendcontrolline@clip% + % and invert it. It is sufficient to cover the current bounding box, as the wire will be drawn between existing operators. + \ifyquantdebug% + \pgfsetfillcolor{teal}% + \pgfsetfillopacity{.3}% + \pgfusepathqfill% + \else% + \begingroup% + \pgftransformreset% + \pgfpathrectanglecorners% + {\pgfqpoint{\pgf@picminx}{\pgf@picminy}}% + {\pgfqpoint{\pgf@picmaxx}{\pgf@picmaxy}}% + \pgfseteorule% even-odd to properly invert the clipping + \pgfusepathqclip% + \endgroup% + \fi% + \edef\cmd{% + \noexpand\path[/yquant/every control line]% + \yquant@circuit@extendcontrolline@cmd;% + }% + \cmd% + \endpgfscope% + \else% + \yquant@draw@onwires{% + \edef\cmd{% + \noexpand\path[/yquant/every control line]% + \yquant@circuit@extendcontrolline@cmd;% + }% + \cmd% }% - \cmd% - \endpgfscope% + \fi% } \protected\def\yquant@draw@mline@prep{% @@ -805,27 +883,33 @@ } \protected\def\yquant@draw@mline#1#2{% - \pgfscope% - % install the clipping - \def\pgfsyssoftpath@thepath{#1}% - \pgfsyssoftpath@setcurrentpath\pgfsyssoftpath@thepath% - % and invert it. It is sufficient to cover the current bounding box, as the wire will be drawn between existing operators. - \ifyquantdebug% - \pgfsetfillcolor{teal}% - \pgfsetfillopacity{.3}% - \pgfusepathqfill% - \else% - \begingroup% - \pgftransformreset% - \pgfpathrectanglecorners% - {\pgfqpoint{\pgf@picminx}{\pgf@picminy}}% - {\pgfqpoint{\pgf@picmaxx}{\pgf@picmaxy}}% - \pgfseteorule% even-odd to properly invert the clipping - \pgfusepathqclip% - \endgroup% - \fi% - \path[/yquant/every multi line] #2;% - \endpgfscope% + \ifyquant@config@draw@quality% + \pgfscope% + % install the clipping + \def\pgfsyssoftpath@thepath{#1}% + \pgfsyssoftpath@setcurrentpath\pgfsyssoftpath@thepath% + % and invert it. It is sufficient to cover the current bounding box, as the wire will be drawn between existing operators. + \ifyquantdebug% + \pgfsetfillcolor{teal}% + \pgfsetfillopacity{.3}% + \pgfusepathqfill% + \else% + \begingroup% + \pgftransformreset% + \pgfpathrectanglecorners% + {\pgfqpoint{\pgf@picminx}{\pgf@picminy}}% + {\pgfqpoint{\pgf@picmaxx}{\pgf@picmaxy}}% + \pgfseteorule% even-odd to properly invert the clipping + \pgfusepathqclip% + \endgroup% + \fi% + \path[/yquant/every multi line] #2;% + \endpgfscope% + \else% + \yquant@draw@onwires{% + \path[/yquant/every multi line] #2;% + }% + \fi% } \protected\def\yquant@draw@alias#1{% @@ -846,7 +930,7 @@ \else% \let\wirexpos=\yquant@circuit@endwires@x% \fi% - \ifdim\wirexpos>\wirexprevpos % + \ifdim\yquant@orientation@plus\wirexpos>\yquant@orientation@plus\wirexprevpos % \edef\wirestyle{\noexpand\tikzset{% /yquant/this wire/.style={% /yquant/every wire,% @@ -855,63 +939,71 @@ }, /yquant/this wire% }}% \wirestyle% - % load all clippings - \edef\wireclipping{% - \unexpanded\expandafter\expandafter\expandafter{% - \expandafter\@thirdandfourthoffour\wirelast% + \ifyquant@config@draw@quality% + % load all clippings + \edef\wireclipping{% + \unexpanded\expandafter\expandafter\expandafter{% + \expandafter\@thirdandfourthoffour\wirelast% + }% }% - }% - \pgfscope% - \unless\ifx\wireclipping\empty% may happen if the style is altered to be invisible, though the type is not none - % install the clipping - \pgfsyssoftpath@setcurrentpath\wireclipping% - % invert the clipping - \ifyquantdebug% - \pgfsetfillcolor{orange}% - \pgfsetfillopacity{.3}% - \pgfusepathqfill% - \else% - % We need to access the current bounding box as well as other positions in the local coordinate frame. For this, transform the bounding box to the current frame (though this is expensive). Does this capture rotations correctly? - \begingroup% - \ifdim\pgf@picminx>\pgf@picmaxx% - % nothing drawn yet (or bounding box reset) - \pgf@picminx=0pt % - \pgf@picmaxx=0pt % + \pgfscope% + \unless\ifx\wireclipping\empty% may happen if the style is altered to be invisible, though the type is not none + % install the clipping + \pgfsyssoftpath@setcurrentpath\wireclipping% + % invert the clipping + \ifyquantdebug% + \pgfsetfillcolor{orange}% + \pgfsetfillopacity{.3}% + \pgfusepathqfill% + \else% + % We need to access the current bounding box as well as other positions in the local coordinate frame. For this, transform the bounding box to the current frame (though this is expensive). Does this capture rotations correctly? + \begingroup% + \ifdim\pgf@picminx>\pgf@picmaxx% + % nothing drawn yet (or bounding box reset) + \pgf@picminx=0pt % + \pgf@picmaxx=0pt % + \fi% + \ifdim\pgf@picminy>\pgf@picmaxy% + \pgf@picminy=0pt % + \pgf@picmaxy=0pt % + \fi% + \pgftransforminvert% + \pgfpointtransformed{\pgfqpoint{\pgf@picminx}{\pgf@picminy}}% + \global\@tempdima=\yquant@pgf@y% + \pgfpointtransformed{\pgfqpoint{\pgf@picmaxx}{\pgf@picmaxy}}% + \global\@tempdimb=\yquant@pgf@y% + \endgroup% + % To avoid rendering artifacts at all zoom levels with all renderers, we need to make the clipping region large. Let's try the current bounding box first. + % This may be insufficient if there is no or a tiny wire label and only registers of a small height. In this case, take ten times the line width or at least 1cm, but don't let it affect the bounding box. + \ifdim\dimexpr\@tempdimb-\@tempdima\relax<10\pgflinewidth % + \@tempdima=\dimexpr\wireypos-5\pgflinewidth\relax% + \@tempdimb=\dimexpr\wireypos+5\pgflinewidth\relax% \fi% - \ifdim\pgf@picminy>\pgf@picmaxy% - \pgf@picminy=0pt % - \pgf@picmaxy=0pt % + \ifdim\dimexpr\@tempdimb-\@tempdima\relax<1cm % + \@tempdima=\dimexpr\wireypos-5mm\relax% + \@tempdimb=\dimexpr\wireypos+5mm\relax% \fi% - \pgftransforminvert% - \pgfpointtransformed{\pgfqpoint{\pgf@picminx}{\pgf@picminy}}% - \global\@tempdima=\pgf@y% - \pgfpointtransformed{\pgfqpoint{\pgf@picmaxx}{\pgf@picmaxy}}% - \global\@tempdimb=\pgf@y% - \endgroup% - % To avoid rendering artifacts at all zoom levels with all renderers, we need to make the clipping region large. Let's try the current bounding box first. - % This may be insufficient if there no or a tiny wire label and only registers of a small height. In this case, take ten times the line width or at least 1cm, but don't let it affect the bounding box. - \ifdim\dimexpr\@tempdimb-\@tempdima\relax<10\pgflinewidth % - \@tempdima=\dimexpr\wireypos-5\pgflinewidth\relax% - \@tempdimb=\dimexpr\wireypos+5\pgflinewidth\relax% - \fi% - \ifdim\dimexpr\@tempdimb-\@tempdima\relax<1cm % - \@tempdima=\dimexpr\wireypos-5mm\relax% - \@tempdimb=\dimexpr\wireypos+5mm\relax% + \pgf@relevantforpicturesizefalse% + \pgfpathrectanglecorners% + {\yquant@pgfqpoint{\dimexpr\wirexprevpos\yquant@orientation@minus% + 2\pgflinewidth\relax}% + {\@tempdima}}% + {\yquant@pgfqpoint{\dimexpr\wirexpos\yquant@orientation@plus% + 2\pgflinewidth\relax}% + {\@tempdimb}}% + \pgf@relevantforpicturesizetrue% + \pgfseteorule% even-odd to properly invert the clipping + \pgfusepathqclip% \fi% - \pgf@relevantforpicturesizefalse% - \pgfpathrectanglecorners% - {\pgfqpoint{\dimexpr\wirexprevpos-2\pgflinewidth\relax}% - {\@tempdima}}% - {\pgfqpoint{\dimexpr\wirexpos+2\pgflinewidth\relax}% - {\@tempdimb}}% - \pgf@relevantforpicturesizetrue% - \pgfseteorule% even-odd to properly invert the clipping - \pgfusepathqclip% \fi% - \fi% - % the clip inversion is left to the drawing commands (clip two \pgflinewidth more to avoid renderer artifacts) - \csname yquant@draw@wire@\wiretype\endcsname{#1}% - \endpgfscope% + % the clip inversion is left to the drawing commands (clip two \pgflinewidth more to avoid renderer artifacts) + \csname yquant@draw@wire@\wiretype\endcsname{#1}% + \endpgfscope% + \else% + \yquant@draw@onwires{% + \csname yquant@draw@wire@\wiretype\endcsname{#1}% + }% + \fi% \fi% \fi% \endgroup% @@ -921,7 +1013,7 @@ \protected\csdef{yquant@draw@wire@\yquant@register@type@q}#1{% \edef\cmd{% \noexpand\path [/yquant/this wire]% - (\wirexprevpos,\wireypos) -- (\wirexpos,\wireypos);% + \yquant@coords(\wirexprevpos,\wireypos) -- \yquant@coords(\wirexpos,\wireypos);% }% \cmd% } @@ -930,8 +1022,10 @@ \protected\csdef{yquant@draw@wire@\yquant@register@type@c}#1{% \edef\cmd{% \noexpand\path [/yquant/this wire]% - (\wirexprevpos,\wireypos+2\pgflinewidth)--(\wirexpos,\wireypos+2\pgflinewidth)% - (\wirexprevpos,\wireypos-2\pgflinewidth)--(\wirexpos,\wireypos-2\pgflinewidth);% + \yquant@coords(\wirexprevpos,\wireypos+2\pgflinewidth) -- + \yquant@coords(\wirexpos,\wireypos+2\pgflinewidth)% + \yquant@coords(\wirexprevpos,\wireypos-2\pgflinewidth) -- + \yquant@coords(\wirexpos,\wireypos-2\pgflinewidth);% }% \cmd% } @@ -940,9 +1034,12 @@ \protected\csdef{yquant@draw@wire@\yquant@register@type@qs}#1{% \edef\cmd{% \noexpand\path [/yquant/this wire]% - (\wirexprevpos,\wireypos+2\pgflinewidth)--(\wirexpos,\wireypos+2\pgflinewidth)% - (\wirexprevpos,\wireypos)--(\wirexpos,\wireypos)% - (\wirexprevpos,\wireypos-2\pgflinewidth)--(\wirexpos,\wireypos-2\pgflinewidth);% + \yquant@coords(\wirexprevpos,\wireypos+2\pgflinewidth) -- + \yquant@coords(\wirexpos,\wireypos+2\pgflinewidth)% + \yquant@coords(\wirexprevpos,\wireypos) -- + \yquant@coords(\wirexpos,\wireypos)% + \yquant@coords(\wirexprevpos,\wireypos-2\pgflinewidth) -- + \yquant@coords(\wirexpos,\wireypos-2\pgflinewidth);% }% \cmd% } @@ -950,7 +1047,7 @@ \protected\def\yquant@draw@hspace#1#2{% \begingroup% \yquant@register@get@maxxlist\newx{#1}% - \dimdef\newx{\newx+#2}% + \dimdef\newx{\newx\yquant@orientation@plus#2}% \dimen0=\newx% \let\pgfshapeclippathhorzresult=\empty% \forlistloop\yquant@draw@move@loop{#1}% diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-env.tex b/Master/texmf-dist/tex/latex/yquant/yquant-env.tex index f26919c8d16..bbbf740e713 100644 --- a/Master/texmf-dist/tex/latex/yquant/yquant-env.tex +++ b/Master/texmf-dist/tex/latex/yquant/yquant-env.tex @@ -85,7 +85,7 @@ \expandafter\noexpand\csname\yquant@prefix seamless\endcsname% \expandafter\noexpand\csname\yquant@prefix cleanup\endcsname% }% - \scope[{/yquant/.cd, #2, /tikz/.cd, /yquant/every circuit}]% + \scope[{/yquant/.cd, #2, /tikz/.cd, /yquant/every circuit, /yquant/internal/setup done}]% } \protected\def\yquant@env@end{% @@ -175,7 +175,7 @@ \yquant@env@end@calcypositions@run1% \yquant@env@end@calcypositions@godeepfalse% \yquant@env@end@calcypositions@redo% -% % The macros now set up performed all the proper and unambiguous justification. After that, we will also need to take care of the multi gates. We expect that for most of all multi gates, we already have enough space. But sometimes, this may not be the case, so we need to increase overall spacing and re-evaluate all spacing. In order to get a proper balanced layout, we start with the largest enlargement that is required. Every enlargement step will equally distribute the registers in between. Starting with the largest one, this is likely to also solve issues with smaller ones. + % The macros now set up performed all the proper and unambiguous justification. After that, we will also need to take care of the multi gates. We expect that for most of all multi gates, we already have enough space. But sometimes, this may not be the case, so we need to increase overall spacing and re-evaluate all spacing. In order to get a proper balanced layout, we start with the largest enlargement that is required. Every enlargement step will equally distribute the registers in between. Starting with the largest one, this is likely to also solve issues with smaller ones. \yquant@env@end@calcypositions@multi% % Turn the preliminary positions into true ones at every level. \yquant@env@end@setypositions1% @@ -477,16 +477,17 @@ \ifyquantdebug% \yquant@for \i := 1 to \csname\yquant@prefix registers\endcsname {% \ifcsname\yquant@prefix registermap@\i\endcsname% - \message{^^J y(#1, \i): external}% + \message{^^J \yquant@orientation@y(#1, \i): external}% \else% - \message{^^J y(#1, \i): \csname\yquant@prefix env@endy@\i\endcsname}% - \yquant@register@set@y\i{-\csname\yquant@prefix env@endy@\i\endcsname}% + \message{^^J \yquant@orientation@y(#1, \i): \csname\yquant@prefix env@endy@\i\endcsname}% + % do not use \yquant@orientation@minus: this will lead to an explicit + in vertical mode, and the value of the register y position is directly used for TikZ coordinates. However, those are parsed using \pgfmathsetlength, which will skip pgf's parser if the value starts with an explicit +. We don't want this. + \yquant@register@set@y\i{\ifyquanthorz{-}{}\csname\yquant@prefix env@endy@\i\endcsname}% \fi% }% \else% \yquant@for \i := 1 to \csname\yquant@prefix registers\endcsname {% \unless\ifcsname\yquant@prefix registermap@\i\endcsname% - \yquant@register@set@y\i{-\csname\yquant@prefix env@endy@\i\endcsname}% + \yquant@register@set@y\i{\ifyquanthorz{-}{}\csname\yquant@prefix env@endy@\i\endcsname}% \fi% }% \fi% diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-lang.tex b/Master/texmf-dist/tex/latex/yquant/yquant-lang.tex index cc882a7ffb0..1b462d2d85f 100644 --- a/Master/texmf-dist/tex/latex/yquant/yquant-lang.tex +++ b/Master/texmf-dist/tex/latex/yquant/yquant-lang.tex @@ -65,9 +65,19 @@ overlay/height/.is if=yquant@lang@attr@overlay@height,% overlay/ht/.forward to=/yquant/global attrs/overlay/height,% overlay/h/.forward to=/yquant/global attrs/overlay/height,% + overlay/left/.forward to=/yquant/global attrs/overlay/height,% + overlay/l/.forward to=/yquant/global attrs/overlay/height,% + overlay/before/.forward to=/yquant/global attrs/overlay/height,% + overlay/bef/.forward to=/yquant/global attrs/overlay/height,% + overlay/b/.forward to=/yquant/global attrs/overlay/height,% overlay/depth/.is if=yquant@lang@attr@overlay@depth,% overlay/dp/.forward to=/yquant/global attrs/overlay/depth,% overlay/d/.forward to=/yquant/global attrs/overlay/depth,% + overlay/right/.forward to=/yquant/global attrs/overlay/depth,% + overlay/r/.forward to=/yquant/global attrs/overlay/depth,% + overlay/after/.forward to=/yquant/global attrs/overlay/depth,% + overlay/aft/.forward to=/yquant/global attrs/overlay/depth,% + overlay/a/.forward to=/yquant/global attrs/overlay/depth,% overlay/single/.code={\pgfkeysalso{% /yquant/global attrs/overlay/height={#1},% /yquant/global attrs/overlay/depth={#1}% diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-prepare.tex b/Master/texmf-dist/tex/latex/yquant/yquant-prepare.tex index 9869a61a763..af5960111d3 100644 --- a/Master/texmf-dist/tex/latex/yquant/yquant-prepare.tex +++ b/Master/texmf-dist/tex/latex/yquant/yquant-prepare.tex @@ -84,7 +84,7 @@ \expandafter% \endpgfinterruptboundingbox% \expandafter\dimen\expandafter0\expandafter=% - \the\dimexpr\pgf@picmaxx-\pgf@picminx\relax\relax% + \the\dimexpr\yquant@pgf@picmaxx-\yquant@pgf@picminx\relax\relax% \ifdim\dimen0>\dimen2 % \dimen2=\dimen0 % \fi% @@ -375,8 +375,8 @@ (0pt, 0pt)% node[/yquant/every operator, #2, /yquant/this operator,% name prefix=, name suffix=, name=] {#1};% - \yquant@register@update@height{#3}{\the\pgf@picmaxy}% - \yquant@register@update@depth{#3}{\the\dimexpr-\pgf@picminy\relax}% + \yquant@register@update@height{#3}{\the\yquant@pgf@picmaxy}% + \yquant@register@update@depth{#3}{\the\dimexpr-\yquant@pgf@picminy\relax}% } \protected\def\yquant@prepare@multi#1#2#3{% @@ -397,7 +397,7 @@ \def\yquant@prepare@style{#2}% \let\yquant@register@multi@contiguous=\yquant@prepare@multi@contiguous% \@fifthoffive#3% - \ifdim\pgf@picmaxy=-16000pt % + \ifdim\yquant@pgf@picmaxy=-16000pt % % if there was no single contiguous part before, determine the width now \path% (0pt, 0pt)% @@ -407,8 +407,8 @@ } \protected\def\yquant@prepare@multi@contiguous#1#2#3{% - \global\pgf@picmaxy=-16000pt % - \global\pgf@picminy=16000pt % + \global\yquant@pgf@picmaxy=-16000pt % + \global\yquant@pgf@picminy=16000pt % \edef\cmd{% \noexpand\path (0pt, 0pt)% node[/yquant/every operator, \yquant@prepare@style, /yquant/this operator,% @@ -419,10 +419,10 @@ \cmd% \ifnum#1=#2 % % this is a single register in disguise - \yquant@register@update@height{#1}{\the\pgf@picmaxy}% - \yquant@register@update@depth{#1}{\the\dimexpr-\pgf@picminy\relax}% + \yquant@register@update@height{#1}{\the\yquant@pgf@picmaxy}% + \yquant@register@update@depth{#1}{\the\dimexpr-\yquant@pgf@picminy\relax}% \else% - \yquant@register@update@multispace{#1}{#2}{\the\dimexpr\pgf@picmaxy-\pgf@picminy\relax}% + \yquant@register@update@multispace{#1}{#2}{\the\dimexpr\yquant@pgf@picmaxy-\yquant@pgf@picminy\relax}% \fi% } @@ -454,14 +454,14 @@ \fi% \ifnum\@secondoffive#3=\@thirdoffive#3 % % this is a single register in disguise - \yquant@register@update@height{\first}{\the\pgf@picmaxy}% - \yquant@register@update@depth{\first}{\the\dimexpr-\pgf@picminy\relax}% + \yquant@register@update@height{\first}{\the\yquant@pgf@picmaxy}% + \yquant@register@update@depth{\first}{\the\dimexpr-\yquant@pgf@picminy\relax}% \else% % this may not be sufficient. Since the text position need not necessarily be at the center (if the register corresponding to the visual center is excluded), we may require some space here which we will later only use in parts, but then extend where we should not. However, resolving this would require a special handling when calculating the y positions at the end, meaning we could not use the multispace facility. Let's assume discontiguous init registers are so scarce that this does not matter (disable the acquiration by using the operator/overlay key). \edef\upd{% \yquant@register@update@multispace% {\first}{\@thirdoffive#3}% - {\the\dimexpr\pgf@picmaxy-\pgf@picminy\relax}% + {\the\dimexpr\yquant@pgf@picmaxy-\yquant@pgf@picminy\relax}% }% \upd% \fi% @@ -502,8 +502,8 @@ name prefix=, name suffix=, name=] {\unexpanded{#1}};% }% \cmd% - \yquant@register@update@height{#3}{\the\pgf@picmaxy}% - \yquant@register@update@depth{#3}{\the\dimexpr-\pgf@picminy\relax}% + \yquant@register@update@height{#3}{\the\yquant@pgf@picmaxy}% + \yquant@register@update@depth{#3}{\the\dimexpr-\yquant@pgf@picminy\relax}% } \protected\long\def\yquant@prepare@output@multi#1#2#3{% @@ -545,14 +545,14 @@ \cmd% \ifnum\@secondoffive#3=\@thirdoffive#3 % % this is a single register in disguise - \yquant@register@update@height{\first}{\the\pgf@picmaxy}% - \yquant@register@update@depth{\first}{\the\dimexpr-\pgf@picminy\relax}% + \yquant@register@update@height{\first}{\the\yquant@pgf@picmaxy}% + \yquant@register@update@depth{\first}{\the\dimexpr-\yquant@pgf@picminy\relax}% \else% % this may not be sufficient. Since the text position need not necessarily be at the center (if the register corresponding to the visual center is excluded), we may require some space here which we will later only use in parts, but then extend where we should not. However, resolving this would require a special handling when calculating the y positions at the end, meaning we could not use the multispace facility. Let's assume discontiguous output registers are so scarce that this does not matter (disable the acquiration by using the operator/overlay key). \edef\upd{% \yquant@register@update@multispace% {\first}{\@thirdoffive#3}% - {\the\dimexpr\pgf@picmaxy-\pgf@picminy\relax}% + {\the\dimexpr\yquant@pgf@picmaxy-\yquant@pgf@picminy\relax}% }% \upd% \fi% @@ -566,11 +566,11 @@ \protected\def\yquant@prepare@subcircuit@getmaxx#1{% \begingroup% - \dimen0=-16383.99999pt % + \dimen0=\yquant@orientation@minus16383.99999pt % \def\do##1{% \ifcsname\yquant@prefix xpos@##1\endcsname% \dimen2=\csname\yquant@prefix xpos@##1\endcsname\relax% - \ifdim\dimen0<\dimen2 % + \ifdim\yquant@orientation@plus\dimen0<\yquant@orientation@plus\dimen2 % \dimen0=\dimen2 % \fi% \else% @@ -598,28 +598,40 @@ \yquant@set{#3}% \let\next=\endgroup% \ifyquant@config@operator@position@rightalign% - \ifdim#1>-\pgf@picminx% - \global\pgf@picminx=-\dimexpr#1\relax% - \fi% + \ifyquanthorz{% + \ifdim#1>-\pgf@picminx% + \global\pgf@picminx=-\dimexpr#1\relax% + \fi% + }{% + \ifdim#1>\pgf@picmaxy% + \global\pgf@picmaxy=#1 % + \fi% + }% \else% \ifyquant@env@seamless{% \ifdim\newx=0pt % \dimdef\newx{% - \newx+#1% + \newx\yquant@orientation@plus#1% }% \else% \dimdef\newx{% - \newx+\yquant@config@operator@sep+#1% + \newx\yquant@orientation@plus\yquant@config@operator@sep\yquant@orientation@plus#1% }% \fi% }{% \dimdef\newx{% - \newx+\yquant@config@operator@sep+#1% + \newx\yquant@orientation@plus\yquant@config@operator@sep\yquant@orientation@plus#1% }% }% - \ifdim\newx>\pgf@picmaxx% - \global\pgf@picmaxx=\newx% - \fi% + \ifyquanthorz{% + \ifdim\newx>\pgf@picmaxx% + \global\pgf@picmaxx=\newx% + \fi% + }{% + \ifdim\newx<\pgf@picminy% + \global\pgf@picminy=\newx% + \fi% + }% \ifyquant@config@operator@position@advance% \edef\next{% \endgroup% @@ -647,27 +659,37 @@ \protected\def\yquant@prepare@subcircuit@hspace#1#2{% \yquant@prepare@subcircuit@getmaxx{#1}% - \dimdef\newx{\newx+#2}% + \dimdef\newx{\newx\yquant@orientation@plus#2}% \forlistloop\yquant@prepare@subcircuit@move@loop{#1}% - \ifdim\newx>\pgf@picmaxx % - \global\pgf@picmaxx=\newx % - \fi% + \ifyquanthorz{% + \ifdim\newx>\pgf@picmaxx % + \global\pgf@picmaxx=\newx % + \fi% + }{% + \ifdim\newx<\pgf@picminy% + \global\pgf@picminy=\newx % + \fi% + }% } \protected\def\yquant@prepare@subcircuit@endwires{% \expandafter\ifx\csname\yquant@prefix outputs\endcsname\relax% % to have a symmetric situation, we extend again one separation at the end, unless this is supposed to be seamless and we don't have outputs (for seamless circuits with outputs, extend - since this extension will be between last register and output) \ifyquant@env@seamless\relax{% - \global\advance\pgf@picmaxx by \yquant@config@operator@sep\relax% + \ifyquanthorz{% + \global\advance\pgf@picmaxx by \yquant@config@operator@sep\relax% + }{% + \global\advance\pgf@picminy by -\yquant@config@operator@sep\relax% + }% }% \else% % if we have outputs, those will be realized as additional drawing groups following this macro, so increasing the picture at this point is rather pointless. Instead, we adjust the wire positions appropriately. The additional separation will be inserted by the outputs. \begingroup% - \dimen0=-16383.99999pt % + \dimen0=\yquant@orientation@minus16383.99999pt % \yquant@fordown \i := \csname\yquant@prefix registers\endcsname downto 1 {% \ifcsname\yquant@prefix xpos@\i\endcsname% \dimen2=\csname\yquant@prefix xpos@\i\endcsname\relax% - \ifdim\dimen0<\dimen2 % + \ifdim\yquant@orientation@plus\dimen0<\yquant@orientation@plus\dimen2 % \dimen0=\dimen2 % \fi% \else% @@ -746,27 +768,39 @@ \let\endtikz@scope@env=\yquant@env@substikz@endscope% \let\endscope=\endtikz@scope@env% \let\stopscope=\endscope% - \global\pgf@picmaxx=0pt % - \global\pgf@picminx=0pt % + \global\yquant@pgf@picmaxx=0pt % + \global\yquant@pgf@picminx=0pt % \global\setbox\yquant@prepare@subcircuit@box=\vbox to 1sp{% \csname\yquant@prefix draw\endcsname% }% - \ifdim\pgf@picmaxy=-16000pt % - \global\pgf@picmaxy=0pt % - \global\pgf@picminy=0pt % + \ifdim\yquant@pgf@picmaxy=-16000pt % + \global\yquant@pgf@picmaxy=0pt % + \global\yquant@pgf@picminy=0pt % \fi% \ifyquant@env@seamless{% % for seamless circuits, we do not have an initial separation. However, if there is a label to registers (which you should not do for seamless subcircuits), the "initial" separation is in fact an inner one, so we need it. - \ifdim\pgf@picminx<0pt % - \global\advance\pgf@picmaxx by \yquant@config@operator@sep\relax% - \fi% + \ifyquanthorz{% + \ifdim\pgf@picminx<0pt % + \global\advance\pgf@picmaxx by \yquant@config@operator@sep\relax% + \fi% + }{% + \ifdim\pgf@picmaxy>0pt % + \global\advance\pgf@picminy by -\yquant@config@operator@sep\relax% + \fi% + }% }\relax% - \global\wd\yquant@prepare@subcircuit@box=\dimexpr\pgf@picmaxx-\pgf@picminx\relax% + \ifyquanthorz{% + \global\wd\yquant@prepare@subcircuit@box=\dimexpr\pgf@picmaxx-\pgf@picminx\relax% + }{% + \global\ht\yquant@prepare@subcircuit@box=\pgf@picmaxy% + \global\dp\yquant@prepare@subcircuit@box=-\pgf@picminy% + }% \endgroup% \edef\yquant@prepare@subcircuit@width{% - {\the\wd\yquant@prepare@subcircuit@box}% inner width - {\noexpand\the\dimexpr\pgf@picmaxx-\pgf@picminx\relax}% outer width - {\the\pgf@picminx}% left margin + {\ifyquanthorz{\the\wd\yquant@prepare@subcircuit@box}% inner width + {\the\dimexpr\ht\yquant@prepare@subcircuit@box+\dp\yquant@prepare@subcircuit@box\relax}}% + {\noexpand\the\dimexpr\yquant@pgf@picmaxx-\yquant@pgf@picminx\relax}% outer width + {\ifyquanthorz{\the\pgf@picminx}{-\the\pgf@picmaxy}}% left margin }% \pgfresetboundingbox% \path% @@ -774,12 +808,12 @@ node[/yquant/every operator, #1,% /yquant/operators/every subcircuit box, /yquant/this operator,% /yquant/operators/this subcircuit box,% - name prefix=, name suffix=, name=, y radius=0pt]% + name prefix=, name suffix=, name=, space radius=0pt]% {\box\yquant@prepare@subcircuit@box};% % the extra height is taken care for by manually inserting it to the height of the first and last register in the subcircuit - \yquant@register@inject@extents{\pgf@picmaxy}{-\pgf@picminy}% + \yquant@register@inject@extents{\yquant@pgf@picmaxy}{-\yquant@pgf@picminy}% \edef\cmd{% - \dimen0=\the\dimexpr\pgf@picmaxx-\pgf@picminx\relax\relax% + \dimen0=\the\dimexpr\yquant@pgf@picmaxx-\yquant@pgf@picminx\relax\relax% \yquant@prepare@subcircuit@add% }% \expandafter% diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-registers.tex b/Master/texmf-dist/tex/latex/yquant/yquant-registers.tex index 41a472821f1..07d443c8642 100644 --- a/Master/texmf-dist/tex/latex/yquant/yquant-registers.tex +++ b/Master/texmf-dist/tex/latex/yquant/yquant-registers.tex @@ -882,13 +882,13 @@ \def#9{#4}% }% -% Set #1 to the maximum x value found between #2 and #3 +% Set #1 to the maximum x (vertical: minimum y) value found between #2 and #3 \protected\def\yquant@register@get@maxxrange#1#2#3{% \begingroup% - \dimen0=-16383.99999pt % + \dimen0=\yquant@orientation@minus16383.99999pt % \yquant@for \yquant@register@get@maxx@i := #2 to #3 {% \dimen2=\yquant@register@get@x{\yquant@register@get@maxx@i}\relax% - \ifdim\dimen0<\dimen2 % + \ifdim\yquant@orientation@plus\dimen0<\yquant@orientation@plus\dimen2 % \dimen0=\dimen2 % \fi% }% @@ -897,13 +897,13 @@ \expandafter\def\expandafter#1\expandafter{\the\dimen0}% } -% Set #1 to the maximum x value found in the list #2 +% Set #1 to the maximum x (vertical: minimum y) value found in the list #2 \protected\def\yquant@register@get@maxxlist#1#2{% \begingroup% - \dimen0=-16383.99999pt % + \dimen0=\yquant@orientation@minus16383.99999pt % \def\do##1{% \dimen2=\yquant@register@get@x{##1}\relax% - \ifdim\dimen0<\dimen2 % + \ifdim\yquant@orientation@plus\dimen0<\yquant@orientation@plus\dimen2 % \dimen0=\dimen2 % \fi% }% diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-shapes.tex b/Master/texmf-dist/tex/latex/yquant/yquant-shapes.tex index ea62802b2b5..0ebfca317ba 100644 --- a/Master/texmf-dist/tex/latex/yquant/yquant-shapes.tex +++ b/Master/texmf-dist/tex/latex/yquant/yquant-shapes.tex @@ -22,6 +22,7 @@ {Failed to patch \string\pgfdeclareshape}% {yquant could not provide a necessary extension to pgf.}}% % Every shape additionally provides information about how it should clip the wires. The clipping softpath instructions of shape #1 are stored into \pgfshapeclippath[horz|vert]result. The path is drawn with the tikz options #2 in place. +% sync with yquant@config \protected\def\pgfshapeclippath#1#2{% % Ok, check whether #1 is known! \ifcsname pgf@sh@ns@#1\endcsname% @@ -459,13 +460,14 @@ }% } +% The dmeter shape is aware of the circuit orientation \pgfdeclareshape{yquant-dmeter}{% \saveddimen\xradius{% \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/tikz/x radius}}% \ifdim\wd\pgfnodeparttextbox=0pt % \pgf@xa=0pt % \else% - \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}+.5mm}% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}\ifyquanthorz{+.5mm}{}}% \fi% \ifdim\dimexpr.5\wd\pgfnodeparttextbox+\pgf@xa\relax>\pgf@x% \pgf@x=\dimexpr.5\wd\pgfnodeparttextbox+\pgf@xa\relax% @@ -476,7 +478,7 @@ \ifdim\dimexpr\ht\pgfnodeparttextbox+\dp\pgfnodeparttextbox\relax=0pt % \pgf@xa=0pt % \else% - \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner ysep}}% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner ysep}\ifyquanthorz{}{+.325mm}}% \fi% \@tempdima=\dimexpr.5\ht\pgfnodeparttextbox+.5\dp\pgfnodeparttextbox+\pgf@xa\relax% \ifdim\@tempdima>\pgf@x% @@ -484,9 +486,24 @@ \fi% }% \savedanchor\stext{% - \pgfqpoint% - {-\dimexpr.5\wd\pgfnodeparttextbox+1mm\relax}% - {-\dimexpr.5\ht\pgfnodeparttextbox-.5\dp\pgfnodeparttextbox\relax}% + \ifyquanthorz{% + \pgfqpoint% + {-\dimexpr.5\wd\pgfnodeparttextbox+1mm\relax}% + {-\dimexpr.5\ht\pgfnodeparttextbox-.5\dp\pgfnodeparttextbox\relax}% + }{% + % \pgf@x is still \yradius + \@tempdima=\pgf@x% + \pgfqpoint% + {-\dimexpr.5\wd\pgfnodeparttextbox\relax}% + {-\dimexpr.5\ht\pgfnodeparttextbox-.5\dp\pgfnodeparttextbox-.75mm\relax}% + }% + }% + \savedmacro\ifhorz{% + \ifyquanthorz{% + \def\ifhorz{\noexpand\@firstoftwo}% + }{% + \def\ifhorz{\noexpand\@secondoftwo}% + }% }% \foreach \anc in {center, north, south, south west, west, north west, text} {% \inheritanchor[from=yquant-rectangle]{\anc}% @@ -497,43 +514,112 @@ \anchorborder{% \@tempdima=\pgf@x% \@tempdimb=\pgf@y% - \ifdim\pgf@x>\dimexpr\xradius-3mm\relax% - \pgfpointborderellipse{\pgfqpoint{\dimexpr\@tempdima-\xradius+3mm\relax}% - {\@tempdimb}}% - {\pgfqpoint{3mm}% - {.707107\dimexpr\yradius\relax}}% - \advance\pgf@x by \dimexpr\xradius-3mm\relax% - \else% - \pgfpointborderrectangle{\pgfqpoint{\@tempdima}{\@tempdimb}}% - {\pgfqpoint{\xradius}{\yradius}}% - \fi% + \pgfpointborderrectangle{\pgfqpoint{\@tempdima}{\@tempdimb}}% + {\pgfqpoint{\xradius}{\yradius}}% + % for very distorted shapes, we lose a lot of accuracy in these calculations + \ifhorz{% + \ifdim\pgf@x>\dimexpr\xradius-3mm\relax% + \pgf@xa=\dimexpr\xradius-3mm\relax% shift of the ellipse + \pgf@xb=\dimexpr\@tempdimb*65536/\@tempdima\relax% + \pgf@xb=\dimexpr\pgf@xb*\pgf@xb/65536\relax% slope^2 + \pgf@ya=72.86009pt % xradius^2 of ellipse (72.86009pt = 3mm^2/65536) + \pgf@yb=\yradius\relax% + \pgf@yb=\dimexpr\pgf@yb*\pgf@yb/65536\relax% yradius^2 + % sqrt(slope^2 * (xradius^2 - shift^2) + yradius^2) + \pgfmathsqrt@{\the\dimexpr\pgf@xb*\dimexpr\pgf@ya-\pgf@xa*\pgf@xa/65536\relax/65536+% + \pgf@yb\relax\@gobbletwo}% + % yradius (shift yradius + xradius sqrt(...)) / (slope^2 xradius^2 + yradius^2) + \pgf@x=\dimexpr\dimexpr\yradius\relax*% + \dimexpr\pgf@xa*\dimexpr\yradius\relax/65536+% + 9\dimexpr\pgfmathresult pt\relax% 9 = 3mm/65536 + \relax/% + \dimexpr\pgf@xb*\pgf@ya/65536+\pgf@yb\relax% + \relax% + % y = slope x + \pgf@y=\dimexpr\@tempdimb*\pgf@x/\@tempdima\relax% + \fi% + }{% + \ifdim\pgf@y<\dimexpr-\yradius+3mm\relax% + \pgf@xa=\dimexpr-\yradius+3mm\relax% shift of the ellipse + \pgf@xb=\dimexpr\@tempdima*65536/\@tempdimb\relax% + \pgf@xb=\dimexpr\pgf@xb*\pgf@xb/65536\relax% 1/slope^2 + \pgf@ya=\xradius\relax% xradius + \pgf@ya=\dimexpr\pgf@ya*\pgf@ya/65535\relax% xradius^2 + \pgf@yb=72.86009pt % yradius^2 of ellipse (72.86009pt = 3mm^2/65536) + % sqrt(1/slope^2 * (yradius^2 - shift^2) + xradius^2) + \pgfmathsqrt@{\the\dimexpr\pgf@xb*\dimexpr\pgf@yb-\pgf@xa*\pgf@xa/65536\relax/65536+% + \pgf@ya\relax\@gobbletwo}% + % xradius (shift xradius - yradius sqrt(...)) / (1/slope^2 yradius^2 + xradius^2) + \pgf@y=\dimexpr\dimexpr\xradius\relax*% + \dimexpr\pgf@xa*\dimexpr\xradius\relax/65536-% + 9\dimexpr\pgfmathresult pt\relax% 9 = 3mm/65536 + \relax/% + \dimexpr\pgf@xb*\pgf@yb/65536+\pgf@ya\relax% + \relax% + % x = 1/slope y + \pgf@x=\dimexpr\@tempdima*\pgf@y/\@tempdimb\relax% + \fi% + }% }% \backgroundpath{% - \pgfpathmoveto{\pgfqpoint{-\xradius}{\yradius}}% - \pgfpathlineto{\pgfqpoint{\dimexpr\xradius-3mm\relax}{\yradius}}% - \pgfpatharc{90}{-90}{3mm and \yradius}% - \pgfpathlineto{\pgfqpoint{-\xradius}{-\yradius}}% + \ifhorz{% + \pgfpathmoveto{\pgfqpoint{-\xradius}{\yradius}}% + \pgfpathlineto{\pgfqpoint{\dimexpr\xradius-3mm\relax}{\yradius}}% + \pgfpatharc{90}{-90}{3mm and \yradius}% + \pgfpathlineto{\pgfqpoint{-\xradius}{-\yradius}}% + }{% + \pgfpathmoveto{\pgfqpoint{\xradius}{\yradius}}% + \pgfpathlineto{\pgfqpoint{\xradius}{\dimexpr-\yradius+3mm\relax}}% + \pgfpatharc{0}{-180}{\xradius and 3mm}% + \pgfpathlineto{\pgfqpoint{-\xradius}{\yradius}}% + }% \pgfpathclose% }% \clippath{% - \pgfpathmoveto{\pgfqpoint{-\dimexpr\xradius+.5\pgflinewidth\relax}% - {\dimexpr\yradius+.5\pgflinewidth\relax}}% - \pgfpathlineto{\pgfqpoint{\dimexpr\xradius-3mm\relax}% - {\dimexpr\yradius+.5\pgflinewidth\relax}}% - \pgfpatharc{90}{-90}{3mm+.5\pgflinewidth and \yradius+.5\pgflinewidth}% - \pgfpathlineto{\pgfqpoint{-\dimexpr\xradius+.5\pgflinewidth\relax}% - {-\dimexpr\yradius+.5\pgflinewidth\relax}}% + \ifhorz{% + \pgfpathmoveto{\pgfqpoint{-\dimexpr\xradius+.5\pgflinewidth\relax}% + {\dimexpr\yradius+.5\pgflinewidth\relax}}% + \pgfpathlineto{\pgfqpoint{\dimexpr\xradius-3mm\relax}% + {\dimexpr\yradius+.5\pgflinewidth\relax}}% + \pgfpatharc{90}{-90}{3mm+.5\pgflinewidth and \yradius+.5\pgflinewidth}% + \pgfpathlineto{\pgfqpoint{-\dimexpr\xradius+.5\pgflinewidth\relax}% + {-\dimexpr\yradius+.5\pgflinewidth\relax}}% + }{% + \pgfpathmoveto{\pgfqpoint{\dimexpr\xradius+.5\pgflinewidth\relax}% + {\dimexpr\yradius+.5\pgflinewidth\relax}}% + \pgfpathlineto{\pgfqpoint{\dimexpr\xradius+.5\pgflinewidth\relax}% + {\dimexpr-\yradius+3mm\relax}}% + \pgfpatharc{0}{-180}{\xradius+.5\pgflinewidth and 3mm+.5\pgflinewidth}% + \pgfpathlineto{\pgfqpoint{-\dimexpr\xradius+.5\pgflinewidth\relax}% + {\dimexpr\yradius+.5\pgflinewidth}}% + }% \pgfpathclose% }% } +% The line shape is aware of the circuit orientation (it always extends in space dimension with constant time) \pgfdeclareshape{yquant-line}{% \saveddimen\xradius{% % we only need this for the border anchor; the value is automatically correct in the paths. - \pgf@x=.5\pgflinewidth% + \ifyquanthorz{% + \pgf@x=.5\pgflinewidth% + }{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/tikz/x radius}+.5*\yquant@config@register@sep}% + }% }% \saveddimen\yradius{% - \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/tikz/y radius}+.5*\yquant@config@register@sep}% + \ifyquanthorz{% + \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/tikz/y radius}+.5*\yquant@config@register@sep}% + }{% + \pgf@x=.5\pgflinewidth% + }% + }% + \savedmacro\ifhorz{% + \ifyquanthorz{% + \def\ifhorz{\noexpand\@firstoftwo}% + }{% + \def\ifhorz{\noexpand\@secondoftwo}% + }% }% \foreach \anc in {center, north, north east, east, south east, south, south west, west, north west} {% \inheritanchor[from=yquant-rectangle]{\anc}% @@ -541,19 +627,36 @@ \inheritanchorborder[from=yquant-rectangle]% \backgroundpath{% % manually shorten for the bounding box - \pgf@xa=\dimexpr\yradius-\pgf@shorten@end@additional\relax% - \pgf@ya=\dimexpr\yradius-\pgf@shorten@start@additional\relax% - \pgf@shorten@end@additional=0pt % - \pgf@shorten@start@additional=0pt % - \pgfpathmoveto{\pgfqpoint{0pt}{\pgf@xa}}% - \pgfpathlineto{\pgfqpoint{0pt}{-\pgf@ya}}% + \ifhorz{% + \pgf@xa=\dimexpr\yradius-\pgf@shorten@end@additional\relax% + \pgf@ya=\dimexpr\yradius-\pgf@shorten@start@additional\relax% + \pgf@shorten@end@additional=0pt % + \pgf@shorten@start@additional=0pt % + \pgfpathmoveto{\pgfqpoint{0pt}{\pgf@xa}}% + \pgfpathlineto{\pgfqpoint{0pt}{-\pgf@ya}}% + }{% + \pgf@xa=\dimexpr\xradius-\pgf@shorten@end@additional\relax% + \pgf@ya=\dimexpr\xradius-\pgf@shorten@start@additional\relax% + \pgf@shorten@end@additional=0pt % + \pgf@shorten@start@additional=0pt % + \pgfpathmoveto{\pgfqpoint{\pgf@xa}{0pt}}% + \pgfpathlineto{\pgfqpoint{-\pgf@ya}{0pt}}% + }% }% \clippath{% - \@tempdima=\dimexpr\yradius-\pgf@shorten@end@additional\relax% - \@tempdimb=\dimexpr\yradius-\pgf@shorten@start@additional\relax% - \pgfpathrectanglecorners% - {\pgfqpoint{-.5\pgflinewidth}{\@tempdima}}% - {\pgfqpoint{.5\pgflinewidth}{-\@tempdimb}}% + \ifhorz{% + \@tempdima=\dimexpr\yradius-\pgf@shorten@end@additional\relax% + \@tempdimb=\dimexpr\yradius-\pgf@shorten@start@additional\relax% + \pgfpathrectanglecorners% + {\pgfqpoint{-.5\pgflinewidth}{\@tempdima}}% + {\pgfqpoint{.5\pgflinewidth}{-\@tempdimb}}% + }{% + \@tempdima=\dimexpr\xradius-\pgf@shorten@end@additional\relax% + \@tempdimb=\dimexpr\xradius-\pgf@shorten@start@additional\relax% + \pgfpathrectanglecorners% + {\pgfqpoint{\@tempdima}{-.5\pgflinewidth}}% + {\pgfqpoint{-\@tempdimb}{.5\pgflinewidth}}% + }% }% } @@ -708,77 +811,145 @@ } % END_FOLD +% The init and output shapes are tightly connected to quantum circuits, so they will depend on the current circuit orientation! \pgfdeclareshape{yquant-init}{% \saveddimen\xradius{% \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/tikz/x radius}}% - % inner xsep is between the brace tip and the right end of the text. Check if the decoration is raised (will define \def\tikz@dec@shift{\pgftransformyshift{#1}}) - \iftikz@decoratepath% - \ifx\tikz@dec@shift\relax% - \pgf@xa=\pgfdecorationsegmentamplitude % + \ifyquanthorz{% + % inner xsep is between the brace tip and the right end of the text. Check if the decoration is raised (will define \def\tikz@dec@shift{\pgftransformyshift{#1}}) + \iftikz@decoratepath% + \ifx\tikz@dec@shift\relax% + \pgf@xa=\pgfdecorationsegmentamplitude % + \else% + \pgfmathsetlength\pgf@xa{\expandafter\@secondoftwo\tikz@dec@shift+\pgfdecorationsegmentamplitude}% + \fi% + \pgfmathaddtolength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% \else% - \pgfmathsetlength\pgf@xa{\expandafter\@secondoftwo\tikz@dec@shift+\pgfdecorationsegmentamplitude}% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% \fi% - \pgfmathaddtolength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% - \else% - \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% - \fi% - % outer xsep is (a lower bound) from the left end of the border to the left end of the text - \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/outer xsep}}% - \@tempdima=.5\dimexpr\wd\pgfnodeparttextbox+\pgf@xa+\pgf@xb\relax% - \ifdim\@tempdima>\pgf@x% - \pgf@x=\@tempdima% - \fi% + % outer xsep is (a lower bound) from the left end of the border to the left end of the text + \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/outer xsep}}% + \@tempdima=.5\dimexpr\wd\pgfnodeparttextbox+\pgf@xa+\pgf@xb\relax% + \ifdim\@tempdima>\pgf@x% + \pgf@x=\@tempdima% + \fi% + }{% + \ifdim.5\wd\pgfnodeparttextbox>\pgf@x% + \pgf@x=.5\wd\pgfnodeparttextbox% + \fi% + \iftikz@decoratepath% + \ifdim2\pgfdecorationsegmentamplitude>\pgf@x% + \pgf@x=2\pgfdecorationsegmentamplitude% + \fi% + \fi% + }% + \global\pgf@y=\pgf@x% }% \saveddimen\yradius{% \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/tikz/y radius}}% - \@tempdima=.5\dimexpr\ht\pgfnodeparttextbox+\dp\pgfnodeparttextbox\relax% - \ifdim\@tempdima>\pgf@x% - \pgf@x=\@tempdima% - \fi% - \iftikz@decoratepath% - \ifdim2\pgfdecorationsegmentamplitude>\pgf@x% - \pgf@x=2\pgfdecorationsegmentamplitude% + \ifyquanthorz{% + \@tempdima=.5\dimexpr\ht\pgfnodeparttextbox+\dp\pgfnodeparttextbox\relax% + \ifdim\@tempdima>\pgf@x% + \pgf@x=\@tempdima% \fi% - \fi% + \iftikz@decoratepath% + \ifdim2\pgfdecorationsegmentamplitude>\pgf@x% + \pgf@x=2\pgfdecorationsegmentamplitude% + \fi% + \fi% + }{% + % inner ysep is between the brace tip and the bottom end of the text. Check if the decoration is raised (will define \def\tikz@dec@shift{\pgftransformyshift{#1}}) + \iftikz@decoratepath% + \ifx\tikz@dec@shift\relax% + \pgf@xa=\pgfdecorationsegmentamplitude % + \else% + \pgfmathsetlength\pgf@xa{\expandafter\@secondoftwo\tikz@dec@shift+\pgfdecorationsegmentamplitude}% + \fi% + \pgfmathaddtolength\pgf@xa{\pgfkeysvalueof{/pgf/inner ysep}}% + \else% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner ysep}}% + \fi% + % outer ysep is (a lower bound) from the top end of the border to the top end of the text + \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/outer ysep}}% + \@tempdima=.5\dimexpr\ht\pgfnodeparttextbox+\dp\pgfnodeparttextbox+\pgf@xa+\pgf@xb\relax% + \ifdim\@tempdima>\pgf@x% + \pgf@x=\@tempdima% + \fi% + }% }% \savedanchor\stext{% - \iftikz@decoratepath% - % \pgf@x is still \yradius... - % first set \pgfdecoratedremainingdistance appropriately - \pgfdecoratedremainingdistance=2\pgf@x% - % now perform the transformation - \yquant@gappedbrace@calcshift% - \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}+\pgfdecorationsegmentamplitude}% - \unless\ifx\tikz@dec@shift\relax% - \pgfmathaddtolength\pgf@xa{\expandafter\@secondoftwo\tikz@dec@shift}% + % \pgf@x is still \yradius, \pgf@y is still \xradius + \@tempdima=\pgf@y% + \@tempdimb=\pgf@x% + \ifyquanthorz{% + \iftikz@decoratepath% + % first set \pgfdecoratedremainingdistance appropriately + \pgfdecoratedremainingdistance=2\@tempdimb% + % now perform the transformation + \yquant@gappedbrace@calcshift% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}+\pgfdecorationsegmentamplitude}% + \unless\ifx\tikz@dec@shift\relax% + \pgfmathaddtolength\pgf@xa{\expandafter\@secondoftwo\tikz@dec@shift}% + \fi% + \pgfqpoint% + {\dimexpr\@tempdima-\wd\pgfnodeparttextbox-\pgf@xa\relax}% + {\dimexpr\@tempdimb% = \yradius + -\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance% - aspect + -.5\ht\pgfnodeparttextbox+.5\dp\pgfnodeparttextbox% center there + \relax}% + \else% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% + \pgfqpoint% + {\dimexpr\@tempdima-\wd\pgfnodeparttextbox-\pgf@xa\relax}% + {-.5\dimexpr\ht\pgfnodeparttextbox-\dp\pgfnodeparttextbox\relax}% \fi% - \pgfqpoint% - {-\dimexpr\wd\pgfnodeparttextbox+\pgf@xa\relax}% - {\dimexpr.5\pgfdecoratedremainingdistance% = \yradius - -\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance% - aspect - -.5\ht\pgfnodeparttextbox+.5\dp\pgfnodeparttextbox% center there - \relax}% - \else% - \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% - \pgfqpoint% - {-\dimexpr\wd\pgfnodeparttextbox+\pgf@xa\relax}% - {-.5\dimexpr\ht\pgfnodeparttextbox-\dp\pgfnodeparttextbox\relax}% - \fi% + }{% + \iftikz@decoratepath% + % first set \pgfdecoratedremainingdistance appropriately + \pgfdecoratedremainingdistance=2\@tempdima% + % now perform the transformation + \yquant@gappedbrace@calcshift% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner ysep}+\pgfdecorationsegmentamplitude}% + \unless\ifx\tikz@dec@shift\relax% + \pgfmathaddtolength\pgf@xa{\expandafter\@secondoftwo\tikz@dec@shift}% + \fi% + \pgfqpoint% + {\dimexpr-\@tempdima+% + \pgfdecorationsegmentaspect\pgfdecoratedremainingdistance% - aspect + -.5\wd\pgfnodeparttextbox% center there + \relax}% + {\dimexpr-\@tempdimb+\dp\pgfnodeparttextbox+\pgf@xa\relax}% + \else% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner ysep}}% + \pgfqpoint% + {-.5\wd\pgfnodeparttextbox}% + {\dimexpr-\@tempdimb+\dp\pgfnodeparttextbox+\pgf@xa\relax}% + \fi% + }% + }% + \savedmacro\ifhorz{% + \ifyquanthorz{% + \def\ifhorz{\noexpand\@firstoftwo}% + }{% + \def\ifhorz{\noexpand\@secondoftwo}% + }% }% % BEGIN_FOLD Operator anchors \foreach \anc in {center, north, north east, east, south east, south, south west, west, north west} {% \inheritanchor[from=yquant-rectangle]{\anc}% }% - \anchor{text}{% - \stext% - \advance \pgf@x by \xradius\relax% - }% + \anchor{text}{\stext}% \inheritanchorborder[from=yquant-rectangle]% % END_FOLD % BEGIN_FOLD Path \backgroundpath{% - \pgfpathmoveto{\pgfqpoint{\xradius}{\yradius}}% - \pgfpathlineto{\pgfqpoint{\xradius}{-\yradius}}% + \ifhorz{% + \pgfpathmoveto{\pgfqpoint{\xradius}{\yradius}}% + \pgfpathlineto{\pgfqpoint{\xradius}{-\yradius}}% + }{% + \pgfpathmoveto{\pgfqpoint{-\xradius}{-\yradius}}% + \pgfpathlineto{\pgfqpoint{\xradius}{-\yradius}}% + }% \pgfpointtransformed{\pgfqpoint{-\xradius}{\yradius}}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgfpointtransformed{\pgfqpoint{-\xradius}{-\yradius}}% for rotations @@ -788,8 +959,8 @@ \pgfpathrectanglecorners% {\pgfqpoint{-\dimexpr\xradius\relax}% {\dimexpr\yradius\relax}}% - {\pgfqpoint{\dimexpr\xradius+.5\pgflinewidth\relax}% - {-\dimexpr\yradius\relax}}% + {\pgfqpoint{\dimexpr\xradius\ifhorz{+.5\pgflinewidth}{}\relax}% + {-\dimexpr\yradius\ifhorz{}{+.5\pgflinewidth}\relax}}% }% % END_FOLD } @@ -798,74 +969,141 @@ % Almost the same as in yquant-input, only a minimal change in \stext's x position \saveddimen\xradius{% \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/tikz/x radius}}% - % inner xsep is from the brace tip and the left end of the text. Check if the decoration is raised (will define \def\tikz@dec@shift{\pgftransformyshift{#1}}) - \iftikz@decoratepath% - \ifx\tikz@dec@shift\relax% - \pgf@xa=\pgfdecorationsegmentamplitude % + \ifyquanthorz{% + % inner xsep is between the brace tip and the left end of the text. Check if the decoration is raised (will define \def\tikz@dec@shift{\pgftransformyshift{#1}}) + \iftikz@decoratepath% + \ifx\tikz@dec@shift\relax% + \pgf@xa=\pgfdecorationsegmentamplitude % + \else% + \pgfmathsetlength\pgf@xa{\expandafter\@secondoftwo\tikz@dec@shift+\pgfdecorationsegmentamplitude}% + \fi% + \pgfmathaddtolength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% \else% - \pgfmathsetlength\pgf@xa{\expandafter\@secondoftwo\tikz@dec@shift+\pgfdecorationsegmentamplitude}% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% \fi% - \pgfmathaddtolength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% - \else% - \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% - \fi% - % outer xsep is (a lower bound) from the left end of the border to the left end of the text - \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/outer xsep}}% - \@tempdima=.5\dimexpr\wd\pgfnodeparttextbox+\pgf@xa+\pgf@xb\relax% - \ifdim\@tempdima>\pgf@x% - \pgf@x=\@tempdima% - \fi% + % outer xsep is (a lower bound) from the right end of the border to the right end of the text + \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/outer xsep}}% + \@tempdima=.5\dimexpr\wd\pgfnodeparttextbox+\pgf@xa+\pgf@xb\relax% + \ifdim\@tempdima>\pgf@x% + \pgf@x=\@tempdima% + \fi% + }{% + \ifdim.5\wd\pgfnodeparttextbox>\pgf@x% + \pgf@x=.5\wd\pgfnodeparttextbox% + \fi% + \iftikz@decoratepath% + \ifdim2\pgfdecorationsegmentamplitude>\pgf@x% + \pgf@x=2\pgfdecorationsegmentamplitude% + \fi% + \fi% + }% + \global\pgf@y=\pgf@x% }% \saveddimen\yradius{% \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/tikz/y radius}}% - \@tempdima=.5\dimexpr\ht\pgfnodeparttextbox+\dp\pgfnodeparttextbox\relax% - \ifdim\@tempdima>\pgf@x% - \pgf@x=\@tempdima% - \fi% - \iftikz@decoratepath% - \ifdim2\pgfdecorationsegmentamplitude>\pgf@x% - \pgf@x=2\pgfdecorationsegmentamplitude% + \ifyquanthorz{% + \@tempdima=.5\dimexpr\ht\pgfnodeparttextbox+\dp\pgfnodeparttextbox\relax% + \ifdim\@tempdima>\pgf@x% + \pgf@x=\@tempdima% \fi% - \fi% + \iftikz@decoratepath% + \ifdim2\pgfdecorationsegmentamplitude>\pgf@x% + \pgf@x=2\pgfdecorationsegmentamplitude% + \fi% + \fi% + }{% + % inner ysep is between the brace tip and the top end of the text. Check if the decoration is raised (will define \def\tikz@dec@shift{\pgftransformyshift{#1}}) + \iftikz@decoratepath% + \ifx\tikz@dec@shift\relax% + \pgf@xa=\pgfdecorationsegmentamplitude % + \else% + \pgfmathsetlength\pgf@xa{\expandafter\@secondoftwo\tikz@dec@shift+\pgfdecorationsegmentamplitude}% + \fi% + \pgfmathaddtolength\pgf@xa{\pgfkeysvalueof{/pgf/inner ysep}}% + \else% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner ysep}}% + \fi% + % outer ysep is (a lower bound) from the bottom end of the border to the bottom end of the text + \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/outer ysep}}% + \@tempdima=.5\dimexpr\ht\pgfnodeparttextbox+\dp\pgfnodeparttextbox+\pgf@xa+\pgf@xb\relax% + \ifdim\@tempdima>\pgf@x% + \pgf@x=\@tempdima% + \fi% + }% }% \savedanchor\stext{% - \iftikz@decoratepath% - % \pgf@x is still \yradius... - % first set \pgfdecoratedremainingdistance appropriately - \pgfdecoratedremainingdistance=2\pgf@x% - % now perform the transformation - \yquant@gappedbrace@calcshift% - \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}+\pgfdecorationsegmentamplitude}% - \unless\ifx\tikz@dec@shift\relax% - \pgfmathaddtolength\pgf@xa{\expandafter\@secondoftwo\tikz@dec@shift}% + % \pgf@x is still \yradius, \pgf@y is still \xradius + \@tempdima=\pgf@y% + \@tempdimb=\pgf@x% + \ifyquanthorz{% + \iftikz@decoratepath% + % first set \pgfdecoratedremainingdistance appropriately + \pgfdecoratedremainingdistance=2\@tempdimb% + % now perform the transformation + \yquant@gappedbrace@calcshift% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}+\pgfdecorationsegmentamplitude}% + \unless\ifx\tikz@dec@shift\relax% + \pgfmathaddtolength\pgf@xa{\expandafter\@secondoftwo\tikz@dec@shift}% + \fi% + \pgfqpoint% + {\dimexpr-\@tempdima+\pgf@xa\relax}% + {\dimexpr\@tempdimb% = \yradius + -\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance% - aspect + -.5\ht\pgfnodeparttextbox+.5\dp\pgfnodeparttextbox% center there + \relax}% + \else% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% + \pgfqpoint% + {\dimexpr-\@tempdima+\pgf@xa\relax}% + {-.5\dimexpr\ht\pgfnodeparttextbox-\dp\pgfnodeparttextbox\relax}% \fi% - \pgfqpoint% - {\dimexpr\pgf@xa\relax}% - {\dimexpr.5\pgfdecoratedremainingdistance% = \yradius - -\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance% - aspect - -.5\ht\pgfnodeparttextbox+.5\dp\pgfnodeparttextbox% center there - \relax}% - \else% - \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}% - \pgfqpoint% - {\dimexpr\pgf@xa\relax}% - {-.5\dimexpr\ht\pgfnodeparttextbox-\dp\pgfnodeparttextbox\relax}% - \fi% + }{% + \iftikz@decoratepath% + % first set \pgfdecoratedremainingdistance appropriately + \pgfdecoratedremainingdistance=2\@tempdima% + % now perform the transformation + \yquant@gappedbrace@calcshift% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner ysep}+\pgfdecorationsegmentamplitude}% + \unless\ifx\tikz@dec@shift\relax% + \pgfmathaddtolength\pgf@xa{\expandafter\@secondoftwo\tikz@dec@shift}% + \fi% + \pgfqpoint% + {\dimexpr-\@tempdima% = \xradius + +\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance% - aspect + -.5\wd\pgfnodeparttextbox% center there + \relax}% + {\dimexpr\@tempdimb-\ht\pgfnodeparttextbox-\pgf@xa\relax}% + \else% + \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner ysep}}% + \pgfqpoint% + {-.5\wd\pgfnodeparttextbox}% + {\dimexpr\@tempdimb-\ht\pgfnodeparttextbox-\pgf@xa\relax}% + \fi% + }% + }% + \savedmacro\ifhorz{% + \ifyquanthorz{% + \def\ifhorz{\noexpand\@firstoftwo}% + }{% + \def\ifhorz{\noexpand\@secondoftwo}% + }% }% % BEGIN_FOLD Operator anchors \foreach \anc in {center, north, north east, east, south east, south, south west, west, north west} {% \inheritanchor[from=yquant-init]{\anc}% }% - \anchor{text}{% - \stext% - \advance \pgf@x by -\xradius\relax% - }% + \anchor{text}{\stext}% \inheritanchorborder[from=yquant-init]% % END_FOLD % BEGIN_FOLD Path \backgroundpath{% - \pgfpathmoveto{\pgfqpoint{-\xradius}{\yradius}}% - \pgfpathlineto{\pgfqpoint{-\xradius}{-\yradius}}% + \ifhorz{% + \pgfpathmoveto{\pgfqpoint{-\xradius}{\yradius}}% + \pgfpathlineto{\pgfqpoint{-\xradius}{-\yradius}}% + }{% + \pgfpathmoveto{\pgfqpoint{-\xradius}{\yradius}}% + \pgfpathlineto{\pgfqpoint{\xradius}{\yradius}}% + }% \pgfpointtransformed{\pgfqpoint{\xradius}{\yradius}}% \pgf@protocolsizes{\pgf@x}{\pgf@y}% \pgfpointtransformed{\pgfqpoint{\xradius}{-\yradius}}% for rotations @@ -873,8 +1111,8 @@ }% \clippath{% \pgfpathrectanglecorners% - {\pgfqpoint{-\dimexpr\xradius+.5\pgflinewidth\relax}% - {\dimexpr\yradius\relax}}% + {\pgfqpoint{-\dimexpr\xradius\ifhorz{+.5\pgflinewidth}{}\relax}% + {\dimexpr\yradius\ifhorz{}{+.5\pgflinewidth}\relax}}% {\pgfqpoint{\dimexpr\xradius\relax}% {-\dimexpr\yradius\relax}}% }% diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-tools.tex b/Master/texmf-dist/tex/latex/yquant/yquant-tools.tex index f30dc308bc0..fbfd3c1814e 100644 --- a/Master/texmf-dist/tex/latex/yquant/yquant-tools.tex +++ b/Master/texmf-dist/tex/latex/yquant/yquant-tools.tex @@ -455,9 +455,10 @@ } % #1 is a pgf soft path. We extract the maximum x position at the y position specified in #2 and assign it to \dimen0, which is translated to the user coordinate system. +% If the circuit is currently vertical, we extract the minimum y position at the x position specified in #2. \protected\def\yquant@softpath@extractmaxxat#1#2{% \begingroup% - \dimen0=-16000pt % + \dimen0=\yquant@orientation@minus16000pt % \dimen2=#2 % \pgftransforminvert% \let\pgfsyssoftpath@movetotoken=\yquant@softpath@extractmaxxat@moveto% @@ -473,44 +474,45 @@ } \protected\def\yquant@softpath@extractmaxxat@update#1{% - \ifdim\dimen0<#1 % + \ifdim\yquant@orientation@plus\dimen0<\yquant@orientation@plus#1 % \dimen0=#1 % \fi% } \protected\def\yquant@softpath@extractmaxxat@moveto#1#2{% \pgfpointtransformed{\pgfqpoint{#1}{#2}}% - \dimen4=\pgf@x % - \dimen6=\pgf@y % + \dimen4=\yquant@pgf@x % + \dimen6=\yquant@pgf@y % } \protected\def\yquant@softpath@extractmaxxat@lineto#1#2{% \pgfpointtransformed{\pgfqpoint{#1}{#2}}% - \ifyquant@OR{\ifdim\dimen4>\dimen0 }{\ifdim\pgf@x>\dimen0 }{% + \ifyquant@OR{\ifdim\yquant@orientation@plus\dimen4>\yquant@orientation@plus\dimen0 }% + {\ifdim\yquant@orientation@plus\yquant@pgf@x>\yquant@orientation@plus\dimen0 }{% \ifdim\dimen6=\dimen2 % \yquant@softpath@extractmaxxat@update{\dimen4}% \else% \ifdim\dimen6<\dimen2 % - \unless\ifdim\pgf@y<\dimen2 % + \unless\ifdim\yquant@pgf@y<\dimen2 % \expandafter\yquant@softpath@extractmaxxat@update\expandafter{\the\dimexpr% \dimen4+% x0 - \dimexpr\pgf@x-\dimen4\relax*% (x1-x0) - \dimexpr\dimen2-\dimen6\relax/\dimexpr\pgf@y-\dimen6\relax% (y-y0)/(y1-y0) + \dimexpr\yquant@pgf@x-\dimen4\relax*% (x1-x0) + \dimexpr\dimen2-\dimen6\relax/\dimexpr\yquant@pgf@y-\dimen6\relax% (y-y0)/(y1-y0) \relax}% \fi% \else% - \unless\ifdim\pgf@y>\dimen2 % + \unless\ifdim\yquant@pgf@y>\dimen2 % \expandafter\yquant@softpath@extractmaxxat@update\expandafter{\the\dimexpr% \dimen4+% x0 - \dimexpr\pgf@x-\dimen4\relax*% (x1-x0) - \dimexpr\dimen2-\dimen6\relax/\dimexpr\pgf@y-\dimen6\relax% (y-y0)/(y1-y0) + \dimexpr\yquant@pgf@x-\dimen4\relax*% (x1-x0) + \dimexpr\dimen2-\dimen6\relax/\dimexpr\yquant@pgf@y-\dimen6\relax% (y-y0)/(y1-y0) \relax}% \fi% \fi% \fi% }\relax% - \dimen4=\pgf@x% - \dimen6=\pgf@y% + \dimen4=\yquant@pgf@x% + \dimen6=\yquant@pgf@y% } \protected\def\yquant@softpath@extractmaxxat@curveto@checkx{% @@ -520,12 +522,12 @@ % it is. \dimen4: x0, \pgf@xa: xa, \pgf@xb: xb, \pgf@xc: x1 \begingroup% \dimen12=\dimexpr1pt-\dimen11\relax% 1 - t - \dimen13=\dimexpr\dimen11*\dimen11/65535\relax% t^2 - \dimen14=\dimexpr\dimen12*\dimen12/65535\relax% (1 - t)^2 - \dimen255=\dimexpr\dimen13*\dimen11/65535*\pgf@xc/65535+% t^3 x1 - 3\dimen13*\dimen12/65535*\pgf@xb/65535+% t^2(1 - t) xb - \dimen14*\dimen12/65535*\dimen4/65535+% (1 - t)^3 x0 - 3\dimen11*\dimen14/65535*\pgf@xa/65535% 3t(1 - t)^2 xa + \dimen13=\dimexpr\dimen11*\dimen11/65536\relax% t^2 + \dimen14=\dimexpr\dimen12*\dimen12/65536\relax% (1 - t)^2 + \dimen255=\dimexpr\dimen13*\dimen11/65536*\pgf@xc/65536+% t^3 x1 + 3\dimen13*\dimen12/65536*\pgf@xb/65536+% t^2(1 - t) xb + \dimen14*\dimen12/65536*\dimen4/65536+% (1 - t)^3 x0 + 3\dimen11*\dimen14/65536*\pgf@xa/65536% 3t(1 - t)^2 xa \relax% \expandafter% \endgroup% @@ -542,60 +544,80 @@ % Likewise for y: % y0 = \dimen6 (the moveto point), ya = #2, yb = #4, y1 = #6. \pgfpointtransformed{\pgfqpoint{#1}{#2}}% - \pgf@xa=\pgf@x% - \pgf@ya=\pgf@y% + \pgf@xa=\yquant@pgf@x% + \pgf@ya=\yquant@pgf@y% \pgfpointtransformed{\pgfqpoint{#3}{#4}}% - \pgf@xb=\pgf@x% - \pgf@yb=\pgf@y% + \pgf@xb=\yquant@pgf@x% + \pgf@yb=\yquant@pgf@y% \pgfpointtransformed{\pgfqpoint{#5}{#6}}% - \pgf@xc=\pgf@x% - \pgf@yc=\pgf@y% + \pgf@xc=\yquant@pgf@x% + \pgf@yc=\yquant@pgf@y% % We first solve the third-order polynomial for t using the y value, then plug it back into the x value. % TODO: this is accurate to approx. 3 digits. Can this be improved by reformulating Cardanos formula to involve less divisions? \begingroup% - % We need so may dimensions that we break with TeX's convention for their use. - % for the multiplications with and divisions by dimensions, we exploit that eTeX fuses muldiv to 64 bits. Further note that each dimension has a scaling factor of 65535 for sp<->pt conversion. This is why don't factor out divisions (which would be more efficient, but not give the benefit of 64bit accuracy). + % We need so many dimensions that we break with TeX's convention for their use. + % for the multiplications with and divisions by dimensions, we exploit that eTeX fuses muldiv to 64 bits. Further note that each dimension has a scaling factor of 65536 for sp<->pt conversion. This is why don't factor out divisions (which would be more efficient, but not give the benefit of 64bit accuracy). % a = 3(ya - yb) + (y1 - y0) \dimen1=\dimexpr3\pgf@ya-3\pgf@yb+\pgf@yc-\dimen6\relax% + \ifdim\dimen1<1pt % + \ifdim\dimen1>-1pt % + \dimen1=0pt % this is almost a quadratic curve + \fi% + \fi% \ifdim\dimen1=0pt % % this is only a quadratic curve! % b = 3(y0 - 2ya + yb) - \dimen3=\dimexpr3\dimexpr\dimen6-2\pgf@ya+\pgf@yb\relax*65535\relax% + \dimen3=3\dimexpr\dimen6-2\pgf@ya+\pgf@yb\relax% % c: 3(ya - y0) - \dimen5=\dimexpr3\dimexpr\pgf@ya-\dimen6\relax*65535\relax% + \dimen5=3\dimexpr\pgf@ya-\dimen6\relax% % d: y0 - <desired y> - \dimen7=\dimexpr\dimexpr\dimen6-\dimen2\relax*65535\relax% - % check the discriminant of the equation - \dimen8=\dimexpr\dimen3*\dimen3/65535-4\dimen3*\dimen7/65535\relax% - \unless\ifdim\dimen8<0pt% - % there are two potential candidates, (-c +- sqrt(c^2 - 4b d))/2b - \pgfmathsqrt@{\the\dimen8\@gobbletwo}% - \dimen11=\dimexpr\dimexpr-\dimen5+\pgfmathresult pt\relax*65535/% - \dimexpr2\dimen3\relax\relax% - \yquant@softpath@extractmaxxat@curveto@checkx% - \dimen11=\dimexpr\dimexpr-\dimen5-\pgfmathresult pt\relax*65535/% - \dimexpr2\dimen3\relax\relax% - \yquant@softpath@extractmaxxat@curveto@checkx% - \fi% + \dimen7=\dimexpr\dimen6-\dimen2\relax% + \ifdim\dimen3<1pt % + \expandafter\@firstofone% + \else% + \expandafter\@secondoftwo% + \fi{% + \ifdim\dimen3>-1pt % + % this is almost a linear curve! + \dimen11=\dimexpr-\dimen7*65536/\dimen5\relax% + \yquant@softpath@extractmaxxat@curveto@checkx% + \expandafter\@gobble% + \else% + \expandafter\@firstofone% + \fi% + }{% + % check the discriminant of the equation + \dimen8=\dimexpr\dimen3*\dimen3/65536-4\dimen3*\dimen7/65536\relax% + \unless\ifdim\dimen8<0pt% + % there are two potential candidates, (-c +- sqrt(c^2 - 4b d))/2b + \pgfmathsqrt@{\the\dimen8\@gobbletwo}% + \dimen11=\dimexpr\dimexpr-\dimen5+\pgfmathresult pt\relax*65536/% + \dimexpr2\dimen3\relax\relax% + \yquant@softpath@extractmaxxat@curveto@checkx% + \dimen11=\dimexpr\dimexpr-\dimen5-\pgfmathresult pt\relax*65536/% + \dimexpr2\dimen3\relax\relax% + \yquant@softpath@extractmaxxat@curveto@checkx% + \fi% + }% \else% % We will simplify by directly dividing all coefficients by a % b = 3(y0 - 2ya + yb) - \dimen3=\dimexpr3\dimexpr\dimen6-2\pgf@ya+\pgf@yb\relax*65535/\dimen1\relax% + \dimen3=\dimexpr3\dimexpr\dimen6-2\pgf@ya+\pgf@yb\relax*65536/\dimen1\relax% % c: 3(ya - y0) - \dimen5=\dimexpr3\dimexpr\pgf@ya-\dimen6\relax*65535/\dimen1\relax% + \dimen5=\dimexpr3\dimexpr\pgf@ya-\dimen6\relax*65536/\dimen1\relax% % d: y0 - <desired y> - \dimen7=\dimexpr\dimexpr\dimen6-\dimen2\relax*65535/\dimen1\relax% + \dimen7=\dimexpr\dimexpr\dimen6-\dimen2\relax*65536/\dimen1\relax% % Note that now our a value (\dimen1) is no longer needed, it is one. % check the discriminant of the equation % Q = (3c - b^2)/9 - \dimen8=\dimexpr\dimexpr3\dimen5-\dimen3*\dimen3/65535\relax/9\relax% + \dimen8=\dimexpr\dimexpr3\dimen5-\dimen3*\dimen3/65536\relax/9\relax% % R = (9bc - 27d - 2b^3)/54 = bc/6 - d/2 - b^3/27 - \dimen9=\dimexpr\dimen3*\dimen5/393210-% 6*65535 + \dimen9=\dimexpr\dimen3*\dimen5/393216-% 6*65536 .5\dimen7-% - \dimen3*\dimen3/65535*\dimen3/1769445% 27*65535 + \dimen3*\dimen3/65536*\dimen3/1769472% 27*65536 \relax% % D = Q^3 + R^2 - \dimen10=\dimexpr\dimen8*\dimen8/65535*\dimen8/65535+\dimen9*\dimen9/65535\relax% + \dimen10=\dimexpr\dimen8*\dimen8/65536*\dimen8/65536+\dimen9*\dimen9/65536\relax% \ifdim\dimen10>0pt % % only one real root: y_1 = S + T - b/3a % S = cbrt(R + sqrt(Q^3 + R^2)) @@ -641,7 +663,7 @@ \pgfmathsqrt@{\the\dimexpr-\dimen10\relax\@gobbletwo}% \dimen10=\pgfmathresult pt % % Let us first find the absolute value - \dimen12=\dimexpr\dimen9*\dimen9/65535+\dimen10*\dimen10/65535\relax% + \dimen12=\dimexpr\dimen9*\dimen9/65536+\dimen10*\dimen10/65536\relax% \pgfmathpow@{\the\dimen12\@gobbletwo}{.1666666667}% \dimen12=\pgfmathresult pt% % then we need 1/3 the argument of R + i sqrt(|D|). @@ -676,15 +698,15 @@ \protected\def\yquant@softpath@extractmaxxat@rectto#1#2\pgfsyssoftpath@rectsizetoken#3#4{% % #1: lower left x, #2: lower left y, #3: width, #4: height \pgfpointtransformed{\pgfqpoint{#1}{#2}}% - \pgf@xa=\pgf@x% - \pgf@ya=\pgf@y% + \pgf@xa=\yquant@pgf@x% + \pgf@ya=\yquant@pgf@y% \pgfpointtransformed{\pgfqpoint{\dimexpr#1+#3\relax}{\dimexpr#2+#4\relax}}% % (\pgf@xa, \pgf@ya) one corner, (\pgf@x, \pgf@y) other corner - \ifdim\pgf@y>\pgf@ya % + \ifdim\yquant@pgf@y>\pgf@ya % \unless\ifdim\pgf@ya>\dimen2 % - \unless\ifdim\pgf@y<\dimen2 % - \ifdim\pgf@x>\pgf@xa % - \yquant@softpath@extractmaxxat@update\pgf@x% + \unless\ifdim\yquant@pgf@y<\dimen2 % + \ifdim\yquant@orientation@plus\yquant@pgf@x>\yquant@orientation@plus\pgf@xa % + \yquant@softpath@extractmaxxat@update\yquant@pgf@x% \else% \yquant@softpath@extractmaxxat@update\pgf@xa% \fi% @@ -692,9 +714,9 @@ \fi% \else% \unless\ifdim\pgf@ya<\dimen2 % - \unless\ifdim\pgf@y>\dimen2 % - \ifdim\pgf@x>\pgf@xa % - \yquant@softpath@extractmaxxat@update\pgf@x% + \unless\ifdim\yquant@pgf@y>\dimen2 % + \ifdim\yquant@orientation@plus\yquant@pgf@x>\yquant@orientation@plus\pgf@xa % + \yquant@softpath@extractmaxxat@update\yquant@pgf@x% \else% \yquant@softpath@extractmaxxat@update\pgf@xa% \fi% diff --git a/Master/texmf-dist/tex/latex/yquant/yquant.sty b/Master/texmf-dist/tex/latex/yquant/yquant.sty index 75b1cfd2149..1b44a60c795 100644 --- a/Master/texmf-dist/tex/latex/yquant/yquant.sty +++ b/Master/texmf-dist/tex/latex/yquant/yquant.sty @@ -15,7 +15,7 @@ % % The Current Maintainer of this work is Benjamin Desef. \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{yquant}[2021/12/28 v0.6 Yet another quantum circuit library for LaTeX] +\ProvidesPackage{yquant}[2022/02/05 v0.7 Yet another quantum circuit library for LaTeX] \RequirePackage{etoolbox}[2018/02/11] \RequirePackage{tikz}[2015/08/29] @@ -37,15 +37,17 @@ \fi \newif\ifyquantdebug -\input yquant-config.tex +\pgfdeclarelayer{wires} +\pgfdeclarelayer{behindwires} \input yquant-tools.tex +\input yquant-shapes.tex +\input yquant-config.tex \input yquant-registers.tex \input yquant-env.tex \input yquant-langhelper.tex \input yquant-circuit.tex \input yquant-prepare.tex \input yquant-draw.tex -\input yquant-shapes.tex \input yquant-lang.tex % usually, \\ is robust; but when using \centering, it is \let to \@centercr, which is not robust (probably because this happens only when not protecting). Fix this, so that \\ does not require \protect if a centered circuit is drawn. diff --git a/Master/texmf-dist/tex/latex/yquant/yquantlanguage-groups.sty b/Master/texmf-dist/tex/latex/yquant/yquantlanguage-groups.sty index 1ea78cace69..fc1986ff048 100644 --- a/Master/texmf-dist/tex/latex/yquant/yquantlanguage-groups.sty +++ b/Master/texmf-dist/tex/latex/yquant/yquantlanguage-groups.sty @@ -15,9 +15,9 @@ % % The Current Maintainer of this work is Benjamin Desef. \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{yquantlanguage-groups}[2021/08/14 v0.6 yquant-groups] +\ProvidesPackage{yquantlanguage-groups}[2022/01/07 v0.7 yquant-groups] -\RequirePackage{yquant}[2021/12/24] +\RequirePackage{yquant}[2022/01/07] % BEGIN_FOLD Config \newif\ifyquantgroup@config@aligned @@ -39,7 +39,11 @@ }% \fi% },% - operators/every group equals/.style={shape=yquant-rectangle, align=center, inner xsep=1mm, x radius=2mm, y radius=2.47mm} + operators/every group equals/.style={% + shape=yquant-rectangle, align=center, + anchor/.expanded=\ifyquanthorz{center}{north west},% + inner xsep=1mm, x radius=2mm, y radius=2.47mm% + } } \def\yquantgroup@config@lineseparation{5mm}% % END_FOLD @@ -66,7 +70,7 @@ \let\equals=\yquantgroup@equals% \let\shiftright=\yquantgroup@shiftright% \let\\=\yquantgroup@linebreak% - % This is a bit inconsistent, we should check \iftikz@inside@picture, but this is no longer appropriately set since at pgf 3.1.2. + % This is a bit inconsistent, we should check \iftikz@inside@picture, but this is no longer appropriately set since at least pgf 3.1.2. \let\ifyquantgroup@inpicture=\ifpgfpicture% \pgfkeysgetvalue{/yquant/preamble}\yquantgroup@save@preamble% \ifpgfpicture% @@ -127,6 +131,10 @@ % BEGIN_FOLD Register declaration \protected\long\def\yquantgroup@registers#1{% + \def\registers{% + \PackageError{yquant.sty}{Double invocation of \string\registers}% + {All registers must be specified once at the beginning of the group. Multiple declarations or later additions are not allowed.}% + }% \begingroup% \gdef\yquantgroup@registers@text{#1}% \let\yquantgroup@save@lang@create@parse=\yquant@lang@create@parse@name% @@ -152,10 +160,6 @@ \yquant@env@end% \endpgfinterruptboundingbox% }% - \def\registers{% - \PackageError{yquant.sty}{Double invocation of \string\registers}% - {All registers must be specified once at the beginning of the group. Multiple declarations or later additions are not allowed.}% - }% \unless\ifx\yquantgroup@registers@text\empty% \csxappto{\yquantgroup@prefix import@\csname\yquantgroup@prefix registers\endcsname}{% \unexpanded\expandafter{\yquantgroup@registers@text}% @@ -248,14 +252,25 @@ \fi% % since \registers is in subcircuit mode, that the existence of the macro implies that it is greater than zero \ifdef\yquant@prefix{% - % We already started the yquant environment - but this means that potentially, we could have changed our wire styles. The underlying subcircuit architecture will preserve these changes, but since in our context, we treat the circuits as independent, this is not the desired behavior: remove all styles. - \yquant@for \i := 1 to \csname\yquant@prefix registers\endcsname {% - % we don't really need to flush a wire, since it is discarded anyway - \csxappto{\yquant@prefix draw}{% - \yquant@register@set@style{\i}{}% + \ifyquanthorz{% + % We already started the yquant environment - but this means that potentially, we could have changed our wire styles. The underlying subcircuit architecture will preserve these changes, but since in our context, we treat the circuits as independent, this is not the desired behavior: remove all styles. + \yquant@for \i := 1 to \csname\yquant@prefix registers\endcsname {% + % we don't really need to flush a wire, since it is discarded anyway + \csxappto{\yquant@prefix draw}{% + \yquant@register@set@style{\i}{}% + }% + }% + \@gobble% + }{% + % We already started the yquant environment, but it was a vertical one. We are unable to perform wire alignment with vertical circuits. We want to place the next circuit to its right, which means that we acutually need to end the environment. + \expandafter% + \yquant@env@end% + \expandafter\def\expandafter\yquantgroup@currentxpos\expandafter{\the\dimexpr% + \pgf@picmaxx+\yquant@config@operator@sep% }% }% - }{% + }\@firstofone% + {% \yquant@env@begin[/tikz/shift={(\yquantgroup@currentxpos, \yquantgroup@currentypos)}]% % we re-create all the outer registers, but without the names. % sync with yquant-registers/\yquant@register@define @@ -377,18 +392,48 @@ } \protected\long\def\yquantgroup@equals@ii#1[#2]{% - \yquantgroup@startenvironments% - \ifx0#1% - \yquant group\space equals {#2} (-);% - \else% + \unless\ifx0#1% \numgdef\yquantgroup@alignments{\yquantgroup@alignments+1}% - % hopefully no prefixes/suffixes are installed - if we reset them here, it will also reset them for the content, which we don't want to do; but this will then give an error when we try to access the node. Probably never a problem. - \yquant [name=yquantgroup@internal@alignment@\yquantgroup@alignments]% - group\space equals {#2} (-);% + \fi% + \ifyquanthorz{% + \yquantgroup@startenvironments% + \ifx0#1% + \yquant group\space equals {#2} (-);% + \else% + % hopefully no prefixes/suffixes are installed - if we reset them here, it will also reset them for the content, which we don't want to do; but this will then give an error when we try to access the node. Probably never a problem. + \yquant [name=yquantgroup@internal@alignment@\yquantgroup@alignments]% + group\space equals {#2} (-);% + \fi% + }{% + % in vertical mode, we must be very careful: we cannot place the box in a circuit, as it would go under the others. In principle, it would be nice to place the equals vertically centered to the right of the last circuit, but the circuits may well have different vertical extents, so a centering does not make sense. Therefore, we place it to the top. + \ifdefined\yquant@prefix% + \edef\yquantgroup@handlesize{% + \global\pgf@picmaxx=-16000pt % + \yquant@env@end% + \edef\noexpand\yquantgroup@currentxpos{% + \noexpand\the\dimexpr\pgf@picmaxx+% + \noexpand\yquant@config@operator@sep\relax% + }% + \noexpand\ifdim\pgf@picmaxx<\the\pgf@picmaxx\space% + \global\pgf@picmaxx=\the\pgf@picmaxx\space% + \noexpand\fi% + }% + \yquantgroup@handlesize% + \fi% + \node[/yquant/operators/every group equals] (yquantnode) at (\yquantgroup@currentxpos, \yquantgroup@currentypos) {#2}; + \unless\ifx0#1% + \pgfcoordinate{yquantgroup@internal@alignment@\yquantgroup@alignments}% + {\pgfqpoint{\dimexpr\yquantgroup@currentxpos+\yquant@config@operator@sep}% + {\yquantgroup@currentypos}}% + \fi% + \pgfpointanchor{yquantnode}{north east} + \dimdef\yquantgroup@currentxpos{\pgf@x+\yquant@config@operator@sep}% + }% + \unless\ifx0#1% \ifnum\yquantgroup@alignments>1 % - \pgfcoordinate{yquantgroup@internal@alignment@\the\numexpr\yquantgroup@alignments-1\relax}{west}% + \pgfpointanchor{yquantgroup@internal@alignment@\the\numexpr\yquantgroup@alignments-1\relax}{west}% \pgf@xa=\pgf@x% - \pgfcoordinate{yquantgroup@internal@alignment@\yquantgroup@alignments}{west}% + \pgfpointanchor{yquantgroup@internal@alignment@\yquantgroup@alignments}{west}% \unless\ifdim\pgf@x>\pgf@xa% \PackageError{yquant.sty}{Invalid alignment mark position}% {The desired alignment mark position would be to the left of an already existing mark.}% @@ -431,7 +476,7 @@ }% \ifx1#1% \ifnum\yquantgroup@alignments>0 % - \pgfcoordinate{yquantgroup@internal@alignment@\yquantgroup@alignments}{west}% + \pgfpointanchor{yquantgroup@internal@alignment@\yquantgroup@alignments}{west}% \unless\ifdim\dimexpr\yquantgroup@currentxpos+\yquant@config@operator@sep\relax>\pgf@x% \PackageError{yquant.sty}{Invalid alignment mark position}% {The desired alignment mark position would be to the left of an already existing mark.}% |