From b00d598c405e2f58e2be6d3511013787b40954dd Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 9 Apr 2010 23:57:25 +0000 Subject: xypdf 1.2 (8apr10) git-svn-id: svn://tug.org/texlive/trunk@17777 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/xypdf/README | 6 +- Master/texmf-dist/doc/latex/xypdf/xypdf.pdf | Bin 196590 -> 217799 bytes Master/texmf-dist/source/latex/xypdf/xypdf.dtx | 1518 ++++++++++++++++-------- Master/texmf-dist/source/latex/xypdf/xypdf.ins | 244 ++-- Master/texmf-dist/tex/latex/xypdf/xypdf.sty | 738 +++++++----- 5 files changed, 1611 insertions(+), 895 deletions(-) (limited to 'Master/texmf-dist') diff --git a/Master/texmf-dist/doc/latex/xypdf/README b/Master/texmf-dist/doc/latex/xypdf/README index 4a06915fed6..a5238038cb7 100644 --- a/Master/texmf-dist/doc/latex/xypdf/README +++ b/Master/texmf-dist/doc/latex/xypdf/README @@ -1,5 +1,5 @@ -xypdf 2010/03/30 v1.1 -Copyright (c) 2010 by Daniel Müllner +xypdf 2010/04/08 v1.2 +Copyright © 2010 by Daniel Müllner http://www.math.uni-bonn.de/people/muellner ------------------------------------------------------------------------------ @@ -8,7 +8,7 @@ The xypdf package improves the output quality of the Xy-pic package when PDF documents are generated. It produces generic PDF code for graphical elements like lines, curves and circles instead of approximating these elements with glyphs in special fonts as the original Xy-pic package does. The xypdf package -works both with pdfLaTeX and the two-step compilation LaTeX -> dvipdfm(x). +works both with pdfLaTeX and the two-step compilation LaTeX → dvipdfm(x). ------------------------------------------------------------------------------ diff --git a/Master/texmf-dist/doc/latex/xypdf/xypdf.pdf b/Master/texmf-dist/doc/latex/xypdf/xypdf.pdf index fe31d4175dc..2167778520e 100644 Binary files a/Master/texmf-dist/doc/latex/xypdf/xypdf.pdf and b/Master/texmf-dist/doc/latex/xypdf/xypdf.pdf differ diff --git a/Master/texmf-dist/source/latex/xypdf/xypdf.dtx b/Master/texmf-dist/source/latex/xypdf/xypdf.dtx index a324870ff68..9912b285b67 100644 --- a/Master/texmf-dist/source/latex/xypdf/xypdf.dtx +++ b/Master/texmf-dist/source/latex/xypdf/xypdf.dtx @@ -36,7 +36,7 @@ % \iffalse %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{xypdf} -% [2010/03/30 v1.1 PDF output for the Xy-pic package] +% [2010/04/08 v1.2 PDF output for the Xy-pic package] % %<*driver> \documentclass[a4paper]{ltxdoc} @@ -115,7 +115,7 @@ % % \fi % -% \CheckSum{0} +% \CheckSum{5713} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z @@ -137,7 +137,7 @@ % \GetFileInfo{xypdf.sty} % % ^^A TeX and LaTeX commands -% \DoNotIndex{\@for,\@gobble,\@gtempa,\@gtempb,\@ifdefinable,\@ifpackageloaded,\@ne,\@tempa,\@tempcnta,\@tempdima,\@tempdimb,\@tempdimc,\@tempswafalse,\@tempswatrue,\@temptokena,\@undefined} +% \DoNotIndex{\@for,\@gobble,\@gtempa,\@ifdefinable,\@ifpackageloaded,\@ne,\@tempa,\@tempcnta,\@tempdima,\@tempdimb,\@tempdimc,\@tempswafalse,\@tempswatrue,\@temptokena,\@undefined} % \DoNotIndex{\advance,\AtBeginDocument,\AtEndOfPackage} % \DoNotIndex{\CheckCommand,\count,\count@,\csname} % \DoNotIndex{\def,\dimen,\dimen@i,\dimexpr,\divide,\do} @@ -181,13 +181,13 @@ % % \section{Introduction} % -% The \Xy-pic package is a utility for typesetting diagrams in \TeX{} and \LaTeX{} documents. The authors of the \Xy-pic package put much effort into the feature that most graphical elements are coded within the limited possibilities of the device independent file format (DVI) and can thus be generated with even the most basic \TeX{} systems and displayed universally by all device drivers. For example, diagonal lines are composed of short dashes, which are glyphs in a special font. Since there are dashes in 127 discrete directions in the font \textsf{xydash10}, diagonal lines which do not match one of these slopes look slightly rugged when they are magnified. +% The \Xy-pic package is a utility for typesetting diagrams in \TeX{} and \LaTeX{} documents. The authors of the \Xy-pic package put much effort into the feature that most graphical elements are coded within the limited possibilities of the device independent file format (DVI). The diagrams can thus be generated with even the most basic \TeX{} systems and displayed universally by all device drivers. For example, diagonal lines are composed of short dashes, which are glyphs in a special font. Since there are dashes in 127 discrete directions in the font \textsf{xydash10}, diagonal lines which do not match one of these slopes look slightly rugged when they are magnified. % % For a better output quality in Postscript files, the authors of the \Xy-pic package provided a Postscript backend for DVI-to-Postscript drivers. These extensions draw lines and curves by generic Postscript commands, thus trading a much better output quality against universality of the produced DVI files. % % As the most recent version 3.7 of \Xy-pic dates from 1999, there is no support for pdf\TeX. In order to produce PDF files with high-quality \Xy-pic diagrams, users had to use so far the Postscript file format as an intermediate step or embed the diagrams as external graphics. However, since many users directly generate PDF files from the \TeX{} or DVI files (with bookmarks, hyperlinks and other PDF features), it is highly desirable to also have the possibility of directly generating \Xy-pic diagrams with high-quality PDF graphics elements. % -% The present package \textsf{xypdf} adapts the output routines of the \Xy-pic package to generate high-quality graphics for PDF output. It works with both pdf\LaTeX and the two-step compilation \LaTeX${}\to{}$dvipdfm(x) with an intermediate DVI file. Note that some version of $\varepsilon$-\TeX{} is needed (which is anyway used by default in modern \TeX{} installations). \autoref{Fig1} compares the output quality of a small \Xy-pic figure. +% The present package \textsf{xypdf} adapts the output routines of the \Xy-pic package to generate high-quality graphics for PDF output. It works with both pdf\LaTeX and the two-step compilation \LaTeX${}\to{}$dvipdfm(x) with an intermediate DVI file. Note that some version of $\varepsilon$-\TeX{} is needed (which is anyway used by default in modern \TeX{} installations). \autoref{Fig1} compares the output quality of a small \Xy-pic diagram. % \newcommand*\testdiag{\xy *[*10]\hbox{\xy (5,0): 0; % a(0) **\dir{-}, % a(6.524)**\dir{-}, @@ -211,9 +211,7 @@ % \end{figure} % % The \textsf{xypdf} package is very similar to the Postscript backend to \Xy-pic. It does not have (yet) all features of the Postscript backend (see \autoref{sec:todo}) but is much more powerful in other respects, e.\,g.\ when drawing multiple curves. In general, it greatly improves graphics quality in most circumstances and otherwise leaves graphics elements as they are. Currently, the following features are implemented: -% \makeatletter % \newcommand\showline[1]{{\xypdfoff#1}&{\xypdfon#1}} -% \makeatother % \begin{itemize} % \item % Both straight lines and curves (solid, dashed, dotted and squiggled) are drawn by generic PDF commands. @@ -261,7 +259,7 @@ % \end{center} % % \item -% \textsf{xypdf} supports the “rotate” extension of \Xy-pic: +% \textsf{xypdf} supports the “rotate” extension of \Xy-pic. % \begin{center} % \begin{tabular}{@{}cl@{}} % with \textsf{xypdf}&code\\ @@ -299,41 +297,41 @@ % Support for the “line styles”, “frame” and “color” extensions. % \end{itemize} % -% \section{Caveat} +% \section{The fine print: curves with multiple segments}\label{beziercont} % -% Since the dashes in Bézier segments are aligned to the boundary points, this results in dashes of double length when a curve is composed of several Bézier segments. The original \Xy-pic draws two dashes on top of each other at these positions. -% \newcommand*\mydiag{} +% Since the dashes in Bézier segments are aligned to the boundary points, this would result in dashes of double length when a curve is composed of several Bézier segments, as shown in the upper left diagram. To avoid this, \textsf{xypdf} records the end point of each segment and adapts the dash pattern whenever the starting point of a segment coincides with the end point of the previous one (see the upper right diagram). Analogous improvements apply to the “dotted” and “squiggled” line styles. +% +% Since this mechanism does not exist in the original \Xy-pic, it can be switched on and off by "\xypdfcontpatternon" and "\xypdfcontpatternoff". By default, it is switched on. +% \newcommand*\mydiag{{\xy(0,0);(50,0)**\crv{~**\dir{--}(10,0)&(20,15)&(30,15)&(40,0)}\endxy}} % \begin{center} % \begin{tabular}{@{}cc@{}} -% without \textsf{xypdf}& with \textsf{xypdf}\\ +% "\xypdfcontpatternoff"&"\xypdfcontpatternon" (default)\\ +% \midrule +% \xypdfcontpatternoff\mydiag&\xypdfcontpatternon\mydiag\\[\bigskipamount] +% \multicolumn{2}{l}{\vbox{\normalbaselines% +% \hbox{code:} +% \vskip\jot +% \hbox{\texttt{\string\xy\space (0,0);(50,0)}} +% \hbox{\texttt{~~**\string\crv\{\textasciitilde**\string\dir\{-{}-\} (10,0)\&(20,15)\&(30,15)\&(40,0)\}}} +% \hbox{\texttt{\string\endxy}} +% }}\\[\bigskipamount] +% similar improvement: dotted curve&squiggled curve\\ % \midrule -% \showline{\xy(0,0);(50,0)**\crv{~**\dir{--}(10,0)&(20,15)&(30,15)&(40,0)}\endxy}\\ +% {\xy(0,0);(50,0)**\crv{~**\dir{.}(10,0)&(20,15)&(30,15)&(40,0)}\endxy}& +% {\xy(0,0);(50,0)**\crv{~**\dir{~}(10,0)&(20,15)&(30,15)&(40,0)}\endxy} % \end{tabular} % \end{center} -% code: -% \begin{verbatim} -%\xy (0,0);(50,0) -% **\crv{~**\dir{--} (10,0)&(20,15)&(30,15)&(40,0)} -%\endxy -% \end{verbatim} -% -% ^^A \StopEventually{\PrintIndex} -% \StopEventually{} % % \section{Copyright, license and disclaimer} % -% The copyright for the \textsf{xypdf} package is by its author, Daniel Müllner. -% You may find current contact details at \url{http://www.math.uni-bonn.de/people/muellner}. +% The copyright for the \textsf{xypdf} package is by its author, Daniel Müllner. Current contact details will be maintained at \url{http://www.math.uni-bonn.de/people/muellner}. % -% The \textsf{xypdf} package is free software: you can redistribute it and/or modify -% it under the terms of the GNU General Public License as published by -% the Free Software Foundation, either version 3 of the License, or -% (at your option) any later version. +% The \textsf{xypdf} package is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This license is available at \url{http://www.gnu.org/licenses/}. % -% This program is distributed in the hope that it will be useful, -% but without any warranty; without even the implied warranty of -% merchantability or fitness for a particular purpose. See the -% GNU General Public License for more details. This license is available at \url{http://www.gnu.org/licenses/}. +% This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. See the GNU General Public License for more details. +% +% ^^A \StopEventually{\PrintIndex} +% \StopEventually{} % % \section{Implementation} % @@ -347,6 +345,12 @@ \PackageError{xypdf}{Do not load Xy-pic with a Postscript backend}{}% } % \end{macrocode} +% Test for $\varepsilon$-\TeX +% \begin{macrocode} +\ifx\unexpanded\@undefined + \PackageError{xypdf}{eTeX is needed for the xypdf package}{} +\fi +% \end{macrocode} % Rely on the ifpdf package to test for PDF output. % \begin{macrocode} \RequirePackage{ifpdf} @@ -379,6 +383,7 @@ \let\xP@hook\@undefined \let\xP@tempvar\@undefined \let\@tempa\@undefined + \let\next@\undefined \let\xP@gobblepart\@undefined \let\xP@endgobble\@undefined } @@ -387,29 +392,65 @@ % \end{macro} % \end{macro} % \begin{macro}{\xP@literal} -% Two possibilities to insert literal PDF commands, one for pdftex and one for dvipdfm(x) +% \begin{macro}{\xP@cm} +% Two possibilities to insert literal PDF commands, one for pdftex and one for dvipdfm(x). The command "\xP@cm" changes the current transformation matrix. % \begin{macrocode} -\@ifdefinable\xP@literal\relax \ifpdf - \let\xP@literal\pdfliteral + \newcommand*\xP@literal[1]{\pdfsave\pdfliteral{#1}\pdfrestore} + \newcommand*\xP@cm[5]{% + \pdfsave + \pdfsetmatrix{#1 #2 #3 #4}% + #5% + \pdfrestore + } \else - \def\xP@literal{% - \PackageWarning{xypdf}{The produced DVI file is NOT PORTABLE. Convert it with% - ^^J% - dvipdfm(x) to the PDF format but do not expect the DVI itself to be displayed% - ^^J% - correctly\@gobble}% - \global\let\xP@literal\xP@literal@ - \xP@literal + \newcommand*\xP@literal{% + \PackageWarning{xypdf}{% + The produced DVI file is NOT PORTABLE. Convert it with^^J% + dvipdfm(x) to the PDF format but do not expect the DVI file itself to be^^J% + displayed correctly\@gobble}% + \global\let\xP@literal\xP@literal@ + \xP@literal + } + \newcommand*\xP@literal@[1]{\special{pdf:content #1}} + \newcommand*\xP@cm[5]{% + \special{pdf:btrans matrix #1 #2 #3 #4 0 0}% + #5% + \special{pdf:etrans}% } - \newcommand*\xP@literal@[1]{\special{pdf:literal #1}} +\fi +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\xP@digits} +% Set the precision for dimension output according to pdf\TeX's "\pdfdecimaldigits". If this number is not defined, use dvipdfm's default precision, which is two decimals. +% \begin{macrocode} +\ifx\pdfdecimaldigits\@undefined + \newcommand*\xP@digits{2} +\else + \@ifdefinable\xP@digits\relax + \xdef\xP@digits{\the\pdfdecimaldigits} + \ifnum\pdfdecimaldigits<2 + \PackageWarning{xypdf}{% + The precision in \string\pdfdecimaldigits\space is only \xP@digits\space + decimals.^^J% + It is recommended to set \string\pdfdecimaldigits\space to 2 or 3 for % + best output quality\@gobble} + \fi \fi % \end{macrocode} % \end{macro} % \begin{macro}{\xP@dim} % Conversion between \TeX{} points (pt) and PDF/Postscript points (bp) % \begin{macrocode} -\newcommand*\xP@dim[1]{\xP@EARPT\dimexpr(#1)*800/803\relax\space} +\newcommand*\xP@dim[1]{% + \expandafter\xP@removePT\the\dimexpr(#1)*800/803\relax\space} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\xP@precdim} +% Precise conversion between \TeX{} points (pt) and PDF/Postscript points (bp). No truncation. +% \begin{macrocode} +\newcommand*\xP@precdim[1]{\xP@EARPT\dimexpr(#1)*800/803\relax\space} % \end{macrocode} % \end{macro} % \begin{macro}{\xP@EARPT} @@ -423,7 +464,125 @@ \newcommand*\xP@coor[1]{\xP@dim{#1}\xP@dim} % \end{macrocode} % \end{macro} +% \begin{macro}{\xP@removePT} +% The following two macros round and truncate a dimension to the desired number of decimal digits. +% \begin{macrocode} +\@ifdefinable\xP@removePT\relax +{\catcode`\p=12\catcode`\t=12\gdef\xP@removePT#1pt{\xP@removePT@#10000@}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\xP@removePT@} +% \begin{macrocode} +\@ifdefinable\xP@removePT@\relax +\ifcase\xP@digits +% \end{macrocode} +% 0 decimals +% \begin{macrocode} + \def\xP@removePT@#1.#2#3@{% + \ifnum#2<5 + #1% + \else + \the\numexpr-\if-#1-\else-#1+\fi\@ne\relax + \fi + } +\or +% \end{macrocode} +% 1 decimal +% \begin{macrocode} + \def\xP@removePT@#1#2.#3#4#5@{% + \ifnum#4<5 + #1#2% + \if#30% + \else + .#3% + \fi + \else + \expandafter\xP@removePT + \the\dimexpr#1#2.#3pt+\if#1--\fi.12pt\relax + \fi + } +\or +% \end{macrocode} +% 2 decimals +% \begin{macrocode} + \def\xP@removePT@#1#2.#3#4#5#6@{% + \ifnum#5<5 + #1#2% + \if#40% + \if#30% + \else + .#3% + \fi + \else + .#3#4% + \fi + \else + \expandafter\xP@removePT + \the\dimexpr#1#2.#3#4pt+\if#1--\fi786sp\relax + \fi + } +\or +% \end{macrocode} +% 3 decimals +% \begin{macrocode} + \def\xP@removePT@#1#2.#3#4#5#6#7@{% + \ifnum#6<5 + #1#2% + \if#50% + \if#40% + \if#30% + \else + .#3% + \fi + \else + .#3#4% + \fi + \else + .#3#4#5% + \fi + \else + \expandafter\xP@removePT + \the\dimexpr#1#2.#3#4#5pt+\if#1--\fi79sp\relax + \fi + } +\or +% \end{macrocode} +% 4 decimals +% \begin{macrocode} + \def\xP@removePT@#1#2.#3#4#5#6#7#8@{% + \ifnum#7<5 + #1#2% + \if#60% + \if#50% + \if#40% + \if#30% + \else + .#3% + \fi + \else + .#3#4% + \fi + \else + .#3#4#5% + \fi + \else + .#3#4#5#6% + \fi + \else + \expandafter\xP@removePT + \the\dimexpr#1#2.#3#4#5#6pt+\if#1--\fi8sp\relax + \fi + } +\else +% \end{macrocode} +% 5 or more decimals: no truncation +% \begin{macrocode} + \let\xP@dim\xP@precdim +\fi +% \end{macrocode} +% \end{macro} % \begin{macro}{\xP@lw} +% \begin{macro}{\xP@preclw} % Find out the default line width in the math fonts. This is done at the beginning of the document, when hopefully all potential changes to math fonts have taken place. % \begin{macrocode} \AtBeginDocument{% @@ -432,11 +591,14 @@ % \begin{macrocode} {\setbox0\hbox{$ $}}% \@ifdefinable\xP@lw\relax - \edef\xP@lw{\xP@dim{\fontdimen8\textfont3}}% - \PackageInfo{xypdf}{Line width: \the\fontdimen8\textfont3 }% + \@ifdefinable\xP@preclw\relax + \edef\xP@preclw{\the\fontdimen8\textfont3}% + \edef\xP@lw{\xP@dim\xP@preclw}% + \PackageInfo{xypdf}{Line width: \xP@preclw}% } % \end{macrocode} % \end{macro} +% \end{macro} % % \subsection{Straight lines} % @@ -477,12 +639,15 @@ % \begin{macro}{\xP@setsolidpat} % Pattern for solid lines % \begin{macrocode} -\newcommand*\xP@setsolidpat{\def\xP@pattern{1 J 1 j []0 d }} +\newcommand*\xP@setsolidpat{% + \def\xP@pattern{1 J 1 j []0 d}% + \global\let\xP@lastpattern\xP@solidmacro +} % \end{macrocode} % \end{macro} % \begin{macro}{\xP@stroke} % \begin{macrocode} -\newcommand*\xP@stroke[1]{\xP@literal{q \xP@lw w \xP@pattern#1 S Q}} +\newcommand*\xP@stroke[1]{\xP@literal{\xP@lw w \xP@pattern\space#1 S}} % \end{macrocode} % \end{macro} % \begin{macro}{\dash@} @@ -504,6 +669,7 @@ % \begin{macrocode} \ifdim\@tempdimb>\z@ \xP@setdashpat + \xP@savec \xP@stroke{\xP@coor\X@p\Y@p m \xP@coor\X@c\Y@c l}% \fi }} @@ -519,12 +685,24 @@ % The length $l$ must be in "\@tempdimb". % \begin{macrocode} \newcommand*\xP@setdashpat{% - \edef\xP@pattern{1 J 1 j [% - \ifdim\@tempdimb>\xydashl@ - \xP@dim{\@tempdimb/(2*\numexpr(\@tempdimb+\xydashl@)% - /(2*\xydashl@)\relax-1)}% + \xP@testcont\xP@dashmacro + \ifxP@splinecont +% \end{macrocode} +% Special pattern in case this line continues another dashed segment. +% \begin{macrocode} + {\count@\numexpr2*((\@tempdimb-\xydashl@/3)/(2*\xydashl@))\relax + \xdef\@gtempa{\ifnum\count@>\z@\xP@dim{\@tempdimb/\count@}\fi}% + }% + \edef\xP@pattern{1 J 1 j [\@gtempa]\ifx\@gtempa\empty0 \else\@gtempa\fi d}% + \else + \edef\xP@pattern{1 J 1 j [% + \ifdim\@tempdimb>\xydashl@ + \xP@dim{\@tempdimb/(2*((\@tempdimb+\xydashl@)/(2*\xydashl@))-1)}% + \fi + ]0 d}% \fi - ]0 d }} + \global\let\xP@lastpattern\xP@dashmacro +} % \end{macrocode} % \end{macro} % \begin{macro}{\point@} @@ -540,16 +718,13 @@ % \end{macrocode} % \end{macro} % \end{macro} -% \begin{macro}{\xP@zerodotpattern} -% \begin{macrocode} -\newcommand*\xP@zerodotpattern{\def\xP@pattern{2 J [0 2]0 d }} -% \end{macrocode} -% \end{macro} % \begin{macro}{\xP@zerodot} % \begin{macrocode} \newcommand*\xP@zerodot{% - \xP@zerodotpattern - \xP@stroke{0 0 m 1 0 l}} + \hb@xt@\z@{\hss + \vbox to\z@{\vss\hrule\@width\xP@preclw\@height\xP@preclw\vss}% + \hss}% +} % \end{macrocode} % \end{macro} % \begin{macro}{\xP@dottedSpread} @@ -559,6 +734,7 @@ \xP@veclen \ifdim\@tempdimb>\z@ \xP@setdottedpat + \xP@savec \xP@stroke{\xP@coor\X@p\Y@p m \xP@coor\X@c\Y@c l}% \fi }} @@ -573,16 +749,38 @@ % % The length $l$ must be in "\@tempdimb". % \begin{macrocode} -\newcommand*\xP@setdottedpat{\edef\xP@pattern{% - 2 J [% +\newcommand*\xP@setdottedpat{% + \xP@testcont\xP@dotmacro + \ifxP@splinecont + \@tempdima\dimexpr\@tempdimb/(\@tempdimb/131072+1)-\xP@preclw\relax + \edef\xP@pattern{% + 0 J [% +% \end{macrocode} +% Produce a dot pattern only when the segment is long enough. +% \begin{macrocode} + \ifdim\@tempdima>\z@ + \xP@precdim\xP@preclw\xP@precdim\@tempdima + \fi +% \end{macrocode} +% Advance the offset very slightly by 1sp to really hide the first dot in the viewer. (This improves the display at least in the author's PDF-Xchange viewer.) +% \begin{macrocode} + ]\xP@precdim{\xP@preclw+1sp}d}% + \else + \advance\@tempdimb-\xP@preclw + \ifdim\@tempdimb<\z@\@tempdimb\z@\fi + \@tempdima\dimexpr\@tempdimb/(\@tempdimb/131072+1)-\xP@preclw\relax + \edef\xP@pattern{% + 0 J [% % \end{macrocode} -% Produce a dot pattern only when the segment length is greater than the line width. +% Produce a dot pattern only when the segment is long enough. % \begin{macrocode} - \ifdim\@tempdimb>\xP@lw bp - 0 \xP@dim{\@tempdimb/\numexpr\@tempdimb/131072+1\relax}% + \ifdim\@tempdima>\z@ + \xP@lw\xP@dim\@tempdima + \fi + ]0 d}% \fi - ]0 d -}} + \global\let\xP@lastpattern\xP@dotmacro +} % \end{macrocode} % \end{macro} % In contrast to the Postscript drivers for \Xy-pic, where some computations are left to the Postscript code, all arithmetic for the PDF output must be done by \TeX{} itself. With \TeX's rudimentary fixed-point arithmetic, it is still a pain to compute even the length of a line segment, but things have become considerably easier with $\varepsilon$-\TeX. @@ -603,12 +801,6 @@ \fi % \end{macrocode} % \end{macro} -% \begin{macro}{\xP@ifabsless@} -% \begin{macrocode} -\newcommand*\xP@ifabsless@[4]{% - \xP@ifabsless{\dimexpr#1\relax}{\dimexpr#2\relax}#3\else#4\fi} -% \end{macrocode} -% \end{macro} % \begin{macro}{\xP@swapdim} % Works unless parameter "#2" is "\@tempdima". % \begin{macrocode} @@ -658,8 +850,7 @@ \newcommand*\xP@veclen{{% \xP@veclen@ \global\dimen@i\@tempdimb - }% - \@tempdimb\dimen@i + }\@tempdimb\dimen@i } % \end{macrocode} % \end{macro} @@ -762,6 +953,15 @@ \ifnum\@tempcnta<\tw@\@tempcnta\tw@\fi \@tempdima\dimexpr\d@X/\@tempcnta\relax \@tempdimc\dimexpr\d@Y/\@tempcnta\relax +% \end{macrocode} +% Reverse the direction of the little arcs, if the last squiggle from the previous segment makes it necessary. +% \begin{macrocode} + \xP@testcont\xP@oddsquigglemacro + \ifxP@splinecont + \def\xP@squigsign{-}% + \else + \let\xP@squigsign\empty + \fi \count@\z@ \loop % \end{macrocode} @@ -769,27 +969,42 @@ % \begin{macrocode} \xP@append\toks@{% \xP@coor{\X@p+\d@X*\count@/\@tempcnta+(\@tempdima - -\ifodd\count@-\fi\@tempdimc)*147546029/534618434}% + -\xP@squigsign\ifodd\count@-\fi\@tempdimc)*147546029/534618434}% {\Y@p+\d@Y*\count@/\@tempcnta+(\@tempdimc - +\ifodd\count@-\fi\@tempdima)*147546029/534618434}% + +\xP@squigsign\ifodd\count@-\fi\@tempdima)*147546029/534618434}% }% \advance\count@\@ne \xP@append\toks@{% \xP@coor{\X@p+\d@X*\count@/\@tempcnta-(\@tempdima - -\ifodd\count@-\fi\@tempdimc)*147546029/534618434}% + -\xP@squigsign\ifodd\count@-\fi\@tempdimc)*147546029/534618434}% {\Y@p+\d@Y*\count@/\@tempcnta-(\@tempdimc - +\ifodd\count@-\fi\@tempdima)*147546029/534618434}% + +\xP@squigsign\ifodd\count@-\fi\@tempdima)*147546029/534618434}% \xP@coor{\X@p+\d@X*\count@/\@tempcnta}% {\Y@p+\d@Y*\count@/\@tempcnta}% c }% \ifnum\count@<\@tempcnta \repeat \xP@setsolidpat +% \end{macrocode} +% Record the direction of the last squiggle. +% \begin{macrocode} + \global\expandafter\let\expandafter\xP@lastpattern + \ifodd\numexpr\count@\if\xP@squigsign-+1\fi\relax + \xP@oddsquigglemacro + \else + \xP@evensquigglemacro + \fi + \xP@savec \xP@stroke{\the\toks@}% \fi }} % \end{macrocode} % \end{macro} +% \begin{macro}{\xP@squigsign} +% \begin{macrocode} +\newcommand*\xP@squigsign{} +% \end{macrocode} +% \end{macro} % \end{macro} % \begin{macro}{\xP@append} % \begin{macrocode} @@ -940,7 +1155,7 @@ % \begin{macro}{\xP@gobblepart} % \begin{macrocode} \@ifdefinable\xP@gobblepart\relax -\long\def\xP@gobblepart#1\xP@endgobble{} +\def\xP@gobblepart#1\xP@endgobble{} % \end{macrocode} % \end{macro} % \begin{macro}{\xP@endgobble} @@ -962,28 +1177,25 @@ \setboxz@h{% \hskip\L@p \hskip-\R@p - \lower\U@p\hbox{% - \xP@literal{q #1\space0 0 #2\space0 0 cm}% - \raise\U@p\hb@xt@\z@{\hskip-\L@p\boxz@\hss}% - \xP@literal{Q}% + \lower\U@p\hbox{\xP@cm{#1}00{#2}% + {\raise\U@p\hb@xt@\z@{\hskip-\L@p\boxz@\hss}}% }% }% + \global\let\xP@lastpattern\empty } % \end{macrocode} % \end{macro} % \begin{macro}{\xP@rotate} % Rotation in the direction "#1". % \begin{macrocode} -\newcommand\xP@rotate{% - \xP@rotate@\xP@trigfromdir -} +\newcommand\xP@rotate{\xP@rotate@\xP@trigfromdir} % \end{macrocode} % \end{macro} % \begin{macro}{\xP@specialrotate} % Rotation by the angle in "#1". % \begin{macrocode} \@ifdefinable\xP@specialrotate\relax -\def\xP@specialrotate#1@@{\xP@rotate@\xP@trig{#1\p@}} +\def\xP@specialrotate#1@@{\xP@rotate@\xP@trig{#1pt}} % \end{macrocode} % \end{macro} % \begin{macro}{\xP@rotate@} @@ -994,17 +1206,12 @@ #1{#2}% \hskip\L@p \hskip-\R@p - \lower\U@p\hbox{% - \xP@literal{q % - \cosDirection\space - \sinDirection\space - \if-\sinDirection\else-\sinDirection\fi\space - \cosDirection\space - 0 0 cm}% - \raise\U@p\hb@xt@\z@{\hskip-\L@p\boxz@\hss}% - \xP@literal{Q}% + \lower\U@p\hbox{\xP@cm\cosDirection\sinDirection + {\if-\sinDirection\else-\sinDirection\fi}\cosDirection + {\raise\U@p\hb@xt@\z@{\hskip-\L@p\boxz@\hss}}% }% }% + \global\let\xP@lastpattern\empty } % \end{macrocode} % \end{macro} @@ -1033,9 +1240,15 @@ % \begin{macrocode} \newcommand*\xP@trigfromdir[1]{{% \Direction#1\relax +% \end{macrocode} +% "\Direction" mod 2048 +% \begin{macrocode} \count@-\Direction \advance\count@4096 \divide\count@2048 +% \end{macrocode} +% Assign the slope in the right way. +% \begin{macrocode} \ifcase\count@ \d@X\K@\p@ \d@Y\numexpr\Direction-3*\K@\relax\p@ @@ -1053,6 +1266,9 @@ {Feel free to contact the author of the xypdf package with a minimal % example.}% \fi +% \end{macrocode} +% Bring the pair $("\d@X","\d@Y")$ to norm 1. +% \begin{macrocode} \xP@veclen \xdef\@gtempa{% \def\noexpand\cosDirection{\xP@EARPT\dimexpr\d@X*\p@/\@tempdimb\relax}% @@ -1067,6 +1283,9 @@ % \begin{macrocode} \newcommand*\xP@trig[1]{% \@tempdima\dimexpr#1\relax +% \end{macrocode} +% Translate the argument into the interval $[0\mathrm{pt},360\mathrm{pt}]$. +% \begin{macrocode} \@tempdimb\@tempdima % \end{macrocode} % $23592960=360\cdot65536$ @@ -1079,6 +1298,9 @@ % $5898240=90\cdot65536$ % \begin{macrocode} \divide\@tempdimb5898240 +% \end{macrocode} +% It's enough to know sin between 0\textdegree{} and 90\textdegree{}. The cos and the values in the other quadrants can be derived from that. +% \begin{macrocode} \ifcase\@tempdimb \xP@sinpoly \edef\sinDirection{\xP@EARPT\@tempdimb}% @@ -1175,44 +1397,44 @@ % >{\color{varcolG}}l@{}} % \Xy-pic var.&Set 1 &~~~Set 2 &Set 3 &~~~Set 4 &Set 5 &Set 6 &~~~Set 7\\ % \midrule -% "\quotPTK@"&"\xP@bigdim" \\ -% "\L@p" &&"\xP@parA" &"\xP@A" & &("\L@p") & &("\L@p") \\ -% "\U@p" &&"\xP@velA" &"\xP@B" & &("\U@p") & &("\U@p") \\ -% "\R@p" &&"\xP@parB" &"\xP@C" & &("\R@p") & &("\R@p") \\ -% "\D@p" &&"\xP@velB" &"\xP@D" & &("\D@p") & &("\D@p") \\ -% "\X@origin"&&"\xP@parC" &"\xP@E" & & & &"\xP@temppar" \\ -% "\Y@origin"&&"\xP@velC" &"\xP@F" & & & &"\xP@tempvel" \\ -% "\X@xbase" &&"\xP@parD" &"\xP@G" & & & &"\xP@posX" \\ -% "\Y@xbase" &&"\xP@velD" &"\xP@H" & & & &"\xP@posY" \\ -% "\X@ybase" &&"\xP@parE" &"\xP@I" & &"\xP@a" & &"\xP@oldpar" \\ -% "\Y@ybase" &&"\xP@velE" &"\xP@J" & &"\xP@b" & &"\xP@lastpar" \\ -% "\X@min" &&"\xP@lenA" &"\xP@K" & &"\xP@c" & &"\xP@tempvel@"\\ -% "\Y@min" &&"\xP@lenB" &"\xP@L" & &"\xP@valA" \\ -% "\X@max" &&"\xP@partlen" &"\xP@fa" & &"\xP@valB" \\ -% "\Y@max" &&"\xP@oldpartlen"&"\xP@fd" & &"\xP@devA" \\ -% "\almostz@"&&"\xP@tolerance" &"\xP@tm" & &"\xP@devB" \\ -% "\K@dXdY" && &"\xP@xm" & &"\xP@ti" \\ -% "\K@dYdX" && &"\xP@ym" & &"\xP@tip" \\ -% new var.~1 && &"\xP@off"& &("\xP@off") \\ -% new var.~2 && &"\xP@ta" & \\ -% new var.~3 && &"\xP@tb" & \\ -% new var.~4 && &"\xP@tc" & \\ -% new var.~5 && &"\xP@M" & \\ -% new var.~6 && &"\xP@oldobj"& \\ -% new var.~7 && & &"\xP@Tax" & &"\xP@sa" \\ -% new var.~8 && & &"\xP@Tay" & &"\xP@sb" \\ -% new var.~9 && & &"\xP@Tdx" & &"\xP@sc" \\ -% new var.~10&& & &"\xP@Tdy" & &"\xP@Ab" \\ -% new var.~11&& & &"\xP@Tmx" & &"\xP@AAb" \\ -% new var.~12&& & &"\xP@Tmy" & &"\xP@Aba" \\ -% new var.~13&& & &"\xP@xa" &("\xP@xa")&"\xP@Abb" \\ -% new var.~14&& & &"\xP@ya" &("\xP@ya")&"\xP@Abc" \\ -% new var.~15&& & &"\xP@xb" &("\xP@xb")&"\xP@AAba" \\ -% new var.~16&& & &"\xP@yb" &("\xP@yb")&"\xP@AAbb" \\ -% new var.~17&& & &"\xP@xc" &("\xP@xc")&"\xP@AAbc" \\ -% new var.~18&& & &"\xP@yc" &("\xP@yc")&"\xP@dta" \\ -% new var.~19&& & &"\xP@xd" &("\xP@xd")&"\xP@dtb" \\ -% new var.~20&& & &"\xP@yd" &("\xP@yd")&"\xP@dtc" \\ +% "\quotPTK@"&"\xP@bigdim" \\ +% "\L@p" &&"\xP@parA" &"\xP@A" & &("\L@p") & &("\L@p") \\ +% "\U@p" &&"\xP@velA" &"\xP@B" & &("\U@p") & &("\U@p") \\ +% "\R@p" &&"\xP@parB" &"\xP@C" & &("\R@p") & &("\R@p") \\ +% "\D@p" &&"\xP@velB" &"\xP@D" & &("\D@p") & &("\D@p") \\ +% "\X@origin"&&"\xP@parC" &"\xP@E" & & & &"\xP@temppar" \\ +% "\Y@origin"&&"\xP@velC" &"\xP@F" & & & &"\xP@tempvel" \\ +% "\X@xbase" &&"\xP@parD" &"\xP@G" & & & &"\xP@posX" \\ +% "\Y@xbase" &&"\xP@velD" &"\xP@H" & & & &"\xP@posY" \\ +% "\X@ybase" &&"\xP@parE" &$"\xP@I"="\xP@a"$& &"\xP@a" & &"\xP@oldpar" \\ +% "\Y@ybase" &&"\xP@velE" &$"\xP@J"="\xP@b"$& &"\xP@b" & &"\xP@lastpar" \\ +% "\X@min" &&"\xP@lenA" &"\xP@K" & &"\xP@c" & &"\xP@tempvel@"\\ +% "\Y@min" &&"\xP@lenB" &"\xP@L" & &"\xP@valA"& &"\xP@parinc" \\ +% "\X@max" &&"\xP@partlen" &"\xP@fa" & &"\xP@valB" \\ +% "\Y@max" &&"\xP@oldpartlen"&"\xP@fd" & &"\xP@devA" \\ +% "\almostz@"&&"\xP@tolerance" &"\xP@tm" & &"\xP@devB"& &"\xP@squiglen"\\ +% "\K@dXdY" && &"\xP@xm" & &"\xP@ti" \\ +% "\K@dYdX" && &"\xP@ym" & &"\xP@tip" \\ +% new var.~1 && &"\xP@off "& &("\xP@off") \\ +% new var.~2 && &"\xP@ta" & \\ +% new var.~3 && &"\xP@tb" & \\ +% new var.~4 && &"\xP@tc" & \\ +% new var.~5 && &"\xP@M" & \\ +% new var.~6 && &"\xP@oldobj" & \\ +% new var.~7 && & &"\xP@Tax" & &"\xP@sa" \\ +% new var.~8 && & &"\xP@Tay" & &"\xP@sb" \\ +% new var.~9 && & &"\xP@Tdx" & &"\xP@sc" \\ +% new var.~10&& & &"\xP@Tdy" & &"\xP@Ab" \\ +% new var.~11&& & &"\xP@Tmx" & &"\xP@AAb" \\ +% new var.~12&& & &"\xP@Tmy" & &"\xP@Aba" \\ +% new var.~13&& & &"\xP@xa" &("\xP@xa")&"\xP@Abb" \\ +% new var.~14&& & &"\xP@ya" &("\xP@ya")&"\xP@Abc" \\ +% new var.~15&& & &"\xP@xb" &("\xP@xb")&"\xP@AAba" \\ +% new var.~16&& & &"\xP@yb" &("\xP@yb")&"\xP@AAbb" \\ +% new var.~17&& & &"\xP@xc" &("\xP@xc")&"\xP@AAbc" \\ +% new var.~18&& & &"\xP@yc" &("\xP@yc")&"\xP@dta" \\ +% new var.~19&& & &"\xP@xd" &("\xP@xd")&"\xP@dtb" \\ +% new var.~20&& & &"\xP@yd" &("\xP@yd")&"\xP@dtc" \\ % \end{tabular*} % \caption{Temporary dimension registers in \textsf{xypdf}.} % \end{figure} @@ -1244,8 +1466,6 @@ % \begin{macro}{\xP@lenA} % \begin{macro}{\xP@lenB} % \begin{macro}{\xP@partlen} -% \begin{macro}{\xP@oldpartlen} -% \begin{macro}{\xP@tolerance} % \BulletB\ Second set of temporary variables: for the arc length algorithm. % \begin{macrocode} \xP@tempvar\xP@parA\L@p @@ -1261,8 +1481,6 @@ \xP@tempvar\xP@lenA\X@min \xP@tempvar\xP@lenB\Y@min \xP@tempvar\xP@partlen\X@max -\xP@tempvar\xP@oldpartlen\Y@max -\xP@tempvar\xP@tolerance\almostz@ % \end{macrocode} % \end{macro} % \end{macro} @@ -1277,6 +1495,13 @@ % \end{macro} % \end{macro} % \end{macro} +% \begin{macro}{\xP@oldpartlen} +% \begin{macro}{\xP@tolerance} +% \BulletB +% \begin{macrocode} +\xP@tempvar\xP@oldpartlen\Y@max +\xP@tempvar\xP@tolerance\almostz@ +% \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\xP@A} @@ -1287,26 +1512,6 @@ % \begin{macro}{\xP@F} % \begin{macro}{\xP@G} % \begin{macro}{\xP@H} -% \BulletC\ -% Third set of temporary registers: Bézier offset algorithm ans solving linear equations. -% \begin{macrocode} -\xP@tempvar\xP@A\L@p -\xP@tempvar\xP@B\U@p -\xP@tempvar\xP@C\R@p -\xP@tempvar\xP@D\D@p -\xP@tempvar\xP@E\X@origin -\xP@tempvar\xP@F\Y@origin -\xP@tempvar\xP@G\X@xbase -\xP@tempvar\xP@H\Y@xbase -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % \begin{macro}{\xP@I} % \begin{macro}{\xP@J} % \begin{macro}{\xP@K} @@ -1317,7 +1522,16 @@ % \begin{macro}{\xP@xm} % \begin{macro}{\xP@ym} % \BulletC\ +% Third set of temporary registers: Bézier offset algorithm ans solving linear equations. % \begin{macrocode} +\xP@tempvar\xP@A\L@p +\xP@tempvar\xP@B\U@p +\xP@tempvar\xP@C\R@p +\xP@tempvar\xP@D\D@p +\xP@tempvar\xP@E\X@origin +\xP@tempvar\xP@F\Y@origin +\xP@tempvar\xP@G\X@xbase +\xP@tempvar\xP@H\Y@xbase \xP@tempvar\xP@I\X@ybase \xP@tempvar\xP@J\Y@ybase \xP@tempvar\xP@K\X@min @@ -1337,6 +1551,14 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % \begin{macro}{\xP@off} % \begin{macro}{\xP@ta} % \begin{macro}{\xP@tb} @@ -1444,8 +1666,11 @@ % \begin{macro}{\xP@AAba} % \begin{macro}{\xP@AAbb} % \begin{macro}{\xP@AAbc} +% \begin{macro}{\xP@dta} +% \begin{macro}{\xP@dtb} +% \begin{macro}{\xP@dtc} % \BulletF\ -% Sixth set of temporary variables: Solving a linear system approximately. +% Sixth set of temporary variables: Solving a linear system approximately.\nopagebreak % \begin{macrocode} \xP@tempvar\xP@sa\xP@Tax \xP@tempvar\xP@sb\xP@Tay @@ -1458,6 +1683,9 @@ \xP@tempvar\xP@AAba\xP@xb \xP@tempvar\xP@AAbb\xP@yb \xP@tempvar\xP@AAbc\xP@xc +\xP@tempvar\xP@dta\xP@yc +\xP@tempvar\xP@dtb\xP@xd +\xP@tempvar\xP@dtc\xP@yd % \end{macrocode} % \end{macro} % \end{macro} @@ -1470,15 +1698,6 @@ % \end{macro} % \end{macro} % \end{macro} -% \begin{macro}{\xP@dta} -% \begin{macro}{\xP@dtb} -% \begin{macro}{\xP@dtc} -% \BulletF\ -% \begin{macrocode} -\xP@tempvar\xP@dta\xP@yc -\xP@tempvar\xP@dtb\xP@xd -\xP@tempvar\xP@dtc\xP@yd -% \end{macrocode} % \end{macro} % \end{macro} % \end{macro} @@ -1489,6 +1708,8 @@ % \begin{macro}{\xP@oldpar} % \begin{macro}{\xP@lastpar} % \begin{macro}{\xP@tempvel@} +% \begin{macro}{\xP@parinc} +% \begin{macro}{\xP@squiglen} % \BulletG\ % Seventh set of temporary registers: For multiple dotted splines. % \begin{macrocode} @@ -1499,6 +1720,8 @@ \xP@tempvar\xP@oldpar\X@ybase \xP@tempvar\xP@lastpar\Y@ybase \xP@tempvar\xP@tempvel@\X@min +\xP@tempvar\xP@parinc\Y@min +\xP@tempvar\xP@squiglen\almostz@ % \end{macrocode} % \end{macro} % \end{macro} @@ -1507,6 +1730,8 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} % \begin{macro}{\xP@scaleone} % \begin{macro}{\xP@scaletwo} % \begin{macro}{\xP@scalethree} @@ -1525,7 +1750,7 @@ % \begin{macro}{\splinesolid@} % \begin{macro}{\splinedashed@} % \begin{macro}{\splinedotted@} -% These are the hooks for splines (solid, dashed and dotted). +% These are the hooks for single-stroke splines (solid, dashed and dotted). % \begin{macrocode} \xP@hook{splinesolid@} \newcommand*\xP@splinesolid@{\xP@spline\xP@setsolidpat} @@ -1542,12 +1767,28 @@ % \begin{macrocode} \newcommand*\xP@spline[1]{% \readsplineparams@ +% \end{macrocode} +% Neglect splines which are drawn “backwards”. Somehow \Xy-pic draws curves forward and backward, but we need it to be drawn only once. +% \begin{macrocode} \ifdim\dimen5<\dimen7 \xP@preparespline +% \end{macrocode} +% Neglect splines of length zero. +% \begin{macrocode} \ifdim\@tempdimb>\z@ +% \end{macrocode} +% Set the dash pattern. +% \begin{macrocode} #1% +% \end{macrocode} +% Draw the spline. +% \begin{macrocode} \xP@stroke{\xP@coor\X@p\Y@p m % \xP@coor\L@c\U@c\xP@coor\R@c\D@c\xP@coor\X@c\Y@c c}% +% \end{macrocode} +% Record the end point for pattern continuation. +% \begin{macrocode} + \xP@savec \fi \fi } @@ -1565,7 +1806,13 @@ \R@c\dimexpr(\X@c+2\A@)/3\relax \D@c\dimexpr(\Y@c+2\B@)/3\relax \fi +% \end{macrocode} +% Cut the spline according to that start and end parameters in "\dimen5" and "\dimen7". +% \begin{macrocode} \xP@shavespline +% \end{macrocode} +% Determine the spline length (for the pattern generation; unnecessary for solid splines). +% \begin{macrocode} \xP@bezierlength } % \end{macrocode} @@ -1594,6 +1841,9 @@ \xP@inibigdim \A@\dimexpr#1\relax \B@\dimexpr#2\relax +% \end{macrocode} +% Shortcut in case the spline is not changed. +% \begin{macrocode} \@tempswatrue \ifdim\A@=\z@\ifdim\B@=\xP@bigdim\@tempswafalse\fi\fi \if@tempswa @@ -1632,7 +1882,7 @@ % \end{macrocode} % \end{macro} % \begin{macro}{\xP@bezierlength} -% \BulletB\ +% \BulletA\ \BulletB\ % Compute the arc length of a cubic Bézier segment. % % The following algorithm is used: The velocity for a partial segment is fitted at @@ -1648,24 +1898,25 @@ % The result goes into "\@tempdimb". % \begin{macrocode} \newcommand*\xP@bezierlength{{% + \xP@inibigdim \@tempdimb\z@ \xP@parA\z@ \xP@velocity\z@\xP@velA - \xP@parC.5\p@ + \xP@parC.5\xP@bigdim \xP@velocity\xP@parC\xP@velC - \xP@velocity\p@\xP@velE + \xP@velocity\xP@bigdim\xP@velE % \end{macrocode} % Arc length (integral over the quadratic approximation) % \begin{macrocode} \xP@oldpartlen\dimexpr(\xP@velA+4\xP@velC+\xP@velE)/6\relax % \end{macrocode} -% Tolerance parameter: It is set to $1/65536$ of the approximate arc length, but at least $1\mathrm{sp}$ (e.\,g.\ for closed arcs). +% Tolerance parameter: It is set to $1/100000$ of the approximate arc length, but at least $1\mathrm{sp}$. % \begin{macrocode} - \xP@tolerance\xP@max{1sp}{\dimexpr\xP@oldpartlen/\p@\relax}% + \xP@tolerance\xP@max{1sp}{\dimexpr\xP@oldpartlen/100000\relax}% % \end{macrocode} % Initiate the recursive algorithm with the interval $[0, 1]$. % \begin{macrocode} - \xP@arclength\xP@parC\xP@velC\p@\xP@velE\xP@oldpartlen + \xP@arclength\xP@parC\xP@velC\xP@bigdim\xP@velE\xP@oldpartlen % \end{macrocode} % Pass the result to outside the group. % \begin{macrocode} @@ -1675,7 +1926,7 @@ % \end{macrocode} % \end{macro} % \begin{macro}{\xP@velocity} -% \BulletE\ +% \BulletA\ % Compute the velocity at the point "#1" on a cubic Bézier curve. % Needs: Bézier control points "\X@p",\ldots,"\Y@c". % Parameter "#2": dimension register for the result. @@ -1683,66 +1934,59 @@ % \begin{macrocode} \newcommand*\xP@velocity[2]{{% \@tempdima\dimexpr#1\relax - \xP@velocity@ + \xP@tangent \global\dimen@i\@tempdimb }#2\dimen@i } % \end{macrocode} % \end{macro} -% \begin{macro}{\xP@velocity@} -% \BulletE\ -% \begin{macrocode} -\newcommand*\xP@velocity@{% - \L@p\dimexpr\L@c-\X@p\relax - \U@p\dimexpr\U@c-\Y@p\relax - \d@X3\dimexpr((\X@c+(\L@c-\R@c)*3-\X@p)*\@tempdima/\p@ - +(\R@c-\L@p-\L@c)*2)*\@tempdima/\p@+\L@p\relax - \d@Y3\dimexpr((\Y@c+(\U@c-\D@c)*3-\Y@p)*\@tempdima/\p@ - +(\D@c-\U@p-\U@c)*2)*\@tempdima/\p@+\U@p\relax - \xP@veclen -} -% \end{macrocode} -% \end{macro} -% \begin{macro}{\xP@velocity@@} -% \BulletE +% \begin{macro}{\xP@tangent} +% \BulletA\ % \begin{macrocode} -\newcommand*\xP@velocity@@{% - \R@p\dimexpr\xP@xb-\xP@xa\relax - \D@p\dimexpr\xP@yb-\xP@ya\relax - \d@X3\dimexpr((\xP@xd+(\xP@xb-\xP@xc)*3-\xP@xa)*\@tempdima/\p@ - +(\xP@xc-\R@p-\xP@xb)*2)*\@tempdima/\p@+\R@p\relax - \d@Y3\dimexpr((\xP@yd+(\xP@yb-\xP@yc)*3-\xP@ya)*\@tempdima/\p@ - +(\xP@yc-\D@p-\xP@yb)*2)*\@tempdima/\p@+\D@p\relax +\newcommand*\xP@tangent{% + \d@X3\xP@precbeziertan\X@p\L@c\R@c\X@c\@tempdima + \d@Y3\xP@precbeziertan\Y@p\U@c\D@c\Y@c\@tempdima \xP@veclen } % \end{macrocode} % \end{macro} -% \begin{macro}{\xP@normalvec} -% \BulletE\ -% Normal vector on a Bézier curve. Parameter: Parameter on segment, normal distance. -% Needs: Bézier parameters "\X@p",\ldots,"\Y@c" +% \begin{macro}{\xP@tangentvec} +% \BulletA\ +% Tangent vector on a Bézier curve. Parameter "#1": Parameter on the segment. +% Needs: Bézier parameters "\X@p",\ldots,"\Y@c". Returns: vector in $("\d@X","\d@Y")$, norm in "\@tempdimb". % \begin{macrocode} -\newcommand*\xP@normalvec[2]{{% +\newcommand*\xP@tangentvec[1]{{% \@tempdima#1\relax - \@tempdimc#2\relax - \xP@velocity@ + \xP@tangent % \end{macrocode} -% If the velocity is zero at some point, take the third derivative for the tangent vector. +% If the velocity is zero at some point, take the second derivative for the tangent vector. % \begin{macrocode} \ifdim\@tempdimb=\z@ - \d@X\dimexpr\xP@xd+(\xP@xb-\xP@xc)*3-\xP@xa\relax - \d@Y\dimexpr\xP@yd+(\xP@yb-\xP@yc)*3-\xP@ya\relax + \L@p\dimexpr\X@c-\X@p+(\L@c-\R@c)*3\relax + \U@p\dimexpr\Y@c-\Y@p+(\U@c-\D@c)*3\relax + \d@X\dimexpr\L@p*\@tempdima/\xP@bigdim+(\X@p-2\L@c+\R@c)\relax + \d@Y\dimexpr\U@p*\@tempdima/\xP@bigdim+(\Y@p-2\U@c+\D@c)\relax \xP@veclen +% \end{macrocode} +% Or even the third derivative. +% \begin{macrocode} \ifdim\@tempdimb=\z@ - \PackageError{xypdf}{Cannot determine a tangent vector to a curve}{}% - \@tempdimb\p@ + \d@X\L@p + \d@Y\U@p + \xP@veclen + \ifdim\@tempdimb=\z@ + \PackageWarning{xypdf}{Cannot determine a tangent vector to a curve}% + \@tempdimb\p@ + \fi \fi \fi - \global\dimen@i\dimexpr\@tempdimc*\d@Y/\@tempdimb\relax - \global\dimen3\dimexpr-\@tempdimc*\d@X/\@tempdimb\relax + \global\dimen@i\d@X + \global\dimen3\d@Y + \global\dimen5\@tempdimb }% \d@X\dimen@i \d@Y\dimen3\relax + \@tempdimb\dimen5\relax } % \end{macrocode} % \end{macro} @@ -1769,9 +2013,9 @@ % Compute the approximations for the arc length on the two smaller parameter intervals (A-B-C) and (C-D-E). % \begin{macrocode} \xP@lenA - \dimexpr(\xP@velA+4\xP@velB+\xP@velC)*(\xP@parC-\xP@parA)/393216\relax + \dimexpr(\xP@velA+4\xP@velB+\xP@velC)/6*(\xP@parC-\xP@parA)/\xP@bigdim\relax \xP@lenB - \dimexpr(\xP@velC+4\xP@velD+\xP@velE)*(\xP@parE-\xP@parC)/393216\relax + \dimexpr(\xP@velC+4\xP@velD+\xP@velE)/6*(\xP@parE-\xP@parC)/\xP@bigdim\relax \xP@partlen\dimexpr\xP@lenA+\xP@lenB\relax % \end{macrocode} % Check whether the approximation for the arc length has changed more than the precision parameter. @@ -1930,6 +2174,10 @@ \else \DN@{ \dir{--}}\ifx\next@\xycrvconn@ \DN@{\splinedashed@}% \else \DN@{ \dir{.}}\ifx\next@\xycrvconn@ \DN@{\splinedotted@}% \else \DN@{ \dir{:}}\ifx\next@\xycrvconn@ \DN@{\splinedbldotted@}% +% \end{macrocode} +% The next line does not occur in \Xy-pic for an unknown reason. However, it seems reasonable to define the special pattern "\dir2{.}" in the same way as for straight lines. +% \begin{macrocode} + \else \DN@{ \dir2{.}}\ifx\next@\xycrvconn@ \DN@{\splinedbldotted@}% \else \DN@{ \dir3{.}}\ifx\next@\xycrvconn@ \DN@{\xP@splinetrbldotted}% \else \DN@{ \dir2{--}}\ifx\next@\xycrvconn@ \DN@{\xP@splinedbldashed}% \else \DN@{ \dir3{--}}\ifx\next@\xycrvconn@ \DN@{\xP@splinetrbldashed}% @@ -1937,7 +2185,7 @@ \else \DN@{ \dir2{~}}\ifx\next@\xycrvconn@ \DN@{\xP@splinedblsquiggled}% \else \DN@{ \dir3{~}}\ifx\next@\xycrvconn@ \DN@{\xP@splinetrblsquiggled}% \else \ifdim\splinetol@>\z@ \else \splinedefaulttol@ \fi - \DN@{\splineset@@}\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \DN@{\splineset@@}\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \else \DN@{\splineset@@}% \fi \ifInvisible@\DN@{}\fi \next@ } @@ -1995,9 +2243,9 @@ % \begin{macrocode} \ifdim\@tempdimb>\z@ % \end{macrocode} -% If the path length is less than the line width, just draw a solid path. +% If the path length is less than twice the line width, just draw a solid path. % \begin{macrocode} - \ifdim\@tempdimb<\xP@lw bp + \ifdim\@tempdimb<2\dimexpr\xP@preclw\relax \let\next@\xP@splinemultsolid \else \let\next@#1% @@ -2015,13 +2263,17 @@ \xP@inibigdim \@temptokena{}% \xP@setsolidpat +% \end{macrocode} +% The "\@for" loop does the multiple strokes. "\@tempa" records the respective offset distance. +% \begin{macrocode} \@for\@tempa:={#1}\do{\xP@paintsolid\z@\xP@bigdim}% \xP@stroke{\the\@temptokena}% }} % \end{macrocode} % \end{macro} % \begin{macro}{\xP@paintsolid} -% \BulletA\ \BulletE +% \BulletA\ \BulletE\ +% Draw a solid spline in the parameter interval $["#1","#2"]\subseteq[0\mathrm{pt},"\xP@bigdim"]$ with a certain offset. The offset distance is expected in "\@tempa". % \begin{macrocode} \newcommand*\xP@paintsolid[2]{{% % \end{macrocode} @@ -2059,11 +2311,7 @@ % \begin{macrocode} \xP@restorepts % \end{macrocode} -% Cut out the current portion of the spline. -% \begin{macrocode} - \xP@shaveprec\xP@a\xP@b -% \end{macrocode} -% Compute the approximate offset curve. +% Compute the approximate offset curve. Note that "\xP@a" and "\xP@b" contain the boundary parameters for the partial spline. % \begin{macrocode} \xP@offsetsegment % \end{macrocode} @@ -2097,6 +2345,9 @@ % \begin{macro}{\ifxP@moveto} % We need a PDF "moveto" operator only for the first partial segment. Additional segments connect seamlessly. % \begin{macrocode} +\@ifdefinable\ifxP@moveto\relax +\@ifdefinable\xP@movetotrue\relax +\@ifdefinable\xP@movetofalse\relax \newif\ifxP@moveto % \end{macrocode} % \end{macro} @@ -2232,86 +2483,119 @@ % \end{macrocode} % \end{macro} % \begin{macro}{\xP@offsetsegment} -% \BulletA\ \BulletC\ \BulletD\ Offset a cubic segment. The offset distance is given in "\xP@off". The anchor points are given in "\X@p",\ldots,"\Y@c". The new Bézier curve is returned in "\xP@xa",\ldots,"\xP@yd". +% \BulletA\ \BulletC\ \BulletD\ Offset a cubic segment. The offset distance is given in "\xP@off". The anchor points are given in "\X@p",\ldots,"\Y@c". The partial spline in the parameter interval $["\xP@a","\xP@b"]\subseteq[0\mathrm{pt},"\xP@bigdim"]$ is offset. The new Bézier curve is returned in "\xP@xa",\ldots,"\xP@yd". % \begin{macrocode} \newcommand*\xP@offsetsegment{{% % \end{macrocode} -% Initial guesses for the tangent vector scalings "\xP@fa", "\xP@fd" and the near-middle position "\xP@tm" +% New first anchor point and tangent vector at $0$ % \begin{macrocode} - \xP@fa\p@ - \xP@fd\p@ - \xP@tm\p@ + \xP@tangentvec\xP@a + \xP@xa\dimexpr\xP@precbezierpoly\X@p\L@c\R@c\X@c\xP@a/8% + +\d@Y*\xP@off/\@tempdimb\relax + \xP@ya\dimexpr\xP@precbezierpoly\Y@p\U@c\D@c\Y@c\xP@a/8% + -\d@X*\xP@off/\@tempdimb\relax + \xP@scaleT + \xP@Tax\d@X + \xP@Tay\d@Y + \xP@E\@tempdimb % \end{macrocode} -% 8 times (middle point plus offset) +% New last anchor point and tangent vector at $1$ % \begin{macrocode} - \xP@normalvec{.5pt}\xP@off - \xP@xm\dimexpr(\X@p+\X@c+(\L@c+\R@c)*3)+8\d@X\relax - \xP@ym\dimexpr(\Y@p+\Y@c+(\U@c+\D@c)*3)+8\d@Y\relax + \xP@tangentvec\xP@b + \xP@xd\dimexpr\xP@precbezierpoly\X@p\L@c\R@c\X@c\xP@b/8% + +\d@Y*\xP@off/\@tempdimb\relax + \xP@yd\dimexpr\xP@precbezierpoly\Y@p\U@c\D@c\Y@c\xP@b/8% + -\d@X*\xP@off/\@tempdimb\relax + \xP@scaleT + \xP@Tdx-\d@X + \xP@Tdy-\d@Y + \xP@F\@tempdimb % \end{macrocode} -% New first anchor point +% Scalar product of the tangent vectors % \begin{macrocode} - \xP@normalvec\z@\xP@off - \xP@xa\dimexpr\X@p+\d@X\relax - \xP@ya\dimexpr\Y@p+\d@Y\relax + \xP@M\z@ + \xP@Max\xP@M\xP@Tdx + \xP@Max\xP@M\xP@Tdy + \xP@L\dimexpr\xP@Tax*\xP@Tdx/\xP@M+\xP@Tay*\xP@Tdy/\xP@M\relax + \xP@tm\dimexpr(\xP@a+\xP@b)/2\relax + \ifdim\xP@L>\dimexpr\xP@E*\xP@F/\xP@M*49/50\relax % \end{macrocode} -% New last anchor point +% Trick to improve the offset algorithm near sharp bends and cusps: If the tangent vectors $(T_{ax},T_{ay})$ and $(T_{dx},T_{dy})$ point nearly in the same direction, we do not use the true tangent vector for $(T_{mx},T_{my})$ at the middle point but a fake one. (The exact condition is that their normed scalar product is greater that $49/50$. For a straight line, the vectors would point in opposite directions.) The fake tangent vector is defined to be $(T_{ax}+T_{dx},T_{ay}+T_{dy})$ rotated by $\pm 90\textrm{\textdegree}$. Its direction is chosen such that the scalar product with $(X_d-X_a, Y_d-Y_a)$ is nonnegative. (Use $(X_c-X_b, Y_c-Y_b)$ in the degenerate case $(X_d-X_a, Y_d-Y_a)=(0,0)$.) +% +% Rationale: In the presence of a sharp bend or cusp, the offset algorithm will hardly meet the tip. Since the tangent/normal at the tip is needed for a good offset curve, we provide this artificially. % \begin{macrocode} - \xP@normalvec\p@\xP@off - \xP@xd\dimexpr\X@c+\d@X\relax - \xP@yd\dimexpr\Y@c+\d@Y\relax + \d@X-\dimexpr\xP@Tay+\xP@Tdy\relax + \d@Y\dimexpr\xP@Tax+\xP@Tdx\relax + \xP@veclen + \xP@A\dimexpr\X@c-\X@p\relax + \xP@B\dimexpr\Y@c-\Y@p\relax + \xP@M\z@ + \xP@Max\xP@M\xP@A + \xP@Max\xP@M\xP@B + \ifdim\xP@M=\z@ + \xP@A\dimexpr\R@c-\L@c\relax + \xP@B\dimexpr\D@c-\U@c\relax + \xP@Max\xP@M\xP@A + \xP@Max\xP@M\xP@B + \fi + \xP@M\dimexpr\d@X*\xP@A/\xP@M+\d@Y*\xP@B/\xP@M\relax + \ifdim\xP@M<\z@ + \multiply\d@X\m@ne + \multiply\d@Y\m@ne + \fi + \else % \end{macrocode} -% Tangent vector at $0$. This also handles degenerate cases. +% Normal case: tangent vector at the middle point. % \begin{macrocode} - \xP@Tax\dimexpr\L@c-\X@p\relax - \xP@Tay\dimexpr\U@c-\Y@p\relax - \ifdim\xP@Tax=\z@ - \ifdim\xP@Tay=\z@ - \xP@Tax\dimexpr\R@c-\X@p\relax - \xP@Tay\dimexpr\D@c-\Y@p\relax - \ifdim\xP@Tax=\z@ - \ifdim\xP@Tay=\z@ - \xP@Tax\dimexpr\X@c-\X@p\relax - \xP@Tay\dimexpr\Y@c-\Y@p\relax - \fi - \fi - \fi + \xP@tangentvec\xP@tm \fi - \multiply\xP@Tax\thr@@ - \multiply\xP@Tay\thr@@ -% \end{macrocode} -% Tangent vector at $1$. -% \begin{macrocode} - \xP@Tdx\dimexpr\R@c-\X@c\relax - \xP@Tdy\dimexpr\D@c-\Y@c\relax - \ifdim\xP@Tdx=\z@ - \ifdim\xP@Tdy=\z@ - \xP@Tdx\dimexpr\L@c-\X@c\relax - \xP@Tdy\dimexpr\U@c-\Y@c\relax - \ifdim\xP@Tdx=\z@ - \ifdim\xP@Tdy=\z@ - \xP@Tdx\dimexpr\X@p-\X@c\relax - \xP@Tdy\dimexpr\Y@p-\Y@c\relax - \fi - \fi +% \end{macrocode} +% From here on, "\xP@a" and "\xP@b" will not be used any more, so these variables can be used under their other names "\xP@I", "\xP@J" for the linear systems below. +% +% 8 times (middle point plus offset) +% \begin{macrocode} + \xP@xm\dimexpr\xP@precbezierpoly\X@p\L@c\R@c\X@c\xP@tm + +8\d@Y*\xP@off/\@tempdimb\relax + \xP@ym\dimexpr\xP@precbezierpoly\Y@p\U@c\D@c\Y@c\xP@tm + -8\d@X*\xP@off/\@tempdimb\relax +% \end{macrocode} +% Tangent at middle point +% \begin{macrocode} + \xP@Tmx\d@X + \xP@Tmy\d@Y + \xP@ifabsless\xP@Tmy\xP@Tmx + \let\xP@tmy\xP@Tmyx + \let\xP@tmx\empty + \else + \ifdim\xP@Tmy=\z@ + \let\xP@tmx\xP@Tmzero + \let\xP@tmy\xP@Tmzero + \else + \let\xP@tmy\empty + \let\xP@tmx\xP@Tmxy \fi \fi - \multiply\xP@Tdx\thr@@ - \multiply\xP@Tdy\thr@@ +% \end{macrocode} +% Initial guesses for the tangent vector scalings "\xP@fa", "\xP@fd" and the near-middle position "\xP@tm" +% \begin{macrocode} + \xP@fa\p@ + \xP@fd\p@ + \xP@tm\p@ % \end{macrocode} % The main loop for finding the offset curve % \begin{macrocode} \count@\z@ \loop +% \end{macrocode} +% Set the new control points up. +% \begin{macrocode} + \xP@offsetpoints \@tempswafalse % \end{macrocode} % At most $10$ iterations % \begin{macrocode} \ifnum10>\count@ % \end{macrocode} -% Set the new control points up. -% \begin{macrocode} - \xP@offsetpoints -% \end{macrocode} % Determine the quality of the approximation by an objective function. % \begin{macrocode} \xP@objfun\xP@oldobj @@ -2331,6 +2615,25 @@ } % \end{macrocode} % \end{macro} +% \begin{macro}{\xP@scaleT} +% \BulletA\ \BulletC\ \BulletD\ +% This macro contains another trick to improve the offset algorithm around sharp bends and cusps. It adjusts the length of the tangent/velocity vectors. Let $("\d@X","\d@Y")$ be the velocity vector to the original curve at some point with velocity $v_0$. The velocity at the same point, considered on a partial segment scales linearly with the length of the parameter interval. Hence, the velocity $v_1$ in the partial segment is $v_1=v_0\cdot("\xP@b"-"\xP@a")/"\xP@bigdim"$. Additionally the offset curve goes with a radius of $r+"\xP@off"$ around bends with radius $r$ in the original curve. As an approximation to the velocity in the offset curve, we therefore scale the velocity vector in the end to the norm $v_1 + 2\pi\cdot|"\xP@off"|$. +% \begin{macrocode} +\newcommand*\xP@scaleT{% + \xP@B6.28\xP@off + \xP@abs\xP@B + \xP@C\dimexpr\d@X*\xP@B/\@tempdimb\relax + \xP@D\dimexpr\d@Y*\xP@B/\@tempdimb\relax + \xP@A\dimexpr\xP@b-\xP@a\relax + \d@X\dimexpr\xP@C+\d@X*\xP@A/\xP@bigdim\relax + \d@Y\dimexpr\xP@D+\d@Y*\xP@A/\xP@bigdim\relax +% \end{macrocode} +% Also record the change to the norm of the vector. +% \begin{macrocode} + \@tempdimb\dimexpr\xP@B+\@tempdimb*\xP@A/\xP@bigdim\relax +} +% \end{macrocode} +% \end{macro} % \begin{macro}{\xP@offsetloop} % \BulletA\ \BulletC\ \BulletD\ The iteration in the offset loop: set up and solve (or approximate) the linear system. % \begin{macrocode} @@ -2354,10 +2657,8 @@ % \begin{macrocode} \xP@tb\dimexpr2\p@-3\xP@tm\relax \xP@tc\dimexpr\xP@tb+2\p@\relax - \xP@I\dimexpr(2\xP@Tay\xP@tmx-2\xP@Tax\xP@tmy) - *\xP@tb/\p@*\xP@ta/\p@\relax - \xP@J\dimexpr(2\xP@Tdy\xP@tmx-2\xP@Tdx\xP@tmy) - *\xP@tc/\p@*\xP@tm/\p@\relax + \xP@I\dimexpr(2\xP@Tay\xP@tmx-2\xP@Tax\xP@tmy)*\xP@tb/\p@*\xP@ta/\p@\relax + \xP@J\dimexpr(2\xP@Tdy\xP@tmx-2\xP@Tdx\xP@tmy)*\xP@tc/\p@*\xP@tm/\p@\relax \xP@K\dimexpr((\xP@yd-\xP@ya+(\xP@yb-\xP@yc)*3) *\xP@tm/\p@+(\xP@yc-2\xP@yb+\xP@ya)*2)*12\xP@tmx -((\xP@xd-\xP@xa+(\xP@xb-\xP@xc)*3) @@ -2393,7 +2694,7 @@ % The near-middle parameter on the curve must not lie outside the segment. % \begin{macrocode} \ifdim\xP@tm<\z@\xP@tm\z@\fi - \ifdim\xP@tm>\tw@\p@\xP@tm\tw@\p@\fi + \ifdim\xP@tm>2\p@\xP@tm2\p@\fi \fi \advance\count@\@ne } @@ -2433,12 +2734,11 @@ % The near-middle parameter must lie on the segment. % \begin{macrocode} \ifdim\xP@tm<\z@\xP@tm\z@\fi - \ifdim\xP@tm>\tw@\p@\xP@tm\tw@\p@\fi + \ifdim\xP@tm>2\p@\xP@tm2\p@\fi % \end{macrocode} % Check whether the solution actually improves the objective function. % \begin{macrocode} - {% - \xP@offsetpoints + {\xP@offsetpoints \xP@objfun\xP@M \expandafter}% % \end{macrocode} @@ -2458,24 +2758,8 @@ % The objective function: sum of squares of the deviation in $x$- and $y$-direction and the angular deviation at the middle point. We also compute some terms which will be used in the linear system. % \begin{macrocode} \newcommand*\xP@objfun[1]{% - \xP@D\xP@bezierpoly\xP@xa\xP@xb\xP@xc\xP@xd\xP@tm - \xP@D\dimexpr\xP@D-\xP@xm\relax - \xP@H\xP@bezierpoly\xP@ya\xP@yb\xP@yc\xP@yd\xP@tm - \xP@H\dimexpr\xP@H-\xP@ym\relax - \xP@Tmx\dimexpr\X@p-\X@c+\L@c-\R@c\relax - \xP@Tmy\dimexpr\Y@p-\Y@c+\U@c-\D@c\relax - \xP@ifabsless\xP@Tmy\xP@Tmx - \let\xP@tmy\xP@Tmyx - \let\xP@tmx\empty - \else - \ifdim\xP@Tmy=\z@ - \let\xP@tmx\xP@Tmzero - \let\xP@tmy\xP@Tmzero - \else - \let\xP@tmy\empty - \let\xP@tmx\xP@Tmxy - \fi - \fi + \xP@D\dimexpr\xP@bezierpoly\xP@xa\xP@xb\xP@xc\xP@xd\xP@tm-\xP@xm\relax + \xP@H\dimexpr\xP@bezierpoly\xP@ya\xP@yb\xP@yc\xP@yd\xP@tm-\xP@ym\relax \xP@C\xP@beziertan\xP@xa\xP@xb\xP@xc\xP@xd\xP@tm \xP@G\xP@beziertan\xP@ya\xP@yb\xP@yc\xP@yd\xP@tm \xP@L\dimexpr\xP@G\xP@tmx-\xP@C\xP@tmy\relax @@ -2486,10 +2770,10 @@ \xP@Max#1\xP@D \xP@Max#1\xP@H \xP@Max#1\xP@L - \ifdim#1>4843165sp - #1\maxdimen + #1\ifdim#1>4843165sp + \maxdimen \else - #1\dimexpr\xP@D*\xP@D/\p@+\xP@H*\xP@H/\p@+\xP@L*\xP@L/\p@\relax + \dimexpr\xP@D*\xP@D/\p@+\xP@H*\xP@H/\p@+\xP@L*\xP@L/\p@\relax \fi } % \end{macrocode} @@ -2517,6 +2801,17 @@ } % \end{macrocode} % \end{macro} +% \begin{macro}{\xP@precbezierpoly} +% Formula for the polynomial $8\left( "#1"\cdot(1-t)^3 +% +3\cdot"#2"\cdot t(1-t)^2+3\cdot"#3"\cdot t^2(1-t)+"#4"\cdot t^3\right)$, +% $t="#5"/"\xP@bigdim"$. +% \begin{macrocode} +\newcommand*\xP@precbezierpoly[5]{% + \dimexpr(((#4-#1+(#2-#3)*3)*2*#5/\xP@bigdim+(#1-2#2+#3)*6)*2*#5/\xP@bigdim + +(#2-#1)*12)*2*#5/\xP@bigdim+#1*8\relax +} +% \end{macrocode} +% \end{macro} % \begin{macro}{\xP@beziertan} % Formula for the polynomial % \[ @@ -2529,6 +2824,19 @@ } % \end{macrocode} % \end{macro} +% \begin{macro}{\xP@precbeziertan} +% Formula for the polynomial +% \[ +% \left( -"#1"\cdot(1-t)^2+"#2"\cdot(3t^2 -4t+1)+"#3"\cdot(-3t^2+2t)+"#4"\cdot t^2\right),\quad t="#5"/"\xP@bigdim". +% \] +% This is $\tfrac13$ times the derivative of the third order Bézier polynomial. +% \begin{macrocode} +\newcommand*\xP@precbeziertan[5]{% + \dimexpr((#4-#1+(#2-#3)*3)*#5/\xP@bigdim+(#1-2#2+#3)*2)*#5/\xP@bigdim + +#2-#1\relax +} +% \end{macrocode} +% \end{macro} % \begin{macro}{\xP@solvelinearsystem} % \BulletC\ % The macro "\xP@solvelinearsystem" solves a system of three linear equations by the Gauss algorithm. The coefficients and desired values are passed in the extended matrix @@ -2555,6 +2863,9 @@ % \begin{macro}{\ifxP@validsol} % Records if a valid solution to the linear system is returned. % \begin{macrocode} +\@ifdefinable\ifxP@validsol\relax +\@ifdefinable\xP@validsoltrue\relax +\@ifdefinable\xP@validsolfalse\relax \newif\ifxP@validsol % \end{macrocode} % \end{macro} @@ -2629,12 +2940,15 @@ % \end{macrocode} % Absolute values below are $<8192\mathrm{pt}$. % \begin{macrocode} - \advance\xP@F\dimexpr\xP@B*\xP@E/\xP@A\relax - \advance\xP@G\dimexpr\xP@C*\xP@E/\xP@A\relax - \advance\xP@H\dimexpr\xP@D*\xP@E/\xP@A\relax - \advance\xP@J\dimexpr\xP@B*\xP@I/\xP@A\relax - \advance\xP@K\dimexpr\xP@C*\xP@I/\xP@A\relax - \advance\xP@L\dimexpr\xP@D*\xP@I/\xP@A\relax + \ifdim\xP@A=\z@ + \else + \advance\xP@F\dimexpr\xP@B*\xP@E/\xP@A\relax + \advance\xP@G\dimexpr\xP@C*\xP@E/\xP@A\relax + \advance\xP@H\dimexpr\xP@D*\xP@E/\xP@A\relax + \advance\xP@J\dimexpr\xP@B*\xP@I/\xP@A\relax + \advance\xP@K\dimexpr\xP@C*\xP@I/\xP@A\relax + \advance\xP@L\dimexpr\xP@D*\xP@I/\xP@A\relax + \fi % \end{macrocode} % Find the second pivot element. "\xP@M" is used temporarily. % \begin{macrocode} @@ -2666,8 +2980,11 @@ % \end{macrocode} % Second elimination. Absolute values are $<16384\mathrm{pt}$. % \begin{macrocode} - \advance\xP@K\dimexpr-\xP@G*\xP@J/\xP@F\relax - \advance\xP@L\dimexpr-\xP@H*\xP@J/\xP@F\relax + \ifdim\xP@F=\z@ + \else + \advance\xP@K\dimexpr-\xP@G*\xP@J/\xP@F\relax + \advance\xP@L\dimexpr-\xP@H*\xP@J/\xP@F\relax + \fi % \end{macrocode} % Compute the result from the upper triagonal form. Since the matrix can be singular, we have to ensure in every step that no overflow occurs. In general, we do not allow any solution greater than $60\mathrm{pt}$. % \begin{macrocode} @@ -2885,12 +3202,9 @@ % \end{macrocode} % Vector $A^t b$ (scaled) % \begin{macrocode} - \xP@Aba\dimexpr\xP@A*\xP@D/\xP@sa+\xP@E*\xP@H/\xP@sa - +\xP@I*\xP@L/\xP@sa\relax - \xP@Abb\dimexpr\xP@B*\xP@D/\xP@sa+\xP@F*\xP@H/\xP@sa - +\xP@J*\xP@L/\xP@sa\relax - \xP@Abc\dimexpr\xP@C*\xP@D/\xP@sa+\xP@G*\xP@H/\xP@sa - +\xP@K*\xP@L/\xP@sa\relax + \xP@Aba\dimexpr\xP@A*\xP@D/\xP@sa+\xP@E*\xP@H/\xP@sa+\xP@I*\xP@L/\xP@sa\relax + \xP@Abb\dimexpr\xP@B*\xP@D/\xP@sa+\xP@F*\xP@H/\xP@sa+\xP@J*\xP@L/\xP@sa\relax + \xP@Abc\dimexpr\xP@C*\xP@D/\xP@sa+\xP@G*\xP@H/\xP@sa+\xP@K*\xP@L/\xP@sa\relax % \end{macrocode} % Vector $AA^t b$ (scaled) % \begin{macrocode} @@ -2917,12 +3231,12 @@ \xP@AAb\z@ \else \xP@Ab\dimexpr\xP@Aba*\xP@bigdim/\xP@sc*\xP@Aba/\xP@sc - +\xP@Abb*\xP@bigdim/\xP@sc*\xP@Abb/\xP@sc - +\xP@Abc*\xP@bigdim/\xP@sc*\xP@Abc/\xP@sc + +\xP@Abb*\xP@bigdim/\xP@sc*\xP@Abb/\xP@sc + +\xP@Abc*\xP@bigdim/\xP@sc*\xP@Abc/\xP@sc \relax \xP@AAb\dimexpr\xP@AAba*\xP@bigdim/\xP@sc*\xP@AAba/\xP@sc - +\xP@AAbb*\xP@bigdim/\xP@sc*\xP@AAbb/\xP@sc - +\xP@AAbc*\xP@bigdim/\xP@sc*\xP@AAbc/\xP@sc + +\xP@AAbb*\xP@bigdim/\xP@sc*\xP@AAbb/\xP@sc + +\xP@AAbc*\xP@bigdim/\xP@sc*\xP@AAbc/\xP@sc \relax \fi % \end{macrocode} @@ -2949,19 +3263,22 @@ % \begin{macro}{\ifxP@offsetok} % Switch whether the offset curve is enough % \begin{macrocode} +\@ifdefinable\ifxP@offsetok\relax +\@ifdefinable\xP@offsetoktrue\relax +\@ifdefinable\xP@offsetokfalse\relax \newif\ifxP@offsetok % \end{macrocode} % \end{macro} % \begin{macro}{\xP@maxdev} % Maximal deviation, measured at $19$ points on the curve. The actual tolerance is $1/8$ of "\xP@maxdev". With the current value $0.1\mathrm{pt}$, the tolerance is $0.0125\mathrm{pt}$, which is about $1/32$ of the line width for the Computer Modern fonts. % \begin{macrocode} -\newcommand*\xP@maxdev{.1\p@} +\newcommand*\xP@maxdev{.1pt} % \end{macrocode} % \end{macro} % \begin{macro}{\xP@maxobjfun} % Tolerance for the objective function. Recommended value is $\tfrac12("\xP@maxdev")^2$. % \begin{macrocode} -\newcommand*\xP@maxobjfun{.005\p@} +\newcommand*\xP@maxobjfun{.005pt} % \end{macrocode} % \end{macro} % \begin{macro}{\xP@testoffset} @@ -2980,32 +3297,30 @@ % \end{macrocode} % Default values for the return statement and the loop continuation. % \begin{macrocode} - \gdef\@gtempa{\xP@offsetoktrue}% - \def\@gtempb{\ifdim\xP@ti<1.85pt}% + \gdef\xP@afteroffsetok{\xP@offsetoktrue}% + \def\xP@offsetokif{\ifdim\xP@ti<1.85pt}% \xP@ti.1pt \loop % \end{macrocode} % $"\xP@tip"=t_i$, denormalized for $c_1$ % \begin{macrocode} - \xP@tip - \dimexpr\xP@a*131072/\xP@bigdim+(\xP@b-\xP@a)*\xP@ti/\xP@bigdim\relax + \xP@tip\dimexpr\xP@a+(\xP@b-\xP@a)*\xP@ti/131072\relax % \end{macrocode} % Point on the original curve $c_1$ (scaled by $-8$) % \begin{macrocode} - \L@p-\xP@bezierpoly\xP@xa\xP@xb\xP@xc\xP@xd\xP@tip - \U@p-\xP@bezierpoly\xP@ya\xP@yb\xP@yc\xP@yd\xP@tip + \L@p-\xP@precbezierpoly\xP@xa\xP@xb\xP@xc\xP@xd\xP@tip + \U@p-\xP@precbezierpoly\xP@ya\xP@yb\xP@yc\xP@yd\xP@tip % \end{macrocode} % $8c_2(t_i)-8c_1(t_i)$ % \begin{macrocode} - \xP@valA\xP@bezierpoly\X@p\L@c\R@c\X@c\xP@ti - \advance\xP@valA\L@p - \xP@valB\xP@bezierpoly\Y@p\U@c\D@c\Y@c\xP@ti - \advance\xP@valB\U@p + \xP@valA\dimexpr\xP@bezierpoly\X@p\L@c\R@c\X@c\xP@ti+\L@p\relax + \xP@valB\dimexpr\xP@bezierpoly\Y@p\U@c\D@c\Y@c\xP@ti+\U@p\relax % \end{macrocode} % $v$ % \begin{macrocode} - \@tempdima\dimexpr\xP@tip/2\relax - \xP@velocity@@ + \d@X3\xP@precbeziertan\xP@xa\xP@xb\xP@xc\xP@xd\xP@tip + \d@Y3\xP@precbeziertan\xP@ya\xP@yb\xP@yc\xP@yd\xP@tip + \xP@veclen % \end{macrocode} % Decide if $v$ is big enough (heuristically, may be changed in the future) % \begin{macrocode} @@ -3023,9 +3338,9 @@ \@tempdima\dimexpr\xP@devA+\xP@devB\relax \else % \end{macrocode} -% If the velocity is \textit{really} too small, just pass the test. +% If the velocity is zero, just pass the test. % \begin{macrocode} - \ifdim.0005pt>\@tempdimc + \ifdim\@tempdimc=\z@ \@tempdima\z@ \else % \end{macrocode} @@ -3040,7 +3355,6 @@ \advance\@tempdima\ifdim\xP@off>\z@-\fi8\xP@off \xP@abs\@tempdima \fi -%\@tempdima\z@ \fi % \end{macrocode} % If the first condition is not fulfilled, test the second one. @@ -3065,13 +3379,23 @@ \xP@findzero }% \fi - \@gtempb + \xP@offsetokif \advance\xP@ti.1pt \repeat - \expandafter}\@gtempa + \expandafter}\xP@afteroffsetok } % \end{macrocode} % \end{macro} +% \begin{macro}{\xP@afteroffsetok} +% \begin{macrocode} +\newcommand*\xP@afteroffsetok{} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\xP@offsetokif} +% \begin{macrocode} +\newcommand*\xP@offsetokif{} +% \end{macrocode} +% \end{macro} % \begin{macro}{\xP@transformcoor} % \BulletE\ % Affine coordinate transformation. First, translate the coordinates in $("#1","#2")$ by the vector $-("\L@p","\U@p")$, then rotate by the angle between $v\coloneq("\d@X","\d@Y")$ and $(1,0)$. The register "\@tempdimb" must contain the length $\|v\|$. @@ -3090,18 +3414,18 @@ % Find the parameter $\tilde t_i$ by nested intervals/intermediate value theorem. % \begin{macrocode} \newcommand*\xP@findzero{% - \xP@setleftvalue\tw@ - \xP@setrightvalue\tw@ + \xP@setleftvalue{.05}% + \xP@setrightvalue{.05}% % \end{macrocode} % Normalize: function value ($x$-coordinate) should be nonnegative at the upper end. % \begin{macrocode} \ifdim\xP@valB<\z@\xP@reversecoeff\fi % \end{macrocode} -% If the function value at the lower end is also positive, try a smaller parameter interval $t_i\pm\frac1n$ for $n\in\{3,4,5,7,10,20\}$. Maybe we have different signs for the $x$-coordinate for the smaller boundary parameters. +% If the function value at the lower end is also positive, try a smaller parameter interval $t_i\pm\delta\,\mathrm{pt}$ for $\delta\in\{.5,.35,.25,.2,.15,.1,.05\}$. Maybe we have different signs for the $x$-coordinate for the larger boundary parameters. % \begin{macrocode} \ifdim\xP@valA>\z@ \@tempswatrue - \@for\@tempa:={\thr@@,4,5,7,10,20}\do{% + \@for\@tempa:={.1,.15,.2,.25,.35,.5,1.1}\do{% \if@tempswa \xP@setleftvalue\@tempa \ifdim\xP@valA<\z@\@tempswafalse\fi @@ -3119,8 +3443,16 @@ % \begin{macrocode} \if@tempswa \L@p\xP@ti - \xP@valA\dimexpr\xP@bezierpoly\X@p\L@c\R@c\X@c\L@p\relax - \ifdim\xP@valA>\z@ + \xP@valA\xP@bezierpoly\X@p\L@c\R@c\X@c\L@p +% \end{macrocode} +% If the midpoint leads to a negative value, we can proceed with a small interval. Otherwise, set both boundary points to the midpoint and effectively skip nested intervals. +% \begin{macrocode} + \ifdim\xP@valA<\z@ +% \end{macrocode} +% We had this before, so we know that the value is positive. +% \begin{macrocode} + \xP@setrightvalue{.05}% + \else \U@p\L@p \xP@valB\xP@valA \fi @@ -3142,7 +3474,7 @@ \fi \repeat % \end{macrocode} -% Take the left or right boundary point (onyl $1\mathrm{sp}$ apart), depending on which one yields the smaller $x$-coordinate. +% Take the left or right boundary point (only $1\mathrm{sp}$ apart), depending on which one yields the smaller $x$-coordinate. % \begin{macrocode} \xP@ifabsless\xP@valB\xP@valA \L@p\U@p @@ -3154,7 +3486,7 @@ \xP@valB\dimexpr\xP@bezierpoly\Y@p\U@c\D@c\Y@c\L@p+8\xP@off\relax \xP@abs\xP@valA \xP@abs\xP@valB - \ifdim\dimexpr\xP@valA+\xP@valB\relax>\xP@maxdev + \ifdim\dimexpr\xP@valA+\xP@valB\relax>\xP@maxdev\relax \xP@failed \fi } @@ -3164,8 +3496,8 @@ % Break the loop for the $t_i$ in "\xP@testoffset". Set the return value to false. % \begin{macrocode} \newcommand*\xP@failed{% - \global\let\@gtempb\iffalse - \gdef\@gtempa{\xP@offsetokfalse}% + \global\let\xP@offsetokif\iffalse + \gdef\xP@afteroffsetok{\xP@offsetokfalse}% } % \end{macrocode} % \end{macro} @@ -3186,9 +3518,9 @@ % \BulletE % \begin{macrocode} \newcommand*\xP@setleftvalue[1]{% - \L@p\dimexpr\xP@ti-\p@/#1\relax - \ifdim\L@p<\z@\L@p\z@\fi - \xP@valA\dimexpr\xP@bezierpoly\X@p\L@c\R@c\X@c\L@p\relax + \L@p\dimexpr\xP@ti-#1\p@\relax + \ifdim\L@p<-.1pt\L@p-.1pt\fi + \xP@valA\xP@bezierpoly\X@p\L@c\R@c\X@c\L@p } % \end{macrocode} % \end{macro} @@ -3196,9 +3528,9 @@ % \BulletE % \begin{macrocode} \newcommand*\xP@setrightvalue[1]{% - \U@p\dimexpr\xP@ti+\p@/#1\relax - \ifdim\U@p>2\p@\U@p2\p@\fi - \xP@valB\dimexpr\xP@bezierpoly\X@p\L@c\R@c\X@c\U@p\relax + \U@p\dimexpr\xP@ti+#1\p@\relax + \ifdim\U@p>2.1\p@\U@p2.1\p@\fi + \xP@valB\xP@bezierpoly\X@p\L@c\R@c\X@c\U@p } % \end{macrocode} % \end{macro} @@ -3219,19 +3551,30 @@ % \end{macro} % \begin{macro}{\xP@splinemultdashed} % \begin{macrocode} -\newcommand*\xP@splinemultdashed{% +\newcommand*\xP@splinemultdashed[1]{% % \end{macrocode} -% Expected dash number +% Expected dash number. It is an even number if the spline is the continuation of the previous one, otherwise (default case) an odd number. % \begin{macrocode} - \@tempcnta\numexpr2*\numexpr(\@tempdimb+\xydashl@)/(2*\xydashl@)\relax-1\relax + \xP@testcont\xP@dashmacro + \@tempcnta + \ifxP@splinecont + \numexpr2*((\@tempdimb-\xydashl@/3)/(2*\xydashl@))\relax + \else + \numexpr2*((\@tempdimb+\xydashl@)/(2*\xydashl@))-1\relax + \fi \ifnum\@tempcnta>\@ne - \expandafter\xP@splinemultdashed@ + \xP@splinemultdashed@#1% \else % \end{macrocode} -% One dash: paint a solid line +% One dash: paint a solid line. Less than one dash: Leave the segment out, just record the end point. % \begin{macrocode} - \expandafter\xP@splinemultsolid - \fi + \ifnum\@tempcnta=\@ne + \xP@splinemultsolid#1 + \else + \xP@savec + \fi + \fi + \global\let\xP@lastpattern\xP@dashmacro } % \end{macrocode} % \end{macro} @@ -3246,6 +3589,11 @@ \@tempdima\dimexpr\@tempdimb/\@tempcnta\relax \xP@temppar\z@ \toks@{}% + \xP@savec + \ifodd\@tempcnta + \else + \xP@slide + \fi \@tempcnta\z@ \loop \advance\@tempcnta\@ne @@ -3270,6 +3618,7 @@ % \begin{macrocode} \@temptokena{}% \xP@setsolidpat + \global\let\xP@lastpattern\xP@dashmacro \@for\@tempa:={#1}\do{\the\toks@}% \xP@stroke{\the\@temptokena}% }} @@ -3308,7 +3657,8 @@ % Dotted lines with multiple strokes are drawn in a different way from single-stroked lines. They are composed of many small, straight lines normal to the curve at every dot position. Hence, the dot pattern for multiple curves has dots which are spaced by the normal distance between strokes. % \begin{macrocode} \newcommand*\xP@multidottedpat{% - \def\xP@pattern{2 J [0 \xP@dim{\xydashh@}]0 d }% + \def\xP@pattern{0 J [\xP@lw\xP@dim{\xydashh@-\xP@preclw}]0 d}% + \global\let\xP@lastpattern\xP@dotmacro } % \end{macrocode} % \end{macro} @@ -3323,41 +3673,73 @@ \newcommand\xP@splinemultdotted[1]{{% \xP@inibigdim % \end{macrocode} +% Make a list of dot positions on the spline segment. +% \begin{macrocode} + \xP@temppar\z@ + \xP@testcont\xP@dotmacro + \ifxP@splinecont +% \end{macrocode} % Expected dot distance (see the formula in "\xP@setdottedpat") % \begin{macrocode} - \@tempdima\dimexpr\@tempdimb/\numexpr\@tempdimb/131072+1\relax\relax + \@tempdimc\dimexpr\@tempdimb/(\@tempdimb/131072+1)\relax + \@tempdima\dimexpr\@tempdimc-\xP@preclw/2\relax + \xP@slide + \@tempdima\@tempdimc + \else + \@tempdima\dimexpr\xP@preclw/2\relax + \xP@slide % \end{macrocode} -% Make a list of dot positions on the spline segment. +% Expected dot distance (see the formula in "\xP@setdottedpat") % \begin{macrocode} - \xP@temppar\z@ + \@tempdima\dimexpr\@tempdimb-\xP@preclw\relax + \ifdim\@tempdima<\z@\@tempdima\z@\fi + \@tempdima\dimexpr\@tempdima/(\@tempdima/131072+1)\relax + \fi + \xP@savec \toks@{}% - \loop - \xP@append\toks@{\noexpand\xP@paintdot{\the\xP@temppar}}% - \xP@oldpar\xP@temppar - \xP@slide +% \end{macrocode} +% If the end of the segment is reached before the first dot position, leave the segment out. +% \begin{macrocode} \ifdim\xP@temppar<\xP@bigdim - \repeat + \loop + \xP@append\toks@{\noexpand\xP@paintdot{\the\xP@temppar}}% + \xP@oldpar\xP@temppar + \xP@slide + \ifdim\xP@temppar<\xP@bigdim + \repeat + \xP@velocity\xP@bigdim\xP@tempvel % \end{macrocode} -% The last position is kept as a scaling factor so that the last dot can be drawn at exactly the parameter $1$. Use the last or the next-to-last position, depending on which is closer to $1$. +% Test whether the last or the next-to-last dot is closer to "\xP@bigdim". Measure from the end of the dot, hence the contribution of "\xP@preclw". Also consider the case that the velocity at the end point is very small. In this case, always choose the next-to-last dot as the final one. % \begin{macrocode} - \xP@lastpar - \ifdim\dimexpr\xP@bigdim-\xP@oldpar\relax<\dimexpr\xP@temppar% - -\xP@bigdim\relax - \xP@oldpar + \ifdim + \ifdim\xP@preclw<\xP@tempvel + \dimexpr2\xP@bigdim-\xP@oldpar-\xP@preclw*\xP@bigdim/\xP@tempvel\relax + \else + -\maxdimen + \fi<\xP@temppar + \xP@temppar\xP@oldpar \else - \xP@temppar \xP@append\toks@{\noexpand\xP@paintdot{\the\xP@temppar}}% \fi + \@tempdima\dimexpr\xP@preclw/2\relax + \xP@slide + \xP@lastpar\xP@temppar % \end{macrocode} % Convert the list of parameters to a list of PDF tokens. % \begin{macrocode} - \@temptokena{}% - \the\toks@ + \@temptokena{}% + \the\toks@ % \end{macrocode} % Actually draw the points in the list. % \begin{macrocode} - \xP@multidottedpat - \xP@stroke{\the\@temptokena}% + \xP@multidottedpat + \xP@stroke{\the\@temptokena}% + \else +% \end{macrocode} +% Leave the segment out because it is too short. +% \begin{macrocode} + \global\let\xP@lastpattern\empty + \fi }} % \end{macrocode} % \end{macro} @@ -3379,28 +3761,97 @@ % \begin{macrocode} \newcommand*\xP@slide@{% % \end{macrocode} -% Compute the velocity at two points, the starting point and an estimate for the end point (estimation based on the total spline length). +% Compute the velocity at two points, the starting point and an estimate for the end point. % \begin{macrocode} - \xP@velocity{\xP@temppar*\p@/\xP@bigdim}\xP@tempvel - \xP@velocity{(\xP@temppar+\xP@bigdim/\numexpr\@tempdimb% - /131072+1\relax)*\p@/\xP@bigdim}\xP@tempvel@ + \xP@velocity\xP@temppar\xP@tempvel % \end{macrocode} -% Use the average velocity to compute the parameter increment. If the parameter increment is too big (i.\,e.\ the velocity was very small), increment the parameter by at most $.1"\xP@bigdim"$, compute the true partial spline length and slide again. +% The first estimate for the parameter increment is based on the total spline length. % \begin{macrocode} - \ifdim\dimexpr\@tempdima*1310720/(\xP@tempvel+\xP@tempvel@)\relax>\p@ + \@tempdimc\dimexpr\xP@bigdim*\@tempdima/\@tempdimb\relax + \count@\z@ + \@tempswatrue +% \end{macrocode} +% Improve the parameter increment iteratively. +% \begin{macrocode} + \loop +% \end{macrocode} +% Velocity at the estimated end point. +% \begin{macrocode} + \xP@velocity{\xP@temppar+\@tempdimc}\xP@tempvel@ +% \end{macrocode} +% Prevent arithmetic overflow. +% \begin{macrocode} + \ifdim\dimexpr\@tempdima*4/13\relax>\xP@tempvel@ + \@tempswafalse + \else +% \end{macrocode} +% Difference to the old parameter increment. This is Newton's method, applied to the estimated spline length based on the velocities "\xP@tempvel" and "\xP@tempvel@" at "\xP@temppar" and $("\xP@temppar"+"\@tempdimc")$. +% \begin{macrocode} + \xP@parinc\dimexpr\@tempdima*\xP@bigdim/\xP@tempvel@ + -(\xP@tempvel+\xP@tempvel@)/2*\@tempdimc/\xP@tempvel@\relax + \advance\@tempdimc\xP@parinc +% \end{macrocode} +% If the estimated parameter increment is bigger than $.12$, increase the parameter by $.1$ and slide only partially. This increases the precision if the parameter increment is big. +% \begin{macrocode} + \ifdim\@tempdimc>.12\xP@bigdim + \@tempswafalse + \else +% \end{macrocode} +% If the estimate is not improved, break the loop. +% \begin{macrocode} + \ifdim\xP@parinc=\z@ + \@tempswafalse + \else +% \end{macrocode} +% Also break the loop after $10$ iterations. +% \begin{macrocode} + \ifnum\count@=9\relax + \@tempswafalse + \fi + \fi + \fi + \fi + \if@tempswa + \advance\count@\@ne + \repeat +% \end{macrocode} +% Note that "\if@tempswa" is always false here. +% +% If the parameter increment would be more than $.1$ and if the parameter is not too big already, increase the parameter by $.1$ and slide again. +% \begin{macrocode} + \ifdim\xP@temppar<5461pt + \ifdim\@tempdimc>.1\xP@bigdim + \@tempswatrue + \fi + \fi + \if@tempswa {% \dimen5\xP@temppar \advance\xP@temppar.1\xP@bigdim +% \end{macrocode} +% Cap the end parameter to prevent arithmetic overflows. +% \begin{macrocode} + \ifdim\xP@temppar>5461pt\xP@temppar5461pt\fi \dimen7\xP@temppar +% \end{macrocode} +% Determine the exact distance of the partial slide. +% \begin{macrocode} \xP@shaveprec{\dimen5}{\dimen7}% \xP@bezierlength - \advance\@tempdima-\@tempdimb - \expandafter}\expandafter\@tempdima\the\@tempdima\relax - \advance\xP@temppar.1\xP@bigdim + \global\dimen@i\dimexpr\@tempdima-\@tempdimb\relax + \global\dimen3\xP@temppar + }% + \@tempdima\dimen@i + \xP@temppar\dimen3\relax +% \end{macrocode} +% Slide again. +% \begin{macrocode} \expandafter\xP@slide@ \else - \advance\xP@temppar - \dimexpr2\xP@bigdim*\@tempdima/(\xP@tempvel+\xP@tempvel@)\relax +% \end{macrocode} +% Finish the slide and return the new parameter. +% \begin{macrocode} + \advance\xP@temppar\@tempdimc \fi } % \end{macrocode} @@ -3412,56 +3863,21 @@ % \end{macrocode} % Scale the parameter with a correction factor % \begin{macrocode} - \xP@temppar\dimexpr#1*\xP@bigdim/\xP@lastpar\relax -% \end{macrocode} -% Auxiliary variables -% \begin{macrocode} - \L@p\dimexpr\L@c-\X@p\relax - \D@p\dimexpr\U@c-\Y@p\relax -% \end{macrocode} -% Velocity vector at parameter value "\xP@temppar" -% \begin{macrocode} - \d@X3\dimexpr((\X@c-\X@p+(\L@c-\R@c)*3)*\xP@temppar/\xP@bigdim - +(\R@c-\L@p-\L@c)*2)*\xP@temppar/\xP@bigdim+\L@p\relax - \d@Y3\dimexpr((\Y@c-\Y@p+(\U@c-\D@c)*3)*\xP@temppar/\xP@bigdim - +(\D@c-\D@p-\U@c)*2)*\xP@temppar/\xP@bigdim+\D@p\relax - \xP@veclen -% \end{macrocode} -% If the velocity is zero, use its first derivative instead to obtain the direction (up to a factor of $6$). -% \begin{macrocode} - \ifdim\@tempdimb=\z@ - \d@X3\dimexpr(\X@c-\X@p+(\L@c-\R@c)*3)*\xP@temppar/\xP@bigdim - +(\R@c-\L@p-\L@c)\relax - \d@Y3\dimexpr(\Y@c-\Y@p+(\U@c-\D@c)*3)*\xP@temppar/\xP@bigdim - +(\D@c-\D@p-\U@c)\relax - \xP@veclen -% \end{macrocode} -% If the first derivative is zero, take the second one (again up to a factor of $6$). -% \begin{macrocode} - \ifdim\@tempdimb=\z@ - \d@X3\dimexpr\X@c-\X@p+(\L@c-\R@c)*3\relax - \d@Y3\dimexpr\Y@c-\Y@p+(\U@c-\D@c)*3\relax - \xP@veclen - \fi - \fi + \@tempdima\dimexpr#1*\xP@bigdim/\xP@lastpar\relax % \end{macrocode} % Position at parameter value "\xP@temppar" % \begin{macrocode} - \U@p\dimexpr\R@c-\L@p-\L@c\relax - \R@p\dimexpr\X@c-3\R@c+3\L@c-\X@p\relax - \X@min\dimexpr\D@c-\D@p-\U@c\relax - \Y@min\dimexpr\Y@c-3\D@c+3\U@c-\Y@p\relax - \xP@posX\dimexpr\X@p+(3\L@p+(3\U@p+\R@p*\xP@temppar/\xP@bigdim)% - *\xP@temppar/\xP@bigdim)*\xP@temppar/\xP@bigdim\relax - \xP@posY\dimexpr\Y@p+(3\D@p+(3\X@min+\Y@min*\xP@temppar/\xP@bigdim)% - *\xP@temppar/\xP@bigdim)*\xP@temppar/\xP@bigdim\relax + \xP@tangent + \xP@posX\dimexpr\xP@precbezierpoly\X@p\L@c\R@c\X@c\@tempdima/8\relax + \xP@posY\dimexpr\xP@precbezierpoly\Y@p\U@c\D@c\Y@c\@tempdima/8\relax % \end{macrocode} % Normal vector to the curve with length "\xydashh@" % \begin{macrocode} - \L@p\dimexpr\xydashh@*\d@Y/\@tempdimb/2\relax - \U@p\dimexpr-\xydashh@*\d@X/\@tempdimb/2\relax + \@tempdima\dimexpr(\xydashh@+\xP@preclw/\xP@normalmult)/2\relax + \L@p\dimexpr\d@Y*\@tempdima/\@tempdimb\relax + \U@p\dimexpr-\d@X*\@tempdima/\@tempdimb\relax % \end{macrocode} -% Append two points on both sides of the curve to the list. (The “zerodot” pattern is made to draw points with distance "\xydashh@".) +% Append two points on both sides of the curve to the list. (The “multidottedpat” pattern is made to draw points with distance "\xydashh@".) % \begin{macrocode} \xP@append\@temptokena{\xP@coor{\xP@posX+\L@p*\xP@normalmult}% {\xP@posY+\U@p*\xP@normalmult}m % @@ -3497,12 +3913,23 @@ \newcommand*\xP@splinesquiggled@[1]{{% \xP@inibigdim % \end{macrocode} +% Reverse the direction of the little arcs, if the last squiggle from the previous segment makes it necessary. +% \begin{macrocode} + \xP@testcont\xP@oddsquigglemacro + \ifxP@splinecont + \def\xP@squigsign{-}% + \else + \let\xP@squigsign\empty + \fi + \xP@savec +% \end{macrocode} % Expected squiggle length % \begin{macrocode} \@tempcnta=\numexpr\@tempdimb/\xybsqll@\relax \ifnum\@tempcnta<\tw@\@tempcnta\tw@\fi \multiply\@tempcnta\tw@ \@tempdima\dimexpr\@tempdimb/\@tempcnta\relax + \xP@squiglen\@tempdima % \end{macrocode} % Make a list of dot positions on the spline segment. % \begin{macrocode} @@ -3522,6 +3949,7 @@ \xP@lastpar \ifodd\@tempcnta \xP@oldpar + \advance\@tempcnta\m@ne \else \xP@temppar \xP@append\toks@{\noexpand\xP@paintsquiggle{\the\xP@temppar}}% @@ -3531,12 +3959,24 @@ % \begin{macrocode} \@temptokena{}% \xP@setsolidpat +% \end{macrocode} +% Record the direction of the last squiggle. +% \begin{macrocode} + \global\expandafter\let\expandafter\xP@lastpattern + \ifodd\numexpr\@tempcnta/2\if\xP@squigsign-+1\fi\relax + \xP@oddsquigglemacro + \else + \xP@evensquigglemacro + \fi +% \end{macrocode} +% Draw the squiggles. +% \begin{macrocode} \@for\@tempa:={#1}\do{% \let\xP@dosquiggle\xP@dosquiggle@ \count@\z@ \the\toks@ }% - \xP@stroke{\the\@temptokena} + \xP@stroke{\the\@temptokena}% }} % \end{macrocode} % \end{macro} @@ -3547,65 +3987,26 @@ % \end{macrocode} % Scale the parameter with a correction factor % \begin{macrocode} - \xP@temppar\dimexpr#1*\xP@bigdim/\xP@lastpar\relax + \@tempdima\dimexpr#1*\xP@bigdim/\xP@lastpar\relax % \end{macrocode} -% Auxiliary variables +% Position at parameter value "\xP@temppar", offset for multiple curves. % \begin{macrocode} - \L@p\dimexpr\L@c-\X@p\relax - \D@p\dimexpr\U@c-\Y@p\relax -% \end{macrocode} -% Velocity vector at parameter value "\xP@temppar" -% \begin{macrocode} - \d@X3\dimexpr((\X@c-\X@p+(\L@c-\R@c)*3)*\xP@temppar/\xP@bigdim - +(\R@c-\L@p-\L@c)*2)*\xP@temppar/\xP@bigdim+\L@p\relax - \d@Y3\dimexpr((\Y@c-\Y@p+(\U@c-\D@c)*3)*\xP@temppar/\xP@bigdim - +(\D@c-\D@p-\U@c)*2)*\xP@temppar/\xP@bigdim+\D@p\relax - \xP@veclen -% \end{macrocode} -% If the velocity is zero, take its first derivative instead to obtain the direction (up to a factor of $6$). -% \begin{macrocode} - \ifdim\@tempdimb=\z@ - \d@X3\dimexpr(\X@c-\X@p+(\L@c-\R@c)*3)*\xP@temppar/\xP@bigdim - +(\R@c-\L@p-\L@c)\relax - \d@Y3\dimexpr(\Y@c-\Y@p+(\U@c-\D@c)*3)*\xP@temppar/\xP@bigdim - +(\D@c-\D@p-\U@c)\relax - \xP@veclen -% \end{macrocode} -% If the first derivative is zero, take the second one (again up to a factor of $6$). -% \begin{macrocode} - \ifdim\@tempdimb=\z@ - \d@X3\dimexpr\X@c-\X@p+(\L@c-\R@c)*3\relax - \d@Y3\dimexpr\Y@c-\Y@p+(\U@c-\D@c)*3\relax - \xP@veclen - \fi - \fi -% \end{macrocode} -% Position at parameter value "\xP@temppar" -% \begin{macrocode} - \U@p\dimexpr\R@c-\L@p-\L@c\relax - \R@p\dimexpr\X@c-3\R@c+3\L@c-\X@p\relax - \X@min\dimexpr\D@c-\D@p-\U@c\relax - \Y@min\dimexpr\Y@c-3\D@c+3\U@c-\Y@p\relax - \xP@posX\dimexpr\X@p+(3\L@p+(3\U@p+\R@p*\xP@temppar/\xP@bigdim)% - *\xP@temppar/\xP@bigdim)*\xP@temppar/\xP@bigdim\relax - \xP@posY\dimexpr\Y@p+(3\D@p+(3\X@min+\Y@min*\xP@temppar/\xP@bigdim)% - *\xP@temppar/\xP@bigdim)*\xP@temppar/\xP@bigdim\relax -% \end{macrocode} -% Offset to the current position for multiple curves. -% \begin{macrocode} - \advance\xP@posX\dimexpr-\d@Y*\numexpr\@tempa\relax/\@tempdimb\relax - \advance\xP@posY\dimexpr\d@X*\numexpr\@tempa\relax/\@tempdimb\relax + \xP@tangent + \xP@posX\dimexpr\xP@precbezierpoly\X@p\L@c\R@c\X@c\@tempdima/8% + -\d@Y*(\@tempa)/\@tempdimb\relax + \xP@posY\dimexpr\xP@precbezierpoly\Y@p\U@c\D@c\Y@c\@tempdima/8% + +\d@X*(\@tempa)/\@tempdimb\relax % \end{macrocode} % Tangent vector to the curve with correct length % \begin{macrocode} - \L@p\dimexpr\d@X*\@tempdima/\@tempdimb\relax - \U@p\dimexpr\d@Y*\@tempdima/\@tempdimb\relax + \L@p\dimexpr\d@X*\xP@squiglen/\@tempdimb\relax + \U@p\dimexpr\d@Y*\xP@squiglen/\@tempdimb\relax \R@p\dimexpr\L@p*543339720/1311738121\relax \D@p\dimexpr\U@p*543339720/1311738121\relax \X@min\dimexpr\L@p*362911648/967576667\relax \Y@min\dimexpr\U@p*362911648/967576667\relax - \X@max\dimexpr(\L@p+\U@p)*173517671/654249180\relax - \Y@max\dimexpr(\L@p-\U@p)*173517671/654249180\relax + \X@max\dimexpr(\L@p+\xP@squigsign\U@p)*173517671/654249180\relax + \Y@max\dimexpr(\L@p-\xP@squigsign\U@p)*173517671/654249180\relax % \end{macrocode} % \begin{macrocode} \xP@dosquiggle @@ -3623,8 +4024,8 @@ % \BulletG % \begin{macrocode} \newcommand*\xP@dosquiggle@{% - \edef\next@{\xP@coor{\xP@posX}{\xP@posY}m % - \xP@coor{\xP@posX+\Y@max}{\xP@posY+\X@max}% + \edef\next@{\xP@coor{\xP@posX}{\xP@posY}m + \xP@coor{\xP@posX+\Y@max}{\xP@posY+\xP@squigsign\X@max}% }% \let\xP@dosquiggle\xP@dosquiggle@@ } @@ -3636,37 +4037,134 @@ \newcommand*\xP@dosquiggle@@{% \xP@append\@temptokena{\next@\expandafter\xP@coor \ifcase\count@ - {\xP@posX-\Y@max}{\xP@posY-\X@max}% + {\xP@posX-\Y@max}{\xP@posY-\xP@squigsign\X@max}% \xP@coor\xP@posX\xP@posY \or - {\xP@posX-\D@p-\X@min}{\xP@posY+\R@p-\Y@min}% - \xP@coor{\xP@posX-\D@p}{\xP@posY+\R@p}% + {\xP@posX-\xP@squigsign\D@p-\X@min}{\xP@posY+\xP@squigsign\R@p-\Y@min}% + \xP@coor{\xP@posX-\xP@squigsign\D@p}{\xP@posY+\xP@squigsign\R@p}% \or - {\xP@posX-\X@max}{\xP@posY+\Y@max}% + {\xP@posX-\X@max}{\xP@posY+\xP@squigsign\Y@max}% \xP@coor\xP@posX\xP@posY \or - {\xP@posX+\D@p-\X@min}{\xP@posY-\R@p-\Y@min}% - \xP@coor{\xP@posX+\D@p}{\xP@posY-\R@p}% + {\xP@posX+\xP@squigsign\D@p-\X@min}{\xP@posY-\xP@squigsign\R@p-\Y@min}% + \xP@coor{\xP@posX+\xP@squigsign\D@p}{\xP@posY-\xP@squigsign\R@p}% \fi c }% \edef\next@{\expandafter\xP@coor \ifcase\count@ - {\xP@posX+\Y@max}{\xP@posY+\X@max}% + {\xP@posX+\Y@max}{\xP@posY+\xP@squigsign\X@max}% \or - {\xP@posX-\D@p+\X@min}{\xP@posY+\R@p+\Y@min}% + {\xP@posX-\xP@squigsign\D@p+\X@min}{\xP@posY+\xP@squigsign\R@p+\Y@min}% \or - {\xP@posX+\X@max}{\xP@posY-\Y@max}% + {\xP@posX+\X@max}{\xP@posY-\xP@squigsign\Y@max}% \or - {\xP@posX+\D@p+\X@min}{\xP@posY-\R@p+\Y@min}% + {\xP@posX+\xP@squigsign\D@p+\X@min}{\xP@posY-\xP@squigsign\R@p+\Y@min}% \fi }% } % \end{macrocode} % \end{macro} +% +% \subsection{Spline continuation} +% +% The following code handles the spline continuation (see \autoref{beziercont}). We introduce global macros which store the last end point of a Bézier segment. If the next segment continues at exactly the same coordinates, the dash/dot/squiggle patterns recognize the continuation. +% \begin{macro}{\xP@lastX} +% \begin{macro}{\xP@lastY} +% \begin{macro}{\xP@lastpattern} +% \begin{macrocode} +\newcommand*\xP@lastX{} +\newcommand*\xP@lastY{} +\newcommand*\xP@lastpattern{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\xP@solidmacro} +% \begin{macro}{\xP@dotmacro} +% \begin{macro}{\xP@dashmacro} +% \begin{macro}{\xP@evensquigglemacro} +% \begin{macro}{\xP@oddsquigglemacro} +% \begin{macrocode} +\newcommand*\xP@solidmacro{solid} +\newcommand*\xP@dotmacro{dot} +\newcommand*\xP@dashmacro{dash} +\newcommand*\xP@evensquigglemacro{evensquiggle} +\newcommand*\xP@oddsquigglemacro{oddsquiggle} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\xy} +% Reset the last position with every new diagram. +% \begin{macrocode} +\CheckCommand*\xy{\ifmmode\expandafter\xymath@\else\expandafter\xynomath@\fi} +\renewcommand*\xy{% + \global\let\xP@lastpattern\empty + \ifmmode\expandafter\xymath@\else\expandafter\xynomath@\fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\xP@savec} +% Save the current end point +% \begin{macrocode} +\newcommand*\xP@savec{% + \xdef\xP@lastX{\the\X@c}% + \xdef\xP@lastY{\the\Y@c}% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\ifxP@splinecont} +% Switch: does the next spline continue at the end point of the last spline? +% \begin{macrocode} +\@ifdefinable\ifxP@splinecont\relax +\@ifdefinable\xP@splineconttrue\relax +\@ifdefinable\xP@splinecontfalse\relax +\newif\ifxP@splinecont +% \end{macrocode} +% \end{macro} +% \begin{macro}{\xP@testcont} +% Test for "\ifxP@splinecont" +% \begin{macrocode} +\newcommand*\xP@testcont[1]{% + \xP@splinecontfalse + \ifxP@cont + \ifx\xP@lastpattern#1% + \ifdim\xP@lastX=\X@p + \ifdim\xP@lastY=\Y@p + \xP@splineconttrue + \fi + \fi + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% % End of the section for \Xy-pic's “curve” option. % \begin{macrocode} \xP@endgobble % \end{macrocode} % +% \begin{macro}{\ifxP@cont} +% Switch: shall the spline hack be applied? This is outside the optional section to avoid error messages. +% \begin{macrocode} +\@ifdefinable\ifxP@cont\relax +\@ifdefinable\xP@conttrue\relax +\@ifdefinable\xP@contfalse\relax +\newif\ifxP@cont +% \end{macrocode} +% \end{macro} +% \begin{macro}{\xypdfcontpatternon} +% \begin{macro}{\xypdfcontpatternoff} +% \begin{macrocode} +\newcommand*\xypdfcontpatternon{\xP@conttrue} +\newcommand*\xypdfcontpatternoff{\xP@contfalse} +\xP@conttrue +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \section{Changelog} % % \begin{description} @@ -3686,6 +4184,14 @@ % % \end{itemize} % +% \item[v1.2] 2010/04/08 +% \begin{itemize} +% \item Improved precision and numerical stability for the offset algorithm around cusps. +% \item Improved slide algorithm "\xP@slide@" +% \item Respect "\pdfdecimaldigits" when dimensions are written to the PDF file. +% \item Correct continuation for dashed/dotted/squiggled curves consisting of more than one segment. +% \item Code cleanup +% \end{itemize} % \end{description} % \Finale \endinput \ No newline at end of file diff --git a/Master/texmf-dist/source/latex/xypdf/xypdf.ins b/Master/texmf-dist/source/latex/xypdf/xypdf.ins index 935f982cb94..ef7dae7a519 100644 --- a/Master/texmf-dist/source/latex/xypdf/xypdf.ins +++ b/Master/texmf-dist/source/latex/xypdf/xypdf.ins @@ -1,123 +1,123 @@ -%% -%% Copyright (c) 2010 by Daniel M\"ullner (Müllner) -%% -%% -------------------------------------------------------------------- -%% -%% This program is free software: you can redistribute it and/or modify -%% it under the terms of the GNU General Public License as published by -%% the Free Software Foundation, either version 3 of the License, or -%% (at your option) any later version. -%% -%% This program is distributed in the hope that it will be useful, -%% but WITHOUT ANY WARRANTY; without even the implied warranty of -%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -%% GNU General Public License for more details. -%% -%% The GNU General Public License is available at -%% . -%% -%% -------------------------------------------------------------------- -%% -%% This file is part of the LaTeX2e xypdf package. The package -%% consists of the following files: -%% -%% README - This file, the distribution guide -%% xypdf.dtx - Documented source code -%% xypdf.ins - Installation script -%% xypdf.pdf - Documentation (generated from xypdf.dtx) -%% -%% The LaTeX style file xypdf.sty is generated by the following command: -%% -%% latex xypdf.ins -%% -\input docstrip.tex -% Change docstrip so that it gobbles spaces at the beginning of lines. Also, -% lines containing a percent sign are merged with the next line. -% -% Caution: this only works if the package does not contain percent signs for -% any other purpose than indicating comments. -\CheckCommand*\putline@do[3]{\StreamPut#1{\inLine}} -\renewcommand*\putline@do[3]{% - \expandafter\docgobblespaces\inLine\endLine - \docgobblepercent - \ifx\@tempa\empty - \StreamPut#1{\@stream}% - \let\@stream\empty - \fi} -\@ifdefinable\space@\relax -{\catcode`\ =12\global\let\space@= } -\newcommand*\docgobblespaces{\futurelet\next\docgobblespaces@} -\newcommand*\docgobblespaces@{% - \ifx\next\space@ - \def\next@{\afterassignment\docgobblespaces\let\next= }% - \else - \def\next@{\definLine}% - \fi - \next@ -} -\@ifdefinable\definLine\relax -\def\definLine#1\endLine{\def\inLine{#1}} - -\newcommand*\@stream{} -{\catcode`\%=12 -\@ifdefinable\percentchar\relax -\gdef\percentchar{%} -\@ifdefinable\docgobblepercent\relax -\gdef\docgobblepercent{\expandafter\docgobblepercent@\inLine%\endLine} -\@ifdefinable\docgobblepercent@\relax -\gdef\docgobblepercent@#1%#2\endLine{\def\inLine{#1}\def\@tempa{#2}\edef\@stream{\@stream\inLine}} -} - -\keepsilent -\askforoverwritefalse -\usedir{tex/latex/xypdf} -\preamble - -Copyright (c) 2010 by Daniel M\string\"ullner (Müllner) - --------------------------------------------------------------------- - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -The GNU General Public License is available at -. - --------------------------------------------------------------------- - -This file is part of the LaTeX2e xypdf package. The package -consists of the following files: - - README - This file, the distribution guide - xypdf.dtx - Documented source code - xypdf.ins - Installation script - xypdf.pdf - Documentation (generated from xypdf.dtx) - -The LaTeX style file xypdf.sty is generated by the following command: - - latex xypdf.ins - -\endpreamble -\generate{\file{xypdf.sty}{\from{xypdf.dtx}{package}}} -\obeyspaces -\Msg{****************************************************} -\Msg{* *} -\Msg{* To finish the installation you have to move the *} -\Msg{* following file into a directory searched by TeX: *} -\Msg{* *} -\Msg{* xypdf.sty *} -\Msg{* *} -\Msg{* To produce the documentation run the file *} -\Msg{* xypdf.dtx through LaTeX. *} -\Msg{* *} -\Msg{* Happy TeXing! *} -\Msg{* *} -\Msg{****************************************************} +%% +%% Copyright (c) 2010 by Daniel M\"ullner (Müllner) +%% +%% -------------------------------------------------------------------- +%% +%% This program is free software: you can redistribute it and/or modify +%% it under the terms of the GNU General Public License as published by +%% the Free Software Foundation, either version 3 of the License, or +%% (at your option) any later version. +%% +%% This program is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%% GNU General Public License for more details. +%% +%% The GNU General Public License is available at +%% . +%% +%% -------------------------------------------------------------------- +%% +%% This file is part of the LaTeX2e xypdf package. The package +%% consists of the following files: +%% +%% README - This file, the distribution guide +%% xypdf.dtx - Documented source code +%% xypdf.ins - Installation script +%% xypdf.pdf - Documentation (generated from xypdf.dtx) +%% +%% The LaTeX style file xypdf.sty is generated by the following command: +%% +%% latex xypdf.ins +%% +\input docstrip.tex +% Change docstrip so that it gobbles spaces at the beginning of lines. Also, +% lines containing a percent sign are merged with the next line. +% +% Caution: this only works if the package does not contain percent signs for +% any other purpose than indicating comments. +\CheckCommand*\putline@do[3]{\StreamPut#1{\inLine}} +\renewcommand*\putline@do[3]{% + \expandafter\docgobblespaces\inLine\endLine + \docgobblepercent + \ifx\@tempa\empty + \StreamPut#1{\@stream}% + \let\@stream\empty + \fi} +\@ifdefinable\space@\relax +{\catcode`\ =12\global\let\space@= } +\newcommand*\docgobblespaces{\futurelet\next\docgobblespaces@} +\newcommand*\docgobblespaces@{% + \ifx\next\space@ + \def\next@{\afterassignment\docgobblespaces\let\next= }% + \else + \def\next@{\definLine}% + \fi + \next@ +} +\@ifdefinable\definLine\relax +\def\definLine#1\endLine{\def\inLine{#1}} + +\newcommand*\@stream{} +{\catcode`\%=12 +\@ifdefinable\percentchar\relax +\gdef\percentchar{%} +\@ifdefinable\docgobblepercent\relax +\gdef\docgobblepercent{\expandafter\docgobblepercent@\inLine%\endLine} +\@ifdefinable\docgobblepercent@\relax +\gdef\docgobblepercent@#1%#2\endLine{\def\inLine{#1}\def\@tempa{#2}\edef\@stream{\@stream\inLine}} +} + +\keepsilent +\askforoverwritefalse +\usedir{tex/latex/xypdf} +\preamble + +Copyright (c) 2010 by Daniel M\string\"ullner (Müllner) + +-------------------------------------------------------------------- + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +The GNU General Public License is available at +. + +-------------------------------------------------------------------- + +This file is part of the LaTeX2e xypdf package. The package +consists of the following files: + + README - This file, the distribution guide + xypdf.dtx - Documented source code + xypdf.ins - Installation script + xypdf.pdf - Documentation (generated from xypdf.dtx) + +The LaTeX style file xypdf.sty is generated by the following command: + + latex xypdf.ins + +\endpreamble +\generate{\file{xypdf.sty}{\from{xypdf.dtx}{package}}} +\obeyspaces +\Msg{****************************************************} +\Msg{* *} +\Msg{* To finish the installation you have to move the *} +\Msg{* following file into a directory searched by TeX: *} +\Msg{* *} +\Msg{* xypdf.sty *} +\Msg{* *} +\Msg{* To produce the documentation run the file *} +\Msg{* xypdf.dtx through LaTeX. *} +\Msg{* *} +\Msg{* Happy TeXing! *} +\Msg{* *} +\Msg{****************************************************} \endbatchfile \ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/xypdf/xypdf.sty b/Master/texmf-dist/tex/latex/xypdf/xypdf.sty index 904dc3cc8c5..39b96dbc1b1 100644 --- a/Master/texmf-dist/tex/latex/xypdf/xypdf.sty +++ b/Master/texmf-dist/tex/latex/xypdf/xypdf.sty @@ -39,12 +39,15 @@ %% \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{xypdf} - [2010/03/30 v1.1 PDF output for the Xy-pic package] + [2010/04/08 v1.2 PDF output for the Xy-pic package] \@ifpackageloaded{xy}\relax {\PackageError{xypdf}{Load the Xy-pic package before this package} {Insert `\string\usepackage[]{xy}' before `\string\usepackage{xypdf}'}} \xywithoption{ps}{\PackageError{xypdf}{Do not load Xy-pic with a Postscript backend}{}} +\ifx\unexpanded\@undefined +\PackageError{xypdf}{eTeX is needed for the xypdf package}{} +\fi \RequirePackage{ifpdf} \newcommand*\xypdfon{} \newcommand*\xypdfoff{} @@ -59,23 +62,99 @@ \let\xP@hook\@undefined \let\xP@tempvar\@undefined \let\@tempa\@undefined +\let\next@\undefined \let\xP@gobblepart\@undefined \let\xP@endgobble\@undefined } -\@ifdefinable\xP@literal\relax \ifpdf -\let\xP@literal\pdfliteral +\newcommand*\xP@literal[1]{\pdfsave\pdfliteral{#1}\pdfrestore} +\newcommand*\xP@cm[5]{\pdfsave +\pdfsetmatrix{#1 #2 #3 #4}#5\pdfrestore +} \else -\def\xP@literal{\PackageWarning{xypdf}{The produced DVI file is NOT PORTABLE. Convert it with^^Jdvipdfm(x) to the PDF format but do not expect the DVI itself to be displayed^^Jcorrectly\@gobble}\global\let\xP@literal\xP@literal@ +\newcommand*\xP@literal{\PackageWarning{xypdf}{The produced DVI file is NOT PORTABLE. Convert it with^^Jdvipdfm(x) to the PDF format but do not expect the DVI file itself to be^^Jdisplayed correctly\@gobble}\global\let\xP@literal\xP@literal@ \xP@literal } -\newcommand*\xP@literal@[1]{\special{pdf:literal #1}} +\newcommand*\xP@literal@[1]{\special{pdf:content #1}} +\newcommand*\xP@cm[5]{\special{pdf:btrans matrix #1 #2 #3 #4 0 0}#5\special{pdf:etrans}} +\fi +\ifx\pdfdecimaldigits\@undefined +\newcommand*\xP@digits{2} +\else +\@ifdefinable\xP@digits\relax +\xdef\xP@digits{\the\pdfdecimaldigits} +\ifnum\pdfdecimaldigits<2 +\PackageWarning{xypdf}{The precision in \string\pdfdecimaldigits\space is only \xP@digits\space +decimals.^^JIt is recommended to set \string\pdfdecimaldigits\space to 2 or 3 for best output quality\@gobble} +\fi \fi -\newcommand*\xP@dim[1]{\xP@EARPT\dimexpr(#1)*800/803\relax\space} +\newcommand*\xP@dim[1]{\expandafter\xP@removePT\the\dimexpr(#1)*800/803\relax\space} +\newcommand*\xP@precdim[1]{\xP@EARPT\dimexpr(#1)*800/803\relax\space} \newcommand*\xP@EARPT{\expandafter\removePT@\the} \newcommand*\xP@coor[1]{\xP@dim{#1}\xP@dim} +\@ifdefinable\xP@removePT\relax +{\catcode`\p=12\catcode`\t=12\gdef\xP@removePT#1pt{\xP@removePT@#10000@}} +\@ifdefinable\xP@removePT@\relax +\ifcase\xP@digits +\def\xP@removePT@#1.#2#3@{\ifnum#2<5 +#1\else +\the\numexpr-\if-#1-\else-#1+\fi\@ne\relax +\fi +} +\or +\def\xP@removePT@#1#2.#3#4#5@{\ifnum#4<5 +#1#2\if#30\else +.#3\fi +\else +\expandafter\xP@removePT +\the\dimexpr#1#2.#3pt+\if#1--\fi.12pt\relax +\fi +} +\or +\def\xP@removePT@#1#2.#3#4#5#6@{\ifnum#5<5 +#1#2\if#40\if#30\else +.#3\fi +\else +.#3#4\fi +\else +\expandafter\xP@removePT +\the\dimexpr#1#2.#3#4pt+\if#1--\fi786sp\relax +\fi +} +\or +\def\xP@removePT@#1#2.#3#4#5#6#7@{\ifnum#6<5 +#1#2\if#50\if#40\if#30\else +.#3\fi +\else +.#3#4\fi +\else +.#3#4#5\fi +\else +\expandafter\xP@removePT +\the\dimexpr#1#2.#3#4#5pt+\if#1--\fi79sp\relax +\fi +} +\or +\def\xP@removePT@#1#2.#3#4#5#6#7#8@{\ifnum#7<5 +#1#2\if#60\if#50\if#40\if#30\else +.#3\fi +\else +.#3#4\fi +\else +.#3#4#5\fi +\else +.#3#4#5#6\fi +\else +\expandafter\xP@removePT +\the\dimexpr#1#2.#3#4#5#6pt+\if#1--\fi8sp\relax +\fi +} +\else +\let\xP@dim\xP@precdim +\fi \AtBeginDocument{{\setbox0\hbox{$ $}}\@ifdefinable\xP@lw\relax -\edef\xP@lw{\xP@dim{\fontdimen8\textfont3}}\PackageInfo{xypdf}{Line width: \the\fontdimen8\textfont3 }} +\@ifdefinable\xP@preclw\relax +\edef\xP@preclw{\the\fontdimen8\textfont3}\edef\xP@lw{\xP@dim\xP@preclw}\PackageInfo{xypdf}{Line width: \xP@preclw}} \xP@hook{solid@} \newcommand*\xP@solid@{\straight@\xP@solidSpread} \@ifdefinable\xP@solidSpread\relax @@ -90,36 +169,56 @@ \xP@stroke{\xP@coor\X@p\Y@p m \xP@coor\X@c\Y@c l}\fi }} \newcommand*\xP@pattern{} -\newcommand*\xP@setsolidpat{\def\xP@pattern{1 J 1 j []0 d }} -\newcommand*\xP@stroke[1]{\xP@literal{q \xP@lw w \xP@pattern#1 S Q}} +\newcommand*\xP@setsolidpat{\def\xP@pattern{1 J 1 j []0 d}\global\let\xP@lastpattern\xP@solidmacro +} +\newcommand*\xP@stroke[1]{\xP@literal{\xP@lw w \xP@pattern\space#1 S}} \xP@hook{dash@} \newcommand\xP@dash@{\line@\def\Connect@@{\straight@\xP@dashedSpread}} \@ifdefinable\xP@dashedSpread\relax \def\xP@dashedSpread#1\repeat@{{\xP@veclen \ifdim\@tempdimb>\z@ \xP@setdashpat +\xP@savec \xP@stroke{\xP@coor\X@p\Y@p m \xP@coor\X@c\Y@c l}\fi }} -\newcommand*\xP@setdashpat{\edef\xP@pattern{1 J 1 j [\ifdim\@tempdimb>\xydashl@ -\xP@dim{\@tempdimb/(2*\numexpr(\@tempdimb+\xydashl@)/(2*\xydashl@)\relax-1)}\fi -]0 d }} +\newcommand*\xP@setdashpat{\xP@testcont\xP@dashmacro +\ifxP@splinecont +{\count@\numexpr2*((\@tempdimb-\xydashl@/3)/(2*\xydashl@))\relax +\xdef\@gtempa{\ifnum\count@>\z@\xP@dim{\@tempdimb/\count@}\fi}}\edef\xP@pattern{1 J 1 j [\@gtempa]\ifx\@gtempa\empty0 \else\@gtempa\fi d}\else +\edef\xP@pattern{1 J 1 j [\ifdim\@tempdimb>\xydashl@ +\xP@dim{\@tempdimb/(2*((\@tempdimb+\xydashl@)/(2*\xydashl@))-1)}\fi +]0 d}\fi +\global\let\xP@lastpattern\xP@dashmacro +} \xP@hook{point@} \newcommand*\xP@point@{\xP@zerodot\egroup\Invisible@false \Hidden@false\def\Leftness@{.5}\def\U@pness@{.5}\ctipEdge@ \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@\xP@dottedSpread}} -\newcommand*\xP@zerodotpattern{\def\xP@pattern{2 J [0 2]0 d }} -\newcommand*\xP@zerodot{\xP@zerodotpattern -\xP@stroke{0 0 m 1 0 l}} +\newcommand*\xP@zerodot{\hb@xt@\z@{\hss +\vbox to\z@{\vss\hrule\@width\xP@preclw\@height\xP@preclw\vss}\hss}} \@ifdefinable\xP@dottedSpread\relax \def\xP@dottedSpread#1\repeat@{{\xP@veclen \ifdim\@tempdimb>\z@ \xP@setdottedpat +\xP@savec \xP@stroke{\xP@coor\X@p\Y@p m \xP@coor\X@c\Y@c l}\fi }} -\newcommand*\xP@setdottedpat{\edef\xP@pattern{2 J [\ifdim\@tempdimb>\xP@lw bp -0 \xP@dim{\@tempdimb/\numexpr\@tempdimb/131072+1\relax}\fi -]0 d -}} +\newcommand*\xP@setdottedpat{\xP@testcont\xP@dotmacro +\ifxP@splinecont +\@tempdima\dimexpr\@tempdimb/(\@tempdimb/131072+1)-\xP@preclw\relax +\edef\xP@pattern{0 J [\ifdim\@tempdima>\z@ +\xP@precdim\xP@preclw\xP@precdim\@tempdima +\fi +]\xP@precdim{\xP@preclw+1sp}d}\else +\advance\@tempdimb-\xP@preclw +\ifdim\@tempdimb<\z@\@tempdimb\z@\fi +\@tempdima\dimexpr\@tempdimb/(\@tempdimb/131072+1)-\xP@preclw\relax +\edef\xP@pattern{0 J [\ifdim\@tempdima>\z@ +\xP@lw\xP@dim\@tempdima +\fi +]0 d}\fi +\global\let\xP@lastpattern\xP@dotmacro +} \newcommand*\xP@abs[1]{\ifdim#1<\z@\multiply#1\m@ne\fi} \ifx\ifpdfabsdim\@undefined \newcommand*\xP@ifabsless[2]{\ifdim\ifdim#1<\z@-\fi#1<\ifdim#2<\z@-\fi#2} @@ -128,7 +227,6 @@ \newcommand*\xP@ifabsless[2]{\ifpdfabsdim#1<#2} \@gobble\fi \fi -\newcommand*\xP@ifabsless@[4]{\xP@ifabsless{\dimexpr#1\relax}{\dimexpr#2\relax}#3\else#4\fi} \newcommand*\xP@swapdim[2]{\@tempdima#1#1#2#2\@tempdima} \newcommand*\xP@swapnum[2]{\@tempcnta#1#1#2#2\@tempcnta} \newcommand*\xP@max[2]{\ifdim#1>#2#1\else#2\fi} @@ -193,18 +291,31 @@ \ifnum\@tempcnta<\tw@\@tempcnta\tw@\fi \@tempdima\dimexpr\d@X/\@tempcnta\relax \@tempdimc\dimexpr\d@Y/\@tempcnta\relax +\xP@testcont\xP@oddsquigglemacro +\ifxP@splinecont +\def\xP@squigsign{-}\else +\let\xP@squigsign\empty +\fi \count@\z@ \loop \xP@append\toks@{\xP@coor{\X@p+\d@X*\count@/\@tempcnta+(\@tempdima --\ifodd\count@-\fi\@tempdimc)*147546029/534618434}{\Y@p+\d@Y*\count@/\@tempcnta+(\@tempdimc -+\ifodd\count@-\fi\@tempdima)*147546029/534618434}}\advance\count@\@ne +-\xP@squigsign\ifodd\count@-\fi\@tempdimc)*147546029/534618434}{\Y@p+\d@Y*\count@/\@tempcnta+(\@tempdimc ++\xP@squigsign\ifodd\count@-\fi\@tempdima)*147546029/534618434}}\advance\count@\@ne \xP@append\toks@{\xP@coor{\X@p+\d@X*\count@/\@tempcnta-(\@tempdima --\ifodd\count@-\fi\@tempdimc)*147546029/534618434}{\Y@p+\d@Y*\count@/\@tempcnta-(\@tempdimc -+\ifodd\count@-\fi\@tempdima)*147546029/534618434}\xP@coor{\X@p+\d@X*\count@/\@tempcnta}{\Y@p+\d@Y*\count@/\@tempcnta}c }\ifnum\count@<\@tempcnta +-\xP@squigsign\ifodd\count@-\fi\@tempdimc)*147546029/534618434}{\Y@p+\d@Y*\count@/\@tempcnta-(\@tempdimc ++\xP@squigsign\ifodd\count@-\fi\@tempdima)*147546029/534618434}\xP@coor{\X@p+\d@X*\count@/\@tempcnta}{\Y@p+\d@Y*\count@/\@tempcnta}c }\ifnum\count@<\@tempcnta \repeat \xP@setsolidpat +\global\expandafter\let\expandafter\xP@lastpattern +\ifodd\numexpr\count@\if\xP@squigsign-+1\fi\relax +\xP@oddsquigglemacro +\else +\xP@evensquigglemacro +\fi +\xP@savec \xP@stroke{\the\toks@}\fi }} +\newcommand*\xP@squigsign{} \newcommand*\xP@append[2]{{\edef\@tempa{#1{\the#1#2}}\expandafter}\@tempa } \xP@hook{circhar@@} @@ -230,23 +341,22 @@ } \newcommand*\xP@optionerror[1]{\PackageError{xypdf}{Load the Xy-pic "#1" option before the xypdf package}{}} \@ifdefinable\xP@gobblepart\relax -\long\def\xP@gobblepart#1\xP@endgobble{} +\def\xP@gobblepart#1\xP@endgobble{} \newcommand*\xP@endgobble{\relax} \xP@optionalsection{rotate} \newcommand*\xP@scale[2]{\setboxz@h{\hskip\L@p \hskip-\R@p -\lower\U@p\hbox{\xP@literal{q #1\space0 0 #2\space0 0 cm}\raise\U@p\hb@xt@\z@{\hskip-\L@p\boxz@\hss}\xP@literal{Q}}}} -\newcommand\xP@rotate{\xP@rotate@\xP@trigfromdir +\lower\U@p\hbox{\xP@cm{#1}00{#2}{\raise\U@p\hb@xt@\z@{\hskip-\L@p\boxz@\hss}}}}\global\let\xP@lastpattern\empty } +\newcommand\xP@rotate{\xP@rotate@\xP@trigfromdir} \@ifdefinable\xP@specialrotate\relax -\def\xP@specialrotate#1@@{\xP@rotate@\xP@trig{#1\p@}} +\def\xP@specialrotate#1@@{\xP@rotate@\xP@trig{#1pt}} \newcommand*\xP@rotate@[2]{\setboxz@h{#1{#2}\hskip\L@p \hskip-\R@p -\lower\U@p\hbox{\xP@literal{q \cosDirection\space -\sinDirection\space -\if-\sinDirection\else-\sinDirection\fi\space -\cosDirection\space -0 0 cm}\raise\U@p\hb@xt@\z@{\hskip-\L@p\boxz@\hss}\xP@literal{Q}}}} +\lower\U@p\hbox{\xP@cm\cosDirection\sinDirection +{\if-\sinDirection\else-\sinDirection\fi}\cosDirection +{\raise\U@p\hb@xt@\z@{\hskip-\L@p\boxz@\hss}}}}\global\let\xP@lastpattern\empty +} \CheckCommand*\xyRotate@@[1]{\xyundefinedRotate@{rotate}{#1}@@} \let\xyRotate@@\xP@rotate \def\@tempa#1@@{\xyundefinedRotate@{special rotate}{#1}@@} @@ -412,6 +522,8 @@ \xP@tempvar\xP@oldpar\X@ybase \xP@tempvar\xP@lastpar\Y@ybase \xP@tempvar\xP@tempvel@\X@min +\xP@tempvar\xP@parinc\Y@min +\xP@tempvar\xP@squiglen\almostz@ \xP@tempvar\xP@scaleone\K@ \xP@tempvar\xP@scaletwo\KK@ \xP@tempvar\xP@scalethree\Direction @@ -425,7 +537,8 @@ \ifdim\dimen5<\dimen7 \xP@preparespline \ifdim\@tempdimb>\z@ -#1\xP@stroke{\xP@coor\X@p\Y@p m \xP@coor\L@c\U@c\xP@coor\R@c\D@c\xP@coor\X@c\Y@c c}\fi +#1\xP@stroke{\xP@coor\X@p\Y@p m \xP@coor\L@c\U@c\xP@coor\R@c\D@c\xP@coor\X@c\Y@c c}\xP@savec +\fi \fi } \newcommand*\xP@preparespline{\ifx\splineinfo@\squineinfo@ @@ -463,62 +576,59 @@ \fi }\@gtempa } -\newcommand*\xP@bezierlength{{\@tempdimb\z@ +\newcommand*\xP@bezierlength{{\xP@inibigdim +\@tempdimb\z@ \xP@parA\z@ \xP@velocity\z@\xP@velA -\xP@parC.5\p@ +\xP@parC.5\xP@bigdim \xP@velocity\xP@parC\xP@velC -\xP@velocity\p@\xP@velE +\xP@velocity\xP@bigdim\xP@velE \xP@oldpartlen\dimexpr(\xP@velA+4\xP@velC+\xP@velE)/6\relax -\xP@tolerance\xP@max{1sp}{\dimexpr\xP@oldpartlen/\p@\relax}\xP@arclength\xP@parC\xP@velC\p@\xP@velE\xP@oldpartlen +\xP@tolerance\xP@max{1sp}{\dimexpr\xP@oldpartlen/100000\relax}\xP@arclength\xP@parC\xP@velC\xP@bigdim\xP@velE\xP@oldpartlen \global\dimen@i\@tempdimb }\@tempdimb\dimen@i } \newcommand*\xP@velocity[2]{{\@tempdima\dimexpr#1\relax -\xP@velocity@ +\xP@tangent \global\dimen@i\@tempdimb }#2\dimen@i } -\newcommand*\xP@velocity@{\L@p\dimexpr\L@c-\X@p\relax -\U@p\dimexpr\U@c-\Y@p\relax -\d@X3\dimexpr((\X@c+(\L@c-\R@c)*3-\X@p)*\@tempdima/\p@ -+(\R@c-\L@p-\L@c)*2)*\@tempdima/\p@+\L@p\relax -\d@Y3\dimexpr((\Y@c+(\U@c-\D@c)*3-\Y@p)*\@tempdima/\p@ -+(\D@c-\U@p-\U@c)*2)*\@tempdima/\p@+\U@p\relax +\newcommand*\xP@tangent{\d@X3\xP@precbeziertan\X@p\L@c\R@c\X@c\@tempdima +\d@Y3\xP@precbeziertan\Y@p\U@c\D@c\Y@c\@tempdima \xP@veclen } -\newcommand*\xP@velocity@@{\R@p\dimexpr\xP@xb-\xP@xa\relax -\D@p\dimexpr\xP@yb-\xP@ya\relax -\d@X3\dimexpr((\xP@xd+(\xP@xb-\xP@xc)*3-\xP@xa)*\@tempdima/\p@ -+(\xP@xc-\R@p-\xP@xb)*2)*\@tempdima/\p@+\R@p\relax -\d@Y3\dimexpr((\xP@yd+(\xP@yb-\xP@yc)*3-\xP@ya)*\@tempdima/\p@ -+(\xP@yc-\D@p-\xP@yb)*2)*\@tempdima/\p@+\D@p\relax +\newcommand*\xP@tangentvec[1]{{\@tempdima#1\relax +\xP@tangent +\ifdim\@tempdimb=\z@ +\L@p\dimexpr\X@c-\X@p+(\L@c-\R@c)*3\relax +\U@p\dimexpr\Y@c-\Y@p+(\U@c-\D@c)*3\relax +\d@X\dimexpr\L@p*\@tempdima/\xP@bigdim+(\X@p-2\L@c+\R@c)\relax +\d@Y\dimexpr\U@p*\@tempdima/\xP@bigdim+(\Y@p-2\U@c+\D@c)\relax \xP@veclen -} -\newcommand*\xP@normalvec[2]{{\@tempdima#1\relax -\@tempdimc#2\relax -\xP@velocity@ \ifdim\@tempdimb=\z@ -\d@X\dimexpr\xP@xd+(\xP@xb-\xP@xc)*3-\xP@xa\relax -\d@Y\dimexpr\xP@yd+(\xP@yb-\xP@yc)*3-\xP@ya\relax +\d@X\L@p +\d@Y\U@p \xP@veclen \ifdim\@tempdimb=\z@ -\PackageError{xypdf}{Cannot determine a tangent vector to a curve}{}\@tempdimb\p@ +\PackageWarning{xypdf}{Cannot determine a tangent vector to a curve}\@tempdimb\p@ +\fi \fi \fi -\global\dimen@i\dimexpr\@tempdimc*\d@Y/\@tempdimb\relax -\global\dimen3\dimexpr-\@tempdimc*\d@X/\@tempdimb\relax +\global\dimen@i\d@X +\global\dimen3\d@Y +\global\dimen5\@tempdimb }\d@X\dimen@i \d@Y\dimen3\relax +\@tempdimb\dimen5\relax } \newcommand*\xP@arclength[5]{\xP@parE#3\xP@velE#4\xP@parC#1\xP@velC#2\xP@oldpartlen#5\xP@parB\dimexpr(\xP@parC+\xP@parA)/2\relax \xP@velocity\xP@parB\xP@velB \xP@parD\dimexpr(\xP@parE+\xP@parC)/2\relax \xP@velocity\xP@parD\xP@velD \xP@lenA -\dimexpr(\xP@velA+4\xP@velB+\xP@velC)*(\xP@parC-\xP@parA)/393216\relax +\dimexpr(\xP@velA+4\xP@velB+\xP@velC)/6*(\xP@parC-\xP@parA)/\xP@bigdim\relax \xP@lenB -\dimexpr(\xP@velC+4\xP@velD+\xP@velE)*(\xP@parE-\xP@parC)/393216\relax +\dimexpr(\xP@velC+4\xP@velD+\xP@velE)/6*(\xP@parE-\xP@parC)/\xP@bigdim\relax \xP@partlen\dimexpr\xP@lenA+\xP@lenB\relax {\@tempdima\dimexpr\xP@oldpartlen-\xP@partlen\relax \expandafter}\ifdim\ifdim\@tempdima<\z@-\fi\@tempdima>\xP@tolerance @@ -576,8 +686,8 @@ \DN@{\splineset@@}\fi \ifInvisible@\DN@{}\fi \next@ } \xP@hook{xysplinespecialcases@} \newcommand*\xP@xysplinespecialcases@{\ifx\empty\xycrvdrop@ -\ifx\empty\xycrvconn@ \DN@{\splinesolid@}\else \DN@{ \dir{-}}\ifx\next@\xycrvconn@ \DN@{\splinesolid@}\else \DN@{ \dir 2{-}}\ifx\next@\xycrvconn@ \DN@{\splinedoubled@}\else \DN@{ \dir{=}}\ifx\next@\xycrvconn@ \DN@{\splineribboned@}\else \DN@{ \dir {2.}}\ifx\next@\xycrvconn@ \DN@{\splinedoubled@}\else \DN@{ \dir 3{-}}\ifx\next@\xycrvconn@ \DN@{\splinetrebled@}\else \DN@{ \dir {3.}}\ifx\next@\xycrvconn@ \DN@{\splinetrebled@}\else \DN@{ \dir{--}}\ifx\next@\xycrvconn@ \DN@{\splinedashed@}\else \DN@{ \dir{.}}\ifx\next@\xycrvconn@ \DN@{\splinedotted@}\else \DN@{ \dir{:}}\ifx\next@\xycrvconn@ \DN@{\splinedbldotted@}\else \DN@{ \dir3{.}}\ifx\next@\xycrvconn@ \DN@{\xP@splinetrbldotted}\else \DN@{ \dir2{--}}\ifx\next@\xycrvconn@ \DN@{\xP@splinedbldashed}\else \DN@{ \dir3{--}}\ifx\next@\xycrvconn@ \DN@{\xP@splinetrbldashed}\else \DN@{ \dir{~}}\ifx\next@\xycrvconn@ \DN@{\xP@splinesquiggled}\else \DN@{ \dir2{~}}\ifx\next@\xycrvconn@ \DN@{\xP@splinedblsquiggled}\else \DN@{ \dir3{~}}\ifx\next@\xycrvconn@ \DN@{\xP@splinetrblsquiggled}\else \ifdim\splinetol@>\z@ \else \splinedefaulttol@ \fi -\DN@{\splineset@@}\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi +\ifx\empty\xycrvconn@ \DN@{\splinesolid@}\else \DN@{ \dir{-}}\ifx\next@\xycrvconn@ \DN@{\splinesolid@}\else \DN@{ \dir 2{-}}\ifx\next@\xycrvconn@ \DN@{\splinedoubled@}\else \DN@{ \dir{=}}\ifx\next@\xycrvconn@ \DN@{\splineribboned@}\else \DN@{ \dir {2.}}\ifx\next@\xycrvconn@ \DN@{\splinedoubled@}\else \DN@{ \dir 3{-}}\ifx\next@\xycrvconn@ \DN@{\splinetrebled@}\else \DN@{ \dir {3.}}\ifx\next@\xycrvconn@ \DN@{\splinetrebled@}\else \DN@{ \dir{--}}\ifx\next@\xycrvconn@ \DN@{\splinedashed@}\else \DN@{ \dir{.}}\ifx\next@\xycrvconn@ \DN@{\splinedotted@}\else \DN@{ \dir{:}}\ifx\next@\xycrvconn@ \DN@{\splinedbldotted@}\else \DN@{ \dir2{.}}\ifx\next@\xycrvconn@ \DN@{\splinedbldotted@}\else \DN@{ \dir3{.}}\ifx\next@\xycrvconn@ \DN@{\xP@splinetrbldotted}\else \DN@{ \dir2{--}}\ifx\next@\xycrvconn@ \DN@{\xP@splinedbldashed}\else \DN@{ \dir3{--}}\ifx\next@\xycrvconn@ \DN@{\xP@splinetrbldashed}\else \DN@{ \dir{~}}\ifx\next@\xycrvconn@ \DN@{\xP@splinesquiggled}\else \DN@{ \dir2{~}}\ifx\next@\xycrvconn@ \DN@{\xP@splinedblsquiggled}\else \DN@{ \dir3{~}}\ifx\next@\xycrvconn@ \DN@{\xP@splinetrblsquiggled}\else \ifdim\splinetol@>\z@ \else \splinedefaulttol@ \fi +\DN@{\splineset@@}\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \else \DN@{\splineset@@}\fi \ifInvisible@\DN@{}\fi \next@ } \xP@hook{splinedoubled@} @@ -594,7 +704,7 @@ \ifdim\dimen5<\dimen7 \xP@preparespline \ifdim\@tempdimb>\z@ -\ifdim\@tempdimb<\xP@lw bp +\ifdim\@tempdimb<2\dimexpr\xP@preclw\relax \let\next@\xP@splinemultsolid \else \let\next@#1\fi @@ -618,7 +728,6 @@ \else \loop \xP@restorepts -\xP@shaveprec\xP@a\xP@b \xP@offsetsegment \xP@testoffset \ifxP@offsetok @@ -633,6 +742,9 @@ \expandafter\xP@paintsolid@ \fi } +\@ifdefinable\ifxP@moveto\relax +\@ifdefinable\xP@movetotrue\relax +\@ifdefinable\xP@movetofalse\relax \newif\ifxP@moveto \newcommand*\xP@savepts{\xP@xa\X@p \xP@ya\Y@p @@ -657,55 +769,74 @@ \newcommand*\xP@Tmxy{*\xP@Tmx/\xP@Tmy} \newcommand*\xP@Tmyx{*\xP@Tmy/\xP@Tmx} \newcommand*\xP@Tmzero{*\z@} -\newcommand*\xP@offsetsegment{{\xP@fa\p@ +\newcommand*\xP@offsetsegment{{\xP@tangentvec\xP@a +\xP@xa\dimexpr\xP@precbezierpoly\X@p\L@c\R@c\X@c\xP@a/8+\d@Y*\xP@off/\@tempdimb\relax +\xP@ya\dimexpr\xP@precbezierpoly\Y@p\U@c\D@c\Y@c\xP@a/8-\d@X*\xP@off/\@tempdimb\relax +\xP@scaleT +\xP@Tax\d@X +\xP@Tay\d@Y +\xP@E\@tempdimb +\xP@tangentvec\xP@b +\xP@xd\dimexpr\xP@precbezierpoly\X@p\L@c\R@c\X@c\xP@b/8+\d@Y*\xP@off/\@tempdimb\relax +\xP@yd\dimexpr\xP@precbezierpoly\Y@p\U@c\D@c\Y@c\xP@b/8-\d@X*\xP@off/\@tempdimb\relax +\xP@scaleT +\xP@Tdx-\d@X +\xP@Tdy-\d@Y +\xP@F\@tempdimb +\xP@M\z@ +\xP@Max\xP@M\xP@Tdx +\xP@Max\xP@M\xP@Tdy +\xP@L\dimexpr\xP@Tax*\xP@Tdx/\xP@M+\xP@Tay*\xP@Tdy/\xP@M\relax +\xP@tm\dimexpr(\xP@a+\xP@b)/2\relax +\ifdim\xP@L>\dimexpr\xP@E*\xP@F/\xP@M*49/50\relax +\d@X-\dimexpr\xP@Tay+\xP@Tdy\relax +\d@Y\dimexpr\xP@Tax+\xP@Tdx\relax +\xP@veclen +\xP@A\dimexpr\X@c-\X@p\relax +\xP@B\dimexpr\Y@c-\Y@p\relax +\xP@M\z@ +\xP@Max\xP@M\xP@A +\xP@Max\xP@M\xP@B +\ifdim\xP@M=\z@ +\xP@A\dimexpr\R@c-\L@c\relax +\xP@B\dimexpr\D@c-\U@c\relax +\xP@Max\xP@M\xP@A +\xP@Max\xP@M\xP@B +\fi +\xP@M\dimexpr\d@X*\xP@A/\xP@M+\d@Y*\xP@B/\xP@M\relax +\ifdim\xP@M<\z@ +\multiply\d@X\m@ne +\multiply\d@Y\m@ne +\fi +\else +\xP@tangentvec\xP@tm +\fi +\xP@xm\dimexpr\xP@precbezierpoly\X@p\L@c\R@c\X@c\xP@tm ++8\d@Y*\xP@off/\@tempdimb\relax +\xP@ym\dimexpr\xP@precbezierpoly\Y@p\U@c\D@c\Y@c\xP@tm +-8\d@X*\xP@off/\@tempdimb\relax +\xP@Tmx\d@X +\xP@Tmy\d@Y +\xP@ifabsless\xP@Tmy\xP@Tmx +\let\xP@tmy\xP@Tmyx +\let\xP@tmx\empty +\else +\ifdim\xP@Tmy=\z@ +\let\xP@tmx\xP@Tmzero +\let\xP@tmy\xP@Tmzero +\else +\let\xP@tmy\empty +\let\xP@tmx\xP@Tmxy +\fi +\fi +\xP@fa\p@ \xP@fd\p@ \xP@tm\p@ -\xP@normalvec{.5pt}\xP@off -\xP@xm\dimexpr(\X@p+\X@c+(\L@c+\R@c)*3)+8\d@X\relax -\xP@ym\dimexpr(\Y@p+\Y@c+(\U@c+\D@c)*3)+8\d@Y\relax -\xP@normalvec\z@\xP@off -\xP@xa\dimexpr\X@p+\d@X\relax -\xP@ya\dimexpr\Y@p+\d@Y\relax -\xP@normalvec\p@\xP@off -\xP@xd\dimexpr\X@c+\d@X\relax -\xP@yd\dimexpr\Y@c+\d@Y\relax -\xP@Tax\dimexpr\L@c-\X@p\relax -\xP@Tay\dimexpr\U@c-\Y@p\relax -\ifdim\xP@Tax=\z@ -\ifdim\xP@Tay=\z@ -\xP@Tax\dimexpr\R@c-\X@p\relax -\xP@Tay\dimexpr\D@c-\Y@p\relax -\ifdim\xP@Tax=\z@ -\ifdim\xP@Tay=\z@ -\xP@Tax\dimexpr\X@c-\X@p\relax -\xP@Tay\dimexpr\Y@c-\Y@p\relax -\fi -\fi -\fi -\fi -\multiply\xP@Tax\thr@@ -\multiply\xP@Tay\thr@@ -\xP@Tdx\dimexpr\R@c-\X@c\relax -\xP@Tdy\dimexpr\D@c-\Y@c\relax -\ifdim\xP@Tdx=\z@ -\ifdim\xP@Tdy=\z@ -\xP@Tdx\dimexpr\L@c-\X@c\relax -\xP@Tdy\dimexpr\U@c-\Y@c\relax -\ifdim\xP@Tdx=\z@ -\ifdim\xP@Tdy=\z@ -\xP@Tdx\dimexpr\X@p-\X@c\relax -\xP@Tdy\dimexpr\Y@p-\Y@c\relax -\fi -\fi -\fi -\fi -\multiply\xP@Tdx\thr@@ -\multiply\xP@Tdy\thr@@ \count@\z@ \loop +\xP@offsetpoints \@tempswafalse \ifnum10>\count@ -\xP@offsetpoints \xP@objfun\xP@oldobj \ifdim\xP@oldobj>\xP@maxobjfun\relax\@tempswatrue\fi \fi @@ -716,6 +847,15 @@ \L@c\the\xP@xb\U@c\the\xP@yb\R@c\the\xP@xc\D@c\the\xP@yc \X@c\the\xP@xd\Y@c\the\xP@yd\relax}}\@gtempa } +\newcommand*\xP@scaleT{\xP@B6.28\xP@off +\xP@abs\xP@B +\xP@C\dimexpr\d@X*\xP@B/\@tempdimb\relax +\xP@D\dimexpr\d@Y*\xP@B/\@tempdimb\relax +\xP@A\dimexpr\xP@b-\xP@a\relax +\d@X\dimexpr\xP@C+\d@X*\xP@A/\xP@bigdim\relax +\d@Y\dimexpr\xP@D+\d@Y*\xP@A/\xP@bigdim\relax +\@tempdimb\dimexpr\xP@B+\@tempdimb*\xP@A/\xP@bigdim\relax +} \newcommand*\xP@offsetloop{\xP@C\dimexpr\xP@C/2\relax \xP@G\dimexpr\xP@G/2\relax \xP@ta\dimexpr2\p@-\xP@tm\relax @@ -726,10 +866,8 @@ \xP@F\dimexpr\xP@Tdy*\xP@tb/\p@*\xP@tm/\p@\relax \xP@tb\dimexpr2\p@-3\xP@tm\relax \xP@tc\dimexpr\xP@tb+2\p@\relax -\xP@I\dimexpr(2\xP@Tay\xP@tmx-2\xP@Tax\xP@tmy) -*\xP@tb/\p@*\xP@ta/\p@\relax -\xP@J\dimexpr(2\xP@Tdy\xP@tmx-2\xP@Tdx\xP@tmy) -*\xP@tc/\p@*\xP@tm/\p@\relax +\xP@I\dimexpr(2\xP@Tay\xP@tmx-2\xP@Tax\xP@tmy)*\xP@tb/\p@*\xP@ta/\p@\relax +\xP@J\dimexpr(2\xP@Tdy\xP@tmx-2\xP@Tdx\xP@tmy)*\xP@tc/\p@*\xP@tm/\p@\relax \xP@K\dimexpr((\xP@yd-\xP@ya+(\xP@yb-\xP@yc)*3) *\xP@tm/\p@+(\xP@yc-2\xP@yb+\xP@ya)*2)*12\xP@tmx -((\xP@xd-\xP@xa+(\xP@xb-\xP@xc)*3) @@ -750,7 +888,7 @@ \advance\xP@fd-\xP@tb \advance\xP@tm-\xP@tc \ifdim\xP@tm<\z@\xP@tm\z@\fi -\ifdim\xP@tm>\tw@\p@\xP@tm\tw@\p@\fi +\ifdim\xP@tm>2\p@\xP@tm2\p@\fi \fi \advance\count@\@ne } @@ -769,7 +907,7 @@ \xP@M\xP@tm \advance\xP@tm-\xP@tc \ifdim\xP@tm<\z@\xP@tm\z@\fi -\ifdim\xP@tm>\tw@\p@\xP@tm\tw@\p@\fi +\ifdim\xP@tm>2\p@\xP@tm2\p@\fi {\xP@offsetpoints \xP@objfun\xP@M \expandafter}\ifdim\xP@M>\xP@oldobj @@ -779,24 +917,8 @@ \xP@validsolfalse \fi } -\newcommand*\xP@objfun[1]{\xP@D\xP@bezierpoly\xP@xa\xP@xb\xP@xc\xP@xd\xP@tm -\xP@D\dimexpr\xP@D-\xP@xm\relax -\xP@H\xP@bezierpoly\xP@ya\xP@yb\xP@yc\xP@yd\xP@tm -\xP@H\dimexpr\xP@H-\xP@ym\relax -\xP@Tmx\dimexpr\X@p-\X@c+\L@c-\R@c\relax -\xP@Tmy\dimexpr\Y@p-\Y@c+\U@c-\D@c\relax -\xP@ifabsless\xP@Tmy\xP@Tmx -\let\xP@tmy\xP@Tmyx -\let\xP@tmx\empty -\else -\ifdim\xP@Tmy=\z@ -\let\xP@tmx\xP@Tmzero -\let\xP@tmy\xP@Tmzero -\else -\let\xP@tmy\empty -\let\xP@tmx\xP@Tmxy -\fi -\fi +\newcommand*\xP@objfun[1]{\xP@D\dimexpr\xP@bezierpoly\xP@xa\xP@xb\xP@xc\xP@xd\xP@tm-\xP@xm\relax +\xP@H\dimexpr\xP@bezierpoly\xP@ya\xP@yb\xP@yc\xP@yd\xP@tm-\xP@ym\relax \xP@C\xP@beziertan\xP@xa\xP@xb\xP@xc\xP@xd\xP@tm \xP@G\xP@beziertan\xP@ya\xP@yb\xP@yc\xP@yd\xP@tm \xP@L\dimexpr\xP@G\xP@tmx-\xP@C\xP@tmy\relax @@ -804,10 +926,10 @@ \xP@Max#1\xP@D \xP@Max#1\xP@H \xP@Max#1\xP@L -\ifdim#1>4843165sp -#1\maxdimen +#1\ifdim#1>4843165sp +\maxdimen \else -#1\dimexpr\xP@D*\xP@D/\p@+\xP@H*\xP@H/\p@+\xP@L*\xP@L/\p@\relax +\dimexpr\xP@D*\xP@D/\p@+\xP@H*\xP@H/\p@+\xP@L*\xP@L/\p@\relax \fi } \newcommand*\xP@offsetpoints{\xP@xb\dimexpr\xP@xa+\xP@Tax*\xP@fa/196608\relax @@ -818,11 +940,20 @@ \newcommand*\xP@bezierpoly[5]{\dimexpr(((#4-#1+(#2-#3)*3)*#5/\p@+(#1-2#2+#3)*6)*#5/\p@+(#2-#1)*12)*#5/\p@ +#1*8\relax } +\newcommand*\xP@precbezierpoly[5]{\dimexpr(((#4-#1+(#2-#3)*3)*2*#5/\xP@bigdim+(#1-2#2+#3)*6)*2*#5/\xP@bigdim ++(#2-#1)*12)*2*#5/\xP@bigdim+#1*8\relax +} \newcommand*\xP@beziertan[5]{\dimexpr((#4-#1+(#2-#3)*3)*3*#5/32768+(#1-2#2+#3)*24)*#5/\p@+(#2-#1)*24\relax } +\newcommand*\xP@precbeziertan[5]{\dimexpr((#4-#1+(#2-#3)*3)*#5/\xP@bigdim+(#1-2#2+#3)*2)*#5/\xP@bigdim ++#2-#1\relax +} \@ifdefinable\xP@varone\relax \@ifdefinable\xP@vartwo\relax \@ifdefinable\xP@varthree\relax +\@ifdefinable\ifxP@validsol\relax +\@ifdefinable\xP@validsoltrue\relax +\@ifdefinable\xP@validsolfalse\relax \newif\ifxP@validsol \newcommand*\xP@solvelinearsystem{{\xP@scalerow\xP@A\xP@B\xP@C\xP@D \xP@scalerow\xP@E\xP@F\xP@G\xP@H @@ -872,12 +1003,15 @@ \fi \multiply\xP@E\m@ne \multiply\xP@I\m@ne +\ifdim\xP@A=\z@ +\else \advance\xP@F\dimexpr\xP@B*\xP@E/\xP@A\relax \advance\xP@G\dimexpr\xP@C*\xP@E/\xP@A\relax \advance\xP@H\dimexpr\xP@D*\xP@E/\xP@A\relax \advance\xP@J\dimexpr\xP@B*\xP@I/\xP@A\relax \advance\xP@K\dimexpr\xP@C*\xP@I/\xP@A\relax \advance\xP@L\dimexpr\xP@D*\xP@I/\xP@A\relax +\fi \count@\m@ne \xP@ifabsless\xP@F\xP@G\@tempcnta\z@\xP@M\xP@G \else\@tempcnta\m@ne\xP@M\xP@F\fi @@ -897,8 +1031,11 @@ \let\xP@vartwo\@tempa \xP@swapnum\xP@scaletwo\xP@scalethree \fi +\ifdim\xP@F=\z@ +\else \advance\xP@K\dimexpr-\xP@G*\xP@J/\xP@F\relax \advance\xP@L\dimexpr-\xP@H*\xP@J/\xP@F\relax +\fi \xP@ifabsless{\dimexpr\xP@L/60\relax}{\dimexpr\xP@K/\xP@scalethree\relax}\xP@validsoltrue \xP@varthree\dimexpr\xP@L*(\xP@scalethree*\p@)/\xP@K\relax \else @@ -1005,12 +1142,9 @@ \xP@H\dimexpr\xP@H*\maxdimen/\xP@sb\relax \xP@L\dimexpr\xP@L*\maxdimen/\xP@sb\relax \fi -\xP@Aba\dimexpr\xP@A*\xP@D/\xP@sa+\xP@E*\xP@H/\xP@sa -+\xP@I*\xP@L/\xP@sa\relax -\xP@Abb\dimexpr\xP@B*\xP@D/\xP@sa+\xP@F*\xP@H/\xP@sa -+\xP@J*\xP@L/\xP@sa\relax -\xP@Abc\dimexpr\xP@C*\xP@D/\xP@sa+\xP@G*\xP@H/\xP@sa -+\xP@K*\xP@L/\xP@sa\relax +\xP@Aba\dimexpr\xP@A*\xP@D/\xP@sa+\xP@E*\xP@H/\xP@sa+\xP@I*\xP@L/\xP@sa\relax +\xP@Abb\dimexpr\xP@B*\xP@D/\xP@sa+\xP@F*\xP@H/\xP@sa+\xP@J*\xP@L/\xP@sa\relax +\xP@Abc\dimexpr\xP@C*\xP@D/\xP@sa+\xP@G*\xP@H/\xP@sa+\xP@K*\xP@L/\xP@sa\relax \xP@AAba\dimexpr\xP@A*\xP@Aba/\xP@sa+\xP@B*\xP@Abb/\xP@sa +\xP@C*\xP@Abc/\xP@sa\relax \xP@AAbb\dimexpr\xP@E*\xP@Aba/\xP@sa+\xP@F*\xP@Abb/\xP@sa @@ -1050,21 +1184,22 @@ \fi }}\@gtempa } +\@ifdefinable\ifxP@offsetok\relax +\@ifdefinable\xP@offsetoktrue\relax +\@ifdefinable\xP@offsetokfalse\relax \newif\ifxP@offsetok -\newcommand*\xP@maxdev{.1\p@} -\newcommand*\xP@maxobjfun{.005\p@} -\newcommand*\xP@testoffset{{\gdef\@gtempa{\xP@offsetoktrue}\def\@gtempb{\ifdim\xP@ti<1.85pt}\xP@ti.1pt +\newcommand*\xP@maxdev{.1pt} +\newcommand*\xP@maxobjfun{.005pt} +\newcommand*\xP@testoffset{{\gdef\xP@afteroffsetok{\xP@offsetoktrue}\def\xP@offsetokif{\ifdim\xP@ti<1.85pt}\xP@ti.1pt \loop -\xP@tip -\dimexpr\xP@a*131072/\xP@bigdim+(\xP@b-\xP@a)*\xP@ti/\xP@bigdim\relax -\L@p-\xP@bezierpoly\xP@xa\xP@xb\xP@xc\xP@xd\xP@tip -\U@p-\xP@bezierpoly\xP@ya\xP@yb\xP@yc\xP@yd\xP@tip -\xP@valA\xP@bezierpoly\X@p\L@c\R@c\X@c\xP@ti -\advance\xP@valA\L@p -\xP@valB\xP@bezierpoly\Y@p\U@c\D@c\Y@c\xP@ti -\advance\xP@valB\U@p -\@tempdima\dimexpr\xP@tip/2\relax -\xP@velocity@@ +\xP@tip\dimexpr\xP@a+(\xP@b-\xP@a)*\xP@ti/131072\relax +\L@p-\xP@precbezierpoly\xP@xa\xP@xb\xP@xc\xP@xd\xP@tip +\U@p-\xP@precbezierpoly\xP@ya\xP@yb\xP@yc\xP@yd\xP@tip +\xP@valA\dimexpr\xP@bezierpoly\X@p\L@c\R@c\X@c\xP@ti+\L@p\relax +\xP@valB\dimexpr\xP@bezierpoly\Y@p\U@c\D@c\Y@c\xP@ti+\U@p\relax +\d@X3\xP@precbeziertan\xP@xa\xP@xb\xP@xc\xP@xd\xP@tip +\d@Y3\xP@precbeziertan\xP@ya\xP@yb\xP@yc\xP@yd\xP@tip +\xP@veclen \@tempdimc\dimexpr(\xP@b-\xP@a)*\@tempdimb/\xP@bigdim\relax \xP@abs\@tempdimc \ifdim.01pt<\@tempdimc @@ -1075,7 +1210,7 @@ \xP@abs\xP@devB \@tempdima\dimexpr\xP@devA+\xP@devB\relax \else -\ifdim.0005pt>\@tempdimc +\ifdim\@tempdimc=\z@ \@tempdima\z@ \else {\d@X\xP@valA @@ -1096,23 +1231,23 @@ \xP@transformcoor\X@c\Y@c \xP@findzero }\fi -\@gtempb +\xP@offsetokif \advance\xP@ti.1pt \repeat -\expandafter}\@gtempa +\expandafter}\xP@afteroffsetok } +\newcommand*\xP@afteroffsetok{} +\newcommand*\xP@offsetokif{} \newcommand*\xP@transformcoor[2]{\advance#1\L@p \advance#2\U@p \@tempdima\dimexpr#1*\d@X/\@tempdimb+#2*\d@Y/\@tempdimb\relax #2\dimexpr#2*\d@X/\@tempdimb-#1*\d@Y/\@tempdimb\relax #1\@tempdima } -\newcommand*\xP@findzero{\xP@setleftvalue\tw@ -\xP@setrightvalue\tw@ -\ifdim\xP@valB<\z@\xP@reversecoeff\fi +\newcommand*\xP@findzero{\xP@setleftvalue{.05}\xP@setrightvalue{.05}\ifdim\xP@valB<\z@\xP@reversecoeff\fi \ifdim\xP@valA>\z@ \@tempswatrue -\@for\@tempa:={\thr@@,4,5,7,10,20}\do{\if@tempswa +\@for\@tempa:={.1,.15,.2,.25,.35,.5,1.1}\do{\if@tempswa \xP@setleftvalue\@tempa \ifdim\xP@valA<\z@\@tempswafalse\fi \if@tempswa @@ -1125,8 +1260,9 @@ \fi }\if@tempswa \L@p\xP@ti -\xP@valA\dimexpr\xP@bezierpoly\X@p\L@c\R@c\X@c\L@p\relax -\ifdim\xP@valA>\z@ +\xP@valA\xP@bezierpoly\X@p\L@c\R@c\X@c\L@p +\ifdim\xP@valA<\z@ +\xP@setrightvalue{.05}\else \U@p\L@p \xP@valB\xP@valA \fi @@ -1151,12 +1287,12 @@ \xP@valB\dimexpr\xP@bezierpoly\Y@p\U@c\D@c\Y@c\L@p+8\xP@off\relax \xP@abs\xP@valA \xP@abs\xP@valB -\ifdim\dimexpr\xP@valA+\xP@valB\relax>\xP@maxdev +\ifdim\dimexpr\xP@valA+\xP@valB\relax>\xP@maxdev\relax \xP@failed \fi } -\newcommand*\xP@failed{\global\let\@gtempb\iffalse -\gdef\@gtempa{\xP@offsetokfalse}} +\newcommand*\xP@failed{\global\let\xP@offsetokif\iffalse +\gdef\xP@afteroffsetok{\xP@offsetokfalse}} \newcommand*\xP@reversecoeff{\multiply\X@p\m@ne \multiply\L@c\m@ne \multiply\R@c\m@ne @@ -1164,27 +1300,42 @@ \multiply\xP@valA\m@ne \multiply\xP@valB\m@ne } -\newcommand*\xP@setleftvalue[1]{\L@p\dimexpr\xP@ti-\p@/#1\relax -\ifdim\L@p<\z@\L@p\z@\fi -\xP@valA\dimexpr\xP@bezierpoly\X@p\L@c\R@c\X@c\L@p\relax +\newcommand*\xP@setleftvalue[1]{\L@p\dimexpr\xP@ti-#1\p@\relax +\ifdim\L@p<-.1pt\L@p-.1pt\fi +\xP@valA\xP@bezierpoly\X@p\L@c\R@c\X@c\L@p } -\newcommand*\xP@setrightvalue[1]{\U@p\dimexpr\xP@ti+\p@/#1\relax -\ifdim\U@p>2\p@\U@p2\p@\fi -\xP@valB\dimexpr\xP@bezierpoly\X@p\L@c\R@c\X@c\U@p\relax +\newcommand*\xP@setrightvalue[1]{\U@p\dimexpr\xP@ti+#1\p@\relax +\ifdim\U@p>2.1\p@\U@p2.1\p@\fi +\xP@valB\xP@bezierpoly\X@p\L@c\R@c\X@c\U@p } \newcommand*\xP@splinedbldashed{\xP@checkspline\xP@splinemultdashed\xP@doublestroke} \newcommand*\xP@splinetrbldashed{\xP@checkspline\xP@splinemultdashed\xP@trblstroke} -\newcommand*\xP@splinemultdashed{\@tempcnta\numexpr2*\numexpr(\@tempdimb+\xydashl@)/(2*\xydashl@)\relax-1\relax +\newcommand*\xP@splinemultdashed[1]{\xP@testcont\xP@dashmacro +\@tempcnta +\ifxP@splinecont +\numexpr2*((\@tempdimb-\xydashl@/3)/(2*\xydashl@))\relax +\else +\numexpr2*((\@tempdimb+\xydashl@)/(2*\xydashl@))-1\relax +\fi \ifnum\@tempcnta>\@ne -\expandafter\xP@splinemultdashed@ +\xP@splinemultdashed@#1\else +\ifnum\@tempcnta=\@ne +\xP@splinemultsolid#1 \else -\expandafter\xP@splinemultsolid +\xP@savec \fi +\fi +\global\let\xP@lastpattern\xP@dashmacro } \newcommand*\xP@splinemultdashed@[1]{{\xP@inibigdim \@tempdima\dimexpr\@tempdimb/\@tempcnta\relax \xP@temppar\z@ -\toks@{}\@tempcnta\z@ +\toks@{}\xP@savec +\ifodd\@tempcnta +\else +\xP@slide +\fi +\@tempcnta\z@ \loop \advance\@tempcnta\@ne \xP@append\toks@{\ifodd\@tempcnta\noexpand\xP@paintdash\fi @@ -1199,6 +1350,7 @@ \xP@oldpar \fi \@temptokena{}\xP@setsolidpat +\global\let\xP@lastpattern\xP@dashmacro \@for\@tempa:={#1}\do{\the\toks@}\xP@stroke{\the\@temptokena}}} \newcommand*\xP@paintdash[2]{\xP@paintsolid{\dimexpr#1*\xP@bigdim/\xP@lastpar\relax}{\dimexpr#2*\xP@bigdim/\xP@lastpar\relax}} \xP@hook{splinedbldotted@} @@ -1206,82 +1358,124 @@ \xP@checkspline\xP@splinemultdotted\xP@doublestroke} \newcommand*\xP@splinetrbldotted{\let\xP@normalmult\tw@ \xP@checkspline\xP@splinemultdotted\xP@trblstroke} -\newcommand*\xP@multidottedpat{\def\xP@pattern{2 J [0 \xP@dim{\xydashh@}]0 d }} +\newcommand*\xP@multidottedpat{\def\xP@pattern{0 J [\xP@lw\xP@dim{\xydashh@-\xP@preclw}]0 d}\global\let\xP@lastpattern\xP@dotmacro +} \@ifdefinable\xP@normalmult\relax \newcommand\xP@splinemultdotted[1]{{\xP@inibigdim -\@tempdima\dimexpr\@tempdimb/\numexpr\@tempdimb/131072+1\relax\relax \xP@temppar\z@ -\toks@{}\loop +\xP@testcont\xP@dotmacro +\ifxP@splinecont +\@tempdimc\dimexpr\@tempdimb/(\@tempdimb/131072+1)\relax +\@tempdima\dimexpr\@tempdimc-\xP@preclw/2\relax +\xP@slide +\@tempdima\@tempdimc +\else +\@tempdima\dimexpr\xP@preclw/2\relax +\xP@slide +\@tempdima\dimexpr\@tempdimb-\xP@preclw\relax +\ifdim\@tempdima<\z@\@tempdima\z@\fi +\@tempdima\dimexpr\@tempdima/(\@tempdima/131072+1)\relax +\fi +\xP@savec +\toks@{}\ifdim\xP@temppar<\xP@bigdim +\loop \xP@append\toks@{\noexpand\xP@paintdot{\the\xP@temppar}}\xP@oldpar\xP@temppar \xP@slide \ifdim\xP@temppar<\xP@bigdim \repeat -\xP@lastpar -\ifdim\dimexpr\xP@bigdim-\xP@oldpar\relax<\dimexpr\xP@temppar-\xP@bigdim\relax -\xP@oldpar +\xP@velocity\xP@bigdim\xP@tempvel +\ifdim +\ifdim\xP@preclw<\xP@tempvel +\dimexpr2\xP@bigdim-\xP@oldpar-\xP@preclw*\xP@bigdim/\xP@tempvel\relax +\else +-\maxdimen +\fi<\xP@temppar +\xP@temppar\xP@oldpar \else -\xP@temppar \xP@append\toks@{\noexpand\xP@paintdot{\the\xP@temppar}}\fi +\@tempdima\dimexpr\xP@preclw/2\relax +\xP@slide +\xP@lastpar\xP@temppar \@temptokena{}\the\toks@ \xP@multidottedpat -\xP@stroke{\the\@temptokena}}} +\xP@stroke{\the\@temptokena}\else +\global\let\xP@lastpattern\empty +\fi +}} \newcommand*\xP@slide{{\xP@slide@ \global\dimen@i\xP@temppar }\xP@temppar\dimen@i } -\newcommand*\xP@slide@{\xP@velocity{\xP@temppar*\p@/\xP@bigdim}\xP@tempvel -\xP@velocity{(\xP@temppar+\xP@bigdim/\numexpr\@tempdimb/131072+1\relax)*\p@/\xP@bigdim}\xP@tempvel@ -\ifdim\dimexpr\@tempdima*1310720/(\xP@tempvel+\xP@tempvel@)\relax>\p@ +\newcommand*\xP@slide@{\xP@velocity\xP@temppar\xP@tempvel +\@tempdimc\dimexpr\xP@bigdim*\@tempdima/\@tempdimb\relax +\count@\z@ +\@tempswatrue +\loop +\xP@velocity{\xP@temppar+\@tempdimc}\xP@tempvel@ +\ifdim\dimexpr\@tempdima*4/13\relax>\xP@tempvel@ +\@tempswafalse +\else +\xP@parinc\dimexpr\@tempdima*\xP@bigdim/\xP@tempvel@ +-(\xP@tempvel+\xP@tempvel@)/2*\@tempdimc/\xP@tempvel@\relax +\advance\@tempdimc\xP@parinc +\ifdim\@tempdimc>.12\xP@bigdim +\@tempswafalse +\else +\ifdim\xP@parinc=\z@ +\@tempswafalse +\else +\ifnum\count@=9\relax +\@tempswafalse +\fi +\fi +\fi +\fi +\if@tempswa +\advance\count@\@ne +\repeat +\ifdim\xP@temppar<5461pt +\ifdim\@tempdimc>.1\xP@bigdim +\@tempswatrue +\fi +\fi +\if@tempswa {\dimen5\xP@temppar \advance\xP@temppar.1\xP@bigdim +\ifdim\xP@temppar>5461pt\xP@temppar5461pt\fi \dimen7\xP@temppar \xP@shaveprec{\dimen5}{\dimen7}\xP@bezierlength -\advance\@tempdima-\@tempdimb -\expandafter}\expandafter\@tempdima\the\@tempdima\relax -\advance\xP@temppar.1\xP@bigdim +\global\dimen@i\dimexpr\@tempdima-\@tempdimb\relax +\global\dimen3\xP@temppar +}\@tempdima\dimen@i +\xP@temppar\dimen3\relax \expandafter\xP@slide@ \else -\advance\xP@temppar -\dimexpr2\xP@bigdim*\@tempdima/(\xP@tempvel+\xP@tempvel@)\relax +\advance\xP@temppar\@tempdimc \fi } -\newcommand*\xP@paintdot[1]{\xP@temppar\dimexpr#1*\xP@bigdim/\xP@lastpar\relax -\L@p\dimexpr\L@c-\X@p\relax -\D@p\dimexpr\U@c-\Y@p\relax -\d@X3\dimexpr((\X@c-\X@p+(\L@c-\R@c)*3)*\xP@temppar/\xP@bigdim -+(\R@c-\L@p-\L@c)*2)*\xP@temppar/\xP@bigdim+\L@p\relax -\d@Y3\dimexpr((\Y@c-\Y@p+(\U@c-\D@c)*3)*\xP@temppar/\xP@bigdim -+(\D@c-\D@p-\U@c)*2)*\xP@temppar/\xP@bigdim+\D@p\relax -\xP@veclen -\ifdim\@tempdimb=\z@ -\d@X3\dimexpr(\X@c-\X@p+(\L@c-\R@c)*3)*\xP@temppar/\xP@bigdim -+(\R@c-\L@p-\L@c)\relax -\d@Y3\dimexpr(\Y@c-\Y@p+(\U@c-\D@c)*3)*\xP@temppar/\xP@bigdim -+(\D@c-\D@p-\U@c)\relax -\xP@veclen -\ifdim\@tempdimb=\z@ -\d@X3\dimexpr\X@c-\X@p+(\L@c-\R@c)*3\relax -\d@Y3\dimexpr\Y@c-\Y@p+(\U@c-\D@c)*3\relax -\xP@veclen -\fi -\fi -\U@p\dimexpr\R@c-\L@p-\L@c\relax -\R@p\dimexpr\X@c-3\R@c+3\L@c-\X@p\relax -\X@min\dimexpr\D@c-\D@p-\U@c\relax -\Y@min\dimexpr\Y@c-3\D@c+3\U@c-\Y@p\relax -\xP@posX\dimexpr\X@p+(3\L@p+(3\U@p+\R@p*\xP@temppar/\xP@bigdim)*\xP@temppar/\xP@bigdim)*\xP@temppar/\xP@bigdim\relax -\xP@posY\dimexpr\Y@p+(3\D@p+(3\X@min+\Y@min*\xP@temppar/\xP@bigdim)*\xP@temppar/\xP@bigdim)*\xP@temppar/\xP@bigdim\relax -\L@p\dimexpr\xydashh@*\d@Y/\@tempdimb/2\relax -\U@p\dimexpr-\xydashh@*\d@X/\@tempdimb/2\relax +\newcommand*\xP@paintdot[1]{\@tempdima\dimexpr#1*\xP@bigdim/\xP@lastpar\relax +\xP@tangent +\xP@posX\dimexpr\xP@precbezierpoly\X@p\L@c\R@c\X@c\@tempdima/8\relax +\xP@posY\dimexpr\xP@precbezierpoly\Y@p\U@c\D@c\Y@c\@tempdima/8\relax +\@tempdima\dimexpr(\xydashh@+\xP@preclw/\xP@normalmult)/2\relax +\L@p\dimexpr\d@Y*\@tempdima/\@tempdimb\relax +\U@p\dimexpr-\d@X*\@tempdima/\@tempdimb\relax \xP@append\@temptokena{\xP@coor{\xP@posX+\L@p*\xP@normalmult}{\xP@posY+\U@p*\xP@normalmult}m \xP@coor{\xP@posX-\L@p*(\xP@normalmult+\@ne)}{\xP@posY-\U@p*(\xP@normalmult+\@ne)}l }} \newcommand*\xP@splinesquiggled{\xP@checkspline\xP@splinesquiggled@\z@} \newcommand*\xP@splinedblsquiggled{\xP@checkspline\xP@splinesquiggled@\xP@doublestroke} \newcommand*\xP@splinetrblsquiggled{\xP@checkspline\xP@splinesquiggled@\xP@trblstroke} \newcommand*\xP@splinesquiggled@[1]{{\xP@inibigdim +\xP@testcont\xP@oddsquigglemacro +\ifxP@splinecont +\def\xP@squigsign{-}\else +\let\xP@squigsign\empty +\fi +\xP@savec \@tempcnta=\numexpr\@tempdimb/\xybsqll@\relax \ifnum\@tempcnta<\tw@\@tempcnta\tw@\fi \multiply\@tempcnta\tw@ \@tempdima\dimexpr\@tempdimb/\@tempcnta\relax +\xP@squiglen\@tempdima \xP@temppar\z@ \toks@{}\@tempcnta\z@ \loop @@ -1293,72 +1487,88 @@ \xP@lastpar \ifodd\@tempcnta \xP@oldpar +\advance\@tempcnta\m@ne \else \xP@temppar \xP@append\toks@{\noexpand\xP@paintsquiggle{\the\xP@temppar}}\fi \@temptokena{}\xP@setsolidpat +\global\expandafter\let\expandafter\xP@lastpattern +\ifodd\numexpr\@tempcnta/2\if\xP@squigsign-+1\fi\relax +\xP@oddsquigglemacro +\else +\xP@evensquigglemacro +\fi \@for\@tempa:={#1}\do{\let\xP@dosquiggle\xP@dosquiggle@ \count@\z@ \the\toks@ -}\xP@stroke{\the\@temptokena} -}} -\newcommand*\xP@paintsquiggle[1]{\xP@temppar\dimexpr#1*\xP@bigdim/\xP@lastpar\relax -\L@p\dimexpr\L@c-\X@p\relax -\D@p\dimexpr\U@c-\Y@p\relax -\d@X3\dimexpr((\X@c-\X@p+(\L@c-\R@c)*3)*\xP@temppar/\xP@bigdim -+(\R@c-\L@p-\L@c)*2)*\xP@temppar/\xP@bigdim+\L@p\relax -\d@Y3\dimexpr((\Y@c-\Y@p+(\U@c-\D@c)*3)*\xP@temppar/\xP@bigdim -+(\D@c-\D@p-\U@c)*2)*\xP@temppar/\xP@bigdim+\D@p\relax -\xP@veclen -\ifdim\@tempdimb=\z@ -\d@X3\dimexpr(\X@c-\X@p+(\L@c-\R@c)*3)*\xP@temppar/\xP@bigdim -+(\R@c-\L@p-\L@c)\relax -\d@Y3\dimexpr(\Y@c-\Y@p+(\U@c-\D@c)*3)*\xP@temppar/\xP@bigdim -+(\D@c-\D@p-\U@c)\relax -\xP@veclen -\ifdim\@tempdimb=\z@ -\d@X3\dimexpr\X@c-\X@p+(\L@c-\R@c)*3\relax -\d@Y3\dimexpr\Y@c-\Y@p+(\U@c-\D@c)*3\relax -\xP@veclen -\fi -\fi -\U@p\dimexpr\R@c-\L@p-\L@c\relax -\R@p\dimexpr\X@c-3\R@c+3\L@c-\X@p\relax -\X@min\dimexpr\D@c-\D@p-\U@c\relax -\Y@min\dimexpr\Y@c-3\D@c+3\U@c-\Y@p\relax -\xP@posX\dimexpr\X@p+(3\L@p+(3\U@p+\R@p*\xP@temppar/\xP@bigdim)*\xP@temppar/\xP@bigdim)*\xP@temppar/\xP@bigdim\relax -\xP@posY\dimexpr\Y@p+(3\D@p+(3\X@min+\Y@min*\xP@temppar/\xP@bigdim)*\xP@temppar/\xP@bigdim)*\xP@temppar/\xP@bigdim\relax -\advance\xP@posX\dimexpr-\d@Y*\numexpr\@tempa\relax/\@tempdimb\relax -\advance\xP@posY\dimexpr\d@X*\numexpr\@tempa\relax/\@tempdimb\relax -\L@p\dimexpr\d@X*\@tempdima/\@tempdimb\relax -\U@p\dimexpr\d@Y*\@tempdima/\@tempdimb\relax +}\xP@stroke{\the\@temptokena}}} +\newcommand*\xP@paintsquiggle[1]{\@tempdima\dimexpr#1*\xP@bigdim/\xP@lastpar\relax +\xP@tangent +\xP@posX\dimexpr\xP@precbezierpoly\X@p\L@c\R@c\X@c\@tempdima/8-\d@Y*(\@tempa)/\@tempdimb\relax +\xP@posY\dimexpr\xP@precbezierpoly\Y@p\U@c\D@c\Y@c\@tempdima/8+\d@X*(\@tempa)/\@tempdimb\relax +\L@p\dimexpr\d@X*\xP@squiglen/\@tempdimb\relax +\U@p\dimexpr\d@Y*\xP@squiglen/\@tempdimb\relax \R@p\dimexpr\L@p*543339720/1311738121\relax \D@p\dimexpr\U@p*543339720/1311738121\relax \X@min\dimexpr\L@p*362911648/967576667\relax \Y@min\dimexpr\U@p*362911648/967576667\relax -\X@max\dimexpr(\L@p+\U@p)*173517671/654249180\relax -\Y@max\dimexpr(\L@p-\U@p)*173517671/654249180\relax +\X@max\dimexpr(\L@p+\xP@squigsign\U@p)*173517671/654249180\relax +\Y@max\dimexpr(\L@p-\xP@squigsign\U@p)*173517671/654249180\relax \xP@dosquiggle \ifnum\count@=\thr@@\relax\count@\z@\else\advance\count@\@ne\fi } \@ifdefinable\xP@dosquiggle@\relax -\newcommand*\xP@dosquiggle@{\edef\next@{\xP@coor{\xP@posX}{\xP@posY}m \xP@coor{\xP@posX+\Y@max}{\xP@posY+\X@max}}\let\xP@dosquiggle\xP@dosquiggle@@ +\newcommand*\xP@dosquiggle@{\edef\next@{\xP@coor{\xP@posX}{\xP@posY}m +\xP@coor{\xP@posX+\Y@max}{\xP@posY+\xP@squigsign\X@max}}\let\xP@dosquiggle\xP@dosquiggle@@ } \newcommand*\xP@dosquiggle@@{\xP@append\@temptokena{\next@\expandafter\xP@coor \ifcase\count@ -{\xP@posX-\Y@max}{\xP@posY-\X@max}\xP@coor\xP@posX\xP@posY +{\xP@posX-\Y@max}{\xP@posY-\xP@squigsign\X@max}\xP@coor\xP@posX\xP@posY \or -{\xP@posX-\D@p-\X@min}{\xP@posY+\R@p-\Y@min}\xP@coor{\xP@posX-\D@p}{\xP@posY+\R@p}\or -{\xP@posX-\X@max}{\xP@posY+\Y@max}\xP@coor\xP@posX\xP@posY +{\xP@posX-\xP@squigsign\D@p-\X@min}{\xP@posY+\xP@squigsign\R@p-\Y@min}\xP@coor{\xP@posX-\xP@squigsign\D@p}{\xP@posY+\xP@squigsign\R@p}\or +{\xP@posX-\X@max}{\xP@posY+\xP@squigsign\Y@max}\xP@coor\xP@posX\xP@posY \or -{\xP@posX+\D@p-\X@min}{\xP@posY-\R@p-\Y@min}\xP@coor{\xP@posX+\D@p}{\xP@posY-\R@p}\fi c }\edef\next@{\expandafter\xP@coor +{\xP@posX+\xP@squigsign\D@p-\X@min}{\xP@posY-\xP@squigsign\R@p-\Y@min}\xP@coor{\xP@posX+\xP@squigsign\D@p}{\xP@posY-\xP@squigsign\R@p}\fi c }\edef\next@{\expandafter\xP@coor \ifcase\count@ -{\xP@posX+\Y@max}{\xP@posY+\X@max}\or -{\xP@posX-\D@p+\X@min}{\xP@posY+\R@p+\Y@min}\or -{\xP@posX+\X@max}{\xP@posY-\Y@max}\or -{\xP@posX+\D@p+\X@min}{\xP@posY-\R@p+\Y@min}\fi +{\xP@posX+\Y@max}{\xP@posY+\xP@squigsign\X@max}\or +{\xP@posX-\xP@squigsign\D@p+\X@min}{\xP@posY+\xP@squigsign\R@p+\Y@min}\or +{\xP@posX+\X@max}{\xP@posY-\xP@squigsign\Y@max}\or +{\xP@posX+\xP@squigsign\D@p+\X@min}{\xP@posY-\xP@squigsign\R@p+\Y@min}\fi }} +\newcommand*\xP@lastX{} +\newcommand*\xP@lastY{} +\newcommand*\xP@lastpattern{} +\newcommand*\xP@solidmacro{solid} +\newcommand*\xP@dotmacro{dot} +\newcommand*\xP@dashmacro{dash} +\newcommand*\xP@evensquigglemacro{evensquiggle} +\newcommand*\xP@oddsquigglemacro{oddsquiggle} +\CheckCommand*\xy{\ifmmode\expandafter\xymath@\else\expandafter\xynomath@\fi} +\renewcommand*\xy{\global\let\xP@lastpattern\empty +\ifmmode\expandafter\xymath@\else\expandafter\xynomath@\fi} +\newcommand*\xP@savec{\xdef\xP@lastX{\the\X@c}\xdef\xP@lastY{\the\Y@c}} +\@ifdefinable\ifxP@splinecont\relax +\@ifdefinable\xP@splineconttrue\relax +\@ifdefinable\xP@splinecontfalse\relax +\newif\ifxP@splinecont +\newcommand*\xP@testcont[1]{\xP@splinecontfalse +\ifxP@cont +\ifx\xP@lastpattern#1\ifdim\xP@lastX=\X@p +\ifdim\xP@lastY=\Y@p +\xP@splineconttrue +\fi +\fi +\fi +\fi +} \xP@endgobble +\@ifdefinable\ifxP@cont\relax +\@ifdefinable\xP@conttrue\relax +\@ifdefinable\xP@contfalse\relax +\newif\ifxP@cont +\newcommand*\xypdfcontpatternon{\xP@conttrue} +\newcommand*\xypdfcontpatternoff{\xP@contfalse} +\xP@conttrue \endinput %% %% End of file `xypdf.sty'. -- cgit v1.2.3