[R] embedding fonts in eps files

(Ted Harding) Ted.Harding at nessie.mcc.ac.uk
Tue Jan 18 12:48:58 CET 2005


On 18-Jan-05 Rudi Alberts wrote:
> Hi,
> 
> I have to make eps files with fonts embedded. 
> I use the following postscript command:
> 
> 
> postscript("fig3a.eps", width = 5.2756, height = 7.27, pointsize =
> 7,horizontal = FALSE, onefile = FALSE, paper = "special",family =
> "Times")
> 
> plot(...)
> 
> dev.off()
> 
> 
> Are fonts automatically embedded in this way?
> How can I see that?
> If not, how to do it?

Well, it seems to have set Times as the working font family
when I used your postscript(...) command above; but see further
down. I viewed the resulting .eps file (using 'less' in Linux
but Windows users should also have some way of looking into a
text file).

The first few lines of the file are:

%!PS-Adobe-3.0 EPSF-3.0
%%DocumentNeededResources: font Times-Roman
%%+ font Times-Bold
%%+ font Times-Italic
%%+ font Times-BoldItalic
%%+ font Symbol
%%Title: R Graphics Output
...

These are so-called DSC ("Document Structuring Conventions")
comments and are not directly executed by whatever renders
the PostScript code. They do, however, provided useful
information for programs which have to handle the PS file.

>From the above, it can be seen that R's postscript() function
has taken note of the 'family="Times"' option.

Further down the .eps file are the lines

%%IncludeResource: font Times-Roman
/Times-Roman findfont
dup length dict begin
  {1 index /FID ne {def} {pop pop} ifelse} forall
  /Encoding ISOLatin1Encoding def
  currentdict
  end
/Font1 exch definefont pop
%%IncludeResource: font Times-Bold
/Times-Bold findfont
dup length dict begin
  {1 index /FID ne {def} {pop pop} ifelse} forall
  /Encoding ISOLatin1Encoding def
  currentdict
  end
/Font2 exch definefont pop
%%IncludeResource: font Times-Italic
/Times-Italic findfont
dup length dict begin
  {1 index /FID ne {def} {pop pop} ifelse} forall
  /Encoding ISOLatin1Encoding def
  currentdict
  end
/Font3 exch definefont pop
%%IncludeResource: font Times-BoldItalic
/Times-BoldItalic findfont
dup length dict begin
  {1 index /FID ne {def} {pop pop} ifelse} forall
  /Encoding ISOLatin1Encoding def
  currentdict
  end
/Font4 exch definefont pop
%%IncludeResource: font Symbol
/Symbol findfont
dup length dict begin
  {1 index /FID ne {def} {pop pop} ifelse} forall
  currentdict
  end
/Font5 exch definefont pop

Apart from the "%%" DSC comments, this is executable PS
code which calls on the interpreter to set up the Times
fonts Times-Roman as Font1, Times-Bold as Font2,
Times-Italic as Font3, Times-BoldItalic as Font4,
and Symbol (not a Times font) as Font5.

If, instead of 'family="Times"', you had used the option
'family="Helvetica"', you would have got (try it and see)
exactly the same with "Helvetica" substituted for "Times"
throughout.

So far so good. Now comes the crunch.

The above (and this is the only part of the .eps file
which has anything to do with setting up fonts) assumes
that the PS interpreter (i.e. the program, including
printer firmware, which renders the PS visible) already
has access to the PostScript definitions of these fonts.

There is a default assumption (not just in R but in
practically any software which outputs PostScript) that
the rendering device will have built-in access to the
"Standard Adobe Font Set" -- a set of 13 fonts comprising
the Times, Helvetica and Courier families, and the Symbol
font, together with the encoding vectors StandardEncoding
and ISOLatin1Encoding; most software also assumes the
presence of further families (typically Bookman, Palatino,
AvantGarde, HelveticaNarrow, ZapfChanceryMediumItalic,
ZapfDingbats). None of these are strictly required by
the specification of the PostScript language, but they
have been a de facto standard for decades and it is most
unusual to find PostScript-generating software which does
not take them for granted (at least the 13 "Standard Adobe"
fonts).

Now "built-in access" means that the rendering device
is already equipped with the PostScript definitions of
how to draw ("render") the characters ("glyphs") in these
various fonts -- e.g. a PostScript printer will have the
definitions internally stored in a ROM chip. Therefore
when the PS definitions of "Font1" etc. as in the above
file are encountered, the device simply hooks its own PS
definitions into the working stack. It is not necessary
to include the definitions in the file which is being
interpreted.

However, to "embed" a font (which is what you refer to
in your query) means to include the PS font definition
in the file itself. This is certainly necessary if you
want to use a "non-standard" font, which might just be
an arty-farty font for English characters (e.g. a fancy
cursive script for greetings cards), or something more
exotic like Cyrillic characters or the International
Phonetic Alphabet. Since PS definitions of such fonts
cannot be expected to be present in a standard PS
rendering device, software which creates files to be
displayed with such fonts must itself have the necessary
resources.

You say you "have to make eps files with fonts embedded."
It would be most unusual to need to embed Times fonts.
Are you using a "non-standard" font family?

As far as I know, R has no provision to embed PS font
definitions in an EPS file. Others may be able to correct
this statement ...

If you do need to embed a PS font, it is not exactly
straightforward to do it "by hand". There is a lot of
stuff that needs to be set up, and one would need to
know more about your environment in order to give any
specific advice.

You ask how you can find out if a font has been embedded.
You need to look through the PS file for stuff like the
following (exemplified for the non-standard font
AGaramond-Regular, the Roman style of Garamond):

%%BeginResource: font AGaramond-Regular
%%CreationDate: Thu Jan 16 17:32:29 1992
%%VMusage: 41576 52468
11 dict begin
/FontInfo 10 dict dup begin
...
/FullName (Adobe Garamond Regular) readonly def
/FamilyName (Adobe Garamond) readonly def
/Weight (Regular) readonly def
/isFixedPitch false def
/ItalicAngle 0 def
/UnderlinePosition -100 def
/UnderlineThickness 50 def
end readonly def
/FontName /AGaramond-Regular def
/Encoding StandardEncoding def
/PaintType 0 def
/FontType 1 def
/FontMatrix [0.001 0 0 0.001 0 0] readonly def
/UniqueID 37598 def
/FontBBox{-183 -269 1099 851}readonly def
currentdict end
currentfile eexec
63c3dc0161e235a2106828042ed9adba0cb00296e1d7da605eb328f0654cec2c
...
[1471 lines of hex-encoded stuff: the PS font definition]
...
0000000000000000000000000000000000000000000000000000000000000000
cleartomark
%%EndResource

The "eexec" instructs the rendering device to decode and
execute the hex-encoded block, after which it then has the
font definition stored in its working memory and available
to be used via "findfont" etc.

Hoping this helps: please supply more specific information
of what you need to do, if you want to follow this up.

Best wishes,
Ted.


--------------------------------------------------------------------
E-Mail: (Ted Harding) <Ted.Harding at nessie.mcc.ac.uk>
Fax-to-email: +44 (0)870 094 0861  [NB: New number!]
Date: 18-Jan-05                                       Time: 11:48:58
------------------------------ XFMail ------------------------------




More information about the R-help mailing list