Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
%    Copyright (C) 1994, 1996, 1997, 1998, 1999, 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_res.ps,v 1.38 2004/10/26 17:07:18 igor Exp $
17
% Initialization file for Level 2 resource machinery.
18
% When this is run, systemdict is still writable,
19
% but (almost) everything defined here goes into level2dict.
20
 
21
level2dict begin
22
 
23
(BEGIN RESOURCES) VMDEBUG
24
 
25
% We keep track of (global) instances with another entry in the resource
26
% dictionary, an .Instances dictionary.  For categories with implicit
27
% instances, the values in .Instances are the same as the keys;
28
% for other categories, the values are [instance status size].
29
 
30
% Note that the dictionary that defines a resource category is stored
31
% in global VM.  The PostScript manual says that each category must
32
% manage global and local instances separately.  However, objects in
33
% global VM other than systemdict can't reference objects in local VM.
34
% This means that the resource category dictionary, which would otherwise be
35
% the obvious place to keep track of the instances, can't be used to keep
36
% track of local instances.  Instead, we define a dictionary in local VM
37
% called localinstancedict, in which the key is the category name and
38
% the value is the analogue of .Instances for local instances.
39
 
40
% We don't currently implement automatic resource unloading.
41
% When and if we do, it should be hooked to the garbage collector.
42
% However, Ed Taft of Adobe says their interpreters don't implement this
43
% either, so we aren't going to worry about it for a while.
44
 
45
currentglobal false setglobal systemdict begin
46
  /localinstancedict 5 dict
47
  .forcedef	% localinstancedict is local, systemdict is global
48
end true setglobal
49
/.emptydict 0 dict readonly def
50
setglobal
51
 
52
% Resource category dictionaries have the following keys (those marked with
53
% * are optional):
54
%	Standard, defined in the Red Book:
55
%		Category (name)
56
%		*InstanceType (name)
57
%		DefineResource
58
%			<key> <instance> DefineResource <instance>
59
%		UndefineResource
60
%			<key> UndefineResource -
61
%		FindResource
62
%			<key> FindResource <instance>
63
%		ResourceStatus
64
%			<key> ResourceStatus <status> <size> true
65
%			<key> ResourceStatus false
66
%		ResourceForAll
67
%			<template> <proc> <scratch> ResourceForAll -
68
%		*ResourceFileName
69
%			<key> <scratch> ResourceFileName <filename>
70
%	Additional, specific to our implementation:
71
%		.Instances (dictionary)
72
%		.LocalInstances
73
%			- .LocalInstances <dict>
74
%		.GetInstance
75
%			<key> .GetInstance <instance> -true-
76
%			<key> .GetInstance -false-
77
%		.CheckResource
78
%			<key> <value> .CheckResource <key> <value> <ok>
79
%			  (or may give an error if not OK)
80
%		.DoLoadResource
81
%			<key> .DoLoadResource <key> (may give an error)
82
%		.LoadResource
83
%			<key> .LoadResource - (may give an error)
84
%		.ResourceFile
85
%			<key> .ResourceFile <file> -true-
86
%			<key> .ResourceFile <key> -false-
87
%		.ResourceFileStatus
88
%			<key> .ResourceFileStatus 2 <vmusage> -true-
89
%			<key> .ResourceFileStatus -false-
90
% All the above procedures expect that the top dictionary on the d-stack
91
% is the resource dictionary.
92
 
93
% Define enough of the Category category so we can define other categories.
94
% The dictionary we're about to create will become the Category
95
% category definition dictionary.
96
 
97
% .findcategory and .resourceexec are only called from within the
98
% implementation of the resource 'operators', so they doesn't have to worry
99
% about cleaning up the stack if they fail (the interpreter's stack
100
% protection machinery for pseudo-operators takes care of this).
101
/.findcategory {	% <name> .findcategory -
102
			%   (pushes the category on the dstack)
103
  /Category findresource begin
104
} bind def
105
 
106
/.resourceexec {	% <key> /xxxResource .resourceexec -
107
			%   (also pops the category from the dstack)
108
  load exec end
109
} bind def
110
 
111
% .getvminstance treats instances on disk as undefined.
112
/.getvminstance {	% <key> .getvminstance <instance> -true-
113
			% <key> .getvminstance -false-
114
  .GetInstance {
115
    dup 1 get 2 ne { true } { pop false } ifelse
116
  } {
117
    false
118
  } ifelse
119
} bind def
120
 
121
20 dict begin
122
 
123
		% Standard entries
124
 
125
/Category /Category def
126
/InstanceType /dicttype def
127
 
128
/DefineResource {
129
	.CheckResource {
130
	  dup /Category 3 index cvlit .growput
131
	  dup [ exch 0 -1 ] exch
132
	  .Instances 4 2 roll put
133
		% Make the Category dictionary read-only.  We will have to
134
		% use .forceput / .forcedef later to replace the dummy,
135
		% empty .Instances dictionary with the real one later.
136
	  readonly
137
	} {
138
	  /defineresource load /typecheck signalerror
139
	} ifelse
140
} bind def
141
/FindResource		% (redefined below)
142
	{ .Instances exch get 0 get
143
	} bind def
