Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
%    Copyright (C) 1990, 2000 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_lev2.ps,v 1.38 2005/10/04 17:51:52 ray Exp $
17
% Initialization file for Level 2 functions.
18
% When this is run, systemdict is still writable,
19
% but (almost) everything defined here goes into level2dict.
20
 
21
level2dict begin
22
 
23
% ------ System and user parameters ------ %
24
 
25
% User parameters must obey save/restore, and must also be maintained
26
% per-context.  We implement the former, and some of the latter, here
27
% with PostScript code.  NOTE: our implementation assumes that user
28
% parameters change only as a result of setuserparams -- that there are
29
% no user parameters that are ever changed dynamically by the interpreter
30
% (although the interpreter may adjust the value presented to setuserparams)
31
%
32
% There are two types of user parameters: those which are actually
33
% maintained in the interpreter, and those which exist only at the
34
% PostScript level.  We maintain the current state of both types in
35
% a read-only local dictionary named userparams, defined in systemdict.
36
% In a multi-context system, each context has its own copy of this
37
% dictionary.  In addition, there is a constant dictionary named
38
% psuserparams where each key is the name of a user parameter that exists
39
% only in PostScript and the value is a procedure to check that the value
40
% is legal: setuserparams uses this for checking the values.
41
% setuserparams updates userparams explicitly, in addition to setting
42
% any user parameters in the interpreter; thus we can use userparams
43
% to reset those parameters after a restore or a context switch.
44
% NOTE: the name userparams is known to the interpreter, and in fact
45
% the interpreter creates the userparams dictionary.
46
 
47
% Check parameters that are managed at the PostScript level.
48
/.checkparamtype {		% <newvalue> <type> .checkparamtype <bool>
49
  exch type eq
50
} .bind def
51
/.checksetparams {		% <newdict> <opname> <checkdict>
52
				%   .checksetparams <newdict>
53
  2 index {
54
		% Stack: newdict opname checkdict key newvalue
55
    3 copy 3 1 roll .knownget {
56
      exec not {
57
	pop pop pop load /typecheck signalerror
58
      } if
59
      dup type /stringtype eq {
60
	dup rcheck not {
61
	  pop pop pop load /invalidaccess signalerror
62
	} if
63
      } if
64
    } {
65
      pop
66
    } ifelse pop pop
67
  } forall pop pop
68
} .bind def	% not odef, shouldn't reset stacks
69
 
70
% currentuser/systemparams creates and returns a dictionary in the
71
% current VM.  The easiest way to make this work is to copy any composite
72
% PostScript-level parameters to global VM.  Currently we have strings
73
% as well as arrays. For arrays, we also need to copy any contents that
74
% are in VM. Also copying string parameters insures the contents won't
75
% be changed. Also be careful to preserve 'executable' state.
76
/.copyparam {			% <value> .copyparam <value'>
77
  dup type /arraytype eq {
78
    .currentglobal true .setglobal exch 
79
    dup wcheck exch dup xcheck exch		% original attributes
80
    dup length array exch dup {	% stack: destination_array original_array original_array
81
      dup type /arraytype eq {
82
	dup 2 index ne {	% avoid recursion
83
          .copyparam	% recurse to handle composite array elements
84
        } {
85
	  % this array self referenced, do it again (yuk!)
86
	  pop 1 index		% get copy of destination array
87
	} ifelse
88
      } {
89
        dup type /stringtype eq {
90
	  .copyparam
91
        } if 
92
      }
93
      ifelse 3 1 roll		% keep arrays on top
94
    } forall pop astore
95
    exch { cvx } if		% set executable state
96
    exch not { readonly } if	% set readonly attribute as original
97
    exch .setglobal
98
  } if
99
  dup type /stringtype eq {
100
    dup wcheck exch	% save attr for setting readonly
101
    .currentglobal true .setglobal
102
    1 index length string exch .setglobal
103
    copy exch not { readonly } if
104
  } if
105
} .bind def
106
 
