]> git.lizzy.rs Git - plan9front.git/blob - sys/lib/ghostscript/gs_res.ps
etherbcm: handle 64-bit host addresses, use PCIWADDR() instead of PADDR()
[plan9front.git] / sys / lib / ghostscript / gs_res.ps
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              0 2 copy get { readonly } .internalstopped pop
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   0 2 {
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         0 dict def
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         0 get .definedefaultcs
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