Annotation of ntddk/src/print/pslib/afmtopfm.c, revision 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.