107
% Some user parameters are managed entirely at the PostScript level.
108
% We take care of that here.
109
systemdict begin
110
/psuserparams 48 dict def
111
/getuserparam {			% <name> getuserparam <value>
112
  /userparams .systemvar 1 index get exch pop
113
} odef
114
% Fill in userparams (created by the interpreter) with current values.
115
mark .currentuserparams
116
counttomark 2 idiv {
117
  userparams 3 1 roll put
118
} repeat pop
119
/.definepsuserparam {		% <name> <value> .definepsuserparam -
120
  psuserparams 3 copy pop
121
  type cvlit /.checkparamtype cvx 2 packedarray cvx put
122
  userparams 3 1 roll put
123
} .bind def
124
end
125
/currentuserparams {		% - currentuserparams <dict>
126
  /userparams .systemvar dup length dict .copydict
127
} odef
128
/setuserparams {		% <dict> setuserparams -
129
	% Check that we will be able to set the PostScript-level
130
	% user parameters.
131
  /setuserparams /psuserparams .systemvar .checksetparams
132
	% Set the C-level user params.  If this succeeds, we know that
133
	% the password check succeeded.
134
  dup .setuserparams
135
	% Now set the PostScript-level params.
136
	% The interpreter may have adjusted the values of some of the
137
	% parameters, so we have to read them back.
138
  dup {
139
    /userparams .systemvar 2 index known {
140
      psuserparams 2 index known not {
141
	pop dup .getuserparam
142
      } if
143
      .copyparam
144
      % special protection for the security related parameters
145
      [ /PermitFileReading /PermitFileWriting /PermitFileControl ]
146
      { 2 index eq { % force all strings to readonly but make sure the
147
		     % array is in the correct VM space (local/global).
148
	currentglobal exch dup gcheck setglobal
149
	dup length array exch { readonly exch } forall astore
150
	exch setglobal
151
        } if
152
      } forall
153
      % protect top level of parameters that we copied
154
      dup type dup /arraytype eq exch /stringtype eq or { readonly } if
155
      /userparams .systemvar 3 1 roll .forceput  % userparams is read-only
156
    } {
157
      pop pop
158
    } ifelse
159
  } forall
160
	% A context switch might have occurred during the above loop,
161
	% causing the interpreter-level parameters to be reset.
162
	% Set them again to the new values.  From here on, we are safe,
163
	% since a context switch will consult userparams.
164
  .setuserparams
165
} .bind odef
166
% Initialize user parameters managed here.
167
/JobName () .definepsuserparam
168
 
169
% Restore must restore the user parameters.
170
% (Since userparams is in local VM, save takes care of saving them.)
171
/restore {		% <save> restore -
172
  //restore /userparams .systemvar .setuserparams
173
} .bind odef
174
 
175
% The pssystemparams dictionary holds some system parameters that
176
% are managed entirely at the PostScript level.
177
systemdict begin
178
currentdict /pssystemparams known not {
179
  /pssystemparams 40 dict readonly def
180
} if
181
/getsystemparam {		% <name> getsystemparam <value>
182
  //pssystemparams 1 index .knownget { exch pop } { .getsystemparam } ifelse
183
} odef
184
end
185
/currentsystemparams {		% - currentsystemparams <dict>
186
  mark .currentsystemparams //pssystemparams { } forall .dicttomark
187
} odef
188
/setsystemparams {		% <dict> setsystemparams -
189
	% Check that we will be able to set the PostScript-level
190
	% system parameters.
191
   /SAFETY .systemvar /safe get {
192
     % SAFER mode disallows some changes
193
     [ /GenericResourceDir /FontResourceDir /GenericResourcePathSep ] {
194
       2 copy .knownget {
195
	 exch //pssystemparams exch .knownget {
196
           ne { /setsystemparams /invalidaccess signalerror } if
197
         } {
198
           pop
199
         } ifelse
200
       } {
201
         pop
202
       } ifelse
203
     } forall
204
   } if
205
   /setsystemparams //pssystemparams mark exch {
206
     type cvlit /.checkparamtype cvx 2 packedarray cvx
207
   } forall .dicttomark .checksetparams
208
	% Set the C-level system params.  If this succeeds, we know that
209
	% the password check succeeded.
210
   dup .setsystemparams
211
	% Now set the PostScript-level params.  We must copy local strings
212
	% into global VM.
213
   dup
214
    { //pssystemparams 2 index known
215
       {		% Stack: key newvalue
216
	 .copyparam
217
	 % protect top level parameters that we copied
218
         dup type dup /arraytype eq exch /stringtype eq or { readonly } if
219
	 //pssystemparams 3 1 roll .forceput	% pssystemparams is read-only
220
       }
221
       { pop pop
222
       }
223
      ifelse
224
    }
225
   forall pop
226
} .bind odef
227
 
228
% Initialize the passwords.
229
% NOTE: the names StartJobPassword and SystemParamsPassword are known to
230
% the interpreter, and must be bound to noaccess strings.
231
% The length of these strings must be max_password (iutil2.h) + 1.
232
/StartJobPassword 65 string noaccess def
233
/SystemParamsPassword 65 string noaccess def
234
 
