home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / prog / c / post17s.lha / postop3.c < prev    next >
Text File  |  1992-03-11  |  32KB  |  1,126 lines

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