home *** CD-ROM | disk | FTP | other *** search
- head 1.3;
- access;
- symbols
- stage1:1.1;
- locks; strict;
- comment @ * @;
-
-
- 1.3
- date 94.04.27.11.37.54; author peteric; state Exp;
- branches;
- next 1.2;
-
- 1.2
- date 94.03.26.11.28.03; author peteric; state Exp;
- branches;
- next 1.1;
-
- 1.1
- date 94.03.07.12.43.26; author peteric; state Exp;
- branches;
- next ;
-
-
- desc
- @Adobe Font Metric file reader for Ftree.
- @
-
-
- 1.3
- log
- @included definitions for the standard Adobe & Latin font
- encodings, support for kerned fonts and ligatures, and a better
- font lookup system.
- @
- text
- @/*************************************************************************
- *
- * $RCSfile: afm.c,v $
- *
- * $Author: peteric $
- *
- * $Date: 1994/03/26 11:28:03 $
- *
- * $Revision: 1.2 $
- *
- * Purpose: Main routine for ftree family tree formatter.
- *
- * $Log: afm.c,v $
- * Revision 1.2 1994/03/26 11:28:03 peteric
- * Modified to use Adobe's parseAFM code. Includes
- * stand-alone tester. Kerning data still to be included.
- *
- * Revision 1.1 1994/03/07 12:43:26 peteric
- * Initial revision
- *
- *
- *
- *************************************************************************/
-
- #include <stdlib.h>
- #include <stdarg.h>
- #include <string.h>
- #include <ctype.h>
- #include <errno.h>
- #include "ftree.h"
- #include "parseAFM.h"
-
- int kern(FontInfo *afonti, char *cname1, char *cname2);
- CharMetricInfo *lookupname(FontInfo *afonti, char *cname, char **p);
- CharMetricInfo *simplelookupname(FontInfo *afonti, char *cname);
-
- #define MAXFONTS 8
- #define EOS '\0'
-
- static FontInfo *fonts[MAXFONTS] = {0};
-
- char *AdobeStandardEncoding[256] =
- {
- ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- "space", "exclam", "quotedbl", "numbersign",
- "dollar", "percent", "ampersand", "quoteright",
- "parenleft", "parenright", "asterisk", "plus",
- "comma", "hyphen", "period", "slash",
- "zero", "one", "two", "three",
- "four", "five", "six", "seven",
- "eight", "nine", "colon", "semicolon",
- "less", "equal", "greater", "question",
- "at", "A", "B", "C", "D", "E", "F", "G",
- "H", "I", "J", "K", "L", "M", "N", "O",
- "P", "Q", "R", "S", "T", "U", "V", "W",
- "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore",
- "quoteleft", "a", "b", "c", "d", "e", "f", "g",
- "h", "i", "j", "k", "l", "m", "n", "o",
- "p", "q", "r", "s", "t", "u", "v", "w",
- "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", ".notdef",
-
- ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", "exclamdown", "cent", "sterling",
- "fraction", "yen", "florin", "section",
- "currency", "quotesingle", "quotedblleft", "guillemotleft",
- "guilsinglleft", "guilsinglright", "fi", "fl",
- ".notdef", "endash", "dagger", "daggerdbl",
- "periodcentered", ".notdef", "paragraph", "bullet",
- "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright",
- "ellipsis", "perthousand", ".notdef", "questiondown",
- ".notdef", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent",
- "dieresis", ".notdef", "ring", "cedilla", ".notdef", "hungarumlaut", "ogonek", "caron",
- "emdash", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", "AE", ".notdef", "ordfeminine", ".notdef", ".notdef", ".notdef", ".notdef",
- "Lslash", "Oslash", "OE", "ordmasculine", ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", "ae", ".notdef", ".notdef", ".notdef", "dotlessi", ".notdef", ".notdef",
- "lslash", "oslash", "oe", "germandbls", ".notdef", ".notdef", ".notdef", ".notdef"
- };
-
- char *ISOLatin1Encoding[256] =
- {
- ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- "space", "exclam", "quotedbl", "numbersign",
- "dollar", "percent", "ampersand", "quoteright",
- "parenleft", "parenright", "asterisk", "plus",
- "comma", "minus", "period", "slash",
- "zero", "one", "two", "three",
- "four", "five", "six", "seven",
- "eight", "nine", "colon", "semicolon",
- "less", "equal", "greater", "question",
- "at", "A", "B", "C", "D", "E", "F", "G",
- "H", "I", "J", "K", "L", "M", "N", "O",
- "P", "Q", "R", "S", "T", "U", "V", "W",
- "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore",
- "quoteleft", "a", "b", "c", "d", "e", "f", "g",
- "h", "i", "j", "k", "l", "m", "n", "o",
- "p", "q", "r", "s", "t", "u", "v", "w",
- "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", ".notdef",
-
- ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- "dotlessi", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent",
- "dieresis", ".notdef", "ring", "cedilla", ".notdef", "hungarumlaut", "ogonek", "caron",
- "space", "exclamdown", "cent", "sterling",
- "currency", "yen", "brokenbar", "section",
- "dieresis", "copyright", "ordfeminine", "guillemotleft",
- "logicalnot", "hyphen", "registered", "macron",
- "degree", "plusminus", "twosuperior", "threesuperior",
- "acute", "mu", "paragraph", "periodcentered",
- "cedilla", "onesuperior", "ordmasculine", "guillemotright",
- "onequarter", "onehalf", "threequarters", "questiondown",
- "Agrave", "Aacute", "Acircumflex", "Atilde",
- "Adieresis", "Aring", "AE", "Ccedilla",
- "Egrave", "Eacute", "Ecircumflex", "Edieresis",
- "Igrave", "Iacute", "Icircumflex", "Idieresis",
- "Eth", "Ntilde", "Ograve", "Oacute",
- "Ocircumflex", "Otilde", "Odieresis", "multiply",
- "Oslash", "Ugrave", "Uacute", "Ucircumflex",
- "Udieresis", "Yacute", "Thorn", "germandbls",
- "agrave", "aacute", "acircumflex", "atilde",
- "adieresis", "aring", "ae", "ccedilla",
- "egrave", "eacute", "ecircumflex", "edieresis",
- "igrave", "iacute", "icircumflex", "idieresis",
- "eth", "ntilde", "ograve", "oacute",
- "ocircumflex", "otilde", "odieresis", "divide",
- "oslash", "ugrave", "uacute", "ucircumflex",
- "udieresis", "yacute", "thorn", "ydieresis"
- };
-
-
- FILE *openfontfile(char *name);
-
- int loadfont(fontinfo_t *font)
- {
- int i, code;
- FILE *fp;
-
- for(i = 0; i < MAXFONTS; i++)
- if (fonts[i] == 0)
- break;
-
- if (i == MAXFONTS)
- {
- errmsg("Maximum number of fonts (%d) loaded; cannot load %s\n",
- MAXFONTS, font->font);
- return FALSE;
- }
-
- fp = openfontfile(font->font);
- if (fp == NULL)
- {
- errmsg("Cannot open font file for font %s: %s\n",
- font->font, strerror(errno));
- return FALSE;
- }
-
- code = parseFile(fp, &fonts[i], P_ALL);
-
- fclose(fp);
-
- return code == ok;
- }
-
- FILE *openfontfile(char *name)
- {
- int i;
- FILE *fp;
- char filen[128];
- char *patt;
- char *p;
- static char *paths[][2] =
- {
- {"psfonts:", ".afm", },
- {"psfonts:afm/", "", },
- {"psfonts:OtherFonts/", ".afm", },
- {"psfonts:OtherFonts/afm/", "", },
- {"psfonts:afm/", ".afm", },
- {"psfonts:OtherFonts/afm/", ".afm", },
- {"/usr/local/lib/fonts/afm/", "", },
- {"/usr/local/lib/fonts/afm/", ".afm", },
- {NULL, NULL},
- };
-
- if (psfontpath[0] != EOS)
- {
- patt = strdup(psfontpath);
- fp = NULL;
- p = strtok(patt, ":");
- for(i = 0; p != NULL && fp == NULL; i++)
- {
- sprintf(filen, p, name);
-
- fp = fopen(filen, "r");
- p = strtok(NULL, ":");
- }
- free(patt);
- }
- else
- {
- fp = NULL;
- for(i = 0; paths[i][0] != NULL && fp == NULL; i++)
- {
- strcpy(filen, paths[i][0]);
- strcat(filen, name);
- strcat(filen, paths[i][1]);
-
- fp = fopen(filen, "r");
- }
- }
- return fp;
- }
-
- void unloadfont(fontinfo_t *font)
- {
- int i;
-
- for(i = 0; i < MAXFONTS; i++)
- {
- if (fonts[i] && streq(fonts[i]->gfi->fontName, font->font))
- {
- freeStorage(fonts[i]);
- fonts[i] = NULL;
- break;
- }
- }
- }
-
- double stringwidth(fontinfo_t *font, double afmconst, char *string)
- {
- char *p, **encv;
- CharMetricInfo *cd;
- int i, cw;
- double w;
- FontInfo *afonti = NULL;
-
- /*
- * look for the requested font
- */
- for(i = 0; i < MAXFONTS; i++)
- {
- if (fonts[i] && streq(fonts[i]->gfi->fontName, font->font))
- {
- afonti = fonts[i];
- break;
- }
- }
-
- /*
- * if no font info available (e.g. no font file for this font)
- * then attempt an approximation, using the supplied font width
- * constant afmconst. This is supposed to return a width which
- * is at least as great as the true width. Of course, it will
- * probably end up being larger.
- */
- if (afonti == NULL)
- {
- if (afmconst != 0.0)
- {
- w = font->size * strlen(string) * afmconst;
- return w;
- }
- else
- return -1;
- }
-
- if (streq(afonti->gfi->encodingScheme, "AdobeStandardEncoding"))
- encv = AdobeStandardEncoding;
- else if (streq(afonti->gfi->encodingScheme, "ISOLatin1Encoding"))
- encv = ISOLatin1Encoding;
- else
- {
- warnmsg("Unknown encoding '%s' of font %s. Using Standard encoding\n",
- afonti->gfi->encodingScheme, afonti->gfi->fontName);
- encv = AdobeStandardEncoding;
- }
-
- for (p = string, w = 0.0; *p != EOS; p++)
- {
- cd = lookupname(afonti, encv[*p], &p);
- if (cd != NULL)
- {
- cw = cd->wx;
- /* dbprintf(("stringwidth: translates to: %s, width %d\n", cd->name, cw)); */
- cw += kern(afonti, cd->name, encv[p[1]]);
- w += cw;
- /* dbprintf(("stringwidth: kern %s: final width %d, sum %.2f\n", cd->name, cw, w)); */
- }
- }
- w = (w * font->size) / 1000.0;
-
- return w;
- }
-
- int kern(FontInfo *afonti, char *cname1, char *cname2)
- {
- PairKernData *pkd = afonti->pkd;
- int i, np, kx;
- CharMetricInfo *cd;
-
- if (streq(cname1, ".notdef") || streq(cname2, ".notdef"))
- return 0;
-
- pkd = afonti->pkd;
- np = afonti->numOfPairs;
- cd = NULL;
- kx = 0;
- for(i = 0; i < np; pkd++, i++)
- {
- if (streq(cname1, pkd->name1))
- {
- if (cd == NULL)
- cd = simplelookupname(afonti, cname2);
- if (cd && streq(cd->name, pkd->name2))
- {
- kx += pkd->xamt;
- break;
- }
- }
- }
- /* dbprintf(("kern: returning %d for kern letter: %s%s%s\n", kx, cname1, cd ? " and letter: " : "", cd ? cd->name : "")); */
-
- return kx;
- }
-
- CharMetricInfo *simplelookupname(FontInfo *afonti, char *cname)
- {
- int i, nc;
- CharMetricInfo *cd;
-
- /* dbprintf(("simplelookupname: looking up %s\n", cname)); */
-
- cd = afonti->cmi;
- nc = afonti->numOfChars;
- for(i = 0; i < nc; i++, cd++)
- {
- if (streq(cname, cd->name))
- break;
- }
-
- if (i == nc)
- {
- /* dbprintf(("No glyph for '%s'\n", cname)); */
- cd = NULL;
- }
- return cd;
- }
-
- CharMetricInfo *lookupname(FontInfo *afonti, char *cname, char **p)
- {
- unsigned int l;
- CharMetricInfo *cd;
- Ligature *ligp;
- char *q;
-
- /* dbprintf(("lookupname: looking up %s\n", cname)); */
-
- cd = simplelookupname(afonti, cname);
-
- if (cd != NULL)
- {
- #if 0
- dbprintf(("lookupname: glyph '%s': ligatures: ", cd->name));
- ligp = cd->ligs;
- while(ligp)
- {
- if (ligp->succ)
- dbprintf(("S: %s ", ligp->succ));
- else
- dbprintf(("S: >??< "));
- if (ligp->lig)
- dbprintf(("L: %s, ", ligp->lig));
- else
- dbprintf(("L: >??< "));
- ligp = ligp->next;
- }
- dbprintf(("\n"));
- #endif
-
- q = (*p)+1;
- ligp = cd->ligs;
- while(ligp != NULL && *q != EOS)
- {
- l = strlen(ligp->succ);
- /* dbprintf(("lookupname: check lig. '%s' against %d char(s) from: '%c'\n", ligp->succ, l, *q)); */
- if (ligp->succ[0] == *q)
- {
- *p += l;
- cd = simplelookupname(afonti, ligp->lig);
-
- /* dbprintf(("lookupname: ligature %s (%d) to get char %s\n", ligp->succ, l, cd->name)); */
-
- ligp = NULL;
- }
- else
- ligp = ligp->next;
- }
- }
- return cd;
- }
- @
-
-
- 1.2
- log
- @Modified to use Adobe's parseAFM code. Includes
- stand-alone tester. Kerning data still to be included.
- @
- text
- @d7 1
- a7 1
- * $Date: 1994/03/07 12:43:26 $
- d9 1
- a9 1
- * $Revision: 1.1 $
- d14 4
- d33 3
- d40 100
- a139 1
- FontInfo *fonts[MAXFONTS] = {0};
- d179 2
- d183 1
- d185 1
- d189 2
- d194 1
- a194 2
- fp = NULL;
- for(i = 0; paths[i][0] != NULL && fp == NULL; i++)
- d196 6
- a201 3
- strcpy(filen, paths[i][0]);
- strcat(filen, name);
- strcat(filen, paths[i][1]);
- d203 16
- a218 1
- fp = fopen(filen, "r");
- d240 3
- a242 2
- char *p;
- int i, ec, cw;
- d246 3
- d258 7
- d275 12
- a286 1
-
- d289 9
- a297 4
- ec = *p;
- cw = afonti->cmi[ec].wx;
- w += cw;
- /* printf("Char '%c'/%d => w(%6d) => tot(%f)\n", ec, ec, cw, w); */
- d304 106
- @
-
-
- 1.1
- log
- @Initial revision
- @
- text
- @d3 1
- a3 1
- * $RCSfile$
- d5 1
- a5 1
- * $Author$
- d7 1
- a7 1
- * $Date$
- d9 1
- a9 1
- * $Revision$
- d13 4
- a16 1
- * $Log$
- d24 10
- d35 1
- a35 1
- #include "ftree.h"
- d37 1
- a37 1
- typedef struct
- d39 28
- a66 5
- char name[64];
- int nchars;
- char *encoding;
- int *widths;
- } fontd_t;
- d68 1
- a68 1
- char *afmNames[] =
- d70 23
- a92 3
- "StartMetrics",
- "EndMetrics",
- };
- d94 1
- a94 1
- void loadfont(char *name)
- d96 1
- d98 9
- d109 1
- a109 1
- int stringwidth(char *font, char *string)
- d111 36
- a147 1
- }
- @
-