235
% Redefine cache parameter setting to interact properly with userparams.
236
/setcachelimit {
237
  mark /MaxFontItem 2 index .dicttomark setuserparams pop
238
} .bind odef
239
/setcacheparams {
240
	% The MaxFontCache parameter is a system parameter, which we might
241
	% not be able to set.  Fortunately, this doesn't matter, because
242
	% system parameters don't have to be synchronized between this code
243
	% and the VM.
244
  counttomark 1 add copy setcacheparams
245
  currentcacheparams	% mark size lower upper
246
    3 -1 roll pop
247
    /MinFontCompress 3 1 roll
248
    /MaxFontItem exch
249
  .dicttomark setuserparams
250
  cleartomark
251
} .bind odef
252
 
253
% Add bogus user and system parameters to satisfy badly written PostScript
254
% programs that incorrectly assume the existence of all the parameters
255
% listed in Appendix C of the Red Book.  Note that some of these may become
256
% real parameters later: code near the end of gs_init.ps takes care of
257
% removing any such parameters from ps{user,system}params.
258
 
259
% psuserparams
260
  /MaxFormItem 100000 .definepsuserparam
261
  /MaxPatternItem 20000 .definepsuserparam
262
  /MaxScreenItem 48000 .definepsuserparam
263
  /MaxUPathItem 5000 .definepsuserparam
264
 
265
% File Access Permission parameters
266
  .currentglobal true .setglobal
267
  /.checkFilePermitparams {
268
    type /arraytype eq {
269
      currentuserparams /LockFilePermissions get {
270
        5 { pop } repeat /setuserparams /invalidaccess signalerror
271
      }{
272
        % in addition to validating the value, ensure the value is read/only
273
        dup { readonly exch } forall
274
        .currentglobal exch dup gcheck .setglobal length array exch .setglobal
275
	astore readonly
276
      }
277
      ifelse
278
    } {
279
      5 { pop } repeat /setuserparams /typecheck signalerror
280
    }
281
    ifelse
282
    true
283
  } .bind def
284
% Initialize the File Permission access control to wide open
285
% These will only be accessed via current/set userparams.
286
% Values are a string containing multiple nul terminated path strings
287
  /PermitFileReading dup [ (*) ] .definepsuserparam
288
    psuserparams exch /.checkFilePermitparams load put
289
  /PermitFileWriting dup [ (*) ] .definepsuserparam
290
    psuserparams exch /.checkFilePermitparams load put
291
  /PermitFileControl dup [ (*) ] .definepsuserparam
292
    psuserparams exch /.checkFilePermitparams load put
293
  .setglobal
294
 
295
pssystemparams begin
296
  /CurDisplayList 0 .forcedef
297
  /CurFormCache 0 .forcedef
298
  /CurOutlineCache 0 .forcedef
299
  /CurPatternCache 0 .forcedef
300
  /CurUPathCache 0 .forcedef
301
  /CurScreenStorage 0 .forcedef
302
  /CurSourceList 0 .forcedef
303
  /DoPrintErrors false .forcedef
304
  /MaxDisplayList 140000 .forcedef
305
  /MaxFormCache 100000 .forcedef
306
  /MaxOutlineCache 65000 .forcedef
307
  /MaxPatternCache 100000 .forcedef
308
  /MaxUPathCache 300000 .forcedef
309
  /MaxScreenStorage 84000 .forcedef
310
  /MaxSourceList 25000 .forcedef
311
  /RamSize 4194304 .forcedef
312
end
313
 
314
% Define the procedures for handling comment scanning.  The names
315
% %ProcessComment and %ProcessDSCComment are known to the interpreter.
316
% These procedures take the file and comment string and file as operands.
317
/.checkprocesscomment {
318
  dup null eq {
319
    pop true
320
  } {
321
    dup xcheck {
322
      type dup /arraytype eq exch /packedarraytype eq or
323
    } {
324
      pop false
325
    } ifelse
326
  } ifelse
327
} .bind def
328
/ProcessComment null .definepsuserparam
329
psuserparams /ProcessComment {.checkprocesscomment} put
330
(%ProcessComment) cvn {
331
  /ProcessComment getuserparam
332
  dup null eq { pop pop pop } { exec } ifelse
333
} bind def
334
/ProcessDSCComment null .definepsuserparam
335
psuserparams /ProcessDSCComment {.checkprocesscomment} put
336
/.loadingfont false def
337
(%ProcessDSCComment) cvn {
338
  /ProcessDSCComment getuserparam
339
  dup null eq .loadingfont or { pop pop pop } { exec } ifelse
340
} bind def
341
 
342
% ------ Miscellaneous ------ %
343
 
344
(<<) cvn			% - << -mark-
345
  /mark load def
346
(>>) cvn			% -mark- <key1> <value1> ... >> <dict>
347
  /.dicttomark load def
348
/languagelevel 2 def
349
% When running in Level 2 mode, this interpreter is supposed to be
350
% compatible with Adobe version 2017.
351
/version (2017) readonly def
352
 
