2 |
- |
1 |
% Copyright (C) 2002 Aladdin Enterprises. All rights reserved.
|
|
|
2 |
%
|
|
|
3 |
% This software is provided AS-IS with no warranty, either express or
|
|
|
4 |
% implied.
|
|
|
5 |
%
|
|
|
6 |
% This software is distributed under license and may not be copied,
|
|
|
7 |
% modified or distributed except as expressly authorized under the terms
|
|
|
8 |
% of the license contained in the file LICENSE in this distribution.
|
|
|
9 |
%
|
|
|
10 |
% For more information about licensing, please refer to
|
|
|
11 |
% http://www.ghostscript.com/licensing/. For information on
|
|
|
12 |
% commercial licensing, go to http://www.artifex.com/licensing/ or
|
|
|
13 |
% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
|
|
|
14 |
% San Rafael, CA 94903, U.S.A., +1(415)492-9861.
|
|
|
15 |
|
|
|
16 |
% $Id: gs_cspace.ps,v 1.6 2003/06/26 22:42:33 dan Exp $
|
|
|
17 |
% basic colorspace mechanism
|
|
|
18 |
|
|
|
19 |
%
|
|
|
20 |
% This new implementation of color spaces extends the color space
|
|
|
21 |
% formalism to all PostScript levels. Level specific features and
|
|
|
22 |
% operators continue to be accessible only in the appropriate level,
|
|
|
23 |
% but the colorspace concept and associated mechanisms are used
|
|
|
24 |
% throughout.
|
|
|
25 |
%
|
|
|
26 |
% The color space mechanism is built around two dictionaries:
|
|
|
27 |
%
|
|
|
28 |
% .cspace_util
|
|
|
29 |
% A dictionary in global VM that is accessible in userdict only
|
|
|
30 |
% during initialization. This dictionary is intended for various
|
|
|
31 |
% utility procedures that are used in implementing the individual
|
|
|
32 |
% color spaces.
|
|
|
33 |
%
|
|
|
34 |
% colorspacedict
|
|
|
35 |
% A dictionary of methods for each color space type. The keys
|
|
|
36 |
% in this dictionary are color space type names (e.g.: /DeviceGray,
|
|
|
37 |
% /Separation, etc.), and the values are dictionaries of methods.
|
|
|
38 |
% The set of methods is the same for each color space type, and
|
|
|
39 |
% provides a complete implementation for the corresponding color
|
|
|
40 |
% space type. This dictionary is in global VM.
|
|
|
41 |
%
|
|
|
42 |
% The information specific to a color space type is created in a file
|
|
|
43 |
% for that type or group of types (e.g.: gs_csdev.ps, gs_csindx.ps,
|
|
|
44 |
% etc.). These files will generally adhere to the template:
|
|
|
45 |
%
|
|
|
46 |
% .currentglobal true .setglobal
|
|
|
47 |
% <level-specific dictionary> begin
|
|
|
48 |
% ...
|
|
|
49 |
% .cspace_util begin
|
|
|
50 |
% colorspacedict
|
|
|
51 |
% /<color space type name>
|
|
|
52 |
% mark
|
|
|
53 |
% /cs_validate
|
|
|
54 |
% {
|
|
|
55 |
% ...
|
|
|
56 |
% }
|
|
|
57 |
% bind
|
|
|
58 |
% ...
|
|
|
59 |
% .dicttomark
|
|
|
60 |
% put
|
|
|
61 |
% end % .cspace_util
|
|
|
62 |
% end ... % level-specific dictionary
|
|
|
63 |
% .setglobal
|
|
|
64 |
%
|
|
|
65 |
% The methods associated with a color space are listed below (along with
|
|
|
66 |
% their stack handling), followed by descriptions.
|
|
|
67 |
%
|
|
|
68 |
% - cs_potential_indexed_base <bool>
|
|
|
69 |
%
|
|
|
70 |
% - cs_potential_pattern_base <bool>
|
|
|
71 |
%
|
|
|
72 |
% - cs_potential_alternate <bool>
|
|
|
73 |
%
|
|
|
74 |
% - cs_potential_icc_alternate <bool>
|
|
|
75 |
%
|
|
|
76 |
%
|
|
|
77 |
% <name | array> cs_get_ncomps <int>
|
|
|
78 |
%
|
|
|
79 |
% <name | array> cs_get_range <range_array>
|
|
|
80 |
%
|
|
|
81 |
% <name | array> cs_get_default_color <c1> ... <cn>
|
|
|
82 |
%
|
|
|
83 |
%
|
|
|
84 |
% <c1> ... <cn> <name | array> cs_get_currentgray <gray>
|
|
|
85 |
%
|
|
|
86 |
% <c1> ... <cn> <name | array> cs_get_currentrgb <red> <green> <blue>
|
|
|
87 |
%
|
|
|
88 |
% <c1> ... <cn> <name | array> cs_get_currentcmyk
|
|
|
89 |
% <cyan> <magenta> <yellow> <black>
|
|
|
90 |
%
|
|
|
91 |
%
|
|
|
92 |
% <name | array> cs_validate <name | array>
|
|
|
93 |
%
|
|
|
94 |
% <name1 | array1> cs_substitute <name1 | array1> <array2>
|
|
|
95 |
%
|
|
|
96 |
% <name1 | array1> <array2> cs_prepare <name1 | array1> <array2>
|
|
|
97 |
%
|
|
|
98 |
% <name | array> cs_install -
|
|
|
99 |
%
|
|
|
100 |
%
|
|
|
101 |
% <c1> ... <cn> <array> cs_verify_color <c1> ... <cn>
|
|
|
102 |
%
|
|
|
103 |
% <array> cs_complete_color -
|
|
|
104 |
%
|
|
|
105 |
%
|
|
|
106 |
% cs_potential_indexed_base, cs_potential_pattern_base,
|
|
|
107 |
% cs_potential_alternate, cs_potential_icc_alternate
|
|
|
108 |
% These are booleans rather than procedures. They indicate if the color
|
|
|
109 |
% space can be a base space of an Indexed color space (anything except
|
|
|
110 |
% Indexed and Pattern), a Pattern color space (anything except Pattern),
|
|
|
111 |
% the alternative color space of a Separation or DeviceN color space, or
|
|
|
112 |
% the alternative color space of an ICCBased color space. The two
|
|
|
113 |
% parameters are distinct only because of a Ghostscript-specific
|
|
|
114 |
% implementation problem; in principle, there is nothing special about
|
|
|
115 |
% ICCBased color spaces in this regard.
|
|
|
116 |
%
|
|
|
117 |
% cs_get_ncomps
|
|
|
118 |
% Return the number of color components for the color spaces. For Pattern
|
|
|
119 |
% color spaces, the value is -1 if there is no base space, or -(n + 1) if
|
|
|
120 |
% the base space has n components.
|
|
|
121 |
%
|
|
|
122 |
% cs_get_range
|
|
|
123 |
% Return the input Range array appropriate for this color space. This is
|
|
|
124 |
% defined for all color spaces, though it is of interest primarily for
|
|
|
125 |
% CIEBased and ICCBased color spaces. For Indexed color spaces this is
|
|
|
126 |
% [ 0 hival ], where hival is the maximum support index value. For all
|
|
|
127 |
% other non-CIEBased, non-ICCBased color spaces, the range is an array
|
|
|
128 |
% of ncomps elements, all of which are [ 0 1 ], where ncomps is the
|
|
|
129 |
% number of color space components.
|
|
|
130 |
%
|
|
|
131 |
% cs_get_default_color
|
|
|
132 |
% Generates the default color for the current color space. Under normal
|
|
|
133 |
% circumstances this is done internally. It is provided in PostScript
|
|
|
134 |
% only to support an optimization that doesn't change the current color
|
|
|
135 |
% space more often than necessary.
|
|
|
136 |
%
|
|
|
137 |
% cs_get_currentgray, cs_get_currentrgb, cs_get_currentcmyk
|
|
|
138 |
% These procedures are used to implement the currentgray, currentrgb,
|
|
|
139 |
% and currentcmyk operators (which are pseudo-operators in the current
|
|
|
140 |
% implementation).
|
|
|
141 |
%
|
|
|
142 |
% cs_validate
|
|
|
143 |
% Validate the operand color space. Because color spaces are extensively
|
|
|
144 |
% manipulated in PostScript in this implementation, error handling can
|
|
|
145 |
% become burdensome. To make the code somewhat simpler, it is useful to
|
|
|
146 |
% be able to validate a color space prior to manipulation, so as to
|
|
|
147 |
% ensure that errors are not discovered in awkward places.
|
|
|
148 |
%
|
|
|
149 |
% cs_substitute
|
|
|
150 |
% Substitute a device-independent color space for device specific color
|
|
|
151 |
% space. This applies directly to the device-specific color spaces
|
|
|
152 |
% (DeviceGray, DeviceRGB, DeviceCMYK), and indirectly when these color
|
|
|
153 |
% spaces are used as base/alternative color spaces. The mechanism for
|
|
|
154 |
% color substitution is included in all language levels, though it may
|
|
|
155 |
% only be accessed for Language Level 3.
|
|
|
156 |
%
|
|
|
157 |
% The substituted color space is the topmost of the operands pushed.
|
|
|
158 |
% this may or may not be the same as the original color space, which
|
|
|
159 |
% is immediately below it on the operand stack. If the two differ,
|
|
|
160 |
% the substituted space will always be in local VM (and will be
|
|
|
161 |
% writable).
|
|
|
162 |
%
|
|
|
163 |
% Substitution is applied recursively to the base/alternate color
|
|
|
164 |
% space of ICCBased, Indexed, Separation, DeviceN, or Pattern
|
|
|
165 |
% color spaces. Because Ghostscript currently requires that any
|
|
|
166 |
% base or alternative color space be the current color space when
|
|
|
167 |
% the enclosing color space is set, this substitution effectively
|
|
|
168 |
% occurs twice: once in the original color space, and once when the
|
|
|
169 |
% base/alternative color space is made the current color space.
|
|
|
170 |
% We retain the first substitution as we would eventually like to
|
|
|
171 |
% remove the restriction on making the base/alternative color space
|
|
|
172 |
% the current color space.
|
|
|
173 |
%
|
|
|
174 |
% cs_prepare
|
|
|
175 |
% Perform any operations required on the color space for installation.
|
|
|
176 |
% This method exists primarily to allow conversion of PostScript
|
|
|
177 |
% procedures to functions for CIEBased color spaces. Two operands are
|
|
|
178 |
% provided: the original and the substituted color space. If the two
|
|
|
179 |
% differ and the latter is writable, required modifications can
|
|
|
180 |
% be made "in place". Otherwise, a new instance of the second color
|
|
|
181 |
% space must be built.
|
|
|
182 |
%
|
|
|
183 |
% Currently, cs_prepare is not explicitly recursive. Because
|
|
|
184 |
% Ghostscript requires a base/alternate color space to be installed
|
|
|
185 |
% as the current color space prior to installing the enclosing color
|
|
|
186 |
% space, the cs_prepare method will implicitly be called recursively.
|
|
|
187 |
% The reason for not making this explicit is that color space
|
|
|
188 |
% preparation may involve a considerable amount of work, which could
|
|
|
189 |
% be avoided if, for example, an alternative color space will not
|
|
|
190 |
% be used because the enclosing Separation/DeviceN color space is
|
|
|
191 |
% supported in native mode by the process color model. We would
|
|
|
192 |
% eventually like to remove the need to prepare color spaces that
|
|
|
193 |
% will not be used.
|
|
|
194 |
%
|
|
|
195 |
% cs_install
|
|
|
196 |
% This method actually installs the color space in the graphic state.
|
|
|
197 |
% Only the substituted/prepared space (which may be the same as the
|
|
|
198 |
% original space) is passed as an operand; the original space is handled
|
|
|
199 |
% directly by the .setcolorspace operator.
|
|
|
200 |
%
|
|
|
201 |
% The provision of a separate method for this tasks reflects the
|
|
|
202 |
% historical implementation of color spaces in the Ghostscript
|
|
|
203 |
% interpreter. This implementation provides a unique operator for each
|
|
|
204 |
% color space type.
|
|
|
205 |
%
|
|
|
206 |
% cs_prepare_color
|
|
|
207 |
% Modify a set of color operands as required by a color space. This
|
|
|
208 |
% is used primarily to verify the color operands, as this is most
|
|
|
209 |
% conveniently done in PostScript.
|
|
|
210 |
%
|
|
|
211 |
% cs_complete_setcolor
|
|
|
212 |
% This method is invoked immediately after a (successful) invocation
|
|
|
213 |
% of setcolor. Ii is provided as a separate method for compatibility
|
|
|
214 |
% with Adobe implementations. These implementations invoke the lookup
|
|
|
215 |
% (Indexed) or tint procedure each time setcolor is invoked (only if
|
|
|
216 |
% the alternative color space is used in the case of the tint
|
|
|
217 |
% transform). Because Ghostscript may convert these procedures to
|
|
|
218 |
% functions (or pre-sample them), the procedures may not always be
|
|
|
219 |
% called when expected. There are applications that depend on this
|
|
|
220 |
% behavior (e.g.: Adobe PhotoShop 5+), so this method provides a way
|
|
|
221 |
% to emulate it.
|
|
|
222 |
%
|
|
|
223 |
% In principle, a cs_complete_setcolor procedure for an Indexed color
|
|
|
224 |
% space whose base space should invoke cs_complete_setcolor on its
|
|
|
225 |
% base space. Currently we don't do this, because it has not been
|
|
|
226 |
% shown to be necessary. It would be simple to add if it is every
|
|
|
227 |
% needed.
|
|
|
228 |
%
|
|
|
229 |
% All of these methods are procedures.
|
|
|
230 |
%
|
|
|
231 |
% For each of these methods, there is a procedure in .cspace_util with
|
|
|
232 |
% a dot ('.') prefix that will invoke the appropriate procedure for the
|
|
|
233 |
% operand array.
|
|
|
234 |
%
|
|
|
235 |
|
|
|
236 |
.currentglobal true .setglobal
|
|
|
237 |
userdict /.cspace_util 80 dict put
|
|
|
238 |
.cspace_util begin
|
|
|
239 |
|
|
|
240 |
%
|
|
|
241 |
% Colorspacedict is initially in .cspace_util; it is copied to level2dict
|
|
|
242 |
% in the Level 2 initialization code to retain compatibility with
|
|
|
243 |
% earlier implementations.
|
|
|
244 |
%
|
|
|
245 |
/colorspacedict 20 dict def
|
|
|
246 |
|
|
|
247 |
|
|
|
248 |
%
|
|
|
249 |
% <obj> make_array1 <array>
|
|
|
250 |
%
|
|
|
251 |
% procedure for conditionally converting a named color space to a
|
|
|
252 |
% 1-element array. Since names are always global, the array will be
|
|
|
253 |
% as well.
|
|
|
254 |
%
|
|
|
255 |
/make_array1
|
|
|
256 |
{
|
|
|
257 |
dup type /nametype eq
|
|
|
258 |
{ currentglobal true setglobal exch 1 array astore exch setglobal }
|
|
|
259 |
if
|
|
|
260 |
}
|
|
|
261 |
bind def
|
|
|
262 |
|
|
|
263 |
%
|
|
|
264 |
% <name|array> .get_cspace_type name
|
|
|
265 |
%
|
|
|
266 |
% Provide generic routine for retrieving the color space type.
|
|
|
267 |
%
|
|
|
268 |
/.get_cspace_type
|
|
|
269 |
{
|
|
|
270 |
dup type dup /arraytype eq exch /packedarraytype eq or
|
|
|
271 |
{ 0 get }
|
|
|
272 |
if
|
|
|
273 |
}
|
|
|
274 |
bind def
|
|
|
275 |
|
|
|
276 |
%
|
|
|
277 |
% <name|array> .get_method_dict <dict>
|
|
|
278 |
%
|
|
|
279 |
% Get the method dictionary for a specific color space. Note that the
|
|
|
280 |
% color space is left on the stack.
|
|
|
281 |
%
|
|
|
282 |
/.get_method_dict
|
|
|
283 |
{ //colorspacedict exch //.get_cspace_type exec get }
|
|
|
284 |
bind def
|
|
|
285 |
|
|
|
286 |
%
|
|
|
287 |
% <name|array> <proc_name> .get_method <name|array> <proc | bool>
|
|
|
288 |
%
|
|
|
289 |
% Get the named method for the operand color space.
|
|
|
290 |
%
|
|
|
291 |
/.get_method
|
|
|
292 |
{ exch //.get_method_dict exec exch get }
|
|
|
293 |
bind def
|
|
|
294 |
|
|
|
295 |
|
|
|
296 |
%
|
|
|
297 |
% <name_array> .cs_potential_indexed_base <bool>
|
|
|
298 |
% <name_array> .cs_potential_pattern_base <bool>
|
|
|
299 |
% <name_array> .cs_potential_alternate <bool>
|
|
|
300 |
% <name_array> .cs_potential_icc_alternate <bool>
|
|
|
301 |
% <name | array> .cs_get_ncomps <int>
|
|
|
302 |
% <name | array> .cs_get_range <range_array>
|
|
|
303 |
% <name | array> .cs_get_default_color <c1> ... <cn>
|
|
|
304 |
% <c1> ... <cn> <name | array> .cs_get_currentgray <gray>
|
|
|
305 |
% <c1> ... <cn> <name | array> .cs_get_currentrgb <r> <g> <b>
|
|
|
306 |
% <c1> ... <cn> <name | array> .cs_get_currentcmyk <c> <m> <y> <k>
|
|
|
307 |
% <name | array> .cs_validate <name | array>
|
|
|
308 |
% <name1 | array1> .cs_substitute <name1 | array1> <array2>
|
|
|
309 |
% <name1 | array1> <array2> .cs_prepare <name1 | array1> <array2>
|
|
|
310 |
% <name | array> .cs_install -
|
|
|
311 |
% <c1> ... <cn> <array> .cs_prepare_color <c1> ... <cn>
|
|
|
312 |
% <array> .cs_complete_setcolor -
|
|
|
313 |
%
|
|
|
314 |
% These procedures provide access to the corresponding methods of the
|
|
|
315 |
% operand color space.
|
|
|
316 |
%
|
|
|
317 |
/.cs_potential_indexed_base
|
|
|
318 |
{ /cs_potential_indexed_base //.get_method exec }
|
|
|
319 |
bind def
|
|
|
320 |
|
|
|
321 |
/.cs_potential_pattern_base
|
|
|
322 |
{ /cs_potential_pattern_base //.get_method exec }
|
|
|
323 |
bind def
|
|
|
324 |
|
|
|
325 |
/.cs_potential_alternate
|
|
|
326 |
{ /cs_potential_alternate //.get_method exec }
|
|
|
327 |
bind def
|
|
|
328 |
|
|
|
329 |
/.cs_potential_icc_alternate
|
|
|
330 |
{ /cs_potential_icc_alternate //.get_method exec }
|
|
|
331 |
bind def
|
|
|
332 |
|
|
|
333 |
/.cs_get_ncomps
|
|
|
334 |
{ dup /cs_get_ncomps //.get_method exec exec }
|
|
|
335 |
bind def
|
|
|
336 |
|
|
|
337 |
/.cs_get_range
|
|
|
338 |
{ dup /cs_get_range //.get_method exec exec }
|
|
|
339 |
bind def
|
|
|
340 |
|
|
|
341 |
/.cs_get_default_color
|
|
|
342 |
{ dup /cs_get_default_color //.get_method exec exec }
|
|
|
343 |
bind def
|
|
|
344 |
|
|
|
345 |
/.cs_get_currentgray
|
|
|
346 |
{ dup /cs_get_currentgray //.get_method exec exec }
|
|
|
347 |
bind def
|
|
|
348 |
|
|
|
349 |
/.cs_get_currentrgb
|
|
|
350 |
{ dup /cs_get_currentrgb //.get_method exec exec }
|
|
|
351 |
bind def
|
|
|
352 |
|
|
|
353 |
/.cs_get_currentcmyk
|
|
|
354 |
{ dup /cs_get_currentcmyk //.get_method exec exec }
|
|
|
355 |
bind def
|
|
|
356 |
|
|
|
357 |
/.cs_validate
|
|
|
358 |
{ dup /cs_validate //.get_method exec exec }
|
|
|
359 |
bind def
|
|
|
360 |
|
|
|
361 |
/.cs_substitute
|
|
|
362 |
{ dup /cs_substitute //.get_method exec exec }
|
|
|
363 |
bind def
|
|
|
364 |
|
|
|
365 |
/.cs_prepare
|
|
|
366 |
{ dup /cs_prepare //.get_method exec exec }
|
|
|
367 |
bind def
|
|
|
368 |
|
|
|
369 |
/.cs_install
|
|
|
370 |
{ dup /cs_install //.get_method exec exec }
|
|
|
371 |
bind def
|
|
|
372 |
|
|
|
373 |
/.cs_prepare_color
|
|
|
374 |
{ dup /cs_prepare_color //.get_method exec exec }
|
|
|
375 |
bind def
|
|
|
376 |
|
|
|
377 |
/.cs_complete_setcolor
|
|
|
378 |
{ dup /cs_complete_setcolor //.get_method exec exec }
|
|
|
379 |
bind def
|
|
|
380 |
|
|
|
381 |
|
|
|
382 |
%
|
|
|
383 |
% Make sure we have an interpreter color space before redefining
|
|
|
384 |
% setcolorspace. The interpreter internal code only sets the effective
|
|
|
385 |
% color space; the interpreters color spaces begins as a null object.
|
|
|
386 |
%
|
|
|
387 |
% NB: This should come prior to the redefinition of setcolorspace, and
|
|
|
388 |
% must use an array operand.
|
|
|
389 |
%
|
|
|
390 |
[ /DeviceGray ] setcolorspace
|
|
|
391 |
|
|
|
392 |
|
|
|
393 |
%
|
|
|
394 |
% <c1> ... <cn> setcolor -
|
|
|
395 |
%
|
|
|
396 |
% As with setcolorspace, setcolor is initially placed in .cspace_util,
|
|
|
397 |
% and is copied to level2dict by the Level 2 initialization code. The
|
|
|
398 |
% internal definition of setcolor is removed from systemdict as soon
|
|
|
399 |
% as this procedure is defined.
|
|
|
400 |
%
|
|
|
401 |
/setcolor
|
|
|
402 |
{
|
|
|
403 |
{
|
|
|
404 |
currentcolorspace //.cs_prepare_color exec //setcolor
|
|
|
405 |
currentcolorspace //.cs_complete_setcolor exec
|
|
|
406 |
}
|
|
|
407 |
stopped
|
|
|
408 |
{ //.cspace_util /setcolor get $error /errorname get signalerror }
|
|
|
409 |
if
|
|
|
410 |
}
|
|
|
411 |
bind odef
|
|
|
412 |
|
|
|
413 |
systemdict /setcolor .undef
|
|
|
414 |
|
|
|
415 |
|
|
|
416 |
%
|
|
|
417 |
% <name|array> <bool> _setcolorspace -
|
|
|
418 |
% <name|array> _setcolorspace_nosub -
|
|
|
419 |
%
|
|
|
420 |
% <name|array> setcolorspace -
|
|
|
421 |
% <name|array> forcesetcolorspace -
|
|
|
422 |
%
|
|
|
423 |
% setcolorspace is initially placed in .cspace_util. It is copied to
|
|
|
424 |
% level2dict by the Level 2 initialization code. The internal
|
|
|
425 |
% setcolorspace operator is removed from systemdict as soon as this
|
|
|
426 |
% procedure is defined.
|
|
|
427 |
%
|
|
|
428 |
% Because some jobs, in particular PDF jobs, repeatedly set the same
|
|
|
429 |
% color space, this procedure will check if the operand and current
|
|
|
430 |
% color spaces are the same. The check is absolute for parameterless
|
|
|
431 |
% color spaces, conservative for others. For PostScript, this
|
|
|
432 |
% optimization can only be employed if color space substitution is
|
|
|
433 |
% disabled, as otherwise there is no way to account for possible changes
|
|
|
434 |
% in the /Default* instances of the ColorSpace resource category. For PDF
|
|
|
435 |
% jobs, resource category instances can only be changed at very specific
|
|
|
436 |
% times (typically page boundaries), so the "operand color space is the
|
|
|
437 |
% same as current color space" optimization may be used even if color
|
|
|
438 |
% space substitution is in effect. The optimization is also highly
|
|
|
439 |
% desirable in such cases, as it greatly improves performance.
|
|
|
440 |
%
|
|
|
441 |
% In certain situations, it is critical that a color space be set,
|
|
|
442 |
% even if it is the same as the current color space. This is the case
|
|
|
443 |
% when a CIEBased color space is used as a base or alternative color
|
|
|
444 |
% space, due to some long-standing problems with the graphics libraries
|
|
|
445 |
% handling of sampled information from the procedures in CIE color
|
|
|
446 |
% spaces and the color rendering dictionary. The forcesetcolorspace
|
|
|
447 |
% operator is provided for those situations.
|
|
|
448 |
%
|
|
|
449 |
% Note also that, if the current color space is not reset, at least
|
|
|
450 |
% the current color must be reset to its default value.
|
|
|
451 |
%
|
|
|
452 |
% Another problem arises in the case of ICCBased color spaces. These
|
|
|
453 |
% color spaces may be used to substitute for a DeviceGray/DeviceRGB/
|
|
|
454 |
% DeviceCMYK color space, and may themselves require such a color
|
|
|
455 |
% space as an alternate. Obviously, when this is the case the normal
|
|
|
456 |
% setcolorspace mechanism would encounter and infinite loop if the
|
|
|
457 |
% alternate colro space needed to be used. For this particular case,
|
|
|
458 |
% the special _setcolorspace_nosub is provided, which suppresses
|
|
|
459 |
% color space substitution. This routine does not bother to check if
|
|
|
460 |
% the operand and current color space are the same.
|
|
|
461 |
%
|
|
|
462 |
/_setcolorspace
|
|
|
463 |
{
|
|
|
464 |
{
|
|
|
465 |
% see if the operand space is the same as the current space
|
|
|
466 |
currentcolorspace dup length 1 eq
|
|
|
467 |
{
|
|
|
468 |
|
|
|
469 |
2 index dup type dup /arraytype eq exch /packedarraytype eq or
|
|
|
470 |
{
|
|
|
471 |
dup length 1 eq
|
|
|
472 |
{ 0 get }
|
|
|
473 |
if
|
|
|
474 |
}
|
|
|
475 |
if
|
|
|
476 |
}
|
|
|
477 |
{ 2 index }
|
|
|
478 |
ifelse
|
|
|
479 |
eq and dup
|
|
|
480 |
{
|
|
|
481 |
%
|
|
|
482 |
% If PDFfile is defined on the dictionary stack, this is a
|
|
|
483 |
% PDF job. No additional check is required in this case (see
|
|
|
484 |
% comment above).
|
|
|
485 |
%
|
|
|
486 |
/PDFfile where
|
|
|
487 |
{ pop }
|
|
|
488 |
{ .getuseciecolor not and } % check that UseCIEColor is off
|
|
|
489 |
ifelse
|
|
|
490 |
}
|
|
|
491 |
if
|
|
|
492 |
{ //.cs_get_default_color exec setcolor }
|
|
|
493 |
{
|
|
|
494 |
//.cs_validate exec
|
|
|
495 |
//.cs_substitute exec
|
|
|
496 |
//.cs_prepare exec
|
|
|
497 |
//.cs_install exec
|
|
|
498 |
//make_array1 exec //setcolorspace
|
|
|
499 |
}
|
|
|
500 |
ifelse
|
|
|
501 |
}
|
|
|
502 |
stopped
|
|
|
503 |
{ //.cspace_util /setcolorspace get $error /errorname get signalerror }
|
|
|
504 |
if
|
|
|
505 |
}
|
|
|
506 |
bind def
|
|
|
507 |
|
|
|
508 |
/_setcolorspace_nosub
|
|
|
509 |
{
|
|
|
510 |
{
|
|
|
511 |
//.cs_validate exec
|
|
|
512 |
dup
|
|
|
513 |
//.cs_prepare exec
|
|
|
514 |
//.cs_install exec
|
|
|
515 |
//make_array1 exec //setcolorspace
|
|
|
516 |
}
|
|
|
517 |
stopped
|
|
|
518 |
{ //.cspace_util /setcolorspace get $error /errorname get signalerror }
|
|
|
519 |
if
|
|
|
520 |
}
|
|
|
521 |
bind def
|
|
|
522 |
|
|
|
523 |
/setcolorspace { //true //_setcolorspace exec } bind odef
|
|
|
524 |
/forcesetcolorspace { //false //_setcolorspace exec } bind odef
|
|
|
525 |
|
|
|
526 |
%
|
|
|
527 |
% - initgraphics -
|
|
|
528 |
%
|
|
|
529 |
% The initgraphics operator must be redefined create a real color space.
|
|
|
530 |
% Previously this was unnecessary, as .currentcolorspace could return
|
|
|
531 |
% an integer.
|
|
|
532 |
%
|
|
|
533 |
%
|
|
|
534 |
/initgraphics
|
|
|
535 |
{ initgraphics { /DeviceGray } cvlit forcesetcolorspace }
|
|
|
536 |
.bind systemdict begin odef end
|
|
|
537 |
|
|
|
538 |
systemdict /setcolorspace .undef
|
|
|
539 |
|
|
|
540 |
|
|
|
541 |
%
|
|
|
542 |
% <gray> setgray -
|
|
|
543 |
%
|
|
|
544 |
% <r> <g> <b> setrgbcolor -
|
|
|
545 |
%
|
|
|
546 |
% <c> <m> <y> <b> setcmykcolor -
|
|
|
547 |
%
|
|
|
548 |
% The Level 1 color setting operators. setcmykcolor is created only if
|
|
|
549 |
% setcolorscreen is present. These operators are always defined in
|
|
|
550 |
% systemdict.
|
|
|
551 |
%
|
|
|
552 |
/setgray
|
|
|
553 |
{
|
|
|
554 |
{ { /DeviceGray } cvlit //setcolorspace //setcolor }
|
|
|
555 |
stopped
|
|
|
556 |
{ /setgray load $error /errorname get signalerror }
|
|
|
557 |
if
|
|
|
558 |
}
|
|
|
559 |
bind systemdict begin odef end
|
|
|
560 |
|
|
|
561 |
/setrgbcolor
|
|
|
562 |
{
|
|
|
563 |
{ { /DeviceRGB } cvlit //setcolorspace //setcolor }
|
|
|
564 |
stopped
|
|
|
565 |
{ /setrgbcolor load $error /errorname get signalerror }
|
|
|
566 |
if
|
|
|
567 |
}
|
|
|
568 |
bind systemdict begin odef end
|
|
|
569 |
|
|
|
570 |
/setcolorscreen where
|
|
|
571 |
{
|
|
|
572 |
pop
|
|
|
573 |
/setcmykcolor
|
|
|
574 |
{
|
|
|
575 |
{ { /DeviceCMYK } cvlit //setcolorspace //setcolor }
|
|
|
576 |
stopped
|
|
|
577 |
{ /setcmykcolor load $error /errorname get signalerror }
|
|
|
578 |
if
|
|
|
579 |
}
|
|
|
580 |
bind systemdict begin odef end
|
|
|
581 |
}
|
|
|
582 |
if
|
|
|
583 |
|
|
|
584 |
|
|
|
585 |
%
|
|
|
586 |
% - currentgray <gray>
|
|
|
587 |
%
|
|
|
588 |
% - currentrgbcolor <r> <g> <b>
|
|
|
589 |
%
|
|
|
590 |
% - currentcmykcolor <c> <m> <y> <k>
|
|
|
591 |
%
|
|
|
592 |
% Return the current color, mapped to a DeviceGray, DeviceRGB, or
|
|
|
593 |
% DeviceCMYK color space. The latter is only created if setcolorscreen
|
|
|
594 |
% is present.
|
|
|
595 |
/currentgray
|
|
|
596 |
{ currentcolor currentcolorspace //.cs_get_currentgray exec }
|
|
|
597 |
bind systemdict begin odef end
|
|
|
598 |
|
|
|
599 |
/currentrgbcolor
|
|
|
600 |
{ currentcolor currentcolorspace //.cs_get_currentrgb exec }
|
|
|
601 |
bind systemdict begin odef end
|
|
|
602 |
|
|
|
603 |
/setcolorscreen where
|
|
|
604 |
{
|
|
|
605 |
pop
|
|
|
606 |
/currentcmykcolor
|
|
|
607 |
{ currentcolor currentcolorspace //.cs_get_currentcmyk exec }
|
|
|
608 |
bind systemdict begin odef end
|
|
|
609 |
}
|
|
|
610 |
if
|
|
|
611 |
|
|
|
612 |
|
|
|
613 |
|
|
|
614 |
%
|
|
|
615 |
% Add some generically useful structures and procedures to .cspace_util.
|
|
|
616 |
%
|
|
|
617 |
|
|
|
618 |
%
|
|
|
619 |
% Some common errors. The command for these errors will normally be
|
|
|
620 |
% overwritten by the invoking operator. We cannot "load" the secolorspace
|
|
|
621 |
% or setcolor operators, as they are not present in Level 1 systems.
|
|
|
622 |
%
|
|
|
623 |
/setcspace_typecheck
|
|
|
624 |
{ /setcolorspace cvx /typecheck signalerror }
|
|
|
625 |
bind def
|
|
|
626 |
|
|
|
627 |
/setcspace_rangecheck
|
|
|
628 |
{ /setcolorspace cvx /rangecheck signalerror }
|
|
|
629 |
bind def
|
|
|
630 |
|
|
|
631 |
/setcspace_invalidaccess
|
|
|
632 |
{ /setcolorspace cvx /invalidaccess signalerror }
|
|
|
633 |
bind def
|
|
|
634 |
|
|
|
635 |
/setcspace_undefined
|
|
|
636 |
{ /setcolorspace cvx /undefined signalerror }
|
|
|
637 |
bind def
|
|
|
638 |
|
|
|
639 |
/setcolor_typecheck
|
|
|
640 |
{ /setcolor cvx /typecheck signalerror }
|
|
|
641 |
bind def
|
|
|
642 |
|
|
|
643 |
/setcolor_invalidaccess
|
|
|
644 |
{ /setcolor cvx /invalidaccess signalerror }
|
|
|
645 |
bind def
|
|
|
646 |
|
|
|
647 |
|
|
|
648 |
%
|
|
|
649 |
% <obj> check_array <obj>
|
|
|
650 |
%
|
|
|
651 |
% Check that an object is an array. Currently we don't check for
|
|
|
652 |
% readability, as a failing get or length operator should generate
|
|
|
653 |
% the appropriate invalidaccess error.
|
|
|
654 |
/check_array
|
|
|
655 |
{
|
|
|
656 |
dup type dup /arraytype ne exch /packedarraytype ne and
|
|
|
657 |
{ /setcolorspace cvx /typecheck signalerror }
|
|
|
658 |
if
|
|
|
659 |
}
|
|
|
660 |
bind def
|
|
|
661 |
|
|
|
662 |
|
|
|
663 |
% pre-defined procedures for cs_ncomps and cs_get_range
|
|
|
664 |
/ncomps_1 { pop 1 } bind def
|
|
|
665 |
/ncomps_3 { pop 3 } bind def
|
|
|
666 |
/ncomps_4 { pop 4 } bind def
|
|
|
667 |
|
|
|
668 |
/dflt_range_4 [ 0 1 0 1 0 1 0 1 ] readonly def
|
|
|
669 |
/dflt_range_3 dflt_range_4 0 6 getinterval def
|
|
|
670 |
/dflt_range_1 dflt_range_4 0 2 getinterval def
|
|
|
671 |
|
|
|
672 |
% <obj> get_range_[1|3|4] <range>
|
|
|
673 |
/get_range_1 { pop //dflt_range_1 } bind def
|
|
|
674 |
/get_range_3 { pop //dflt_range_3 } bind def
|
|
|
675 |
/get_range_4 { pop //dflt_range_4 } bind def
|
|
|
676 |
|
|
|
677 |
|
|
|
678 |
%
|
|
|
679 |
% <c1> ... <cn> <name | array> <n>
|
|
|
680 |
% check_num_stack
|
|
|
681 |
% <c1> ... <cn> <array | array>
|
|
|
682 |
%
|
|
|
683 |
% <c1> <array> validate_color_1 <c1>
|
|
|
684 |
% <c1> <c2> <c3> <arraY> validate_color_3 <c1> <c2> <c3>
|
|
|
685 |
% <c1> <c2> <c3> <c4> <arraY> validate_color_4 <c1> <c2> <c3> <c4>
|
|
|
686 |
%
|
|
|
687 |
% check_num_stack verifies that the stack consists of a color space array and
|
|
|
688 |
% n numbers. This is used by most of the cs_prepare_color procedures. The
|
|
|
689 |
% validate_color_[1|3|4] procedures can be used as the cs_prepare_color
|
|
|
690 |
% procedure for Device specific, CIEBased, and Indexed color spaces.
|
|
|
691 |
%
|
|
|
692 |
% Note that the pseudo-operator that (indirectly) invokes this routine will
|
|
|
693 |
% handle resetting the stacks.
|
|
|
694 |
%
|
|
|
695 |
/check_num_stack
|
|
|
696 |
{
|
|
|
697 |
dup 2 add copy exch pop
|
|
|
698 |
{
|
|
|
699 |
type dup /integertype ne exch /realtype ne and
|
|
|
700 |
//setcolor_typecheck
|
|
|
701 |
if
|
|
|
702 |
}
|
|
|
703 |
repeat
|
|
|
704 |
pop % remove the extra op_count
|
|
|
705 |
}
|
|
|
706 |
bind def
|
|
|
707 |
|
|
|
708 |
% <c1> <array> validate_1 <c1>
|
|
|
709 |
/validate_1 { 1 //check_num_stack exec pop } bind def
|
|
|
710 |
|
|
|
711 |
% <c1> <c2> <c3> <array> validate_3 <c1> <c2> <c3>
|
|
|
712 |
/validate_3 { 3 //check_num_stack exec pop } bind def
|
|
|
713 |
|
|
|
714 |
% <c1> <c2> <c3> <c4> <array> validate_4 <c1> <c2> <c3> <c4>
|
|
|
715 |
/validate_4 { 4 //check_num_stack exec pop } bind def
|
|
|
716 |
|
|
|
717 |
|
|
|
718 |
%
|
|
|
719 |
% <obj> pop_1 -
|
|
|
720 |
%
|
|
|
721 |
% This is a procedure form of pop. It may be used where a procedure is
|
|
|
722 |
% expected, but the function of the procedure is the same as the pop
|
|
|
723 |
% operator.
|
|
|
724 |
/pop_1 { pop } bind def
|
|
|
725 |
|
|
|
726 |
%
|
|
|
727 |
% <obj> dup_1 <obj> <obj>
|
|
|
728 |
%
|
|
|
729 |
% An analog to pop_1, this one for dup.
|
|
|
730 |
%
|
|
|
731 |
/dup_1 { dup } bind def
|
|
|
732 |
|
|
|
733 |
%
|
|
|
734 |
% <obj1> ... <objn> <n> clear_n_objs -
|
|
|
735 |
%
|
|
|
736 |
% Clear n objects from the operand stack.
|
|
|
737 |
%
|
|
|
738 |
/clear_n_objs { //pop_1 repeat } bind def
|
|
|
739 |
|
|
|
740 |
%
|
|
|
741 |
% <obj1> ... <objn> <array> clear_setcolor_operands -
|
|
|
742 |
%
|
|
|
743 |
% Clear the setcolor operands for a color space.
|
|
|
744 |
%
|
|
|
745 |
/clear_setcolor_operands
|
|
|
746 |
{ //.cs_get_ncomps exec //clear_n_objs exec }
|
|
|
747 |
bind def
|
|
|
748 |
|
|
|
749 |
%
|
|
|
750 |
% Return 1, 3, or 4 zeros. These routines are used primarily for the
|
|
|
751 |
% CIEBased color spaces, for which currentgray and currentrgb
|
|
|
752 |
% should return 0 for all components, and currentcmyk should return
|
|
|
753 |
% 0 0 0 1.0 (this varies from Adobe's documentation but is consistent
|
|
|
754 |
% with their impelementations).
|
|
|
755 |
%
|
|
|
756 |
/no_currentgray { //.cs_get_ncomps exec //clear_n_objs exec 0 } bind def
|
|
|
757 |
/no_currentrgb { //.cs_get_ncomps exec //clear_n_objs exec 0 0 0 } bind def
|
|
|
758 |
/no_currentcmyk { //.cs_get_ncomps exec //clear_n_objs exec 0 0 0 1.0 } bind def
|
|
|
759 |
|
|
|
760 |
|
|
|
761 |
%
|
|
|
762 |
% <num> bound_0_1 <num>
|
|
|
763 |
%
|
|
|
764 |
% Bound a number to the range [0, 1]
|
|
|
765 |
%
|
|
|
766 |
/bound_0_1
|
|
|
767 |
{
|
|
|
768 |
dup 0 lt
|
|
|
769 |
{ pop 0 }
|
|
|
770 |
{
|
|
|
771 |
dup 1 gt
|
|
|
772 |
{ pop 1 }
|
|
|
773 |
if
|
|
|
774 |
}
|
|
|
775 |
ifelse
|
|
|
776 |
}
|
|
|
777 |
bind def
|
|
|
778 |
|
|
|
779 |
|
|
|
780 |
%
|
|
|
781 |
% Provide pseudo-operators for sethsbcolor and currenthsbcolor. These are
|
|
|
782 |
% alternate versions of the setrgbcolor and currentrgbcolor operators, which
|
|
|
783 |
% make use of a hue/staturation/brightness color description.
|
|
|
784 |
%
|
|
|
785 |
|
|
|
786 |
%
|
|
|
787 |
% <num_1> ... <num_n> n max_n <num>
|
|
|
788 |
% <num_1> ... <num_n> n min_n <num>
|
|
|
789 |
%
|
|
|
790 |
% Find the maximum and minum of 3 color component intensities.
|
|
|
791 |
%
|
|
|
792 |
/max_n
|
|
|
793 |
{
|
|
|
794 |
1 sub
|
|
|
795 |
{ 2 copy lt { exch } if pop }
|
|
|
796 |
repeat
|
|
|
797 |
}
|
|
|
798 |
bind def
|
|
|
799 |
|
|
|
800 |
/min_n
|
|
|
801 |
{
|
|
|
802 |
1 sub
|
|
|
803 |
{ 2 copy gt { exch } if pop }
|
|
|
804 |
repeat
|
|
|
805 |
}
|
|
|
806 |
bind def
|
|
|
807 |
|
|
|
808 |
|
|
|
809 |
%
|
|
|
810 |
% <r> <g> <b> .rgb_2_hsb <h> <s> <br>
|
|
|
811 |
% <h> <s> <br> .hsb_2_rgb <r> <g> <b>
|
|
|
812 |
%
|
|
|
813 |
% Convert between RGB and HSB colors, using the hexcone approach (see
|
|
|
814 |
% Rogers, David, "Procedureal Elements For Computer Graphics",
|
|
|
815 |
% (McGraw-Hill, 1985), pp. 402 - 3).
|
|
|
816 |
%
|
|
|
817 |
% The rgb ==> hsb calculation is:
|
|
|
818 |
%
|
|
|
819 |
% br = max(r, g, b)
|
|
|
820 |
%
|
|
|
821 |
% if (br == 0)
|
|
|
822 |
% h = 0, s = 0;
|
|
|
823 |
% else {
|
|
|
824 |
% v = min(r, g, b)
|
|
|
825 |
% diff = br - v;
|
|
|
826 |
% sat = diff / br;
|
|
|
827 |
% if (r == br)
|
|
|
828 |
% h = (g - b) / (6 * diff) + (b > g ? 1 : 0);
|
|
|
829 |
% else if (g == br)
|
|
|
830 |
% h = 1/3 + (b - r) / (6 * diff);
|
|
|
831 |
% else /* b == br */
|
|
|
832 |
% h = 2/3 + (r - g) / (6 * diff);
|
|
|
833 |
% }
|
|
|
834 |
%
|
|
|
835 |
% The hsb ==> rgb conversion is:
|
|
|
836 |
%
|
|
|
837 |
% mn = (1 - s) * br, md = 6 * s * br;
|
|
|
838 |
%
|
|
|
839 |
% switch ((int)floor(6 * h)) {
|
|
|
840 |
% case 0: /* r >= g >= b */
|
|
|
841 |
% r = br;
|
|
|
842 |
% g = mn + h * md;
|
|
|
843 |
% b = mn;
|
|
|
844 |
% break;
|
|
|
845 |
%
|
|
|
846 |
% case 1: /* g >= r >= b */
|
|
|
847 |
% r = mn + md * (1/3 - h);
|
|
|
848 |
% g = br;
|
|
|
849 |
% b = mn;
|
|
|
850 |
% break;
|
|
|
851 |
%
|
|
|
852 |
% case 2: /* g >= b >= r */
|
|
|
853 |
% r = mn;
|
|
|
854 |
% g = br;
|
|
|
855 |
% b = mn + (h - 1/3) * md;
|
|
|
856 |
% break;
|
|
|
857 |
%
|
|
|
858 |
% case 3: /* b >= g >= r */
|
|
|
859 |
% r = mn;
|
|
|
860 |
% g = mn + (2/3 - h) * md;
|
|
|
861 |
% b = br;
|
|
|
862 |
% break;
|
|
|
863 |
%
|
|
|
864 |
% case 4: /* b >= r >= g */
|
|
|
865 |
% r = mn + (h - 2/3) * md;
|
|
|
866 |
% g = mn;
|
|
|
867 |
% b = br;
|
|
|
868 |
% break;
|
|
|
869 |
%
|
|
|
870 |
% case 5: /* r >= b >= g */
|
|
|
871 |
% r = br;
|
|
|
872 |
% g = mn;
|
|
|
873 |
% b = mn + (1 - h) * md;
|
|
|
874 |
% break;
|
|
|
875 |
%
|
|
|
876 |
% case 6: /* We have wrapped around the hexcone. Thus this case is
|
|
|
877 |
% the same as case 0 with h = 0 */
|
|
|
878 |
% h = 0;
|
|
|
879 |
% r = br;
|
|
|
880 |
% g = mn + h * md = mn;
|
|
|
881 |
% b = mn;
|
|
|
882 |
% break;
|
|
|
883 |
% }
|
|
|
884 |
%
|
|
|
885 |
/.rgb_2_hsb
|
|
|
886 |
{
|
|
|
887 |
% find the largest and smallest components
|
|
|
888 |
3 copy 3 //max_n exec dup 5 1 roll
|
|
|
889 |
dup 0 eq
|
|
|
890 |
{ pop pop pop pop 0 0 }
|
|
|
891 |
{
|
|
|
892 |
4 copy pop 3 //min_n exec 1 index exch sub
|
|
|
893 |
dup 2 index div 7 1 roll
|
|
|
894 |
dup 0 eq
|
|
|
895 |
{ 5 { pop } repeat 0 3 1 roll }
|
|
|
896 |
{
|
|
|
897 |
6 mul 5 1 roll
|
|
|
898 |
2 copy eq % blue == brightness
|
|
|
899 |
{ pop pop sub exch div .666667 add }
|
|
|
900 |
{
|
|
|
901 |
2 index eq % green == brightness
|
|
|
902 |
{ exch pop exch sub exch div .3333333 add }
|
|
|
903 |
{
|
|
|
904 |
% red == brightness
|
|
|
905 |
sub exch pop exch div
|
|
|
906 |
dup 0 lt
|
|
|
907 |
{ 1 add }
|
|
|
908 |
if
|
|
|
909 |
}
|
|
|
910 |
ifelse
|
|
|
911 |
}
|
|
|
912 |
ifelse
|
|
|
913 |
3 1 roll
|
|
|
914 |
}
|
|
|
915 |
ifelse
|
|
|
916 |
}
|
|
|
917 |
ifelse
|
|
|
918 |
}
|
|
|
919 |
bind def
|
|
|
920 |
|
|
|
921 |
|
|
|
922 |
/.hsb_2_rgb
|
|
|
923 |
{
|
|
|
924 |
3 { 0 max 1 min 3 1 roll } repeat
|
|
|
925 |
1 2 index sub 1 index mul % (1 - s) * br
|
|
|
926 |
3 -1 roll 2 index mul 6 mul % 6 * s * br
|
|
|
927 |
4 -1 roll % stack: <br> <(1 - s) * br> <6 * s * br> <h>
|
|
|
928 |
|
|
|
929 |
% array of procedures for the 7 hue cases
|
|
|
930 |
{
|
|
|
931 |
% 0 ==> r >= g >= b
|
|
|
932 |
{ mul 1 index add exch }
|
|
|
933 |
|
|
|
934 |
% 1 ==> g >= r >= b
|
|
|
935 |
{ 0.333333 exch sub mul 1 index add 3 1 roll }
|
|
|
936 |
|
|
|
937 |
% 2 ==> g >= b >= r
|
|
|
938 |
{ 0.333333 sub mul 1 index add 3 1 roll exch 3 -1 roll }
|
|
|
939 |
|
|
|
940 |
% 3 ==> b >= g >= r
|
|
|
941 |
{ 0.666667 exch sub mul 1 index add 3 -1 roll }
|
|
|
942 |
|
|
|
943 |
% 4 ==> b >= r >= g
|
|
|
944 |
{ 0.666667 sub mul 1 index add 3 1 roll exch }
|
|
|
945 |
|
|
|
946 |
% 5 ==> r >= b >= g
|
|
|
947 |
{ 1 exch sub mul 1 index add }
|
|
|
948 |
|
|
|
949 |
% 6 ==> r = br, g = b = mn
|
|
|
950 |
% Case 6 is the same as case 0 with h = 0. This also simplifies
|
|
|
951 |
% the calculations.
|
|
|
952 |
{ pop pop dup }
|
|
|
953 |
}
|
|
|
954 |
1 index 6 mul cvi % (int)(6 * h)
|
|
|
955 |
get exec
|
|
|
956 |
}
|
|
|
957 |
bind def
|
|
|
958 |
|
|
|
959 |
|
|
|
960 |
%
|
|
|
961 |
% <hue> <saturation> <brightness sethsbcolor -
|
|
|
962 |
%
|
|
|
963 |
% - currenthsbcolor <hue> <saturation> <brightness>
|
|
|
964 |
%
|
|
|
965 |
/sethsbcolor
|
|
|
966 |
{
|
|
|
967 |
{ //.hsb_2_rgb exec setrgbcolor }
|
|
|
968 |
stopped
|
|
|
969 |
{ /sethsbcolor load $error /errorname get signalerror }
|
|
|
970 |
if
|
|
|
971 |
}
|
|
|
972 |
bind systemdict begin odef end
|
|
|
973 |
|
|
|
974 |
/currenthsbcolor
|
|
|
975 |
{
|
|
|
976 |
{ currentrgbcolor //.rgb_2_hsb exec }
|
|
|
977 |
stopped
|
|
|
978 |
{ /currenthsbcolor load $error /errorname get signalerror }
|
|
|
979 |
if
|
|
|
980 |
}
|
|
|
981 |
bind systemdict begin odef end
|
|
|
982 |
|
|
|
983 |
end % .cspace_util
|
|
|
984 |
.setglobal
|