[comp.fonts] Type 1 Macintosh to PC conversion

jaglowsk@galaxy.cps.msu.edu (David R Jaglowski) (04/04/91)

A summary of my experience with the Adobe Type 1 fonts:

Supplies you will need:
Adobe Type 1 font format specification:
     I got mine from ps-file-server@adobe.com
     use Subject: send Documents supportingfonts.ps
UN-ADOBE.HQX software for the Macintosh - availible on any Info-MAC
     server such as wuarchive (128.252.135.4 in /mirrors/info-mac/util)
Turbo Pascal v4.0+ in order to use the source code included in this
     document.

The Macintosh Adobe format files (8 bit ASCII as in the Type 1 specs)
need to be converted to 7 bit ASCII files as described in the specs. I
used the UN-ADOBE program to do this.

Both the UN-ADOBEd font file and the accompaning .AFM files that came
with your font package should be ported to the IBM through some kind of
CR to CR/LF filter (I used Apple File Exchange, Text filer. Set CR to
CR/LF on, Special characters Neither, Tab expansion Off).

One note: After you get the files to the PC (or on the Macintosh before
translation), the fonts I had needed to have the header changed in order
to download correctly or some similar problem (from the discussion on
WFNBoss, a la Corel Draw 2.0 and it's various bugs). The ones that need
to be changed have the lead line:

%!PS-AdobeFont-1.0

and need to be changed to:

%!PS-AdobeFont-1.0: <fontname> <fontversion>

With this EXACT spacing. For example:

%!PS-AdobeFont-1.0: Courier-BoldOblique 001.002

Get the fontname from the "/FontName" line of the font file and the
version from the "/version" line of the font file...

Once the file is edited and on the IBM PC, rename all of the font files
(the UN-ADOBE files, not the .AFM files) to "name.HEX" - this is the
file that my conversion program looks for. I put one blessing in this
program - It will process every .HEX file in the current directory and
save the IBM PC format font file to "name.PFB" automatically.

The final step in this process (long, isn't it? This is the only method
I've found that positively won't mess up or drop characters, change the
font file header, or mess with the spacing of the font, however, so I
think it is worth it.) is to build the .INF file needed by the program
MAKEPFM.EXE (Included with the Adobe Plus Pack) or automatically used
and included in Adobe Type Manager (when you use "Add" in the ATM
control panel, it will build a .PFM metrics file if it has the
.PFB,.AFM, and .INF files available.) There are five critical lines to
the .INF file - the others deal with PCL printers and Non-Windows
software - I have no experience with these). These are:

CapHeight xxx
Serif xxxxx
Pi xxxxx
MSMenuName (xxxxxxxxx)
VPStyle (x)

I'm not sure if they are case sensitive or not - this is the
capitalization used with the .INF files in the Adobe Plus Pack. 

CapHeight is a number you can get from most .AFM files - the symbol
files such as Zapf Dingbats don't seem to include this so I used the
size of Zapf Dingbats - 692.