144
 
145
		% Additional entries
146
 
147
/.Instances 30 dict def
148
.Instances /Category [currentdict 0 -1] put
149
 
150
/.LocalInstances 0 dict def
151
/.GetInstance
152
	{ .Instances exch .knownget
153
	} bind def
154
/.CheckResource
155
	{ dup gcheck currentglobal and
156
	   { /DefineResource /FindResource /ResourceForAll /ResourceStatus
157
	     /UndefineResource }
158
	   { 2 index exch known and }
159
	  forall
160
	  not { /defineresource load /invalidaccess signalerror } if
161
	  true
162
	} bind def
163
 
164
.Instances end begin	% for the base case of findresource
165
 
166
(END CATEGORY) VMDEBUG
167
 
168
% Define the resource operators.  We use the "stack protection" feature of
169
% odef to make sure the stacks are restored properly on an error.
170
% This requires that the operators not pop anything from the stack until
171
% they have executed their logic successfully.  We can't make this
172
% work for resourceforall, because the procedure it executes mustn't see
173
% the operands of resourceforall on the stack, but we can make it work for
174
% the others.
175
 
176
% findresource is the only operator that needs to bind //Category.
177
/findresource {		% <key> <category> findresource <instance>
178
	2 copy dup /Category eq
179
	  { pop //Category 0 get begin } { .findcategory } ifelse
180
	/FindResource .resourceexec exch pop exch pop
181
} bind
182
end		% .Instances of Category
183
odef
184
 
185
/defineresource {	% <key> <instance> <category> defineresource <instance>
186
	3 copy .findcategory
187
	currentdict /InstanceType known {
188
	  dup type InstanceType ne {
189
	    dup type /packedarraytype eq InstanceType /arraytype eq and
190
	    not { /defineresource load /typecheck signalerror } if
191
	  } if
192
	} if
193
	/DefineResource .resourceexec
194
	4 1 roll pop pop pop
195
} bind odef
196
% We must prevent resourceforall from automatically restoring the stacks,
197
% because we don't want the stacks restored if proc causes an error or
198
% executes a 'stop'. On the other hand, resourceforall is defined in the
199
% PLRM as an operator, so it must have type /operatortype.  We hack this
200
% by taking advantage of the fact that the interpreter optimizes tail
201
% calls, so stack protection doesn't apply to the very last token of an
202
% operator procedure.
203
/resourceforall1 {	% <template> <proc> <scratch> <category> resourceforall1 -
204
	dup /Category findresource begin
205
	/ResourceForAll load
206
	% Stack: <template> <proc> <scratch> <category> proc
207
	exch pop		% pop the category
208
	exec end
209
} bind def
210
/resourceforall {	% <template> <proc> <scratch> <category> resourceforall1 -
211
	//resourceforall1 exec		% see above
212
} bind odef
213
/resourcestatus {	% <key> <category> resourcestatus <status> <size> true
214
			% <key> <category> resourcestatus false
215
	2 copy .findcategory /ResourceStatus .resourceexec
216
	 { 4 2 roll pop pop true } { pop pop false } ifelse
217
} bind odef
218
/undefineresource {	% <key> <category> undefineresource -
219
	2 copy .findcategory /UndefineResource .resourceexec pop pop
220
} bind odef
221
 
222
% Define the system parameters used for the Generic implementation of
223
% ResourceFileName.
224
systemdict begin
225
 
226
%     - .default_resource_dir <string>
227
/.default_resource_dir {
228
  .file_name_parent .file_name_directory_separator concatstrings
229
  (Resource) concatstrings
230
  /LIBPATH .systemvar {
231
    dup .file_name_current eq {
232
      pop
233
    } {
234
      1 index false .file_name_combine {
235
        exch pop exit
236
      } {
237
        pop pop
238
      } ifelse
239
    } ifelse
240
  } forall
241
} bind def
242
 
243
%  <path> <name> <string> .resource_dir_name <path> <name> <string>
244
/.resource_dir_name
245
{  systemdict 2 index .knownget {
246
     exch pop
247
     systemdict 1 index undef
248
   } {
249
     dup () ne {
250
     .file_name_directory_separator concatstrings
251
    } if
252
    2 index exch false .file_name_combine not {
253
      (Error: .default_resource_dir returned ) print exch print ( that can't combine with ) print =
254
      /.default_resource_dir /configurationerror .signalerror
255
    } if
256
  } ifelse
257
} bind def
258
 
259
currentdict /pssystemparams known not {
260
  /pssystemparams 10 dict readonly def
261
} if
262
pssystemparams begin
263
  .default_resource_dir
264
  /FontResourceDir (Font) .resource_dir_name
265
     readonly .forcedef	% pssys'params is r-o
266
  /GenericResourceDir () .resource_dir_name
267
     readonly .forcedef	% pssys'params is r-o
268
  pop % .default_resource_dir
269
  /GenericResourcePathSep
270
  	.file_name_separator readonly .forcedef		% pssys'params is r-o
271
  (%diskFontResourceDir) cvn (/Resource/Font/) readonly .forcedef	% pssys'params is r-o
272
  (%diskGenericResourceDir) cvn (/Resource/) readonly .forcedef	% pssys'params is r-o
273
end
274
end
275
 
276
% Check if GenericResourceDir presents in LIBPATH.
277
 
278
% The value of GenericResourceDir must end with directory separator.
279
% We use .file_name_combine to check it. 
280
% Comments use OpenVMS syntax, because it is the most complicated case.
281
(x) pssystemparams /GenericResourcePathSep get
282
(y) concatstrings concatstrings dup length              % (x]y) l1
283
pssystemparams /GenericResourceDir get dup length exch  % (x]y) l1 l2 (dir)
284
3 index true .file_name_combine not {
285
  exch
286
  (File name ) print print ( cant combine with ) print =
287
  /GenericResourceDir cvx /configurationerror signalerror
288
} if
289
dup length                                              % (x]y) l1 l2 (dir.x]y) l
290
4 2 roll add                                            % (x]y) (dir.x]y) l ll
291
ne {
292
  (GenericResourceDir value does not end with directory separator.\n) =
293
  /GenericResourceDir cvx /configurationerror signalerror
294
} if
295
pop pop
296
 
