summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/tex-ps/cmyk-hax.tex
blob: 4d397c2f45fd3ab4273d0a81da4761a994293bd0 (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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% CMYK-HAX.TEX:
% E  This is a set of TeX macros supporting color separation and
%    substitution using TeX/PostScript environment. Needs DVIPS and
%    COLORDVI from standard DVIPS distribution.
%
% P  Zestaw makr TeX-owo-PostScript-owych do tworzenia wyci/ag/ow barwnych
%    i podmiany kolor/ow. Wsp/o/lpracuje ze sterownikiem DVIPS
%    i zestawem makr COLORDVI (ze standardowej dystrybucji DVIPS-a);
%
% AUTHORS' COORDINATES:
%   BOP s.c.
%   ul. Piastowska 70, 80-363 Gda\'nsk, Poland
%   tel./fax +48 58 553-46-59
%   email: bop@bop.com.pl
%
% VERSION 0.75, 15.06.2000
% Public domain
%
% HISTORY:
%  E  version released during the GUST annual meeting Bacho\TeX'95.
%  P  wersja udost/epniona podczas Bacho\TeX'95.
% VERSION 0.51, 5 V 1995:
%  E  macro \CMYKinit added (it places necessary def's in a PS prolog).
%  P  dodane zosta/lo makro inicjalizacyjne `\CMYKinit',
%     kt/ore umieszcza w prologu PS u/zywane definicje.
% VERSION 0.52, 27 VI 1995:
%  E  the `currentpoint' fault in case of empty current path; now `currentpoint'
%     is called by the `stopped' command, which makes an error action
%     availlable.
%  P  `currentpoint' generowa/l b/l/ad gdy bie/z/aca /scie/zki by/la pusta;
%     obecnie `currentpoint' jest wykonywane przez `stopped',
%     co daje mo/zliwo/s/c zareagowania na b/l/ad.
% VERSION 0.53, 23 VII 1996:
%  E   1. the constant `epsilon=0.005' entered to do approximed
%         color comparations.
%      2. \PSscreen became a \special.
%  P   1. wprowadzono sta/l/a `epsilon=0.005', kt/ora jest dok/ladno/sci/a
%         por/ownania kolor/ow.
%      2. \PSscreen by/l dot/ad makrem TeX-owym o tre/sci PS-owej
%         sensowne jest, aby sta/l si/e \specialem
% VERSION 0.54, 8 XI 1996 r.
%  E   `show'  redefinition allows the text outlining.
%  P   redefinicja `show' umo/zliwia ju/z dok/ladanie obw/odki do tekst/ow.
% VERSION 0.60, 11 IV 1997:
%  E   processing of CMYK bitmaps enabled
%  P   umo/zliwienie przetwarzania bitmap CMYK
% VERSION 0.61, 11.VIII.1997
%  E   `adddownstroke' added (stroke under fill)
%  P   dodano `adddownstroke' (rysowan/a pod fillem)
% VERSION 0.62, 24.IX.1997
%  E   `setscreen' gets all parameters
%  P   `setscreen' zyskuje wszystkie parametry podawane explicite
%      nie korzysta si/e z warto/sci `currentscreen'
% VERSION 0.64, 9.VII.1999
%  E   bitmap color separation added, delblack (also for imagemask),
%      additional 5-th all-white bitmap separation (\BITinit and /to_sep_bitmap true def /hax_sep 4 def)
%      additional 6-th all-black bitmap separation (\BITinit and /to_sep_bitmap true def /hax_sep 5 def)
%  P   do/l/aczono rozbarwianie bitmap, delblack (tak/ze dla imagemask),
%      5. bia/ly wyci/ag z bitmap (\BITinit oraz /to_sep_bitmap true def /hax_sep 4 def)
%      6. czarny wyci/ag z bitmap (\BITinit oraz /to_sep_bitmap true def /hax_sep 5 def)
% VERSION 0.65, 6.VIII.1999
%  E   5-th and 6-th bitmap separation were improved (`pop' added
%      in the case of not-dictionary images)
%  P   poprawka w 5. i 6. wyci/agu bitmap (dodano `pop' w bitmapach
%      nies/lownikowych)
% VERSION 0.66, 13.IX.1999
%  E   indexed color bitmaps support (for `colormap')
%  P   obs/luga bitmap paletowych (do `colormap')
% VERSION 0.67, 21.01.2000
%  E   support for multisource `colorimage' -- only CMYK separations
%  P   obs/luga wersji wielo/xr/od/lowej polecenia `colorimage'
%      -- na razie tylko CMYK i tylko separacja
% VERSION 0.68, 16.03.2000
%  E   \projectCMYK calls setcmykcolor explicite
%  P   \projectCMYK wywo/luje explicite setcmykcolor
% VERSION 0.70, 27.03.2000
%  E   image, colorimage and imagemask operators are transferred to
%      their dictionary form and we support them almost completly;
%      limitations: we support only bitmaps with
%      ImageType = 1, in one of Device Color Spaces,
%      when BitsPerComponent = 1 (other values of BitsPerComponent
%      we allow for imagemask, of corse, and for DeviceGray model --
%      without color substitution, unfortunately)
%  P   oparatory image, colorimage oraz imagemask przeniesione do wersji
%      s/lownikowej i prawie kompletnie obs/lu/zone;
%      ograniczenia: obs/lugujemy tylko bitmapy, dla kt/orych
%      ImageType = 1, model barw nale/zy do klasy Device Color Spaces,
%      BitsPerComponent = 8 (inne warto/sci BitsPerComponent dopuszczamy
%      oczywi/scie dla imagemask oraz w przypadku modelu DeviceGray --
%      wtedy jednak nie potrafimy podmienia/c kolor/ow)
% VERSION 0.71, 10.04.2000
%  E   3 bugs fixed:
%      1) we already support MultipleDataSources in ImageDict
%      2) it was a superfluous pop in merge_multi3
%      3) 1 level of redefinition setcmykcolor (hax_setcmykcolor) added
%  P   usuni/eto 3 pluskwy w obs/ludze image:
%      1) ju/z obs/luguje si/e MultipleDataSources w ImageDict
%      2) by/l zb/edny pop w merge_multi3
%      3) dodano 1 poziom redefinicji setcmykcolor (hax_setcmykcolor)
% VERSION 0.73, 28.04.2000
%  E   1) \sepbitmapfalse turns bitmap separation off,
%         \sepbitmaptrue turns bitmap separation on
%      2) missing ImageDict parameter added before ori_image
%  P   1) \sepbitmapfalse wy/l/acza rozbarwianie bitmap,
%         \sepbitmaptrue przywraca rozbarwianie bitmap
%      2) dodano brakuj/acy parametr ImageDict przed ori_image
% VERSION 0.74, 11.05.2000
%  E   Bug in \delblacktrue handling has been fixed;
%      the colors created from black with changecolor can be separated now.
%  P   Poprawiona pluskwa w obs/ludze \delblacktrue;
%      mo/zliwe staje si/e rozbarwianie kolor/ow powsta/lych z podmiany
%      koloru czarnego.
% VERSION 0.75, 15.06.2000
%  E   \convertbitmaptrue turns on conversion of RGB bitmaps to CMYK,
%      to allow them to be separated
%      \convertbitmapfalse truns conversion off, by default, RGB bitmaps 
%      are neither converted nor separated
%  P   \convertbitmaptrue w/l/acza konwersj/e bitmap RGB do modelu CMYK,
%      co umo/zliwia ich rozbarwianie
%      \convertbitmapfalse wy/l/acza konwersj/e bitmap RGB do modelu CMYK,
%      co uniemo/zliwia ich rozbarwianie; domy/slnie bitmapy RGB nie s/a
%      ani konwertowane, ani rozbarwiane
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
\edef\slashcatcode {\the\catcode`\/}
\catcode`\/12
%
\def\CMYKinit {\special {! userdict begin
%
/ori_setcmykcolor where {pop} {/ori_setcmykcolor /setcmykcolor load def} ifelse
/ori_setrgbcolor where {pop} {/ori_setrgbcolor /setrgbcolor load def} ifelse
/ori_setgray where {pop} {/ori_setgray /setgray load def} ifelse
/ori_colorimage where {pop} {/ori_colorimage /colorimage load def} ifelse
/ori_image where {pop} {/ori_image /image load def} ifelse
/ori_imagemask where {pop} {/ori_imagemask /imagemask load def} ifelse
/ori_fill where {pop} {/ori_fill /fill load def} ifelse
/ori_eofill where {pop} {/ori_eofill /eofill load def} ifelse
/ori_stroke where {pop} {/ori_stroke /stroke load def} ifelse
/ori_show where {pop} {/ori_show /show load def} ifelse
/hax_setcmykcolor /ori_setcmykcolor load def
%
/maybe_black {
  4 copy
  1 sub abs epsilon le exch
  0 sub abs epsilon le and exch
  0 sub abs epsilon le and exch
  0 sub abs epsilon le and 
  /if_delblack exch def
} def
%
/my_fill {userdict begin if_delblack {newpath} {ori_fill} ifelse end} def
/my_eofill {userdict begin if_delblack {newpath} {ori_eofill} ifelse end} def
/my_stroke {userdict begin if_delblack {newpath} {ori_stroke} ifelse end} def
/my_show {userdict begin if_delblack {false charpath currentpoint newpath moveto} {ori_show} ifelse end} def
%
/eofill {userdict begin my_eofill end} def
/fill {userdict begin my_fill end} def
/stroke {userdict begin my_stroke end} def
/show {userdict begin my_show end} def
%
/setcmykcolor {userdict begin
  /k_ exch def /y_ exch def /m_ exch def /c_ exch def
  c_ m_ y_ k_ hax_setcmykcolor end} def
/setgray {ori_setgray currentcmykcolor setcmykcolor} def
/setrgbcolor {ori_setrgbcolor currentcmykcolor setcmykcolor} def
%
/hax_image {
  dup type cvlit /dicttype eq {
    /ImageDict exch def
    currentcolorspace dup length 1 eq  % only Device color spaces
    ImageDict /ImageType get 1 eq and {% and ImageType 1 are supported
      0 get
      dup /DeviceRGB  eq {/ncomp 3 def} if
      dup /DeviceGray eq {/ncomp 1 def} if
          /DeviceCMYK eq {/ncomp 4 def} if
      ImageDict /BitsPerComponent get 8 ne % only gray image separations
        /ncomp 1 ne and {/ncomp 0 def} if  % allowed if sample is not a byte
    } {pop /ncomp 0 def} ifelse
  } {
    false 1 makeimagedict
  } ifelse
  ncomp 0 eq {ImageDict ori_image} {hax_image_} ifelse
} def
%
/hax_colorimage {
  makeimagedict
  hax_image_
} def
%
/makeimagedict {
  dup /ncomp exch def
  dup 4 eq {/DeviceCMYK setcolorspace} if
  dup 3 eq {/DeviceRGB setcolorspace} if
      1 eq {/DeviceGray setcolorspace} if
  /ImageDict 7 dict def ImageDict begin
    {/MultipleDataSources true def
     ncomp array astore} if % store multi source in array
    /DataSource exch def
    /ImageMatrix exch def
    /BitsPerComponent exch def
    /Height exch def
    /Width exch def
    /Decode [ncomp {0 1} repeat] def
    /ImageType 1 def
  end
} def
%
/data_str 65532 string def % very long
/data_str_ 8192 string def
/merge_multi4 {
  ImageDict /DataSource get aload pop
  dup type cvlit /filetype eq {
    /fdatsrck exch def
    /fdatsrcy exch def
    /fdatsrcm exch def
    /fdatsrcc exch def
    /datasrck {fdatsrck data_str_ readstring pop} def
    /datasrcy {fdatsrcy data_str_ readstring pop} def
    /datasrcm {fdatsrcm data_str_ readstring pop} def
    /datasrcc {fdatsrcc data_str_ readstring pop} def
  } {
    /datasrck exch def
    /datasrcy exch def
    /datasrcm exch def
    /datasrcc exch def
  } ifelse
  ImageDict /DataSource {
    data_str
    0 datasrcc {3 copy put pop 4 add} forall pop
    1 datasrcm {3 copy put pop 4 add} forall pop
    2 datasrcy {3 copy put pop 4 add} forall pop
    3 datasrck {3 copy put pop 4 add} forall
    3 sub 0 exch getinterval
  } put
} def
%
/merge_multi3 {
  ImageDict /DataSource get aload pop
  dup type cvlit /filetype eq {
    /fdatsrcb exch def
    /fdatsrcg exch def
    /fdatsrcr exch def
    /datasrcb {fdatsrcb data_str_ readstring pop} def
    /datasrcg {fdatsrcg data_str_ readstring pop} def
    /datasrcr {fdatsrcr data_str_ readstring pop} def
  } {
    /datasrcb exch def
    /datasrcg exch def
    /datasrcr exch def
  } ifelse
  ImageDict /DataSource {
    data_str
    0 datasrcr {3 copy put pop 3 add} forall pop
    1 datasrcg {3 copy put pop 3 add} forall pop
    2 datasrcb {3 copy put pop 3 add} forall
    2 sub 0 exch getinterval
  } put
} def
%
/i_Str 3 string def
/O_Str 4 string def
/UCR {0.5 mul} def
/BG {0.7 mul} def
/min {1 index 1 index le {pop} {exch pop} ifelse} def
/max {1 index 1 index ge {pop} {exch pop} ifelse} def
%
/RGBtoCMYK {% RGB pixel is on the stack
  % RGB --> CMYK conversion (Red Book p. 306)
  dup 0 get R_scale mul R_shift add /c_i exch def
  dup 1 get G_scale mul G_shift add /m_i exch def
      2 get B_scale mul B_shift add /y_i exch def
  /k_i c_i m_i y_i min min def
  O_Str
  dup 0 255 0 c_i k_i UCR sub cvi max min put
  dup 1 255 0 m_i k_i UCR sub cvi max min put
  dup 2 255 0 y_i k_i UCR sub cvi max min put
  dup 3 255 0 k_i BG cvi max min put
} def
%
/RGBtoCMYKfilter {
  ImageDict /Decode get aload pop % use Decode for RGB -> CMYK conversion
  2 copy sub /B_scale exch def pop 255 mul 255 exch sub /B_shift exch def
  2 copy sub /G_scale exch def pop 255 mul 255 exch sub /G_shift exch def
  2 copy sub /R_scale exch def pop 255 mul 255 exch sub /R_shift exch def
  /rtc_file ImageDict /DataSource get def
  ImageDict /DataSource {rtc_file i_Str readstring {RGBtoCMYK} if}
    0 () /SubFileDecode filter put
  /DeviceCMYK setcolorspace /ncomp 4 def
  ImageDict /Decode [0 1 0 1 0 1 0 1] put
} def
%
/sep_str 8192 string def
/SEP_CMYK {
  0
  hax_sep 4 3 index length 1 sub {
    2 index exch get
    3 copy put pop
    1 add
  } for
  dup 0 ne {0 exch getinterval}{pop pop ()} ifelse
} def
%
/SEPfilters {
  ncomp 4 eq {
    hax_sep 3 le {
      /sepproc /SEP_CMYK load def
      ImageDict begin /Decode [
        Decode hax_sep 2 mul 1 add get
        Decode hax_sep 2 mul get
      ] def end
    } {
      /sepproc {dup length 4 idiv 0 exch getinterval} def
    } ifelse
    /sep_file ImageDict /DataSource get def
    ImageDict /DataSource {sep_file sep_str readstring pop sepproc} 0 ()
      /SubFileDecode filter put
    /DeviceGray setcolorspace
  } {% ncomp 1 eq
    hax_sep 3 ne {ImageDict /Decode [ 1 1 ] put} if
  } ifelse
  hax_sep 4 eq {ImageDict /Decode [ 1 1 ] put} if
  hax_sep 5 eq {ImageDict /Decode [ 0 0 ] put} if
} def
%
/change_str 12288 string def % must be a multiplicity of 3 and 4
/CHANGEfilter {
  /change_file ImageDict /DataSource get def
  ImageDict /DataSource {
    change_file change_str readstring pop
    0 ncomp 2 index length ncomp sub {
      1 index exch 2 copy ncomp
      getinterval changebits putinterval
    } for
  } 0 () /SubFileDecode filter put
} def
%
/hax_image_ {
  ImageDict /MultipleDataSources known {
    ImageDict /MultipleDataSources get {
      ImageDict /MultipleDataSources false put
      ImageDict /DataSource get length
      dup 4 eq {merge_multi4} if
      dup 3 eq {merge_multi3} if
          1 eq {ImageDict begin /DataSource DataSource aload pop def end} if
    } if
  } if
  ImageDict begin
    /DataSource dup load Width BitsPerComponent mul 7 add 8 idiv
      Height ncomp mul mul () /SubFileDecode filter def
  end
  to_change_bitmap {CHANGEfilter} if
  ncomp 3 eq to_convert_bitmap and {RGBtoCMYKfilter} if
  ncomp 3 ne to_sep_bitmap and {SEPfilters} if
  ImageDict ori_image
} def
%
/zero_data_str 65532 string def % length of the data_str
/hax_imagemask {
  if_delblack {
    dup type cvlit /dicttype eq {
      /ImageDict exch def
    } {
      /ImageDict 7 dict def ImageDict begin
        /DataSource exch def
        /ImageMatrix exch def
        /Decode exch {[1 0]} {[0 1]} ifelse def
        /Height exch def
        /Width exch def
        /BitsPerComponent 1 def
        /ImageType 1 def
      end
    } ifelse
    ImageDict begin
      /DataSource load Width 7 add 8 idiv Height mul
      () /SubFileDecode filter
    end /mask_file exch def
    ImageDict /DataSource {
      zero_data_str 0 mask_file data_str readstring pop length getinterval
    } 0 () /SubFileDecode filter put
    ImageDict /Decode [1 0] put
    ImageDict ori_imagemask
  } {ori_imagemask} ifelse
} def
%
/truebp {0 matrix defaultmatrix matrix currentmatrix
  matrix invertmatrix matrix concatmatrix dtransform
  dup mul exch dup mul add sqrt} def
/truein {72 mul truebp} def
/truept {72.27 div truein} def
/truesp {65536 div truept} def
/truedd {1238 mul 1157 div truept} def
/truecc {12 mul truedd} def
/truemm {25.4 div truein} def
/truecm {10 mul truemm} def
%
/epsilon 0.005 def
/if_delblack false def
/to_change_bitmap false def
/to_convert_bitmap false def
/to_sep_bitmap false def
%
currentcmykcolor setcmykcolor
%
end % userdict
}}% \special \CMYKinit
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\PSbegingroup {\begingroup \special{ps: save }}
\def\PSendgroup {\special{ps: restore }\endgroup}
%
\def\forcolor #1{\def\thecolor{#1}}
\def\checkcolor {\thecolor\space count 4 lt {(Not CMYK ) print} if
% k_ eq exch y_ eq and exch m_ eq and exch c_ eq and
% comparison of colours with a predefined accurracy (epsilon):
  k_ sub abs epsilon le exch
  y_ sub abs epsilon le and exch
  m_ sub abs epsilon le and exch
  c_ sub abs epsilon le and }
%
\def\changefill #1{%
   \edef\changefills{\changefills \checkcolor
     {#1 hax_setcmykcolor} if }}
\def\changestroke #1{%
   \edef\changestrokes{\changestrokes \checkcolor
     {#1 hax_setcmykcolor} if }}
\def\changecolor #1{%
   \edef\changecolors{\changecolors \checkcolor
     {#1 hax_setcmykcolor} if }}
\def\addfill #1{%
   \edef\addfills{\addfills \checkcolor {addfill} if }%
   \edef\changefills{\changefills \checkcolor
     {#1 hax_setcmykcolor} if }}
\def\adddownstroke #1{%
   \edef\addstrokes{\addstrokes \checkcolor {adddownstroke} if }%
   \edef\changestrokes{\changestrokes \checkcolor
     {#1 hax_setcmykcolor} if }}
\def\addstroke #1{%
   \edef\addstrokes{\addstrokes \checkcolor {addstroke} if }%
   \edef\changestrokes{\changestrokes \checkcolor
     {#1 hax_setcmykcolor} if }}
\def\addcolor #1{\addstroke{#1}\addfill{#1}}
\def\delfill {%
   \edef\delfills{\delfills \checkcolor {delfill} if }}
\def\delstroke {%
   \edef\delstrokes{\delstrokes \checkcolor {delstroke} if }}
\def\delcolor {%
   \edef\delcolors{\delcolors \checkcolor {delfill delstroke} if }}
\def\strokehook #1{%
   \edef\strokehooks{\strokehooks \checkcolor {#1} if }}
\def\fillhook #1{%
   \edef\fillhooks{\fillhooks \checkcolor {#1} if }}
\def\strokeup {%
   \edef\changestrokes{\changestrokes \checkcolor {upstroke} if }}
\def\fillup {%
   \edef\changestrokes{\changestrokes \checkcolor {upfill} if }}
%
\def\forbitmap #1{\def\thebitcolor{<#1>}}
\def\checkbitcolor {dup \thebitcolor\space eq }
%
\def\changebitmap #1{%
   \edef\changebits{\changebits \checkbitcolor {pop <#1>} if }}
%
\def\setCMYKchange{%
  \edef\changestrokes{}%
  \edef\changefills{}%
  \edef\changecolors{}%
  \edef\addstrokes{}%
  \edef\addfills{}%
  \edef\delstrokes{}%
  \edef\delfills{}%
  \edef\delcolors{}%
  \edef\strokehooks{}%
  \edef\fillhooks{}%
  \edef\changebits{}%
}
%
\def\fillinitials{%
  /to_fill true def
  /to_stroke false def
  /to_upstroke false def
}
\def\strokeinitials{%
  /to_fill false def
  /to_stroke true def
  /to_upstroke true def
}
%
\def\useCMYKchange{%
  \special{ps:
  userdict begin
    /addfill {/to_fill true def} def
    /delfill {/to_fill false def} def
    /upfill {/to_upstroke false def} def
    /addstroke {/to_stroke true def upstroke} def
    /adddownstroke {/to_stroke true def upfill} def
    /delstroke {/to_stroke false def} def
    /upstroke {/to_upstroke true def} def
    /current_point {{currentpoint} stopped {0 0} if} def
    %
    /do_stroke {
      to_stroke {gsave \changestrokes \strokehooks my_stroke grestore} if
    } def
    %
    /eofill {
      userdict begin
        \fillinitials \delfills \delcolors \addstrokes
        current_point
        to_upstroke {} {do_stroke} ifelse
        to_fill {gsave \changefills \fillhooks my_eofill grestore} if
        to_upstroke {do_stroke} if
        newpath moveto
      end
    } def
    %
    /fill {
      userdict begin
        \fillinitials \delfills \delcolors \addstrokes
        current_point
        to_upstroke {} {do_stroke} ifelse
        to_fill {gsave \changefills \fillhooks my_fill grestore} if
        to_upstroke {do_stroke} if
        newpath moveto
      end
    } def
    %
    /stroke {
      userdict begin
        \strokeinitials \delstrokes \delcolors \addfills
        current_point
        to_upstroke {} {do_stroke} ifelse
        to_fill {gsave \changefills \fillhooks my_eofill grestore} if
        to_upstroke {do_stroke} if
        newpath moveto
      end
    } def
    %
    /show {
      userdict begin
        \fillinitials \delfills \delcolors \addstrokes
        to_upstroke {} {dup false gsave charpath do_stroke grestore} ifelse
        to_fill {dup gsave my_show grestore} {} ifelse
        to_upstroke {dup false gsave charpath do_stroke grestore} if
        false charpath current_point newpath moveto
      end
    } def
    %
    /setcmykcolor {
      userdict begin
        /k_ exch def /y_ exch def /m_ exch def /c_ exch def
        c_ m_ y_ k_ hax_setcmykcolor \changecolors
      end
    } def
    %
    currentcmykcolor setcmykcolor
  end}%
  \ifx\changebits\empty\else
    \BITinit 
    \special{ps:
      userdict begin
        /to_change_bitmap true def
        /changebits {\changebits} def
    end}%
  \fi
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\cyan    {1 0 0 0}
\def\magenta {0 1 0 0}
\def\yellow  {0 0 1 0}
\def\black   {0 0 0 1}
\def\white   {0 0 0 0}
%
\def\ScreenFrequency {150}
\def\Cangle {15}
\def\Mangle {75}
\def\Yangle {0}
\def\Kangle {45}
%
\def\PSscreen #1{\ifx\ScreenFrequency\empty
  \special{ps: currentscreen exch pop #1 exch setscreen}%
  \else
  \special{ps:
  /dot_spot {dup mul exch dup mul add 1 exch sub 2 div} def
  \ScreenFrequency\space #1 {dot_spot} setscreen
  }\fi}
%
\newif\ifdelblack \delblackfalse
\newif\ifbitmapsep \bitmapseptrue
%
\def\sepbitmaptrue{%
  \bitmapseptrue
  \BITinit
  \special{ps:
    userdict begin
     /to_sep_bitmap true def
    end}}
%
\def\sepbitmapfalse{%
  \bitmapsepfalse
  \special{ps:
    userdict begin
     /to_sep_bitmap false def
    end}}
%
\def\convertbitmaptrue{%
  \BITinit
  \special{ps:
    userdict begin
     /to_convert_bitmap true def
    end}}
%
\def\convertbitmapfalse{%
  \special{ps:
    userdict begin
     /to_convert_bitmap false def
    end}}
%
\def\BITinit{\special{ps:
  userdict begin
  /image /hax_image load def
  /colorimage /hax_colorimage load def
  /imagemask /hax_imagemask load def
  end}}
%
\def\projectCMYK #1{%
  \edef\projectcolor{#1}%
  \ifx\projectcolor\cyan
    \special{ps:
      userdict begin
        /hax_sep 0 def
        /hax_setcmykcolor {\ifdelblack maybe_black \fi pop pop pop 1 exch sub ori_setgray} def
      end
    }%
    \PSscreen\Cangle
  \else \ifx\projectcolor\magenta
    \special{ps:
      userdict begin
        /hax_sep 1 def
        /hax_setcmykcolor {\ifdelblack maybe_black \fi pop pop exch pop 1 exch sub ori_setgray} def
      end
    }%
    \PSscreen\Mangle
  \else \ifx\projectcolor\yellow
    \special{ps:
      userdict begin
        /hax_sep 2 def
        /hax_setcmykcolor {\ifdelblack maybe_black \fi pop exch pop exch pop 1 exch sub ori_setgray} def
      end
    }%
    \PSscreen\Yangle
  \else \ifx\projectcolor\black
    \special{ps:
      userdict begin
        /hax_sep 3 def
        /hax_setcmykcolor {exch pop exch pop exch pop 1 exch sub ori_setgray} def
      end
    }%
    \PSscreen\Kangle
  \fi \fi \fi \fi
  \ifbitmapsep\sepbitmaptrue\fi
  \special{ps: currentcmykcolor setcmykcolor}%
}
%
\def\CMYKlabels #1{{#1% #1 is a font csname
  \Cyan{CYAN}
  \Magenta{MAGENTA}
  \Yellow{YELLOW}
  \Black{BLACK}}}
%
\ifx\notCMYKinit\undefined\CMYKinit\fi
%
\catcode`\/\slashcatcode
%
\endinput