%%%%%%%%%% texpictex.tex %%%%%%%%%%
%
% texpictex.tex -- The following macros over-ride certain definitions in the
% PiCTeX macro package. The net effect is that line-drawing is done using
% the \special's used by texpic (tpic). Several DVI printers understand
% and handle these specials.
%
% Currently, only straight lines are translated. Recently, I added a
% clipping routine to clip to the bounding box.
%
% If people extend this to included elliptic circles and quadratics,
% please forward the extensions to me (quads are used in the \arrow
% macro, making them very slow).
%
% Dirk Grunwald
% Univ. of Illinois
% grunwald@m.cs.uiuc.edu
%
\def\makebangletter{\catcode`\!=11\relax}
\def\makebangother{\catcode`\!=12\relax}
%
\makebangletter
%
% The units that texpic deals in. You should define it this way instead
% of simply saying ``0.001in'' because the difference in resolution
% actually makes a big difference
%
\newdimen\!tpu
\!tpu=1in
\divide\!tpu by 1000
%%%
%%      \!maptpus       -- map a PiCTeX dimension to a TeXPiC dimension
%%                      using the \!tpu conversion factor.
%%
%%      uses: dimen0
%%
\def\!maptpus#1#2 {\dimen0=#1\divide \dimen0 by \!tpu #2=\dimen0}
%
% **  \setplotsymbol ({PLOTSYMBOL} [ ] < , >)
% **  Save PLOTSYMBOL away in an hbox for use with curve plotting routines
% **  See Subsection 5.2 of the manual.
\def\setplotsymbol(#1#2){%
  \!setputobject{#1}{#2}
  \setbox\!plotsymbol=\box\!putobject%
  \!plotsymbolxshift=\!xshift 
  \!plotsymbolyshift=\!yshift
%
% Additions: compute size of dot, convert to TPUs and issue a pensize
%  
  \!dimenB=\wd\!plotsymbol
  \!dimenC=\ht\!plotsymbol
  \advance\!dimenC by \dp\!plotsymbol
  \ifdim\!dimenB<\!dimenC \!dimenF=\!dimenC  \else \!dimenF=\!dimenB\fi
  \!maptpus{\!dimenF}{\!countC}
  \special{pn \the\!countC}
  \ignorespaces}

\setplotsymbol({\fiverm .})%       ** initialize plotsymbol

% **  The following routine is used to draw a "solid" line between (xS,yS)
% **  and (xE,yE).  Points are spaced nearly every  \plotsymbolspacing length
% **  along the line.  
%
%       Note: this is a replacement for PicTeX \!linearsolid.
%       If line clipping is enabled, the line to be drawn is
%       clipped using \!clipline. If there's anything left
%       to draw after clipping, it's drawn. If clipping is off,
%       the line is simply drawn. In either case, line drawing
%       is done by \!texpicline.
%
\def\!linearsolid{%
%  \typeout{Using texpictex linearsolid}%
  \let\!nextLinearAct=\!texpicline
  \expandafter\ifx \!initinboundscheck \relax
    \else \!clipline \if!InBounds \else \let\!nextLinearAct=\relax \fi \fi%
  \!nextLinearAct%
}
%
% Texpic has increasing origin in the upper left corner, while
% pictex has origin in bottom left corner. Ergo, we flip the signs
% for y-coordinates.
%
\def\!texpicline{%
\advance\!xS by -\!xorigin
\advance\!xE by -\!xorigin
\advance\!yS by -\!yorigin
\advance\!yE by -\!yorigin
\!maptpus{\!xS}{\!countC} \!maptpus{\!yS}{\!countD} \!countD=-\!countD%
\special{pa \the\!countC \space \the\!countD}%
\!maptpus{\!xE}{\!countC} \!maptpus{\!yE}{\!countD} \!countD=-\!countD%
\special{pa \the\!countC \space \the\!countD}\special{fp}%
\ignorespaces}
%
%%%
%       Code to support line clipping
%
%       Line clipping routine. Clips to bounding box specified
%       by (!checkleft, !checkbot) and (!checkright, !checktop).
%       Note that this box is only defined if \initboundscheckon
%       has been called.
%
%       The clipping algorithm was published in ACM TOG Vol 3 No 1
%       by people at Berkeley, but I've forgotten the complete reference.
%       This was translated from a version I wrote in C.
%
%%
%       After calling \!cliplines, !InBounds tells you if the line contains
%       any points within the clipping window.
%
\newif\if!InBounds
%
%%
%       \!clipt -- this corresponds to the routine by the same name
%       in the published algorithm.
%
%       Dimens used are descibed below. All are grouped and know that
%       PiCTeX doesn't use dimen0..9. Variable names are taken from
%       the TOG article. The junk on the r.h.s. is indenting information
%
%       Globals:        dimen8 corresponds to t0
%                       dimen9 corresponds to t1
%
%       clipt           dimen0 corresponds to p
%                       dimen1 corresponds to q
%                       dimen2 corresponds to r
%
%       !fastclip       Uses bounding boxes
%
%       !clipline       passes dimen3 to clipt as p
%                       passes dimen4 to clipt as q
%                       uses   dimen0, dimen2
%
%
\def\!clipt#1#2{%
  \dimen0=#1 \relax \dimen1=#2 \relax
  \ifdim \dimen0 < \!zpt%                                               >0
        \!divide{\dimen1}{\dimen0}{\dimen2}%
        \ifdim \dimen2 > \dimen9%                                       >1
                \global\!InBoundsfalse
        \else%                                                          =1
                \ifdim \dimen2 > \dimen8 \dimen8=\dimen2 \fi
        \fi%                                                            <1
  \else \ifdim \dimen0 > \!zpt%                                         =0>1
        \!divide{\dimen1}{\dimen0}{\dimen2}%
        \ifdim \dimen2 < \dimen8%                                       >2
                \global\!InBoundsfalse
        \else%                                                          =2
                \ifdim \dimen2 < \dimen9 \dimen9=\dimen2 \fi
        \fi%                                                            <2
   \else%                                                               =1
        \ifdim \dimen1 < \!zpt \global\!InBoundsfalse \fi
   \fi%                                                                 <1
  \fi%                                                                  <0
}
%
%       fastclipcheck
%
\def\!fastclip#1#2{%
  \ifdim #1<\!checkleft \global\!InBoundsfalse \else
    \ifdim #1>\!checkright \global\!InBoundsfalse \else
      \ifdim #2<\!checkbot \global\!InBoundsfalse \else
         \ifdim #2>\!checktop \global\!InBoundsfalse \else
         \fi 
      \fi
    \fi
  \fi}
