1

I have a file which is attempting to find which font is available to re-encode it for some internal reason (I have no idea why yet, it's just another roll-your-own PS file).

It does this with some logic like:

/Arial 
dup /Font resourcestatus{ pop pop }{ pop /ArialMT }ifelse
dup /Font resourcestatus{ pop pop }{ pop /Helvetica }ifelse 

The intent is that the best available font key is on the stack at the end.

In Ghostscript on Windows this appears to be /Arial (as resourcestatus returns 2). However attempting to find the font results in the common warnings:

Can't find (or can't open) font file %rom%Resource/Font/ArialMT.
Can't find (or can't open) font file ArialMT.
Can't find (or can't open) font file %rom%Resource/Font/ArialMT.
Can't find (or can't open) font file ArialMT.
Querying operating system for font files...
Didn't find this font on the system!
Substituting font Helvetica for ArialMT.

Is it possible to determine the final /Helvetica font key in this situation, before we attempt to use it?

It matters since the substitution process is causing some errors where other embedded fonts go missing. There's surely a bug somewhere causing this but I'm still investigating, and curious anyway.

Nick P
  • 759
  • 5
  • 20

1 Answers1

4

The answer is 'not really'. The font substitution mechanism in Ghostscript is quite complex and involves some heuristics based on the font characteristics. It also dependsw on how you have configured Ghostscript and the fonts installed.

In your specific case you will probably find that there is a definition in fontmap.GS for Arial. In fact the default fontmap.GS includes this:

/Arial /ArialMT ;

However, unless you installed on a Windows system (and used the GS installer to set FontPath) it won't have actually installed a reference for ArialMT. So, since ArialMT isn't defined, it reverts to the 'if all else fails' font, which is Helvetica. Pretty much what you see on the back channel above.

Your best bet for avoiding font substitution problems is to carefully configure fontmap.GS, the version shipped with the Ghostscript sources is an example, its not intended to be used 'as is' on every system.

KenS
  • 30,202
  • 3
  • 34
  • 51
  • Thanks for clearing it up. In this case I am just using the defaults compiled into the Windows version. I'm only investigating how the file is behaving when the font is substituted since it seems to block future fonts from being defined, or something like that. – Nick P Nov 23 '14 at 23:23
  • The font substitution code does not block the definition (or redefinition) of fonts, but of course if a PostScript program tests for a named font's presence before defining it, then it might have that effect. But still, the fonts substitution code won't be blocking anything. – KenS Nov 24 '14 at 07:56
  • If you really want to walk through the arcane font substitution heuristics then you can look at gs_fonts.ps, gs_fapi.ps, gs_fntmem.ps. For CIDFonts you will need to look at gs_cidcm.ps, gs_ciddc.ps, gs_cidfn.ps and gs_cmap.ps. gs_ttf.ps and gs_cidtt.ps are used for direct loading of TrueType fonts, but not substitution. Note, you will need an excellent working knowledge of PostScript to get far with these programs. – KenS Nov 24 '14 at 08:02
  • Thanks Ken - I had a look yesterday and have confirmed I do not have an excellent working knowledge :) The issue is similar to one I raised a while ago at http://stackoverflow.com/questions/18477930/ghostscript-using-a-font-in-a-form-makes-it-unavailable where multiple calls of 'true setglobal execform false setglobal' replace the font definitions, but only if the font was originally substituted. – Nick P Nov 25 '14 at 00:44
  • That one was to do with local/global VM and substituted fonts are defined in local VM as I recall, whereas embedded fonts are defined in the VM mode in force at the time the font is defined. What Distiller does is, of course, up to Distiller. It doesn't have to follow the PostScript rules as closely as we do, because it only converts to PDF. And, to a degree, font substitution is pretty much device specific, interpreters can do more or less what they want. – KenS Nov 25 '14 at 08:11