home *** CD-ROM | disk | FTP | other *** search
/ Internet Magazine 2002 February / INTERNET88.ISO / pc / software / windows / bits / pdf995 / data1.cab / Program_Executable_Files / res / wrfont.ps < prev    next >
Encoding:
Text File  |  2001-12-08  |  18.5 KB  |  666 lines

  1. %    Copyright (C) 1991, 1995, 1996 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of GNU Ghostscript.
  3. % GNU Ghostscript is distributed in the hope that it will be useful, but
  4. % WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  5. % to anyone for the consequences of using it or for whether it serves any
  6. % particular purpose or works at all, unless he says so in writing.  Refer
  7. % to the GNU General Public License for full details.
  8. % Everyone is granted permission to copy, modify and redistribute GNU
  9. % Ghostscript, but only under the conditions described in the GNU General
  10. % Public License.  A copy of this license is supposed to have been given
  11. % to you along with GNU Ghostscript so you can know your rights and
  12. % responsibilities.  It should be in a file named COPYING.  Among other
  13. % things, the copyright notice and this notice must be preserved on all
  14. % copies.
  15.  
  16. % $RCSfile: wrfont.ps,v $ $Revision: 1.2.2.1 $
  17. % wrfont.ps
  18. % Write out a Type 1 font in readable, reloadable form.
  19. % Note that this does NOT work on protected fonts, such as Adobe fonts
  20. % (unless you have loaded unprot.ps first, in which case you may be
  21. % violating the Adobe license).
  22.  
  23. % ****** NOTE: This file must be kept consistent with gs_pfile.ps.
  24.  
  25. /wrfont_dict 100 dict def
  26. wrfont_dict begin
  27.  
  28. % ------ Options ------ %
  29.  
  30. % Define whether to use eexec encryption for the font.
  31. % eexec encryption is only useful for compatibility with Adobe Type Manager
  32. % and other programs; it only slows Ghostscript down.
  33.    /eexec_encrypt false def
  34.  
  35. % Define whether to write out the CharStrings in binary or in hex.
  36. % Binary takes less space on the file, but isn't guaranteed portable.
  37.    /binary_CharStrings false def
  38.  
  39. % Define whether to use binary token encodings when possible.
  40. % Binary tokens are smaller and load faster, but are a Level 2 feature.
  41.    /binary_tokens false def
  42.  
  43. % Define whether to encrypt the CharStrings on the file.  (CharStrings
  44. % are always encrypted in memory.)  Unencrypted CharStrings load about
  45. % 20% slower, but make the files compress much better for transport.
  46.    /encrypt_CharStrings true def
  47.  
  48. % Define whether the font must provide standard PostScript language
  49. % equivalents for any facilities it uses that are provided in Ghostscript
  50. % but are not part of the standard PostScript language.
  51.    /standard_only true def
  52.  
  53. % Define the value of lenIV to use in writing out the font.
  54. % use_lenIV = 0 produces the smallest output, but this may not be
  55. % compatible with old Adobe interpreters.  use_lenIV = -1 means
  56. % use the value of lenIV from the font.
  57.    /use_lenIV -1 def
  58.  
  59. % Define whether to produce the smallest possible output, relying
  60. % as much as possible on Ghostscript-specific support code.
  61. % Taking full advantage of this requires the following settings:
  62. % binary_CharStrings = true, binary_tokens = true, standard_only = false.
  63.    /smallest_output false def
  64.  
  65. % Define whether to write out all currently known Encodings by name,
  66. % or only StandardEncoding and ISOLatin1Encoding.
  67.    /name_all_Encodings false def
  68.  
  69. % ---------------- Runtime support ---------------- %
  70.  
  71. /.packedfilefilter where
  72.  { pop }
  73.  { (gs_pfile.ps) runlibfile }
  74. ifelse
  75.  
  76. % ------ Output utilities ------ %
  77.  
  78. % By convention, the output file is named psfile.
  79.  
  80. % Define some utilities for writing the output file.
  81.    /wtstring 2000 string def
  82.    /wb {psfile exch write} bind def
  83.    /wnb {/wb load repeat} bind def
  84.    /w1 {psfile exch write} bind def
  85.    /ws {psfile exch writestring} bind def
  86.    /wl {ws (\n) ws} bind def
  87.    /wt {wtstring cvs ws ( ) ws} bind def
  88.    /wd        % Write a dictionary.
  89.     { dup length wo {dict dup begin} wol { we } forall
  90.       {end} wol
  91.     } bind def
  92.    /wld        % Write a large dictionary more efficiently.
  93.            % Ignore the readonly attributes.
  94.     { dup length wo {dict dup begin} wol
  95.       0 exch
  96.        { exch wo wo () wl
  97.      1 add dup 200 eq
  98.       { wo ({def} repeat) wl 0 }
  99.      if
  100.        }
  101.       forall
  102.       dup 0 ne
  103.        { wo ({def} repeat) wl }
  104.        { pop }
  105.       ifelse
  106.       (end) ws
  107.     } bind def
  108.    /we        % Write a dictionary entry.
  109.     { exch wo wo /def cvx wo (\n) ws
  110.     } bind def
  111.    /wcs        % Write a CharString (or Subrs entry)
  112.     { dup type /stringtype eq
  113.        { 4330 exch changelenIV 0 ge
  114.           {    % Add some leading garbage bytes.
  115.         wtstring changelenIV 2 index length getinterval
  116.         .type1decrypt exch pop
  117.         wtstring exch 0 exch length changelenIV add getinterval
  118.       }
  119.       {    % Drop some leading garbage bytes.
  120.         wtstring .type1decrypt exch pop
  121.         changelenIV neg 1 index length 1 index sub getinterval
  122.       }
  123.      ifelse
  124.          binary_tokens encrypt_CharStrings and
  125.       { % Suppress recognizing the readonly status of the string.
  126.         4330 exch dup .type1encrypt exch pop wo
  127.       }
  128.       { encrypt_CharStrings
  129.          { 4330 exch dup .type1encrypt exch pop
  130.          } if
  131.         smallest_output
  132.          { wo
  133.          }
  134.          { readonly dup length wo
  135.            binary_tokens not { ( ) ws } if
  136.            readproc ws wx
  137.          }
  138.         ifelse
  139.       }
  140.      ifelse
  141.        }
  142.        { wo        % PostScript procedure
  143.        }
  144.       ifelse
  145.     } bind def
  146.  
  147. % Construct the inversion of the system name table.
  148.    /SystemNames where
  149.     { pop /snit 256 dict def
  150.       0 1 255
  151.        { dup SystemNames exch get
  152.          dup null ne { exch snit 3 1 roll put } { pop pop } ifelse
  153.        }
  154.       for
  155.     }
  156.     { /snit 1 dict def
  157.     }
  158.    ifelse
  159.  
  160. % Write an object, using binary tokens if requested and possible.
  161.    /woa        % write in ascii
  162.     { psfile exch write==only
  163.     } bind def
  164.  
  165.             % Lookup table for ASCII output.
  166.  
  167.    /intbytes    % int nbytes -> byte*
  168.     { { dup 255 and exch -8 bitshift } repeat pop
  169.     } bind def
  170.    /wotta 10 dict dup begin
  171.       { /booleantype /integertype }
  172.       { { ( ) ws woa } def }
  173.      forall
  174.         % Iterate over arrays so we can print operators.
  175.      /arraytype
  176.       { dup xcheck {(}) ({)} {(]) ([)} ifelse ws exch dup wol exch ws wop
  177.       } bind def
  178.      /dicttype
  179.       { ( ) ws wd } def
  180.      /nametype
  181.       { dup xcheck { ( ) ws } if woa
  182.       } bind def
  183.         % Map back operators to their names,
  184.         % so we can write procedures.
  185.      /nulltype
  186.       { pop ( null) ws
  187.       } bind def
  188.      /operatortype
  189.       { wtstring cvs cvn cvx wo
  190.       } bind def
  191.         % Convert reals to integers if possible.
  192.      /realtype
  193.       { dup cvi 1 index eq { cvi wo } { ( ) ws woa } ifelse
  194.       } bind def
  195.         % == truncates strings longer than 200 characters!
  196.      /stringtype
  197.       { (\() ws dup
  198.      { dup dup 32 lt exch 127 ge or
  199.         { (\\) ws dup -6 bitshift 48 add w1
  200.           dup -3 bitshift 7 and 48 add w1
  201.           7 and 48 add
  202.         }
  203.         { dup dup -2 and 40 eq exch 92 eq or {(\\) ws} if
  204.         }
  205.        ifelse w1
  206.      }
  207.     forall
  208.     (\)) ws wop
  209.       } bind def
  210.      /packedarraytype
  211.       { ([) ws dup { wo } forall
  212.     encodingnames 1 index known
  213.         % This is an encoding, but not one of the standard ones.
  214.         % Use the built-in encoding only if it is available.
  215.      { encodingnames exch get wo
  216.        ({findencoding}stopped{pop) ws
  217.        (}{counttomark 1 add 1 roll cleartomark}ifelse)
  218.      }
  219.      { pop ()
  220.      }
  221.     ifelse
  222.     (/packedarray where{pop counttomark packedarray exch pop}{]readonly}ifelse) ws
  223.     wl
  224.       }
  225.      def
  226.    end def
  227.  
  228.             % Lookup table for binary output.
  229.  
  230.    /wottb 8 dict dup begin
  231.    wotta currentdict copy pop
  232.      /integertype
  233.       { dup dup 127 le exch -128 ge and
  234.          { 136 wb 255 and wb }
  235.      { dup dup 32767 le exch -32768 ge and
  236.         { 134 wb 2 intbytes wb wb }
  237.         { 132 wb 4 intbytes wb wb wb wb }
  238.        ifelse
  239.      }
  240.     ifelse
  241.       } bind def
  242.      /nametype
  243.       { dup snit exch known
  244.          { dup xcheck { 146 } { 145 } ifelse wb
  245.        snit exch get wb
  246.      }
  247.      { wotta /nametype get exec
  248.      }
  249.     ifelse
  250.       } bind def
  251.      /stringtype
  252.       { dup dup length dup 255 le { 142 2 } { 2 intbytes 143 3 } ifelse wnb
  253.     ws wop
  254.       } bind def
  255.    end def
  256.  
  257.    /wop        % Write object protection
  258.      { wcheck not { /readonly cvx wo } if
  259.      } bind def
  260.    /wo        % Write an object.
  261.      { dup type binary_tokens { wottb } { wotta } ifelse
  262.        exch get exec
  263.      } bind def
  264.    /wol        % Write a list of objects.
  265.      { { wo } forall
  266.      } bind def
  267.  
  268. % Write a hex string for Subrs or CharStrings.
  269.    /wx        % string ->
  270.     { binary_CharStrings
  271.        { ws
  272.        }
  273.        { % Some systems choke on very long lines, so
  274.      % we break up the hexstring into chunks of 50 characters.
  275.       { dup length 25 le {exit} if
  276.         dup 0 25 getinterval psfile exch writehexstring (\n) ws
  277.         dup length 25 sub 25 exch getinterval
  278.       } loop
  279.      psfile exch writehexstring
  280.        } ifelse
  281.     } bind def
  282.  
  283. % ------ CharString encryption utilities ------ %
  284.  
  285. /enc_dict 20 dict def
  286. 1 dict begin
  287. /bind { } def        % make sure we can print out the procedures
  288. enc_dict begin
  289.  
  290. (type1enc.ps) runlibfile
  291. enc_dict /.type1decrypt undef        % we don't need this
  292.  
  293. end end
  294.  
  295. enc_dict { 1 index where { pop pop pop } { def } ifelse } forall
  296.  
  297. % ------ Other utilities ------ %
  298.  
  299. % Test whether two values are equal (for default dictionary entries).
  300.    /valueeq        % <obj1> <obj2> valueeq <bool>
  301.     { 2 copy eq
  302.        { pop pop true }
  303.        {    % Special hack for comparing FontMatrix values
  304.      dup type /arraytype eq 2 index type /arraytype eq and
  305.       { dup length 2 index length eq
  306.          { true 0 1 3 index length 1 sub
  307.         {    % Stack: arr1 arr2 true index
  308.           3 index 1 index get 3 index 3 -1 roll get eq not
  309.            { pop false exit }
  310.           if
  311.         }
  312.            for 3 1 roll pop pop
  313.          }
  314.          { pop pop false
  315.          }
  316.         ifelse
  317.       }
  318.       { pop pop false
  319.       }
  320.      ifelse
  321.        }
  322.       ifelse
  323.     } bind def
  324.  
  325. % ------ The main program ------ %
  326.  
  327. % Define the dictionary of keys to skip because they are treated specially.
  328. /.fontskipkeys mark
  329.   /CharStrings dup
  330.   /Encoding dup
  331.   /FDepVector dup
  332.   /FID dup
  333.   /FontInfo dup
  334.   /Metrics dup
  335.   /Metrics2 dup
  336.   /Private dup
  337. .dicttomark def
  338. /.minfontskipkeys mark
  339.   .fontskipkeys { } forall
  340.   /FontName dup
  341.   /UniqueID dup
  342. .dicttomark def
  343. /.privateskipkeys mark
  344.   /ND dup
  345.   /NP dup
  346.   /RD dup
  347.   /Subrs dup
  348. .dicttomark def
  349. /.minprivateskipkeys mark
  350.   .privateskipkeys { } forall
  351.   /MinFeature dup
  352.   /Password dup
  353.   /UniqueID dup
  354. .dicttomark def
  355.  
  356. % Define the procedures for the Private dictionary.
  357. % These must be defined without `bind',
  358. % for the sake of the DISKFONTS feature.
  359. 4 dict begin
  360.  /-! {string currentfile exch readhexstring pop} def
  361.  /-| {string currentfile exch readstring pop} def
  362.  /|- {readonly def} def
  363.  /| {readonly put} def
  364. currentdict end /encrypted_procs exch def
  365. 4 dict begin
  366.  /-! {string currentfile exch readhexstring pop
  367.    4330 exch dup .type1encrypt exch pop} def
  368.  /-| {string currentfile exch readstring pop
  369.    4330 exch dup .type1encrypt exch pop} def
  370.  /|- {readonly def} def
  371.  /| {readonly put} def
  372. currentdict end /unencrypted_procs exch def
  373.  
  374. % Construct an inverse dictionary of encodings.
  375. /encodingnames mark
  376.  StandardEncoding /StandardEncoding
  377.  ISOLatin1Encoding /ISOLatin1Encoding
  378.  SymbolEncoding /SymbolEncoding
  379.  DingbatsEncoding /DingbatsEncoding
  380.  /resourceforall where
  381.   { pop (*) { cvn dup findencoding exch } 100 string /Encoding resourceforall }
  382.  if
  383. .dicttomark def
  384.  
  385. % Invert the standard encodings.
  386. .knownEncodings length 256 mul dict begin
  387.   0 .knownEncodings
  388.    {  { currentdict 1 index known { pop } { 1 index def } ifelse
  389.     1 add
  390.       }
  391.      forall
  392.    }
  393.   forall pop
  394. currentdict end /inverseencodings exch def
  395.  
  396. /writefont        % <psfile> writefont - (writes the current font)
  397.  { /psfile exch def
  398.    /Font currentfont def
  399.    /FontInfo Font /FontInfo .knownget not { 0 dict } if def
  400.    /FontType Font /FontType get def
  401.    /hasPrivate Font /Private known def
  402.    /Private hasPrivate { Font /Private get } { 0 dict } ifelse def
  403.    /readproc binary_CharStrings { (-| ) } { (-! ) } ifelse def
  404.    /privateprocs
  405.      encrypt_CharStrings binary_tokens not and
  406.       { encrypted_procs } { unencrypted_procs } ifelse
  407.      def
  408.    /addlenIV false def
  409.    /changelenIV use_lenIV 0 lt
  410.     { 0 }
  411.     { use_lenIV Private /lenIV .knownget not
  412.        { 4 /addlenIV use_lenIV 4 ne def } if sub }
  413.    ifelse def
  414.    /minimize
  415.      smallest_output
  416.      FontType 1 eq and
  417.      Font /UniqueID known and
  418.    def
  419.    (%!FontType) ws FontType wtstring cvs ws (-1.0: ) ws
  420.      currentfont /FontName get wt
  421.      FontInfo /version .knownget not { (001.001) } if wl
  422.    FontInfo /CreationDate .knownget { (%%Creation Date: ) ws wl } if
  423.    FontInfo /VMusage .knownget
  424.     { (%%VMusage: ) ws dup wt wtstring cvs wl }
  425.    if
  426.    (systemdict begin) wl
  427.  
  428. % If we're going to use eexec, create the filters now.
  429.    /realpsfile psfile def
  430.    eexec_encrypt
  431.     { /eexecfilter psfile binary_CharStrings not
  432.        { pop /bxstring 35 string def
  433.       { pop dup length 0 ne
  434.          { realpsfile exch writehexstring realpsfile (\n) writestring }
  435.          { pop }
  436.         ifelse bxstring
  437.       }
  438.      /NullEncode filter dup /hexfilter exch def
  439.        }
  440.       if 55665 /eexecEncode filter def
  441.     }
  442.    if
  443.  
  444. % Turn on binary tokens if relevant.
  445.    binary_tokens { (currentobjectformat 1 setobjectformat) wl } if
  446.  
  447. % If the file has a UniqueID, write out a check against loading it twice.
  448.    minimize
  449.     { Font /FontName get wo
  450.       Font /UniqueID get wo
  451.       Private length addlenIV { 1 add } if wo
  452.       Font length 1 add wo        % +1 for FontFile
  453.       ( .checkexistingfont) wl
  454.     }
  455.     { Font /UniqueID known
  456.        { ({} FontDirectory) ws Font /FontName get dup wo ( known) wl
  457.      ( {) ws wo ( findfont dup /UniqueID known) wl
  458.      (    { dup /UniqueID get) ws Font /UniqueID get wo ( eq exch /FontType get 1 eq and }) wl
  459.      (    { pop false } ifelse) wl
  460.      (    { pop save /restore load } if) wl
  461.      ( } if) wl
  462.        }
  463.       if
  464.     }
  465.    ifelse
  466.  
  467. % If we are writing unencrypted CharStrings for a standard environment,
  468. % write out the encryption procedures.
  469.    privateprocs unencrypted_procs eq standard_only and
  470.     { (systemdict /.type1encrypt known) wl
  471.       ( { save /restore load } { { } } ifelse) wl
  472.       (userdict begin) wl
  473.       enc_dict { we } forall
  474.       (end exec) wl
  475.     }
  476.    if
  477.  
  478. % Write out the creation of the font dictionary and FontInfo.
  479.    minimize not
  480.     { Font length 1 add wo {dict begin} wol        % +1 for FontFile
  481.     }
  482.    if
  483.    (/FontInfo ) ws FontInfo wd {readonly def} wol
  484.  
  485. % Write out the other fixed entries in the font dictionary.
  486.    Font begin
  487.    Font
  488.     { minimize
  489.        { .minfontskipkeys 2 index known
  490.       { pop pop
  491.       }
  492.       { //.compactfontdefault 2 index .knownget
  493.          { 1 index valueeq { pop pop } { we } ifelse }
  494.          { we }
  495.         ifelse
  496.       }
  497.      ifelse
  498.        }
  499.        { .fontskipkeys 2 index known { pop pop } { we } ifelse
  500.        }
  501.       ifelse
  502.     } forall
  503.    /Encoding
  504.    encodingnames Encoding known
  505.    name_all_Encodings
  506.    Encoding StandardEncoding eq or
  507.    Encoding ISOLatin1Encoding eq or and
  508.     { encodingnames Encoding get cvx }
  509.     { Encoding }
  510.    ifelse
  511.    dup /StandardEncoding cvx eq minimize and
  512.     { pop pop }
  513.     { we }
  514.    ifelse
  515.  
  516. % Write the FDepVector, if any.
  517.    Font /FDepVector .knownget
  518.     { {/FDepVector [} wol
  519.        { /FontName get wo {findfont} wol () wl } forall
  520.       {] readonly def} wol
  521.     }
  522.    if
  523.  
  524. % Write out the Metrics, if any.
  525.    Font /Metrics .knownget
  526.     { (/Metrics ) ws wld {readonly def} wol
  527.     }
  528.    if
  529.    Font /Metrics2 .knownget
  530.     { (/Metrics2 ) ws wld {readonly def} wol
  531.     }
  532.    if
  533.  
  534. % Start the eexec-encrypted section, if applicable.
  535.   eexec_encrypt
  536.    { {currentdict currentfile eexec} wol () wl
  537.      /psfile eexecfilter store
  538.      (\000\000\000\000) ws {begin} wol
  539.    }
  540.   if
  541.  
  542. % Create and initialize the Private dictionary, if any.
  543.    hasPrivate
  544. {
  545.    Private
  546.    minimize
  547.     { begin {Private dup begin}
  548.     }
  549.     {  dup length privateprocs length add dict copy begin
  550.        privateprocs { readonly def } forall
  551.        /Private wo
  552.        currentdict length 1 add wo {dict dup begin}
  553.     }
  554.    ifelse wol () wl
  555.    currentdict
  556.     { 1 index minimize { .minprivateskipkeys } { .privateskipkeys } ifelse
  557.       exch known
  558.        { pop pop }
  559.        { 1 index /lenIV eq use_lenIV 0 ge and { pop use_lenIV } if we }
  560.       ifelse
  561.     } forall
  562.    addlenIV { /lenIV use_lenIV we } if
  563. }
  564. if
  565.  
  566. % Write the Subrs entries, if any.
  567.    currentdict /Subrs known
  568.     { (/Subrs[) wl
  569.       Subrs
  570.        { dup null ne
  571.       { wcs minimize not { () wl } if }
  572.       { pop /null cvx wo }
  573.      ifelse
  574.        } forall
  575.       {] dup {readonly pop} forall readonly def} wol () wl
  576.     }
  577.    if
  578.  
  579. % Wrap up the Private dictionary.
  580.    hasPrivate
  581.     { end            % Private
  582.       minimize
  583.        { {end readonly pop} }    % Private
  584.        { {end readonly def} }    % Private in font
  585.       ifelse wol
  586.     }
  587.    if
  588.  
  589. % Write the CharStrings entries.
  590. % Detect identical (eq) entries, which bdftops produces.
  591.    currentdict /CharStrings known
  592. {
  593.    /CharStrings wo CharStrings length wo
  594.    minimize
  595.     { encrypt_CharStrings not wo ( .readCharStrings) wl
  596.       CharStrings length dict
  597.       CharStrings
  598.        { exch inverseencodings 1 index .knownget not { dup } if wo
  599.         % Stack: vdict value key
  600.      3 copy pop .knownget { wo pop pop } { 3 copy put pop wcs } ifelse
  601.        } forall
  602.     }
  603.     { {dict dup Private begin begin} wol () wl
  604.       CharStrings length dict
  605.       CharStrings
  606.        { 2 index 1 index known
  607.       { exch wo 1 index exch get wo {load def} wol () wl
  608.       }
  609.       { 2 index 1 index 3 index put
  610.         exch wo wcs ( |-) wl
  611.       }
  612.      ifelse
  613.        } forall
  614.       {end end} wol
  615.     }
  616.    ifelse
  617.    pop
  618.     { readonly def }    % CharStrings in font
  619.    wol
  620. }
  621. if
  622.  
  623. % Terminate the output.
  624.    end            % Font
  625.    eexec_encrypt
  626.     { {end mark currentfile closefile} wol () wl
  627.       eexecfilter dup flushfile closefile    % psfile is eexecfilter
  628.       binary_CharStrings not { hexfilter dup flushfile closefile } if
  629.       /psfile realpsfile store
  630.       8
  631.        { (0000000000000000000000000000000000000000000000000000000000000000)
  632.          wl
  633.        }
  634.       repeat {cleartomark} wol
  635.     }
  636.    if
  637.     { FontName currentdict end definefont pop
  638.     }
  639.    wol
  640.    Font /UniqueID known { /exec cvx wo } if
  641.    binary_tokens { /setobjectformat cvx wo } if
  642.    ( end) wl        % systemdict
  643.  
  644.  } bind def
  645.  
  646. % ------ Other utilities ------ %
  647.  
  648. % Prune garbage characters and OtherSubrs out of the current font,
  649. % if the relevant dictionaries are writable.
  650. /prunefont
  651.  { currentfont /CharStrings get wcheck
  652.     { currentfont /CharStrings get dup [ exch
  653.        { pop dup (S????00?) .stringmatch not { pop } if
  654.        } forall
  655.       ] { 2 copy undef pop } forall pop
  656.     }
  657.    if
  658.  } bind def
  659.  
  660. end            % wrfont_dict
  661.  
  662. /writefont { wrfont_dict begin writefont end } def
  663.