297
% Define the generic algorithm for computing resource file names.
298
/.rfnstring 8192 string def
299
/.genericrfn		% <key> <scratch> <prefix> .genericrfn <filename>
300
 { 3 -1 roll //.rfnstring cvs concatstrings exch copy
301
 } bind def
302
 
303
% Define a procedure for making a packed array in local VM.
304
/.localpackedarray {	% <obj1> ... <objn> <n> .localpackedarray <packedarray>
305
  .currentglobal false .setglobal 1 index 2 add 1 roll
306
  packedarray exch .setglobal
307
} bind def
308
 
309
% Define the Generic category.
310
 
311
/Generic mark
312
 
313
		% Standard entries
314
 
315
% We're still running in Level 1 mode, so dictionaries won't expand.
316
% Leave room for the /Category entry.
317
/Category null
318
 
319
% Implement the body of Generic resourceforall for local, global, and
320
% external cases.  'args' is [template proc scratch resdict].
321
/.enumerateresource {	% <key> [- <proc> <scratch>] .enumerateresource -
322
  1 index type dup /stringtype eq exch /nametype eq or {
323
    exch 1 index 2 get cvs exch
324
  } if
325
	% Use .setstackprotect to prevent the stacks from being restored if
326
	% an error occurs during execution of proc.
327
  1 get false .setstackprotect exec true .setstackprotect
328
} bind def
329
/.localresourceforall {		% <key> <value> <args> .localr'forall -
330
  exch pop
331
  2 copy 0 get .stringmatch { .enumerateresource } { pop pop } ifelse
332
} bind def
333
/.globalresourceforall {	% <key> <value> <args> .globalr'forall -
334
  exch pop
335
  2 copy 0 get .stringmatch {
336
    dup 3 get begin .LocalInstances end 2 index known not {
337
      .enumerateresource
338
    } {
339
      pop pop
340
    } ifelse
341
  } {
342
    pop pop
343
  } ifelse
344
} bind def
345
/.externalresourceforall {	% <filename> <len> <args> .externalr'forall -
346
  3 1 roll 1 index length 1 index sub getinterval exch
347
  dup 3 get begin .Instances .LocalInstances end
348
		% Stack: key args insts localinsts
349
  3 index known {
350
    pop pop pop
351
  } {
352
    2 index known { pop pop } { .enumerateresource } ifelse
353
  } ifelse
354
} bind def
355
 
356
/DefineResource {
357
	.CheckResource
358
	   { dup [ exch 0 -1 ]
359
			% Stack: key value instance
360
	     currentglobal
361
	      { false setglobal 2 index UndefineResource	% remove local def if any
362
		true setglobal
363
		.Instances dup //.emptydict eq {
364
		  pop 3 dict
365
			% As noted above, Category dictionaries are read-only,
366
			% so we have to use .forcedef here.
367
		  /.Instances 1 index .forcedef	% Category dict is read-only
368
		} if
369
	      }
370
	      { .LocalInstances dup //.emptydict eq
371
	         { pop 3 dict localinstancedict Category 2 index put
372
		 }
373
		if
374
	      }
375
	     ifelse
376
			% Stack: key value instance instancedict
377
	     3 index 2 index .growput
378
			% Now make the resource value read-only.
379
 
380
	     dup 4 1 roll put exch pop exch pop
381
	   }
382
	   { /defineresource load /typecheck signalerror
383
	   }
384
	ifelse
385
} .bind executeonly		% executeonly to prevent access to .forcedef
386
/UndefineResource
387
	{  { dup 2 index .knownget
388
	      { dup 1 get 1 ge
389
		 { dup 0 null put 1 2 put pop pop }
390
		 { pop exch .undef }
391
		ifelse
392
	      }
393
	      { pop pop
394
	      }
395
	     ifelse
396
	   }
397
	  currentglobal
398
	   { 2 copy .Instances exch exec
399
	   }
400
	  if .LocalInstances exch exec
401
	} bind