%
%       clipline        - clip a line to the current bounding box.
%       assumes line is in (!xS, !yS) and extends to (!xE,!yE) and that
%       \!xdiff and \!ydiff has been set up. This is normally done
%       in \!lstart.
%
%       \!clipline first checks to see if the start & end points are
%       conainted in the clipping box. If the simple compare works,
%       then no clipping is done, else \!doclip is called to
%       do the actually clipping computations.
%
\def\!clipline{%
   \!!initinboundscheck
   \!InBoundstrue
   \!fastclip{\!xS}{\!yS}%
   \!fastclip{\!xE}{\!yE}%
   \if!InBounds\else\!doclip\fi}
%
\def\!doclip{%
\begingroup%
  \global\!InBoundstrue%
  \dimen8=0pt
  \dimen9=1pt
  %
  \dimen3=-\!xdiff
  \dimen4=\!xS \advance\dimen4 by -\!checkleft%         fromX-minX
  \!clipt{\dimen3}{\dimen4}%
%
  \if!InBounds% 0
    \dimen3=\!xdiff
    \dimen4=\!checkright \advance\dimen4 by -\!xS%      maxX - fromX
    \!clipt{\dimen3}{\dimen4}%
%
    \if!InBounds% 1
%
      \dimen3=-\!ydiff
      \dimen4=\!yS \advance\dimen4 by -\!checkbot%      fromY-minY
      \!clipt{\dimen3}{\dimen4}%
%
      \if!InBounds% 2
%
        \dimen3=\!ydiff
        \dimen4=\!checktop \advance\dimen4 by -\!yS%    maxY-fromY
        \!clipt{\dimen3}{\dimen4}%
%
        \if!InBounds% 3
          \dimen0=1pt
%
%       The following \if's truncate the line based on the solution
%       to the parametric solution to the bounding box.
%
%       Note that we don't have a \!multiply, the equivilent to \!divide.
%       The code below compute X * Y as (x / ( 1/ Y)), which is far
%       from optimal.
%
          \ifdim\dimen9 < \dimen0% 4
            \ifdim\dimen9=\!zpt%        handle multiply by zero
             \global\!xE=\!xS
             \global\!yE=\!yS
             \!InBoundsfalse%
            \else
             \!divide{\dimen0}{\dimen9}{\dimen2}%
%
             \dimen3=\!xdiff \!divide{\dimen3}{\dimen2}{\dimen4}%
             \global\!xE=\dimen4 \global\advance\!xE by \!xS
%
             \dimen3=\!ydiff \!divide{\dimen3}{\dimen2}{\dimen4}%
             \global\!yE=\dimen4 \global\advance\!yE by \!yS
            \fi
          \fi% 4
          \ifdim\dimen8 > \!zpt% 4
             \!divide{\dimen0}{\dimen8}{\dimen2}%
%
             \dimen3=\!xdiff \!divide{\dimen3}{\dimen2}{\dimen4}%
             \global\advance\!xS by \dimen4
%
             \dimen3=\!ydiff \!divide{\dimen3}{\dimen2}{\dimen4}%
             \global\advance\!yS by \dimen4
          \fi% 4
        \fi% 3
      \fi% 2
    \fi% 1
  \fi% 0
\endgroup}
%
\makebangother

\endinput
