665 lines · 17.7 KB · Text
RawDownload
%    Copyright (C) 1991, 1995, 1996, 2002 Aladdin Enterprises.  All rights reserved.% % This software is provided AS-IS with no warranty, either express or% implied.% % This software is distributed under license and may not be copied,% modified or distributed except as expressly authorized under the terms% of the license contained in the file LICENSE in this distribution.% % For more information about licensing, please refer to% http://www.ghostscript.com/licensing/. For information on% commercial licensing, go to http://www.artifex.com/licensing/ or% contact Artifex Software, Inc., 101 Lucas Valley Road #110,% San Rafael, CA  94903, U.S.A., +1(415)492-9861. % $Id: wrfont.ps,v 1.5 2002/04/19 06:52:25 lpd Exp $% wrfont.ps% Write out a Type 1 font in readable, reloadable form.% Note that this does NOT work on protected fonts, such as Adobe fonts% (unless you have loaded unprot.ps first, in which case you may be% violating the Adobe license). % ****** NOTE: This file must be kept consistent with gs_pfile.ps. /wrfont_dict 100 dict defwrfont_dict begin % ------ Options ------ % % Define whether to use eexec encryption for the font.% eexec encryption is only useful for compatibility with Adobe Type Manager% and other programs; it only slows Ghostscript down.   /eexec_encrypt false def % Define whether to write out the CharStrings in binary or in hex.% Binary takes less space on the file, but isn't guaranteed portable.   /binary_CharStrings false def % Define whether to use binary token encodings when possible.% Binary tokens are smaller and load faster, but are a Level 2 feature.   /binary_tokens false def % Define whether to encrypt the CharStrings on the file.  (CharStrings% are always encrypted in memory.)  Unencrypted CharStrings load about% 20% slower, but make the files compress much better for transport.   /encrypt_CharStrings true def % Define whether the font must provide standard PostScript language% equivalents for any facilities it uses that are provided in Ghostscript% but are not part of the standard PostScript language.   /standard_only true def % Define the value of lenIV to use in writing out the font.% use_lenIV = 0 produces the smallest output, but this may not be% compatible with old Adobe interpreters.  use_lenIV = -1 means% use the value of lenIV from the font.   /use_lenIV -1 def % Define whether to produce the smallest possible output, relying% as much as possible on Ghostscript-specific support code.% Taking full advantage of this requires the following settings:% binary_CharStrings = true, binary_tokens = true, standard_only = false.   /smallest_output false def % Define whether to write out all currently known Encodings by name,% or only StandardEncoding and ISOLatin1Encoding.   /name_all_Encodings false def % ---------------- Runtime support ---------------- % /.packedfilefilter where { pop } { (gs_pfile.ps) runlibfile }ifelse % ------ Output utilities ------ % % By convention, the output file is named psfile. % Define some utilities for writing the output file.   /wtstring 2000 string def   /wb {psfile exch write} bind def   /wnb {/wb load repeat} bind def   /w1 {psfile exch write} bind def   /ws {psfile exch writestring} bind def   /wl {ws (\n) ws} bind def   /wt {wtstring cvs ws ( ) ws} bind def   /wd		% Write a dictionary.    { dup length wo {dict dup begin} wol { we } forall      {end} wol    } bind def   /wld		% Write a large dictionary more efficiently.   		% Ignore the readonly attributes.    { dup length wo {dict dup begin} wol      0 exch       { exch wo wo () wl	 1 add dup 200 eq	  { wo ({def} repeat) wl 0 }	 if       }      forall      dup 0 ne       { wo ({def} repeat) wl }       { pop }      ifelse      (end) ws    } bind def   /we		% Write a dictionary entry.    { exch wo wo /def cvx wo (\n) ws    } bind def   /wcs		% Write a CharString (or Subrs entry)    { dup type /stringtype eq       { 4330 exch changelenIV 0 ge          {	% Add some leading garbage bytes.	    wtstring changelenIV 2 index length getinterval	    .type1decrypt exch pop	    wtstring exch 0 exch length changelenIV add getinterval	  }	  {	% Drop some leading garbage bytes.	    wtstring .type1decrypt exch pop	    changelenIV neg 1 index length 1 index sub getinterval	  }	 ifelse         binary_tokens encrypt_CharStrings and	  { % Suppress recognizing the readonly status of the string.	    4330 exch dup .type1encrypt exch pop wo	  }	  { encrypt_CharStrings	     { 4330 exch dup .type1encrypt exch pop	     } if	    smallest_output	     { wo	     }	     { readonly dup length wo	       binary_tokens not { ( ) ws } if	       readproc ws wx	     }	    ifelse	  }	 ifelse       }       { wo		% PostScript procedure       }      ifelse    } bind def % Construct the inversion of the system name table.  (\210\001) token pop exch pop 1 eq {	% i.e., do we have binary tokens?    /snit 256 dict def    0 1 255 {      (\221 ) dup 1 3 index put      { token } stopped {	pop pop      } {		% Stack: char () token true	pop exch pop exch snit 3 1 roll put      } ifelse    } for  } {    /snit 1 dict def  } ifelse % Write an object, using binary tokens if requested and possible.   /woa		% write in ascii    { psfile exch write==only    } bind def 			% Lookup table for ASCII output.    /intbytes	% int nbytes -> byte*    { { dup 255 and exch -8 bitshift } repeat pop    } bind def   /wotta 10 dict dup begin      { /booleantype /integertype }      { { ( ) ws woa } def }     forall		% Iterate over arrays so we can print operators.     /arraytype      { dup xcheck {(}) ({)} {(]) ([)} ifelse ws exch dup wol exch ws wop      } bind def     /dicttype      { ( ) ws wd } def     /nametype      { dup xcheck { ( ) ws } if woa      } bind def		% Map back operators to their names,		% so we can write procedures.     /nulltype      { pop ( null) ws      } bind def     /operatortype      { wtstring cvs cvn cvx wo      } bind def		% Convert reals to integers if possible.     /realtype      { dup cvi 1 index eq { cvi wo } { ( ) ws woa } ifelse      } bind def		% == truncates strings longer than 200 characters!     /stringtype      { (\() ws dup	 { dup dup 32 lt exch 127 ge or	    { (\\) ws dup -6 bitshift 48 add w1	      dup -3 bitshift 7 and 48 add w1	      7 and 48 add	    }	    { dup dup -2 and 40 eq exch 92 eq or {(\\) ws} if	    }	   ifelse w1	 }	forall	(\)) ws wop      } bind def     /packedarraytype      { ([) ws dup { wo } forall	encodingnames 1 index known		% This is an encoding, but not one of the standard ones.		% Use the built-in encoding only if it is available.	 { encodingnames exch get wo	   ({findencoding}stopped{pop) ws	   (}{counttomark 1 add 1 roll cleartomark}ifelse)	 }	 { pop ()	 }	ifelse	(/packedarray where{pop counttomark packedarray exch pop}{]readonly}ifelse) ws	wl      }     def   end def 			% Lookup table for binary output.    /wottb 8 dict dup begin   wotta currentdict copy pop     /integertype      { dup dup 127 le exch -128 ge and         { 136 wb 255 and wb }	 { dup dup 32767 le exch -32768 ge and	    { 134 wb 2 intbytes wb wb }	    { 132 wb 4 intbytes wb wb wb wb }	   ifelse	 }	ifelse      } bind def     /nametype      { dup snit exch known         { dup xcheck { 146 } { 145 } ifelse wb	   snit exch get wb	 }	 { wotta /nametype get exec	 }	ifelse      } bind def     /stringtype      { dup dup length dup 255 le { 142 2 } { 2 intbytes 143 3 } ifelse wnb	ws wop      } bind def   end def    /wop		% Write object protection     { wcheck not { /readonly cvx wo } if     } bind def   /wo		% Write an object.     { dup type binary_tokens { wottb } { wotta } ifelse       exch get exec     } bind def   /wol		% Write a list of objects.     { { wo } forall     } bind def % Write a hex string for Subrs or CharStrings.   /wx		% string ->    { binary_CharStrings       { ws       }       { % Some systems choke on very long lines, so	 % we break up the hexstring into chunks of 50 characters.	  { dup length 25 le {exit} if	    dup 0 25 getinterval psfile exch writehexstring (\n) ws	    dup length 25 sub 25 exch getinterval	  } loop	 psfile exch writehexstring       } ifelse    } bind def % ------ CharString encryption utilities ------ % /enc_dict 20 dict def1 dict begin/bind { } def		% make sure we can print out the proceduresenc_dict begin (type1enc.ps) runlibfileenc_dict /.type1decrypt undef		% we don't need this end end enc_dict { 1 index where { pop pop pop } { def } ifelse } forall % ------ Other utilities ------ % % Test whether two values are equal (for default dictionary entries).   /valueeq		% <obj1> <obj2> valueeq <bool>    { 2 copy eq       { pop pop true }       {	% Special hack for comparing FontMatrix values	 dup type /arraytype eq 2 index type /arraytype eq and	  { dup length 2 index length eq	     { true 0 1 3 index length 1 sub		{	% Stack: arr1 arr2 true index		  3 index 1 index get 3 index 3 -1 roll get eq not		   { pop false exit }		  if		}	       for 3 1 roll pop pop	     }	     { pop pop false	     }	    ifelse	  }	  { pop pop false	  }	 ifelse       }      ifelse    } bind def % ------ The main program ------ % % Define the dictionary of keys to skip because they are treated specially./.fontskipkeys mark  /CharStrings dup  /Encoding dup  /FDepVector dup  /FID dup  /FontInfo dup  /Metrics dup  /Metrics2 dup  /Private dup.dicttomark def/.minfontskipkeys mark  .fontskipkeys { } forall  /FontName dup  /UniqueID dup.dicttomark def/.privateskipkeys mark  /ND dup  /NP dup  /RD dup  /Subrs dup.dicttomark def/.minprivateskipkeys mark  .privateskipkeys { } forall  /MinFeature dup  /Password dup  /UniqueID dup.dicttomark def % Define the procedures for the Private dictionary.% These must be defined without `bind',% for the sake of the DISKFONTS feature.4 dict begin /-! {string currentfile exch readhexstring pop} def /-| {string currentfile exch readstring pop} def /|- {readonly def} def /| {readonly put} defcurrentdict end /encrypted_procs exch def4 dict begin /-! {string currentfile exch readhexstring pop   4330 exch dup .type1encrypt exch pop} def /-| {string currentfile exch readstring pop   4330 exch dup .type1encrypt exch pop} def /|- {readonly def} def /| {readonly put} defcurrentdict end /unencrypted_procs exch def % Construct an inverse dictionary of encodings./encodingnames mark StandardEncoding /StandardEncoding ISOLatin1Encoding /ISOLatin1Encoding SymbolEncoding /SymbolEncoding DingbatsEncoding /DingbatsEncoding /resourceforall where  { pop (*) { cvn dup findencoding exch } 100 string /Encoding resourceforall } if.dicttomark def % Invert the standard encodings..knownEncodings length 256 mul dict begin  0 .knownEncodings   {  { currentdict 1 index known { pop } { 1 index def } ifelse	1 add      }     forall   }  forall popcurrentdict end /inverseencodings exch def /writefont		% <psfile> writefont - (writes the current font) { /psfile exch def   /Font currentfont def   /FontInfo Font /FontInfo .knownget not { 0 dict } if def   /FontType Font /FontType get def   /hasPrivate Font /Private known def   /Private hasPrivate { Font /Private get } { 0 dict } ifelse def   /readproc binary_CharStrings { (-| ) } { (-! ) } ifelse def   /privateprocs     encrypt_CharStrings binary_tokens not and      { encrypted_procs } { unencrypted_procs } ifelse     def   /addlenIV false def   /changelenIV use_lenIV 0 lt    { 0 }    { use_lenIV Private /lenIV .knownget not       { 4 /addlenIV use_lenIV 4 ne def } if sub }   ifelse def   /minimize     smallest_output     FontType 1 eq and     Font /UniqueID known and   def   (%!FontType) ws FontType wtstring cvs ws (-1.0: ) ws     currentfont /FontName get wt     FontInfo /version .knownget not { (001.001) } if wl   FontInfo /CreationDate .knownget { (%%Creation Date: ) ws wl } if   FontInfo /VMusage .knownget    { (%%VMusage: ) ws dup wt wtstring cvs wl }   if   (systemdict begin) wl % If we're going to use eexec, create the filters now.   /realpsfile psfile def   eexec_encrypt    { /eexecfilter psfile binary_CharStrings not       { pop /bxstring 35 string def	  { pop dup length 0 ne	     { realpsfile exch writehexstring realpsfile (\n) writestring }	     { pop }	    ifelse bxstring	  }	 /NullEncode filter dup /hexfilter exch def       }      if 55665 /eexecEncode filter def    }   if % Turn on binary tokens if relevant.   binary_tokens { (currentobjectformat 1 setobjectformat) wl } if % If the file has a UniqueID, write out a check against loading it twice.   minimize    { Font /FontName get wo      Font /UniqueID get wo      Private length addlenIV { 1 add } if wo      Font length 1 add wo		% +1 for FontFile      ( .checkexistingfont) wl    }    { Font /UniqueID known       { ({} FontDirectory) ws Font /FontName get dup wo ( known) wl	 ( {) ws wo ( findfont dup /UniqueID known) wl	 (    { dup /UniqueID get) ws Font /UniqueID get wo ( eq exch /FontType get 1 eq and }) wl	 (    { pop false } ifelse) wl	 (    { pop save /restore load } if) wl	 ( } if) wl       }      if    }   ifelse % If we are writing unencrypted CharStrings for a standard environment,% write out the encryption procedures.   privateprocs unencrypted_procs eq standard_only and    { (systemdict /.type1encrypt known) wl      ( { save /restore load } { { } } ifelse) wl      (userdict begin) wl      enc_dict { we } forall      (end exec) wl    }   if % Write out the creation of the font dictionary and FontInfo.   minimize not    { Font length 1 add wo {dict begin} wol		% +1 for FontFile    }   if   (/FontInfo ) ws FontInfo wd {readonly def} wol % Write out the other fixed entries in the font dictionary.   Font begin   Font    { minimize       { .minfontskipkeys 2 index known	  { pop pop	  }	  { //.compactfontdefault 2 index .knownget	     { 1 index valueeq { pop pop } { we } ifelse }	     { we }	    ifelse	  }	 ifelse

Lines 1–500 of 665.