ref: 47ec5de29e56c4cf223e0582b930b88ca2a589ee
dir: /sys/src/cmd/gs/lib/gs_diskf.ps/
% Copyright (C) 1996 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: gs_diskf.ps,v 1.4 2002/02/21 21:49:28 giles Exp $ % Support for converting Type 1 fonts without eexec encryption to % Type 4 fonts that load individual character outlines on demand. % If DISKFONTS is true, we load individual CharStrings as they are needed. % (This is intended primarily for machines with very small memories.) % Initially, the character definition is the file position of the definition; % this gets replaced with the actual CharString. % Note that if we are loading characters lazily, CharStrings is writable. % _Cstring must be long enough to hold the longest CharString for % a character defined using seac. This is lenIV + 4 * 5 (for the operands % of sbw, assuming div is not used) + 2 (for sbw) + 3 * 5 (for the operands % of seac other than the character codes) + 2 * 2 (for the character codes) % + 2 (for seac), i.e., lenIV + 43. /_Cstring 60 string def % When we initially load the font, we call % <index|charname> <length> <readproc> cskip_C % to skip over each character definition and return the file position instead. % This substitutes for the procedure % <index|charname> <length> string currentfile exch read[hex]string pop % [encrypt] % What we actually store in the CharString is fileposition * 1000 + length, % negated if the string is stored in binary form. /cskip_C { exch dup 1000 ge 3 index type /nametype ne or { % This is a Subrs string, or the string is so long we can't represent % its length. Load it now. exch exec } { % Record the position and length, and skip the string. dup currentfile fileposition 1000 mul add 2 index 3 get /readstring cvx eq { neg } if 3 1 roll dup _Cstring length idiv { currentfile _Cstring 3 index 3 get exec pop pop } repeat _Cstring length mod _Cstring exch 0 exch getinterval currentfile exch 3 -1 roll 3 get exec pop pop } ifelse } bind def % Load a CharString from the file. The font is the top entry % on the dictionary stack. /load_C % <charname> <fileposandlength> load_C - { dup abs 1000 idiv FontFile exch setfileposition CharStrings 3 1 roll .currentglobal CharStrings .gcheck .setglobal exch dup 0 lt { neg 1000 mod string FontFile exch readstring } { 1000 mod string FontFile exch readhexstring } ifelse pop exch .setglobal % If the CharStrings aren't encrypted on the file, encrypt now. Private /-| get 0 get dup type /nametype ne { dup length 5 sub 5 exch getinterval exec } { pop } ifelse dup 4 1 roll put % If the character is defined with seac, load its components now. mark exch seac_C counttomark { StandardEncoding exch get dup CharStrings exch get dup type /integertype eq { load_C } { pop pop } ifelse } repeat pop % the mark } bind def /seac_C % <charstring> seac_C <achar> <bchar> ..or nothing.. { dup length _Cstring length le { 4330 exch _Cstring .type1decrypt exch pop dup dup length 2 sub 2 getinterval <0c06> eq % seac { dup length Private /lenIV known { Private /lenIV get } { 4 } ifelse exch 1 index sub getinterval % Parse the string just enough to extract the seac information. % We assume that the only possible operators are hsbw, sbw, and seac, % and that there are no 5-byte numbers. mark 0 3 -1 roll { exch { { dup 32 lt { pop 0 } { dup 247 lt { 139 sub 0 } { dup 251 lt { 247 sub 256 mul 108 add 1 1 } { 251 sub -256 mul -108 add -1 1 } ifelse } ifelse } ifelse } % 0 { mul add 0 } % 1 } exch get exec } forall pop counttomark 1 add 2 roll cleartomark % pop all but achar bchar } { pop % not seac } ifelse } { pop % punt } ifelse } bind def % Define replacement procedures for loading fonts. % If DISKFONTS is true and the body of the font is not encrypted with eexec: % - Prevent the CharStrings from being made read-only. % - Substitute a different CharString-reading procedure. % (eexec disables this because the implicit 'systemdict begin' hides % the redefinitions that make the scheme work.) % We assume that: % - The magic procedures (-|, -!, |-, and |) are defined with % executeonly or readonly; % - The contents of the reading procedures are as defined in bdftops.ps; % - The font includes the code % <font> /CharStrings <CharStrings> readonly put /.loadfontdict 6 dict def mark /begin % push this dict after systemdict { dup begin //systemdict eq { //.loadfontdict begin } if } bind /end % match begin { currentdict end //.loadfontdict eq currentdict //systemdict eq and { end } if } bind /dict % leave room for FontFile, BuildChar, BuildGlyph { 3 add dict } bind /executeonly % for reading procedures { readonly } /noaccess % for Subrs strings and Private dictionary { readonly } /readonly % for procedures and CharStrings dictionary { % We want to take the following non-standard actions here: % - If the operand is the CharStrings dictionary, do nothing; % - If the operand is a number (a file position replacing the % actual CharString), do nothing; % - If the operand is either of the reading procedures (-| or -!), % substitute a different one. dup type /dicttype eq % CharStrings or Private count 2 gt and { 1 index /CharStrings ne { readonly } if } { dup type /arraytype eq % procedure or data array { dup length 5 ge 1 index xcheck and { dup 0 get /string eq 1 index 1 get /currentfile eq and 1 index 2 get /exch eq and 1 index 3 get dup /readstring eq exch /readhexstring eq or and 1 index 4 get /pop eq and { /cskip_C cvx 2 packedarray cvx } { readonly } ifelse } { readonly } ifelse } { dup type /stringtype eq % must be a Subr string { readonly } if } ifelse } ifelse } bind /definefont % to insert BuildChar/Glyph and change FontType { dup /FontType get 1 eq { dup /FontType 4 put dup /BuildChar /build_C load put dup /BuildGlyph /build_C load put } if definefont } bind counttomark 2 idiv { .loadfontdict 3 1 roll put } repeat pop .loadfontdict readonly pop % Define the BuildChar and BuildGlyph procedures for modified fonts. % A single procedure serves for both. /build_C % <font> <code|name> build_C - { 1 index begin dup dup type /integertype eq { Encoding exch get } if % Stack: font code|name name dup CharStrings exch .knownget not { 2 copy eq { exch pop /.notdef exch } if QUIET not { (Substituting .notdef for ) print = flush } { pop } ifelse /.notdef CharStrings /.notdef get } if % Stack: font code|name name charstring dup type /integertype eq { load_C end build_C } { end .type1execchar } ifelse } bind def