home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / fp / ifp_unix.lzh / ifp / interp / G_draw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-23  |  8.0 KB  |  317 lines

  1.  
  2. /****** G_draw.c ******************************************************/
  3. /**                                                                  **/
  4. /**                    University of Illinois                        **/
  5. /**                                                                  **/
  6. /**                Department of Computer Science                    **/
  7. /**                                                                  **/
  8. /**   Tool: IFP                  Version: 0.5             **/
  9. /**                                                                  **/
  10. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  11. /**                                                                  **/
  12. /**   Revised by: Arch D. Robison    Date: June 18, 1986         **/
  13. /**                                                                  **/
  14. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  15. /**                            Prof. W. J. Kubitz                    **/
  16. /**                                                                  **/
  17. /**                                                                  **/
  18. /**------------------------------------------------------------------**/
  19. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  20. /**                       All Rights Reserved.                       **/
  21. /**********************************************************************/
  22.  
  23. /******************** FP Graphics Interface Module ********************/
  24.  
  25. /*
  26.  * The fp interpreter must be compiled with the -DGRAPHICS option to use
  27.  * the graphics interface.  The interface is specific to the PC/RT.
  28.  *
  29.  * There are no graphics primitives in FP itself, rather FP is used to
  30.  * calculate a display list.  The display list is then fed to DrawObject,
  31.  * which draws the picture specified by the display list.
  32.  *
  33.  * The display list has the following structure:
  34.  *
  35.  *     display-list == < {display-list} > | polyline | color | transform | text
  36.  *     polyline == < "line" { < x y > } >
  37.  *     color == < "color" color-index display-list >
  38.  *     text == <"text" print-atom size ["center"]>
  39.  *     transform = <"trans" t-matrix display-list >
  40.  *     t-matrix = <<Txx Txy Txo> <Tyx Tyy Tyo>>
  41.  *
  42.  * The polyline structure specifies a sequence of points.  Adjacent points
  43.  * are connected with line segments.
  44.  *
  45.  * The color structure draws the display-list in the color specified by
  46.  * the color index (0..15).  The color applies to all parts of the
  47.  * subordinate display-list which are not subordinate to a color structure
  48.  * within.  
  49.  *
  50.  * The transform structure draws the display-list as transformed by the
  51.  * t-matrix.  Transforms may be nested.
  52.  *
  53.  * The text structure draws a string with the lower-left corner at (0,0).
  54.  * Each character is drawn in a 1.0 by 1.0 box (including spacing).
  55.  */
  56.  
  57. #include <stdio.h>
  58. #include "struct.h"
  59. #include "string.h"
  60.  
  61. #define NKey 4
  62. StrPtr SKey[4],SCenter;
  63.  
  64. private short ScreenDim[2];
  65.  
  66. private void GraphError (InOut,Message)
  67.    ObjectPtr InOut;
  68.    char *Message;
  69.    {
  70.       VI_Term ();
  71.       printf ("%s\n",Message);
  72.       OutObject (InOut);
  73.       printf ("\n");
  74.       RepTag (InOut,BOTTOM);
  75.    }
  76.  
  77. void InitDraw ()
  78.    {
  79.       printf (" (RT/PC graphics)");
  80.       fflush (stdout);
  81.       SKey[0] = MakeString ("line");
  82.       SKey[1] = MakeString ("trans");
  83.       SKey[2] = MakeString ("color");
  84.       SKey[3] = MakeString ("text");
  85.       SCenter = MakeString ("center");
  86.    }
  87.  
  88. typedef double Transform [2][3];
  89.  
  90. Transform TransDefault = {
  91.    {800,0,0},
  92.    {0,800,0}
  93. };
  94.  
  95. forward void DrOb(), DrawText(), DrawTrans(), DrawColor (), PolyLine();
  96.  
  97. void DrawObject (InOut)
  98.    ObjectPtr InOut;
  99.    {
  100.       if (InOut->Tag == BOTTOM) return;
  101.  
  102.       VI_Init(ScreenDim,ScreenDim+1);
  103.       VI_Force();
  104.       VI_Color (0);
  105.       VI_Tile (ScreenDim[0],ScreenDim[1],1,1,"\0");
  106.       DrOb (InOut,TransDefault,1);
  107.       if (InOut->Tag != BOTTOM) {
  108.      while (getchar () != '\n') continue;
  109.      VI_Term ();
  110.       }
  111.    }
  112.  
  113. /*
  114.  * DrOb
  115.  *
  116.  * Draw object Inout with transform T and in color Color.
  117.  */
  118. private void DrOb (InOut,T,Color)
  119.    register ObjectPtr InOut;
  120.    Transform T;
  121.    int Color;
  122.    {
  123.       register int K;
  124.       register ListPtr P;
  125.  
  126.       if (InOut->Tag != LIST)
  127.      GraphError (InOut,"DrOb: invalid display object");
  128.       else {
  129.      P = InOut->List;
  130.      if (P == NULL || P->Val.Tag == LIST)
  131.         for (; P!=NULL; P=P->Next) DrOb (&P->Val,T,Color);
  132.      else if (P->Val.Tag != STRING)
  133.         GraphError (InOut,"DrOb: first element must be string");
  134.      else {
  135.         for (K=0; K<NKey; K++)
  136.            if (!StrComp (SKey [K],P->Val.String)) break;
  137.         switch (K) {
  138.            case 0:
  139.           PolyLine (P->Next,T,Color);
  140.           break;
  141.            case 1:
  142.           DrawTrans (P->Next,T,Color);
  143.           break;
  144.            case 2:
  145.           DrawColor (P->Next,T);
  146.           break;
  147.            case 3:
  148.           DrawText (P->Next,T,Color);
  149.           break;
  150.            default:
  151.           GraphError (InOut,"DrOb: unknown drawing command");
  152.           break;
  153.         }
  154.      }
  155.       }
  156.    }
  157.  
  158. private void GetCoor (P,T,X,Y)
  159.    register ListPtr P;
  160.    Transform T;
  161.    int *X,*Y;
  162.    {
  163.       extern short sddmul ();
  164.       register ListPtr Q;
  165.       double Xf,Yf;
  166.  
  167.       if (!PairTest (&P->Val,NUMERIC,NUMERIC))
  168.      GraphError (&P->Val,"GetCoor: numeric pair expected\n");
  169.       else {
  170.      Q = P->Val.List;
  171.      GetDouble (&Q->Val,&Xf);
  172.      GetDouble (&Q->Next->Val,&Yf);
  173.      *X = Xf * T[0][0] + Yf * T[0][1] + T[0][2];
  174.      *Y = Xf * T[1][0] + Yf * T[1][1] + T[1][2];
  175.       }
  176.    }
  177.  
  178. private void DrawText (P,T,Color)
  179.    register ListPtr P;
  180.    Transform T;
  181.    int Color;
  182.    {
  183.       char Buf[256];
  184.       CharPtr U;
  185.       int S[2][3];
  186.       int i,j,N3;
  187.       double Size;
  188.       boolean Center;
  189.  
  190.       if (P!=NULL) {
  191.      switch (P->Val.Tag) {
  192.         default: return;
  193.         case STRING:
  194.            CPInit (&U,&P->Val.List);
  195.            (void) CPRead (&U,Buf,256);
  196.            break;
  197.         case BOOLEAN:
  198.            (void) sprintf (Buf,P->Val.Bool ? "t" : "f");
  199.            break;
  200.         case INT:
  201.            (void) sprintf (Buf,"%ld",P->Val.Int);
  202.            break;
  203.         case FLOAT:
  204.            (void) sprintf (Buf,"%g",P->Val.Float);
  205.            break;
  206.      }
  207.      Size = 1.0;
  208.      Center = 0;
  209.      if (NULL != (P=P->Next)) {
  210.         GetDouble (&P->Val,&Size);
  211.     
  212.         if (NULL != (P=P->Next) && P->Val.Tag == STRING &&
  213.         !StrComp (P->Val.String,SCenter)) {
  214.            Center = 1;
  215.            N3 = 3*strlen (Buf);
  216.         }
  217.      }
  218.  
  219.      Size /= 6.0;
  220.  
  221.      for (i=0; i<2; i++)
  222.         for (j=0; j<3; j++)
  223.            S[i][j] = (int) ((j<2 ? Size * T[i][j] : T[i][j]) * (1 << 10));
  224.     
  225.      if (Center) {
  226.         S[0][2] -= N3 * S[0][0] + 3 * S[0][1];
  227.         S[1][2] -= N3 * S[1][0] + 3 * S[1][1];
  228.      }
  229.  
  230.      ConSymbol (Buf,S);
  231.       }
  232.    }
  233.  
  234. private void PolyLine (P,T,Color)
  235.    register ListPtr P;
  236.    Transform T;
  237.    int Color;
  238.    {
  239.       int X,Y;
  240.  
  241.       VI_Color (!Color);
  242.       if (P != NULL) {
  243.      GetCoor (P,T,&X,&Y);
  244.      VI_AMove (X,Y);
  245.      while (NULL != (P=P->Next)) {
  246.         GetCoor (P,T,&X,&Y);
  247.         VI_ALine (X,Y);
  248.      }
  249.       }
  250.    }
  251.  
  252. boolean GetTrans (X,T)
  253.    ObjectPtr X;
  254.    Transform T;
  255.    {
  256.       register ListPtr P,Q;
  257.       register int i,j;
  258.  
  259.       if (!PairTest (X,1<<LIST,1<<LIST)) return 0;
  260.       else {
  261.      P = X->List;
  262.      for (i=0; i<2; P=P->Next,i++) {
  263.         Q = P->Val.List;
  264.         for (j=0; j<3; Q=Q->Next,j++) {
  265.            if (Q == NULL) return 0;
  266.            if (GetDouble (&Q->Val,&T[i][j])) return 0;
  267.         }
  268.      }
  269.      return 1;
  270.       }
  271.    }
  272.  
  273. private void DrawTrans (P,T,Color)
  274.    register ListPtr P;
  275.    Transform T;
  276.    int Color;
  277.    {
  278.       Transform R,S;
  279.       int i,j;
  280.  
  281.       if (P!=NULL)
  282.      if (!GetTrans (&P->Val,R))
  283.         GraphError (&P->Val,"DrawTrans: not a transform");
  284.      else {
  285.         for (i=0; i<2; i++) {
  286.            for (j=0; j<3; j++)
  287.           S[i][j] = T[i][0] * R[0][j] + T[i][1] * R[1][j];
  288.            S[i][2] += T[i][2];
  289.         }
  290.      }
  291.      if (NULL != (P=P->Next)) DrOb (&P->Val,S,Color);
  292.    }
  293.  
  294. private void DrawColor (P,T)
  295.    register ListPtr P;
  296.    Transform T;
  297.    {
  298.       int Color;
  299.  
  300.       if (P!=NULL) {
  301.      switch (P->Val.Tag) {
  302.         case INT:
  303.            Color = P->Val.Int;
  304.            break;
  305.         case FLOAT:
  306.            Color = (int) (P->Val.Float + 0.5);
  307.            break;
  308.         default:
  309.            GraphError (&P->Val,"DrawColor: not a color");
  310.      }
  311.      if (P->Next != NULL) DrOb (&P->Next->Val,T,Color);
  312.       }
  313.    }
  314.  
  315. /***************************** end of G_draw.c *******************************/
  316.  
  317.