home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / GRAPHICS / PSCRIPT / GS241PS.ZIP / GS_FONTS.PS < prev    next >
Encoding:
Text File  |  1992-04-20  |  13.4 KB  |  441 lines

  1. %    Copyright (C) 1990, 1992 Aladdin Enterprises.  All rights reserved.
  2. %    Distributed by Free Software Foundation, Inc.
  3. %
  4. % This file is part of Ghostscript.
  5. %
  6. % Ghostscript is distributed in the hope that it will be useful, but
  7. % WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  8. % to anyone for the consequences of using it or for whether it serves any
  9. % particular purpose or works at all, unless he says so in writing.  Refer
  10. % to the Ghostscript General Public License for full details.
  11. %
  12. % Everyone is granted permission to copy, modify and redistribute
  13. % Ghostscript, but only under the conditions described in the Ghostscript
  14. % General Public License.  A copy of this license is supposed to have been
  15. % given to you along with Ghostscript so you can know your rights and
  16. % responsibilities.  It should be in a file named COPYING.  Among other
  17. % things, the copyright notice and this notice must be preserved on all
  18. % copies.
  19.  
  20. % Font initialization for Ghostscript.
  21.  
  22. % Ghostscript fonts have essentially the same contents as Adobe Type 1 fonts,
  23. % except that the external form doesn't use eexec encryption.
  24. % Someday there will be GNU documentation that describes this format.
  25. % Until then, you'll have to either get a copy of Adobe's book, or read
  26. % the Ghostscript code.  The interpreter for Type 1 fonts, which reveals
  27. % most of their structure, is in the file gstype1.c.
  28.  
  29.  
  30. % Define the default font.
  31. /defaultfontname /Ugly def
  32.  
  33. % Put an entry into a dictionary, with automatic expansion.
  34. /.xput
  35.  { 2 index length 3 index maxlength eq
  36.     { 3 copy pop known not
  37.        { 2 index dup length 3 mul 2 idiv 1 add setmaxlength
  38.        } if
  39.     } if
  40.    put
  41.  } bind def
  42.  
  43. % Internal procedure to load the font name -> font file name map
  44. % if it isn't loaded already, and push it on the stack.
  45. /Fontmap
  46.  { /FontFileMap where
  47.     { /FontFileMap get }
  48.     { (Fontmap) findlibfile not
  49.        { (Can't find ) print print (!\n) print stop }
  50.       if exch pop
  51.  
  52.       FontDirectory maxlength dict exch
  53.       2 dict begin
  54.         mark exch 2 index exch
  55.     /;
  56.      { % The stack contains a mark, the dictionary, the font name,
  57.        % the file name, and additional information about the font.
  58.        counttomark 3 sub { pop } repeat .xput
  59.        1 index
  60.      } bind def
  61.     run
  62.       end
  63.       pop pop        % pop the mark and the copy of the dictionary
  64.       userdict exch /FontFileMap exch put
  65.       FontFileMap
  66.      }
  67.    ifelse
  68.  } bind def
  69.  
  70.  
  71. % Ghostscript optionally can load individual CharStrings as they are needed.
  72. % (This is intended primarily for machines with very small memories.)
  73. % This happens if DISKFONTS is true.  In this case, we define another
  74. % dictionary parallel to FontDirectory that retains an open file
  75. % for every font loaded.
  76. DISKFONTS
  77.  { /FontFileDirectory FontDirectory maxlength dict def
  78.  }
  79. if
  80.  
  81.  
  82. % Define definefont.  This is a procedure built on an operator that
  83. % does all the error checking and key insertion.
  84. /.buildfontdict 3 dict
  85.     /.buildfont0 where { pop dup 0 /.buildfont0 load put } if
  86.     /.buildfont1 where { pop dup 1 /.buildfont1 load put } if
  87.     /.buildfont3 where { pop dup 3 /.buildfont3 load put } if
  88. def
  89. /definefont
  90.  { 1 dict begin count /d exch def    % save stack depth in case of error
  91.     { dup /FontType get .buildfontdict exch get exec
  92.       DISKFONTS
  93.        { FontFileDirectory 2 index known
  94.           { dup /FontFile FontFileDirectory 4 index get put
  95.       }
  96.      if
  97.        }
  98.       if
  99.       readonly
  100.     }
  101.    stopped
  102.     { count d sub { pop } repeat end /invalidfont signalerror }
  103.     { end dup FontDirectory 4 2 roll .xput }
  104.    ifelse
  105.  } odef
  106.  
  107.  
  108. % Ghostscript optionally can load individual CharStrings as they are needed.
  109. % (This is intended primarily for machines with very small memories.)
  110. % Initially, the character definition is the file position of the definition;
  111. % this gets replaced with the actual CharString.
  112. % Note that if we are loading characters lazily, CharStrings is writable.
  113.  
  114. % _Cstring must be long enough to hold the longest CharString for
  115. % a character defined using seac.  This is lenIV + 4 * 5 (for the operands
  116. % of sbw, assuming div is not used) + 2 (for sbw) + 3 * 5 (for the operands
  117. % of seac other than the character codes) + 2 * 2 (for the character codes)
  118. % + 2 (for seac), i.e., lenIV + 43.
  119.  
  120. /_Cstring 60 string def
  121.  
  122. % When we initially load the font, we call
  123. %    <index|charname> <length> /readstring|/readhexstring skip_C
  124. % to skip over each character definition and return the file position instead.
  125. % This substitutes for the procedure
  126. %    <length> string currentfile exch read[hex]string pop
  127. % What we actually store is fileposition * 1000 + length,
  128. %   negated if the string is stored in binary form.
  129.  
  130. /skip_C
  131.  { load exch dup 1000 ge 3 index type /nametype ne or
  132.     { % This is a Subrs string, or the string is so long we can't represent
  133.       % its length.  Load it now.
  134.       currentfile 3 1 roll string exch exec pop
  135.     }
  136.     { % Record the position and length, and skip the string.
  137.       dup currentfile fileposition 1000 mul add
  138.       2 index /readstring load eq { neg } if
  139.       3 1 roll
  140.       dup _Cstring length idiv
  141.        { currentfile _Cstring 3 index exec pop pop
  142.        } repeat
  143.       _Cstring length mod _Cstring exch 0 exch getinterval
  144.       currentfile exch 3 -1 roll exec pop pop
  145.     }
  146.    ifelse
  147.  } bind def
  148.  
  149. % Type1BuildChar calls load_C to actually load the character definition.
  150.  
  151. /load_C        % charindex fileposandlength ->
  152.  { exch Encoding exch get exch
  153.    read_C type1addpath
  154.  } bind def
  155.  
  156. /read_C        % charname fileposandlength -> charstring
  157.  { dup abs 1000 idiv FontFile exch setfileposition
  158.    CharStrings 3 1 roll
  159.    dup 0 lt
  160.     { neg 1000 mod string FontFile exch readstring }
  161.     { 1000 mod string FontFile exch readhexstring }
  162.    ifelse pop
  163.    dup 4 1 roll put
  164. % If the character is defined with seac, load its components now.
  165.    dup mark exch seac_C
  166.    counttomark
  167.     { StandardEncoding exch get dup CharStrings exch get
  168.       dup type /integertype eq { read_C } { pop } ifelse pop
  169.     } repeat
  170.    pop        % the mark
  171.  } bind def
  172.  
  173. /seac_C        % charstring -> achar bchar ..or nothing..
  174.  { dup length _Cstring length le
  175.     { 4330 exch _Cstring type1decrypt exch pop
  176.       dup dup length 2 sub 2 getinterval <0c06> eq    % seac
  177.        { dup length
  178.          Private /lenIV known { Private /lenIV get } { 4 } ifelse
  179.      exch 1 index sub getinterval
  180. % Parse the string just enough to extract the seac information.
  181. % We assume that the only possible operators are hsbw, sbw, and seac,
  182. % and that there are no 5-byte numbers.
  183.      mark 0 3 -1 roll
  184.       { exch
  185.          { { dup 32 lt
  186.               { pop 0 }
  187.           { dup 247 lt
  188.              { 139 sub 0 }
  189.              { dup 251 lt
  190.             { 247 sub 256 mul 108 add 1 1 }
  191.             { 251 sub -256 mul -108 add -1 1 }
  192.                ifelse
  193.              }
  194.             ifelse
  195.           }
  196.          ifelse
  197.            }            % 0
  198.            { mul add 0 }        % 1
  199.          }
  200.         exch get exec
  201.       }
  202.      forall pop
  203.      counttomark 1 add 2 roll cleartomark    % pop all but achar bchar
  204.        }
  205.        { pop    % not seac
  206.        }
  207.       ifelse
  208.     }
  209.     { pop    % punt
  210.     }
  211.    ifelse
  212.  } bind def
  213.  
  214. % Define an auxiliary procedure for loading a font.
  215. % If DISKFONTS is true:
  216. %    - Prevent the CharStrings from being made read-only.
  217. %    - Substitute a different CharString-reading procedure.
  218. % If the body of the font is encrypted with eexec, this is disabled,
  219. % because the implicit 'systemdict begin' hides the redefinitions.
  220. % We assume that:
  221. %    - The magic procedures (-|, -!, |-, and |) are defined with
  222. %    executeonly or readonly;
  223. %    - The contents of the reading procedures are as defined in bdftops.ps;
  224. %    - The font ends with
  225. %    <font> <Private> <CharStrings>
  226. %    readonly put noaccess|readonly put
  227. 4 dict begin
  228.  /dict            % leave room for FontFile
  229.   { 1 add dict
  230.   } bind def
  231.  /executeonly        % for reading procedures
  232.   { readonly
  233.   } def
  234.  /noaccess        % for Subrs strings and Private dictionary
  235.   { readonly
  236.   } def
  237.  /readonly        % for procedures and CharStrings dictionary
  238.   {    % We want to take the following non-standard actions here:
  239.       %   - If the operand is the CharStrings dictionary, do nothing;
  240.     %   - If the operand is a number (a file position replacing the
  241.     %    actual CharString), do nothing;
  242.     %   - If the operand is either of the reading procedures (-| or -!),
  243.     %    substitute a different one.
  244.     dup type /dicttype eq        % CharStrings or Private
  245.      { 1 index /CharStrings ne { readonly } if }
  246.      { dup type /arraytype eq        % procedure or data array
  247.         { dup length 5 eq 1 index xcheck and
  248.        { dup 0 get /string eq
  249.          1 index 1 get /currentfile eq and
  250.          1 index 2 get /exch eq and
  251.          1 index 3 get dup /readstring eq exch /readhexstring eq or and
  252.          1 index 4 get /pop eq and
  253.           { 3 get cvlit /skip_C cvx 2 packedarray cvx
  254.           }
  255.           { readonly
  256.           }
  257.          ifelse
  258.        }
  259.        { readonly
  260.        }
  261.       ifelse
  262.     }
  263.     { dup type /stringtype eq    % must be a Subr string
  264.        { readonly }
  265.       if
  266.     }
  267.        ifelse
  268.      }
  269.     ifelse
  270.   } bind def
  271. currentdict end /.loadfontdict exch def
  272. /.loadfont        % <file> .loadfont ->
  273.  { mark exch systemdict begin
  274.    DISKFONTS { .loadfontdict begin } if
  275.     % We can't just use `run', because we want to check for
  276.     % .PFB files.  We can't save the packing status anywhere,
  277.     % so we need two separate control paths.
  278.    currentpacking
  279.     { false setpacking
  280.        { dup read not { -1 } if
  281.          2 copy unread 16#80 eq { /PFBDecode filter } if
  282.      cvx exec
  283.        } stopped    % split up `execute'
  284.       true setpacking
  285.       $error /newerror get and {handleerror} if
  286.     }
  287.     {  { dup read not { -1 } if
  288.          2 copy unread 16#80 eq { /PFBDecode filter } if
  289.      cvx exec
  290.        } execute
  291.     }
  292.    ifelse
  293.    DISKFONTS { end } if
  294.    end cleartomark
  295.  } bind def
  296.  
  297. % Define findfont so it tries to load a font if it's not found.
  298. /findfont
  299.  {
  300.     % If the key is a string, convert it to a name for lookup.
  301.     dup type /stringtype eq { cvn } if
  302.  
  303.     % If the font isn't in FontDirectory already, load it.
  304.     dup FontDirectory exch known
  305.      { FontDirectory exch get
  306.      }
  307.      { dup        % save the font name on the stack
  308.  
  309.        % Push the font name -> font file name map on the stack,
  310.        % loading it if necessary.
  311.        Fontmap
  312.  
  313.        % Read the file name from the map.
  314.        % (The stack contains the font name and the font file map.)
  315.        1 index known not
  316.         { QUIET not
  317.            { (Substituting ) print defaultfontname cvx =only
  318.              ( for unknown font ) print == flush
  319.            } { pop } ifelse
  320.           pop defaultfontname findfont
  321.         }
  322.         { dup Fontmap exch get
  323.  
  324.           % If we can't find the file, substitute for the font.
  325.           findlibfile
  326.            { DISKFONTS
  327.               { 1 index (r) file
  328.             FontFileDirectory exch 4 index exch .xput
  329.           }
  330.              if
  331.              QUIET not
  332.           { (Loading ) print 2 index =only
  333.             ( font from ) print exch print (... ) print flush }
  334.           { exch pop }
  335.          ifelse exch pop
  336.          .loadfont
  337.          QUIET not
  338.           { vmstatus 3 { =only ( ) print } repeat
  339.             (done.\n) print flush
  340.           } if
  341.          % Check to make sure the font was actually loaded.
  342.          dup FontDirectory exch known
  343.           { findfont
  344.           }
  345.           { (Loading ) print cvx =only
  346.             ( font failed, substituting )print defaultfontname cvx =only
  347.             (.\n) print flush
  348.             defaultfontname findfont
  349.           }
  350.          ifelse
  351.            }
  352.            { 1 index defaultfontname eq
  353.           { (Can't find default font!\n) print
  354.             pop pop NullFont
  355.           }
  356.           { (Can't find font file ) print print
  357.             (, substituting ) print defaultfontname cvx =only
  358.             (.\n) print flush
  359.             pop pop defaultfontname findfont
  360.           }
  361.          ifelse
  362.            }
  363.           ifelse
  364.         }
  365.        ifelse
  366.  
  367.      } ifelse
  368.  
  369.  } odef % bind def
  370.  
  371.  
  372. % The CharStrings for a Ghostscript font are a dictionary in which
  373. % the key is the character name, and the value is a compressed
  374. % representation of a path, as produced by type1imagepath.
  375. % For detailed information, see the book
  376. % "Adobe Type 1 Font Format", published by Adobe Systems Inc.
  377.  
  378. % Here is the BuildChar implementation
  379. % for Type 1 (Ghostscript standard) fonts.
  380. % The name Type1BuildChar is known to the interpreter.
  381.  
  382. /Type1BuildChar
  383.  { exch begin
  384.     dup Encoding exch get
  385.     dup CharStrings exch known not
  386.      { QUIET not
  387.         { (Substituting .notdef for ) print = flush
  388.     } { pop } ifelse
  389.        /.notdef
  390.      } if
  391.     currentdict /Metrics known
  392.      { dup Metrics exch known
  393.         { dup Metrics exch get .setmetrics } if
  394.      } if
  395.     CharStrings exch get
  396.     PaintType 0 ne
  397.      { 1 setmiterlimit 1 setlinejoin 1 setlinecap
  398.        currentdict /StrokeWidth known { StrokeWidth } { 0 } ifelse
  399.        setlinewidth
  400.      } if
  401.     dup type /stringtype eq        % encoded outline
  402.      { type1addpath pop }        % does a fill or stroke
  403.      { dup type /integertype eq        % file position for lazy loading
  404.         { load_C
  405.     }
  406.     { currentdict end systemdict begin begin
  407.       exec
  408.       end
  409.     }
  410.        ifelse
  411.      }
  412.     ifelse
  413.    end
  414.  } bind def
  415.  
  416. % Find all the precompiled font operators in systemdict.
  417.    systemdict
  418.     { exch =string cvs (.font_) anchorsearch
  419.        { pop pop exec    % execute the operator, returns the font dictionary
  420.          dup begin
  421.        Encoding type /stringtype eq
  422.         { Encoding cvn cvx exec /Encoding exch def
  423.         }
  424.        if
  425.        FontName exch
  426.      end definefont pop
  427.        }
  428.        { pop pop
  429.        }
  430.       ifelse
  431.     }
  432.    forall
  433.  
  434.  
  435.  
  436. % Define a procedure to load all known fonts.
  437. % This isn't likely to be very useful.
  438. /loadallfonts
  439.  { Fontmap { pop findfont pop } forall
  440.  } bind def
  441.