home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / g / gs252src.zip / GS252 / ZCOLOR2.C < prev    next >
C/C++ Source or Header  |  1992-07-17  |  9KB  |  312 lines

  1. /* Copyright (C) 1992 Aladdin Enterprises.  All rights reserved.
  2.    Distributed by Free Software Foundation, Inc.
  3.  
  4. This file is part of Ghostscript.
  5.  
  6. Ghostscript is distributed in the hope that it will be useful, but
  7. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  8. to anyone for the consequences of using it or for whether it serves any
  9. particular purpose or works at all, unless he says so in writing.  Refer
  10. to the Ghostscript General Public License for full details.
  11.  
  12. Everyone is granted permission to copy, modify and redistribute
  13. Ghostscript, but only under the conditions described in the Ghostscript
  14. General Public License.  A copy of this license is supposed to have been
  15. given to you along with Ghostscript so you can know your rights and
  16. responsibilities.  It should be in a file named COPYING.  Among other
  17. things, the copyright notice and this notice must be preserved on all
  18. copies.  */
  19.  
  20. /* zcolor2.c */
  21. /* Level 2 color operators for Ghostscript */
  22. #include "ghost.h"
  23. #include "errors.h"
  24. #include "oper.h"
  25. #include "gscolor.h"
  26. #include "gscspace.h"
  27. #include "gscolor2.h"
  28. #include "gsmatrix.h"
  29. #include "dict.h"
  30. #include "dparam.h"
  31. #include "name.h"        /* for name_eq */
  32. #include "state.h"
  33. #include "store.h"
  34.  
  35. /*
  36.  * NOTE: The only color spaces currently implemented by Ghostscript
  37.  * are DeviceGray, DeviceRGB, and DeviceCMYK.  This is enforced by
  38.  * gs_setcolorspace; the routines here assume all color spaces are
  39.  * implemented.
  40.  */
  41.  
  42.  
  43. /* Forward references */
  44. typedef enum { cs_allow_base, cs_allow_non_pattern, cs_allow_all } cs_allowed;
  45. private int cspace_param(P3(const ref *pcsref, gs_color_space *pcs, cs_allowed allow));
  46.  
  47. /* Names of color spaces: */
  48. static ref color_space_names[8];
  49. #define name_DeviceGray color_space_names[0]
  50. #define name_DeviceRGB color_space_names[1]
  51. #define name_DeviceCMYK color_space_names[2]
  52. #define name_CIEBasedABC color_space_names[3]
  53. #define name_CIEBasedA color_space_names[4]
  54. #define name_Separation color_space_names[5]
  55. #define name_Indexed color_space_names[6]
  56. #define name_Pattern color_space_names[7]
  57.  
  58. /* Names of keys in pattern dictionaries: */
  59. static ref name_PatternType;
  60. static ref name_PaintType;
  61. static ref name_TilingType;
  62. static ref name_BBox;
  63. static ref name_XStep;
  64. static ref name_YStep;
  65. static ref name_PaintProc;
  66. static ref name_Implementation;
  67.  
  68. /* Initialization */
  69. private void
  70. zcolor2_init()
  71. {    static const names_def patn[] = {
  72.  
  73.     /* Create the names of the color spaces. */
  74.        { "DeviceGray", &name_DeviceGray },
  75.        { "DeviceRGB", &name_DeviceRGB },
  76.        { "DeviceCMYK", &name_DeviceCMYK },
  77.        { "CIEBasedABC", &name_CIEBasedABC },
  78.        { "CIEBasedA", &name_CIEBasedA },
  79.        { "Separation", &name_Separation },
  80.        { "Indexed", &name_Indexed },
  81.        { "Pattern", &name_Pattern },
  82.  
  83.     /* Create the names of the known entries in */
  84.     /* a pattern dictionary. */
  85.        { "PatternType", &name_PatternType },
  86.        { "PaintType", &name_PaintType },
  87.        { "TilingType", &name_TilingType },
  88.        { "BBox", &name_BBox },
  89.        { "XStep", &name_XStep },
  90.        { "YStep", &name_YStep },
  91.        { "PaintProc", &name_PaintProc },
  92.        { "Implementation", &name_Implementation },
  93.  
  94.     /* Mark the end of the initalized name list. */
  95.        names_def_end
  96.     };
  97.  
  98.     init_names(patn);
  99. }
  100.  
  101.  
  102. /* currentcolor */
  103. int
  104. zcurrentcolor(register os_ptr op)
  105. {    gs_color_space cs;
  106.     gs_currentcolorspace(igs, &cs);
  107.     switch ( cs.type )
  108.     {
  109.     case gs_color_space_DeviceGray:
  110.         return zcurrentgray(op);
  111.     case gs_color_space_DeviceRGB:
  112.         return zcurrentrgbcolor(op);
  113.     case gs_color_space_DeviceCMYK:
  114.         return zcurrentcmykcolor(op);
  115.     default:
  116.         return e_typecheck;
  117.     }
  118. }
  119.  
  120. /* currentcolorspace */
  121. int
  122. zcurrentcolorspace(register os_ptr op)
  123. {    gs_color_space cs;
  124.     gs_currentcolorspace(igs, &cs);
  125.     push(1);
  126.     *op = istate.colorspace;    /* default */
  127.     switch ( cs.type )
  128.     {
  129.     case gs_color_space_Pattern:
  130.         if ( cs.params.pattern.has_base_space ) break;
  131.     case gs_color_space_DeviceGray:
  132.     case gs_color_space_DeviceRGB:
  133.     case gs_color_space_DeviceCMYK:
  134.         /* Create the 1-element array on the fly. */
  135.         make_tasv(op, t_array, a_readonly, 1, refs,
  136.               &color_space_names[(int)cs.type]);
  137.     }
  138.     return 0;
  139. }
  140.  
  141. /* makepattern */
  142. int
  143. zmakepattern(os_ptr op)
  144. {    os_ptr op1 = op - 1;
  145.     int code;
  146.     gs_matrix mat;
  147.     int PatternType, PaintType, TilingType;
  148.     float BBox[4];
  149.     float XStep, YStep;
  150.     ref *pPaintProc;
  151.     check_type(*op1, t_dictionary);
  152.     check_dict_read(*op1);
  153.     if ( (code = read_matrix(op, &mat)) < 0 ||
  154.          (code = dict_int_param(op1, &name_PatternType, 1, 1, 0, &PatternType)) < 0 ||
  155.          (code = dict_int_param(op1, &name_PaintType, 1, 2, 0, &PaintType)) < 0 ||
  156.          (code = dict_int_param(op1, &name_TilingType, 1, 3, 0, &TilingType)) < 0 ||
  157.          (code = dict_float_array_param(op1, &name_BBox, 4, BBox, NULL)) != 4 ||
  158.          (code = dict_float_param(op1, &name_XStep, 0.0, &XStep)) != 0 ||
  159.          (code = dict_float_param(op1, &name_YStep, 0.0, &YStep)) != 0 ||
  160.          (code = dict_find(op1, &name_PaintProc, &pPaintProc)) <= 0
  161.        )
  162.         return_error((code < 0 ? code : e_typecheck));
  163.     check_proc(*pPaintProc);
  164.     if ( XStep == 0 || YStep == 0 )
  165.         return_error(e_rangecheck);
  166.     /* NOT IMPLEMENTED YET */
  167.     if ( 1 ) return_error(e_undefined);
  168.     pop(1);
  169.     return 0;
  170. }
  171.  
  172. /* setcolor */
  173. int
  174. zsetcolor(register os_ptr op)
  175. {    gs_color_space cs;
  176.     gs_currentcolorspace(igs, &cs);
  177.     switch ( cs.type )
  178.     {
  179.     case gs_color_space_DeviceGray:
  180.         return zsetgray(op);
  181.     case gs_color_space_DeviceRGB:
  182.         return zsetrgbcolor(op);
  183.     case gs_color_space_DeviceCMYK:
  184.         return zsetcmykcolor(op);
  185.     default:
  186.         return e_typecheck;
  187.     }
  188. }
  189.  
  190. /* setcolorspace */
  191. int
  192. zsetcolorspace(register os_ptr op)
  193. {    gs_color_space cs;
  194.     int code = cspace_param((const ref *)op, &cs, cs_allow_all);
  195.     if ( code < 0 ) return code;
  196.     code = gs_setcolorspace(igs, &cs);
  197.     if ( code < 0 ) return code;
  198.     if ( r_has_type(op, t_name) )
  199.         make_null(&istate.colorspace);        /* no params */
  200.     else
  201.         istate.colorspace = *op;
  202.     pop(1);
  203.     return 0;
  204. }
  205.  
  206. /* ------ Internal procedures ------ */
  207.  
  208. /* Extract the parameters for a color space. */
  209. private int
  210. cspace_param(const ref *pcsref, gs_color_space *pcs, cs_allowed allow)
  211. {    const ref *pcsa, *pcsn;
  212.     uint asize;
  213.     int csi;
  214.     int code;
  215.     if ( r_has_type(pcsref, t_array) )
  216.     {    check_read(*pcsref);
  217.         pcsa = pcsref->value.const_refs;
  218.         asize = r_size(pcsa);
  219.         if ( asize == 0 ) return e_rangecheck;
  220.     }
  221.     else
  222.     {    pcsa = pcsref;
  223.         asize = 1;
  224.     }
  225.     pcsn = pcsa++;
  226.     asize--;
  227.     check_type(*pcsn, t_name);
  228.     for ( csi = 0; !name_eq(pcsn, &color_space_names[csi]); )
  229.     {    if ( ++csi == countof(color_space_names) )
  230.             return e_typecheck;
  231.     }
  232.     pcs->type = (gs_color_space_type)csi;
  233.     switch ( pcs->type )
  234.     {
  235.     case gs_color_space_DeviceGray:
  236.     case gs_color_space_DeviceRGB:
  237.     case gs_color_space_DeviceCMYK:
  238.         if ( asize != 0 ) return e_rangecheck;
  239.         break;
  240.     case gs_color_space_CIEBasedABC:
  241.         if ( asize != 1 ) return e_rangecheck;
  242.         /*return zcolorspace_CIEBasedABC(pcsa, &cs.params.abc);*/
  243.         /* NOT IMPLEMENTED YET */
  244.         return e_undefined;
  245.     case gs_color_space_CIEBasedA:
  246.         if ( asize != 1 ) return e_rangecheck;
  247.         /*return zcolorspace_CIEBasedA(pcsa, &cs.params.abc);*/
  248.         /* NOT IMPLEMENTED YET */
  249.         return e_undefined;
  250.     case gs_color_space_Separation:
  251.         if ( allow == cs_allow_base ) return e_rangecheck;
  252.         if ( asize != 3 ) return e_rangecheck;
  253.         code = cspace_param(pcsa + 1, (gs_color_space *)&pcs->params.separation.alt_space, cs_allow_base);
  254.         if ( code < 0 ) return code;
  255.         /* NOT IMPLEMENTED YET */
  256.         return e_undefined;
  257.     case gs_color_space_Indexed:
  258.         if ( allow == cs_allow_base ) return e_rangecheck;
  259.         if ( asize != 3 ) return e_rangecheck;
  260.         code = cspace_param(pcsa, (gs_color_space *)&pcs->params.indexed.base_space, cs_allow_base);
  261.         if ( code < 0 ) return code;
  262.         check_type(pcsa[1], t_integer);
  263.         if ( pcsa[1].value.intval < 0 || pcsa[1].value.intval > 4095 )
  264.             return e_rangecheck;
  265.         pcs->params.indexed.hival = pcsa[1].value.intval;
  266.         if ( r_has_type(&pcsa[2], t_string) )
  267.         {    check_read(pcsa[2]);
  268.             if ( r_size(&pcsa[2]) !=
  269.                   (pcs->params.indexed.hival + 1) *
  270.                   gs_color_space_num_components[(int)pcs->params.indexed.base_space.type]
  271.                )
  272.                 return e_rangecheck;
  273.             pcs->params.indexed.lookup =
  274.                 pcsa[2].value.const_bytes;
  275.         }
  276.         else
  277.         {    check_proc(pcsa[2]);
  278.             /* NOW WHAT? */
  279.             return e_undefined;
  280.         }
  281.         return 0;
  282.     case gs_color_space_Pattern:
  283.         if ( allow != cs_allow_all ) return e_rangecheck;
  284.         switch ( asize )
  285.         {
  286.         case 0:        /* no base space */
  287.             pcs->params.pattern.has_base_space = 0;
  288.             return 0;
  289.         default:
  290.             return e_rangecheck;
  291.         case 1:
  292.             ;
  293.         }
  294.         pcs->params.pattern.has_base_space = 1;
  295.         return cspace_param(pcsa, (gs_color_space *)&pcs->params.pattern.base_space, cs_allow_non_pattern);
  296.     default:
  297.         return e_typecheck;
  298.     }
  299.     return 0;
  300. }
  301.  
  302. /* ------ Initialization procedure ------ */
  303.  
  304. op_def zcolor2_op_defs[] = {
  305.     {"0currentcolor", zcurrentcolor},
  306.     {"0currentcolorspace", zcurrentcolorspace},
  307.     {"2makepattern", zmakepattern},
  308.     {"1setcolor", zsetcolor},
  309.     {"1setcolorspace", zsetcolorspace},
  310.     op_def_end(zcolor2_init)
  311. };
  312.