home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d518 / post.lha / Post / post16s.lzh / postop3.c < prev    next >
Text File  |  1991-04-17  |  32KB  |  1,121 lines

  1. /* PostScript interpreter file "postop3.c" - operators (3) */
  2. /* (C) Adrian Aylward 1989, 1991 */
  3.  
  4. # include "post.h"
  5.  
  6. /* concat */
  7.  
  8. void opconcat(void)
  9. {   struct object *token1;
  10.     float newctm[6], matrix[6];
  11.     if (opernest < 1) error(errstackunderflow);
  12.     token1 = &operstack[opernest - 1];
  13.     if (token1->type != typearray) error(errtypecheck);
  14.     if (token1->length != 6) error(errrangecheck);
  15.     if (token1->flags & flagrprot) error(errinvalidaccess);
  16.     getmatrix(token1->value.vref, matrix);
  17.     multiplymatrix(newctm, matrix, gstate.ctm);
  18.     memcpy((char *) gstate.ctm, (char *) newctm, sizeof newctm);
  19.     opernest -= 1;
  20. }
  21.  
  22. /* concatmatrix */
  23.  
  24. void opconcatmatrix(void)
  25. {   struct object *token1, *token2, *token3;
  26.     float newctm[6], matrix[6], oldctm[6];
  27.     if (opernest < 3) error(errstackunderflow);
  28.     token3 = &operstack[opernest - 1];
  29.     token2 = token3 - 1;
  30.     token1 = token2 - 1;
  31.     if (token1->type != typearray) error(errtypecheck);
  32.     if (token1->length != 6) error(errrangecheck);
  33.     if (token1->flags & flagrprot) error(errinvalidaccess);
  34.     getmatrix(token1->value.vref, matrix);
  35.     if (token2->type != typearray) error(errtypecheck);
  36.     if (token2->length != 6) error(errrangecheck);
  37.     if (token2->flags & flagrprot) error(errinvalidaccess);
  38.     getmatrix(token2->value.vref, oldctm);
  39.     if (token3->type != typearray) error(errtypecheck);
  40.     if (token3->length != 6) error(errrangecheck);
  41.     if (token3->flags & flagwprot) error(errinvalidaccess);
  42.     multiplymatrix(newctm, matrix, oldctm);
  43.     arraysave(token3->value.vref, 6);
  44.     putmatrix(token3->value.vref, newctm);
  45.     *token1 = *token3;
  46.     opernest -= 2;
  47. }
  48.  
  49. /* currentblackgeneration */
  50.  
  51. void opcurrentblackgeneration(void)
  52. {   if (opernest == operstacksize) error(errstackoverflow);
  53.     operstack[opernest++] = gstate.gcr;
  54. }
  55.  
  56. /* currentcmykcolor */
  57.  
  58. void opcurrentcmykcolor(void)
  59. {   struct object token, *token1;
  60.     float c, m, y, k;
  61.     if (opernest + 4 > operstacksize) error(errstackoverflow);
  62.     c = 1.0 - gstate.rgbw[0];
  63.     m = 1.0 - gstate.rgbw[1];
  64.     y = 1.0 - gstate.rgbw[2];
  65.     k = 1.0 - gstate.rgbw[3];
  66.     token1 = &operstack[opernest];
  67.     token.type = typereal;
  68.     token.flags = 0;
  69.     token.length = 0;
  70.     token.value.rval = c;
  71.     token1[0] = token;
  72.     token.value.rval = m;
  73.     token1[1] = token;
  74.     token.value.rval = y;
  75.     token1[2] = token;
  76.     token.value.rval = k;
  77.     token1[3] = token;
  78.     opernest += 4;
  79. }
  80.  
  81. /* currentcolorscreen */
  82.  
  83. void opcurrentcolorscreen(void)
  84. {   struct object token, *token1;
  85.     int plane, p;
  86.     if (opernest + 12 > operstacksize) error(errstackoverflow);
  87.     token.type = typereal;
  88.     token.flags = 0;
  89.     token.length = 0;
  90.     p = 0;
  91.     token1 = &operstack[opernest];
  92.     for (plane = 0; plane < 4 ; plane++)
  93.     {   token.value.rval = gstate.screenfreq[p];
  94.         token1[0] = token;
  95.         token.value.rval = gstate.screenangle[p];
  96.         token1[1] = token;
  97.         token1[2] = gstate.screenfunc[p];
  98.         token1 += 3;
  99.         if (gstate.screendepth != 1) p++;
  100.     }
  101.     opernest += 12;
  102. }
  103.  
  104. /* currentcolortransfer */
  105.  
  106. void opcurrentcolortransfer(void)
  107. {   int plane, p;
  108.     if (opernest + 4 > operstacksize) error(errstackoverflow);
  109.     p = (gstate.screendepth == 1) ? 0 : 3;
  110.     for (plane = 0; plane < 4 ; plane++)
  111.     {   operstack[opernest++] = gstate.transfer[p];
  112.         if (gstate.screendepth != 1) p++;
  113.     }
  114.     opernest += 4;
  115. }
  116.  
  117. /* currentdash */
  118.  
  119. void opcurrentdash(void)
  120. {   struct object token, *token1;
  121.     if (opernest + 2 > operstacksize) error(errstackoverflow);
  122.     token1 = &operstack[opernest];
  123.     token1[0] = gstate.dasharray;
  124.     token.type = typereal;
  125.     token.flags = 0;
  126.     token.length = 0;
  127.     token.value.rval = gstate.dashoffset;
  128.     token1[1] = token;
  129.     opernest += 2;
  130. }
  131.  
  132. /* currentflat */
  133.  
  134. void opcurrentflat(void)
  135. {   struct object token;
  136.     if (opernest == operstacksize) error(errstackoverflow);
  137.     token.type = typereal;
  138.     token.flags = 0;
  139.     token.length = 0;
  140.     token.value.rval = gstate.flatness;
  141.     operstack[opernest++] = token;
  142. }
  143.  
  144. /* currentgray */
  145.  
  146. void opcurrentgray(void)
  147. {   struct object token;
  148.     if (opernest == operstacksize) error(errstackoverflow);
  149.     token.type = typereal;
  150.     token.flags = 0;
  151.     token.length = 0;
  152.     token.value.rval = gstate.gray;
  153.     operstack[opernest++] = token;
  154. }
  155.  
  156. /* currenthsbcolor */
  157.  
  158. void opcurrenthsbcolor(void)
  159. {   struct object token, *token1;
  160.     float hsb[3];
  161.     if (opernest + 3 > operstacksize) error(errstackoverflow);
  162.     token1 = &operstack[opernest];
  163.     gethsbcolour(hsb);
  164.     token.type = typereal;
  165.     token.flags = 0;
  166.     token.length = 0;
  167.     token.value.rval = hsb[0];
  168.     token1[0] = token;
  169.     token.value.rval = hsb[1];
  170.     token1[1] = token;
  171.     token.value.rval = hsb[2];
  172.     token1[2] = token;
  173.     opernest += 3;
  174. }
  175.  
  176. /* currentlinecap */
  177.  
  178. void opcurrentlinecap(void)
  179. {   struct object token;
  180.     if (opernest == operstacksize) error(errstackoverflow);
  181.     token.type = typeint;
  182.     token.flags = 0;
  183.     token.length = 0;
  184.     token.value.ival = gstate.linecap;
  185.     operstack[opernest++] = token;
  186. }
  187.  
  188. /* currentlinejoin */
  189.  
  190. void opcurrentlinejoin(void)
  191. {   struct object token;
  192.     if (opernest == operstacksize) error(errstackoverflow);
  193.     token.type = typeint;
  194.     token.flags = 0;
  195.     token.length = 0;
  196.     token.value.ival = gstate.linejoin;
  197.     operstack[opernest++] = token;
  198. }
  199.  
  200. /* currentlinewidth */
  201.  
  202. void opcurrentlinewidth(void)
  203. {   struct object token;
  204.     if (opernest == operstacksize) error(errstackoverflow);
  205.     token.type = typereal;
  206.     token.flags = 0;
  207.     token.length = 0;
  208.     token.value.rval = gstate.linewidth;
  209.     operstack[opernest++] = token;
  210. }
  211.  
  212. /* currentmatrix */
  213.  
  214. void opcurrentmatrix(void)
  215. {   struct object *token1;
  216.     if (opernest < 1) error(errstackunderflow);
  217.     token1 = &operstack[opernest - 1];
  218.     if (token1->type != typearray) error(errtypecheck);
  219.     if (token1->length != 6) error(errrangecheck);
  220.     if (token1->flags & flagwprot) error(errinvalidaccess);
  221.     arraysave(token1->value.vref, 6);
  222.     putmatrix(token1->value.vref, gstate.ctm);
  223. }
  224.  
  225. /* currentmiterlimit */
  226.  
  227. void opcurrentmiterlimit(void)
  228. {   struct object token;
  229.     if (opernest == operstacksize) error(errstackoverflow);
  230.     token.type = typereal;
  231.     token.flags = 0;
  232.     token.length = 0;
  233.     token.value.rval = gstate.mitrelimit;
  234.     operstack[opernest++] = token;
  235. }
  236.  
  237. /* currentrgbcolor */
  238.  
  239. void opcurrentrgbcolor(void)
  240. {   struct object token, *token1;
  241.     if (opernest + 3 > operstacksize) error(errstackoverflow);
  242.     token1 = &operstack[opernest];
  243.     token.type = typereal;
  244.     token.flags = 0;
  245.     token.length = 0;
  246.     token.value.rval = gstate.rgb[0];
  247.     token1[0] = token;
  248.     token.value.rval = gstate.rgb[1];
  249.     token1[1] = token;
  250.     token.value.rval = gstate.rgb[2];
  251.     token1[2] = token;
  252.     opernest += 3;
  253. }
  254.  
  255. /* currentscreen */
  256.  
  257. void opcurrentscreen(void)
  258. {   struct object token, *token1;
  259.     if (opernest + 3 > operstacksize) error(errstackoverflow);
  260.     token1 = &operstack[opernest];
  261.     token.type = typereal;
  262.     token.flags = 0;
  263.     token.length = 0;
  264.     token.value.rval = gstate.screenfreq[gstate.screendepth - 1];
  265.     token1[0] = token;
  266.     token.value.rval = gstate.screenangle[gstate.screendepth - 1];
  267.     token1[1] = token;
  268.     token1[2] = gstate.screenfunc[gstate.screendepth - 1];
  269.     opernest += 3;
  270. }
  271.  
  272. /* currenttansfer */
  273.  
  274. void opcurrenttransfer(void)
  275. {   if (opernest == operstacksize) error(errstackoverflow);
  276.     operstack[opernest++] = gstate.transfer[gstate.transdepth - 1];
  277. }
  278.  
  279. /* currentundercolorremoval */
  280.  
  281. void opcurrentundercolorremoval(void)
  282. {   if (opernest == operstacksize) error(errstackoverflow);
  283.     operstack[opernest++] = gstate.ucr;
  284. }
  285.  
  286. /* defaultmatrix */
  287.  
  288. void opdefaultmatrix(void)
  289. {   struct object *token1;
  290.     float newctm[6];
  291.     if (opernest < 1) error(errstackunderflow);
  292.     token1 = &operstack[opernest - 1];
  293.     if (token1->type != typearray) error(errtypecheck);
  294.     if (token1->length != 6) error(errrangecheck);
  295.     if (token1->flags & flagwprot) error(errinvalidaccess);
  296.     initctm(newctm);
  297.     arraysave(token1->value.vref, 6);
  298.     putmatrix(token1->value.vref, newctm);
  299. }
  300.  
  301. /* dtransform */
  302.  
  303. void opdtransform(void)
  304. {   struct object *token1, *token2, *token3;
  305.     struct point point;
  306.     float newctm[6];
  307.     if (opernest < 2) error(errstackunderflow);
  308.     token3 = &operstack[opernest - 1];
  309.     if (token3->type == typearray)
  310.     {   if (token3->length != 6) error(errrangecheck);
  311.         if (token3->flags & flagrprot) error(errinvalidaccess);
  312.         if (opernest < 3) error(errstackunderflow);
  313.         token2 = token3 - 1;
  314.         token1 = token2 - 1;
  315.         getmatrix(token3->value.vref, newctm);
  316.     }
  317.     else
  318.     {   token2 = token3;
  319.         token1 = token2 - 1;
  320.     }
  321.     if      (token1->type == typeint)
  322.         point.x = token1->value.ival;
  323.     else if (token1->type == typereal)
  324.         point.x = token1->value.rval;
  325.     else
  326.         error(errtypecheck);
  327.     if      (token2->type == typeint)
  328.         point.y = token2->value.ival;
  329.     else if (token2->type == typereal)
  330.         point.y = token2->value.rval;
  331.     else
  332.         error(errtypecheck);
  333.     if (token3->type == typearray)
  334.     {   dtransform(&point, newctm);
  335.         opernest--;
  336.     }
  337.     else
  338.         dtransform(&point, gstate.ctm);
  339.     token1->type = typereal;
  340.     token1->value.rval = point.x;
  341.     token2->type = typereal;
  342.     token2->value.rval = point.y;
  343. }
  344.  
  345. /* grestore */
  346.  
  347. void opgrestore(void)
  348. {   grest();
  349. }
  350.  
  351. /* grestoreall */
  352.  
  353. void opgrestoreall(void)
  354. {   grestall();
  355. }
  356.  
  357. /* gsave */
  358.  
  359. void opgsave(void)
  360. {   gsave();
  361. }
  362.  
  363. /* identmatrix */
  364.  
  365. void opidentmatrix(void)
  366. {   struct object *token1;
  367.     float matrix[6];
  368.     if (opernest < 1) error(errstackunderflow);
  369.     token1 = &operstack[opernest - 1];
  370.     if (token1->type != typearray) error(errtypecheck);
  371.     if (token1->length != 6) error(errrangecheck);
  372.     if (token1->flags & flagwprot) error(errinvalidaccess);
  373.     matrix[0] = matrix[3] = 1.0;
  374.     matrix[1] = matrix[2] = matrix[4] = matrix[5] = 0.0;
  375.     arraysave(token1->value.vref, 6);
  376.     putmatrix(token1->value.vref, matrix);
  377. }
  378.  
  379. /* idtransform */
  380.  
  381. void opidtransform(void)
  382. {   struct object *token1, *token2, *token3;
  383.     struct point point;
  384.     float newctm[6];
  385.     if (opernest < 2) error(errstackunderflow);
  386.     token3 = &operstack[opernest - 1];
  387.     if (token3->type == typearray)
  388.     {   if (token3->length != 6) error(errrangecheck);
  389.         if (token3->flags & flagrprot) error(errinvalidaccess);
  390.         if (opernest < 3) error(errstackunderflow);
  391.         token2 = token3 - 1;
  392.         token1 = token2 - 1;
  393.         getmatrix(token3->value.vref, newctm);
  394.     }
  395.     else
  396.     {   token2 = token3;
  397.         token1 = token2 - 1;
  398.     }
  399.     if      (token1->type == typeint)
  400.         point.x = token1->value.ival;
  401.     else if (token1->type == typereal)
  402.         point.x = token1->value.rval;
  403.     else
  404.         error(errtypecheck);
  405.     if      (token2->type == typeint)
  406.         point.y = token2->value.ival;
  407.     else if (token2->type == typereal)
  408.         point.y = token2->value.rval;
  409.     else
  410.         error(errtypecheck);
  411.     if (token3->type == typearray)
  412.     {   idtransform(&point, newctm);
  413.         opernest--;
  414.     }
  415.     else
  416.         idtransform(&point, gstate.ctm);
  417.     token1->type = typereal;
  418.     token1->value.rval = point.x;
  419.     token2->type = typereal;
  420.     token2->value.rval = point.y;
  421. }
  422.  
  423. /* initgraphics */
  424.  
  425. void opinitgraphics(void)
  426. {   initgraphics();
  427. }
  428.  
  429. /* initmatrix */
  430.  
  431. void opinitmatrix(void)
  432. {   initctm(gstate.ctm);
  433. }
  434.  
  435. /* invertmatrix */
  436.  
  437. void opinvertmatrix(void)
  438. {   struct object *token1, *token2;
  439.     float newctm[6], oldctm[6];
  440.     if (opernest < 2) error(errstackunderflow);
  441.     token2 = &operstack[opernest - 1];
  442.     token1 = token2 - 1;
  443.     if (token1->type != typearray) error(errtypecheck);
  444.     if (token1->length != 6) error(errrangecheck);
  445.     if (token1->flags & flagrprot) error(errinvalidaccess);
  446.     if (token2->type != typearray) error(errtypecheck);
  447.     if (token2->length != 6) error(errrangecheck);
  448.     if (token2->flags & flagwprot) error(errinvalidaccess);
  449.     getmatrix(token1->value.vref, oldctm);
  450.     invertmatrix(newctm, oldctm);
  451.     arraysave(token2->value.vref, 6);
  452.     putmatrix(token2->value.vref, newctm);
  453.     *token1 = *token2;
  454.     opernest--;
  455. }
  456.  
  457. /* itransform */
  458.  
  459. void opitransform(void)
  460. {   struct object *token1, *token2, *token3;
  461.     struct point point;
  462.     float newctm[6];
  463.     if (opernest < 2) error(errstackunderflow);
  464.     token3 = &operstack[opernest - 1];
  465.     if (token3->type == typearray)
  466.     {   if (token3->length != 6) error(errrangecheck);
  467.         if (token3->flags & flagrprot) error(errinvalidaccess);
  468.         if (opernest < 3) error(errstackunderflow);
  469.         token2 = token3 - 1;
  470.         token1 = token2 - 1;
  471.         getmatrix(token3->value.vref, newctm);
  472.     }
  473.     else
  474.     {   token2 = token3;
  475.         token1 = token2 - 1;
  476.     }
  477.     if      (token1->type == typeint)
  478.         point.x = token1->value.ival;
  479.     else if (token1->type == typereal)
  480.         point.x = token1->value.rval;
  481.     else
  482.         error(errtypecheck);
  483.     if      (token2->type == typeint)
  484.         point.y = token2->value.ival;
  485.     else if (token2->type == typereal)
  486.         point.y = token2->value.rval;
  487.     else
  488.         error(errtypecheck);
  489.     if (token3->type == typearray)
  490.     {   itransform(&point, newctm);
  491.         opernest--;
  492.     }
  493.     else
  494.         itransform(&point, gstate.ctm);
  495.     token1->type = typereal;
  496.     token1->value.rval = point.x;
  497.     token2->type = typereal;
  498.     token2->value.rval = point.y;
  499. }
  500.  
  501. /* matrix */
  502.  
  503. void opmatrix(void)
  504. {   struct object token;
  505.     float matrix[6];
  506.     if (opernest == operstacksize) error(errstackoverflow);
  507.     token.type = typearray;
  508.     token.flags = 0;
  509.     token.length = 6;
  510.     token.value.vref = arrayalloc(6);
  511.     matrix[0] = matrix[3] = 1.0;
  512.     matrix[1] = matrix[2] = matrix[4] = matrix[5] = 0.0;
  513.     putmatrix(token.value.vref, matrix);
  514.     operstack[opernest++] = token;
  515. }
  516.  
  517. /* rotate */
  518.  
  519. void oprotate(void)
  520. {   struct object *token1, *token2;
  521.     float newctm[6], matrix[6], a, s, c;
  522.     if (opernest < 1) error(errstackunderflow);
  523.     token2 = &operstack[opernest - 1];
  524.     if (token2->type == typearray)
  525.     {   if (token2->length != 6) error(errrangecheck);
  526.         if (token2->flags & flagwprot) error(errinvalidaccess);
  527.         if (opernest < 2) error(errstackunderflow);
  528.         token1 = token2 - 1;
  529.     }
  530.     else
  531.         token1 = token2;
  532.     if      (token1->type == typeint)
  533.         a = token1->value.ival;
  534.     else if (token1->type == typereal)
  535.         a = token1->value.rval;
  536.     else
  537.         error(errtypecheck);
  538.     a *= degtorad;
  539.     s = sin(a);
  540.     c = cos(a);
  541.     matrix[0] =  c; 
  542.     matrix[1] =  s;
  543.     matrix[2] = -s;
  544.     matrix[3] =  c; 
  545.     matrix[4] = matrix[5] = 0;
  546.     if (token2->type == typearray)
  547.     {   arraysave(token2->value.vref, 6);
  548.         putmatrix(token2->value.vref, matrix);
  549.         *token1 = *token2;
  550.     }
  551.     else
  552.     {   multiplymatrix(newctm, matrix, gstate.ctm);
  553.         memcpy((char *) gstate.ctm, (char *) newctm, sizeof newctm);
  554.     }
  555.     opernest -= 1;
  556. }
  557.  
  558. /* scale */
  559.  
  560. void opscale(void)
  561. {   struct object *token1, *token2, *token3;
  562.     float newctm[6], matrix[6], x, y;
  563.     if (opernest < 2) error(errstackunderflow);
  564.     token3 = &operstack[opernest - 1];
  565.     if (token3->type == typearray)
  566.     {   if (token3->length != 6) error(errrangecheck);
  567.         if (token3->flags & flagrprot) error(errinvalidaccess);
  568.         if (opernest < 3) error(errstackunderflow);
  569.         token2 = token3 - 1;
  570.         token1 = token2 - 1;
  571.     }
  572.     else
  573.     {   token2 = token3;
  574.         token1 = token2 - 1;
  575.     }
  576.     if      (token1->type == typeint)
  577.         x = token1->value.ival;
  578.     else if (token1->type == typereal)
  579.         x = token1->value.rval;
  580.     else
  581.         error(errtypecheck);
  582.     if      (token2->type == typeint)
  583.         y = token2->value.ival;
  584.     else if (token2->type == typereal)
  585.         y = token2->value.rval;
  586.     else
  587.         error(errtypecheck);
  588.     matrix[0] = x;
  589.     matrix[1] = 0.0;
  590.     matrix[2] = 0.0;
  591.     matrix[3] = y;
  592.     matrix[4] = matrix[5] = 0.0;
  593.     if (token3->type == typearray)
  594.     {   arraysave(token3->value.vref, 6);
  595.         putmatrix(token3->value.vref, matrix);
  596.         *token1 = *token3;
  597.     }
  598.     else
  599.     {   multiplymatrix(newctm, matrix, gstate.ctm);
  600.         memcpy((char *) gstate.ctm, (char *) newctm, sizeof newctm);
  601.     }
  602.     opernest -= 2;
  603. }
  604.  
  605. /* setblackgeneration */
  606.  
  607. void opsetblackgeneration(void)
  608. {   struct object *token1;
  609.     if (opernest < 1) error(errstackunderflow);
  610.     token1 = &operstack[opernest - 1];
  611.     if ((token1->type != typearray && token1->type != typepacked) ||
  612.         !(token1->flags & flagexec))
  613.         error(errtypecheck);
  614.     gstate.gcr = *token1;
  615.     opernest--;
  616. }
  617.  
  618. /* setcmykcolor */
  619.  
  620. void opsetcmykcolor(void)
  621. {   struct object *token1;
  622.     float cmyk[4];
  623.     int i;
  624.     if (gstate.cacheflag) error(errundefined);
  625.     if (opernest < 4) error(errstackunderflow);
  626.     token1 = &operstack[opernest - 4];
  627.     for (i = 0; i < 4; i++)
  628.     {   if      (token1->type == typeint)
  629.             cmyk[i] = token1->value.ival;
  630.         else if (token1->type == typereal)
  631.             cmyk[i] = token1->value.rval;
  632.         else
  633.             error(errtypecheck);
  634.         token1++;
  635.     }
  636.     setcolour(4, cmyk);
  637.     opernest -= 4;
  638. }
  639.  
  640. /* setcolorscreen */
  641.  
  642. void opsetcolorscreen(void)
  643. {   struct object *token1, *token2, *token3;
  644.     struct object func[4];
  645.     float freq[4], ang[4];
  646.     int plane;
  647.     if (opernest < 12) error(errstackunderflow);
  648.     token3 = &operstack[opernest - 10];
  649.     token2 = token3 - 1;
  650.     token1 = token2 - 1;
  651.     for (plane = 0; plane < 4; plane++)
  652.     {   if      (token1->type == typeint)
  653.             freq[plane] = token1->value.ival;
  654.         else if (token1->type == typereal)
  655.             freq[plane] = token1->value.rval;
  656.         else
  657.             error(errtypecheck);
  658.         if (freq[plane] <= 0.0) error(errrangecheck);
  659.         if      (token2->type == typeint)
  660.             ang[plane] = token2->value.ival;
  661.         else if (token2->type == typereal)
  662.             ang[plane] = token2->value.rval;
  663.         else
  664.             error(errtypecheck);
  665.         if ((token3->type != typearray && token3->type != typepacked) ||
  666.             !(token3->flags & flagexec))
  667.             error(errtypecheck);
  668.         func[plane] = *token3;
  669.         token1 += 3;
  670.         token2 += 3;
  671.         token3 += 3;
  672.     }
  673.     gstate.screendepth = 4;
  674.     memcpy((char *) gstate.screenfreq, freq, sizeof freq);
  675.     memcpy((char *) gstate.screenangle, ang, sizeof ang);
  676.     memcpy((char *) gstate.screenfunc, func, sizeof func);
  677.     halfok = gstacksize + 1;
  678.     setuphalf();
  679.     opernest -= 12;
  680. }
  681.  
  682. /* setcolortransfer */
  683.  
  684. void opsetcolortransfer(void)
  685. {   struct object *token1;
  686.     struct object func[4];
  687.     int plane;
  688.     if (gstate.cacheflag) error(errundefined);
  689.     if (opernest < 4) error(errstackunderflow);
  690.     token1 = &operstack[opernest - 4];
  691.     for (plane = 0; plane < 4; plane++)
  692.     {   if ((token1->type != typearray && token1->type != typepacked) ||
  693.             !(token1->flags & flagexec))
  694.             error(errtypecheck);
  695.         func[plane] = *token1;
  696.         token1++;
  697.     }
  698.     gstate.transdepth = 4;
  699.     memcpy((char *) gstate.transfer, func, sizeof func);
  700.     gstate.shadeok = 0;
  701.     setupshade();
  702.     opernest -= 4;
  703. }
  704.  
  705. /* setdash */
  706.  
  707. void opsetdash(void)
  708. {   struct object *token1, *token2, *aptr;
  709.     float dashlength[dashsize], dashtotal;
  710.     float r;
  711.     int len;
  712.     if (opernest < 2) error(errstackunderflow);
  713.     token2 = &operstack[opernest - 1];
  714.     token1 = token2 - 1;
  715.     if (token1->type != typearray) error(errtypecheck);
  716.     if (token1->flags & flagrprot) error(errinvalidaccess);
  717.     if (token2->type == typeint)
  718.         r = token2->value.ival;
  719.     else if (token2->type == typereal)
  720.         r = token2->value.rval;
  721.     else
  722.         error(errtypecheck);
  723.     if (r < 0.0) error(errrangecheck);
  724.     if (token1->length != 0)
  725.     {   dashtotal = 0.0;
  726.         aptr = vmaptr(token1->value.vref);
  727.         for (len = 0; len < token1->length; len++)
  728.         {   if      (aptr->type == typeint)
  729.                 dashlength[len] = aptr->value.ival;
  730.             else if (aptr->type == typereal)
  731.                 dashlength[len] = aptr->value.rval;
  732.             else
  733.                 error(errtypecheck);
  734.             if (dashlength[len] < 0.0) error(errrangecheck);
  735.             dashtotal += dashlength[len];
  736.             aptr++;
  737.         }
  738.         if (dashtotal == 0.0) error(errrangecheck);
  739.         memcpy((char *) gstate.dashlength, (char *) dashlength,
  740.                 len * sizeof (float));
  741.     }
  742.     gstate.dasharray = *token1;
  743.     gstate.dashoffset = r;
  744.     opernest -= 2;
  745. }
  746.  
  747. /* setflat */
  748.  
  749. void opsetflat(void)
  750. {   struct object *token1;
  751.     float r;
  752.     if (opernest < 1) error(errstackunderflow);
  753.     token1 = &operstack[opernest - 1];
  754.     if      (token1->type == typeint)
  755.         r = token1->value.ival;
  756.     else if (token1->type == typereal)
  757.         r = token1->value.rval;
  758.     else
  759.         error(errtypecheck);
  760.     if (r <= 0.0001) error(errrangecheck);
  761.     gstate.flatness = r;
  762.     opernest--;
  763. }
  764.  
  765. /* setgray */
  766.  
  767. void opsetgray(void)
  768. {   struct object *token1;
  769.     float gray;
  770.     if (gstate.cacheflag) error(errundefined);
  771.     if (opernest < 1) error(errstackunderflow);
  772.     token1 = &operstack[opernest - 1];
  773.     if      (token1->type == typeint)
  774.         gray = token1->value.ival;
  775.     else if (token1->type == typereal)
  776.         gray = token1->value.rval;
  777.     else
  778.         error(errtypecheck);
  779.     setcolour(1, &gray);
  780.     opernest--;
  781. }
  782.  
  783. /* sethsbcolor */
  784.  
  785. void opsethsbcolor(void)
  786. {   struct object *token1;
  787.     float hsb[3];
  788.     int i;
  789.     if (gstate.cacheflag) error(errundefined);
  790.     if (opernest < 3) error(errstackunderflow);
  791.     token1 = &operstack[opernest - 3];
  792.     for (i = 0; i < 3; i++)
  793.     {   if      (token1->type == typeint)
  794.             hsb[i] = token1->value.ival;
  795.         else if (token1->type == typereal)
  796.             hsb[i] = token1->value.rval;
  797.         else
  798.             error(errtypecheck);
  799.         token1++;
  800.     }
  801.     sethsbcolour(hsb);
  802.     opernest -= 3;
  803. }
  804.  
  805. /* setlinecap */
  806.  
  807. void opsetlinecap(void)
  808. {   struct object *token1;
  809.     int i;
  810.     if (opernest < 1) error(errstackunderflow);
  811.     token1 = &operstack[opernest - 1];
  812.     if (token1->type != typeint) error(errtypecheck);
  813.     i = token1->value.ival;
  814.     if (i < 0 || i > 2) error(errrangecheck);
  815.     gstate.linecap = i;
  816.     opernest--;
  817. }
  818.  
  819. /* setlinejoin */
  820.  
  821. void opsetlinejoin(void)
  822. {   struct object *token1;
  823.     int i;
  824.     if (opernest < 1) error(errstackunderflow);
  825.     token1 = &operstack[opernest - 1];
  826.     if (token1->type != typeint) error(errtypecheck);
  827.     i = token1->value.ival;
  828.     if (i < 0 || i > 2) error(errrangecheck);
  829.     gstate.linejoin = i;
  830.     opernest--;
  831. }
  832.  
  833. /* setlinewidth */
  834.  
  835. void opsetlinewidth(void)
  836. {   struct object *token1;
  837.     float r;
  838.     if (opernest < 1) error(errstackunderflow);
  839.     token1 = &operstack[opernest - 1];
  840.     if      (token1->type == typeint)
  841.         r = token1->value.ival;
  842.     else if (token1->type == typereal)
  843.         r = token1->value.rval;
  844.     else
  845.         error(errtypecheck);
  846.     if (r < 0.0) error(errrangecheck);
  847.     gstate.linewidth = r;
  848.     opernest--;
  849. }
  850.  
  851. /* setmatrix */
  852.  
  853. void opsetmatrix(void)
  854. {   struct object *token1;
  855.     float newctm[6];
  856.     if (opernest < 1) error(errstackunderflow);
  857.     token1 = &operstack[opernest - 1];
  858.     if (token1->type != typearray) error(errtypecheck);
  859.     if (token1->length != 6) error(errrangecheck);
  860.     if (token1->flags & flagrprot) error(errinvalidaccess);
  861.     getmatrix(token1->value.vref, newctm);
  862.     memcpy((char *) gstate.ctm, (char *) newctm, sizeof newctm);
  863.     opernest--;
  864. }
  865.  
  866. /* setmiterlimit */
  867.  
  868. void opsetmiterlimit(void)
  869. {   struct object *token1;
  870.     float r, s;
  871.     if (opernest < 1) error(errstackunderflow);
  872.     token1 = &operstack[opernest - 1];
  873.     if      (token1->type == typeint)
  874.         r = token1->value.ival;
  875.     else if (token1->type == typereal)
  876.         r = token1->value.rval;
  877.     else
  878.         error(errtypecheck);
  879.     if (r < 1.0) error(errrangecheck);
  880.     s = 1.0 / r;
  881.     gstate.mitrelimit = r;
  882.     gstate.mitresin = 2.0 * s * sqrt(1.0 - s * s);
  883.     opernest--;
  884. }
  885.  
  886. /* setrgbcolor */
  887.  
  888. void opsetrgbcolor(void)
  889. {   struct object *token1;
  890.     float rgb[3];
  891.     int i;
  892.     if (gstate.cacheflag) error(errundefined);
  893.     if (opernest < 3) error(errstackunderflow);
  894.     token1 = &operstack[opernest - 3];
  895.     for (i = 0; i < 3; i++)
  896.     {   if      (token1->type == typeint)
  897.             rgb[i] = token1->value.ival;
  898.         else if (token1->type == typereal)
  899.             rgb[i] = token1->value.rval;
  900.         else
  901.             error(errtypecheck);
  902.         token1++;
  903.     }
  904.     setcolour(3, rgb);
  905.     opernest -= 3;
  906. }
  907.  
  908. /* setscreen */
  909.  
  910. void opsetscreen(void)
  911. {   struct object *token1, *token2, *token3;
  912.     float freq, ang;
  913.     if (opernest < 3) error(errstackunderflow);
  914.     token3 = &operstack[opernest - 1];
  915.     token2 = token3 - 1;
  916.     token1 = token2 - 1;
  917.     if      (token1->type == typeint)
  918.         freq = token1->value.ival;
  919.     else if (token1->type == typereal)
  920.         freq = token1->value.rval;
  921.     else
  922.         error(errtypecheck);
  923.     if (freq <= 0) error(errrangecheck);
  924.     if      (token2->type == typeint)
  925.         ang = token2->value.ival;
  926.     else if (token2->type == typereal)
  927.         ang = token2->value.rval;
  928.     else
  929.         error(errtypecheck);
  930.     if ((token3->type != typearray && token3->type != typepacked) ||
  931.         !(token3->flags & flagexec))
  932.         error(errtypecheck);
  933.     gstate.screendepth = 1;
  934.     gstate.screenfreq[0] = freq;
  935.     gstate.screenangle[0] = ang;
  936.     gstate.screenfunc[0] = *token3;
  937.     halfok = gstacksize + 1;
  938.     setuphalf();
  939.     opernest -= 3;
  940. }
  941.  
  942. /* settransfer */
  943.  
  944. void opsettransfer(void)
  945. {   struct object *token1;
  946.     if (gstate.cacheflag) error(errundefined);
  947.     if (opernest < 1) error(errstackunderflow);
  948.     token1 = &operstack[opernest - 1];
  949.     if ((token1->type != typearray && token1->type != typepacked) ||
  950.         !(token1->flags & flagexec))
  951.         error(errtypecheck);
  952.     gstate.transdepth = 1;
  953.     gstate.transfer[0] = *token1;
  954.     gstate.shadeok = 0;
  955.     setupshade();
  956.     opernest--;
  957. }
  958.  
  959. /* setundercolorremoval */
  960.  
  961. void opsetundercolorremoval(void)
  962. {   struct object *token1;
  963.     if (opernest < 1) error(errstackunderflow);
  964.     token1 = &operstack[opernest - 1];
  965.     if ((token1->type != typearray && token1->type != typepacked) ||
  966.         !(token1->flags & flagexec))
  967.         error(errtypecheck);
  968.     gstate.ucr = *token1;
  969.     opernest--;
  970. }
  971.  
  972.  
  973. /* transform */
  974.  
  975. void optransform(void)
  976. {   struct object *token1, *token2, *token3;
  977.     struct point point;
  978.     float newctm[6];
  979.     if (opernest < 2) error(errstackunderflow);
  980.     token3 = &operstack[opernest - 1];
  981.     if (token3->type == typearray)
  982.     {   if (token3->length != 6) error(errrangecheck);
  983.         if (token3->flags & flagrprot) error(errinvalidaccess);
  984.         if (opernest < 3) error(errstackunderflow);
  985.         token2 = token3 - 1;
  986.         token1 = token2 - 1;
  987.         getmatrix(token3->value.vref, newctm);
  988.     }
  989.     else
  990.     {   token2 = token3;
  991.         token1 = token2 - 1;
  992.     }
  993.     if      (token1->type == typeint)
  994.         point.x = token1->value.ival;
  995.     else if (token1->type == typereal)
  996.         point.x = token1->value.rval;
  997.     else
  998.         error(errtypecheck);
  999.     if      (token2->type == typeint)
  1000.         point.y = token2->value.ival;
  1001.     else if (token2->type == typereal)
  1002.         point.y = token2->value.rval;
  1003.     else
  1004.         error(errtypecheck);
  1005.     if (token3->type == typearray)
  1006.     {   transform(&point, newctm);
  1007.         opernest--;
  1008.     }
  1009.     else
  1010.         transform(&point, gstate.ctm);
  1011.     token1->type = typereal;
  1012.     token1->value.rval = point.x;
  1013.     token2->type = typereal;
  1014.     token2->value.rval = point.y;
  1015. }
  1016.  
  1017. /* translate */
  1018.  
  1019. void optranslate(void)
  1020. {   struct object *token1, *token2, *token3;
  1021.     float newctm[6], matrix[6], x, y;
  1022.     if (opernest < 2) error(errstackunderflow);
  1023.     token3 = &operstack[opernest - 1];
  1024.     if (token3->type == typearray)
  1025.     {   if (token3->length != 6) error(errrangecheck);
  1026.         if (token3->flags & flagwprot) error(errinvalidaccess);
  1027.         if (opernest < 3) error(errstackunderflow);
  1028.         token2 = token3 - 1;
  1029.         token1 = token2 - 1;
  1030.     }
  1031.     else
  1032.     {   token2 = token3;
  1033.         token1 = token2 - 1;
  1034.     }
  1035.     if      (token1->type == typeint)
  1036.         x = token1->value.ival;
  1037.     else if (token1->type == typereal)
  1038.         x = token1->value.rval;
  1039.     else
  1040.         error(errtypecheck);
  1041.     if      (token2->type == typeint)
  1042.         y = token2->value.ival;
  1043.     else if (token2->type == typereal)
  1044.         y = token2->value.rval;
  1045.     else
  1046.         error(errtypecheck);
  1047.     matrix[0] = matrix[3] = 1.0;
  1048.     matrix[1] = matrix[2] = 0.0;
  1049.     matrix[4] = x;
  1050.     matrix[5] = y;
  1051.     if (token3->type == typearray)
  1052.     {   arraysave(token3->value.vref, 6);
  1053.         putmatrix(token3->value.vref, matrix);
  1054.         *token1 = *token3;
  1055.     }
  1056.     else
  1057.     {   multiplymatrix(newctm, matrix, gstate.ctm);
  1058.         memcpy((char *) gstate.ctm, (char *) newctm, sizeof newctm);
  1059.     }
  1060.     opernest -= 2;
  1061. }
  1062.  
  1063. /* Initialise the operators (3) */
  1064.  
  1065. void initop3(void)
  1066. {   systemop(opconcat,           "concat");
  1067.     systemop(opconcatmatrix,     "concatmatrix");
  1068.     systemop(opcurrentblackgeneration,"currentblackgeneration");
  1069.     systemop(opcurrentcmykcolor, "currentcmykcolor");
  1070.     systemop(opcurrentcolorscreen,"currentcolorscreen");
  1071.     systemop(opcurrentcolortransfer,"currentcolortransfer");
  1072.     systemop(opcurrentdash,      "currentdash");
  1073.     systemop(opcurrentflat,      "currentflat");
  1074.     systemop(opcurrentgray,      "currentgray");
  1075.     systemop(opcurrenthsbcolor,  "currenthsbcolor");
  1076.     systemop(opcurrentlinecap,   "currentlinecap");
  1077.     systemop(opcurrentlinejoin,  "currentlinejoin");
  1078.     systemop(opcurrentlinewidth, "currentlinewidth");
  1079.     systemop(opcurrentmatrix,    "currentmatrix");
  1080.     systemop(opcurrentmiterlimit,"currentmiterlimit");
  1081.     systemop(opcurrentrgbcolor,  "currentrgbcolor");
  1082.     systemop(opcurrentscreen,    "currentscreen");
  1083.     systemop(opcurrenttransfer,  "currenttransfer");
  1084.     systemop(opcurrentundercolorremoval,"currentundercolorremoval");
  1085.     systemop(opdefaultmatrix,    "defaultmatrix");
  1086.     systemop(opdtransform,       "dtransform");
  1087.     systemop(opgrestore,         "grestore");
  1088.     systemop(opgrestoreall,      "grestoreall");
  1089.     systemop(opgsave,            "gsave");
  1090.     systemop(opidentmatrix,      "identmatrix");
  1091.     systemop(opidtransform,      "idtransform");
  1092.     systemop(opinitgraphics,     "initgraphics");
  1093.     systemop(opinitmatrix,       "initmatrix");
  1094.     systemop(opinvertmatrix,     "invertmatrix");
  1095.     systemop(opitransform,       "itransform");
  1096.     systemop(opmatrix,           "matrix");
  1097.     systemop(oprotate,           "rotate");
  1098.     systemop(opscale,            "scale");
  1099.     systemop(opsetblackgeneration,"setblackgeneration");
  1100.     systemop(opsetcmykcolor,     "setcmykcolor");
  1101.     systemop(opsetcolorscreen,   "setcolorscreen");
  1102.     systemop(opsetcolortransfer, "setcolortransfer");
  1103.     systemop(opsetdash,          "setdash");
  1104.     systemop(opsetflat,          "setflat");
  1105.     systemop(opsetgray,          "setgray");
  1106.     systemop(opsethsbcolor,      "sethsbcolor");
  1107.     systemop(opsetlinecap,       "setlinecap");
  1108.     systemop(opsetlinejoin,      "setlinejoin");
  1109.     systemop(opsetlinewidth,     "setlinewidth");
  1110.     systemop(opsetmatrix,        "setmatrix");
  1111.     systemop(opsetmiterlimit,    "setmiterlimit");
  1112.     systemop(opsetrgbcolor,      "setrgbcolor");
  1113.     systemop(opsetscreen,        "setscreen");
  1114.     systemop(opsettransfer,      "settransfer");
  1115.     systemop(opsetundercolorremoval,"setundercolorremoval");
  1116.     systemop(optransform,        "transform");
  1117.     systemop(optranslate,        "translate");
  1118. }
  1119.  
  1120. /* End of file "postop3.c" */
  1121.