supp-tpi.mkii / last modification: 2020-01-30 14:15
%D \module
%D   [       file=supp-tpi,
%D        version=1997.07.05,
%D          title=\CONTEXT\ Support Macros,
%D       subtitle=\TPIC\ Conversion,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

%D This modules implements the conversion of graphic \TPIC\
%D specials using \METAPOST.
%D
%D We reimplement the \TPIC\ specials using the special
%D mimmicking mechanism implemented in the support module
%D \type{supp-spe} as well as the \METAPOST\ run||time support
%D implemented in \type{supp-mps}.

\ifnum\texengine=\luatexengine
    \expandafter \endinput
\fi

\ifx\undefined\writestatus         \input supp-mis.mkii \relax \fi
\ifx\undefined\mimmickspecials     \input supp-spe.mkii \relax \fi
\ifx\undefined\MPgraphicbox        \input supp-mps.mkii \relax \fi
\ifx\undefined\dogetEPSboundingbox \input supp-eps.mkii \relax \fi

\writestatus{loading}{ConTeXt Support Macros / TPIC Conversion}

%D Beware: we haven't activated both mechanism yet. This is
%D to be done in the calling module.

\unprotect

%D When we want to mimmick \TPIC\ specials in \PDFTEX, we need
%D to map its graphic primitives into \PDF\ ones. The main
%D problem in doing so is that \PDF\ does not support b-splines
%D directly and also does not offer us something to draw arcs.
%D Of course all this scan be implemented in \TEX, and the
%D first implementation of this module did so, but the results
%D were not that satisfying. Not having used these specials
%D before, I had for instance to find out that the \TPIC\
%D specials were not that unambiguesly defined.
%D
%D Then, while discussing something else, Sebastian Ratz told
%D me that the Web2c implementation that \PDFTEX\ is base upon,
%D offers some rather discutable, but nevertheless handy
%D feature:
%D
%D \starttyping
%D \write18{execute program with arguments}
%D \stoptyping
%D
%D Knowing this, I immediatelly decided to throw away the old
%D conversion macros and use the marvelous \METAPOST, \TEX\
%D related, drawing program to do the conversion in as high a
%D quality as possible.
%D
%D implementation we're going to present here, not only uses
%D for drawing purposes, but also uses the more efficient
%D \METAPOST\ features to store the path.
%D
%D \in{Table}[tab:TPIC specials] lists the \TPIC\ specials as
%D mentioned in the \LATEX\ Graphics Companion and the
%D relevant part of the \DVIPS\ source. This list shows us
%D that we have to store the path before we can use it, simply
%D because we don't know in advance what actions to apply on
%D it.
%D
%D \placetable[here][tab:TPIC specials]{The \TPIC\ special syntax.}
%D \starttable[|||l|]
%D \HL
%D \NC \bf tag \NC \bf arguments               \NC \bf meaning        \NC\SR
%D \HL
%D \NC pn      \NC $w$                         \NC set linewidth      \NC\FR
%D \NC pa      \NC $x$ $y$                     \NC add point to path  \NC\MR
%D \NC fp      \NC                             \NC draw/fill path     \NC\MR
%D \NC ip      \NC                             \NC fill path          \NC\MR
%D \NC da      \NC $l$                         \NC draw dashed path   \NC\MR
%D \NC dt      \NC $l$                         \NC draw doted path    \NC\MR
%D \NC sp      \NC $d$                         \NC draw spline        \NC\MR
%D \NC ar      \NC $x$ $y$ $r_x$ $r_y$ $b$ $e$ \NC draw (partial) arc \NC\MR
%D \NC ia      \NC $x$ $y$ $r_x$ $r_y$ $b$ $e$ \NC fill (partial) arc \NC\MR
%D \NC sh      \NC $s$                         \NC fill next path     \NC\LR
%D \HL
%D \stoptable

%D The first problem we have to take care of is the fact that
%D there is no decent begin or end of the drawing process
%D defined. We can however be quite sure that writers of
%D packages using these specials will put them into a box,
%D simply because else this is the most common used way to
%D treat something \TEX\ as as a whole, like:
%D
%D \starttyping
%D \hbox{\special{}\special{}...}
%D \stoptyping
%D
%D We just start a picture as soon as the first special is
%D encountered, so this becomes:
%D
%D \starttyping
%D \hbox{\openpicture\newspecial{}\newspecial{}...
%D \stoptyping

%D The first step in opening the picture is to start a group.
%D Now we can savely use the egroup that closes the box to also
%D end the picture.

% BETER: check for context and include mp-tool.mp

\def\startTPICspecials
  {\bgroup
   \let\startTPICspecials\relax
   \aftergroup\stopTPICspecials
   \resetMPdrawing
   \startMPdrawing
     input mp-tool.mpii ;
     pair p[];
   \stopMPdrawing}

%D As soon as we begin a picture, we inhibit nesting by
%D relaxing the start macro. The first \METAPOST\ action we
%D take is declaring an array of pairs named $p$.

%D Ending the picture is invoked by closing the current group.
%D Because the \TPIC\ picture comes out mirrored, we have to
%D reflect the current \METAPOST\ picture, stored in the system
%D variable {\it currentpicture}, around the $x$-axis.

\def\stopTPICspecials
  {\startMPdrawing
     currentpicture:=currentpicture reflectedabout ((0,0),(4095,0));
   \stopMPdrawing
   \MPdrawingdonetrue
   \setbox\MPgraphicbox\hbox
     {\getMPdrawing}%
   \setbox\MPgraphicbox\hbox to \zeropoint
     {\kern-\wd\MPgraphicbox
      \vbox to \zeropoint{\box\MPgraphicbox\vss}\hss}%
   \ht\MPgraphicbox\zeropoint
   \wd\MPgraphicbox\zeropoint
   \dp\MPgraphicbox\zeropoint
   \box\MPgraphicbox
   \egroup}

%D Here the macro \type{\stopwritingMPgraphic} has to take care
%D of executing and including the \METAPOST\ code.

%D We need to keep track of the number of elements that form
%D the path. This is needed because we don't know in advance
%D how the points are to be connected.

\newcount\TPICcounter

%D When a path is draw, we can connect the points using a
%D smooth curve of drawing straight lines. A closed path can be
%D drawn or filled.

\newif\ifTPICdraw
\newif\ifTPICfill
\newif\ifTPICcurve

%D The \TPIC\ specials permit specifying the line and fill
%D color as well as the linetype, which can be solid, dashed or
%D dotted. We'll save those specifications as a \METAPOST\
%D string, using:

\let\TPIClinetype =\empty
\let\TPICgrayscale=\empty

%D The magic reduction factor $.07227$ is needed to map the
%D \TPIC\ $1/1000$ of an inch to \POSTSCRIPT\ points. We cannot
%D delegate this task to \METAPOST\ because this program does
%D not accept values greater than 4095.

%D I won't discuss all the specifics used in implementing
%D the specials. The \METAPOST\ part is rather trivial. Many
%D specials have much in common, so the amout of code is not
%D that large.

\redefinespecial pa \using#1 #2\endspecial
  {\startTPICspecials
   \bgroup
   \global\advance\TPICcounter 1
   \dimen0=#1pt \dimen0=.07227\dimen0
   \dimen2=#2pt \dimen2=.07227\dimen2
   \startMPdrawing
     p[\the\TPICcounter]:=(\the\dimen0,\the\dimen2);
   \stopMPdrawing
   \egroup}

\redefinespecial pn \using#1\endspecial
  {\startTPICspecials
   \bgroup
   \dimen0=#1pt \dimen0=.07227\dimen0
   \startMPdrawing
     pickup pencircle scaled \the\dimen0;
   \stopMPdrawing
   \egroup}

\redefinespecial sh \using#1\endspecial
  {\startTPICspecials
   \bgroup
   \edef\g{#1}%
   \edef\g{\ifx\g\empty.5\else#1\fi}%
   \xdef\TPICgrayscale{withcolor (\g,\g,\g)}%
   \egroup}

\redefinespecial wh \using#1\endspecial
  {\mimmickspecial sh \using0\endspecial}

\redefinespecial bk \using#1\endspecial
  {\mimmickspecial sh \using1\endspecial}

\redefinespecial da \using#1\endspecial
  {\startTPICspecials
   \bgroup
   \edef\l{#1}%
   \ifx\l\empty
     \gdef\TPIClinetype{dashed evenly}%
   \else
     \dimen0=#1in
     \ifdim\dimen0<\!!zeropoint \dimen0=-\dimen0\fi
     \edef\f{\the\dimen0 \space}%
     \dimen0=.5\dimen0
     \edef\h{\the\dimen0 \space}%
     \xdef\TPIClinetype{dashed dashpattern (on \h off \f on \h)}%
   \fi
   \egroup
   \TPICcurvefalse\TPICdrawtrue
   \drawTPICpath\using#1\endspecial}

\redefinespecial dt \using#1\endspecial
  {\startTPICspecials
   \bgroup
   \edef\l{#1}%
   \xdef\TPIClinetype{dashed withdots \ifx\l\empty\else scaled #1in\fi}%
   \egroup
   \TPICcurvefalse\TPICdrawtrue
   \drawTPICpath\using#1\endspecial}

\redefinespecial fp \using#1\endspecial
  {\startTPICspecials
   \TPICcurvefalse\TPICdrawtrue
   \ifdim0#1pt=\!!zeropoint
     \drawTPICpath\using#1\endspecial
   \else\ifdim0#1pt<\!!zeropoint
     \mimmickspecial dt\using#1\endspecial
   \else
     \mimmickspecial da\using#1\endspecial
   \fi\fi}

\redefinespecial sp
  {\startTPICspecials\TPICdrawtrue\TPICcurvetrue\drawTPICpath}

\redefinespecial ip
  {\startTPICspecials\TPICfilltrue\drawTPICpath}

\redefinespecial ar
  {\startTPICspecials\TPICdrawtrue\drawTPICarc}

\redefinespecial ia
  {\startTPICspecials\TPICfilltrue\drawTPICarc}

%D These substitutes use two auxiliary macros that take care of
%D actually drawing the shape or arc. Here we use the stored
%D linetype (solid, dashed, dotted) and color (grayscale).

\def\drawTPICpath\using#1\endspecial
  {\bgroup
   \ifTPICdraw
     \def\TPICgrayscale{}%
   \fi
   \startMPdrawing
     \ifTPICfill fill\fi\ifTPICdraw draw\fi\space
     for i:=1 upto \the\TPICcounter-1:
       p[i]\ifTPICcurve..\else--\fi
     endfor
     p[\the\TPICcounter]
     \ifTPICfill\ifTPICcurve..\else--\fi cycle \fi
     \TPIClinetype\space\TPICgrayscale;
   \stopMPdrawing
   \resetTPICvariables
   \egroup}

%D I have to admit that at the moment I wrote this macro, I
%D could not write this piece of \METAPOST. Fortunately
%D Thortsen Ohl promptly answered the question I posted to the
%D \METAFONT\ discussion list.

\def\drawTPICarc\using#1 #2 #3 #4 #5 #6\endspecial
  {\bgroup
   \ifTPICdraw
     \def\TPICgrayscale{}%
   \fi
   \dimen 0=#1pt\dimen 0=.07227\dimen 0
   \dimen 2=#2pt\dimen 2=.07227\dimen 2
   \dimen10=#3pt\dimen10=.14454\dimen10
   \dimen12=#4pt\dimen12=.14454\dimen12
   \dimen20=#5pt
   \dimen22=#6pt
   \startMPdrawing
     \ifTPICfill fill\fi\ifTPICdraw draw\fi \space
     \ifTPICfill\else subpath 4/3.14159*(\the\dimen20,\the\dimen22) of \fi
     fullcircle xscaled \the\dimen10 \space yscaled \the\dimen12 \space
     shifted (\the\dimen0,\the\dimen2)
     \TPIClinetype \space \TPICgrayscale;
   \stopMPdrawing
   \resetTPICvariables
   \egroup}

%D Resetting the variables need to be done globally because we
%D cannot be sure if any further grouping is used by the
%D envelopping macros.

\def\resetTPICvariables
  {\global\TPICcounter\zerocount
   \global\TPICfillfalse
   \global\TPICdrawfalse
   \global\let\TPIClinetype\empty
   \global\let\TPICgrayscale\empty}

%D I have to admit that by using the \METAPOST\ B‚zier cubics
%D routines these implementation does produce better curves
%D then most \DVI\ drivers do using the \TPIC\ prescribed
%D b-splines. Take for instance the sequence:
%D
%D \starttyping
%D \special{pa 2000 1000}
%D \special{pa 1000 2000}
%D \special{pa 0000 1000}
%D \special{pa 1000 0000}
%D \special{pa 2000 1000}
%D \special{sp}
%D \stoptyping
%D
%D One would expect that this code produced a closed circle,
%D but the curve that comes out using b-splines is far from
%D round. We can however savely asume that the arc producing
%D specials will be used for drawing circle fragments, while
%D the path specials will be used for arbitraty curves. And for
%D b-splines to produce nice curves, one will often use many
%D points to get the desired results. Therefore, using the
%D \METAPOST\ B‚zier curves will certainly produce similar and
%D even better graphics, except in those rare cases where one
%D uses delinberately the not that accurate features of
%D b-splines. Hereby the user is warned.

\protect \endinput