home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 266_01 / conlib.c < prev    next >
C/C++ Source or Header  |  1990-07-05  |  19KB  |  599 lines

  1. /*  PLOX keyword handling modules  04-21-90       FILE: CONLIB.C
  2.          Robert L. Patton, Jr.
  3.          1713 Parkcrest Terrace
  4.          Arlington, TX 76012
  5. */
  6. #define HOLD 10
  7. #define FNLEN 15
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include "PLOX.H"
  12. #include "CONLIB.H"
  13. #include "DATLIB.H"
  14. #include "DRAWLIB.H"
  15. #include "PXLIB.H"
  16. #include "WORDLIB.H"
  17.                            /* Global scaling parameters */
  18. static SCALING Xfit = {0.0,20.0,4.32},
  19.                Yfit = {0.0,25.0,2.88};
  20. static int     Xlen = 6*INCH-1, Ylen = 4*INCH-1;
  21.  
  22. /*   ======= */
  23. void Unknown (Word)
  24. /*   ======= */
  25. char *Word;
  26. {
  27. char Phrase[31] = "  unknown keyword: ";
  28.   strncat (Phrase,Word,12);
  29.   PauseMsg (Phrase);
  30. }
  31. /*   ===== */
  32. void ARcon (Sentence)
  33. /*   =====           Handles an AREA specification */
  34. char *Sentence;
  35. {
  36.   #define INSET INCH/2
  37.   char       Word[HOLD+1];
  38.   double     Xarea, Yarea, Xsize, Ysize;
  39.   static int Xa, Ya;
  40.   int        Border;
  41.  
  42.   #ifdef DEBUG
  43.   printf("ARcon:%s\n",Sentence);
  44.   #endif
  45.  
  46.   GetWord (Sentence, Word, HOLD);
  47.   Xa = INSET; Xlen = XMAX - 2 * INSET;
  48.   Ya = INSET; Ylen = YMAX - 2 * INSET;
  49.   Border = NO;
  50.   while (Word[0] != ' ') {
  51.  
  52.     if (EQUAL (Word,"at")) {
  53.       GetVal (Sentence, &Xarea);
  54.       GetVal (Sentence, &Yarea);
  55.       if (Xarea<=0 || Yarea<=0)
  56.         PauseMsg("  invalid AREA location, default used ");
  57.       else {
  58.         Xa = PIXELS (Xarea);
  59.         Ya = PIXELS (Yarea);
  60.       }
  61.     }
  62.     else if (EQUAL (Word,"size")) {
  63.       GetVal (Sentence, &Xsize);
  64.       GetVal (Sentence, &Ysize);
  65.       if (Xsize==0 || Ysize==0)
  66.         PauseMsg("  invalid AREA size, default used");
  67.       else {
  68.         Xlen = PIXELS (Xsize);
  69.         Ylen = PIXELS (Ysize);
  70.       }
  71.     }
  72.     else if (EQUAL (Word,"outline")) Border = YES;
  73.  
  74.     else Unknown (Word);
  75.  
  76.     GetWord (Sentence, Word, HOLD);
  77.   }
  78.   PX_Origin (Xa, Ya);
  79.   if (Border) Box (0, 0, Xlen, Ylen);
  80. }
  81. /*@@                                     CONLIB-2 */
  82. /*   ===== */
  83. void AXcon (Sentence)
  84. /*   =====           Handles an AXIS specification */
  85. char *Sentence;
  86. {
  87.   #define EXACT 1
  88.   char       Dir, Locus, Word[HOLD+1];
  89.   double     From, To;
  90.   int        Axlen, Boxes, Side, Visible, Xa, Ya;
  91.   SCALING    AxFit;
  92.  
  93.   #ifdef DEBUG
  94.   printf("AXcon:%s\n",Sentence);
  95.   #endif
  96.  
  97.   GetWord (Sentence, Word, HOLD);
  98.  
  99.                    /* Set all defaults */
  100.  
  101.   From = 0.0;  To = 0.0;  Boxes = 0;
  102.   Locus = 'L'; Dir = 'V', Side = -1;
  103.   Visible = YES;
  104.                           /* Interpret the specification */
  105.   while (Word[0] != ' ') {
  106.  
  107.       if      (EQUAL (Word,"invisible")) Visible = NO;
  108.       else if (EQUAL (Word,"above")) {Locus='A' ;Dir='H'; Side=-1;}
  109.       else if (EQUAL (Word,"below")) {Locus='B' ;Dir='H'; Side= 1;}
  110.       else if (EQUAL (Word,"right")) {Locus='R' ;Dir='V'; Side= 1;}
  111.       else if (EQUAL (Word,"left"))  {Locus='L' ;Dir='V'; Side=-1;}
  112.       else if (EQUAL (Word,"boxes")) GetInt (Sentence, &Boxes);
  113.       else if (EQUAL (Word,"from")) GetVal (Sentence, &From);
  114.       else if (EQUAL (Word,"to"))  GetVal (Sentence, &To);
  115.       else Unknown (Word);
  116.  
  117.       GetWord (Sentence, Word, HOLD);
  118.   }
  119.   Axlen = (Dir=='V'? Ylen: Xlen);
  120.   Xa = (Locus=='R'? Xlen: 0);
  121.   Ya = (Locus=='A'? Ylen: 0);
  122.   if (From==0.0 && To==0.0) {
  123.     PauseMsg("  axis range not given, using 0 to 100");
  124.     To = 100.0;
  125.   }
  126.   Scale (From, To, Axlen, EXACT, &Boxes, &AxFit);
  127.   if (Dir == 'H') CopyScale (&AxFit, &Xfit);
  128.   else            CopyScale (&AxFit, &Yfit);
  129.   if (Visible) AxNum (Xa, Ya, Dir, Side, Axlen, &AxFit, Boxes);
  130. }
  131. /*@@                                       CONLIB-3 */
  132. void BRcon (Sentence)
  133. /*   =====           Handles a BAR specification */
  134. #define BRBUF  12
  135. char *Sentence;
  136. {
  137.   double  Value;           /* local storage */
  138.   double  Width;           /* user bar spec */
  139.   float   Base;
  140.   float   *Xptr, *Yptr;    /* pointers to plot data */
  141.   char    Word[BRBUF+1];   /* local string storage */
  142.   char    Fname[FNLEN+1];  /* file name for data */
  143.   char    Dtype[MAXITEMS]; /* data type for any item */
  144.   char    Dir;             /* bar direction (H,V) */
  145.   int     Ix, Iy;          /* item no. in data line */
  146.   int     Foot, Thick;     /* pixel bar specs */
  147.   int     Rank, Of, Offset;/* abutted bar specs */
  148.   int     Xfoot, Yfoot;    /* local storage */
  149.   int     Xbar, Ybar;
  150.   int     BaseSet;         /* flag for user set base */
  151.   int     Points;          /* no. of data points */
  152.   int     Hatch, Gap;      /* bar hatch pattern code */
  153.   int     k;               /* local storage */
  154.  
  155.   #ifdef DEBUG
  156.   printf("BRcon:%s\n",Sentence);
  157.   #endif
  158.  
  159.   GetWord (Sentence, Word, BRBUF);
  160.  
  161.                  /* set defaults */
  162.   Fname[0] = ' ';
  163.   for (k=0; k<MAXITEMS; k++) Dtype[k] = 'N';
  164.   Ix = 1;         Iy = 2;
  165.   Width = .125;   Dir = 'V';  BaseSet = NO;
  166.   Rank = 1;       Of = 1;
  167.   Hatch = 0;      Gap = 4;
  168.                         /* Interpret specification */
  169.   while (Word[0]!=' ') {
  170.       if      (EQUAL (Word,"file"))  GetWord (Sentence, Fname, FNLEN);
  171.       else if (EQUAL (Word,"items")) SetItems (Sentence, &Ix, &Iy);
  172.       else if (EQUAL (Word,"item"))  SetDtype (Sentence, Dtype);
  173.       else if (EQUAL (Word,"base")) {GetVal (Sentence, &Value);
  174.                                      Base = (float) Value;
  175.                                      BaseSet = YES; }
  176.       else if (EQUAL (Word,"width")) GetVal (Sentence, &Width);
  177.       else if (EQUAL (Word,"hor") ||
  178.                EQUAL (Word,"H")          ) Dir = 'H';
  179.       else if (EQUAL (Word,"ver") ||
  180.                EQUAL (Word,"V")          ) Dir = 'V';
  181.       else if (EQUAL (Word,"hatch")) {
  182.                 GetWord (Sentence, Word, BRBUF);
  183.                 if      (EQUAL (Word,"H") ||
  184.                          EQUAL (Word,"hor"))    Hatch = 1;
  185.                 else if (EQUAL (Word,"V") ||
  186.                          EQUAL (Word,"ver"))    Hatch = 2;
  187.                 else if (EQUAL (Word,"right"))  Hatch = 3;
  188.                 else if (EQUAL (Word,"left"))   Hatch = 4;
  189.                 else if (EQUAL (Word,"square")) Hatch = 5;
  190.                 else if (EQUAL (Word,"blank"))  Hatch = 6;
  191.                 else    Unknown (Word);
  192.       }
  193.       else if (EQUAL (Word,"gap")) {
  194.                 GetInt (Sentence, &Gap);
  195.                 if (Gap <= 0) {
  196.                   PauseMsg ("  positive number must follow 'gap'");
  197.                   Gap = 4;
  198.                 }
  199.       }
  200. /*@@                                    CONLIB-4 */
  201.       else if (EQUAL (Word,"abut")) {
  202.                 GetInt (Sentence, &Rank);
  203.                 GetInt (Sentence, &Of);
  204.                 if (Rank > Of || Rank <= 0) {
  205.                   PauseMsg ("  error in abut specification");
  206.                   Rank = 1; Of = 1;
  207.                 }
  208.       }
  209.       else    Unknown (Word);
  210.       GetWord (Sentence, Word, BRBUF);
  211.   }
  212.                            /* Draw bars */
  213.   if (Fname[0]==' ')
  214.     PauseMsg("  no data file given - no bars drawn");
  215.   else {
  216.     GetTwo (Fname, &Xptr, Dtype[Ix-1], Ix, &Yptr, Dtype[Iy-1], Iy);
  217.     Points = (int) *Xptr;
  218.     if (Points == 0) {printf("  no data found for: "); PauseMsg(Fname);}
  219.     else {
  220.       PX_Style (Hatch, Gap);
  221.       Thick = PIXELS (Width);
  222.       Offset = (Thick * ((Rank<<1) - Of - 1)) / 2;
  223.       if (BaseSet) Foot = Scaled (&Base, Dir=='V'? &Yfit: &Xfit);
  224.       else         Foot = 0;
  225.       printf("  drawing %d bars\n",Points);
  226.       for (k=1; k<=Points; k++) {
  227.         Xbar = Scaled (++Xptr, &Xfit);
  228.         Ybar = Scaled (++Yptr, &Yfit);
  229.         if (Dir == 'V') {Xbar += Offset; Xfoot = Xbar; Yfoot = Foot;}
  230.         else            {Ybar += Offset; Xfoot = Foot; Yfoot = Ybar;}
  231.         Bar (Xfoot, Yfoot, Xbar, Ybar, Dir, Thick, Hatch, Gap);
  232.       }
  233.     }
  234.   }
  235. }
  236. /*@@                                      CONLIB-5 */
  237. void IScon (Sentence)
  238. /*   =====           Handles an ISO (gram) specification */
  239. #define ISBUF  12
  240. char *Sentence;
  241. {
  242.  
  243.   float   Xdata[3];        /* isogram line x points */
  244.   float   Ydata[3];        /* isogram line y points */
  245.   char    Vword[ISBUF+1];  /* local string storage */
  246.   char    Word[ISBUF+1];   /* local string storage */
  247.   char    Dir;             /* direction code (X/Y) */
  248.   char    Form;            /* location format code */
  249.   int     Trace;           /* line type code */
  250.  
  251.   #ifdef DEBUG
  252.   printf("IScon:%s\n",Sentence);
  253.   #endif
  254.   GetWord (Sentence, Word, ISBUF);
  255.  
  256.                  /* set defaults */
  257.   Dir  = 'H';
  258.   Form = 'N';
  259.   strcpy(Vword,"0");
  260.   Xdata[0] = Ydata[0] = 2.0;
  261.   Xdata[1] = Xdata[2] = Ydata[1] = Ydata[2] = 0.0;
  262.   Trace = SOLID;
  263.                            /* Interpret specification */
  264.   while (Word[0] != ' ') {
  265.  
  266.       if      (EQUAL (Word,"at")) GetWord (Sentence,Vword,ISBUF);
  267.       else if (EQUAL(Word,"H") || EQUAL(Word,"hor"))   Dir = 'X';
  268.       else if (EQUAL(Word,"V") || EQUAL(Word,"ver"))   Dir = 'Y';
  269.  
  270.       else if (EQUAL(Word,"form")) {
  271.         Sentence[1] = '1';
  272.         SetDtype (Sentence,&Form);
  273.       }
  274.       else if (LineType (Word,&Trace));
  275.       else Unknown (Word);
  276.  
  277.       GetWord (Sentence, Word, ISBUF);
  278.   }
  279.   Evaluate (Vword,Form,&Xdata[1]);
  280.   if (Dir=='Y') {
  281.     Xdata[2] = Xdata[1];
  282.     Ydata[1] = Yfit.Start;
  283.     Ydata[2] = Ydata[1] + (double) Ylen / Yfit.DeltaP;
  284.   }
  285.   else {
  286.     Ydata[2] = Ydata[1] = Xdata[1];
  287.     Xdata[1] = Xfit.Start;
  288.     Xdata[2] = Xdata[1] + (double) Xlen / Xfit.DeltaP;
  289.   }
  290.   #ifdef ISDEBUG
  291.   ShowScale ('X',1,&Xfit);
  292.   ShowScale ('Y',1,&Yfit);
  293.   printf("Xlen = %d, Ylen = %d\n",Xlen,Ylen);
  294.   printf("Line at %s %c\n",Vword,Form);
  295.   printf("Trace = %o, Dir = %c\n",Trace,Dir);
  296.   printf("Xdata = %.2f, %.2f, %.2f\n",Xdata[0],Xdata[1],Xdata[2]);
  297.   printf("Ydata = %.2f, %.2f, %.2f\n",Ydata[0],Ydata[1],Ydata[2]);
  298.   #endif
  299.   Liner (Xdata,&Xfit,Ydata,&Yfit,Trace,0);
  300. }
  301. /*@@                                       CONLIB-6 */
  302. void LAcon (Sentence)
  303. /*   =====           Handles a LABEL specification */
  304. #define LABUF  12
  305. char *Sentence;
  306. {
  307.   float   Xdata, Ydata;    /* label-locus, data units */
  308.   char    Dir, Justify;    /* text placement codes */
  309.   char    Word[LABUF+1];   /* local string storage */
  310.   char    Xword[LABUF+1];  /* local string storage */
  311.   char    Yword[LABUF+1];  /* local string storage */
  312.   char   *Text;            /* text manip. ptr  */
  313.   char    Xform, Yform;    /* label-locus format codes */
  314.   int     Font, Xt, Yt;    /* text size & location */
  315.   int     TexLen;
  316.  
  317.   #ifdef DEBUG
  318.   printf("LAcon:%s\n",Sentence);
  319.   #endif
  320.  
  321.   GetWord (Sentence, Word, LABUF);
  322.  
  323.                  /* set defaults */
  324.   Font = 1;
  325.   Justify = 'C'; Dir   = 'H';
  326.   Xform   = 'N'; Yform = 'N';
  327.                            /* Interpret specification */
  328.   while (Word[0] != ' ') {
  329.  
  330.       if (EQUAL (Word,"at")) {
  331.         GetWord (Sentence,Xword,LABUF);
  332.         GetWord (Sentence,Yword,LABUF);
  333.       }
  334.       else if (EQUAL(Word,"L") || EQUAL(Word,"left"))   Justify = 'L';
  335.       else if (EQUAL(Word,"R") || EQUAL(Word,"right"))  Justify = 'R';
  336.       else if (EQUAL(Word,"C") || EQUAL(Word,"center")) Justify = 'C';
  337.       else if (EQUAL(Word,"V") || EQUAL(Word,"ver"))    Dir = 'V';
  338.       else if (EQUAL(Word,"H") || EQUAL(Word,"hor"))    Dir = 'H';
  339.       else if (EQUAL(Word,"font")) GetInt (Sentence,&Font);
  340.  
  341.       else if (EQUAL(Word,"xform")) {
  342.         Sentence[1] = '1';
  343.         SetDtype (Sentence,&Xform);
  344.       }
  345.       else if (EQUAL(Word,"yform")) {
  346.         Sentence[1] = '1';
  347.         SetDtype (Sentence,&Yform);
  348.       }
  349.       else if (EQUAL (Word,"text")) {
  350.         Text = Sentence;
  351.         while (*Text == ' ') Text++;
  352.         Evaluate (Xword,Xform,&Xdata);
  353.         Evaluate (Yword,Yform,&Ydata);
  354.         Xt = Scaled (&Xdata,&Xfit);
  355.         Yt = Scaled (&Ydata,&Yfit);
  356.         if (Dir == 'H') {
  357.           TexLen = TxWide (strlen (Text), Font);
  358.           if      (Justify == 'C') Xt -= (TexLen>>1);
  359.           else if (Justify == 'R') Xt -= TexLen;
  360.         }
  361.         PX_Text (Xt, Yt, Font, Dir, Text);
  362.         break;
  363.       }
  364.       else Unknown (Word);
  365.  
  366.       GetWord (Sentence, Word, LABUF);
  367.   }
  368. }
  369. /*@@                                  CONLIB-7 */
  370. /*   ===== */
  371. void LIcon (Sentence)
  372. /*   =====            Handles a LINE specification */
  373. #define LIBUF 20
  374. char * Sentence;
  375. {
  376.   float    *Xptr, *Yptr;    /* pointers to plot data */
  377.   char     Word[LIBUF+1];   /* local string storage */
  378.   char     Fname[FNLEN+1];  /* file name for data */
  379.   char     Dtype[MAXITEMS]; /* data type for any item */
  380.   int      Ix, Iy;          /* item no. in data line */
  381.   int      k, Points;       /* local storage */
  382.   int      Node, Trace;     /* point and line type */
  383.  
  384.   #ifdef DEBUG
  385.   printf("LIcon:%s\n",Sentence);
  386.   #endif
  387.  
  388.   GetWord (Sentence, Word, LIBUF);
  389.  
  390.                        /* set defaults */
  391.   Fname[0] = ' ';
  392.   for (k=0; k<MAXITEMS; k++) Dtype[k] = 'N';
  393.   Ix = 1; Trace = SOLID;
  394.   Iy = 2;  Node = 0;
  395.                          /* interpret specification */
  396.   while (Word[0]!=' ') {
  397.       if      (LineType (Word,&Trace));
  398.       else if (EQUAL (Word,"file"))  GetWord (Sentence, Fname, FNLEN);
  399.       else if (EQUAL (Word,"items")) SetItems (Sentence, &Ix, &Iy);
  400.       else if (EQUAL (Word,"item"))  SetDtype (Sentence, Dtype);
  401.       else if (EQUAL (Word,"points")) {
  402.           GetWord (Sentence, Word, LIBUF);
  403.           if      (EQUAL (Word,"square"))   Node = 0071;
  404.           else if (EQUAL (Word,"circle"))   Node = 0061;
  405.           else if (EQUAL (Word,"diamond"))  Node = 0042;
  406.           else if (EQUAL (Word,"plus"))     Node = 0144;
  407.           else if (EQUAL (Word,"pinwheel")) Node = 0113;
  408.           else if (EQUAL (Word,"x"))        Node = 0112;
  409.           else if (EQUAL (Word,"flower"))   Node = 0133;
  410.           else if (EQUAL (Word,"blob"))     Node = 0077;
  411.           else if (EQUAL (Word,"blot"))     Node = 0106;
  412.           else    Unknown (Word);
  413.       }
  414.       else    Unknown (Word);
  415.       GetWord (Sentence, Word, LIBUF);
  416.     }
  417.     if (Fname[0]==' ')
  418.       PauseMsg("  no data file given - no line drawn");
  419.     else {
  420.       GetTwo (Fname, &Xptr, Dtype[Ix-1], Ix, &Yptr, Dtype[Iy-1], Iy);
  421.       Points = (int) *Xptr;
  422.       if (Points) {
  423.         printf("  tracing %d points\n",Points);
  424.         Liner (Xptr, &Xfit, Yptr, &Yfit, Trace, Node);
  425.       }
  426.       else
  427.         {printf("  no data found for: "); PauseMsg(Fname);}
  428.   }
  429. }
  430. /*@@                                      CONLIB-8 */
  431. int ItemOut (Item)
  432. /*  =======       check for data item out of range */
  433. int Item;
  434. {
  435.   if (Item < 1 || Item > MAXITEMS) {
  436.     printf("  item number %d",Item); PauseMsg(" out of range");
  437.     return YES;
  438.   }
  439.   else return NO;
  440. }
  441. /*  ======== */
  442. int LineType (Word,Trace)
  443. /*  ========          Sets the Trace value if Word is a line type */
  444. char *Word;
  445. int  *Trace;
  446. {
  447.   int Result;
  448.  
  449.   Result = YES;
  450.   if      (EQUAL (Word,"invisible")) *Trace = 000;
  451.   else if (EQUAL (Word,"solid"))     *Trace = SOLID;
  452.   else if (EQUAL (Word,"dotted"))    *Trace = 011;
  453.   else if (EQUAL (Word,"spotted"))   *Trace = 025;
  454.   else if (EQUAL (Word,"dash"))      *Trace = 007;
  455.   else if (EQUAL (Word,"longdash"))  *Trace = 067;
  456.   else if (EQUAL (Word,"dashdot"))   *Trace = 027;
  457.   else if (EQUAL (Word,"sparse"))    *Trace = 001;
  458.   else Result = NO;
  459.   return Result;
  460. }
  461. /*   ======== */
  462. void SetDtype (Sentence, Dtype)
  463. /*   ========   handles an "item is" spec */
  464. char *Sentence, *Dtype;
  465. {
  466.   #define    DTYPLEN 8
  467.   char  Word[DTYPLEN+1];
  468.   int   Item;
  469.  
  470.   GetInt (Sentence, &Item);
  471.   GetWord (Sentence, Word, DTYPLEN);
  472.   if (!ItemOut (Item)) {
  473.     if      (EQUAL (Word, "yymmdd"))  Dtype[Item-1] = 'D';
  474.     else   {printf("  unknown data type: "); PauseMsg(Word);}
  475.   }
  476. }
  477. /*   ======== */
  478. void SetItems (Sentence, Ix, Iy)
  479. /*   ========    handles an "items" spec */
  480. char *Sentence;
  481. int  *Ix, *Iy;
  482. {
  483.   GetInt (Sentence, Ix);
  484.   if (ItemOut (*Ix)) *Ix = 1;
  485.   GetInt (Sentence, Iy);
  486.   if (ItemOut (*Iy)) *Iy = 2;
  487. }
  488. /*@@                                 CONLIB-9 */
  489. /*   ===== */
  490. void PCcon (Sentence)
  491. /*   =====           Handles a PIC specification */
  492. char *Sentence;
  493. {
  494.   char       Word[HOLD+1];
  495.   double     Xpic, Ypic;
  496.   static int Xmax, Ymax;
  497.   int        Border, Margin = 5;
  498.  
  499.   #ifdef DEBUG
  500.   printf("PCcon:%s\n",Sentence);
  501.   #endif
  502.  
  503.   GetWord (Sentence, Word, HOLD);
  504.   if (EQUAL (Word,"CLOSE"))
  505.     PX_Close (Xmax, Ymax);
  506.   else {
  507.     PX_Open ();
  508.     Xmax = XMAX;
  509.     Ymax = YMAX;
  510.     Border = NO;
  511.     while (Word[0] != ' ') {
  512.  
  513.       if (EQUAL (Word,"size")) {
  514.         GetVal (Sentence, &Xpic);
  515.         GetVal (Sentence, &Ypic);
  516.         if (Xpic==0 || PIXELS(Xpic) > XMAX ||
  517.             Ypic==0 || PIXELS(Ypic) > YMAX   )
  518.           PauseMsg("  invalid PIC size, max used");
  519.         else {
  520.           Xmax = PIXELS (Xpic);
  521.           Ymax = PIXELS (Ypic);
  522.         }
  523.       }
  524.       else if (EQUAL (Word,"outline")) Border = YES;
  525.  
  526.       else if (EQUAL (Word,"margin"))  GetInt (Sentence, &Margin);
  527.  
  528.       else Unknown (Word);
  529.  
  530.       GetWord (Sentence, Word, HOLD);
  531.     }
  532.     PX_Margin (Margin);
  533.     if (Border) Box (0, 0, Xmax, Ymax);
  534.   }
  535. }
  536. /*@@                                  CONLIB-10 */
  537. /*   ===== */
  538. void TLcon (Sentence)
  539. /*   =====           Handles a TITLE specification */
  540. char *Sentence;
  541. {
  542.   static char Dir, Justify;
  543.   static int  Font, Xt, Yt;
  544.   double      Xloc, Yloc;
  545.   char       *Text, Word[HOLD+1];
  546.   int         TexLen;
  547.  
  548.   #ifdef DEBUG
  549.   printf("TLcon:%s\n",Sentence);
  550.   #endif
  551.  
  552.   GetWord (Sentence, Word, HOLD);
  553.   if (!EQUAL (Word,"text")) {
  554.     Justify = 'C';
  555.     Dir = 'H';
  556.     Font = 1;
  557.   }
  558.   while (Word[0] != ' ') {
  559.  
  560.     if (EQUAL (Word,"at")) {
  561.       GetVal (Sentence,&Xloc);
  562.       GetVal (Sentence,&Yloc);
  563.       Xt = PIXELS (Xloc);
  564.       Yt = PIXELS (Yloc);
  565.       if (Xloc==0 || Yloc==0)
  566.         PauseMsg("  invalid title location");
  567.     }
  568.     else if (EQUAL(Word,"L") || EQUAL(Word,"left"))   Justify = 'L';
  569.     else if (EQUAL(Word,"R") || EQUAL(Word,"right"))  Justify = 'R';
  570.     else if (EQUAL(Word,"C") || EQUAL(Word,"center")) Justify = 'C';
  571.     else if (EQUAL(Word,"V") || EQUAL(Word,"ver"))    Dir = 'V';
  572.     else if (EQUAL(Word,"H") || EQUAL(Word,"hor"))    Dir = 'H';
  573.     else if (EQUAL(Word,"font")) GetInt (Sentence,&Font);
  574.  
  575.     else if (EQUAL (Word,"text")) {
  576.       Text = Sentence;
  577.       while (*Text == ' ') Text++;
  578.       if (Dir == 'H') {
  579.         TexLen = TxWide (strlen (Text), Font);
  580.         if      (Justify == 'C') Xt -= (TexLen>>1);
  581.         else if (Justify == 'R') Xt -= TexLen;
  582.       }
  583.       PX_Text (Xt, Yt, Font, Dir, Text);
  584.       break;
  585.     }
  586.     else Unknown (Word);
  587.  
  588.     GetWord (Sentence, Word, HOLD);
  589.   }
  590. }
  591. void HUcon (char *Sentence) {
  592. /*   =====                    Handles a HUE specification */
  593. char Word[HOLD+1];
  594. int  Color;
  595.   GetWord (Sentence, Word, HOLD);
  596.   if ((Color=IsHue(Word)) > 0) PX_Hue (Color);
  597.   else                         PauseMsg ("  unknown hue");
  598. }
  599.