353
% If binary tokens are supported by this interpreter,
354
% set an appropriate default binary object format.
355
/setobjectformat where
356
 { pop
357
   /RealFormat getsystemparam (IEEE) eq { 1 } { 3 } ifelse
358
   /ByteOrder getsystemparam { 1 add } if
359
   setobjectformat
360
 } if
361
 
362
% Aldus Freehand versions 2.x check for the presence of the
363
% setcolor operator, and if it is missing, substitute a procedure.
364
% Unfortunately, the procedure takes different parameters from
365
% the operator.  As a result, files produced by this application
366
% cause an error if the setcolor operator is actually defined
367
% and 'bind' is ever used.  Aldus fixed this bug in Freehand 3.0,
368
% but there are a lot of files created by the older versions
369
% still floating around.  Therefore, at Adobe's suggestion,
370
% we implement the following dreadful hack in the 'where' operator:
371
%      If the key is /setcolor, and
372
%        there is a dictionary named FreeHandDict, and
373
%        currentdict is that dictionary,
374
%      then "where" consults only that dictionary and not any other
375
%        dictionaries on the dictionary stack.
376
.wheredict /setcolor {
377
  /FreeHandDict .where {
378
    /FreeHandDict get currentdict eq {
379
      pop currentdict /setcolor known { currentdict true } { false } ifelse
380
    } {
381
      .where
382
    } ifelse
383
  } {
384
    .where
385
  } ifelse
386
} bind put
387
 
388
% ------ Virtual memory ------ %
389
 
390
/currentglobal			% - currentglobal <bool>
391
  /currentshared load def
392
/gcheck				% <obj> gcheck <bool>
393
  /scheck load def
394
/setglobal			% <bool> setglobal -
395
  /setshared load def
396
% We can make the global dictionaries very small, because they auto-expand.
397
/globaldict currentdict /shareddict .knownget not { 4 dict } if def
398
/GlobalFontDirectory SharedFontDirectory def
399
 
400
% VMReclaim and VMThreshold are user parameters.
401
/setvmthreshold {		% <int> setvmthreshold -
402
  mark /VMThreshold 2 index .dicttomark setuserparams pop
403
} odef
404
/vmreclaim {			% <int> vmreclaim -
405
  dup 0 gt {
406
    .vmreclaim
407
  } {
408
    mark /VMReclaim 2 index .dicttomark setuserparams pop
409
  } ifelse
410
} odef
411
-1 setvmthreshold
412
 
413
% ------ IODevices ------ %
414
 
415
/.getdevparams where {
416
  pop /currentdevparams {	% <iodevice> currentdevparams <dict>
417
    .getdevparams .dicttomark
418
  } odef
419
} if
420
/.putdevparams where {
421
  pop /setdevparams {		% <iodevice> <dict> setdevparams -
422
    mark 1 index { } forall counttomark 2 add index
423
    .putdevparams pop pop
424
  } odef
425
} if
426
 
427
% ------ Job control ------ %
428
 
429
serverdict begin
430
 
431
% We could protect the job information better, but we aren't attempting
432
% (currently) to protect ourselves against maliciousness.
433
 
434
/.jobsave null def		% top-level save object
435
/.jobsavelevel 0 def		% save depth of job (0 if .jobsave is null,
436
				% 1 otherwise)
437
/.adminjob true def		% status of current unencapsulated job
438
 
439
end		% serverdict
440
 
441
% Because there may be objects on the e-stack created since the job save,
442
% we have to clear the e-stack before doing the end-of-job restore.
443
% We do this by executing a 2 .stop, which is caught by the 2 .stopped
444
% in .runexec; we leave on the o-stack a procedure to execute aftewards.
445
%
446
%**************** The definition of startjob is not complete yet, since
447
% it doesn't reset stdin/stdout.
448
/.startnewjob {			% <exit_bool> <password_level>
449
				%   .startnewjob -
450
    serverdict /.jobsave get dup null eq { pop } { restore } ifelse
451
    exch {
452
			% Unencapsulated job
453
      serverdict /.jobsave null put
454
      serverdict /.jobsavelevel 0 put
455
      serverdict /.adminjob 3 -1 roll 1 gt put
456
		% The Adobe documentation doesn't say what happens to the
457
		% graphics state stack in this case, but an experiment
458
		% produced results suggesting that a grestoreall occurs.
459
      grestoreall
460
    } {
461
			% Encapsulated job
462
      pop
463
      serverdict /.jobsave save put
464
      serverdict /.jobsavelevel 1 put
465
      .userdict /quit /stop load put
466
    } ifelse
467
		% Reset the interpreter state.
468
  clear cleardictstack
469
  initgraphics
470
  false setglobal
471
  2 vmreclaim	% Make sure GC'ed memory is reclaimed and freed.
472
} bind def
473
/.startjob {			% <exit_bool> <password> <finish_proc>
474
				%   .startjob <ok_bool>
475
  vmstatus pop pop serverdict /.jobsavelevel get eq
476
  2 index .checkpassword 0 gt and {
477
    exch .checkpassword exch count 3 roll count 3 sub { pop } repeat
478
    cleardictstack
479
		% Reset the e-stack back to the 2 .stopped in .runexec,
480
		% passing the finish_proc to be executed afterwards.
481
    2 .stop
482
  } {		% Password check failed
483
    pop pop pop false
484
  } ifelse
485
} odef
486
/startjob {			% <exit_bool> <password> startjob <ok_bool>
487
	% This is a hack.  We really need some way to indicate explicitly
488
	% to the interpreter that we are under control of a job server.
489
  { .startnewjob true } .startjob
490
} odef
491
 