Serif is set to either true or false depending upon if it is a serif
font or not (I'm guessing here) and doesn't seem to have an effect upon
the look of the font - for the curious it toggles a byte at hex location
5A in the .PFM metrics file and doesn't seem to effect the kerning
pairs.

Pi is set to true or false depending upon if it is a Pi face (Universal
Greek and Math Pi) or a symbol face (Carta, etc.) - this is also a
guess. I don't have any Pi faces or symbol faces other than Carta. It is
set to true in Zapf Dingbats and nowhere else in the Plus Pack fonts.

MSMenuName is the font name that will appear under for the font under
Windows. It can have spaces, etc.

VPStyle is the font attribute.
     N,B,I,T - Normal, Bold, Italic, BoldItalic

Example:

CapHeight 692
Serif false
Pi true
MSMenuName (Carta)
VPStyle (N)

Note: The .AFM, .INF, and .PFB files must all have the same name, with
these extensions.

Note: If you let Adobe Type Manager make the .PFM metrics files from
these you may get messages "Unable to parse xxxxxxxx.INF" on some of the
faces, this is apparently a bug - "Add" these fonts again individually
again and they will install correctly.

Now you have a working Adobe Type 1 font in PC format - Good luck.

Note: The files that you convert in this manner are not PD. They are
still the property of Adobe and you should not remove their copywrite
notice from the header. From what one of the Adobe reps has said on the
group earlier, I gather that it is legal for you to convert Macintosh
faces that you own for use on your PC. Please only use this utility on
fonts that you own - By supplying this utility/compiling this process I
really don't want to abuse Adobe's generosity at making their techical
specs availible to developers. A designer spent MANY hours working on
the faces you use and deserves the royalties/whatever.

-------------------------------------------------------------
Cut HERE: Turbo Pascal v4.0+ source for HEX2PFM.EXE
The line UNTIL (data='00000000000000000000000000000000000 etc'
was split in the upload, you must rejoin it.
-------------------------------------------------------------

PROGRAM MakePFB;
Uses Dos;
 
VAR
usefile: SearchRec;
 
PROCEDURE ConvertFile;
 
VAR
source   : Text;
dest     : File of Char;
name     : String[12];
data     : String[255];
counter  : Byte;
temp     : Array[1..4] of Char;
position1: Longint;
position2: Longint;
position3: Longint;
chksum   : Array[1..4] of Byte;
 
BEGIN
  Assign (source,usefile.name);
  Reset (source);
  name:=usefile.name;
  IF (Pos('.',name)>10) THEN
    Insert ('.PFB',name,9)
  ELSE
    Insert ('.PFB',name,Pos('.',name));
  Assign (dest,name);
  Rewrite (dest);
  temp[1]:=Chr(128);
  temp[2]:=Chr(1);
  temp[3]:=Chr(0);
  temp[4]:=Chr(13);
  Write (dest,temp[1],temp[2],temp[3],temp[3],temp[3],temp[3]);
  REPEAT
    Readln (source,data);
    FOR counter:=1 TO Length(data) DO
      Write (dest,data[counter]);
    Write (dest,temp[4])
  UNTIL (Pos('currentfile eexec',data)<>0);
  position1:=FilePos(dest);
  position2:=position1-6;
  chksum[4]:=position2 DIV 16777216;
  position2:=position2-chksum[4]*16777216;
  chksum[3]:=position2 DIV 65536;
  position2:=position2-chksum[3]*65536;
  chksum[2]:=position2 DIV 256;
  position2:=position2-chksum[2]*256;
  chksum[1]:=position2;
  temp[1]:=chr(chksum[1]);
  temp[2]:=chr(chksum[2]);
  temp[3]:=chr(chksum[3]);
  temp[4]:=chr(chksum[4]);
  Seek (dest,2);
  Write (dest,temp[1],temp[2],temp[3],temp[4]);
  Seek (dest,position1);
  temp[1]:=chr(128);
  temp[2]:=chr(2);
  temp[3]:=chr(0);
  Write (dest,temp[1],temp[2],temp[3],temp[3],temp[3],temp[3]);
  Readln (source,data);
  REPEAT
    counter:=1;
    While (counter<Length(data)) DO
      BEGIN
        chksum[1]:=Ord(data[counter]);
        chksum[2]:=Ord(data[counter+1]);
        IF chksum[1]>64 THEN
          chksum[1]:=chksum[1]-7;
        IF chksum[2]>64 THEN
          chksum[2]:=chksum[2]-7;
        chksum[1]:=chksum[1]-48;
        chksum[2]:=chksum[2]-48;
        chksum[3]:=(chksum[1]*16)+chksum[2];
        temp[1]:=Chr(chksum[3]);
        Write (dest,temp[1]);
        counter:=counter+2;
      END;
    Readln (source,data);
  UNTIL
(data='0000000000000000000000000000000000000000000000000000000000000000');
  position3:=FilePos(dest);
  position2:=position3-position1;
  chksum[4]:=position2 DIV 16777216;
  position2:=position2-chksum[4]*16777216;
  chksum[3]:=position2 DIV 65536;
  position2:=position2-chksum[3]*65536;
  chksum[2]:=position2 DIV 256;
  position2:=position2-chksum[2]*256;
  chksum[1]:=position2;
  temp[1]:=chr(chksum[1]);
  temp[2]:=chr(chksum[2]);
  temp[3]:=chr(chksum[3]);
  temp[4]:=chr(chksum[4]);
  Seek (dest,position1+2);
  Write (dest,temp[1],temp[2],temp[3],temp[4]);
  Seek (dest,position3);
  temp[1]:=chr(128);
  temp[2]:=chr(1);
  temp[3]:=chr(0);
  temp[4]:=chr(13);
  Write (dest,temp[1],temp[2],temp[3],temp[3],temp[3],temp[3]);
  REPEAT
    FOR counter:=1 TO Length(data) DO
      Write (dest,data[counter]);
    Write (dest,temp[4]);
    Readln (source,data)
  UNTIL EOF(source);
  FOR counter:=1 TO Length(data) DO
      Write (dest,data[counter]);
  Write (dest,temp[4]);
  position1:=FilePos(dest);
  position2:=position1-position3;
  chksum[4]:=position2 DIV 16777216;
  position2:=position2-chksum[4]*16777216;
  chksum[3]:=position2 DIV 65536;
  position2:=position2-chksum[3]*65536;
  chksum[2]:=position2 DIV 256;
  position2:=position2-chksum[2]*256;
  chksum[1]:=position2;
  temp[1]:=chr(chksum[1]);
  temp[2]:=chr(chksum[2]);
  temp[3]:=chr(chksum[3]);
  temp[4]:=chr(chksum[4]);
  Seek (dest,position3+2);
  Write (dest,temp[1],temp[2],temp[3],temp[4]);
  Seek (dest,position1);
  temp[1]:=chr(128);
  temp[2]:=chr(3);
  Write (dest,temp[1],temp[2]);
  Close (source);
  Close (dest);
END;
 
BEGIN
  FindFirst ('*.HEX',AnyFile,usefile);
  IF ((DosError=2) OR (DosError=18)) THEN
     HALT;
  REPEAT
    ConvertFile;
    FindNext (usefile)
  UNTIL (DosError=18)
END.