%!PS-GhostScript-2.6.1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %!PS-GhostScript-3.12 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % File: psfstat.ps % % % % This PostScript program calculate fonts and characters used % % in PostScript file loaded after this. % % This program usefull for make partial font DownLoading... % % % % Usage: % % gs -DNODISPLAY -DWRITESYSTEMDICT % % -I... (must be synchronized with SubFont path) % % -sRESIDENTFONTS=file_name_with_list_of_printer_fonts % % -sINFILE=file_name_of_the_user_PostScript_file % % -sOUTFILE=file_name_for_output_font/char_using_statistics % % psfstat.ps quit.ps % % % % Result: % % If all right, It generates OUTFILE which contains names of fonts% % and required glyph names. % % Zero length file mean that all fonts already in file. % % OUTFILE absense means that some error was accured % % in processing time. Typically, PS files refers to such fonts % % which have no in file and not accesible by GS. % % % % Date: 5-Dec-1994 % % % % Copyright (C) 1994 Basil K. Malyshev. All rights reserved. % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /usrdef { userdict begin def end } bind def /sysdef { systemdict begin odef end } bind def /savdef { load systemdict begin def end } bind def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % USAGE % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /usage { (Usage:\n) print ( gs -q -DWRITESYSTEMDICT -DNODISPLAY psfstat.ps \n) print stop } bind def %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Check SYSTEMDICT write permission and disable all access checks. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% systemdict dup wcheck not { usage } if begin /readonly { } odef /executeonly { } odef /noaccess { } odef end /readonly { } odef /executeonly { } odef /noaccess { } odef %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Statistic collection routines .... % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /PSF-Stat 100 dict def % Dictionary with statistics ... /PSF-CurFont null def % No Any current font there /Create-Font-Stat-Pool { 256 dict % Dictionary with charstrings ... } bind def /Use-Font % Select current font ... { % (Call Use-Font\n) print pstack dup /FontType get 1 eq { % { dup /OrigFont known { /OrigFont get } { exit } ifelse } loop % /FontName get % Name of original font there ... /FontInfo get /FullName get cvn dup PSF-Stat exch known { PSF-Stat exch get } { Create-Font-Stat-Pool PSF-Stat 2 index 2 index put exch pop } ifelse } { % Don't try collect statistics for NOT Type1 fonts. pop null % discard dictionary, and fill NONE font identifier ... } ifelse /PSF-CurFont exch usrdef % (End of Call Use-Font\n) print pstack } bind sysdef /Use-Character { PSF-CurFont dup null eq { pop (Calling font using routines (i.e. `show') before font selection\n) print (Refer to character ) print (....) cvs print (\n) print } { begin currentfont /Encoding get exch get 1 def end } ifelse } bind sysdef %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Save original system command and redefine it by self hacks % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /Native-show /show savdef /Native-charpath /charpath savdef /Native-widthshow /widthshow savdef /Native-awidthshow /awidthshow savdef /Native-ashow /ashow savdef /Native-setfont /setfont savdef /Native-showpage /showpage savdef /Native-findfont /findfont savdef % This important routine dump marking of the font preloading % and font full names ... /Can-not-find-font { (Can not find font ) print (...........................................) cvs print (\n Process will be terminated in this reason...\n) print psfsFile closefile OUTFILE deletefile % File absence denotes some error... quit } bind def %%% Load map of our ATM compatible Type1 fonts. %%% Load our map into separate dictionary (PSF-Fontmap) /PSF-Fontmap 512 dict def PSF-Fontmap begin /; { def } bind def (Fontmap.t1) findlibfile { closefile run % exch pop .loadFontmap % It is run in GS2.61 and GS3.12 } { pop (I can not found Type 1 fonts specific map Fontmap.t1\n) print (It is probabbly error, but I will continue...\n) print } ifelse currentdict /; undef end %%% Load list of resident fonts now .... /ResidentFonts 100 dict def systemdict /RESIDENTFONTS known { % load list of resident fonts RESIDENTFONTS findlibfile { % Load all described fonts... { % Read line by line in loop dup (....................................) readline not { pop exit } if cvn ResidentFonts begin true def end } loop closefile } if pop } if % In this dictionary is stored already prepared fonts to % avoid recursion effects which is appeared in GS 3.12 /findfontCalledOn 100 dict def /findfont { findfontCalledOn 1 index known { Native-findfont } { findfontCalledOn begin dup true def end (/) psfsWrite dup (........................................) cvs psfsWrite dup FontDirectory exch known { % Font exists in DontDirectory, this means that it is already preloaded ... ( true ) psfsWrite Native-findfont } { % Font yet not loaded, There I will try to load it ... ( false ) psfsWrite dup ResidentFonts exch known { Native-findfont } { dup PSF-Fontmap exch known { dup PSF-Fontmap exch get findlibfile {.loadfont pop} {Can-not-find-font} ifelse } { dup Fontmap exch known { dup Fontmap exch get findlibfile {.loadfont pop} {Can-not-find-font} ifelse } { Can-not-find-font } ifelse } ifelse Native-findfont } ifelse } ifelse dup /FontInfo get /FullName get (\() psfsWrite psfsWrite (\) psfsAlias\n) psfsWrite } ifelse } bind sysdef % bind systemdict begin def end % sysdef /show { PSF-CurFont null ne { dup { Use-Character } forall } if Native-show } bind sysdef /charpath { PSF-CurFont null ne { 1 index { Use-Character } forall } if Native-charpath } bind sysdef /ashow % ax ay string ashow - { PSF-CurFont null ne { dup { Use-Character } forall } if Native-ashow } bind sysdef /awidthshow % cx cy char ax ay string awidthshow - { PSF-CurFont null ne { dup { Use-Character } forall } if Native-awidthshow } bind sysdef /widthshow % cx cy char string widthshow - { PSF-CurFont null ne { dup { Use-Character } forall } if Native-widthshow } bind sysdef /setfont { % (call setfont\n) print pstack dup Use-Font Native-setfont } bind sysdef /showpage { Print-Stat Native-showpage } bind sysdef %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Routines for output statistics ... % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /Print-Stat { PSF-Stat { % Prepare font name ... (\() psfsWrite exch (.........1.........2.........3.........4) cvs psfsWrite (\) cvn [ ) psfsWrite % Prepare statistics ... { pop (/) psfsWrite (.............................) cvs psfsWrite } forall (] psfsChars\n) psfsWrite } forall } bind sysdef /Native-restore /restore load def /restore { Print-Stat Native-restore } bind sysdef %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % To avoid destruction our hacks Close up systemdict % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% systemdict readonly pop /psfsFile OUTFILE (w) file def /psfsWrite { dup print psfsFile exch writestring } bind sysdef %%% Now executes user file { INFILE run } stopped { % There is error, finish process with removing output file ... psfsFile closefile OUTFILE deletefile % handleerror % command run already calls this ... quit } if % Load raw statistic file, that will remove duplicate refernces. /PSF-Loaded 100 dict def % List of loaded fonts ... /PSF-Alias 100 dict def /psfsChars { PSF-Stat 2 index known not { PSF-Stat 2 index 256 dict put } if exch PSF-Stat exch get begin { 1 def } forall end } bind def /psfsAlias { % Check, if alias yet not exists put it into dictionary ... cvn dup PSF-Alias exch known not { PSF-Alias exch 3 index put { % Mark this font as already loaded ... dup PSF-Loaded exch true put } if pop } { pop pop pop } ifelse } bind def psfsFile closefile (ReLoad file ... \n) print OUTFILE run % % There are fonts which share CharaterStrings. % For example Univers & Univer-Oblique fonts. % In this reason Univers-Oblique font contains Univers font. % In this reason we have list of such fonts check that used both % and in this case redirect request from first font to second. % So, if PS files uses both Univers and Univers-Oblique fonts % all references to Univers font will be replaced by references % to Univers-Oblique. % % NOTE. There is list of fonts of the Univers family ! % One, before installing this tool, must detect such fonts % and expand this list... % The most simplest method to detect such fonts is to call: % t1disasm font-file | grep FontName % So in case of normal font (Univers) you will see: % /FontName /Univers def % dup/FontName get exch definefont pop % but the same command for font Univers-Oblique will outputs: % /FontName /Univers-Oblique def % /FontName /Univers def % dup/FontName get exch definefont pop % dup/FontName get exch definefont pop % So, one can see that Univers-Oblique font contains Univers font. % /BiFontList 20 dict begin /Univers /Univers-Oblique def /Univers-Black /Univers-BlackOblique def /Univers-Bold /Univers-BoldOblique def /Univers-CondensedBold /Univers-CondensedBoldOblique def /Univers-CondensedLight /Univers-CondensedLightOblique def /Univers-Condensed /Univers-CondensedOblique def /Univers-Light /Univers-LightOblique def currentdict end def BiFontList { PSF-Stat 1 index known 2 index PSF-Stat exch known and { % Redirect first font references into second font PSF-Stat exch get begin dup PSF-Stat exch get { def } forall end PSF-Stat exch undef } { pop pop } ifelse } forall % Write back prepared statistic ... /psfsFile OUTFILE (w) file def PSF-Loaded { ==only == } forall PSF-Stat { % Prepare font name ... exch PSF-Alias exch get dup PSF-Loaded exch known not 1 index ResidentFonts exch known not and { (.........1.........2.........3.........4) cvs psfsWrite % Write list of used characters { pop (/) psfsWrite (..........................) cvs psfsWrite } forall (/\n) psfsWrite } { pop pop } ifelse } forall psfsFile closefile quit %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % End of file `psfstat.ps' % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%