402
% Because of some badly designed code in Adobe's CID font downloader that
403
% makes findresource and resourcestatus deliberately inconsistent with each
404
% other, the default FindResource must not call ResourceStatus if there is
405
% an instance of the desired name already defined in VM.
406
/FindResource {
407
	dup .getvminstance {
408
	  exch pop 0 get
409
	} {
410
	  dup ResourceStatus {
411
	    pop 1 gt {
412
	      .DoLoadResource .getvminstance not {
413
		/findresource load /undefinedresource signalerror
414
	      } if 0 get
415
	    } {
416
	      .GetInstance pop 0 get
417
	    } ifelse
418
	  } {
419
	   /findresource load /undefinedresource signalerror
420
	  } ifelse
421
	} ifelse
422
} bind
423
% Because of some badly designed code in Adobe's CID font downloader, the
424
% definition of ResourceStatus for Generic and Font must be the same (!).
425
% We patch around this by using an intermediate .ResourceFileStatus procedure.
426
/ResourceStatus {
427
	dup .GetInstance {
428
	  exch pop dup 1 get exch 2 get true
429
	} {
430
	  .ResourceFileStatus
431
	} ifelse
432
} bind
433
/.ResourceFileStatus {
434
	.ResourceFile { closefile 2 -1 true } { pop false } ifelse
435
} bind
436
/ResourceForAll {
437
		% Construct a new procedure to hold the arguments.
438
		% All objects constructed here must be in local VM to avoid
439
		% a possible invalidaccess.
440
	currentdict 4 .localpackedarray	% [template proc scratch resdict]
441
		% We must pop the resource dictionary off the dict stack
442
		% when doing the actual iteration, and restore it afterwards.
443
	.currentglobal not {
444
	  .LocalInstances length 0 ne {
445
		% We must do local instances, and do them first.
446
	    //.localresourceforall {exec} 0 get 3 .localpackedarray cvx
447
	    .LocalInstances exch {forall} 0 get 1 index 0 get
448
	    currentdict end 3 .execn begin
449
	  } if
450
	} if
451
		% Do global instances next.
452
	//.globalresourceforall {exec} 0 get 3 .localpackedarray cvx
453
	.Instances exch cvx {forall} 0 get 1 index 0 get
454
	currentdict end 3 .execn begin
455
        mark                                             % args [
456
        Category .namestring .file_name_separator concatstrings
457
        2 index 0 get                                    % args [ (c/) (t)
458
        dup length 3 1 roll                              % args [ l (c/) (t)
459
        concatstrings                                    % args [ l (c/t)
460
	[ 
461
	  /LIBPATH .systemvar 2 index
462
	  .generate_dir_list_templates                   % args (t) [ l [(pt)]
463
	    % also add on the Resources as specified by the GenericResourceDir
464
          [ currentsystemparams /GenericResourceDir get]
465
	  counttomark 1 add index .generate_dir_list_templates
466
            % Resource files on OpenVMS requires a separate template (gs:[dir.*]*)
467
          [ currentsystemparams /GenericResourceDir get]
468
	  counttomark 1 add index .file_name_separator (*)
469
          concatstrings concatstrings .generate_dir_list_templates
470
	  ] exch pop
471
	{                                                % args [ l (pt)
472
	  dup length 2 index sub exch                    % args [ l Lp (pt)
473
 
474
	  {                                              % args [ l Lp (pf)
475
	    dup length                                   % args [ l Lp (pf) Lpf
476
	    2 index sub                                  % args [ l Lp (pf) Lf
477
	    2 index exch                                 % args [ l Lp (pf) Lp Lf
478
	    getinterval cvn dup                          % args [ l Lp /n /n
479
	    4 2 roll                                     % args [ /n /n l Lp
480
	  } //.rfnstring filenameforall
481
	  pop                                            % args [ l /n1 /n1 ... /nN /nN l
482
	} forall                                         % args [ l /n1 /n1 ... /nN /nN
483
	pop
484
	.dicttomark % An easy way to exclude duplicates. % args <</n/n>>
485
	  % {
486
	  { pop } 0 get
487
          2 index 2 get { cvs 0 } aload pop 5 index
488
          //.externalresourceforall {exec} 0 get
489
          % }
490
        7 .localpackedarray cvx
491
        3 2 roll pop % args
492
	{ forall } 0 get
493
  	currentdict end 2 .execn begin
494
} bind
495
/ResourceFileName
496
	  {                                             % /in (scr)
497
	    exch //.rfnstring cvs                       % (scr) (n)
498
            /GenericResourcePathSep getsystemparam exch % (scr) (/) (n)
499
            Category .namestring                        % (scr) (/) (n) (c)
500
            3 1 roll                                    % (scr) (c) (/) (n)
501
	    concatstrings concatstrings                 % (scr) (c/n)
502
            /GenericResourceDir getsystemparam .file_name_is_absolute not {
503
              /GenericResourceDir getsystemparam exch concatstrings
504
	      findlibfile
505
	      {                                         % (scr) (p/c/n) file
506
	        pop exch copy true                      % (p/c/n) true
507
	      } {                                       % (scr) (c/n)
508
	        false                                   % (scr) (c/n) false
509
	      } ifelse
510
	    } {                                         % (scr) (c/n)
511
	      false                                     % (scr) (c/n) false
512
	    } ifelse
513
	    not {                                       % (scr) (c/n)
514
              /GenericResourceDir getsystemparam        % (scr) (c/n) (d/)
515
              dup length exch                           % (scr) (c/n) Ld (d/)
516
              3 index copy pop                          % (scr') (c/n) Ld
517
              1 index length                            % (scr') (c/n) Ld Lcn
518
              3 index 3 copy pop                        % (scr') (c/n) Ld Lcn (scr') Ld Lcn
519
              getinterval                               % (scr') (c/n) Ld Lcn (scr[Ld:Lcn])
520
              4 3 roll exch                             % (scr') Ld Lcn (c/n) (scr[Ld:Lcn])
521
              copy pop                                  % (scr'') Ld Lcn
522
              add 0 exch getinterval                    % (scr''[0:Ld+Lcn])
523
	    } if
524
	  } bind
525
 
526
		% Additional entries
527
 
528
% Unfortunately, we can't create the real .Instances dictionary now,
529
% because if someone copies the Generic category (which pp. 95-96 of the
530
% 2nd Edition Red Book says is legitimate), they'll wind up sharing
531
% the .Instances.  Instead, we have to create .Instances on demand,
532
% just like the entry in localinstancedict.
533
% We also have to prevent anyone from creating instances of Generic itself.
534
/.Instances //.emptydict
535
 
536
/.LocalInstances
537
	{ localinstancedict Category .knownget not { //.emptydict } if
538
	} bind
539
/.GetInstance
540
	{ currentglobal
541
	   { .Instances exch .knownget }
542
	   { .LocalInstances 1 index .knownget
543
	      { exch pop true }
544
	      { .Instances exch .knownget }
545
	     ifelse
546
	   }
547
	  ifelse
548
	} bind
549
/.CheckResource
550
	{ true
551
	} bind
552
/.vmused {
553
		% - .vmused <usedvalue>
554
		% usedvalue = vmstatus in global + vmstatus in local.
555
 
556
    .currentglobal not .setglobal
557
    vmstatus pop exch pop add
558
  } repeat
559
} bind def
560
/.DoLoadResource {
561
		% .LoadResource may push entries on the operand stack.
562
		% It is an undocumented feature of Adobe implementations,
563
		% which we must match for the sake of some badly written
564
		% font downloading code, that such entries are popped
565
		% automatically.
566
	count 1 index cvlit .vmused
567
		% Stack: key count litkey memused
568
	{.LoadResource} 4 1 roll 4 .execn
569
		% Stack: ... count key memused
570
	.vmused exch sub
571
	1 index .getvminstance not {
572
	  pop dup /undefinedresource signalerror	% didn't load
573
	} if
574
	dup 1 1 put
575
	2 3 -1 roll put
576
		% Stack: ... count key
577
	exch count 1 sub exch sub {exch pop} repeat
578
} bind
579
/.LoadResource
580
	{ dup .ResourceFile
581
	   { exch pop currentglobal
582
	      { .runresource }
583
	      { true setglobal { .runresource } stopped false setglobal { stop } if }
584
	     ifelse
585
	   }
586
	   { dup /undefinedresource signalerror
587
	   }
588
	 ifelse
589
	} bind
590
/.ResourceFile
591
        {
592
          Category //.rfnstring cvs length                      % key l
593
          dup //.rfnstring dup length 2 index sub               % key l l (buf) L-l
594
          3 2 roll exch getinterval                             % key l ()
595
          .file_name_directory_separator exch copy length add   % key l1
596
          dup //.rfnstring dup length 2 index sub               % key l1 l1 (buf) L-l
597
          3 2 roll exch getinterval                             % key l1 ()
598
          2 index exch cvs length add                           % key l2
599
          //.rfnstring exch 0 exch getinterval                  % key (relative_path)
600
          .libfile {
601
            exch pop true
602
          } {
603
            pop
604
            currentdict /ResourceFileName known {
605
	      mark 1 index //.rfnstring { ResourceFileName } .internalstopped {
606
	        cleartomark false
607
	      } {
608
	        dup status {
609
	          pop pop pop pop
610
	          (r) file
611
	          exch pop exch pop true
612
	        } {
613
	          cleartomark false
614
	        } ifelse
615
	      } ifelse
616
	     } {
617
	       pop false
618
	     } ifelse
619
          } ifelse
620
	} bind
621
 
622
 
623
 
624
.dicttomark
625
/Category defineresource pop
626
 
627
% Fill in the rest of the Category category.
628
/Category /Category findresource dup
629
/Generic /Category findresource begin {
630
  /FindResource /ResourceForAll /ResourceStatus /.ResourceFileStatus
631
  /UndefineResource /ResourceFileName
632
  /.ResourceFile /.LoadResource /.DoLoadResource
633
} { dup load put dup } forall
634
pop readonly pop end
635
 
636
(END GENERIC) VMDEBUG
637
 
638
% Define the fixed categories.
639
 
640
mark
641
	% Non-Type categories with existing entries.
642
 /ColorSpaceFamily
643
   { }	% These must be deferred, because optional features may add some.
644
 /Emulator
645
   mark EMULATORS { cvn } forall .packtomark
646
 /Filter
647
   { }	% These must be deferred, because optional features may add some.
648
 /IODevice
649
	% Loop until the .getiodevice gets a rangecheck.
650
   errordict /rangecheck 2 copy get
651
   errordict /rangecheck { pop stop } put	% pop the command
652
   mark 0 { {
653
    dup .getiodevice dup null eq { pop } { exch } ifelse 1 add
654
   } loop} .internalstopped
655
   pop pop pop .packtomark
656
   4 1 roll put
657
   .clearerror
658
	% Type categories listed in the Red Book.
659
 /ColorRenderingType
660
   { }	% These must be deferred, because optional features may add some.
661
 /FMapType
662
   { }	% These must be deferred, because optional features may add some.
663
 /FontType
664
   { }	% These must be deferred, because optional features may add some.
665
 /FormType
666
   { }	% These must be deferred, because optional features may add some.
667
 /HalftoneType
668
   { }	% These must be deferred, because optional features may add some.
669
 /ImageType
670
   { }	% Deferred, optional features may add some.
671
 /PatternType
672
   { }  % Deferred, optional features may add some.
673
	% Type categories added since the Red Book.
674
 /setsmoothness where {
675
   pop /ShadingType { }	% Deferred, optional features may add some.
676
 } if
677
counttomark 2 idiv
678
 { mark
679
 
680
		% Standard entries
681
 
682
		% We'd like to prohibit defineresource,
683
		% but because optional features may add entries, we can't.
684
		% We can at least require that the key and value match.
685
   /DefineResource
686
	{ currentglobal not
687
	   { /defineresource load /invalidaccess signalerror }
688
	   { 2 copy ne
689
	      { /defineresource load /rangecheck signalerror }
690
	      { dup .Instances 4 -2 roll .growput }
691
	     ifelse
692
	   }
693
	  ifelse
694
	} bind
695
   /UndefineResource
696
	{ /undefineresource load /invalidaccess signalerror } bind
697
   /FindResource
698
	{ .Instances 1 index .knownget
699
	   { exch pop }
700
	   { /findresource load /undefinedresource signalerror }
701
	  ifelse
702
	} bind
703
   /ResourceStatus
704
	{ .Instances exch known { 0 0 true } { false } ifelse } bind
705
   /ResourceForAll
706
	/Generic /Category findresource /ResourceForAll get
707
 
708
		% Additional entries
709
 
710
   counttomark 2 add -1 roll
711
   dup length dict dup begin exch { dup def } forall end
712
		% We'd like to make the .Instances readonly here,
713
		% but because optional features may add entries, we can't.
714
   /.Instances exch
715
   /.LocalInstances	% used by ResourceForAll
716
 
717
 
718
   .dicttomark /Category defineresource pop
719
 } repeat pop
720
 
721
(END FIXED) VMDEBUG
722
 
723
% Define the other built-in categories.
724
 
725
/.definecategory	% <name> -mark- <key1> ... <valuen> .definecategory -
726
 { counttomark 2 idiv 2 add		% .Instances, Category
727
   /Generic /Category findresource dup maxlength 3 -1 roll add
728
   dict .copydict begin
729
   counttomark 2 idiv { def } repeat pop	% pop the mark
730
   currentdict end /Category defineresource pop
731
 } bind def
732
 
733
/ColorRendering mark /InstanceType /dicttype .definecategory
734
% ColorSpace is defined below
735
% Encoding is defined below
736
% Font is defined below
737
/Form mark /InstanceType /dicttype .definecategory
738
/Halftone mark /InstanceType /dicttype .definecategory
739
/Pattern mark /InstanceType /dicttype .definecategory
740
/ProcSet mark /InstanceType /dicttype .definecategory
741
% Added since the Red Book:
742
/ControlLanguage mark /InstanceType /dicttype .definecategory
743
/HWOptions mark /InstanceType /dicttype .definecategory
744
/Localization mark /InstanceType /dicttype .definecategory
745
/OutputDevice mark /InstanceType /dicttype .definecategory
746
/PDL mark /InstanceType /dicttype .definecategory
747
% CIDFont, CIDMap, and CMap are defined in gs_cidfn.ps
748
% FontSet is defined in gs_cff.ps
749
% IdiomSet is defined in gs_ll3.ps
750
% InkParams and TrapParams are defined in gs_trap.ps
751
 
752
(END MISC) VMDEBUG
753
 
754
% Define the ColorSpace category.
755
 
756
/.defaultcsnames mark
757
  /DefaultGray 0
758
  /DefaultRGB 1
759
  /DefaultCMYK 2
760
.dicttomark readonly def
761
 
762
% The "hooks" are no-ops here, redefined in LL3.
763
/.definedefaultcs {	% <index> <value> .definedefaultcs -
764
  pop pop
765
} bind def
766
/.undefinedefaultcs {	% <index> .undefinedefaultcs -
767
  pop
768
} bind def
769
 
770
/ColorSpace mark
771
 
772
/InstanceType /arraytype
773
 
774
% We keep track of whether there are any local definitions for any of
775
% the Default keys.  This information must get saved and restored in
776
% parallel with the local instance dictionary, so it must be stored in
777
% local VM.
778
userdict /.localcsdefaults false put
779
 
780
/DefineResource {
781
  2 copy /Generic /Category findresource /DefineResource get exec
782
  exch pop
783
  exch //.defaultcsnames exch .knownget {
784
    1 index .definedefaultcs
785
    currentglobal not { .userdict /.localcsdefaults true put } if
786
  } if
787
} bind
788
 
789
/UndefineResource {
790
  dup /Generic /Category findresource /UndefineResource get exec
791
  //.defaultcsnames 1 index .knownget {
792
	% Stack: resname index
793
    currentglobal {
794
      .undefinedefaultcs pop
795
    } {
796
	% We removed the local definition, but there might be a global one.
797
      exch .GetInstance {
798
 
799
      } {
800
	.undefinedefaultcs
801
      } ifelse
802
	% Recompute .localcsdefaults by scanning.  This is rarely needed.
803
      .userdict /.localcsdefaults false //.defaultcsnames {
804
	pop .LocalInstances exch known { pop true exit } if
805
      } forall put
806
    } ifelse
807
  } {
808
    pop
809
  } ifelse
810
} bind
811
 
812
.definecategory			% ColorSpace
813
 
814
% Define the Encoding category.
815
 
816
/Encoding mark
817
 
818
/InstanceType /arraytype
819
 
820
% Handle already-registered encodings, including lazily loaded encodings
821
% that aren't loaded yet.
822
 
823
/.Instances mark
824
  EncodingDirectory
825
   { dup length 256 eq { [ exch readonly 0 -1 ] } { pop [null 2 -1] } ifelse
826
   } forall
827
.dicttomark
828
 
829
/.ResourceFileDict mark
830
  EncodingDirectory
831
   { dup length 256 eq { pop pop } { 0 get } ifelse
832
   } forall
833
.dicttomark
834
 
835
/ResourceFileName
836
 { .ResourceFileDict 2 index .knownget
837
    { exch copy exch pop }
838
    { /Generic /Category findresource /ResourceFileName get exec }
839
   ifelse
840
 } bind
841
 
842
.definecategory			% Encoding
843
 
844
% Make placeholders in level2dict for the redefined Encoding operators,
845
% so that they will be swapped properly when we switch language levels.
846
 
847
/.findencoding /.findencoding load def
848
/findencoding /findencoding load def
849
/.defineencoding /.defineencoding load def
850
 
851
(END ENCODING) VMDEBUG
852
 
853
% Define the Font category.
854
 
855
/.fontstatus {		% <fontname> .fontstatus <fontname> <found>
856
  {		% Create a loop context just so we can exit it early.
857
		% Check Fontmap.
858
    Fontmap 1 index .knownget {
859
      {
860
	dup type /nametype eq {
861
	  .fontstatus { pop null exit } if
862
	} {
863
	  dup type /stringtype eq {
864
	    findlibfile { closefile pop null exit } if pop
865
	  } {
866
		% Procedure, assume success.
867
	    pop null exit
868
	  } ifelse
869
	} ifelse
870
      } forall dup null eq { pop true exit } if
871
    } if
872
		% Convert names to strings; give up on other types.
873
    dup type /nametype eq { .namestring } if
874
    dup type /stringtype ne { false exit } if
875
		% Check the resource directory.
876
    dup .fonttempstring /FontResourceDir getsystemparam .genericrfn
877
    status {
878
      pop pop pop pop true exit
879
    } if
880
		% Check for a file on the search path with the same name
881
		% as the font.
882
    findlibfile { closefile true exit } if
883
		% Scan a FONTPATH directory and try again.
884
    .scannextfontdir not { false exit } if
885
  } loop
886
} bind def
887
 
888
/Font mark
889
 
890
/InstanceType /dicttype
891
 
892
/DefineResource
893
	{ 2 copy //definefont exch pop
894
	  /Generic /Category findresource /DefineResource get exec
895
	} bind
896
/UndefineResource
897
	{ dup //undefinefont
898
	  /Generic /Category findresource /UndefineResource get exec
899
	} bind
900
/FindResource {
901
	dup .getvminstance {
902
	  exch pop 0 get
903
	} {
904
	  dup ResourceStatus {
905
	    pop 1 gt { .loadfontresource } { .GetInstance pop 0 get } ifelse
906
	  } {
907
	    .loadfontresource
908
	  } ifelse
909
	} ifelse
910
} bind
911
/ResourceForAll {
912
	{ .scannextfontdir not { exit } if } loop
913
	/Generic /Category findresource /ResourceForAll get exec
914
} bind
915
/.ResourceFileStatus {
916
	.fontstatus { pop 2 -1 true } { pop false } ifelse
917
} bind
918
 
919
/.loadfontresource {
920
	dup vmstatus pop exch pop exch
921
		% Hack: rebind .currentresourcefile so that all calls of
922
		% definefont will know these are built-in fonts.
923
	currentfile {pop //findfont exec} .execasresource  % (findfont is a procedure)
924
	exch vmstatus pop exch pop exch sub
925
		% stack: name font vmused
926
		% findfont has the prerogative of not calling definefont
927
		% in certain obscure cases of font substitution.
928
	2 index .getvminstance {
929
	  dup 1 1 put
930
	  2 3 -1 roll put
931
	} {
932
	  pop
933
	} ifelse exch pop
934
} bind
935
 
936
/.Instances FontDirectory length 2 mul dict
937
 
938
.definecategory			% Font
939
 
940
% Redefine font "operators".
941
/.definefontmap
942
 { /Font /Category findresource /.Instances get
943
   dup 3 index known
944
    { pop
945
    }
946
    { 2 index
947
		% Make sure we create the array in global VM.
948
      .currentglobal true .setglobal
949
      [null 2 -1] exch .setglobal
950
      .growput
951
    }
952
   ifelse
953
   //.definefontmap exec
954
 } bind def
955
 
956
% Make sure the old definitions are still in systemdict so that
957
% they will get bound properly.
958
systemdict begin
959
  /.origdefinefont /definefont load def
960
  /.origundefinefont /undefinefont load def
961
  /.origfindfont /findfont load def
962
end
963
/definefont {
964
  /Font defineresource
965
} bind odef
966
/undefinefont {
967
  /Font undefineresource
968
} bind odef
969
% The Red Book requires that findfont be a procedure, not an operator,
970
% but it still needs to restore the stacks reliably if it fails.
971
/.findfontop {
972
  /Font findresource
973
} bind odef
974
/findfont {
975
  .findfontop
976
} bind def	% Must be a procedure, not an operator
977
 
978
% Remove initialization utilities.
979
currentdict /.definecategory .undef
980
currentdict /.emptydict .undef
981
 
982
end				% level2dict
983
 
984
% Convert deferred resources after we finally switch to Level 2.
985
 
986
/.fixresources {
987
	% Encoding resources
988
  EncodingDirectory
989
   { dup length 256 eq
990
      { /Encoding defineresource pop }
991
      { pop pop }
992
     ifelse
993
   } forall
994
  /.findencoding { /Encoding findresource } bind def
995
  /findencoding /.findencoding load def		% must be a procedure
996
  /.defineencoding { /Encoding defineresource pop } bind def
997
	% ColorRendering resources and ProcSet
998
  systemdict /ColorRendering .knownget {
999
    /ColorRendering exch /ProcSet defineresource pop
1000
    systemdict /ColorRendering undef
1001
    /DefaultColorRendering currentcolorrendering /ColorRendering defineresource pop
1002
  } if
1003
	% ColorSpace resources
1004
  systemdict /CIEsRGB .knownget {
1005
    /sRGB exch /ColorSpace defineresource pop
1006
    systemdict /CIEsRGB undef
1007
  } if
1008
	% ColorSpaceFamily resources
1009
  colorspacedict { pop dup /ColorSpaceFamily defineresource pop } forall
1010
	% Filter resources
1011
  filterdict { pop dup /Filter defineresource pop } forall
1012
	% FontType and FMapType resources
1013
  buildfontdict { pop dup /FontType defineresource pop } forall
1014
  mark
1015
    buildfontdict 0 known { 2 3 4 5 6 7 8 } if
1016
    buildfontdict 9 known { 9 } if
1017
  counttomark { dup /FMapType defineresource pop } repeat pop
1018
	% FormType resources
1019
  .formtypes { pop dup /FormType defineresource pop } forall
1020
	% HalftoneType resources
1021
  .halftonetypes { pop dup /HalftoneType defineresource pop } forall
1022
	% ColorRenderingType resources
1023
  .colorrenderingtypes {pop dup /ColorRenderingType defineresource pop} forall
1024
	% ImageType resources
1025
  .imagetypes { pop dup /ImageType defineresource pop } forall
1026
	% PatternType resources
1027
  .patterntypes { pop dup /PatternType defineresource pop } forall
1028
	% Make the fixed resource categories immutable.
1029
  /.shadingtypes where {
1030
    pop .shadingtypes { pop dup /ShadingType defineresource pop } forall
1031
  } if
1032
  [ /ColorSpaceFamily /Emulator /Filter /IODevice /ColorRenderingType
1033
    /FMapType /FontType /FormType /HalftoneType /ImageType /PatternType
1034
    /.shadingtypes where { pop /ShadingType } if
1035
  ] {
1036
    /Category findresource
1037
    dup /.Instances get readonly pop
1038
    .LocalInstances readonly pop
1039
    readonly pop
1040
  } forall
1041
	% clean up
1042
  systemdict /.fixresources undef
1043
} bind def
1044
 
1045
%% Replace 1 (gs_resmp.ps)
1046
(gs_resmp.ps)  dup runlibfile VMDEBUG
1047
%% Replace 1 (gs_resst.ps)
1048
(gs_resst.ps)  dup runlibfile VMDEBUG