492
% The procedure to undo the job encapsulation 
493
/.endjob {
494
  clear cleardictstack
495
  serverdict /.jobsave get dup null eq { pop } { restore } ifelse
496
  serverdict /.jobsave null put
497
  2 vmreclaim   % recover local and global VM
498
} odef
499
 
500
systemdict begin
501
/quit {				% - quit -
502
  //systemdict begin serverdict /.jobsave get null eq
503
   { end //quit }
504
   { /quit load /invalidaccess /signalerror load end exec }
505
  ifelse
506
} bind odef
507
end
508
 
509
% We would like to define exitserver as a procedure, using the code
510
% that the Red Book says is equivalent to it.  However, since startjob
511
% resets the exec stack, we can't do this, because control would never
512
% proceed past the call on startjob if the exitserver is successful.
513
% Instead, we need to construct exitserver out of pieces of startjob.
514
 
515
serverdict begin
516
 
517
/exitserver {			% <password> exitserver -
518
  true exch { .startnewjob } .startjob not {
519
    /exitserver /invalidaccess signalerror
520
  } if
521
} bind def
522
 
523
end		% serverdict
524
 
525
% ------ Compatibility ------ %
526
 
527
% In Level 2 mode, the following replace the definitions that gs_statd.ps
528
% installs in statusdict and serverdict.
529
% Note that statusdict must be allocated in local VM.
530
% We don't bother with many of these yet.
531
 
532
/.dict1 { exch mark 3 1 roll .dicttomark } bind def
533
 
534
currentglobal false setglobal 25 dict exch setglobal begin
535
currentsystemparams
536
 
537
% The following do not depend on the presence of setpagedevice.
538
/buildtime 1 index /BuildTime get def
539
% Also define /buildtime in systemdict because Adobe does so and some fonts use it as ID
540
systemdict /buildtime dup load put
541
/byteorder 1 index /ByteOrder get def
542
/checkpassword { .checkpassword 0 gt } bind def
543
dup /DoStartPage known
544
 { /dostartpage { /DoStartPage getsystemparam } bind def
545
   /setdostartpage { /DoStartPage .dict1 setsystemparams } bind def
546
 } if
547
dup /StartupMode known
548
 { /dosysstart { /StartupMode getsystemparam 0 ne } bind def
549
   /setdosysstart { { 1 } { 0 } ifelse /StartupMode .dict1 setsystemparams } bind def
550
 } if
551
%****** Setting jobname is supposed to set userparams.JobName, too.
552
/jobname { /JobName getuserparam } bind def
553
/jobtimeout { /JobTimeout getuserparam } bind def
554
/ramsize { /RamSize getsystemparam } bind def
555
/realformat 1 index /RealFormat get def
556
dup /PrinterName known
557
 { /setprintername { /PrinterName .dict1 setsystemparams } bind def
558
 } if
559
/printername
560
 { currentsystemparams /PrinterName .knownget not { () } if exch copy
561
 } bind def
562
currentuserparams /WaitTimeout known
563
 { /waittimeout { /WaitTimeout getuserparam } bind def
564
 } if
565
 
566
% The following do require setpagedevice.
567
/.setpagedevice where { pop } { (%END PAGEDEVICE) .skipeof } ifelse
568
/defaulttimeouts
569
 { currentsystemparams dup
570
   /JobTimeout .knownget not { 0 } if
571
   exch /WaitTimeout .knownget not { 0 } if
572
   currentpagedevice /ManualFeedTimeout .knownget not { 0 } if
573
 } bind def
574
/margins
575
 { currentpagedevice /Margins .knownget { exch } { [0 0] } ifelse
576
 } bind def
577
/pagemargin
578
 { currentpagedevice /PageOffset .knownget { 0 get } { 0 } ifelse
579
 } bind def
580
/pageparams
581
 { currentpagedevice
582
   dup /Orientation .knownget { 1 and ORIENT1 { 1 xor } if } { 0 } ifelse exch
583
   dup /PageSize get aload pop 3 index 0 ne { exch } if 3 2 roll
584
   /PageOffset .knownget { 0 get } { 0 } ifelse 4 -1 roll
585
 } bind def
586
/setdefaulttimeouts
587
 { exch mark /ManualFeedTimeout 3 -1 roll
588
   /Policies mark /ManualFeedTimeout 1 .dicttomark
589
   .dicttomark setpagedevice
590
   /WaitTimeout exch mark /JobTimeout 5 2 roll .dicttomark setsystemparams
591
 } bind def
592
/.setpagesize { 2 array astore /PageSize .dict1 setpagedevice } bind def
593
/setduplexmode { /Duplex .dict1 setpagedevice } bind def
594
/setmargins
595
 { exch 2 array astore /Margins .dict1 setpagedevice
596
 } bind def
597
/setpagemargin { 0 2 array astore /PageOffset .dict1 setpagedevice } bind def
598
/setpageparams
599
 { mark /PageSize 6 -2 roll
600
   4 index 1 and ORIENT1 { 1 } { 0 } ifelse ne { exch } if 2 array astore
601
   /Orientation 5 -1 roll ORIENT1 { 1 xor } if
602
   /PageOffset counttomark 2 add -1 roll 0 2 array astore
603
   .dicttomark setpagedevice
604
 } bind def
605
/setresolution
606
 { dup 2 array astore /HWResolution .dict1 setpagedevice
607
 } bind def
608
%END PAGEDEVICE
609
 
610
% The following are not implemented yet.
611
%manualfeed
612
%manualfeedtimeout
613
%pagecount
614
%pagestackorder
615
%setpagestackorder
616
 
617
pop		% currentsystemparams
618
 
619
% Flag the current dictionary so it will be swapped when we
620
% change language levels.  (See zmisc2.c for more information.)
621
/statusdict currentdict def
622
 
623
currentdict end
624
/statusdict exch .forcedef	% statusdict is local, systemdict is global
625
 
626
% The following compatibility operators are in systemdict.  They are
627
% defined here, rather than in gs_init.ps, because they require the
628
% resource machinery.
629
 
630
/devforall {		% <proc> <scratch> devforall -
631
  exch {
632
    1 index currentdevparams
633
    /Type .knownget { /FileSystem eq } { false } ifelse
634
    { exec } { pop pop } ifelse
635
  } /exec load 3 packedarray cvx exch
636
  (*) 3 1 roll /IODevice resourceforall
637
} odef
638
/devstatus {		% <(%disk*%)> devstatus <searchable> <writable>
639
			%   <hasNames> <mounted> <removable> <searchOrder>
640
			%   <freePages> <size> true
641
			% <string> devstatus false
642
  dup length 5 ge {
643
    dup 0 5 getinterval (%disk) eq {
644
      dup /IODevice resourcestatus {
645
	pop pop dup currentdevparams
646
	dup /Searchable get
647
	exch dup /Writeable get
648
	exch dup /HasNames get
649
	exch dup /Mounted get
650
	exch dup /Removable get
651
	exch dup /SearchOrder get
652
	exch dup /Free get
653
	exch /LogicalSize get
654
	9 -1 roll pop true
655
      } {
656
	pop false
657
      } ifelse
658
    } {
659
      pop false
660
    } ifelse
661
  } {
662
    pop false
663
  } ifelse
664
} odef
665
 
666
% ------ Color spaces ------ %
667
 
668
% Move setcolorsapce, setcolor, and colorspacedict to level2dict
669
level2dict /setcolorspace .cspace_util 1 index get put
670
level2dict /setcolor .cspace_util 1 index get put
671
level2dict /colorspacedict .cspace_util 1 index get put
672
 
673
% Add the level 2 color spaces
674
% DevicePixel is actually a LanguageLevel 3 feature; it is here for
675
% historical reasons.
676
%% Replace 1 (gs_devpxl.ps) 
677
(gs_devpxl.ps) runlibfile
678
 
679
%% Replace 1 (gs_ciecs2.ps)
680
(gs_ciecs2.ps) runlibfile
681
 
682
%% Replace 1 (gs_indxd.ps)
683
(gs_indxd.ps) runlibfile
684
 
685
%% Replace 1 (gs_sepr.ps)
686
(gs_sepr.ps) runlibfile
687
 
688
%% Replace 1 (gs_patrn.ps)
689
(gs_patrn.ps) runlibfile
690
 
691
 
692
 
693
% ------ CIE color rendering ------ %
694
 
695
% Define findcolorrendering and a default ColorRendering ProcSet.
696
 
697
/findcolorrendering {		% <intentname> findcolorrendering
698
				%   <crdname> <found>
699
  /ColorRendering /ProcSet findresource
700
  1 index .namestring (.) concatstrings
701
  1 index /GetPageDeviceName get exec .namestring (.) concatstrings
702
  2 index /GetHalftoneName get exec .namestring
703
  concatstrings concatstrings
704
  dup /ColorRendering resourcestatus {
705
    pop pop exch pop exch pop true
706
  } {
707
    pop /GetSubstituteCRD get exec false
708
  } ifelse
709
} odef
710
 
711
5 dict dup begin
712
 
713
/GetPageDeviceName {		% - GetPageDeviceName <name>
714
  currentpagedevice dup /PageDeviceName .knownget {
715
    exch pop dup null eq { pop /none } if
716
  } {
717
    pop /none
718
  } ifelse
719
} bind def
720
 
721
/GetHalftoneName {		% - GetHalftoneName <name>
722
  currenthalftone /HalftoneName .knownget not { /none } if
723
} bind def
724
 
725
/GetSubstituteCRD {		% <intentname> GetSubstituteCRD <crdname>
726
  pop /DefaultColorRendering
727
} bind def
728
 
729
end
730
% The resource machinery hasn't been activated, so just save the ProcSet
731
% and let .fixresources finish the installation process.
732
/ColorRendering exch def
733
 
734
% Define setcolorrendering.
735
 
736
/.colorrenderingtypes 5 dict def
737
 
738
/setcolorrendering {		% <crd> setcolorrendering -
739
  dup /ColorRenderingType get //.colorrenderingtypes exch get exec
740
} odef
741
 
742
/.setcolorrendering1 where { pop } { (%END CRD) .skipeof } ifelse
743
 
744
.colorrenderingtypes 1 {
745
  dup .buildcolorrendering1 .setcolorrendering1
746
} .bind put
747
 
748
% Note: the value 101 in the next line must be the same as the value of
749
% GX_DEVICE_CRD1_TYPE in gscrdp.h.
750
.colorrenderingtypes 101 {
751
  dup .builddevicecolorrendering1 .setdevicecolorrendering1
752
} .bind put
753
 
754
% sRGB output CRD, D65 white point
755
mark
756
/ColorRenderingType 1
757
/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ] readonly
758
 
