home *** CD-ROM | disk | FTP | other *** search
/ Freelog Special Freeware 31 / FreelogHS31.iso / PDF / Ghostscript / gs860w32.exe / gs8.60 / lib / wrfont.ps < prev    next >
Text File  |  2005-12-29  |  19KB  |  666 lines

  1. %    Copyright (C) 1991, 1995, 1996, 2002 Aladdin Enterprises.  All rights reserved.
  2. % This software is provided AS-IS with no warranty, either express or
  3. % implied.
  4. % This software is distributed under license and may not be copied,
  5. % modified or distributed except as expressly authorized under the terms
  6. % of the license contained in the file LICENSE in this distribution.
  7. % For more information about licensing, please refer to
  8. % http://www.ghostscript.com/licensing/. For information on
  9. % commercial licensing, go to http://www.artifex.com/licensing/ or
  10. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
  12.  
  13. % $Id: wrfont.ps 6300 2005-12-28 19:56:24Z giles $
  14. % wrfont.ps
  15. % Write out a Type 1 font in readable, reloadable form.
  16. % Note that this does NOT work on protected fonts, such as Adobe fonts
  17. % (unless you have loaded unprot.ps first, in which case you may be
  18. % violating the Adobe license).
  19.  
  20. % ****** NOTE: This file must be kept consistent with gs_pfile.ps.
  21.  
  22. /wrfont_dict 100 dict def
  23. wrfont_dict begin
  24.  
  25. % ------ Options ------ %
  26.  
  27. % Define whether to use eexec encryption for the font.
  28. % eexec encryption is only useful for compatibility with Adobe Type Manager
  29. % and other programs; it only slows Ghostscript down.
  30.    /eexec_encrypt false def
  31.  
  32. % Define whether to write out the CharStrings in binary or in hex.
  33. % Binary takes less space on the file, but isn't guaranteed portable.
  34.    /binary_CharStrings false def
  35.  
  36. % Define whether to use binary token encodings when possible.
  37. % Binary tokens are smaller and load faster, but are a Level 2 feature.
  38.    /binary_tokens false def
  39.  
  40. % Define whether to encrypt the CharStrings on the file.  (CharStrings
  41. % are always encrypted in memory.)  Unencrypted CharStrings load about
  42. % 20% slower, but make the files compress much better for transport.
  43.    /encrypt_CharStrings true def
  44.  
  45. % Define whether the font must provide standard PostScript language
  46. % equivalents for any facilities it uses that are provided in Ghostscript
  47. % but are not part of the standard PostScript language.
  48.    /standard_only true def
  49.  
  50. % Define the value of lenIV to use in writing out the font.
  51. % use_lenIV = 0 produces the smallest output, but this may not be
  52. % compatible with old Adobe interpreters.  use_lenIV = -1 means
  53. % use the value of lenIV from the font.
  54.    /use_lenIV -1 def
  55.  
  56. % Define whether to produce the smallest possible output, relying
  57. % as much as possible on Ghostscript-specific support code.
  58. % Taking full advantage of this requires the following settings:
  59. % binary_CharStrings = true, binary_tokens = true, standard_only = false.
  60.    /smallest_output false def
  61.  
  62. % Define whether to write out all currently known Encodings by name,
  63. % or only StandardEncoding and ISOLatin1Encoding.
  64.    /name_all_Encodings false def
  65.  
  66. % ---------------- Runtime support ---------------- %
  67.  
  68. /.packedfilefilter where
  69.  { pop }
  70.  { (gs_pfile.ps) runlibfile }
  71. ifelse
  72.  
  73. % ------ Output utilities ------ %
  74.  
  75. % By convention, the output file is named psfile.
  76.  
  77. % Define some utilities for writing the output file.
  78.    /wtstring 2000 string def
  79.    /wb {psfile exch write} bind def
  80.    /wnb {/wb load repeat} bind def
  81.    /w1 {psfile exch write} bind def
  82.    /ws {psfile exch writestring} bind def
  83.    /wl {ws (\n) ws} bind def
  84.    /wt {wtstring cvs ws ( ) ws} bind def
  85.    /wd        % Write a dictionary.
  86.     { dup length wo {dict dup begin} wol { we } forall
  87.       {end} wol
  88.     } bind def
  89.    /wld        % Write a large dictionary more efficiently.
  90.            % Ignore the readonly attributes.
  91.     { dup length wo {dict dup begin} wol
  92.       0 exch
  93.        { exch wo wo () wl
  94.      1 add dup 200 eq
  95.       { wo ({def} repeat) wl 0 }
  96.      if
  97.        }
  98.       forall
  99.       dup 0 ne
  100.        { wo ({def} repeat) wl }
  101.        { pop }
  102.       ifelse
  103.       (end) ws
  104.     } bind def
  105.    /we        % Write a dictionary entry.
  106.     { exch wo wo /def cvx wo (\n) ws
  107.     } bind def
  108.    /wcs        % Write a CharString (or Subrs entry)
  109.     { dup type /stringtype eq
  110.        { 4330 exch changelenIV 0 ge
  111.           {    % Add some leading garbage bytes.
  112.         wtstring changelenIV 2 index length getinterval
  113.         .type1decrypt exch pop
  114.         wtstring exch 0 exch length changelenIV add getinterval
  115.       }
  116.       {    % Drop some leading garbage bytes.
  117.         wtstring .type1decrypt exch pop
  118.         changelenIV neg 1 index length 1 index sub getinterval
  119.       }
  120.      ifelse
  121.          binary_tokens encrypt_CharStrings and
  122.       { % Suppress recognizing the readonly status of the string.
  123.         4330 exch dup .type1encrypt exch pop wo
  124.       }
  125.       { encrypt_CharStrings
  126.          { 4330 exch dup .type1encrypt exch pop
  127.          } if
  128.         smallest_output
  129.          { wo
  130.          }
  131.          { readonly dup length wo
  132.            binary_tokens not { ( ) ws } if
  133.            readproc ws wx
  134.          }
  135.         ifelse
  136.       }
  137.      ifelse
  138.        }
  139.        { wo        % PostScript procedure
  140.        }
  141.       ifelse
  142.     } bind def
  143.  
  144. % Construct the inversion of the system name table.
  145.   (\210\001) token pop exch pop 1 eq {    % i.e., do we have binary tokens?
  146.     /snit 256 dict def
  147.     0 1 255 {
  148.       (\221 ) dup 1 3 index put
  149.       { token } stopped {
  150.     pop pop
  151.       } {
  152.         % Stack: char () token true
  153.     pop exch pop exch snit 3 1 roll put
  154.       } ifelse
  155.     } for
  156.   } {
  157.     /snit 1 dict def
  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.