home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Updates / GhostScript / !GhostScr / 6_01 / lib / gs_lev2.ps < prev    next >
Text File  |  2000-03-29  |  25KB  |  744 lines

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