home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************/
- /* */
- /* P F M 2 A F M */
- /* */
- /*****************************************************************************/
-
-
- /* changes by m.schmidt (11/1992):
- - bug fix for the names above code 128
- - pfm-analysis
- - Weight,Italics-Guessing
- - wfont-name for FamilyName
-
- Manufacturing (dont forget the big stack!):
- cl /AL /Zp /Lp pfm2afm.c /link /NOD /PM:VIO /ST:12000 os2.lib llibcep.lib
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "pfm2afm.h"
-
- #define GUESS(name,what,where, what2) if (strstr(name,what)!=NULL) \
- strcpy(where,what2);
-
- void process_pfb(FILE *);
- void name_guessing(char *);
- void after_space_copy(char *, char *);
- void to_space_copy(char *, char *);
-
- /* don't tell me anything about software-engeneering!
- better remove the globals for yourself! :-) (ms) */
- extern const char *charname[];
- char ItalicAngle[100]= "";
- char FamilyName[100]= "";
- char Weight[100]= "";
- char FontBBox[100]= "";
-
-
-
- void main (int argc, char *argv[])
- {
- PFMHEADER pfmhead;
- PFMEXTENSION pfmextension;
- EXTTEXTMETRIC ext_text_metric;
- char driver[255];
- char pfb_name[255];
- char afm_name[255];
- char wfont_name[255];
- char psfont_name[255];
- FILE *fp, *fp2;
- WORD *ext_tab;
- int ext_entries;
- KERNPAIR *kernpairs;
- FILE *ofp;
- int i;
-
- if (argc < 2)
- {
- printf ("Error dude\nNeed Parameter with pfm-file and \n");
- printf ("optinal parameter with afm-file!\n");
- printf ("SAY: PFM2AFM <pfm-file> [<afm-file>]\n");
- exit (EXIT_FAILURE);
- }
-
- if (NULL == (fp = fopen (argv[1], "rb")))
- {
- printf("ERROR: ");
- perror (argv[1]);
- exit (EXIT_FAILURE);
- }
-
- if (argc>2) {
- strcpy(afm_name, argv[2]);
- }
- else {
- strcpy(afm_name, argv[1]); /* Build pfb_file */
- strcpy(afm_name+strlen(afm_name)-3, "afm");
- }
-
- if (NULL == (ofp = fopen (afm_name, "w")))
- {
- printf("ERROR: ");
- perror (afm_name);
- exit (EXIT_FAILURE);
- }
-
- strcpy(pfb_name, argv[1]); /* Build pfb_file */
- strcpy(pfb_name+strlen(pfb_name)-3, "pfb");
- if (NULL == (fp2 = fopen (pfb_name, "rb")))
- {
- printf("WARNING: ");
- perror (pfb_name);
- }
-
- fread (&pfmhead, sizeof (pfmhead), 1, fp);
- fread (&pfmextension, sizeof (pfmextension), 1, fp);
-
- fseek (fp, pfmhead.dfDevice, SEEK_SET);
- fread (driver, 50, 1, fp);
-
- fseek (fp, pfmhead.dfFace, SEEK_SET);
- fread (wfont_name, 50, 1, fp);
-
- fseek (fp, pfmextension.dfExtMetricsOffset, SEEK_SET);
- fread (&ext_text_metric, sizeof (ext_text_metric), 1, fp);
-
- fseek (fp, pfmextension.dfDriverInfo, SEEK_SET);
- fread (psfont_name, 50, 1, fp);
-
- ext_entries = pfmhead.dfLastChar - pfmhead.dfFirstChar + 1;
- ext_tab = malloc (ext_entries * sizeof (WORD));
- if (ext_tab == NULL)
- {
- perror ("malloc");
- exit (EXIT_FAILURE);
- }
- fseek (fp, pfmextension.dfExtentTable, SEEK_SET);
- fread (ext_tab, sizeof (WORD), ext_entries, fp);
-
- /* Try to get something from the pfb-file or from the name */
- if (fp2!=NULL)
- process_pfb(fp2);
- name_guessing(psfont_name);
-
- fprintf (ofp, "StartFontMetrics 2.0\n");
- fprintf (ofp, "Comment Generated by pfm2afm Public Domain ");
- fprintf (ofp, "by Kevin Nickerson 1991\n");
- fprintf (ofp, "Comment Bugfix and improved by Markus Schmidt 1992\n");
- fprintf (ofp, "FontName %s\n", psfont_name);
- fprintf (ofp, "FullName %s\n", psfont_name);
- fprintf (ofp, "FamilyName %s\n",
- (FamilyName[0]=='\0')?wfont_name:FamilyName);
- fprintf (ofp, "Weight %s\n", (Weight[0]=='\0')?"standard":Weight);
- fprintf (ofp, "Notice This frees you from Windoze\n");
- fprintf (ofp, "ItalicAngle %s\n", (ItalicAngle[0]=='\0')?"0.0":ItalicAngle);
- fprintf (ofp, "IsFixedPitch false\n");
- fprintf (ofp, "UnderlinePosition -%d\n", ext_text_metric.etmUnderlineOffset);
- fprintf (ofp, "UnderlineThickness %d\n", ext_text_metric.etmUnderlineWidth);
- fprintf (ofp, "Version 001.000\n"); /*hm*/
- fprintf (ofp, "EncodingScheme AdobeStandardEncoding\n");
- if (FontBBox[0]=='\0')
- fprintf (ofp, "FontBBox %d %d %d %d\n",
- 0, ext_text_metric.etmLowerCaseDescent,
- pfmhead.dfMaxWidth, ext_text_metric.etmCapHeight );
- else
- fprintf (ofp, "FontBBox %s\n", FontBBox);
- fprintf (ofp, "CapHeight %d\n", ext_text_metric.etmCapHeight );
- fprintf (ofp, "XHeight %d\n", ext_text_metric.XHeight);
- fprintf (ofp, "Descender %d\n", ext_text_metric.etmLowerCaseDescent);
- fprintf (ofp, "Ascender %d\n", ext_text_metric.etmCapHeight);
-
-
-
- fprintf (ofp, "StartCharMetrics %d\n", ext_entries);
- for (i = 0; i < ext_entries; i++)
- {
- fprintf (ofp, "C %d ; WX %d ; N %s ; B 0 0 1000 1000 ;\n",
- i + pfmhead.dfFirstChar,
- ext_tab[i],
- charname[i + pfmhead.dfFirstChar]);
- }
-
- fprintf (ofp, "EndCharMetrics\n");
- fprintf (ofp, "StartKernData\n");
- fprintf (ofp, "StartKernPairs %d\n", ext_text_metric.etmKernPairs);
- kernpairs = malloc (ext_text_metric.etmKernPairs * sizeof (KERNPAIR));
- if (kernpairs == NULL)
- {
- perror ("malloc");
- exit (EXIT_FAILURE);
- }
- fseek (fp, pfmextension.dfPairKernTable+2, SEEK_SET);
- fread (kernpairs, sizeof (KERNPAIR), ext_text_metric.etmKernPairs, fp);
- for (i = 0; i < (int) ext_text_metric.etmKernPairs; i++)
- {
- fprintf (ofp, "KPX %s %s %d\n", charname[kernpairs[i].kpPair.each[0]],
- charname[kernpairs[i].kpPair.each[1]],
- kernpairs[i].kpKernAmount);
- }
-
- fprintf (ofp, "EndKernPairs\n");
- fprintf (ofp, "EndKernData\n");
- fprintf (ofp, "StartComposites 0\n");
- fprintf (ofp, "EndComposites\n");
- fprintf (ofp, "EndFontMetrics\n");
-
- fclose (fp);
- if (fp2!=NULL)
- fclose (fp2);
- exit (EXIT_SUCCESS);
- }
-
-
-
- /* PFB-File analysis by M. Schmidt (bix:shimoda), no copyrights, of course */
- /* quick and dirty, I know, it could be done with tables and loops,
- * but I did't have the time */
-
-
- void process_pfb(FILE *f)
- {
- char buffer[256];
-
- fread(buffer, 1, 6, f); /* kill first 6 bytes */
-
- /* this loop is a little bit crude for binary files, I know */
- while (!feof(f)) {
- fgets(buffer, 256, f);
- /* we 're interested in the /xxx lines */
- if (buffer[0]=='/') {
- if (strncmp(buffer, "/ItalicAngle", 12)==0) {
- after_space_copy(ItalicAngle, buffer);
- }
- else
- if (strncmp(buffer, "/Weight", 7)==0) {
- after_space_copy(Weight, buffer);
- }
- else
- if (strncmp(buffer, "/FamilyName", 10)==0) {
- after_space_copy(FamilyName, buffer);
- }
- else
- if (strncmp(buffer, "/FontBBox", 9)==0) {
- after_space_copy(FontBBox, buffer);
- }
-
- }
- }
- }
-
-
- /* put the word/expression after the keyword to "to" */
- void after_space_copy(char *to, char *from)
- {
- char *p, *p1;
- char tmpbuf[256];
-
- for (p= from; *p!=' ' && *p!='\t' && *p!='\0'; p++) {
- }
-
- if (*p==' ' || *p=='\t')
- p++;
-
- strcpy(tmpbuf, p);
-
- to_space_copy(to, tmpbuf);
- }
-
-
- /* copy one word, or one expr. in brackets etc. */
- void to_space_copy(char *to, char *from)
- {
- char *p, c, e= ' ';
-
- c= from[0];
- if (c=='(' || c=='[' || c=='{') {
- from++;
-
- if (c=='[')
- e= ']';
-
- if (c=='(')
- e= ')';
-
- if (c=='{')
- e= '}';
- }
-
- for (p= from; *p!=e && *p!='\0'; p++) {
-
- }
-
- strncpy(to, from, p-from);
- to[p-from]= '\0';
- }
-
-
- /* Try to guess weight or italicangle from the name */
- void name_guessing(char *name)
- {
- if (Weight[0]=='\0') {
- GUESS(name, "Bold", Weight, "Bold");
- GUESS(name, "bold", Weight, "Bold");
- GUESS(name, "Demi", Weight, "Bold");
- GUESS(name, "demi", Weight, "Bold");
- GUESS(name, "Heavy", Weight, "Heavy");
- GUESS(name, "heavy", Weight, "Heavy");
- GUESS(name, "Light", Weight, "Light");
- GUESS(name, "light", Weight, "Light");
- GUESS(name, "ExtraBold", Weight, "ExtraBold");
- GUESS(name, "extraBold", Weight, "ExtraBold");
- }
-
- if (ItalicAngle[0]=='\0') {
- GUESS(name, "Italic", ItalicAngle, "20.0");
- GUESS(name, "italic", ItalicAngle, "20.0");
- GUESS(name, "Oblique", ItalicAngle, "20.0");
- GUESS(name, "oblique", ItalicAngle, "20.0");
- }
- }
-
-
-
-
-
- /* Quite frankly, this has me puzzled. The first 127 seem constant,
- but the names of the characters past there seem to change with the
- font. Some of the fonts give the names in the ascii part. If so,
- you should use them. Otherwise, these seem (after looking at a number
- of fonts) to be the correct names. (kn) */
-
- /* This contained some bug in the orignal table (there were some
- blank etries missing (quite bad for a indexed table :-)).
- Does anyone know the names for the empty places? (ms)
- */
-
- static const char *charname[] =
- {
- "null", /* 0*/
- "^A", /* 1*/
- "^B", /* 2*/
- "^C", /* 3*/
- "^D", /* 4*/
- "^E", /* 5*/
- "^F", /* 6*/
- "^G", /* 7*/
- "^H", /* 8*/
- "^I", /* 9*/
- "^J", /*10*/
- "^K", /*11*/
- "^L", /*12*/
- "^M", /*13*/
- "^N", /*14*/
- "^O", /*15*/
- "^P", /*16*/
- "^Q", /*17*/
- "^R", /*18*/
- "^S", /*19*/
- "^T", /*20*/
- "^U", /*21*/
- "^V", /*22*/
- "^W", /*23*/
- "^X", /*24*/
- "^Y", /*25*/
- "^Z", /*26*/
- "escape", /*27*/
- "28", /*28*/
- "29", /*29*/
- "30", /*30*/
- "31", /*31*/
- "space", /*32*/
- "exclam", /*33*/
- "quotedbl", /*34*/
- "numbersign", /*35*/
- "dollar", /*36*/
- "percent", /*37*/
- "ampersand", /*38*/
- "quoteright", /*39*/
- "parenleft", /*40*/
- "parenright", /*41*/
- "asterisk", /*42*/
- "plus", /*43*/
- "comma", /*44*/
- "hyphen", /*45*/
- "period", /*46*/
- "slash", /*47*/
- "zero", /*48*/
- "one", /*49*/
- "two", /*50*/
- "three", /*51*/
- "four", /*52*/
- "five", /*53*/
- "six", /*54*/
- "seven", /*55*/
- "eight", /*56*/
- "nine", /*57*/
- "colon", /*58*/
- "semicolon", /*59*/
- "less", /*60*/
- "equal", /*61*/
- "greater", /*62*/
- "question", /*63*/
- "at", /*64*/
- "A", /*65*/
- "B", /*66*/
- "C", /*67*/
- "D", /*68*/
- "E", /*69*/
- "F", /*70*/
- "G", /*71*/
- "H", /*72*/
- "I", /*73*/
- "J", /*74*/
- "K", /*75*/
- "L", /*76*/
- "M", /*77*/
- "N", /*78*/
- "O", /*79*/
- "P", /*80*/
- "Q", /*81*/
- "R", /*82*/
- "S", /*83*/
- "T", /*84*/
- "U", /*85*/
- "V", /*86*/
- "W", /*87*/
- "X", /*88*/
- "Y", /*89*/
- "Z", /*90*/
- "bracketleft", /*91*/
- "backslash", /*92*/
- "bracketright", /*93*/
- "asciicircum", /*94*/
- "underscore", /*95*/
- "grave", /*96*/
- "a", /* 97*/
- "b", /* 98*/
- "c", /* 99*/
- "d", /*100*/
- "e", /*101*/
- "f", /*102*/
- "g", /*103*/
- "h", /*104*/
- "i", /*105*/
- "j", /*106*/
- "k", /*107*/
- "l", /*108*/
- "m", /*109*/
- "n", /*110*/
- "o", /*111*/
- "p", /*112*/
- "q", /*113*/
- "r", /*114*/
- "s", /*115*/
- "t", /*116*/
- "u", /*117*/
- "v", /*118*/
- "w", /*119*/
- "x", /*120*/
- "y", /*121*/
- "z", /*122*/
- "braceleft", /*123*/
- "bar", /*124*/
- "braceright", /*125*/
- "asciitilde", /*126*/
- "127",
- "grave", /*128*/
- "circumflex", /*129*/
- "tilde", /*130*/
- "dotlessi", /*131*/
- "florin", /*132*/
- "quotedblleft", /*133*/
- "quotedblright", /*134*/
- "guilsinglleft", /*135*/
- "guilsinglright", /*136*/
- "fi", /*137*/
- "fl", /*138*/
- "dagger", /*139*/
- "daggerdbl", /*140*/
- "endash", /*141*/
- "bullet", /*142*/
- "breve", /*143*/
- "quotedblbase", /*144*/
- "ellipsis", /*145*/
- "perthousand", /*146*/
- "trademark", /*147*/
- "", /*148*/
- "", /*149*/
- "", /*150*/
- "", /*151*/
- "divide", /*152*/
- "", /*153*/
- "", /*154*/
- "", /*155*/
- "", /*156*/
- "", /*157*/
- "", /*158*/
- "", /*159*/
- "", /*160*/
- "exclamdown", /*161*/
- "cent", /*162*/
- "sterling", /*163*/
- "currency", /*164*/
- "yen", /*165*/
- "brokenbar", /*166*/
- "section", /*167*/
- "dieresis", /*168*/
- "copyright", /*169*/
- "ordfeminine", /*170*/
- "guillemotleft", /*171*/
- "logicalnot", /*172*/
- "emdash", /*173*/
- "registered", /*174*/
- "", /*175*/
- "ring", /*176*/
- "plusminus", /*177*/
- "twosuperior", /*178*/
- "threesuperior", /*179*/
- "acute", /*180*/
- "mu", /*181*/
- "paragraph", /*182*/
- "periodcentered", /*183*/
- "cedilla", /*184*/
- "onesuperior", /*185*/
- "ordmasculine", /*186*/
- "guillemotright", /*187*/
- "onequarter", /*188*/
- "onehalf", /*189*/
- "threequarters", /*190*/
- "questiondown", /*191*/
- "Agrave", /*192*/
- "Aacute", /*193*/
- "Acircumflex", /*194*/
- "Atilde", /*195*/
- "Adieresis", /*196*/
- "Aring", /*197*/
- "AE", /*198*/
- "Ccedilla", /*199*/
- "Egrave", /*200*/
- "Eacute", /*201*/
- "Ecircumflex", /*202*/
- "Edieresis", /*203*/
- "Igrave", /*204*/
- "Iacute", /*205*/
- "Icircumflex", /*206*/
- "Idieresis", /*207*/
- "Eth", /*208*/
- "Ntilde", /*209*/
- "Ograve", /*210*/
- "Oacute", /*211*/
- "Ocircumflex", /*212*/
- "Otilde", /*213*/
- "Odieresis", /*214*/
- "OE", /*215*/
- "Oslash", /*216*/
- "Ugrave", /*217*/
- "Uacute", /*218*/
- "Ucircumflex", /*219*/
- "Udieresis", /*220*/
- "Yacute", /*221*/
- "Thorn", /*222*/
- "germandbls", /*223*/
- "agrave", /*224*/
- "aacute", /*225*/
- "acircumflex", /*226*/
- "atilde", /*227*/
- "adieresis", /*228*/
- "aring", /*229*/
- "ae", /*230*/
- "ccedilla", /*231*/
- "egrave", /*232*/
- "eacute", /*233*/
- "ecircumflex", /*234*/
- "edieresis", /*235*/
- "igrave", /*236*/
- "iacute", /*237*/
- "icircumflex", /*238*/
- "idieresis", /*239*/
- "eth", /*240*/
- "ntilde", /*241*/
- "ograve", /*242*/
- "oacute", /*243*/
- "ocircumflex", /*244*/
- "otilde", /*245*/
- "odieresis", /*246*/
- "oe", /*247*/
- "oslash", /*248*/
- "ugrave", /*249*/
- "uacute", /*250*/
- "ucircumflex", /*251*/
- "udieresis", /*252*/
- "yacute", /*253*/
- "thorn", /*254*/
- "ydieresis", /*255*/
-
-
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","","","","","","","",
- "","","","","","","",""
- };
-
-