home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 April / PCWorld_2001-04_cd.bin / Software / Vyzkuste / gs / gs650w32.exe / gs6.50 / lib / gs_lev2.ps < prev    next >
Text File  |  2000-12-05  |  28KB  |  843 lines

  1. %    Copyright (C) 1990, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of AFPL Ghostscript.
  3. % AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  4. % distributor accepts any responsibility for the consequences of using it, or
  5. % for whether it serves any particular purpose or works at all, unless he or
  6. % she says so in writing.  Refer to the Aladdin Free Public License (the
  7. % "License") for full details.
  8. % Every copy of AFPL Ghostscript must include a copy of the License, normally
  9. % in a plain ASCII text file named PUBLIC.  The License grants you the right
  10. % to copy, modify and redistribute AFPL Ghostscript, but only under certain
  11. % conditions described in the License.  Among other things, the License
  12. % requires that the copyright notice and this notice be preserved on all
  13. % copies.
  14.  
  15. % $Id: gs_lev2.ps,v 1.6 2000/09/19 18:29:11 lpd Exp $
  16. % Initialization file for Level 2 functions.
  17. % When this is run, systemdict is still writable,
  18. % but (almost) everything defined here goes into level2dict.
  19.  
  20. level2dict begin
  21.  
  22. % ------ System and user parameters ------ %
  23.  
  24. % User parameters must obey save/restore, and must also be maintained
  25. % per-context.  We implement the former, and some of the latter, here
  26. % with PostScript code.  NOTE: our implementation assumes that user
  27. % parameters change only as a result of setuserparams -- that there are
  28. % no user parameters that are ever changed dynamically by the interpreter
  29. % (although the interpreter may adjust the value presented to setuserparams)
  30. %
  31. % There are two types of user parameters: those which are actually
  32. % maintained in the interpreter, and those which exist only at the
  33. % PostScript level.  We maintain the current state of both types in
  34. % a read-only local dictionary named userparams, defined in systemdict.
  35. % In a multi-context system, each context has its own copy of this
  36. % dictionary.  In addition, there is a constant dictionary named
  37. % psuserparams where each key is the name of a user parameter that exists
  38. % only in PostScript and the value is a procedure to check that the value
  39. % is legal: setuserparams uses this for checking the values.
  40. % setuserparams updates userparams explicitly, in addition to setting
  41. % any user parameters in the interpreter; thus we can use userparams
  42. % to reset those parameters after a restore or a context switch.
  43. % NOTE: the name userparams is known to the interpreter, and in fact
  44. % the interpreter creates the userparams dictionary.
  45.  
  46. % Check parameters that are managed at the PostScript level.
  47. /.checkparamtype {        % <newvalue> <type> .checkparamtype <bool>
  48.   exch type eq
  49. } .bind def
  50. /.checksetparams {        % <newdict> <opname> <checkdict>
  51.                 %   .checksetparams <newdict>
  52.   2 index {
  53.         % Stack: newdict opname checkdict key newvalue
  54.     3 copy 3 1 roll .knownget {
  55.       exec not {
  56.     pop pop pop load /typecheck signalerror
  57.       } if
  58.       dup type /stringtype eq {
  59.     dup rcheck not {
  60.       pop pop pop load /invalidaccess signalerror
  61.     } if
  62.       } if
  63.     } {
  64.       pop
  65.     } ifelse pop pop
  66.   } forall pop pop
  67. } .bind def    % not odef, shouldn't reset stacks
  68.  
  69. % currentuser/systemparams creates and returns a dictionary in the
  70. % current VM.  The easiest way to make this work is to copy any composite
  71. % PostScript-level parameters to global VM.  Currently, the only such
  72. % parameters are strings.  In fact, we always copy string parameters,
  73. % so that we can be sure the contents won't be changed.
  74. /.copyparam {            % <value> .copyparam <value'>
  75.   dup type /stringtype eq {
  76.     .currentglobal true .setglobal
  77.     1 index length string exch .setglobal
  78.     copy readonly
  79.   } if
  80. } .bind def
  81.  
  82. % Some user parameters are managed entirely at the PostScript level.
  83. % We take care of that here.
  84. systemdict begin
  85. /psuserparams 40 dict def
  86. /getuserparam {            % <name> getuserparam <value>
  87.   /userparams .systemvar 1 index get exch pop
  88. } odef
  89. % Fill in userparams (created by the interpreter) with current values.
  90. mark .currentuserparams
  91. counttomark 2 idiv {
  92.   userparams 3 1 roll put
  93. } repeat pop
  94. /.definepsuserparam {        % <name> <value> .definepsuserparam -
  95.   psuserparams 3 copy pop
  96.   type cvlit /.checkparamtype cvx 2 packedarray cvx put
  97.   userparams 3 1 roll put
  98. } .bind def
  99. end
  100. /currentuserparams {        % - currentuserparams <dict>
  101.   /userparams .systemvar dup length dict .copydict
  102. } odef
  103. /setuserparams {        % <dict> setuserparams -
  104.     % Check that we will be able to set the PostScript-level
  105.     % user parameters.
  106.   /setuserparams /psuserparams .systemvar .checksetparams
  107.     % Set the C-level user params.  If this succeeds, we know that
  108.     % the password check succeeded.
  109.   dup .setuserparams
  110.     % Now set the PostScript-level params.
  111.     % The interpreter may have adjusted the values of some of the
  112.     % parameters, so we have to read them back.
  113.   dup {
  114.     /userparams .systemvar 2 index known {
  115.       psuserparams 2 index known not {
  116.     pop dup .getuserparam
  117.       } if
  118.       .copyparam
  119.       /userparams .systemvar 3 1 roll .forceput  % userparams is read-only
  120.     } {
  121.       pop pop
  122.     } ifelse
  123.   } forall
  124.     % A context switch might have occurred during the above loop,
  125.     % causing the interpreter-level parameters to be reset.
  126.     % Set them again to the new values.  From here on, we are safe,
  127.     % since a context switch will consult userparams.
  128.   .setuserparams
  129. } .bind odef
  130. % Initialize user parameters managed here.
  131. /JobName () .definepsuserparam
  132.  
  133. % Restore must restore the user parameters.
  134. % (Since userparams is in local VM, save takes care of saving them.)
  135. /restore {        % <save> restore -
  136.   //restore /userparams .systemvar .setuserparams
  137. } .bind odef
  138.  
  139. % The pssystemparams dictionary holds some system parameters that
  140. % are managed entirely at the PostScript level.
  141. systemdict begin
  142. currentdict /pssystemparams known not {
  143.   /pssystemparams 40 dict readonly def
  144. } if
  145. /getsystemparam {        % <name> getsystemparam <value>
  146.   //pssystemparams 1 index .knownget { exch pop } { .getsystemparam } ifelse
  147. } odef
  148. end
  149. /currentsystemparams {        % - currentsystemparams <dict>
  150.   mark .currentsystemparams //pssystemparams { } forall .dicttomark
  151. } odef
  152. /setsystemparams {        % <dict> setsystemparams -
  153.     % Check that we will be able to set the PostScript-level
  154.     % system parameters.
  155.    /setsystemparams //pssystemparams mark exch {
  156.      type cvlit /.checkparamtype cvx 2 packedarray cvx
  157.    } forall .dicttomark .checksetparams
  158.     % Set the C-level system params.  If this succeeds, we know that
  159.     % the password check succeeded.
  160.    dup .setsystemparams
  161.     % Now set the PostScript-level params.  We must copy local strings
  162.     % into global VM.
  163.    dup
  164.     { //pssystemparams 2 index known
  165.        {        % Stack: key newvalue
  166.      .copyparam
  167.      //pssystemparams 3 1 roll .forceput    % pssystemparams is read-only
  168.        }
  169.        { pop pop
  170.        }
  171.       ifelse
  172.     }
  173.    forall pop
  174. } .bind odef
  175.  
  176. % Initialize the passwords.
  177. % NOTE: the names StartJobPassword and SystemParamsPassword are known to
  178. % the interpreter, and must be bound to noaccess strings.
  179. % The length of these strings must be max_password (iutil2.h) + 1.
  180. /StartJobPassword 65 string noaccess def
  181. /SystemParamsPassword 65 string noaccess def
  182.  
  183. % Redefine cache parameter setting to interact properly with userparams.
  184. /setcachelimit {
  185.   mark /MaxFontItem 2 index .dicttomark setuserparams pop
  186. } .bind odef
  187. /setcacheparams {
  188.     % The MaxFontCache parameter is a system parameter, which we might
  189.     % not be able to set.  Fortunately, this doesn't matter, because
  190.     % system parameters don't have to be synchronized between this code
  191.     % and the VM.
  192.   counttomark 1 add copy setcacheparams
  193.   currentcacheparams    % mark size lower upper
  194.     3 -1 roll pop
  195.     /MinFontCompress 3 1 roll
  196.     /MaxFontItem exch
  197.   .dicttomark setuserparams
  198.   cleartomark
  199. } .bind odef
  200.  
  201. % Add bogus user and system parameters to satisfy badly written PostScript
  202. % programs that incorrectly assume the existence of all the parameters
  203. % listed in Appendix C of the Red Book.  Note that some of these may become
  204. % real parameters later: code near the end of gs_init.ps takes care of
  205. % removing any such parameters from ps{user,system}params.
  206.  
  207. % psuserparams
  208.   /MaxFormItem 100000 .definepsuserparam
  209.   /MaxPatternItem 20000 .definepsuserparam
  210.   /MaxScreenItem 48000 .definepsuserparam
  211.   /MaxUPathItem 5000 .definepsuserparam
  212.  
  213. pssystemparams begin
  214.   /CurDisplayList 0 .forcedef
  215.   /CurFormCache 0 .forcedef
  216.   /CurOutlineCache 0 .forcedef
  217.   /CurPatternCache 0 .forcedef
  218.   /CurUPathCache 0 .forcedef
  219.   /CurScreenStorage 0 .forcedef
  220.   /CurSourceList 0 .forcedef
  221.   /DoPrintErrors false .forcedef
  222.   /MaxDisplayList 140000 .forcedef
  223.   /MaxFormCache 100000 .forcedef
  224.   /MaxOutlineCache 65000 .forcedef
  225.   /MaxPatternCache 100000 .forcedef
  226.   /MaxUPathCache 300000 .forcedef
  227.   /MaxScreenStorage 84000 .forcedef
  228.   /MaxSourceList 25000 .forcedef
  229.   /RamSize 4194304 .forcedef
  230. end
  231.  
  232. % Define the procedures for handling comment scanning.  The names
  233. % %ProcessComment and %ProcessDSCComment are known to the interpreter.
  234. % These procedures take the file and comment string and file as operands.
  235. /.checkprocesscomment {
  236.   dup null eq {
  237.     pop true
  238.   } {
  239.     dup xcheck {
  240.       type dup /arraytype eq exch /packedarraytype eq or
  241.     } {
  242.       pop false
  243.     } ifelse
  244.   } ifelse
  245. } .bind def
  246. /ProcessComment null .definepsuserparam
  247. psuserparams /ProcessComment {.checkprocesscomment} put
  248. (%ProcessComment) cvn {
  249.   /ProcessComment getuserparam
  250.   dup null eq { pop pop pop } { exec } ifelse
  251. } bind def
  252. /ProcessDSCComment null .definepsuserparam
  253. psuserparams /ProcessDSCComment {.checkprocesscomment} put
  254. (%ProcessDSCComment) cvn {
  255.   /ProcessDSCComment getuserparam
  256.   dup null eq { pop pop pop } { exec } ifelse
  257. } bind def
  258.  
  259. % ------ Miscellaneous ------ %
  260.  
  261. (<<) cvn            % - << -mark-
  262.   /mark load def
  263. (>>) cvn            % -mark- <key1> <value1> ... >> <dict>
  264.   /.dicttomark load def
  265. /languagelevel 2 def
  266. % When running in Level 2 mode, this interpreter is supposed to be
  267. % compatible with Adobe version 2017.
  268. /version (2017) readonly def
  269.  
  270. % If binary tokens are supported by this interpreter,
  271. % set an appropriate default binary object format.
  272. /setobjectformat where
  273.  { pop
  274.    /RealFormat getsystemparam (IEEE) eq { 1 } { 3 } ifelse
  275.    /ByteOrder getsystemparam { 1 add } if
  276.    setobjectformat
  277.  } if
  278.  
  279. % Aldus Freehand versions 2.x check for the presence of the
  280. % setcolor operator, and if it is missing, substitute a procedure.
  281. % Unfortunately, the procedure takes different parameters from
  282. % the operator.  As a result, files produced by this application
  283. % cause an error if the setcolor operator is actually defined
  284. % and 'bind' is ever used.  Aldus fixed this bug in Freehand 3.0,
  285. % but there are a lot of files created by the older versions
  286. % still floating around.  Therefore, at Adobe's suggestion,
  287. % we implement the following dreadful hack in the 'where' operator:
  288. %      If the key is /setcolor, and
  289. %        there is a dictionary named FreeHandDict, and
  290. %        currentdict is that dictionary,
  291. %      then "where" consults only that dictionary and not any other
  292. %        dictionaries on the dictionary stack.
  293. .wheredict /setcolor {
  294.   /FreeHandDict .where {
  295.     /FreeHandDict get currentdict eq {
  296.       pop currentdict /setcolor known { currentdict true } { false } ifelse
  297.     } {
  298.       .where
  299.     } ifelse
  300.   } {
  301.     .where
  302.   } ifelse
  303. } bind put
  304.  
  305. % ------ Virtual memory ------ %
  306.  
  307. /currentglobal            % - currentglobal <bool>
  308.   /currentshared load def
  309. /gcheck                % <obj> gcheck <bool>
  310.   /scheck load def
  311. /setglobal            % <bool> setglobal -
  312.   /setshared load def
  313. % We can make the global dictionaries very small, because they auto-expand.
  314. /globaldict currentdict /shareddict .knownget not { 4 dict } if def
  315. /GlobalFontDirectory SharedFontDirectory def
  316.  
  317. % VMReclaim and VMThreshold are user parameters.
  318. /setvmthreshold {        % <int> setvmthreshold -
  319.   mark /VMThreshold 2 index .dicttomark setuserparams pop
  320. } odef
  321. /vmreclaim {            % <int> vmreclaim -
  322.   dup 0 gt {
  323.     .vmreclaim
  324.   } {
  325.     mark /VMReclaim 2 index .dicttomark setuserparams pop
  326.   } ifelse
  327. } odef
  328. -1 setvmthreshold
  329.  
  330. % ------ IODevices ------ %
  331.  
  332. /.getdevparams where {
  333.   pop /currentdevparams {    % <iodevice> currentdevparams <dict>
  334.     .getdevparams .dicttomark
  335.   } odef
  336. } if
  337. /.putdevparams where {
  338.   pop /setdevparams {        % <iodevice> <dict> setdevparams -
  339.     mark 1 index { } forall counttomark 2 add index
  340.     .putdevparams pop pop
  341.   } odef
  342. } if
  343.  
  344. % ------ Job control ------ %
  345.  
  346. serverdict begin
  347.  
  348. % We could protect the job information better, but we aren't attempting
  349. % (currently) to protect ourselves against maliciousness.
  350.  
  351. /.jobsave null def        % top-level save object
  352. /.jobsavelevel 0 def        % save depth of job (0 if .jobsave is null,
  353.                 % 1 otherwise)
  354. /.adminjob true def        % status of current unencapsulated job
  355.  
  356. end        % serverdict
  357.  
  358. % Because there may be objects on the e-stack created since the job save,
  359. % we have to clear the e-stack before doing the end-of-job restore.
  360. % We do this by executing a 2 .stop, which is caught by the 2 .stopped
  361. % in .runexec; we leave on the o-stack a procedure to execute aftewards.
  362. %
  363. %**************** The definition of startjob is not complete yet, since
  364. % it doesn't reset stdin/stdout.
  365. /.startnewjob {            % <exit_bool> <password_level>
  366.                 %   .startnewjob -
  367.     serverdict /.jobsave get dup null eq { pop } { restore } ifelse
  368.     exch {
  369.             % Unencapsulated job
  370.       serverdict /.jobsave null put
  371.       serverdict /.jobsavelevel 0 put
  372.       serverdict /.adminjob 3 -1 roll 1 gt put
  373.         % The Adobe documentation doesn't say what happens to the
  374.         % graphics state stack in this case, but an experiment
  375.         % produced results suggesting that a grestoreall occurs.
  376.       grestoreall
  377.     } {
  378.             % Encapsulated job
  379.       pop
  380.       serverdict /.jobsave save put
  381.       serverdict /.jobsavelevel 1 put
  382.     } ifelse
  383.         % Reset the interpreter state.
  384.   clear cleardictstack
  385.   initgraphics
  386.   false setglobal
  387. } bind def
  388. /.startjob {            % <exit_bool> <password> <finish_proc>
  389.                 %   .startjob <ok_bool>
  390.   vmstatus pop pop serverdict /.jobsavelevel get eq
  391.   2 index .checkpassword 0 gt and {
  392.     exch .checkpassword exch count 3 roll count 3 sub { pop } repeat
  393.     cleardictstack
  394.         % Reset the e-stack back to the 2 .stopped in .runexec,
  395.         % passing the finish_proc to be executed afterwards.
  396.     2 .stop
  397.   } {        % Password check failed
  398.     pop pop pop false
  399.   } ifelse
  400. } odef
  401. /startjob {            % <exit_bool> <password> startjob <ok_bool>
  402.     % This is a hack.  We really need some way to indicate explicitly
  403.     % to the interpreter that we are under control of a job server.
  404.   .userdict /quit /stop load put
  405.   { .startnewjob true } .startjob
  406. } odef
  407.  
  408. systemdict begin
  409. /quit {                % - quit -
  410.   //systemdict begin serverdict /.jobsave get null eq
  411.    { end //quit }
  412.    { /quit load /invalidaccess /signalerror load end exec }
  413.   ifelse
  414. } bind odef
  415. end
  416.  
  417. % We would like to define exitserver as a procedure, using the code
  418. % that the Red Book says is equivalent to it.  However, since startjob
  419. % resets the exec stack, we can't do this, because control would never
  420. % proceed past the call on startjob if the exitserver is successful.
  421. % Instead, we need to construct exitserver out of pieces of startjob.
  422.  
  423. serverdict begin
  424.  
  425. /exitserver {            % <password> exitserver -
  426.   true exch { .startnewjob } .startjob not {
  427.     /exitserver /invalidaccess signalerror
  428.   } if
  429. } bind def
  430.  
  431. end        % serverdict
  432.  
  433. % ------ Compatibility ------ %
  434.  
  435. % In Level 2 mode, the following replace the definitions that gs_statd.ps
  436. % installs in statusdict and serverdict.
  437. % Note that statusdict must be allocated in local VM.
  438. % We don't bother with many of these yet.
  439.  
  440. /.dict1 { exch mark 3 1 roll .dicttomark } bind def
  441.  
  442. currentglobal false setglobal 25 dict exch setglobal begin
  443. currentsystemparams
  444.  
  445. % The following do not depend on the presence of setpagedevice.
  446. /buildtime 1 index /BuildTime get def
  447. /byteorder 1 index /ByteOrder get def
  448. /checkpassword { .checkpassword 0 gt } bind def
  449. dup /DoStartPage known
  450.  { /dostartpage { /DoStartPage getsystemparam } bind def
  451.    /setdostartpage { /DoStartPage .dict1 setsystemparams } bind def
  452.  } if
  453. dup /StartupMode known
  454.  { /dosysstart { /StartupMode getsystemparam 0 ne } bind def
  455.    /setdosysstart { { 1 } { 0 } ifelse /StartupMode .dict1 setsystemparams } bind def
  456.  } if
  457. %****** Setting jobname is supposed to set userparams.JobName, too.
  458. /jobname { /JobName getuserparam } bind def
  459. /jobtimeout { /JobTimeout getuserparam } bind def
  460. /ramsize { /RamSize getsystemparam } bind def
  461. /realformat 1 index /RealFormat get def
  462. dup /PrinterName known
  463.  { /setprintername { /PrinterName .dict1 setsystemparams } bind def
  464.  } if
  465. /printername
  466.  { currentsystemparams /PrinterName .knownget not { () } if exch copy
  467.  } bind def
  468. currentuserparams /WaitTimeout known
  469.  { /waittimeout { /WaitTimeout getuserparam } bind def
  470.  } if
  471.  
  472. % The following do require setpagedevice.
  473. /.setpagedevice where { pop } { (%END PAGEDEVICE) .skipeof } ifelse
  474. /defaulttimeouts
  475.  { currentsystemparams dup
  476.    /JobTimeout .knownget not { 0 } if
  477.    exch /WaitTimeout .knownget not { 0 } if
  478.    currentpagedevice /ManualFeedTimeout .knownget not { 0 } if
  479.  } bind def
  480. /margins
  481.  { currentpagedevice /Margins .knownget { exch } { [0 0] } ifelse
  482.  } bind def
  483. /pagemargin
  484.  { currentpagedevice /PageOffset .knownget { 0 get } { 0 } ifelse
  485.  } bind def
  486. /pageparams
  487.  { currentpagedevice
  488.    dup /Orientation .knownget { 1 and ORIENT1 { 1 xor } if } { 0 } ifelse exch
  489.    dup /PageSize get aload pop 3 index 0 ne { exch } if 3 2 roll
  490.    /PageOffset .knownget { 0 get } { 0 } ifelse 4 -1 roll
  491.  } bind def
  492. /setdefaulttimeouts
  493.  { exch mark /ManualFeedTimeout 3 -1 roll
  494.    /Policies mark /ManualFeedTimeout 1 .dicttomark
  495.    .dicttomark setpagedevice
  496.    /WaitTimeout exch mark /JobTimeout 5 2 roll .dicttomark setsystemparams
  497.  } bind def
  498. /.setpagesize { 2 array astore /PageSize .dict1 setpagedevice } bind def
  499. /setduplexmode { /Duplex .dict1 setpagedevice } bind def
  500. /setmargins
  501.  { exch 2 array astore /Margins .dict1 setpagedevice
  502.  } bind def
  503. /setpagemargin { 0 2 array astore /PageOffset .dict1 setpagedevice } bind def
  504. /setpageparams
  505.  { mark /PageSize 6 -2 roll
  506.    4 index 1 and ORIENT1 { 1 } { 0 } ifelse ne { exch } if 2 array astore
  507.    /Orientation 5 -1 roll ORIENT1 { 1 xor } if
  508.    /PageOffset counttomark 2 add -1 roll 0 2 array astore
  509.    .dicttomark setpagedevice
  510.  } bind def
  511. /setresolution
  512.  { dup 2 array astore /HWResolution .dict1 setpagedevice
  513.  } bind def
  514. %END PAGEDEVICE
  515.  
  516. % The following are not implemented yet.
  517. %manualfeed
  518. %manualfeedtimeout
  519. %pagecount
  520. %pagestackorder
  521. %setpagestackorder
  522.  
  523. pop        % currentsystemparams
  524.  
  525. % Flag the current dictionary so it will be swapped when we
  526. % change language levels.  (See zmisc2.c for more information.)
  527. /statusdict currentdict def
  528.  
  529. currentdict end
  530. /statusdict exch .forcedef    % statusdict is local, systemdict is global
  531.  
  532. % The following compatibility operators are in systemdict.  They are
  533. % defined here, rather than in gs_init.ps, because they require the
  534. % resource machinery.
  535.  
  536. /devforall {        % <pattern> <proc> <scratch> devforall -
  537.   exch {
  538.     1 index currentdevparams
  539.     /Type .knownget { /FileSystem eq } { false } ifelse
  540.     { exec } { pop pop } ifelse
  541.   } /exec load 3 packedarray cvx exch
  542.   (*) 3 1 roll ppstack flush /IODevice resourceforall
  543. } odef
  544. /devstatus {        % <(%disk*%)> devstatus <searchable> <writable>
  545.             %   <hasNames> <mounted> <removable> <searchOrder>
  546.             %   <freePages> <size> true
  547.             % <string> devstatus false
  548.   dup length 5 ge {
  549.     dup 0 5 getinterval (%disk) eq {
  550.       dup /IODevice resourcestatus {
  551.     pop pop dup currentdevparams
  552.     dup /Searchable get
  553.     exch dup /Writable get
  554.     exch dup /HasNames get
  555.     exch dup /Mounted get
  556.     exch dup /Removable get
  557.     exch dup /SearchOrder get
  558.     exch dup /Free get
  559.     exch /LogicalSize get
  560.     9 -1 roll pop true
  561.       } {
  562.     pop false
  563.       } ifelse
  564.     } {
  565.       pop false
  566.     } ifelse
  567.   } {
  568.     pop false
  569.   } ifelse
  570. } odef
  571.  
  572. % ------ Color spaces ------ %
  573.  
  574. % Attempt to convert a tint transformation procedure to a Function.
  575. % The current color space defines the number of output values.
  576. /.converttinttransform {    % [.. .. .. proc ] <m>
  577.                 %   .converttinttransform [.. .. .. proc']
  578.   .currentglobal 2 index gcheck .setglobal
  579.   4 dict
  580.     dup /FunctionType 4 put
  581.     dup /Function 5 index 3 get put
  582.         % Stack: orig m global func
  583.     dup /Domain [ 6 -1 roll {0 1} repeat ] put
  584.     dup /Range [
  585.       mark currentcolor counttomark
  586.       dup 2 add 1 roll cleartomark    % # of components in alternate space
  587.     {0 1} repeat ] put
  588.   { .buildfunction } .internalstopped {
  589.     pop .setglobal
  590.   } {
  591.         % Stack: orig global func
  592.     2 index 4 array copy dup 3 4 -1 roll put
  593.     exch .setglobal exch pop
  594.   } ifelse
  595. } bind def
  596.  
  597. % Define the setcolorspace procedures:
  598. %    <colorspace> proc <colorspace'|null>
  599. % We have to define the dictionary first, so it can be bound into the
  600. % implementation procedure, but we can't populate it until the procedure
  601. % has been defined, so that the procedure can get bound into recursive calls.
  602. /colorspacedict 20 dict def
  603.  
  604. /.devcs [
  605.   /DeviceGray /DeviceRGB /DeviceCMYK /DevicePixel
  606. ] readonly def
  607. /currentcolorspace {        % - currentcolorspace <array>
  608.   .currentcolorspace dup type /integertype eq {
  609.     //.devcs exch 1 getinterval
  610.   } if
  611. } odef
  612. currentdict /.devcs .undef
  613.  
  614. /setcolorspace {        % <name|array> setcolorspace -
  615.   dup dup dup type /nametype ne { 0 get } if
  616.   //colorspacedict exch get exec
  617.   dup null eq { pop } { .setcolorspace } ifelse pop
  618. } odef
  619.  
  620. colorspacedict
  621.   dup /DeviceGray { pop 0 setgray null } bind put
  622.   dup /DeviceRGB { pop 0 0 0 setrgbcolor null } bind put
  623.   /setcmykcolor where
  624.    { pop dup /DeviceCMYK { pop 0 0 0 1 setcmykcolor null } bind put
  625.    } if
  626.   /.setcieaspace where
  627.    { pop dup /CIEBasedA { NOCIE { pop 0 setgray null } { dup 1 get .setcieaspace } ifelse } bind put
  628.    } if
  629.   /.setcieabcspace where
  630.    { pop dup /CIEBasedABC { NOCIE { pop 0 0 0 setrgbcolor null } { dup 1 get .setcieabcspace } ifelse } bind put
  631.    } if
  632.   /.setciedefspace where
  633.    { pop dup /CIEBasedDEF { NOCIE { pop 0 0 0 setrgbcolor null } { dup 1 get .setciedefspace } ifelse } bind put
  634.    } if
  635.   /.setciedefgspace where
  636.    { pop dup /CIEBasedDEFG { NOCIE { pop 0 0 0 1 setcmykcolor null } { dup 1 get .setciedefgspace } ifelse } bind put
  637.    } if
  638.   /.setseparationspace where
  639.    { pop dup /Separation { dup 2 get setcolorspace dup 1 .converttinttransform .setseparationspace } bind put
  640.    } if
  641.   /.setindexedspace where
  642.    { pop dup /Indexed { dup 1 get setcolorspace dup .setindexedspace } bind put
  643.    } if
  644.   /.nullpatternspace [/Pattern] readonly def
  645.   /.setpatternspace where
  646.    { pop dup /Pattern
  647.       { dup type /nametype eq { pop //.nullpatternspace } if
  648.     dup length 1 gt { dup 1 get setcolorspace } if
  649.         dup .setpatternspace
  650.       } bind put
  651.    } if
  652.     % If DeviceN space is included, gs_ll3.ps registers it.
  653.   /.setdevicepixelspace where
  654.    { pop dup /DevicePixel { dup .setdevicepixelspace } bind put
  655.    } if
  656.   currentdict /.nullpatternspace .undef
  657. pop
  658.  
  659. % ------ CIE color rendering ------ %
  660.  
  661. % Define findcolorrendering and a default ColorRendering ProcSet.
  662.  
  663. /findcolorrendering {        % <intentname> findcolorrendering
  664.                 %   <crdname> <found>
  665.   /ColorRendering /ProcSet findresource
  666.   1 index .namestring (.) concatstrings
  667.   1 index /GetPageDeviceName get exec .namestring (.) concatstrings
  668.   2 index /GetHalftoneName get exec .namestring
  669.   concatstrings concatstrings
  670.   dup /ColorRendering resourcestatus {
  671.     pop pop exch pop exch pop true
  672.   } {
  673.     pop /GetSubstituteCRD get exec false
  674.   } ifelse
  675. } odef
  676.  
  677. 5 dict dup begin
  678.  
  679. /GetPageDeviceName {        % - GetPageDeviceName <name>
  680.   currentpagedevice dup /PageDeviceName .knownget {
  681.     exch pop dup null eq { pop /none } if
  682.   } {
  683.     pop /none
  684.   } ifelse
  685. } bind def
  686.  
  687. /GetHalftoneName {        % - GetHalftoneName <name>
  688.   currenthalftone /HalftoneName .knownget not { /none } if
  689. } bind def
  690.  
  691. /GetSubstituteCRD {        % <intentname> GetSubstituteCRD <crdname>
  692.   pop /DefaultColorRendering
  693. } bind def
  694.  
  695. end
  696. % The resource machinery hasn't been activated, so just save the ProcSet
  697. % and let .fixresources finish the installation process.
  698. /ColorRendering exch def
  699.  
  700. % Define setcolorrendering.
  701.  
  702. /.colorrenderingtypes 5 dict def
  703.  
  704. /setcolorrendering {        % <crd> setcolorrendering -
  705.   dup /ColorRenderingType get //.colorrenderingtypes exch get exec
  706. } odef
  707.  
  708. /.setcolorrendering1 where { pop } { (%END CRD) .skipeof } ifelse
  709.  
  710. .colorrenderingtypes 1 {
  711.   dup .buildcolorrendering1 .setcolorrendering1
  712. } .bind put
  713.  
  714. % Note: the value 101 in the next line must be the same as the value of
  715. % GX_DEVICE_CRD1_TYPE in gscrdp.h.
  716. .colorrenderingtypes 101 {
  717.   dup .builddevicecolorrendering1 .setdevicecolorrendering1
  718. } .bind put
  719.  
  720. % Initialize the default CIE rendering dictionary.
  721. % The most common CIE files seem to assume the "calibrated RGB color space"
  722. % described on p. 189 of the PostScript Language Reference Manual,
  723. % 2nd Edition; we simply invert this transformation back to RGB.
  724. mark
  725.    /ColorRenderingType 1
  726. % We must make RangePQR and RangeLMN large enough so that values computed by
  727. % the assumed encoding MatrixLMN don't get clamped.
  728.    /RangePQR [0 0.9505 0 1 0 1.0890] readonly
  729.    /TransformPQR
  730.      [ {exch pop exch pop exch pop exch pop} bind dup dup ] readonly
  731.    /RangeLMN [0 0.9505 0 1 0 1.0890] readonly
  732.    /MatrixABC
  733.     [ 3.24063 -0.96893  0.05571
  734.      -1.53721  1.87576 -0.20402
  735.      -0.49863  0.04152  1.05700
  736.     ] readonly
  737.    /EncodeABC [ {0 .max 0.45 exp} bind dup dup] readonly
  738.    /WhitePoint [0.9505 1 1.0890] readonly
  739.     % Some Genoa tests seem to require the presence of BlackPoint.
  740.    /BlackPoint [0 0 0] readonly
  741. .dicttomark setcolorrendering
  742.  
  743. %END CRD
  744.  
  745. % Initialize a CIEBased color space for sRGB.
  746. /CIEsRGB [ /CIEBasedABC
  747.   mark
  748.     /DecodeLMN [ {
  749.       dup 0.03928 le { 12.92321 div } { 0.055 add 1.055 div 2.4 exp } ifelse
  750.     } bind dup dup ] readonly
  751.     /MatrixLMN [
  752.       0.412457 0.212673 0.019334
  753.       0.357576 0.715152 0.119192
  754.       0.180437 0.072175 0.950301
  755.     ] readonly
  756.     /WhitePoint [0.9505 1.0 1.0890] readonly
  757.   .dicttomark readonly
  758. ] readonly def
  759.  
  760. % ------ Painting ------ %
  761.  
  762. % A straightforward definition of execform that doesn't actually
  763. % do any caching.
  764. /.execform1 {
  765.     % This is a separate operator so that the stacks will be restored
  766.     % properly if an error occurs.
  767.   dup /Matrix get concat
  768.   dup /BBox get aload pop
  769.   exch 3 index sub exch 2 index sub rectclip
  770.   dup /PaintProc get
  771.   1 index /Implementation known not {
  772.     1 index dup /Implementation null .forceput readonly pop
  773.   } if
  774.   exec
  775. } .bind odef    % must bind .forceput
  776.  
  777. /.formtypes 5 dict
  778.   dup 1 /.execform1 load put
  779. def
  780.  
  781. /execform {            % <form> execform -
  782.   gsave {
  783.     dup /FormType get //.formtypes exch get exec
  784.   } stopped grestore { stop } if
  785. } odef
  786.  
  787. /.patterntypes 5 dict
  788.   dup 1 /.buildpattern1 load put
  789. def
  790.  
  791. /makepattern {            % <proto_dict> <matrix> makepattern <pattern>
  792.   //.patterntypes 2 index /PatternType get get
  793.   .currentglobal false .setglobal exch
  794.         % Stack: proto matrix global buildproc
  795.   3 index dup length 1 add dict .copydict
  796.   3 index 3 -1 roll exec 3 -1 roll .setglobal
  797.   1 index /Implementation 3 -1 roll put
  798.   readonly exch pop exch pop
  799. } odef
  800.  
  801. /setpattern {            % [<comp1> ...] <pattern> setpattern -
  802.   currentcolorspace 0 get /Pattern ne {
  803.     [ /Pattern currentcolorspace ] setcolorspace
  804.   } if setcolor
  805. } odef
  806.  
  807. % Extend image and imagemask to accept dictionaries.
  808. % We must create .imagetypes and .imagemasktypes outside level2dict,
  809. % and leave some extra space because we're still in Level 1 mode.
  810. systemdict begin
  811. /.imagetypes 5 dict
  812.   dup 1 /.image1 load put
  813. def
  814. /.imagemasktypes 5 dict
  815.   dup 1 /.imagemask1 load put
  816. def
  817. end
  818.  
  819. /.image /image load def
  820. /image {
  821.   dup type /dicttype eq {
  822.     dup /ImageType get //.imagetypes exch get exec
  823.   } {
  824.     //.image
  825.   } ifelse
  826. } odef
  827. currentdict /.image undef
  828.  
  829. /.imagemask /imagemask load def
  830. /imagemask {
  831.   dup type /dicttype eq {
  832.     dup /ImageType get //.imagemasktypes exch get exec
  833.   } {
  834.     //.imagemask
  835.   } ifelse
  836. } odef
  837. currentdict /.imagemask undef
  838.  
  839. end                % level2dict
  840.