home *** CD-ROM | disk | FTP | other *** search
/ NOVA - For the NeXT Workstation / NOVA - For the NeXT Workstation.iso / SourceCode / AdobeExamples / NX_Binary / iinterpreter.c < prev    next >
Encoding:
Text File  |  1992-12-19  |  8.2 KB  |  442 lines

  1.  
  2. /*
  3.  * (a)  (C) 1990 by Adobe Systems Incorporated. All rights reserved.
  4.  *
  5.  * (b)  If this Sample Code is distributed as part of the Display PostScript
  6.  *    System Software Development Kit from Adobe Systems Incorporated,
  7.  *    then this copy is designated as Development Software and its use is
  8.  *    subject to the terms of the License Agreement attached to such Kit.
  9.  *
  10.  * (c)  If this Sample Code is distributed independently, then the following
  11.  *    terms apply:
  12.  *
  13.  * (d)  This file may be freely copied and redistributed as long as:
  14.  *    1) Parts (a), (d), (e) and (f) continue to be included in the file,
  15.  *    2) If the file has been modified in any way, a notice of such
  16.  *      modification is conspicuously indicated.
  17.  *
  18.  * (e)  PostScript, Display PostScript, and Adobe are registered trademarks of
  19.  *    Adobe Systems Incorporated.
  20.  * 
  21.  * (f) THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO
  22.  *    CHANGE WITHOUT NOTICE, AND SHOULD NOT BE CONSTRUED
  23.  *    AS A COMMITMENT BY ADOBE SYSTEMS INCORPORATED.
  24.  *    ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY
  25.  *    OR LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO
  26.  *    WARRANTY OF ANY KIND (EXPRESS, IMPLIED OR STATUTORY)
  27.  *    WITH RESPECT TO THIS INFORMATION, AND EXPRESSLY
  28.  *    DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, 
  29.  *    FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT
  30.  *    OF THIRD PARTY RIGHTS.
  31.  */
  32.  
  33. /*
  34. *    iinterpreter.c
  35.  *
  36.  *    Version:    2.0
  37.  *    Author:    Ken Fromm
  38.  *    History:
  39.  *            03-07-91        Added this comment.
  40. */
  41.  
  42. #import "iinterpreterhooks.h"
  43. #import "ierror.h"
  44. #import <appkit/nextstd.h>
  45. #import <appkit/graphics.h>
  46. #import <dpsclient/dpsclient.h>
  47. #import <objc/hashtable.h>
  48.  
  49. #define  STACKSIZE        256        /* Maximum stack size. */
  50. #define  ELEMENTSIZE    128        /* Max size of one link in string expression */
  51.  
  52. typedef enum {
  53.     UNDEFINED,
  54.     INTEGER,
  55.     REAL,
  56.     STRING,
  57.     NAME,
  58.     ARRAY,
  59.     MARK
  60. }  ElementType;
  61.  
  62. typedef struct _Any {
  63.     ElementType    type;
  64.     union {
  65.         int        integer;
  66.         float        real;
  67.         char        *name;
  68.         struct {
  69.             char        *data;
  70.             int        len;
  71.         }  string;        
  72.         struct {
  73.             char        *data;
  74.             int        len;
  75.         }  array;
  76.     }  element;
  77. }  Any;
  78.  
  79. static int            istackdepth;        /* number of elements */
  80. static Any        *istacktop;        /* ptr to top of stack */
  81. static Any        *istack;            /* ptr to bottom of stack */
  82.  
  83. static NXPoint        icurrentpoint,
  84.                 istartpoint;
  85.  
  86. static BOOL        inocurrentpoint,
  87.                 ierror;
  88.  
  89. static NXRect        ipathbbox;
  90.  
  91. BOOL iiferror()
  92. {
  93.     return ierror;
  94. }
  95.  
  96. void ireset()
  97. {
  98.     istackdepth = 0;
  99.     istacktop = istack;
  100.     ierror = NO;
  101. }
  102.  
  103. void iinitialize()
  104. {
  105.     ii_initPathStruct();
  106.     ii_initGraphicStruct();
  107.     
  108.     NX_MALLOC(istack, Any, STACKSIZE * sizeof(Any));
  109.     inocurrentpoint = YES;
  110.     ireset();
  111. }
  112.  
  113. void iclear()
  114. {
  115.     if (!ierror)
  116.         ireset();
  117. }
  118.  
  119. void ipop()
  120. {
  121.     if (!ierror)
  122.     {
  123.         if (istackdepth > 0)
  124.         {
  125.             if (istacktop->type == STRING)
  126.             {
  127.                 NX_FREE(istacktop->element.string.data);
  128.             }
  129.             else if (istacktop->type == NAME)
  130.             {
  131.                 NX_FREE(istacktop->element.name);
  132.             }
  133.  
  134.             istackdepth--;
  135.             istacktop--;
  136.         }
  137.         else
  138.             ierrorlog("Error: stack underrflow", &ierror);
  139.     }
  140. }
  141. void ipopint(int *aval)
  142. {
  143.     if (!ierror)
  144.     {
  145.         if (istackdepth > 0)
  146.         {
  147.             if (istacktop->type == INTEGER)
  148.             {
  149.                 *aval = istacktop->element.integer;
  150.                 istackdepth--;
  151.                 istacktop--;
  152.             }
  153.             else
  154.                 ierrorlog("Error: typecheck", &ierror);
  155.         }
  156.         else
  157.             ierrorlog("Error: stack underrflow", &ierror);
  158.     }
  159. }
  160.  
  161. void ipopreal(float *aval)
  162. {
  163.     if (!ierror)
  164.     {
  165.         if (istackdepth > 0)
  166.         {
  167.             if (istacktop->type == REAL || istacktop->type == INTEGER)
  168.             {
  169.                 if (istacktop->type == REAL)
  170.                     *aval = istacktop->element.real;
  171.                 else
  172.                     *aval = (float) istacktop->element.integer;
  173.                 istackdepth--;
  174.                 istacktop--;
  175.             }
  176.             else
  177.                 ierrorlog("Error: typecheck", &ierror);
  178.         }
  179.         else
  180.             ierrorlog("Error: stack underrflow", &ierror);
  181.     }
  182. }
  183.  
  184. void ipopstring(char **str_ptr, int *len)
  185. {
  186.     if (!ierror)
  187.     {
  188.         if (istackdepth > 0)
  189.         {
  190.             if (istacktop->type == STRING)
  191.             {
  192.                 *str_ptr = istacktop->element.string.data;
  193.                 *len = istacktop->element.string.len;
  194.                 istackdepth--;
  195.                 istacktop--;
  196.             }
  197.             else
  198.                 ierrorlog("Error: typecheck", &ierror);
  199.         }
  200.         else
  201.             ierrorlog("Error: stack underrflow", &ierror);
  202.     }
  203. }
  204.  
  205. void ipopname(char **name_ptr)
  206. {
  207.     if (!ierror)
  208.     {
  209.         if (istackdepth > 0)
  210.         {
  211.             if (istacktop->type == NAME)
  212.             {
  213.                 *name_ptr = istacktop->element.name;
  214.                 istackdepth--;
  215.                 istacktop--;
  216.             }
  217.             else
  218.                 ierrorlog("Error: typecheck", &ierror);
  219.         }
  220.         else
  221.             ierrorlog("Error: stack underrflow", &ierror);
  222.     }
  223. }
  224.  
  225. void ipushint(int aval)
  226. {
  227.     if (!ierror)
  228.     {
  229.         if (istackdepth < STACKSIZE)
  230.         {
  231.             istackdepth++;
  232.             istacktop++;
  233.             istacktop->type = INTEGER;
  234.             istacktop->element.integer = aval;
  235.         }
  236.         else
  237.             ierrorlog("Error: stack overflow", &ierror);
  238.     }
  239. }
  240.  
  241. void ipushreal(float aval)
  242. {
  243.     if (!ierror)
  244.     {
  245.         if (istackdepth < STACKSIZE)
  246.         {
  247.             istackdepth++;
  248.             istacktop++;
  249.             istacktop->type = REAL;
  250.             istacktop->element.real = aval;
  251.         }
  252.         else
  253.              ierrorlog("Error: stack overflow", &ierror);
  254.     }
  255. }
  256.  
  257. void  ipushstring(char *str, int len)
  258. {
  259.     if (!ierror)
  260.     {
  261.         if (istackdepth < STACKSIZE)
  262.         {
  263.             istackdepth++;
  264.             istacktop++;
  265.             istacktop->type = STRING;
  266.         
  267.             NX_MALLOC(istacktop->element.string.data, char, len+1);
  268.             strncpy(istacktop->element.string.data, str, len);
  269.             istacktop->element.string.data[len] = 0;
  270.             istacktop->element.string.len = len;            
  271.         }
  272.         else
  273.             ierrorlog("Error: stack overflow", &ierror);
  274.     }
  275. }
  276.  
  277. void  ipushname(char *name, int len)
  278. {
  279.     if (!ierror)
  280.     {
  281.         if (istackdepth < STACKSIZE)
  282.         {
  283.             istackdepth++;
  284.             istacktop++;
  285.             istacktop->type = NAME;
  286.             istack->element.name = NXCopyStringBuffer(name);
  287.         }
  288.         else
  289.             ierrorlog("Error: stack overflow", &ierror);
  290.     }
  291. }
  292.  
  293. void iroll(int n, int j)
  294. {
  295.     int        a, b;
  296.  
  297.     Any        temp;
  298.  
  299.     if (!ierror)
  300.     {
  301.         if (istackdepth -n >= 0)
  302.         {
  303.             for (a = j; a > 0; a--)
  304.             {
  305.                 temp = *istacktop;
  306.                 for (b = 1; b < n; b++)
  307.                     istack[istackdepth - (b-1)] = istack[istackdepth - b];            
  308.                 istack[istackdepth - (n - 1)] = temp;
  309.             }
  310.         }
  311.         else
  312.             ierrorlog("Error: stack underflow", &ierror);
  313.     }
  314. }
  315.  
  316. static void icheckBounds(NXPoint  *pts, int num_pts, BOOL relative)
  317. {
  318.     int            i;
  319.  
  320.     NXPoint        pt;
  321.  
  322.     if (inocurrentpoint && num_pts > 0)
  323.     {
  324.         ipathbbox.origin.x = pts->x;
  325.         ipathbbox.origin.y = pts->y;
  326.         ipathbbox.size.width = 0;
  327.         ipathbbox.size.height = 0;
  328.     }
  329.  
  330.     for (i = 0; i < num_pts; i++)
  331.     {
  332.         pt = pts[i];    
  333.         if (relative)
  334.         {
  335.             pt.x += icurrentpoint.x;
  336.             pt.y += icurrentpoint.y;
  337.         }
  338.         
  339.         if (pt.x < ipathbbox.origin.x )
  340.         {
  341.             ipathbbox.size.width += ipathbbox.origin.x - pt.x;
  342.             ipathbbox.origin.x = pt.x;
  343.         }
  344.         else if (pt.x - ipathbbox.origin.x > ipathbbox.size.width)
  345.             ipathbbox.size.width = pt.x - ipathbbox.origin.x;
  346.     
  347.         if (pt.y < ipathbbox.origin.y)
  348.         {
  349.             ipathbbox.size.height += ipathbbox.origin.y - pt.y;
  350.             ipathbbox.origin.y = pt.y;
  351.         }
  352.         else if (pt.y - ipathbbox.origin.y > ipathbbox.size.height)
  353.             ipathbbox.size.height = pt.y - ipathbbox.origin.y;
  354.     }
  355. }
  356.  
  357. void iinsertPathOp(int dps_op, int num_args)
  358. {
  359.     BOOL    relative_op = YES, start_path = NO;
  360.  
  361.     int        i, num_pts;
  362.     
  363.     NXPoint    pts[3];
  364.  
  365.     if (!ierror)
  366.     {
  367.         switch(dps_op)
  368.         {
  369.             case dps_rmoveto:
  370.                 start_path = YES;
  371.                 break;
  372.             case dps_moveto:
  373.                 start_path = YES;
  374.             case dps_lineto:
  375.             case dps_curveto:
  376.             case dps_closepath:
  377.                 relative_op = NO;
  378.                 break;
  379.             default:    ;    
  380.         }
  381.  
  382.         if ((relative_op || dps_op == dps_closepath) && inocurrentpoint)
  383.         {
  384.             ierrorlog("Error: no currentpoint", &ierror);
  385.         }
  386.         else
  387.         {
  388.             /* Take points off stack and place back to front into pt array. */
  389.             num_pts = num_args/2;
  390.             for (i = num_pts - 1;  i >= 0;  i--)
  391.             {
  392.                 ipopreal(&pts[i].y);
  393.                 ipopreal(&pts[i].x);
  394.             }
  395.  
  396.             if (!ierror)
  397.             {
  398.                 /*  Path from end to start and check bounds. */    
  399.                 icheckBounds(pts, num_pts, relative_op);
  400.                 ii_insertPathCoord(pts, num_pts, dps_op, &icurrentpoint);
  401.  
  402.                 if (relative_op)
  403.                 {
  404.                     icurrentpoint.x += pts[num_pts-1].x;
  405.                     icurrentpoint.y += pts[num_pts-1].y;
  406.                 }
  407.                 else if (dps_op == dps_closepath)
  408.                     icurrentpoint = istartpoint;
  409.                 else
  410.                     icurrentpoint = pts[num_pts-1];
  411.                 
  412.                 if (start_path)
  413.                     istartpoint = icurrentpoint;
  414.  
  415.                 inocurrentpoint = NO;
  416.             }
  417.         }
  418.     }
  419. }
  420.  
  421. void iinsertPath(int path_type)
  422. {
  423.     if (!ierror)
  424.     {
  425.         ii_insertPath(path_type, &ipathbbox);
  426.         ii_resetPathStruct();
  427.         inocurrentpoint = YES;
  428.     }
  429. }
  430.  
  431. void iinsertPage(int page)
  432. {    
  433.     if (!ierror)
  434.     {
  435.         ii_insertPage(page);
  436.  
  437.         ii_resetPathStruct();
  438.         inocurrentpoint = YES;
  439.     }
  440. }
  441.  
  442.