Annotation of ntddk/src/print/pslib/afmtopfm.c, revision 1.1.1.1

1.1       root        1: //--------------------------------------------------------------------------
                      2: //
                      3: // Module Name:  AFMTOPFM.C
                      4: //
                      5: // This module of the afm compiler parses the afm file and collects
                      6: // information in the PFM structure.  It then passes control to the
                      7: // pfm module which outputs the pfm file.
                      8: //
                      9: // USAGE: AFM <AFM filename> <MS database filename>
                     10: //      output is filename.pfm.
                     11: //
                     12: // Author:  Kent Settle (kentse)
                     13: // Created: 18-Mar-1991
                     14: //
                     15: // Copyright (c) 1988 - 1993 Microsoft Corporation
                     16: //--------------------------------------------------------------------------
                     17: 
                     18: #include <string.h>
                     19: #include "pscript.h"
                     20: #include "mapping.h"
                     21: #include "tables.h"
                     22: 
                     23: int     _fltused;   // HEY, it shut's up the linker.  That's why it's here.
                     24: 
                     25: #define U_SPACE         0x20
                     26: #define U_SYMBOL_BULLET 0x00B7
                     27: #define U_BULLET        0x2022
                     28: 
                     29: // Alias Family Tables.
                     30: 
                     31: static char *TimesAlias[] = {"Times", "Tms Rmn", "Times Roman", "TimesRoman",
                     32:                              "TmsRmn", "Varitimes", "Dutch",
                     33:                              "Times New Roman", "TimesNewRomanPS",
                     34:                              NULL };
                     35: 
                     36: static char *HelveticaAlias[] = {"Helvetica", "Helv", "Arial", "Swiss", NULL};
                     37: 
                     38: static char *CourierAlias[] = {"Courier", "Courier New", NULL};
                     39: 
                     40: static char *HelveticaNarrowAlias[] = {"Helvetica-Narrow", "Helvetica Narrow",
                     41:                                        "Arial-Narrow", "Arial Narrow", NULL};
                     42: 
                     43: static char *PalatinoAlias[] = {"Palatino", "Zapf Calligraphic",
                     44:                                 "Bookman Antiqua", "Book Antiqua",
                     45:                                 "ZapfCalligraphic", NULL};
                     46: 
                     47: static char *BookmanAlias[] = {"ITC Bookman", "Bookman Old Style", "Bookman",
                     48:                                NULL};
                     49: 
                     50: static char *NewCenturySBAlias[] = {"NewCenturySchlbk", "New Century Schoolbook",
                     51:                                     "Century Schoolbook", "NewCenturySchoolBook",
                     52:                                     "New Century SchoolBook", "CenturySchoolBook",
                     53:                                     NULL};
                     54: 
                     55: static char *AvantGardeAlias[] = {"AvantGarde", "ITC Avant Garde Gothic",
                     56:                                   "Century Gothic", "ITC Avant Garde", NULL};
                     57: 
                     58: static char *ZapfChanceryAlias[] = {"ZapfChancery", "ITC Zapf Chancery",
                     59:                                     "Monotype Corsiva", NULL};
                     60: 
                     61: static char *ZapfDingbatsAlias[] = {"ZapfDingbats", "ITC Zapf Dingbats",
                     62:                                     "Monotype Sorts", "Zapf Dingbats", NULL};
                     63: 
                     64: static USHORT ausIFIMetrics2WinWeight[12] =
                     65: {
                     66:     FW_DONTCARE,
                     67:     FW_DONTCARE,
                     68:     FW_LIGHT,
                     69:     FW_LIGHT,
                     70:     FW_NORMAL,
                     71:     FW_NORMAL,
                     72:     FW_NORMAL,
                     73:     FW_BOLD,
                     74:     FW_BOLD,
                     75:     FW_BOLD,
                     76:     FW_BOLD,
                     77:     FW_BOLD
                     78: };
                     79: 
                     80: //#define   ALL_METRICS
                     81: 
                     82: // declarations of routines defined within this module.
                     83: 
                     84: VOID PrintLine(char *);
                     85: VOID ParseKernPairs(PPARSEDATA);
                     86: VOID ParseKernData(PPARSEDATA);
                     87: VOID ParseFontName(PPARSEDATA);
                     88: VOID ParseFullName(PPARSEDATA);
                     89: VOID ParseFamilyName(PPARSEDATA);
                     90: VOID ParseWeight(PPARSEDATA);
                     91: BOOL ParseCharMetrics(PPARSEDATA);
                     92: int ParseCharName(PPARSEDATA);
                     93: int ParseCharWidth(PPARSEDATA);
                     94: VOID ParseBoundingBox(PPARSEDATA);
                     95: VOID InitPfm(PPARSEDATA);
                     96: VOID SetWidths(PPARSEDATA);
                     97: BOOL WritePFM(PWSTR, PPARSEDATA);
                     98: VOID ParseAfm(PPARSEDATA);
                     99: int ParseCharCode(PPARSEDATA);
                    100: int GetCharCode(char *, PPARSEDATA);
                    101: BOOL GetFirstLastChar(PPARSEDATA);
                    102: VOID BuildNTFM(PPARSEDATA, PSTR);
                    103: VOID InitIFIMETRICS(PPARSEDATA);
                    104: VOID CompleteIFIMETRICS(PPARSEDATA);
                    105: VOID ParseMSFamilyName(PPARSEDATA);
                    106: VOID ParsePitch(PPARSEDATA);
                    107: VOID GetFamilyAliases(IFIMETRICS *, PSTR);
                    108: 
                    109: // external declarations.
                    110: 
                    111: extern BOOL GetLine(PPARSEDATA);
                    112: extern int GetFloat(int, PPARSEDATA);
                    113: extern int GetNumber(PPARSEDATA);
                    114: extern VOID UnGetLine(PPARSEDATA);
                    115: extern VOID EatWhite(PPARSEDATA);
                    116: extern VOID GetWord(char *, int, PPARSEDATA);
                    117: extern int MapToken(char *, TABLE_ENTRY *);
                    118: extern int GetKeyword(TABLE_ENTRY *, PPARSEDATA);
                    119: 
                    120: //--------------------------------------------------------------------------
                    121: //
                    122: // VOID InitPfm(pdata)
                    123: // PPARSEDATA   pdata;
                    124: //
                    125: // Initialize the NTFM structure.
                    126: //
                    127: // Returns:
                    128: //   This routine returns no value.
                    129: //
                    130: // History:
                    131: //   18-Mar-1991    -by-    Kent Settle    (kentse)
                    132: //  Brought in from PM, and cleaned up.
                    133: //--------------------------------------------------------------------------
                    134: 
                    135: VOID InitPfm(pdata)
                    136: PPARSEDATA  pdata;
                    137: {
                    138:     PNTFM   pntfm;
                    139: 
                    140:     pntfm = pdata->pntfm;
                    141: 
                    142:     pntfm->cjThis = DWORDALIGN(sizeof(NTFM));
                    143:     pntfm->ulVersion = (ULONG)PFM_VERSION;
                    144:     pntfm->fwdLowerCaseAscent = 0;
                    145:     pntfm->loszFullName = 0;
                    146:     pntfm->loszFontName = 0;
                    147:     pntfm->loszFamilyName = 0;
                    148:     pntfm->cKernPairs = 0;
                    149:     pntfm->cCharacters = 0;
                    150:     pntfm->cjSoftFont = 0;
                    151:     pntfm->loSoftFont = 0;
                    152:     pntfm->loIFIMETRICS = 0;
                    153: }
                    154: 
                    155: 
                    156: //--------------------------------------------------------------------------
                    157: // VOID ParseAfm(pdata)
                    158: // PPARSEDATA  pdata;
                    159: //
                    160: // Parses most of the AFM file to fill in the NTFM structure.
                    161: //
                    162: // Parameters:
                    163: //   None.
                    164: //
                    165: // Returns:
                    166: //   This routine returns no value.
                    167: //
                    168: // History:
                    169: //   19-Mar-1991    -by-    Kent Settle    (kentse)
                    170: //  Ripped out of main.
                    171: //--------------------------------------------------------------------------
                    172: 
                    173: VOID ParseAfm(pdata)
                    174: PPARSEDATA  pdata;
                    175: {
                    176:     int         iToken;
                    177:     BOOL        fEndOfInput;
                    178:     PNTFM       pntfm;
                    179:     PIFIMETRICS pTmpIFI;
                    180:     FLOAT       eCharSlope;
                    181: 
                    182:     // get local pointers.
                    183: 
                    184:     pntfm = pdata->pntfm;
                    185:     pTmpIFI = pdata->pTmpIFI;
                    186: 
                    187:     // fill in some default values.
                    188: 
                    189:     InitIFIMETRICS(pdata);
                    190: 
                    191:     fEndOfInput = FALSE;
                    192:     while (!fEndOfInput)
                    193:     {
                    194:         GetLine(pdata);
                    195:         iToken = GetKeyword(AFMKeywordTable, pdata);
                    196: 
                    197:         switch(iToken)
                    198:         {
                    199:             case TK_STARTFONTMETRICS:
                    200:                 break;
                    201: 
                    202:             case TK_STARTKERNDATA:
                    203:                 ParseKernData(pdata);
                    204:                 break;
                    205: 
                    206:             case TK_FONTNAME:
                    207:                 ParseFontName(pdata);
                    208:                 break;
                    209: 
                    210:             case TK_FULLNAME:
                    211:                 ParseFullName(pdata);
                    212:                 break;
                    213: 
                    214:             case TK_FAMILYNAME:
                    215:                 ParseFamilyName(pdata);
                    216:                 break;
                    217: 
                    218:             case TK_WEIGHT:
                    219:                 ParseWeight(pdata);
                    220: 
                    221:                 pTmpIFI->usWinWeight = ausIFIMetrics2WinWeight[pTmpIFI->panose.bWeight];
                    222: 
                    223:                 if (pTmpIFI->usWinWeight > FW_NORMAL)
                    224:                     pTmpIFI->fsSelection |= FM_SEL_BOLD;
                    225: 
                    226:                 break;
                    227: 
                    228:             case TK_ITALICANGLE:
                    229:                 eCharSlope = (FLOAT)(GetFloat(10, pdata) / 10);
                    230: 
                    231:                 if ((LONG)(eCharSlope * 1000) == 0)
                    232:                 {
                    233:                     pTmpIFI->ptlCaret.x = 0;
                    234:                     pTmpIFI->ptlCaret.y = 1;
                    235:                 }
                    236:                 else
                    237:                 {
                    238:                     pTmpIFI->fsSelection |= FM_SEL_ITALIC;
                    239: 
                    240:                     // lean 17.5 degrees away from the y-axis.
                    241: 
                    242:                     pTmpIFI->ptlCaret.x = 3153;
                    243:                     pTmpIFI->ptlCaret.y = 10000;
                    244:                 }
                    245: 
                    246:                 break;
                    247: 
                    248:             case TK_MSFAMILY:
                    249:                 ParseMSFamilyName(pdata);
                    250:                 break;
                    251: 
                    252:             case TK_ISFIXEDPITCH:
                    253:                 ParsePitch(pdata);
                    254: 
                    255:                 break;
                    256: 
                    257:             case TK_ENCODINGSCHEME:
                    258:                 break;
                    259: 
                    260:             case TK_UNDERLINEPOSITION:
                    261:                 pTmpIFI->fwdUnderscorePosition = (FWORD) GetNumber(pdata);
                    262: #ifdef ALL_METRICS
                    263:                 DbgPrint("fwdUnderscorePosition = %d\n",
                    264:                          pTmpIFI->fwdUnderscorePosition);
                    265: #endif
                    266:                 break;
                    267: 
                    268:             case TK_UNDERLINETHICKNESS:
                    269:                 pTmpIFI->fwdUnderscoreSize = (FWORD)GetNumber(pdata);
                    270:                 pTmpIFI->fwdStrikeoutSize = pTmpIFI->fwdUnderscoreSize;
                    271: #ifdef ALL_METRICS
                    272:                 DbgPrint("fwdUnderscoreSize = %d\n",
                    273:                          pTmpIFI->fwdUnderscoreSize);
                    274: #endif
                    275:                 break;
                    276: 
                    277:             case TK_FONTBBOX:
                    278:                 ParseBoundingBox(pdata);
                    279:                 break;
                    280: 
                    281:             case TK_CAPHEIGHT:
                    282:                 break;
                    283: 
                    284:             case TK_XHEIGHT:
                    285:                 pTmpIFI->fwdXHeight = (FWORD)GetNumber(pdata);
                    286: #ifdef ALL_METRICS
                    287:                 DbgPrint("fwdXHeight = %d\n", pTmpIFI->fwdXHeight);
                    288: #endif
                    289:                 break;
                    290: 
                    291:             case TK_ASCENDER:
                    292:                 pntfm->fwdLowerCaseAscent = (FWORD)GetNumber(pdata);
                    293: #ifdef ALL_METRICS
                    294:                 DbgPrint("fwdLowerCaseAscent = %d\n",
                    295:                          pntfm->fwdLowerCaseAscent);
                    296: #endif
                    297:                 break;
                    298: 
                    299:             case TK_STARTCHARMETRICS:
                    300:                 ParseCharMetrics(pdata);
                    301:                 break;
                    302: 
                    303:             case TK_ENDFONTMETRICS:
                    304:                 fEndOfInput = TRUE;
                    305:                 break;
                    306: 
                    307:         }
                    308: 
                    309:         pdata->szLine = pdata->rgbLine;
                    310:     }
                    311: }
                    312: 
                    313: 
                    314: //--------------------------------------------------------------------------
                    315: //
                    316: // VOID  SetWidths();
                    317: //
                    318: // This routine computes the maximum and average character widths from the
                    319: // character metrics in the NTFM structure.
                    320: //
                    321: // Parameters:
                    322: //   None.
                    323: //
                    324: // Returns:
                    325: //   This routine returns no value.
                    326: //
                    327: // History:
                    328: //   01-Apr-1991    -by-    Kent Settle    (kentse)
                    329: //  Wrote it.
                    330: //--------------------------------------------------------------------------
                    331: 
                    332: VOID SetWidths(pdata)
                    333: PPARSEDATA  pdata;
                    334: {
                    335:     USHORT  i;
                    336:     int     iAvg;
                    337:     int     iMax;
                    338: 
                    339:     iAvg = 0;
                    340:     iMax = 0;
                    341: 
                    342:     // calculate maximum and average character widths.
                    343: 
                    344:     for (i = 0; i < pdata->pntfm->cCharacters; i++)
                    345:     {
                    346:         iAvg += (int)pdata->TmpCharWidths[i];
                    347:         if (iMax < (int)pdata->TmpCharWidths[i])
                    348:             iMax = (int)pdata->TmpCharWidths[i];
                    349:     }
                    350: 
                    351:     pdata->pTmpIFI->fwdAveCharWidth = (FWORD)(iAvg / pdata->pntfm->cCharacters);
                    352: 
                    353:     pdata->pTmpIFI->fwdMaxCharInc = (FWORD)iMax;
                    354: 
                    355: #ifdef ALL_METRICS
                    356:     DbgPrint("fwdAveCharWidth = %d\n", pdata->pTmpIFI->fwdAveCharWidth);
                    357:     DbgPrint("fwdMaxCharInc = %d\n", pdata->pTmpIFI->fwdMaxCharInc);
                    358: #endif
                    359: }
                    360: 
                    361: 
                    362: //--------------------------------------------------------------------------
                    363: //
                    364: // VOID ParseKernPairs();
                    365: //
                    366: // Parse the pairwise kerning data.
                    367: //
                    368: // Parameters:
                    369: //   None.
                    370: //
                    371: // Returns:
                    372: //   This routine returns no value.
                    373: //
                    374: // History:
                    375: //   13-Mar-1992    -by-    Kent Settle     (kentse)
                    376: //  Modified to use FD_KERNINGPAIR struct instead of KP.
                    377: //   18-Mar-1991    -by-    Kent Settle    (kentse)
                    378: //  Brought in from PM, and cleaned up.
                    379: //--------------------------------------------------------------------------
                    380: 
                    381: VOID ParseKernPairs(pdata)
                    382: PPARSEDATA  pdata;
                    383: {
                    384:     int i;
                    385:     int iCh1;
                    386:     int iCh2;
                    387:     int iKernAmount;
                    388:     int iToken;
                    389:     int cPairs;
                    390:     char szWord[80];
                    391:     WCHAR   wc1, wc2;
                    392:     UCMap  *pmap;
                    393:     UCMap  *pmapReset;
                    394:     BOOL    bFound;
                    395:     cPairs = GetNumber(pdata);
                    396: 
                    397:     pdata->pntfm->cKernPairs = (USHORT)cPairs;
                    398: 
                    399:     // point to the appropriate mapping table in mapping.h.
                    400: 
                    401:     if (!strcmp(pdata->szTmpFontName, "Symbol"))
                    402:         pmap = SymbolMap;
                    403:     else if (!strcmp(pdata->szTmpFontName, "ZapfDingbats"))
                    404:         pmap = DingbatsMap;
                    405:     else
                    406:         pmap = LatinMap;
                    407: 
                    408:     pmapReset = pmap;
                    409: 
                    410:     for (i = 0; i < cPairs; ++i)
                    411:     {
                    412:         if (GetLine(pdata))
                    413:             break;
                    414:         if (GetKeyword(AFMKeywordTable, pdata) != TK_KPX)
                    415:         {
                    416:             UnGetLine(pdata);
                    417:             break;
                    418:         }
                    419: 
                    420:         GetWord(szWord, sizeof(szWord), pdata);
                    421: #ifdef ALL_METRICS
                    422:         DbgPrint("Char1 = %s ", szWord);
                    423: #endif
                    424:         iCh1 = GetCharCode(szWord, pdata);
                    425:         GetWord(szWord, sizeof(szWord), pdata);
                    426: #ifdef ALL_METRICS
                    427:         DbgPrint("Char2 = %s ", szWord);
                    428: #endif
                    429:         iCh2 = GetCharCode(szWord, pdata);
                    430: 
                    431:         iKernAmount = GetNumber(pdata);
                    432: 
                    433: #ifdef ALL_METRICS
                    434:         DbgPrint("Amount = %d\n", iKernAmount);
                    435: #endif
                    436: 
                    437:         iCh1 = iCh1 & 0x0FF;    // 0 <= CharacerCode <= 255.
                    438:         iCh2 = iCh2 & 0x0FF;
                    439: 
                    440:         // we now have the postscript character code for each character
                    441:         // of the kerning pair.  we now need to convert them to UNICODE.
                    442: 
                    443:         pmap = pmapReset;
                    444: 
                    445:         bFound = FALSE;
                    446: 
                    447:         while (pmap->szChar)
                    448:         {
                    449:             if ((USHORT)(pmap->usPSValue & 0x7FFF) == (USHORT)iCh1)
                    450:             {
                    451:                 wc1 = pmap->usUCValue;
                    452:                 bFound = TRUE;
                    453:                 break;
                    454:             }
                    455:             pmap++;
                    456:         }
                    457: 
                    458:         if (!bFound)
                    459:             DbgPrint("GetPairs: Error char code %d not found.\n", iCh1);
                    460: 
                    461:         pmap = pmapReset;
                    462: 
                    463:         bFound = FALSE;
                    464: 
                    465:         while (pmap->szChar)
                    466:         {
                    467:             if ((USHORT)(pmap->usPSValue & 0x7FFF) == (USHORT)iCh2)
                    468:             {
                    469:                 wc2 = pmap->usUCValue;
                    470:                 bFound = TRUE;
                    471:                 break;
                    472:             }
                    473:             pmap++;
                    474:         }
                    475: 
                    476: #ifdef ALL_METRICS
                    477:         if (!bFound)
                    478:             DbgPrint("GetPairs: Error char code %d not found.\n", iCh2);
                    479: #endif
                    480:         pdata->TmpKernPairs[i].wcFirst = wc1;
                    481:         pdata->TmpKernPairs[i].wcSecond = wc2;
                    482:         pdata->TmpKernPairs[i].fwdKern = (FWORD)iKernAmount;
                    483:     }
                    484: 
                    485:     GetLine(pdata);
                    486:     iToken = GetKeyword(AFMKeywordTable, pdata);
                    487: 
                    488: #if DBG
                    489:     if (pdata->fEOF)
                    490:         RIP("GetPairs: Premature end of file encountered\n");
                    491:     else if (iToken != TK_ENDKERNPAIRS)
                    492:     {
                    493:         DbgPrint("GetPairs: expected EndKernPairs\n");
                    494:         DbgPrint("%s\n", pdata->rgbLine);
                    495:     }
                    496: #endif
                    497: 
                    498:     return;
                    499: }
                    500: 
                    501: 
                    502: //--------------------------------------------------------------------------
                    503: // VOID ParseKernData(pdata)
                    504: // PPARSEDATA  pdata;
                    505: //
                    506: // Start processing the pairwise kerning data.
                    507: //
                    508: // Parameters:
                    509: //   None.
                    510: //
                    511: // Returns:
                    512: //   This routine returns no value.
                    513: //
                    514: // History:
                    515: //   18-Mar-1991    -by-    Kent Settle    (kentse)
                    516: //  Brought in from PM, and cleaned up.
                    517: //--------------------------------------------------------------------------
                    518: 
                    519: VOID ParseKernData(pdata)
                    520: PPARSEDATA  pdata;
                    521: {
                    522:     if (!GetLine(pdata))
                    523:     {
                    524:         if (GetKeyword(AFMKeywordTable, pdata) == TK_STARTKERNPAIRS)
                    525:             ParseKernPairs(pdata);
                    526:         else
                    527:            RIP("PSCRPTUI!ParseKernData: expected StartKernPairs\n");
                    528:     }
                    529:     else
                    530:        RIP("PSCRPTUI!ParseKernData: unexpected end of file\n");
                    531: }
                    532: 
                    533: 
                    534: //--------------------------------------------------------------------------
                    535: // VOID ParseFontName(pdata)
                    536: // PPARSEDATA  pdata;
                    537: //
                    538: // Move the font name from the input buffer into the pfm structure.
                    539: //
                    540: // Parameters:
                    541: //   None.
                    542: //
                    543: // Returns:
                    544: //   This routine returns no value.
                    545: //
                    546: // History:
                    547: //   18-Mar-1991    -by-    Kent Settle    (kentse)
                    548: //  Brought in from PM, and cleaned up.
                    549: //--------------------------------------------------------------------------
                    550: 
                    551: VOID ParseFontName(pdata)
                    552: PPARSEDATA  pdata;
                    553: {
                    554:     EatWhite(pdata);
                    555: 
                    556:     // get the length of the font name.
                    557: 
                    558:     pdata->cbFontName = strlen((char *)(pdata->szLine)) + 1;
                    559: 
                    560:     // now copy the facename to temporary storage.
                    561: 
                    562:     memcpy(pdata->szTmpFontName, pdata->szLine, pdata->cbFontName);
                    563: 
                    564: #ifdef ALL_METRICS
                    565:     DbgPrint("FontName = %s.\n", pdata->szLine);
                    566: #endif
                    567: }
                    568: 
                    569: 
                    570: //--------------------------------------------------------------------------
                    571: // VOID ParseFullName(pdata)
                    572: // PPARSEDATA  pdata;
                    573: //
                    574: // Move the full name from the input buffer into the pfm structure.
                    575: //
                    576: // Parameters:
                    577: //   None.
                    578: //
                    579: // Returns:
                    580: //   This routine returns no value.
                    581: //
                    582: // History:
                    583: //   29-Mar-1991    -by-    Kent Settle    (kentse)
                    584: //  Wrote it.
                    585: //--------------------------------------------------------------------------
                    586: 
                    587: VOID ParseFullName(pdata)
                    588: PPARSEDATA  pdata;
                    589: {
                    590:     EatWhite(pdata);
                    591: 
                    592:     // get the length of the full name.
                    593: 
                    594:     pdata->cbFullName = strlen((char *)(pdata->szLine)) + 1;
                    595: 
                    596:     // now copy the Uniquename to temporary storage.
                    597: 
                    598:     memcpy(pdata->szTmpFullName, pdata->szLine, pdata->cbFullName);
                    599: 
                    600: #ifdef ALL_METRICS
                    601:     DbgPrint("FullName = %s.\n", pdata->szLine);
                    602: #endif
                    603: }
                    604: 
                    605: 
                    606: //--------------------------------------------------------------------------
                    607: //
                    608: // VOID ParseFamilyName();
                    609: //
                    610: // Move the family name from the input buffer into the pfm structure.
                    611: //
                    612: // Parameters:
                    613: //   None.
                    614: //
                    615: // Returns:
                    616: //   This routine returns no value.
                    617: //
                    618: // History:
                    619: //   29-Mar-1991    -by-    Kent Settle    (kentse)
                    620: //  Wrote it.
                    621: //--------------------------------------------------------------------------
                    622: 
                    623: VOID ParseFamilyName(pdata)
                    624: PPARSEDATA  pdata;
                    625: {
                    626:     EatWhite(pdata);
                    627: 
                    628:     // get the length of the family name.
                    629: 
                    630:     pdata->cbFamilyName = strlen((char *)(pdata->szLine)) + 1;
                    631: 
                    632:     // now copy the familyname to temporary storage.
                    633: 
                    634:     memcpy(pdata->szTmpFamilyName, pdata->szLine, pdata->cbFamilyName);
                    635: 
                    636: #ifdef ALL_METRICS
                    637:     DbgPrint("FamilyNameName = %s.\n", pdata->szLine);
                    638: #endif
                    639: }
                    640: 
                    641: 
                    642: //--------------------------------------------------------------------------
                    643: // VOID ParseMSFamilyName(pdata)
                    644: // PPARSEDATA  pdata;
                    645: //
                    646: // gets the MSFamily name, and converts it to a value.
                    647: //
                    648: // Parameters:
                    649: //   None.
                    650: //
                    651: // Returns:
                    652: //   This routine returns no value.
                    653: //
                    654: // History:
                    655: //   18-Mar-1991    -by-    Kent Settle    (kentse)
                    656: //  Brought in from PM, and cleaned up.
                    657: //--------------------------------------------------------------------------
                    658: 
                    659: VOID ParseMSFamilyName(pdata)
                    660: PPARSEDATA  pdata;
                    661: {
                    662:     char szWord[80];
                    663:     BOOL bFound = FALSE;
                    664:     TABLE_ENTRY  *pTable;
                    665: 
                    666:     // clear out the MSFamily flags.
                    667: 
                    668:     pdata->pTmpIFI->jWinPitchAndFamily &= ~(FF_DECORATIVE | FF_DONTCARE |
                    669:                                             FF_MODERN | FF_ROMAN | FF_SCRIPT |
                    670:                                             FF_SWISS);
                    671:     GetWord(szWord, sizeof(szWord), pdata);
                    672: 
                    673: #ifdef ALL_METRICS
                    674:     DbgPrint("MSFamily = %s\n", szWord);
                    675: #endif
                    676: 
                    677:     pTable = MSFamilyTable;
                    678:     while (pTable->szStr)
                    679:     {
                    680:         if (!strcmp(szWord, pTable->szStr))
                    681:         {
                    682:             pdata->pTmpIFI->jWinPitchAndFamily |= pTable->iValue;
                    683:             bFound = TRUE;
                    684:             break;
                    685:         }
                    686: 
                    687:         ++pTable;
                    688:     }
                    689: 
                    690:     // set flag, if not found.
                    691: 
                    692:     if (!bFound)
                    693:     {
                    694: #if DBG
                    695: #ifdef ALL_METRICS
                    696:         DbgPrint("ParseMSFamilyName: unknown MSFamily = \"%s\"\n", szWord);
                    697: #endif
                    698: #endif
                    699:         pdata->pTmpIFI->jWinPitchAndFamily |= FF_DONTCARE;
                    700:     }
                    701: }
                    702: 
                    703: 
                    704: //--------------------------------------------------------------------------
                    705: // VOID ParseMSFamilyName(pdata)
                    706: // PPARSEDATA  pdata;
                    707: //
                    708: // gets the MSFamily name, and converts it to a value.
                    709: //
                    710: // Parameters:
                    711: //   None.
                    712: //
                    713: // Returns:
                    714: //   This routine returns no value.
                    715: //
                    716: // History:
                    717: //   18-Mar-1991    -by-    Kent Settle    (kentse)
                    718: //  Brought in from PM, and cleaned up.
                    719: //--------------------------------------------------------------------------
                    720: 
                    721: VOID ParsePitch(pdata)
                    722: PPARSEDATA  pdata;
                    723: {
                    724:     CHAR    szWord[6];
                    725: 
                    726:     GetWord(szWord, sizeof(szWord), pdata);
                    727: 
                    728:     pdata->pTmpIFI->jWinPitchAndFamily &= ~(FIXED_PITCH | VARIABLE_PITCH);
                    729: 
                    730:     if ((!(strncmp(szWord, "True", 4))) ||
                    731:         (!(strncmp(szWord, "true", 4))))
                    732:     {
                    733:         pdata->pTmpIFI->jWinPitchAndFamily |= FIXED_PITCH;
                    734: #ifdef ALL_METRICS
                    735:         DbgPrint("Font is fixed pitch.\n");
                    736: #endif
                    737:     }
                    738:     else
                    739:     {
                    740:         pdata->pTmpIFI->jWinPitchAndFamily |= VARIABLE_PITCH;
                    741: #ifdef ALL_METRICS
                    742:         DbgPrint("Font is variable pitch.\n");
                    743: #endif
                    744:     }
                    745: }
                    746: 
                    747: //--------------------------------------------------------------------------
                    748: // VOID ParseWeight(pdata)
                    749: // PPARSEDATA  pdata;
                    750: //
                    751: // Parse the fonts weight and set the corresponding entry in the PFM
                    752: // structure.
                    753: //
                    754: // Parameters:
                    755: //   None.
                    756: //
                    757: // Returns:
                    758: //   This routine returns no value.
                    759: //
                    760: // History:
                    761: //   18-Mar-1991    -by-    Kent Settle    (kentse)
                    762: //  Brought in from PM, and cleaned up.
                    763: //--------------------------------------------------------------------------
                    764: 
                    765: VOID ParseWeight(pdata)
                    766: PPARSEDATA  pdata;
                    767: {
                    768:     char szWord[80];
                    769:     BOOL bFound = FALSE;
                    770:     TABLE_ENTRY  *pTable;
                    771: 
                    772:     GetWord(szWord, sizeof(szWord), pdata);
                    773: 
                    774: #ifdef ALL_METRICS
                    775:     DbgPrint("Weight = %s\n", szWord);
                    776: #endif
                    777: 
                    778:     pTable = WeightTable;
                    779:     while (pTable->szStr)
                    780:     {
                    781: #ifdef ALL_METRICS
                    782:         DbgPrint("\tweight = %s\n", pTable->szStr);
                    783: #endif
                    784:        if (!strcmp(szWord, pTable->szStr))
                    785:         {
                    786:             pdata->pTmpIFI->panose.bWeight = pTable->iValue;
                    787:             bFound = TRUE;
                    788:             break;
                    789:         }
                    790: 
                    791:         ++pTable;
                    792:     }
                    793: 
                    794:     // check for and flag error conditions.
                    795: 
                    796:     if (!bFound)
                    797:     {
                    798: #if DBG
                    799: #ifdef ALL_METRICS
                    800:         DbgPrint("ParseWeight: unknown font weight = \"%s\"\n", szWord);
                    801: #endif
                    802: #endif
                    803:         pdata->pTmpIFI->panose.bWeight = PAN_WEIGHT_MEDIUM;
                    804:     }
                    805: }
                    806: 
                    807: 
                    808: //--------------------------------------------------------------------------
                    809: // BOOL ParseCharMetrics(pdata)
                    810: // PPARSEDATA  pdata;
                    811: //
                    812: // Parse the character metrics entry in the input file and set the
                    813: // width and bounding box in the PFM structure.
                    814: //
                    815: // Parameters:
                    816: //   None.
                    817: //
                    818: // Returns:
                    819: //   This routine returns no value.
                    820: //
                    821: // History:
                    822: //   18-Mar-1991    -by-    Kent Settle    (kentse)
                    823: //  Brought in from PM, and cleaned up.
                    824: //--------------------------------------------------------------------------
                    825: 
                    826: BOOL ParseCharMetrics(pdata)
                    827: PPARSEDATA  pdata;
                    828: {
                    829:     int     cChars;
                    830:     USHORT  usCount = 0;
                    831:     int     i;
                    832:     int     iWidth;
                    833:     int     iChar;
                    834: 
                    835:     cChars = GetNumber(pdata);
                    836:     for (i = 0; i < cChars; ++i)
                    837:     {
                    838:         if (GetLine(pdata))
                    839:         {
                    840:            RIP("PSCRPTUI!ParseCharMetrics: unexpected end of file encountered\n");
                    841:             return(FALSE);
                    842:         }
                    843: 
                    844:         iChar = ParseCharCode(pdata);
                    845: 
                    846:         iWidth = ParseCharWidth(pdata);
                    847: 
                    848:         iChar = ParseCharName(pdata);
                    849: 
                    850:         if (iChar >= 0)
                    851:         {
                    852:             pdata->TmpCharWidths[usCount] = (USHORT)iWidth;
                    853:             pdata->TmpCharCodes[usCount] = (BYTE)iChar;
                    854: 
                    855:             usCount++;   // increment character counter.
                    856: 
                    857: #ifdef ALL_METRICS
                    858:             DbgPrint("iChar = %x, CharWidth = %d\n",
                    859:                      pdata->TmpCharCodes[usCount - 1],
                    860:                      pdata->TmpCharWidths[usCount - 1]);
                    861: #endif
                    862:         }
                    863:     }
                    864: 
                    865:     pdata->pntfm->cCharacters = usCount;
                    866:     GetLine(pdata);
                    867:     if (GetKeyword(AFMKeywordTable, pdata) != TK_ENDCHARMETRICS)
                    868:     {
                    869:        RIP("PSCRPTUI!ParseCharMetrics: expected EndCharMetrics\n");
                    870:        SetLastError(ERROR_INVALID_DATA);
                    871:         return(FALSE);
                    872:     }
                    873: 
                    874:     return(TRUE);
                    875: }
                    876: 
                    877: 
                    878: //--------------------------------------------------------------------------
                    879: // int ParseCharName(pdata)
                    880: // PPARSEDATA  pdata;
                    881: //
                    882: // Parse a character's name and return its numeric value.
                    883: //
                    884: // Parameters:
                    885: //   None.
                    886: //
                    887: // Returns:
                    888: //   This routine returns numeric value of given character.
                    889: //
                    890: // History:
                    891: //   18-Mar-1991    -by-    Kent Settle    (kentse)
                    892: //  Brought in from PM, and cleaned up.
                    893: //--------------------------------------------------------------------------
                    894: 
                    895: int ParseCharName(pdata)
                    896: PPARSEDATA  pdata;
                    897: {
                    898:     int iChar;
                    899:     char szWord[18];
                    900: 
                    901:     EatWhite(pdata);
                    902:     GetWord(szWord, sizeof(szWord), pdata);
                    903: 
                    904:     if (!strcmp("N", szWord))
                    905:     {
                    906:         GetWord(szWord, sizeof(szWord), pdata);
                    907: #ifdef ALL_METRICS
                    908:         DbgPrint("Char = %s ", szWord);
                    909: #endif
                    910:         iChar = GetCharCode(szWord, pdata);
                    911:     }
                    912:     else
                    913:     {
                    914:        RIP("PSCRPTUI!ParseCharName: expected name field\n");
                    915:        SetLastError(ERROR_INVALID_DATA);
                    916:         return(-1);
                    917:     }
                    918: 
                    919:     return(iChar);
                    920: }
                    921: 
                    922: 
                    923: //--------------------------------------------------------------------------
                    924: // int ParseCharWidth(pdata)
                    925: // PPARSEDATA  pdata;
                    926: //
                    927: // Parse a character's width and return its numeric value.
                    928: //
                    929: // Parameters:
                    930: //   None.
                    931: //
                    932: // Returns:
                    933: //   This routine returns numeric value of given character's width.
                    934: //
                    935: // History:
                    936: //   18-Mar-1991    -by-    Kent Settle    (kentse)
                    937: //  Brought in from PM, and cleaned up.
                    938: //--------------------------------------------------------------------------
                    939: 
                    940: int ParseCharWidth(pdata)
                    941: PPARSEDATA  pdata;
                    942: {
                    943:     int iWidth;
                    944:     char szWord[16];
                    945: 
                    946:     GetWord(szWord, sizeof(szWord), pdata);
                    947:     if (!strcmp("WX", szWord))
                    948:     {
                    949:         iWidth = GetNumber(pdata);
                    950:         if (iWidth==0)
                    951:         {
                    952:            RIP("PSCRPTUI!ParseCharWidth: zero character width\n");
                    953:            SetLastError(ERROR_INVALID_DATA);
                    954:             return(-1);
                    955:         }
                    956: 
                    957:         EatWhite(pdata);
                    958:         if (*(pdata->szLine++) != ';')
                    959:         {
                    960:            RIP("PSCRPTUI!ParseCharWidth: missing semicolon\n");
                    961:            SetLastError(ERROR_INVALID_DATA);
                    962:             return(-1);
                    963:         }
                    964:     }
                    965:     else
                    966:     {
                    967:        RIP("PSCRPTUI!ParseCharWidth: expected \"WX\"\n");
                    968:        SetLastError(ERROR_INVALID_DATA);
                    969:         return(-1);
                    970:     }
                    971: 
                    972:     return(iWidth);
                    973: }
                    974: 
                    975: 
                    976: //--------------------------------------------------------------------------
                    977: // int ParseCharCode(pdata)
                    978: // PPARSEDATA  pdata;
                    979: //
                    980: // Parse the ASCII form of a character's code point and return its
                    981: // numeric value.
                    982: //
                    983: // Parameters:
                    984: //   None.
                    985: //
                    986: // Returns:
                    987: //   This routine returns numeric value of given character's codepoint.
                    988: //
                    989: // History:
                    990: //   18-Mar-1991    -by-    Kent Settle    (kentse)
                    991: //  Brought in from PM, and cleaned up.
                    992: //--------------------------------------------------------------------------
                    993: 
                    994: int ParseCharCode(pdata)
                    995: PPARSEDATA  pdata;
                    996: {
                    997:     int iChar;
                    998:     char szWord[16];
                    999: 
                   1000:     iChar = 0;
                   1001:     GetWord(szWord, sizeof(szWord), pdata);
                   1002:     if (!strcmp("C", szWord))
                   1003:     {
                   1004:         iChar = GetNumber(pdata);
                   1005:         if (iChar==0)
                   1006:         {
                   1007:            RIP("PSCRPTUI!ParseCharCode: invalid character code\n");
                   1008:            SetLastError(ERROR_INVALID_DATA);
                   1009:             return(-1);
                   1010:         }
                   1011: 
                   1012:         EatWhite(pdata);
                   1013:         if (*(pdata->szLine++) != ';')
                   1014:         {
                   1015:            RIP("PSCRPTUI!ParseCharCode: missing semicolon\n");
                   1016:            SetLastError(ERROR_INVALID_DATA);
                   1017:             return(-1);
                   1018:         }
                   1019:     }
                   1020:     return(iChar);
                   1021: }
                   1022: 
                   1023: 
                   1024: //--------------------------------------------------------------------------
                   1025: // VOID ParseBoundingBox(pdata)
                   1026: // PPARSEDATA  pdata;
                   1027: //
                   1028: // Parses a characters's bounding box and stores its size in
                   1029: // the NTFM structure.
                   1030: //
                   1031: // Parameters:
                   1032: //   None.
                   1033: //
                   1034: // Returns:
                   1035: //   This routine returns no value.
                   1036: //
                   1037: // History:
                   1038: //   18-Mar-1991    -by-    Kent Settle    (kentse)
                   1039: //  Brought in from PM, and cleaned up.
                   1040: //--------------------------------------------------------------------------
                   1041: 
                   1042: VOID ParseBoundingBox(pdata)
                   1043: PPARSEDATA  pdata;
                   1044: {
                   1045:     pdata->pntfm->rcBBox.left = GetNumber(pdata);
                   1046:     pdata->pntfm->rcBBox.bottom = GetNumber(pdata);
                   1047:     pdata->pntfm->rcBBox.right = GetNumber(pdata);
                   1048:     pdata->pntfm->rcBBox.top = GetNumber(pdata);
                   1049: }
                   1050: 
                   1051: 
                   1052: 
                   1053: //--------------------------------------------------------------------------
                   1054: // BOOL WritePFM(pwstrPFMFile, pdata)
                   1055: // PWSTR       pwstrPFMFile;
                   1056: // PPARSEDATA  pdata;
                   1057: //
                   1058: // Flush the ouput buffer to the file.    Note that this function is only
                   1059: // called after the entire pfm structure has been built in the output buffer.
                   1060: //
                   1061: // Parameters:
                   1062: //   None.
                   1063: //
                   1064: // Returns:
                   1065: //   This routine returns TRUE if success, FALSE otherwise.
                   1066: //
                   1067: // History:
                   1068: //   20-Mar-1991    -by-    Kent Settle    (kentse)
                   1069: //  Wrote it.
                   1070: //--------------------------------------------------------------------------
                   1071: 
                   1072: BOOL WritePFM(pwstrPFMFile, pdata)
                   1073: PWSTR       pwstrPFMFile;
                   1074: PPARSEDATA  pdata;
                   1075: {
                   1076:     HANDLE  hPFMFile;
                   1077:     ULONG   ulCount;
                   1078: 
                   1079:     // create the .PFM file.
                   1080: 
                   1081:     hPFMFile = CreateFile(pwstrPFMFile, GENERIC_WRITE, FILE_SHARE_READ, NULL,
                   1082:                           CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
                   1083: 
                   1084:     if (hPFMFile == INVALID_HANDLE_VALUE)
                   1085:     {
                   1086:        RIP("PSCRPTUI!WritePFM: Can't open .PFM file.\n");
                   1087:        return(FALSE);
                   1088:     }
                   1089: 
                   1090:     // write to the .PFM file, then close it.
                   1091: 
                   1092:     if (!WriteFile(hPFMFile, (LPVOID)pdata->pntfm, (DWORD)pdata->pntfm->cjThis,
                   1093:              (LPDWORD)&ulCount, (LPOVERLAPPED)NULL))
                   1094:     {
                   1095:        RIP("PSCRPTUI!WritePFM: WriteFile to .PFM file failed.\n");
                   1096:        return(FALSE);
                   1097:     }
                   1098: 
                   1099:     if (ulCount != pdata->pntfm->cjThis)
                   1100:     {
                   1101:        RIP("PSCRPTUI!WritePFM: WriteFile count to .PFM file failed.\n");
                   1102:        return(FALSE);
                   1103:     }
                   1104: 
                   1105:     if (!CloseHandle(hPFMFile))
                   1106:        RIP("PSCRPTUI!WritePFM: CloseHandle of .PFM file failed.\n");
                   1107: 
                   1108:     return(TRUE);
                   1109: }
                   1110: 
                   1111: 
                   1112: //--------------------------------------------------------------------------
                   1113: //
                   1114: // int GetCharCode(szWord, pdata)
                   1115: // char       *szWord;
                   1116: // PPARSEDATA  pdata;
                   1117: //
                   1118: // This routine is given a pointer to the character string.  It returns
                   1119: // the character code, as defined in mapping.h, corresponding to this
                   1120: // character.
                   1121: //
                   1122: // Parameters:
                   1123: //   szWord
                   1124: //     Pointer to character name string.
                   1125: //
                   1126: // Returns:
                   1127: //   This routine returns -1 if character not found, otherwise it
                   1128: //   returns the character code.
                   1129: //
                   1130: // History:
                   1131: //   27-Mar-1991    -by-    Kent Settle    (kentse)
                   1132: //  Wrote it.
                   1133: //--------------------------------------------------------------------------
                   1134: 
                   1135: int GetCharCode(szWord, pdata)
                   1136: char       *szWord;
                   1137: PPARSEDATA  pdata;
                   1138: {
                   1139:     UCMap  *pmap;
                   1140: 
                   1141:     //!!! maybe there is a better way to do this???
                   1142: 
                   1143:     // point to the appropriate mapping table in mapping.h.
                   1144: 
                   1145:     if (!strcmp(pdata->szTmpFontName, "Symbol"))
                   1146:         pmap = SymbolMap;
                   1147:     else if (!strcmp(pdata->szTmpFontName, "ZapfDingbats"))
                   1148:         pmap = DingbatsMap;
                   1149:     else
                   1150:         pmap = LatinMap;
                   1151: 
                   1152:     while (pmap->szChar)
                   1153:     {
                   1154:        if (!strcmp(szWord, pmap->szChar))
                   1155:             return((int)(pmap->usPSValue & 0x7FFF));
                   1156:         pmap++;
                   1157:     }
                   1158: 
                   1159: #ifdef ALL_METRICS
                   1160:     DbgPrint("GetCharCode: Undefined Character = %s.\n", szWord);
                   1161: #endif
                   1162:     return(-1);
                   1163: }
                   1164: 
                   1165: 
                   1166: //--------------------------------------------------------------------------
                   1167: //
                   1168: // BOOL GetFirstLastChar()
                   1169: //
                   1170: // This routine searches through the encoding table in mapping.h to
                   1171: // determine the first and last characters in the font.  The character
                   1172: // codes are stored into the NTFM structure in UNICODE value.
                   1173: //
                   1174: // Parameters:
                   1175: //   None.
                   1176: //
                   1177: // Returns:
                   1178: //   This routine returns TRUE for success, FALSE otherwise.
                   1179: //
                   1180: // History:
                   1181: //   18-Apr-1991    -by-    Kent Settle    (kentse)
                   1182: //  Wrote it.
                   1183: //--------------------------------------------------------------------------
                   1184: 
                   1185: BOOL GetFirstLastChar(pdata)
                   1186: PPARSEDATA  pdata;
                   1187: {
                   1188:     PUCMap  pmap;
                   1189:     PUCMap  pmapReset;
                   1190:     USHORT  usFirst = MAX_UNICODE_VALUE;
                   1191:     USHORT  usLast = MIN_UNICODE_VALUE;
                   1192:     USHORT  i;
                   1193:     USHORT  usTmp;
                   1194: 
                   1195:     //!!! maybe there is a better way to do this???
                   1196: 
                   1197:     // point to the appropriate mapping table in mapping.h.
                   1198: 
                   1199:     if (!strcmp(pdata->szTmpFontName, "Symbol"))
                   1200:         pmap = SymbolMap;
                   1201:     else if (!strcmp(pdata->szTmpFontName, "ZapfDingbats"))
                   1202:         pmap = DingbatsMap;
                   1203:     else
                   1204:         pmap = LatinMap;
                   1205: 
                   1206:     pmapReset = pmap;
                   1207: 
                   1208:     // for every character in the font, do a lookup in the mapping
                   1209:     // table in mapping.h to find the corresponding UNICODE value.
                   1210: 
                   1211:     for (i = 0; i < pdata->pntfm->cCharacters; i++)
                   1212:     {
                   1213:         while (pmap->szChar)
                   1214:         {
                   1215:             if ((BYTE)pdata->TmpCharCodes[i] == (BYTE)(pmap->usPSValue & 0xFF))
                   1216:             {
                   1217:                 usTmp = pmap->usUCValue;
                   1218:                 if (usFirst > usTmp)
                   1219:                     usFirst = usTmp;
                   1220:                 if (usLast < usTmp)
                   1221:                     usLast = usTmp;
                   1222:                 break;
                   1223:             }
                   1224: 
                   1225:             pmap++;
                   1226:         }
                   1227: 
                   1228:         // reset pointer.
                   1229: 
                   1230:         pmap = pmapReset;
                   1231:     }
                   1232: 
                   1233:     // make sure we have valid numbers.
                   1234: 
                   1235:     if (usFirst > usLast)
                   1236:     {
                   1237:        RIP("PSCRPTUI!etFirstLastChar: first char > last.\n");
                   1238:        SetLastError(ERROR_INVALID_DATA);
                   1239:        return(FALSE);
                   1240:     }
                   1241: 
                   1242:     // everything must be OK.
                   1243: 
                   1244:     pdata->pTmpIFI->wcFirstChar = (WCHAR)usFirst;
                   1245:     pdata->pTmpIFI->wcLastChar = (WCHAR)usLast;
                   1246: 
                   1247: #ifdef ALL_METRICS
                   1248:     DbgPrint("FirstChar = %x, LastChar = %x.\n", usFirst, usLast);
                   1249: #endif
                   1250: 
                   1251:     return(TRUE);
                   1252: }
                   1253: 
                   1254: 
                   1255: //--------------------------------------------------------------------------
                   1256: //
                   1257: // VOID BuildNTFM(pdata, pPFA)
                   1258: // PPARSEDATA  pdata;
                   1259: // CHAR       *pPFA;
                   1260: //
                   1261: // This routine builds an NTFM structure from all the temporary values
                   1262: // which have been determined by now.
                   1263: //
                   1264: // Returns:
                   1265: //   This routine returns no value.
                   1266: //
                   1267: // History:
                   1268: //   18-Apr-1991    -by-    Kent Settle    (kentse)
                   1269: //  Wrote it.
                   1270: //--------------------------------------------------------------------------
                   1271: 
                   1272: VOID BuildNTFM(pdata, pPFA)
                   1273: PPARSEDATA  pdata;
                   1274: CHAR       *pPFA;
                   1275: {
                   1276:     PNTFM       pntfm;
                   1277:     int         cbKernPairs, cbWidths;
                   1278:     DWORD       cbPFA;
                   1279:     PSTR        pstr;
                   1280: 
                   1281:     // get local pointer.
                   1282: 
                   1283:     pntfm = pdata->pntfm;
                   1284: 
                   1285:     // deal with the softfont if there is one.
                   1286: 
                   1287:     if (pPFA)
                   1288:     {
                   1289:         // the first DWORD of the .PFA file contains the length in BYTES of the
                   1290:         // remainder of the .PFA file.
                   1291: 
                   1292:         cbPFA = *(DWORD *)pPFA;
                   1293:         pntfm->cjSoftFont = DWORDALIGN(cbPFA);
                   1294:     }
                   1295: 
                   1296:     // there are several bits of data which have now been put into temporary
                   1297:     // storage, but need to be attached to the NTFM structure.
                   1298: 
                   1299:     cbKernPairs = (pntfm->cKernPairs * sizeof(FD_KERNINGPAIR));
                   1300:     cbWidths = DWORDALIGN(pntfm->cCharacters * sizeof(USHORT));
                   1301:     pntfm->cjThis += DWORDALIGN(pdata->cbFullName) + DWORDALIGN(pdata->cbFontName) +
                   1302:                      DWORDALIGN(pdata->cbFamilyName) + DWORDALIGN(cbKernPairs) +
                   1303:                      cbWidths + DWORDALIGN(pntfm->cCharacters) +
                   1304:                      DWORDALIGN(pntfm->cjSoftFont);
                   1305: 
                   1306:     if (pntfm->cjThis > INIT_PFM)
                   1307:     {
                   1308: #if DBG
                   1309:         DbgPrint("afm: PFM size greater than allocated.\n");
                   1310: #endif
                   1311:         return;
                   1312:     }
                   1313: 
                   1314:     pntfm->loszFullName = DWORDALIGN(sizeof(NTFM));
                   1315:     pntfm->loszFontName = pntfm->loszFullName + DWORDALIGN(pdata->cbFullName);
                   1316:     pntfm->loszFamilyName = pntfm->loszFontName + DWORDALIGN(pdata->cbFontName);
                   1317:     pntfm->loKernPairs = pntfm->loszFamilyName +
                   1318:                          DWORDALIGN(pdata->cbFamilyName);
                   1319:     pntfm->loCharMetrics = pntfm->loKernPairs + DWORDALIGN(cbKernPairs);
                   1320: 
                   1321:     if (pPFA)
                   1322:         pntfm->loSoftFont = pntfm->loCharMetrics +
                   1323:                             DWORDALIGN(pntfm->cCharacters) + cbWidths;
                   1324: 
                   1325:     pntfm->loIFIMETRICS = pntfm->loCharMetrics +
                   1326:                           DWORDALIGN(pntfm->cCharacters) + cbWidths +
                   1327:                           DWORDALIGN(pntfm->cjSoftFont);
                   1328: 
                   1329:     pstr = (char *)pntfm + pntfm->loszFullName;
                   1330:     memcpy(pstr, pdata->szTmpFullName, pdata->cbFullName);
                   1331:     pstr += DWORDALIGN(pdata->cbFullName);
                   1332:     memcpy(pstr, pdata->szTmpFontName, pdata->cbFontName);
                   1333:     pstr += DWORDALIGN(pdata->cbFontName);
                   1334:     memcpy(pstr, (char *)pdata->szTmpFamilyName, pdata->cbFamilyName);
                   1335:     pstr += DWORDALIGN(pdata->cbFamilyName);
                   1336:     memcpy(pstr, (char *)pdata->TmpKernPairs, cbKernPairs);
                   1337:     pstr += DWORDALIGN(cbKernPairs);
                   1338:     memcpy(pstr, (char *)pdata->TmpCharWidths, cbWidths);
                   1339:     pstr += cbWidths;
                   1340:     memcpy(pstr, (char *)pdata->TmpCharCodes, pntfm->cCharacters);
                   1341:     pstr += DWORDALIGN(pntfm->cCharacters);
                   1342: 
                   1343: #ifdef ALL_METRICS
                   1344:     DbgPrint("FullName = %s\n", (char *)pntfm + pntfm->loszFullName);
                   1345:     DbgPrint("FontName = %s\n", (char *)pntfm + pntfm->loszFontName);
                   1346:     DbgPrint("FamilyName = %s\n", (char *)pntfm + pntfm->loszFamilyName);
                   1347: #endif
                   1348: 
                   1349:     // deal with the soft font, if there is one.
                   1350: 
                   1351:     if (pPFA)
                   1352:     {
                   1353:         // skip over the DWORD count.
                   1354: 
                   1355:         pPFA += sizeof(DWORD);
                   1356:         memcpy(pstr, pPFA, cbPFA);
                   1357:         pstr += DWORDALIGN(cbPFA);
                   1358:     }
                   1359: 
                   1360:     // fill in the rest of the IFIMETRICS.
                   1361: 
                   1362:     CompleteIFIMETRICS(pdata);
                   1363: 
                   1364:     pntfm->cjThis += pdata->pTmpIFI->cjThis;
                   1365: 
                   1366:     // copy the IFIMETRICS stucture to the NTFM.
                   1367: 
                   1368:     memcpy(pstr, (CHAR *)pdata->pTmpIFI, pdata->pTmpIFI->cjThis);
                   1369: }
                   1370: 
                   1371: 
                   1372: //--------------------------------------------------------------------------
                   1373: //
                   1374: // VOID InitIFIMETRICS(pdata)
                   1375: // PPARSEDATA  pdata;
                   1376: //
                   1377: // This routine initializes the IFIMETRICS structure with default values.
                   1378: //
                   1379: // Returns:
                   1380: //   This routine returns no value.
                   1381: //
                   1382: // History:
                   1383: //   25-Mar-1993    -by-    Kent Settle    (kentse)
                   1384: //  Wrote it.
                   1385: //--------------------------------------------------------------------------
                   1386: 
                   1387: VOID InitIFIMETRICS(pdata)
                   1388: PPARSEDATA  pdata;
                   1389: {
                   1390:     PIFIMETRICS pTmpIFI;
                   1391: 
                   1392:     pTmpIFI = pdata->pTmpIFI;
                   1393: 
                   1394:     // initialize the size of the structure
                   1395:     // we will have to add the size of added strings later
                   1396: 
                   1397:     pTmpIFI->cjThis    = DWORDALIGN(sizeof(IFIMETRICS));
                   1398: 
                   1399:     pTmpIFI->ulVersion = FM_VERSION_NUMBER;
                   1400: 
                   1401:     pTmpIFI->jWinCharSet            =  ANSI_CHARSET;                // !!! i guess
                   1402:     pTmpIFI->jWinPitchAndFamily     =  FF_DONTCARE | VARIABLE_PITCH;// !!! i Guess
                   1403:     pTmpIFI->flInfo                 =  FM_INFO_ARB_XFORMS                  |
                   1404:                                        FM_INFO_NOT_CONTIGUOUS              |
                   1405:                                        FM_INFO_TECH_OUTLINE_NOT_TRUETYPE   |
                   1406:                                        FM_INFO_1BBP                        |
                   1407:                                        FM_INFO_RIGHT_HANDED;
                   1408:     pTmpIFI->fsType                 =  FM_NO_EMBEDDING;
                   1409:     pTmpIFI->fwdUnitsPerEm          =  1000;             // for PostScript fonts.
                   1410:     pTmpIFI->fwdLowestPPEm          =  1;                // !!!I guess [kirko]
                   1411: 
                   1412:     pTmpIFI->fwdCapHeight           =  0;                       //!!![kirko] Kent-can you do better?
                   1413:     pTmpIFI->fwdSubscriptXSize      =  300;                     // !!! a guess
                   1414:     pTmpIFI->fwdSubscriptYSize      =  300;                     // !!! a guess
                   1415:     pTmpIFI->fwdSubscriptXOffset    =  600;                     // !!! a guess
                   1416:     pTmpIFI->fwdSubscriptYOffset    = -100;                     // !!! a guess
                   1417:     pTmpIFI->fwdSuperscriptXSize    =  300;                     // !!! a guess
                   1418:     pTmpIFI->fwdSuperscriptYSize    =  300;                     // !!! a guess
                   1419:     pTmpIFI->fwdSuperscriptXOffset  =  600;                     // !!! a guess
                   1420:     pTmpIFI->fwdSuperscriptYOffset  =  300;                     // !!! a guess
                   1421: 
                   1422:     pTmpIFI->wcBreakChar            = U_SPACE;
                   1423:     WideCharToMultiByte(CP_ACP, 0, (LPWSTR)&pTmpIFI->wcBreakChar, 1,
                   1424:                         (LPSTR)&pTmpIFI->chBreakChar, 1, NULL, NULL);
                   1425: 
                   1426:     pTmpIFI->ptlBaseline.x          = 1;
                   1427:     pTmpIFI->ptlBaseline.y          = 0;
                   1428:     pTmpIFI->ptlAspect.x            = 1;
                   1429:     pTmpIFI->ptlAspect.y            = 1;
                   1430:     pTmpIFI->achVendId[0]           = 'U';
                   1431:     pTmpIFI->achVendId[1]           = 'n';
                   1432:     pTmpIFI->achVendId[2]           = 'k';
                   1433:     pTmpIFI->achVendId[3]           = 'n';
                   1434:     pTmpIFI->ulPanoseCulture        = FM_PANOSE_CULTURE_LATIN;
                   1435:     pTmpIFI->panose.bFamilyType     = PAN_ANY;
                   1436:     pTmpIFI->panose.bSerifStyle     = PAN_ANY;
                   1437:     pTmpIFI->panose.bProportion     = PAN_ANY;
                   1438:     pTmpIFI->panose.bContrast       = PAN_ANY;
                   1439:     pTmpIFI->panose.bStrokeVariation= PAN_ANY;
                   1440:     pTmpIFI->panose.bArmStyle       = PAN_ANY;
                   1441:     pTmpIFI->panose.bLetterform     = PAN_ANY;
                   1442:     pTmpIFI->panose.bMidline        = PAN_ANY;
                   1443:     pTmpIFI->panose.bXHeight        = PAN_ANY;
                   1444: }
                   1445: 
                   1446: 
                   1447: 
                   1448: //--------------------------------------------------------------------------
                   1449: //
                   1450: // VOID CompleteIFIMETRICS(pdata)
                   1451: // PPARSEDATA  pdata;
                   1452: //
                   1453: // This routine fill in IFIMETRICS values using NTFM values.
                   1454: //
                   1455: // Returns:
                   1456: //   This routine returns no value.
                   1457: //
                   1458: // History:
                   1459: //   25-Mar-1993    -by-    Kent Settle    (kentse)
                   1460: //  Wrote it.
                   1461: //--------------------------------------------------------------------------
                   1462: 
                   1463: VOID CompleteIFIMETRICS(pdata)
                   1464: PPARSEDATA  pdata;
                   1465: {
                   1466:     PIFIMETRICS     pTmpIFI;
                   1467:     WINFONTPAIR    *pTable;
                   1468:     BOOL            bFound;
                   1469:     PSTR            pstr;
                   1470:     PNTFM           pntfm;
                   1471:     LONG            InternalLeading;
                   1472: 
                   1473:     // get local pointers.
                   1474: 
                   1475:     pntfm = pdata->pntfm;
                   1476:     pTmpIFI = pdata->pTmpIFI;
                   1477: 
                   1478:     // for Win31 compatability - if there is a match in WinFontTable for
                   1479:     // the Adobe facename, use the Windows Face Name for the IFIMETRICS
                   1480:     // family name, otherwise, use the Adobe family name.
                   1481: 
                   1482: //!!! use nls conversion for this.
                   1483: 
                   1484:     pTable = (WINFONTPAIR *)WinFontTable;
                   1485:     bFound = FALSE;
                   1486: 
                   1487:     while(pTable->pstrAdobeFace)
                   1488:     {
                   1489:         if (!(strncmp(pTable->pstrAdobeFace,
                   1490:              (CHAR *)pntfm + pntfm->loszFontName, MAX_FONT_NAME)))
                   1491:         {
                   1492:             pstr = pTable->pstrWinFace;
                   1493:             bFound = TRUE;
                   1494:             break;
                   1495:         }
                   1496: 
                   1497:         pTable++;
                   1498:     }
                   1499: 
                   1500:     if (!bFound)
                   1501:         pstr = (CHAR *)pntfm + pntfm->loszFamilyName;
                   1502: 
                   1503:     // WIN31 COMPATABILITY!  Check to see if this face name has aliases.
                   1504:     // if it does, then we need to set the FM_INFO_FAMILY_EQUIV bit of
                   1505:     // pTmpIFI->flInfo, and fill in an array of family aliases.
                   1506: 
                   1507:     GetFamilyAliases(pTmpIFI, pstr);
                   1508: 
                   1509:     // make the style name the same as the family name.
                   1510: 
                   1511:     pTmpIFI->dpwszStyleName = pTmpIFI->dpwszFamilyName;
                   1512: 
                   1513:     // get the face name for the font.
                   1514: 
                   1515:     pTmpIFI->dpwszFaceName = pTmpIFI->cjThis;
                   1516: 
                   1517:     strcpy2WChar((PWSZ)((char *)pTmpIFI + pTmpIFI->dpwszFaceName),
                   1518:                  (PSZ)((char *)pntfm + pntfm->loszFontName));
                   1519: 
                   1520:     // while we have the face name, lets fill in the windows compatability
                   1521:     // stuff.
                   1522: 
                   1523:     if (!strcmp((char *)pntfm + pntfm->loszFontName, "Symbol"))
                   1524:         pTmpIFI->jWinCharSet = SYMBOL_CHARSET;
                   1525:     else if (!strcmp((char *)pntfm + pntfm->loszFontName, "ZapfDingbats"))
                   1526:         pTmpIFI->jWinCharSet = OEM_CHARSET;
                   1527:     else
                   1528:         pTmpIFI->jWinCharSet = ANSI_CHARSET;
                   1529: 
                   1530:     pTmpIFI->chFirstChar = (BYTE)0x20;
                   1531:     pTmpIFI->chLastChar = (BYTE)0xFE;
                   1532: 
                   1533:     pTmpIFI->cjThis += ((wcslen((PWSZ)((char *)pTmpIFI +
                   1534:                                pTmpIFI->dpwszFaceName)) + 1) * sizeof(WCHAR));
                   1535: 
                   1536:     // get the unique name for the font.
                   1537: 
                   1538:     pTmpIFI->dpwszUniqueName = pTmpIFI->cjThis;
                   1539:     strcpy2WChar((PWSZ)((char *)pTmpIFI + pTmpIFI->dpwszUniqueName),
                   1540:                  (PSZ)((char *)pntfm + pntfm->loszFullName));
                   1541:     pTmpIFI->cjThis += ((wcslen((PWSZ)((char *)pTmpIFI +
                   1542:                               pTmpIFI->dpwszUniqueName)) + 1) * sizeof(WCHAR));
                   1543: 
                   1544:     pTmpIFI->dpFontSim              =  0;
                   1545: 
                   1546:     pTmpIFI->fwdWinAscender         =  (FWORD) pntfm->rcBBox.top;
                   1547:     pTmpIFI->fwdWinDescender        = -(FWORD) pntfm->rcBBox.bottom;
                   1548:     pTmpIFI->fwdMacAscender         =  pTmpIFI->fwdWinAscender;
                   1549:     pTmpIFI->fwdMacDescender        =  -pTmpIFI->fwdWinDescender;
                   1550: 
                   1551:     // as windows does, set total leading to 19.6% of EmHeight.
                   1552:     // therefore, ExternalLeading = 196 - InternalLeading.
                   1553: 
                   1554:     InternalLeading = (pntfm->rcBBox.top - pntfm->rcBBox.bottom) -
                   1555:                       ADOBE_FONT_UNITS;
                   1556: 
                   1557:     if (InternalLeading < 0)
                   1558:         InternalLeading = 0;
                   1559: 
                   1560:     pTmpIFI->fwdMacLineGap          =  196 - InternalLeading;
                   1561:     if (pTmpIFI->fwdMacLineGap < 0)
                   1562:         pTmpIFI->fwdMacLineGap = 0;
                   1563: 
                   1564:     pTmpIFI->fwdTypoLineGap         =  0;
                   1565:     pTmpIFI->fwdTypoAscender        =  pTmpIFI->fwdWinAscender;
                   1566:     pTmpIFI->fwdTypoDescender       =  pTmpIFI->fwdWinDescender;
                   1567:     pTmpIFI->fwdStrikeoutPosition   =  pTmpIFI->fwdWinAscender / 2;
                   1568: 
                   1569:     // hardcoded from mapping.h values.
                   1570: 
                   1571:     if (!(strcmp((char *) pntfm + pntfm->loszFontName, "ZapfDingbats")))
                   1572:     {
                   1573:         pTmpIFI->wcDefaultChar = U_SPACE;
                   1574:         pTmpIFI->chDefaultChar = (BYTE)0x20;
                   1575:     }
                   1576:     else if (!(strcmp((char *) pntfm + pntfm->loszFontName, "Symbol")))
                   1577:     {
                   1578:         pTmpIFI->wcDefaultChar = U_SYMBOL_BULLET;
                   1579:         pTmpIFI->chDefaultChar = (BYTE)0xB7;
                   1580:     }
                   1581: 
                   1582:     else
                   1583:     {
                   1584:         pTmpIFI->wcDefaultChar = U_BULLET;
                   1585:         pTmpIFI->chDefaultChar = (BYTE)0x8C;
                   1586:     }
                   1587: 
                   1588:     WideCharToMultiByte(CP_ACP, 0, (LPWSTR)&pTmpIFI->wcDefaultChar, 1,
                   1589:                         (LPSTR)&pTmpIFI->chDefaultChar, 1, NULL, NULL);
                   1590: 
                   1591:     pTmpIFI->cKerningPairs          = pntfm->cKernPairs;
                   1592: 
                   1593:     // set the average and maximum character widths for the font.
                   1594: 
                   1595:     SetWidths(pdata);
                   1596: 
                   1597:     // find the first and last characters for the given font.
                   1598: 
                   1599:     GetFirstLastChar(pdata);
                   1600: }
                   1601: 
                   1602: 
                   1603: //--------------------------------------------------------------------------
                   1604: //
                   1605: // VOID GetFamilyAliases(pifi, pstr)
                   1606: // IFIMETRICS *pifi;
                   1607: // PSTR        pstr;
                   1608: //
                   1609: // This routine fill in the family name of the IFIMETRICS structure.
                   1610: //
                   1611: // Returns:
                   1612: //   This routine returns no value.
                   1613: //
                   1614: // History:
                   1615: //   25-Mar-1993    -by-    Kent Settle    (kentse)
                   1616: //  Wrote it.
                   1617: //--------------------------------------------------------------------------
                   1618: 
                   1619: VOID GetFamilyAliases(pifi, pstr)
                   1620: IFIMETRICS *pifi;
                   1621: PSTR        pstr;
                   1622: {
                   1623:     PSTR       *pTable;
                   1624:     PWSTR       pwstr;
                   1625:     DWORD       cb;
                   1626: 
                   1627:     // assume no alias table found.
                   1628: 
                   1629:     pTable = (PSTR *)(NULL);
                   1630: 
                   1631:     // this is an ugly hardcoded Win31 Hack that we need to be compatible
                   1632:     // with since some stupid apps have hardcoded font names.
                   1633: 
                   1634:     if (!(strcmp(pstr, "Times")))
                   1635:         pTable = TimesAlias;
                   1636: 
                   1637:     else if (!(strcmp(pstr, "Helvetica")))
                   1638:         pTable = HelveticaAlias;
                   1639: 
                   1640:     else if (!(strcmp(pstr, "Courier")))
                   1641:         pTable = CourierAlias;
                   1642: 
                   1643:     else if (!(strcmp(pstr, "Helvetica-Narrow")))
                   1644:         pTable = HelveticaNarrowAlias;
                   1645: 
                   1646:     else if (!(strcmp(pstr, "Palatino")))
                   1647:         pTable = PalatinoAlias;
                   1648: 
                   1649:     else if (!(strcmp(pstr, "Bookman")))
                   1650:         pTable = BookmanAlias;
                   1651: 
                   1652:     else if (!(strcmp(pstr, "NewCenturySchlbk")))
                   1653:         pTable = NewCenturySBAlias;
                   1654: 
                   1655:     else if (!(strcmp(pstr, "AvantGarde")))
                   1656:         pTable = AvantGardeAlias;
                   1657: 
                   1658:     else if (!(strcmp(pstr, "ZapfChancery")))
                   1659:         pTable = ZapfChanceryAlias;
                   1660: 
                   1661:     else if (!(strcmp(pstr, "ZapfDingbats")))
                   1662:         pTable = ZapfDingbatsAlias;
                   1663: 
                   1664:     // get offset to family name from start of IFIMETRICS structure.
                   1665: 
                   1666:     pifi->dpwszFamilyName = pifi->cjThis;
                   1667:     pwstr = (PWSZ)((char *)pifi + pifi->dpwszFamilyName);
                   1668: 
                   1669:     if (pTable)
                   1670:     {
                   1671:         // set the pifi->flInfo flag.
                   1672: 
                   1673:         pifi->flInfo |= FM_INFO_FAMILY_EQUIV;
                   1674: 
                   1675:         // now fill in the array of alias family names.
                   1676: 
                   1677:         while (*pTable)
                   1678:         {
                   1679:             strcpy2WChar(pwstr, (PSTR)*pTable++);
                   1680:             cb = ((wcslen(pwstr) + 1) * sizeof(WCHAR));
                   1681:             pifi->cjThis += cb;
                   1682:             pwstr += (cb >> 1);
                   1683:         }
                   1684: 
                   1685:         // add the extra NULL terminator to the end of the array.
                   1686: 
                   1687:         *pwstr = (WCHAR)'\0';
                   1688:         pifi->cjThis += sizeof(WCHAR);
                   1689:     }
                   1690:     else
                   1691:     {
                   1692:         // fill in the single family name.
                   1693: 
                   1694:         strcpy2WChar(pwstr, pstr);
                   1695:         pifi->cjThis += ((wcslen(pwstr) + 1) * sizeof(WCHAR));
                   1696:     }
                   1697: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.