759
% Bradford Cone Space
760
/MatrixPQR [ 0.8951 -0.7502  0.0389
761
	     0.2664  1.7135 -0.0685
762
	    -0.1614  0.0367  1.0296] readonly
763
 
764
/MatrixLMN [ 3.240449 -0.969265  0.055643
765
	    -1.537136  1.876011 -0.204026
766
	    -0.498531  0.041556  1.057229 ] readonly
767
 
768
% Inverse sRGB gamma transform
769
/EncodeABC [ { dup 0.00304 le
770
                { 12.92321 mul }
771
                { 1 2.4 div exp 1.055 mul 0.055 sub }
772
               ifelse
773
             } bind dup dup
774
           ] readonly
775
 
776
/WhitePoint [ 0.9505 1 1.0890 ] readonly % D65
777
/BlackPoint [ 0 0 0 ] readonly
778
 
779
% VonKries-like transform in Bradford Cone Space
780
   /TransformPQR
781
     % The implementations have been moved to C for performance.
782
     [ { .TransformPQR_scale_WB0 } bind
783
       { .TransformPQR_scale_WB1 } bind 
784
       { .TransformPQR_scale_WB2 } bind
785
     ] readonly
786
.dicttomark setcolorrendering
787
 
788
%END CRD
789
 
790
% Initialize a CIEBased color space for sRGB.
791
/CIEsRGB [ /CIEBasedABC
792
  mark
793
    /DecodeLMN [ {
794
      dup 0.03928 le { 12.92321 div } { 0.055 add 1.055 div 2.4 exp } ifelse
795
    } bind dup dup ] readonly
796
    /MatrixLMN [
797
      0.412457 0.212673 0.019334
798
      0.357576 0.715152 0.119192
799
      0.180437 0.072175 0.950301
800
    ] readonly
801
    /WhitePoint [0.9505 1.0 1.0890] readonly
802
  .dicttomark readonly
803
] readonly def
804
 
