summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlgs/lib/gs_indxd.ps
blob: f58e552d0a8719e7f4612155e47654e6b142dc50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
%    Copyright (C) 2001, 2002 Aladdin Enterprises.  All rights reserved.
% 
% This software is provided AS-IS with no warranty, either express or
% implied.
% 
% This software is distributed under license and may not be copied,
% modified or distributed except as expressly authorized under the terms
% of the license contained in the file LICENSE in this distribution.
% 
% For more information about licensing, please refer to
% http://www.ghostscript.com/licensing/. For information on
% commercial licensing, go to http://www.artifex.com/licensing/ or
% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
% San Rafael, CA  94903, U.S.A., +1(415)492-9861.

% $Id: gs_indxd.ps 7162 2006-11-04 17:05:22Z alexcher $
% Indexed color space method dictionary


% verify that Indexed color spaces are supported
/.setindexedspace where
  { pop }
  { currentfile closefile }
ifelse

.currentglobal true .setglobal
.cspace_util begin

%
%   <num>  <array>   restrict_index   <int>  <array>
%
% Restrict the operand to setcolor for an Indexed color space to be an
% integer in the applicable range.
%
/restrict_index
  {
    exch round cvi
    dup 0 lt
      { pop 0 }
      {
        1 index 2 get 2 copy gt
          { exch }
        if
        pop
      } 
    ifelse
    exch
  }
bind def

%
%   <num>  <array>   get_indexed_base_color   <c1> ... <cn>  <array>
%
% Get the base color corresponding to an indexed color value.
%
/get_indexed_base_color
  {
    % just in case, set the index into the appropriate range
    //restrict_index exec

    % lookup in the string or use the lookup proc
    mark 1 index 3 get dup type /stringtype eq
      {
        2 index 1 get //.cs_get_ncomps exec dup 6 -1 roll mul exch getinterval
          { 255 div }
        forall
      }
      { 4 -1 roll exch exec }
    ifelse
    counttomark 2 add -2 roll pop
  }
bind def


colorspacedict
/Indexed
  mark
    /cs_potential_indexed_base false
    /cs_potential_pattern_base true
    /cs_potential_alternate false
    /cs_potential_icc_alternate false
    /cs_get_ncomps //ncomps_1
    /cs_get_range { 0 exch 2 get 2 array astore } bind
    /cs_get_default_color { pop 0 } bind

    /cs_get_currentgray
      { //get_indexed_base_color exec 1 get //.cs_get_currentgray exec }
    bind
    /cs_get_currentrgb
      { //get_indexed_base_color exec 1 get //.cs_get_currentrgb exec }
    bind
    /cs_get_currentcmyk
      { //get_indexed_base_color exec 1 get //.cs_get_currentcmyk exec }
    bind

    % a lot of validation is done by the cs_validate method
    /cs_validate
      {
        //check_array exec
        dup 1 get //.cs_validate exec //.cs_potential_indexed_base exec not
          //setcspace_rangecheck
        if
        dup 2 get dup type /integertype ne
          //setcspace_typecheck
          {
            dup 0 lt exch 4095 gt or
              //setcspace_rangecheck
            if
          }
        ifelse
        dup 3 get dup type /stringtype eq
          {
            length
            1 index dup 2 get 1 add exch 1 get //.cs_get_ncomps exec mul
            lt
              //setcspace_rangecheck
            if
          }
          {
            //check_array exec xcheck not
              //setcspace_typecheck
            if
          }
        ifelse
      }
    bind

    % substitute the base space if appropriate
    /cs_substitute
      {
        dup 1 get //.cs_substitute exec 2 copy eq
          { pop pop dup }
          {
            % retain only the new base space
            exch pop

            % build all new structures in local VM
            .currentglobal 3 1 roll //false .setglobal

            % construct a new array and insert the new base color space            
            1 index dup length array copy dup 1 4 -1 roll put

            % restore VM mode
            3 -1 roll .setglobal
          }
        ifelse
      }
    bind

    /cs_prepare {}

    %
    % Install the current color space. Note that the alternative color
    % space will already have been set as the current color space.
    %
    % The current Ghostscript color space implementation requires that
    % color spaces that provide a base or alternative color space set
    % that base/alternative color space to be the current color space
    % before attempting to set the original color space.
    %
    /cs_install
      {
        % save the current color space
        currentcolorspace

        % set the base color space as the current color space
        1 index 1 get //forcesetcolorspace

        % set the indexed color space; restore the earlier space on error
        mark 2 index
          { .setindexedspace }
        stopped
          { cleartomark setcolorspace stop }
          { pop pop pop }
        ifelse
      }
    bind

    % Adobe implementations accept floating point values
    /cs_prepare_color { //validate_1 exec cvi } bind

    %
    % Adobe implementations always execute a lookup procedure when setcolor
    % is invoked. Ghostscript samples the lookup procedure when
    % setcolorspace is invoked, and then does not access it again. In the
    % unlikely event that an application depends on the Adobe-specific
    % behavior, it is replicated in this method.
    %
    /cs_complete_setcolor
      {
        3 get dup type /stringtype eq
          { pop }
          {
            currentcolor exch exec
            currentcolorspace 1 get //clear_setcolor_operands exec
          }
        ifelse
      }
    bind

  .dicttomark
put

end     % .cspace_util
.setglobal