summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlgs/lib/gs_sepr.ps
blob: 07b070b96756202f69062bc47631fb450468c945 (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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
%    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_sepr.ps 7201 2006-11-15 16:12:42Z ray $
% Separation color space method dictionary


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

.currentglobal true .setglobal
.cspace_util begin


%
%   <c1>  <array>   apply_sepr_tint_xform   <c1>' ... <cn>'  <array>
%
% Apply the tint transform for a Separation color space color intensity
% value.
%
/apply_sepr_tint_xform
  {
    exch //bound_0_1 exec
    mark exch 2 index 3 get exec
    counttomark { cvr counttomark -1 roll } repeat % for CET, make all tints real.
    counttomark 2 add -2 roll pop
  }
bind def


%
%  <cspace_array>   build_tintxform_function   <cspace_array>  <proc>
%
% Convert a tint transformation into a function, if possible. If this is
% successful, <proc> will be a function procedure (a two-element,
% execute-only, executable array whose first element is the function
% data structure and whose second element is the operator %execfunction.
% If it is not successful, <proc> will be the same as the tint transform
% in <cspace_array>.
%
% Note that, for PDF files, the tint transform will likely already be a
% function-array. In this case, <proc> will be this array, and thus will
% also be identical to the original tint transform.
%
% This procedure is used for both Separation and DeviceN color spaces.
%
/build_tintxform_function
  {
    dup 3 get dup .isencapfunction not
      {
        % Try a FunctionType 4 function first; build the function dictionary
        % in local VM.
        .currentglobal exch //false .setglobal
	% Make the dictionary a couple of elements large in case this fails
	% and we need the dictionary to build a sampled function.
        6 dict begin
        /FunctionType 4 def
        /Function exch def
        /Domain 2 index //.cs_get_range exec def
        /Range 2 index 2 get //.cs_get_range exec def
        currentdict end
        { .buildfunction }
        .internalstopped	% If .buildfunction fails then not type 4 func.
        {			% If not then try building a sampled (type 0) func.
	  % We are using the dictionary which was created before .buildfunction
          dup /Order 3 put
          dup /BitsPerSample 16 put
          { .buildsampledfunction }
          .internalstopped	% If .buildsamplefunction fails then invalid func.
          {			% Failed - Create a dummy tint transform function
	    % We are using the dictionary which was created before .buildfunction
    	    dup /Function {} put    % Replace invalid tint transform with dummy
    	    .buildfunction
    	  }
          if		% Check status from .buildsamplefunction/.internalstopped
	}
	if		% check status from .buildfunction/.intermalstopped
        % restore the VM mode
        exch .setglobal
      }
    if
  }
bind def

%
%  <array1>  <array2>   converttinttransform   <array1>  <array2'>
%
% Convert a Separation/DeviceN color space to use a function as a tint
% transformation, if this is possible. Possible outcomes are:
%
%  1. The tint transform already is a function, or is a procedure that
%     cannot be converted to a function. In either case, <array2> is
%     left unchanged (<array2> == <array2'>).
%
%  2. The tint transform is not already a function but can be converted
%     to a function, and <array1> != <array2>. In this case, <array2>
%     is modified directly.
%
%  3. The tint transform is not already a function but can be converted
%     to a function, and <array1> == <array2>. In this case, <array2>
%     is copied, and the copy is modified (i.e., after the operation
%     <array1> != <array2>
%
% This slightly complex approach avoids creating an extra color space
% array unnecessarily.
%
/converttinttransform
  {
    % convert the tint transform to a fucntion
    //build_tintxform_function exec

    % see if anything needs to be modified
    1 index 3 get 2 copy eq
      { pop pop }
      {
        pop

        % see if the color space must be copied
        3 copy pop eq
          {
            % copy the array into local VM
            .currentglobal //false .setglobal
            3 -1 roll dup length array copy 3 1 roll
            .setglobal
          }
        if
        1 index exch 3 exch put
      }
    ifelse
  }
bind def


colorspacedict
/Separation
  mark
    /cs_potential_indexed_base true
    /cs_potential_pattern_base true
    /cs_potential_alternate false
    /cs_potential_icc_alternate false
    /cs_get_ncomps //ncomps_1
    /cs_get_range //get_range_1
    /cs_get_default_color { pop 1 } bind

    /cs_get_currentgray
      { //apply_sepr_tint_xform exec 2 get //.cs_get_currentgray exec }
    bind
    /cs_get_currentrgb
      { //apply_sepr_tint_xform exec 2 get //.cs_get_currentrgb exec }
    bind
    /cs_get_currentcmyk
      { //apply_sepr_tint_xform exec 2 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 type dup /nametype ne exch /stringtype ne and
          //setcspace_typecheck
        if
        dup 2 get //.cs_validate exec //.cs_potential_alternate exec not
          //setcspace_rangecheck
        if
        dup 3 get //check_array exec xcheck not
          //setcspace_typecheck
        if
      }
    bind

    % substitute the base space if appropriate
    /cs_substitute
      {
        dup 2 get //.cs_substitute exec 2 copy eq
          { pop pop dup }
          {
            % retain only the new alternate 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 2 4 -1 roll put

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

    %
    % The Ghostscript interpreter works better when tinttransform procedures
    % are translated into functions. Attempt to do that here.
    %
    /cs_prepare //converttinttransform

    %
    % Install 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 2 get //forcesetcolorspace

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

    /cs_prepare_color //validate_1

    %
    % If a Separation color space is not supported in native mode by
    % the current process color model, Adobe implementations will always
    % execute the tint transform procedure when setcolor is invoked.
    % Ghostscript may have turned this transform into a sampled function,
    % and even if this is not the case, will have sampled the transform
    % when the color space is first set. Some applications may depend
    % on the Adobe behavior, so we implement it via the
    % cs_complete_setcolor method.
    %
    /cs_complete_setcolor
      {
        .usealternate
          {
            currentcolor exch 3 get exec
            currentcolorspace 2 get //clear_setcolor_operands exec
          }
          { pop }
        ifelse
      }
    bind

  .dicttomark
put

end     % .cspace_util
.setglobal