805
% ------ Painting ------ %
806
 
807
% A straightforward definition of execform that doesn't actually
808
% do any caching.
809
/.execform1 {
810
	% This is a separate operator so that the stacks will be restored
811
	% properly if an error occurs.
812
  dup /Matrix get concat
813
  dup /BBox get aload pop
814
  exch 3 index sub exch 2 index sub rectclip
815
  dup /PaintProc get
816
  1 index /Implementation known not {
817
    1 index dup /Implementation null .forceput readonly pop
818
  } if
819
  exec
820
} .bind odef	% must bind .forceput
821
 
822
/.formtypes 5 dict
823
  dup 1 /.execform1 load put
824
def
825
 
826
/execform {			% <form> execform -
827
  gsave {
828
    dup /FormType get //.formtypes exch get exec
829
  } stopped grestore { stop } if
830
} odef
831
 
832
/.patterntypes 5 dict
833
  dup 1 /.buildpattern1 load put
834
def
835
 
836
/makepattern {			% <proto_dict> <matrix> makepattern <pattern>
837
  //.patterntypes 2 index /PatternType get get
838
  .currentglobal false .setglobal exch
839
		% Stack: proto matrix global buildproc
840
  3 index dup length 1 add dict .copydict
841
  3 index 3 -1 roll exec 3 -1 roll .setglobal
842
  1 index /Implementation 3 -1 roll put
843
  readonly exch pop exch pop
844
} odef
845
 
