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