Annotation of ntddk/src/print/pscript/fontdata.c, revision 1.1.1.1

1.1       root        1: //--------------------------------------------------------------------------
                      2: //
                      3: // Module Name:  FONTDATA.C
                      4: //
                      5: // Brief Description:  Device font data querying routines
                      6: //
                      7: // Author:  Kent Settle (kentse)
                      8: // Created: 25-Apr-1991
                      9: //
                     10: // Copyright (C) 1991 - 1992 Microsoft Corporation.
                     11: //
                     12: // This module contains DrvQueryFontData and related routines.
                     13: //
                     14: // History:
                     15: //   25-Apr-1991    -by-    Kent Settle       (kentse)
                     16: // Created.
                     17: //--------------------------------------------------------------------------
                     18: 
                     19: #include "pscript.h"
                     20: #include "enable.h"
                     21: #include "resource.h"
                     22: #include <memory.h>
                     23: #include "winbase.h"
                     24: 
                     25: #define WIN31_INTEGER_METRICS
                     26: 
                     27: extern HMODULE     ghmodDrv;    // GLOBAL MODULE HANDLE.
                     28: extern LONG iHipot(LONG, LONG);
                     29: 
                     30: //--------------------------------------------------------------------------
                     31: // LONG DrvQueryFontData (dhpdev,pfo,iMode,cData,pvIn,pvOut)
                     32: // DHPDEV     dhpdev;
                     33: // PFONTOBJ   pfo;
                     34: // ULONG      iMode;
                     35: // ULONG      cData;
                     36: // PVOID      pvIn;
                     37: // PVOID      pvOut;
                     38: //
                     39: // This function is used to return information about a realized font.
                     40: // GDI provides a pointer to an array of glyph or kerning handles and
                     41: // the driver returns information about the glyphs or kerning pairs.
                     42: // The driver may assume that all handles in the array are valid.
                     43: //
                     44: // Parameters:
                     45: //   dhpdev
                     46: //     This is a PDEV handle returned from a call to DrvEnablePDEV.
                     47: //
                     48: //   pfo
                     49: //     This is a pointer to a FONTOBJ.  Details of the font realization
                     50: //     can be queried from this object.
                     51: //
                     52: //   iMode
                     53: //     This defines the information requested.  This may take one of the
                     54: //     following values.
                     55: //
                     56: //       QFD_GLYPH    GDI has placed an array of cData HGLYPHs at pvIn.
                     57: //                    If pvOut is not NULL the driver must return an array
                     58: //                    of corresponding GLYPHDATA structures to the buffer
                     59: //                    at pvOut.  If pvOut is NULL then the driver should return
                     60: //                    only the size of the buffer needed for output.
                     61: //
                     62: //       QFD_KERNPAIR GDI has placed an array of cData HKERNs at pvIn.
                     63: //                    If pvOut is not NULL the driver must return an array of
                     64: //                    corresponding POINTLs to the buffer at pvOUt, each of
                     65: //                    which describes a kerning adjustment.  If pvOut if NULL
                     66: //                    the driver should return only the size of the buffer
                     67: //                    needed for output.
                     68: //
                     69: //
                     70: //   cData
                     71: //     A count of input items at pvIn.  The interpretation of this count
                     72: //     depends on iMode.
                     73: //
                     74: //   pvIn
                     75: //     This is a pointer to an array of cData handles.If iMode is equal to
                     76: //     DRV_FONTDATA_GLYPH then these are glyph handles (HGLYPHs).  If iMode
                     77: //     is DRV_FONTDATA_KERNPAIR then the handles identify kerning pairs
                     78: //     (HKERNS).  The driver may assume that all handles are valid.
                     79: //
                     80: // Returns:
                     81: //   The return value is either the number of BYTEs needed or the number of
                     82: //   BYTEs written, depending on iMode.  In all cases a return value of
                     83: //   -1 indicates an error, and an error code is logged.
                     84: //
                     85: //
                     86: // History:
                     87: //   25-Apr-1991    -by-    Kent Settle       (kentse)
                     88: // Wrote it.
                     89: //--------------------------------------------------------------------------
                     90: 
                     91: LONG DrvQueryFontData (dhpdev,pfo,iMode,hg,pgd,pv,cjSize)
                     92: DHPDEV     dhpdev;
                     93: FONTOBJ   *pfo;
                     94: ULONG      iMode;
                     95: HGLYPH     hg;
                     96: GLYPHDATA  *pgd;
                     97: PVOID      pv;
                     98: ULONG     cjSize;
                     99: {
                    100:     PNTFM               pntfm = NULL;
                    101:     LONG                lWidth;
                    102:     PBYTE               pCharCode;
                    103:     PBYTE               pCode;
                    104:     PUSHORT             pCharWidth;
                    105:     int                 i;
                    106:     PDEVDATA            pdev;
                    107:     XFORMOBJ           *pxo;
                    108:     ULONG               ulComplex;
                    109:     PIFIMETRICS         pifi;
                    110:     POINTL              ptl1, ptl2;
                    111:     POINTFIX            ptfx1;
                    112:     FD_DEVICEMETRICS   *pdm = (FD_DEVICEMETRICS *)pv;
                    113:     FIX                 fxLength, fxExtLeading;
                    114:     LONG                lfHeight, InternalLeading;
                    115:     FD_REALIZEEXTRA    *pre = NULL;
                    116:     DWORD               dwPointSize, dwLeadSuggest;
                    117: 
                    118: #ifdef TESTING
                    119:     DbgPrint("Entering DrvQueryFontData.\n");
                    120: #endif
                    121: 
                    122:     pdev = (PDEVDATA)dhpdev;
                    123: 
                    124:     if (bValidatePDEV(pdev) == FALSE)
                    125:        return(-1);
                    126: 
                    127:     // make sure we have been given a valid font.
                    128: 
                    129:     if ((pfo->iFace == 0) || (pfo->iFace > (pdev->cDeviceFonts + pdev->cSoftFonts)))
                    130:     {
                    131:        RIP("PSCRIPT!DrvQueryFontData: invalid iFace.\n");
                    132:        SetLastError(ERROR_INVALID_PARAMETER);
                    133:        return(-1);
                    134:     }
                    135: 
                    136:     // get the metrics for the given font.
                    137: 
                    138:     pntfm = pdev->pfmtable[pfo->iFace - 1].pntfm;
                    139: 
                    140:     // get the Notional to Device transform.
                    141: 
                    142:     if(!(pxo = FONTOBJ_pxoGetXform(pfo)))
                    143:     {
                    144:         RIP("PSCRIPT!DrvQueryFontData: pxo == NULL.\n");
                    145:         return(-1);
                    146:     }
                    147: 
                    148:     // get the font transform information.
                    149: 
                    150:     ulComplex = XFORMOBJ_iGetXform(pxo, &pdev->cgs.FontXform);
                    151: 
                    152:     // get local pointer to IFIMETRICS.
                    153: 
                    154:     pifi = (PIFIMETRICS)((CHAR *)pntfm + pntfm->loIFIMETRICS);
                    155: 
                    156:     // fill in the appropriate data, depending on iMode.
                    157: 
                    158:     switch(iMode)
                    159:     {
                    160:         case QFD_GLYPHANDBITMAP:
                    161:             // We don't actually return bitmaps, but we give them
                    162:            // metrics via this call.
                    163: 
                    164:             if (pgd)
                    165:             {
                    166:                 // get a pointer to the character codes.
                    167: 
                    168:                 pCharCode = ((PBYTE)pntfm + pntfm->loCharMetrics +
                    169:                              DWORDALIGN(pntfm->cCharacters * sizeof(USHORT)));
                    170: 
                    171:                // get a pointer to the character widths.
                    172: 
                    173:                 pCharWidth = (PUSHORT)((PBYTE)pntfm + pntfm->loCharMetrics);
                    174: 
                    175:                 // now get the character width for the given GLYPH.
                    176:                 // we set our HGLYPHs to be equal to the PostScript
                    177:                 // character code for that given glyph.  this allows
                    178:                 // us to quickly search through our font metrics and
                    179:                 // find the width for the given character.
                    180: 
                    181:                 // first get a pointer to the character codes.  once
                    182:                 // the character has been found, we know how much to
                    183:                 // index into the character widths and find the width
                    184:                 // in question.
                    185: 
                    186:                pCode = pCharCode;
                    187: 
                    188:                 for (i = 0; (USHORT)i < pntfm->cCharacters; i++)
                    189:                 {
                    190:                     if (*pCharCode++ == (BYTE)hg)
                    191:                         break;
                    192:                 }
                    193: 
                    194:                // now get the width in question.
                    195: 
                    196:                 lWidth = (LONG)pCharWidth[i];
                    197: 
                    198: //!!! currently, I am just putting the BBox for the font here, not
                    199: //!!! for the character.   Does anyone care?  - kentse.
                    200: 
                    201:                 // now fill in the GLYPHDATA structure.
                    202:                 // remember under NT 0,0 is top left, while under
                    203:                // PostScript 0,0 is bottom left.  return device coords.
                    204: 
                    205:             #ifdef THIS_IS_WRONG
                    206:             //!!! but fortunatelly it is also useless except for tt fonts [bodind]
                    207:             //!!! rclInk is measured along x,y, not along base,side unit vectors
                    208: 
                    209:                 ptl1.x = pntfm->rcBBox.left;
                    210:                 ptl1.y = 0;
                    211:                 XFORMOBJ_bApplyXform(pxo, XF_LTOFX, 1, &ptl1, &ptfx1);
                    212:                 pgd->rclInk.left = FXTOL(iHipot(ptfx1.x, ptfx1.y));
                    213: 
                    214:                 ptl1.x = pntfm->rcBBox.right;
                    215:                 ptl1.y = 0;
                    216:                 XFORMOBJ_bApplyXform(pxo, XF_LTOFX, 1, &ptl1, &ptfx1);
                    217:                 pgd->rclInk.right = FXTOL(iHipot(ptfx1.x, ptfx1.y));
                    218: 
                    219:                 ptl1.x = 0;
                    220:                 ptl1.y = -pntfm->rcBBox.bottom;
                    221:                 XFORMOBJ_bApplyXform(pxo, XF_LTOFX, 1, &ptl1, &ptfx1);
                    222:                 pgd->rclInk.bottom = FXTOL(iHipot(ptfx1.x, ptfx1.y));
                    223: 
                    224: 
                    225:                 ptl1.x = 0;
                    226:                 ptl1.y = -pntfm->rcBBox.top;
                    227:                 XFORMOBJ_bApplyXform(pxo, XF_LTOFX, 1, &ptl1, &ptfx1);
                    228:                 pgd->rclInk.top = FXTOL(iHipot(ptfx1.x, ptfx1.y));
                    229: 
                    230:             #endif // THIS_IS_WRONG
                    231: 
                    232:             // fxInkBottom,Top are measured along pteSide vector:
                    233: 
                    234:                 ptl1.x = 0;
                    235:                 ptl1.y = pntfm->rcBBox.bottom;
                    236:                 XFORMOBJ_bApplyXform(pxo, XF_LTOFX, 1, &ptl1, &ptfx1);
                    237:                 pgd->fxInkBottom = iHipot(ptfx1.x, ptfx1.y);
                    238:                 if (pntfm->rcBBox.bottom < 0)
                    239:                     pgd->fxInkBottom = -pgd->fxInkBottom;
                    240: 
                    241:                 ptl1.x = 0;
                    242:                 ptl1.y = pntfm->rcBBox.top;
                    243:                 XFORMOBJ_bApplyXform(pxo, XF_LTOFX, 1, &ptl1, &ptfx1);
                    244:                 pgd->fxInkTop = iHipot(ptfx1.x, ptfx1.y);
                    245:                 if (pntfm->rcBBox.top < 0)
                    246:                     pgd->fxInkTop = -pgd->fxInkTop;
                    247: 
                    248: #ifdef WIN31_INTEGER_METRICS
                    249:                 pgd->fxInkBottom = ROUNDFIX(pgd->fxInkBottom);
                    250:                 pgd->fxInkTop = ROUNDFIX(pgd->fxInkTop);
                    251: #endif
                    252: 
                    253:            // aw info, ideally we would like more precission than 28.4
                    254:            // in case of text at an angle. [bodind]
                    255: 
                    256:                 ptl1.x = lWidth;
                    257:                 ptl1.y = 0;
                    258: 
                    259:                 XFORMOBJ_bApplyXform(pxo, XF_LTOFX, 1, &ptl1, &ptfx1);
                    260: 
                    261:                 pgd->fxD = iHipot(ptfx1.x, ptfx1.y);
                    262: 
                    263:                 pgd->ptqD.x.HighPart = ptfx1.x;
                    264:                 pgd->ptqD.x.LowPart = 0;
                    265:                 pgd->ptqD.y.HighPart = ptfx1.y;
                    266:                 pgd->ptqD.y.LowPart = 0;
                    267: 
                    268: #ifdef WIN31_INTEGER_METRICS
                    269:                 pgd->fxD = ROUNDFIX(pgd->fxD);
                    270:                 pgd->ptqD.x.HighPart = ROUNDFIX(pgd->ptqD.x.HighPart);
                    271:                 pgd->ptqD.y.HighPart = ROUNDFIX(pgd->ptqD.y.HighPart);
                    272: #endif
                    273: 
                    274:             //!!! often wrong but it seems win31 is doing the same thing
                    275:             //!!! this may cause char to stick outside the computed
                    276:             //!!! background box. try ZapfChancery on NT and Win31
                    277: 
                    278:                 pgd->fxA = 0;
                    279:                 pgd->fxAB = pgd->fxD;
                    280: 
                    281:                 pgd->hg = hg;
                    282:             }
                    283: 
                    284:            // size is now just the size of the (in this case non-existant)
                    285:            // bitmap
                    286:             return 0;
                    287: 
                    288: 
                    289:         case QFD_MAXEXTENTS:
                    290:             // if there is no output buffer, just return the size needed.
                    291: 
                    292:             if (pv == NULL)
                    293:                 return((LONG)sizeof(FD_DEVICEMETRICS));
                    294: 
                    295:             ASSERTPS(
                    296:                 cjSize >= sizeof(FD_DEVICEMETRICS),
                    297:                 "pscript! cjSize < sizeof(FD_DEVICEMETRICS)\n"
                    298:                 );
                    299: 
                    300:             // we have a large enough buffer, so fill it in.
                    301: 
                    302:             pdm->flRealizedType = 0;
                    303: 
                    304:             // base and side, as used below, basically are vectors
                    305:             // describing the orientation of the font.  for example,
                    306:             // for a left to right font, the base vector would be
                    307:             // (1,0).  the side vector should be in the direction of
                    308:             // the ascender, so in the standard case the side vector
                    309:             // would be (0,-1), since 0 is up in Windows.
                    310: 
                    311:             ptl1.x = 1000;
                    312:             ptl1.y = 0;
                    313: 
                    314:             XFORMOBJ_bApplyXform(pxo, XF_LTOFX, 1, &ptl1, &ptfx1);
                    315: 
                    316:             fxLength = iHipot(ptfx1.x, ptfx1.y);
                    317: 
                    318:             pdm->pteBase.x = (FLOAT)ptfx1.x / fxLength;
                    319:             pdm->pteBase.y = (FLOAT)ptfx1.y / fxLength;
                    320: 
                    321:             ptl1.x = 0;
                    322:             ptl1.y = -1000;
                    323: 
                    324:             XFORMOBJ_bApplyXform(pxo, XF_LTOFX, 1, &ptl1, &ptfx1);
                    325: 
                    326:             fxLength = iHipot(ptfx1.x, ptfx1.y);
                    327: 
                    328:             pdm->pteSide.x = (FLOAT)ptfx1.x / fxLength;
                    329:             pdm->pteSide.y = (FLOAT)ptfx1.y / fxLength;
                    330: 
                    331:             // munge with the FD_REALIZEEXTRA external leading field for
                    332:             // win31 compatability.
                    333: 
                    334:             if (pgd)
                    335:             {
                    336:                 // -fxLength is the FIX 28.4 lfHeight in pels.
                    337: 
                    338:                 lfHeight = abs(FXTOL(fxLength));
                    339: 
                    340:                 // get point size as win31 does.
                    341: 
                    342:                 dwPointSize = (DWORD)MulDiv(lfHeight, PS_RESOLUTION,
                    343:                                             pdev->psdm.dm.dmPrintQuality);
                    344: 
                    345:                 if (pifi->jWinPitchAndFamily & FF_ROMAN)
                    346:                 {
                    347:                     dwLeadSuggest = 2;
                    348:                 }
                    349:                 else if (pifi->jWinPitchAndFamily & FF_SWISS)
                    350:                 {
                    351:                     if (dwPointSize <= 12)
                    352:                         dwLeadSuggest = 2;
                    353:                     else if (dwPointSize < 14)
                    354:                         dwLeadSuggest = 3;
                    355:                     else
                    356:                         dwLeadSuggest = 4;
                    357:                 }
                    358:                 else
                    359:                 {
                    360:                     // default to 19.6%.
                    361: 
                    362:                     dwLeadSuggest = (DWORD)MulDiv(dwPointSize, 196,
                    363:                                                   ADOBE_FONT_UNITS);
                    364:                 }
                    365: 
                    366:                 // get notional internal leading.
                    367: 
                    368:                 InternalLeading = (pntfm->rcBBox.top - pntfm->rcBBox.bottom) -
                    369:                                   ADOBE_FONT_UNITS;
                    370: 
                    371:                 // make it device coordinates.
                    372: 
                    373:                 InternalLeading = MulDiv(InternalLeading, lfHeight,
                    374:                                          ADOBE_FONT_UNITS);
                    375: 
                    376:                 if (InternalLeading < 0)
                    377:                     InternalLeading = 0;
                    378: 
                    379:                 fxExtLeading = LTOFX(MulDiv(dwLeadSuggest,
                    380:                                       pdev->psdm.dm.dmPrintQuality,
                    381:                                       PS_RESOLUTION) - InternalLeading);
                    382: 
                    383:                 // if the external leading was calculated to be negative, or
                    384:                 // if this is a fixed pitch font, set external leading to
                    385:                 // zero.
                    386: 
                    387:                 if ((fxExtLeading < 0) ||
                    388:                     (pifi->jWinPitchAndFamily & FIXED_PITCH))
                    389:                     fxExtLeading = 0;
                    390: 
                    391:                 // fill in the leading field of the FD_REALIZEEXTRA struct.
                    392: 
                    393:                 ((FD_REALIZEEXTRA *)pgd)->lExtLeading = (LONG)fxExtLeading;
                    394: 
                    395:                 if (pifi->jWinPitchAndFamily & FIXED_PITCH)
                    396:                     ((FD_REALIZEEXTRA *)pgd)->alReserved[0] = 0;
                    397:             }
                    398: 
                    399:             // cxMax the same as max char width for a and c's are zero:
                    400: 
                    401:             ptl1.x = pifi->fwdMaxCharInc;
                    402:             ptl1.y = 0;
                    403: 
                    404:             XFORMOBJ_bApplyXform(pxo, XF_LTOL, 1, &ptl1, &ptl2);
                    405: 
                    406:             // now get the length of the vector.
                    407: 
                    408:             pdm->cxMax = iHipot(ptl2.x, ptl2.y);
                    409: 
                    410:             // lD is the advance width if the font is fixed pitch,
                    411:             // otherwise, set to zero.
                    412: 
                    413:             if(pifi->fwdMaxCharInc != pifi->fwdAveCharWidth)
                    414:                 pdm->lD = 0;
                    415:             else
                    416:             {
                    417:                 pdm->lD = (LONG)pdm->cxMax;
                    418:             }
                    419: 
                    420:             // calculate the max ascender.
                    421: 
                    422:             ptl1.x = 0;
                    423:             ptl1.y = pntfm->rcBBox.top;
                    424: 
                    425:             XFORMOBJ_bApplyXform(pxo, XF_LTOFX, 1, &ptl1, &ptfx1);
                    426: 
                    427:             pdm->fxMaxAscender = iHipot(ptfx1.x, ptfx1.y);
                    428: 
                    429:             // calculate the max descender.
                    430: 
                    431:             ptl1.x = 0;
                    432:             ptl1.y = pntfm->rcBBox.bottom;
                    433: 
                    434:             if (ptl1.y < 0)
                    435:                 ptl1.y = -ptl1.y;
                    436: 
                    437:             // do the ugly fixed pitch means zero internal leading hack.
                    438: 
                    439:             if (pifi->jWinPitchAndFamily & FIXED_PITCH)
                    440:             {
                    441:                 // get notional internal leading.
                    442: 
                    443:                 InternalLeading = (pntfm->rcBBox.top - pntfm->rcBBox.bottom) -
                    444:                                   ADOBE_FONT_UNITS;
                    445: 
                    446:                 // WFW seems to make all the adjustment here in the
                    447:                 // MaxDescender, so we will too.
                    448: 
                    449:                 ptl1.y -= InternalLeading;
                    450: 
                    451:                 if (ptl1.y < 0)
                    452:                     ptl1.y = 0;
                    453:             }
                    454: 
                    455:             XFORMOBJ_bApplyXform(pxo, XF_LTOFX, 1, &ptl1, &ptfx1);
                    456: 
                    457:             pdm->fxMaxDescender = iHipot(ptfx1.x, ptfx1.y);
                    458: 
                    459: #ifdef WIN31_INTEGER_METRICS
                    460:             pdm->fxMaxAscender = ROUNDFIX(pdm->fxMaxAscender);
                    461:             pdm->fxMaxDescender = ROUNDFIX(pdm->fxMaxDescender);
                    462: #endif
                    463: 
                    464:             // calculate the underline position for this font instance.
                    465: 
                    466:             ptl1.x = 0;
                    467:             ptl1.y = - pifi->fwdUnderscorePosition;
                    468: 
                    469:             XFORMOBJ_bApplyXform(pxo, XF_LTOL, 1, &ptl1, &pdm->ptlUnderline1);
                    470: 
                    471:             // calculate the strikeout position for this font instance.
                    472: 
                    473:             ptl1.x = 0;
                    474:             ptl1.y = - (pntfm->fwdLowerCaseAscent / 2);
                    475: 
                    476:             XFORMOBJ_bApplyXform(pxo, XF_LTOL, 1, &ptl1, &pdm->ptlStrikeOut);
                    477: 
                    478:             // calculate the line thickness.
                    479: 
                    480:             ptl1.x = 0;
                    481:             ptl1.y = pifi->fwdUnderscoreSize;
                    482: 
                    483:             XFORMOBJ_bApplyXform(pxo, XF_LTOL, 1, &ptl1, &pdm->ptlULThickness);
                    484: 
                    485:             pdm->ptlSOThickness = pdm->ptlULThickness;
                    486: 
                    487:             return(sizeof(FD_DEVICEMETRICS));
                    488: 
                    489: 
                    490:         default:
                    491:            RIP("PSCRIPT!DrvQueryFontData: invalid iMode.\n");
                    492:            return(-1);
                    493:     }
                    494: }
                    495: 
                    496: 
                    497: //--------------------------------------------------------------------------
                    498: // BOOL DrvQueryAdvanceWidths(
                    499: // DHPDEV   dhpdev,
                    500: // FONTOBJ *pfo,
                    501: // ULONG    iMode,
                    502: // HGLYPH  *phg,
                    503: // PVOID    plWidths,
                    504: // ULONG    cGlyphs);
                    505: //
                    506: // This routine returns an array of FIX (28.4) widths in pels of the
                    507: // indicated glyphs.
                    508: //
                    509: // History:
                    510: //   23-Jan-1993    -by-    Kent Settle       (kentse)
                    511: // Wrote it.
                    512: //--------------------------------------------------------------------------
                    513: 
                    514: BOOL DrvQueryAdvanceWidths(
                    515: DHPDEV   dhpdev,
                    516: FONTOBJ *pfo,
                    517: ULONG    iMode,
                    518: HGLYPH  *phg,
                    519: PVOID    plWidths,
                    520: ULONG    cGlyphs)
                    521: {
                    522:     PDEVDATA        pdev;
                    523:     ULONG           i, j;
                    524:     PNTFM           pntfm;
                    525:     HGLYPH         *phglyph;
                    526:     USHORT         *pwidth;
                    527:     USHORT         *pCharWidth;
                    528:     PBYTE           pCharCode;
                    529:     PBYTE           pCode;
                    530:     XFORMOBJ       *pxo;
                    531:     POINTL          ptl;
                    532:     POINTFIX        ptfx;
                    533: #ifdef WIN31_INTEGER_METRICS
                    534:     POINTL          ptl2;
                    535:     FIX             fxLength;
                    536:     LONG            lfHeight;
                    537: #endif
                    538: 
                    539:     pdev = (PDEVDATA)dhpdev;
                    540: 
                    541:     if (bValidatePDEV(pdev) == FALSE)
                    542:         return(FALSE);
                    543: 
                    544:     // for now we will treat GETWIDTHS and GETEASYWIDTHS the same.
                    545: 
                    546:     if ((iMode != QAW_GETWIDTHS) && (iMode != QAW_GETEASYWIDTHS))
                    547:     {
                    548:         SetLastError(ERROR_INVALID_PARAMETER);
                    549: #if DBG
                    550:         DbgPrint("PSCRIPT!DrvQueryAdvanceWidths: invalid iMode.\n");
                    551: #endif
                    552:         return(FALSE);
                    553:     }
                    554: 
                    555:     // see if there is anything to do.
                    556: 
                    557:     if (!cGlyphs)
                    558:         return(TRUE);
                    559: 
                    560:     // make sure we have been given a valid font.
                    561: 
                    562:     if ((pfo->iFace == 0) ||
                    563:         (pfo->iFace > (pdev->cDeviceFonts + pdev->cSoftFonts)))
                    564:     {
                    565:         RIP("PSCRIPT!DrvQueryAdvanceWidths: invalid iFace.\n");
                    566:        SetLastError(ERROR_INVALID_PARAMETER);
                    567:         return(FALSE);
                    568:     }
                    569: 
                    570:     // get the metrics for the given font.
                    571: 
                    572:     pntfm = pdev->pfmtable[pfo->iFace - 1].pntfm;
                    573: 
                    574:     // get a pointer to the character widths.
                    575: 
                    576:     pCharWidth = (PUSHORT)((PBYTE)pntfm + pntfm->loCharMetrics);
                    577: 
                    578:     // get a pointer to the character codes.
                    579: 
                    580:     pCharCode = ((PBYTE)pntfm + pntfm->loCharMetrics +
                    581:                  DWORDALIGN(pntfm->cCharacters * sizeof(USHORT)));
                    582: 
                    583:     // get the Notional to Device transform.
                    584: 
                    585:     if(!(pxo = FONTOBJ_pxoGetXform(pfo)))
                    586:     {
                    587:         RIP("PSCRIPT!DrvQueryAdvancedWidths: pxo == NULL.\n");
                    588:         return(FALSE);
                    589:     }
                    590: 
                    591:     // get some local pointers to munge with.
                    592: 
                    593:     phglyph = phg;
                    594:     pwidth = (USHORT *) plWidths;
                    595: 
                    596:     for (i = 0; i < cGlyphs; i++)
                    597:     {
                    598:         pCode = pCharCode;
                    599: 
                    600:         for (j = 0; (USHORT)j < pntfm->cCharacters; j++)
                    601:         {
                    602:             if (*pCode++ == (BYTE)*phglyph)
                    603:                 break;
                    604:         }
                    605: 
                    606:         // now get the width in question.
                    607: 
                    608: #ifdef WIN31_INTEGER_METRICS
                    609:         ptl.x = 0;
                    610:         ptl.y = 1000;
                    611: 
                    612:         XFORMOBJ_bApplyXform(pxo, XF_LTOFX, 1, &ptl, &ptfx);
                    613: 
                    614:         fxLength = iHipot(ptfx.x, ptfx.y);
                    615: 
                    616:         lfHeight = abs(FXTOL(fxLength));
                    617: 
                    618:         *pwidth = LTOFX(MulDiv(pCharWidth[j], lfHeight, ADOBE_FONT_UNITS));
                    619: #else
                    620:         ptl.x = (LONG)pCharWidth[j];
                    621:         ptl.y = 0;
                    622: 
                    623:         XFORMOBJ_bApplyXform(pxo, XF_LTOFX, 1, &ptl, &ptfx);
                    624: 
                    625:         *pwidth = (USHORT)iHipot(ptfx.x, ptfx.y);
                    626: #endif
                    627: 
                    628:         // get the next glyph.
                    629: 
                    630:         phglyph++;
                    631:         pwidth++;
                    632:     }
                    633: 
                    634:     return(TRUE);
                    635: }

unix.superglobalmegacorp.com

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