846
/setpattern {			% [<comp1> ...] <pattern> setpattern -
847
  currentcolorspace 0 get /Pattern ne {
848
    [ /Pattern currentcolorspace ] setcolorspace
849
  } if setcolor
850
} odef
851
 
852
% The following functions emulate the actions of findcmykcustomcolor and
853
% setcustomcolor.  These functions are described in Adobe's TN 5044.  That
854
% same document also says "The following “operators” are not defined in the
855
% PostScript Language Reference Manual, but should be used as pseudo-operators
856
% in your PostScript language output. Separation applications from Adobe
857
% Systems and other vendors will redefine these convention operators to
858
% separate your documents.  Your application should conditionally define
859
% procedures with these special names, as shown later in this document."
860
%
861
% We are providing these functions because we have found files created by
862
% "QuarkXPress: pictwpstops filter 1.0" which produce bad shading dictionaries
863
% if these operators are not defined. 
864
 
865
% Conditionally disable the TN 5044 psuedo-ops if NO_TN5044 specified
866
/NO_TN5044 where { pop (%END TN 5044 psuedo-ops) .skipeof } if
867
 
868
% TN 5044 does not define the contents of the array.  We are simply putting
869
% the values given into an array.  This is consistent with what we see when
870
% testing with Adobe Distiller 6.0.
871
%   <cyan> <magenta> <yellow> <black> <key> findcmykcustomcolor <array>
872
/findcmykcustomcolor { 5 array astore } bind def
873
 
874
% Build a tint transform function for use by setcustomcolor.  This function
875
% is for a Separation color space which has a DeviceCMYK base color space
876
% (i.e. 1 input and 4 outputs).  The input to buildcustomtinttransform is the
877
% array created by findcmykcustomcolor.  The resulting function is:
878
%   { dup cyan mul exch dup magenta mul exch dup yellow mul exch black mul }
879
%   Where cyan, magenta, yellow, and black are values from the array.
880
/buildcustomtinttransform	% <array> buildcustomtinttransform <function>
881
{ [ /dup load 2 index 0 get /mul load
882
  /exch load /dup load 6 index 1 get /mul load
883
  /exch load /dup load 10 index 2 get /mul load
884
  /exch load 13 index 3 get /mul load
885
  ] cvx bind
886
  exch pop			% Remove the input array
887
} bind def
888
 
889
% Set a custom color based upon a tint and array which describes the custom
890
% color.  See findcmykcustomcolor.  First we create and then set a Separation
891
% colorspace.  Then we set the specified color.
892
% Note that older Adobe ProcSets apparently allow for 'null' as the tint
893
% for some reason, so an alternate operational mode is tolerated:
894
% 					    null setcustomcolor -
895
/setcustomcolor			% <array> <tint> setcustomcolor -
896
{ dup //null ne {
897
    % Start building Separation colorspace
898
    [ /Separation 3 index 4 get	% Get separation name from array's key
899
    /DeviceCMYK
900
    5 index buildcustomtinttransform ]	% build the tint transform function
901
    setcolorspace			% Set the Separation color space as current
902
    setcolor			% Set the tint as the current color
903
    pop				% Remove the input array
904
  }
905
  { pop }	% 'null' as the tint is ignored
906
  ifelse
907
} bind def
908
 
909
% This proc is supposed to implement a version of overprinting. TN 5044 says
910
% that this proc is not used by any shipping host-based application. We have
911
% only found it being used in a proc set in files by Canvas from Deneba Systems.
912
% Even their proc set does not actually do any overprinting.  However their
913
% files crash if this is not defined.  Thus we have a copy of this proc but
914
% we are simply checking for inputs being -1 and if so then we set the value
915
% to 0.
916
/setcmykoverprint {
917
  4 { dup -1 eq { pop 0 } if 4 1 roll } repeat setcmykcolor
918
} bind def
919
 
920
%END TN 5044 psuedo-ops
921
 
922
end				% level2dict