/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Lexmark Corporation, 1989                                   */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/**************************************************************************
 *
 * SOURCE FILE NAME = PRDAQERY
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS  prda_DeviceQueryFontAttributes
 *            prda_DeviceQueryFonts
 *            prda_ProcessAttributes
 *            prda_MatchFaceNames
 *            prda_CopyMetrics
 *            prda_ReturnMetrics
 *            prda_AdjustFaceName
 *            prda_AdjustForCharBox
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/
#define INCL_32                   /* Convert to C/SET2    CON3201       */
#define INCL_DOSPROCESS           /* CON3201 */
#define INCL_DOSSEMAPHORES
#define INCL_GPIPRIMITIVES
#define INCL_WINHEAP
#define INCL_GPIBITMAPS
#define INCL_GPIERRORS
#define INCL_GPILCIDS
#include <os2.h>
#undef INCL_DOSPROCESS            /* CON3201 */
#undef INCL_DOSSEMAPHORES
#undef INCL_GPIPRIMITIVES
#undef INCL_WINHEAP
#undef INCL_GPIBITMAPS
#undef INCL_GPIERRORS
#undef INCL_GPILCIDS

#define INCL_DDICOMFLAGS
#define INCL_DDIBUNDLES
#define INCL_DDIFONTSTRUCS
#define INCL_DDIDEFS
#define INCL_DDIMISC
#include <pmddi.h>
#undef INCL_DDICOMFLAGS
#undef INCL_DDIBUNDLES
#undef INCL_DDIFONTSTRUCS
#undef INCL_DDIDEFS
#undef INCL_DDIMISC

#define INCL_WINP_SELECTIVE
#define INCL_WINP_SEI
#define INCL_WINP_MISC
#include <pmwinx.h>
#undef INCL_WINP_SELECTIVE
#undef INCL_WINP_SEI
#undef INCL_WINP_MISC
#undef INCL_32                    /* CON3201 */

#include <prdconse.h>
#include <prddcone.h>
#include <prdacone.h>
#include <prdncone.h>
#include <prdtcone.h>
#include <prdmcone.h>                                              /* PD00604 */
#include <prdecone.h>                                              /* PD00651 */

#define NO_CONSTANT_INCL
#include <prdinclt.h>
#undef NO_CONSTANT_INCL

#include <prdaextf.h>
#include <prdgextf.h>
#include <prdtextf.h>
#include <prduextf.h>


extern lplpFontCPListType   DVTFontCPList [];
extern DVTItalicSlopeType   DVTItalicSlopeList [];
extern USHORT               prdd_HugeInc;
extern CHAR                 szBoldString[];
extern CHAR                 szDWideString[];
extern CHAR                 szDHighString[];
extern CHAR                 szQualityString1[];
extern CHAR                 szQualityString2[];
extern CHAR                 szQualityString3[];
extern CHAR                 szQualityString2a[];           /* PD00731 */

/******************************************************************************/
/*  FUNCTION: prda_DeviceQueryFontAttributes                                  */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  See "OS/2 Technical Reference: I/O Subsytems and Device Drivers"          */
/*                                                                            */
/*  HDC           DcH;                                                        */
/*  PFONTMETRICS  ArgMetrics;                                                 */
/*  ULONG         ArgSize;                                                    */
/*  lpDCI         DCIData;                                                    */
/*  ULONG         FunN;                                                       */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  Returns (in ArgMetrics) the current font metrics in structure of          */
/*  PFONTMETRICS type.  Copies the FMF referenced from FONTDATA to the        */
/*  ArgMetrics buffer.  Updates the FMF in ArgMetrics based on the engine     */
/*  attributes selected in the current FontInfo LCID match number structure.  */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
ULONG EXPENTRY prda_DeviceQueryFontAttributes( HDC           DcH,
                                               ULONG         ArgSize,
                                               PFONTMETRICS  ArgMetrics,
                                               lpDCI         DCIData,
                                               ULONG         FunN )

{
#define TFUNC "prda_DevQryFAtt"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    lpFontInfoType  pFontInfo;
    lpFontDataType  pFontData;
    lpFMFFileStruc  pFont;
    BYTE            fsAttrs;
    USHORT          ItalicIndex;
    USHORT          FontIndex;
    USHORT          FontSelect;
    USHORT          PrinterType;
    lpDDTType       pDDT;
    USHORT          flflags;
    ULONG           ArgSizeReturn;      /* PD00673                            */
    BYTE            DfltFontRealized;   /* PD00681                            */
    /**************************************************************************/
    /* Do entry processing                                                    */
    /**************************************************************************/
#ifdef PRD_TIMING
    DEKHOOK0(A,7,12)
#endif
    prdm_EnterDriver(DCIData);

    /**************************************************************************/
    /*  Set up pointers.                                                      */
    /**************************************************************************/
    pDDT        = &DCIData->DCIPdbInstance->DDT;
    pFontData   = &DCIData->DCIFontData;
    pFontInfo   = &pFontData->Info;
    pFont       = pFontInfo->pFont;
    PrinterType = DCIData->DCIPdbInstance->PrinterType;

    /**************************************************************************/
    /*  The driver should not see this call for an engine font.               */
    /**************************************************************************/
    if (pFontData->Genre != DEVICE_FONT)
    {
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,92)
#endif
        return (ERROR_ZERO);
    }
    /**************************************************************************/
    /* PD00673 : Save ArgSizeReturn which can be larger than Fontmetrics      */
    /**************************************************************************/
    ArgSizeReturn = ArgSize;

    /**************************************************************************/
    /*  Put a bound on ArgSize.                                               */
    /**************************************************************************/
    if (ArgSize > sizeof(FONTMETRICS))
        ArgSize = sizeof(FONTMETRICS);

    /**************************************************************************/
    /*  Copy the metrics for the current font to ArgMetrics.                  */
    /*                                                                        */
    /*  PD00137 Def outline font pointsize selection                          */
    /*                                                                        */
    /*  If a font has not been realized and the default font is an outline    */
    /*  font and the user has selected a pointsize (otherwise                 */
    /*  PDBInstance->DfltFontPointSz == 0) then set the flag to adjust the    */
    /*  metrics to the pointsize instead of charbox.                          */
    /**************************************************************************/
    /**************************************************************************/
    /*  PD00681 : Get the lcid attribute to see if default font was realized  */
    /**************************************************************************/
    DfltFontRealized = prdm_GetLCIDEngineAttrs(pFontInfo->LCID) &
                                                             FATTR_SEL_DEFAULT;
    flflags = USE_CHAR_BOX;
    if (prda_CopyMetrics(DcH, (ULONG)flflags, ArgMetrics, ArgSize, pFont,
                         DCIData, pFontInfo->LCID, FunN) != OK)
    {
        prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,92)
#endif
        return (ERROR_ZERO);
    }

    /**************************************************************************/
    /*  Set the match number.                                                 */
    /**************************************************************************/

  /**************************************************************************/
  /* CON3201 - Must change this test to take into account that the new      */
  /* FONTMETRICS structure is a different size in CSet/2.  So we will       */
  /* test the offset from beginning of structure to the lMatch member       */
  /*if (ArgSize == sizeof(FONTMETRICS))                                     */
  /**************************************************************************/
    if  (ArgSize > ((PBYTE)&ArgMetrics->lMatch - (PBYTE)ArgMetrics))
    {

        /**********************************************************************/
        /*  Only return the base match number for this font.  The attribute   */
        /*  information and the codepage information are encoded inside the   */
        /*  metrics if necessary.                                             */
        /**********************************************************************/
        ArgMetrics->lMatch = 0xFF000000;
        ULTOLCID(ArgMetrics->lMatch).BaseMatchNo = pFontInfo->LCID.BaseMatchNo;
    }

    /**************************************************************************/
    /*  Set the codepage if this is a simulated font.  Currently only the     */
    /*  default font is simulated so the target codepage is always in the     */
    /*  DCIData.                                                              */
    /**************************************************************************/
    if (pFontData->Simulated)
    {
        if  (ArgSize > ((PBYTE)&ArgMetrics->usCodePage - (PBYTE)ArgMetrics))
        {
            ArgMetrics->usCodePage = DCIData->DCICodePage;
        }
    }

    /**************************************************************************/
    /*  Adjust the Metrics for BOLD, UNDERSCORE and STRIKEOUT when these      */
    /*  attributes are set in the LCID.  If these attributes are implemented  */
    /*  using a font switch then the LCID flags are not set.  Be careful to   */
    /*  only change the metrics if the font supports this attribute.          */
    /**************************************************************************/

    /**************************************************************************/
    /*  Get the font attribute in terms of bit flags.                         */
    /**************************************************************************/
    fsAttrs = prdm_GetLCIDEngineAttrs(pFontInfo->LCID);

    /**************************************************************************/
    /*  Adjust the metrics for the Underline attribute.  This is always       */
    /*  supported across all fonts.                                           */
    /**************************************************************************/
    if ((fsAttrs & FATTR_SEL_UNDERSCORE) &&
        (ArgSize > ((PBYTE)&ArgMetrics->fsSelection - (PBYTE)ArgMetrics)))
    {
        ArgMetrics->fsSelection |= FATTR_SEL_UNDERSCORE;
    }

    /**************************************************************************/
    /*  Adjust the metrics for the Bold attribute if bold is requested and the*/
    /*  font supports bold and the buffer is big enough to return this        */
    /*  information.                                                          */
    /**************************************************************************/
    if ((fsAttrs & FATTR_SEL_BOLD) && (pFontInfo->Attr & FATT_BOLD) &&
        (ArgSize > ((PBYTE)&ArgMetrics->usWeightClass - (PBYTE)ArgMetrics)))
    {
        /**********************************************************************/
        /*  Note: Do not set BOLD flag - this causes the engine to simulate   */
        /*  bold by double striking, e.g.  for char mode 2 text.              */
        /*                                                                    */
        /*     pTargetBuffer->fsSelection |= FATTR_SEL_BOLD;                  */
        /*                                                                    */
        /*  Just adjust the wieght class.                                     */
        /**********************************************************************/
        ArgMetrics->usWeightClass += 2;

        /**********************************************************************/
        /*  Maximum Weight Class is 9...                                      */
        /**********************************************************************/
        if (ArgMetrics->usWeightClass > 9)
            ArgMetrics->usWeightClass = 9;
    }

    /**************************************************************************/
    /*  Adjust the metrics for Italic if italic is requested and the font     */
    /*  supports italic and the buffer is big enough to hold this information.*/
    /**************************************************************************/
    if ((fsAttrs & FATTR_SEL_ITALIC ) && (pFontInfo->Attr & FATT_ITALIC) &&
        (ArgSize > ((PBYTE)&ArgMetrics->sCharSlope - (PBYTE)ArgMetrics)))
    {

        /**********************************************************************/
        /*  Get the italic table entry from the DDT.                          */
        /**********************************************************************/
        ItalicIndex = pDDT->DDTItalicSlopeIndex;

        /**********************************************************************/
        /*  Use the selection id to determine which italic slope to use.      */
        /**********************************************************************/
        FontIndex  = prdm_GetLCIDFontIndex(pFontInfo->LCID);
        FontSelect = DCIData->DCIPdbInstance->FontList[FontIndex]->SelectionId;

        /**********************************************************************/
        /*  PD00220 : The method used here to distinguish NLQ fonts from      */
        /*  non-NLQ fonts is specific to the 4224.                            */
        /**********************************************************************/
        if ((pDDT->DDTDriverType == DDT_IBM42XX_DRV &&
            (PrinterType == IBM_4224_MONO || PrinterType == IBM_4224_COLOR)) &&
            (FontSelect == SEL_NLQ_COURIER_FP ||
             FontSelect == SEL_NLQ_ESSAY_PS))
        {
            ItalicIndex += 1;
        }

        /**********************************************************************/
        /*  Set the char slope.                                               */
        /**********************************************************************/
        ArgMetrics->sCharSlope = DVTItalicSlopeList[ItalicIndex].Slope;

        /**********************************************************************/
        /*  PD00220 : For Nile/Tiber/4226 need to adjust CharSlope for code   */
        /*  page 864.                                                         */
        /**********************************************************************/
        if (((pDDT->DDTDriverType == DDT_IBM42XX_DRV) &&
            (PrinterType >  IBM_4224_MONO)) &&
            (ArgMetrics->usCodePage == 864))
        {
             ArgMetrics->sCharSlope =
                                    360 - DVTItalicSlopeList[ItalicIndex].Slope;
        }
    }

    /**************************************************************************/
    /*  Adjust the metrics for the StrikeOut Attribute.  This is always       */
    /*  supported because it is simulated by the engine.                      */
    /**************************************************************************/
    if ((fsAttrs & FATTR_SEL_STRIKEOUT ) &&
        (ArgSize > ((PBYTE)&ArgMetrics->fsSelection - (PBYTE)ArgMetrics)))
    {
        ArgMetrics->fsSelection |= FATTR_SEL_STRIKEOUT;
    }
    /**************************************************************************/
    /* PD00673 : Fill rest of return buffer with zeroes                       */
    /**************************************************************************/
    if ( ArgSizeReturn > ArgSize )
    {
        prdu_memset((PBYTE)((PBYTE)ArgMetrics + ArgSize), 0,
                    ArgSizeReturn - ArgSize);
    }

    /**************************************************************************/
    /*  All done.                                                             */
    /**************************************************************************/
    prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,92)
#endif
    return (OK);
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prda_DeviceQueryFonts                                           */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  HDC           DcH;                                                        */
/*  ULONG         ArgOptions                                                  */
/*  PSZ           ArgFilter;                                                  */
/*  PFONTMETRICS  ArgMetrics;                                                 */
/*  ULONG         ArgSize;                                                    */
/*  PULONG        ArgCount;                                                   */
/*  lpDCI         DCIData;                                                    */
/*  ULONG         FunN;                                                       */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  Returns the metrics to all fonts with a facename which matches the        */
/*  facename in ArgFilter in a block starting at ArgMetrics.  The number of   */
/*  fonts NOT returned is returned from the function.                         */
/*                                                                            */
/*  The ArgMetrics buffer is filled and ArgCount is set to the number of fonts*/
/*  returned.                                                                 */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
ULONG EXPENTRY prda_DeviceQueryFonts( HDC           DcH,
                                      ULONG         ArgOptions,
                                      PSZ           ArgFilter,
                                      PFONTMETRICS  ArgMetrics,
                                      ULONG         ArgSize,
                                      PULONG        ArgCount,
                                      lpDCI         DCIData,
                                      ULONG         FunN )

{
#define TFUNC "prda_DevQryFnts"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    lpDDTType           pDDT;          /* Pointer to the DDT                  */
    SHORT               Returned;      /* No. of fonts returned               */
    USHORT              Remaining;     /* No. of matching fonts left          */
    LCIDType            MatchNo;       /* Match no. Structure(4 bytes)        */
    lpPDBI              PDBInstance;   /* Pointer to the PDB                  */
    ULONG               BytesSoFarInSeg;
    USHORT              Attrs;
    USHORT              i,l;
    USHORT              Index;
    USHORT              Result;
    lpFMFFileStruc      pFont;         /* FMF pointer - contains metrics for  */
                                       /* the base version of the font        */
    lpPrtDataEntry      PrinterData;
    lplpFontCPListType  FontCodePageList;
    lpFontCPListType    CodePageList;
    lpFontCPListType    pCodePageData;
    PFONTMETRICS        pfmMetrics;
    BOOL                CardIsSelected;
    USHORT              NumberOfSlots;
    SHORT               SystemCodePage;                             /* PD00604*/
    SHORT               FMFCodePage;                                /* PD00604*/
    BOOL                FirstTime;                                  /* PD00717*/
    BOOL                SecondTime;                                 /* PD00717*/
    SHORT               SystemCodePage1;                            /* PD00717*/
    SHORT               SystemCodePage2;                            /* PD00717*/
    PSZ                 FirstCardName;                              /* PD00717*/
    BOOL                SystemCodePageInCard;                       /* PD00717*/
    USHORT              SaveIndex;                                  /* PD00717*/
    BOOL                FacenameFlag;                               /* PD00737*/

    /******************************************************************/
    /* Do entry processing                                            */
    /******************************************************************/
#ifdef PRD_TIMING
    DEKHOOK0(A,7,13)
#endif
    prdm_EnterDriver(DCIData);

    /**************************************************************************/
    /*  Initialize local counts                                               */
    /**************************************************************************/
    Returned  = 0;
    Remaining = 0;

    FirstTime = TRUE;
    SecondTime = TRUE;
    /**************************************************************************/
    /*  Set up pointers.                                                      */
    /**************************************************************************/
    PDBInstance = DCIData->DCIPdbInstance;
    PrinterData = PDBInstance->PrinterData;
    pDDT        = &PDBInstance->DDT;
    pfmMetrics  = ArgMetrics;

    /**************************************************************************/
    /*  Querying of private fonts handled by engine, only concerned here with */
    /*  public fonts when FontCount is > 0.                                   */
    /**************************************************************************/
    if ((ArgOptions & QF_PUBLIC) && (PDBInstance->FontCount > 0))
    {
        TRACE4(TFUNC, "Query Public Fonts", FNULL, 0);

        /**********************************************************************/
        /*  We need to handle the case of the total size of all the metrics   */
        /*  returned being more than 64K.  We use a local buffer to pass to   */
        /*  prda_ReturnMetrics.  We then copy data from this buffer to        */
        /*  ArgMetrics; splitting the copy in two if it will take us over a   */
        /*  64K segment boundary.                                             */
        /**********************************************************************/
/*      BytesSoFarInSeg = OFFSETOF(ArgMetrics);     CON3201    */

        /**********************************************************************/
        /*  Put a bound on ArgSize.                                           */
        /* PD00673 : Removed this if stmt to allow ArgSize to be larger than  */
        /* Fontmetrics for this routine, added if stmt to ProcessAttributes   */
        /* and ReturnMetrics routines.                                         */
        /**********************************************************************/
/*      if (ArgSize > sizeof(FONTMETRICS))    */
/*          ArgSize = sizeof(FONTMETRICS);    */

        /**********************************************************************/
        /*  Construct zero-index resident font match number (LCID)            */
        /**********************************************************************/
        MatchNo.CPIndex     = INVALID_CODEPAGE_INDEX;
        MatchNo.BaseMatchNo = 0;
        prdm_PutLCIDFontType(MatchNo, FT_RESIDENT);
        MatchNo.EngineAttrs = 0;

        /**********************************************************************/
        /*  Loop thru each resident font                                      */
        /**********************************************************************/
        for (Index = 0 ; Index < pDDT->DDTNoOfResidentFonts ; Index++)
        {

            /******************************************************************/
            /*  Put Index into the LCID FontIndex field                       */
            /******************************************************************/
            prdm_PutLCIDFontIndex(MatchNo, Index);

            /******************************************************************/
            /*  Pick up the FMF pointer for this Resident font.               */
            /******************************************************************/
            pFont = PDBInstance->FontList[Index]->pFMFData;

            /******************************************************************/
            /*  Get device attributes from resident font list and process them*/
            /*  by calling prda_ProcessAttributes.  Note that only the bottom */
            /*  two bits are significant in the attributes field.             */
            /******************************************************************/
            Attrs = PDBInstance->FontList[Index]->Attrs & 0x03;

            /******************************************************************/
            /*  PD00651 : Must check for the Courier PS fonts on the extended */
            /*  NLS 238x machines and continue out of the loop if it is one   */
            /*  of these fonts in the extended NLS code pages, otherwise we   */
            /*  will continue on inside the loop.                             */
            /******************************************************************/
            if ( (pDDT->DDTDriverType == DDT_IBM42XX_DRV) &&
                 ((PDBInstance->PrinterType == IBM_NILE_9) ||
                  (PDBInstance->PrinterType == IBM_TIBER_9)) &&
                 (pDDT->DDTNoOfResidentFonts == NLS_9WIRE) )
            {
               /***************************************************************/
               /*  Check for a Courier PS font in one of the extended NLS     */
               /*  code pages. 852 = 134, 855 = 135, 857 = 136, 862 = 138,    */
               /*  864 = 140, and 869 = 142.  These are the indexes of these  */
               /*  fonts into the font list.                                  */
               /***************************************************************/
               if ( ((Index >= 134) && (Index <=136)) ||
                    (Index == 138) || (Index == 140) || (Index == 142) )
               {
                  continue;
               }
            }

            /******************************************************************/
            /*  PD00604 : Must limit the number of fonts and code pages       */
            /*  returned if "Limited Code Pages" radio button is selected     */
            /*  in Printer Fonts box.                                         */
            /******************************************************************/
            if ( (pDDT->DDTDialogFlags & DDT_LIMIT_FONTS) &&
                 (pDDT->DDTPrinterFonts == DEV_FONTS_LIMITED) )
            {
                SystemCodePage = (SHORT)WinQueryProcessCP();
                FMFCodePage = pFont->Metrics.usCodePage;

                if ( (FMFCodePage == 437) || (FMFCodePage == 850) ||
                     (FMFCodePage == SystemCodePage) )
                {
                    Result = prda_ProcessAttributes(DcH, ArgFilter,
                                            (PPFONTMETRICS)&pfmMetrics, ArgSize,
                                            ArgCount, DCIData, FunN, pFont,
                                            MatchNo, Attrs, &Returned,
                                            &Remaining, &BytesSoFarInSeg);
                }
                else
                {
                    continue;
                }
            }
            else
            {
                Result = prda_ProcessAttributes(DcH,
                                                ArgFilter,
                                                (PPFONTMETRICS)&pfmMetrics,
                                                ArgSize,
                                                ArgCount, DCIData, FunN, pFont,
                                                MatchNo, Attrs, &Returned,
                                                &Remaining, &BytesSoFarInSeg);
            }
        }

        /**********************************************************************/
        /*  Construct zero-index codepage font match number (LCID)            */
        /**********************************************************************/
        MatchNo.CPIndex     = INVALID_CODEPAGE_INDEX;
        MatchNo.BaseMatchNo = 0;
        MatchNo.EngineAttrs = 0;
        prdm_PutLCIDFontType(MatchNo, FT_CODE_PAGE);

       /***********************************************************************/
       /*  Loop through the global code page list.  Check whether the font is */
       /*  present by looking at the corresponding entry into the CPPathList. */
       /*  By doing it this way it becomes trivial to unpack the match number */
       /*  later.  Note that it is important that the 850 codepage is index   */
       /*  one, because index zero should be 437 (ie.  the resident font.     */
       /***********************************************************************/
       if (PDBInstance->TotalCodePageFonts > 0)
       {

           /*******************************************************************/
           /*  Loop thru each codepage font.                                  */
           /*******************************************************************/
           for (i = 0 ; i <= NO_OF_ADDABLE_CPS ; i++)
           {
                /**************************************************************/
                /*  PD00437 : If the printer is the XL24E or the X24E and     */
                /*  there are download code pages available on these printers */
                /*  then we should not download code page 850 as it will be   */
                /*  there twice.                                              */
                /**************************************************************/
                if ((i == 0 &&
                     PDBInstance->PrinterType != IBM_PRO_PRINTER_X24E &&
                     PDBInstance->PrinterType != IBM_PRO_PRINTER_XL24E)
                    || PrinterData->CPPathList[i])
                {
                    /**********************************************************/
                    /*  This is a valid CodePage so update the LCID FontIndex */
                    /*  (top 4 bits) with this index.  Note: Codepage = 850   */
                    /*  when i = 0.                                           */
                    /*                                                        */
                    /*  Use i+1 below since it is an index into DVTCPList     */
                    /*  which starts with codepage 437 and has 9 entries      */
                    /*  instead of 8 as CPPathList!                           */
                    /**********************************************************/
                    prdm_PutLCIDGCPIndex(MatchNo, (BYTE)(i+1));

                    /**********************************************************/
                    /*  For each font in this codepage                        */
                    /**********************************************************/
                    for (Index = 0 ; Index < pDDT->DDTFontsInCodePage; Index++)
                    {

                       /*******************************************************/
                       /*  Pick up the FMF pointer.  CodePageList has 8       */
                       /*  entries starting with 850 CodePgaeNo in the font   */
                       /*  info is an index into DVTCodePageList which has 9  */
                       /*  entries starting with 437; hence the -1.           */
                       /*******************************************************/
                       FontCodePageList = DVTFontCPList[PDBInstance->
                                                        PrinterType];
                       CodePageList     = FontCodePageList[Index];
                       pCodePageData    = &CodePageList[i];
                       pFont            = pCodePageData->pFMFData;

                       /*******************************************************/
                       /*  Get device attributes from resident font list and  */
                       /*  process them by calling prda_ProcessAttributes.    */
                       /*  Note only bottom two bytes are valid.              */
                       /*******************************************************/
                       Attrs = PDBInstance->FontList[Index]->Attrs & 0x03;

                       /*******************************************************/
                       /*  Put the CPFontIndex into the LCID                  */
                       /*******************************************************/
                       prdm_PutLCIDCPFontIndex(MatchNo, (USHORT)Index);
                       Result = prda_ProcessAttributes(DcH, ArgFilter,
                                                     (PPFONTMETRICS)&pfmMetrics,
                                                       ArgSize, ArgCount,
                                                       DCIData, FunN, pFont,
                                                       MatchNo, Attrs,
                                                       &Returned, &Remaining,
                                                       &BytesSoFarInSeg);
                    }
                }
           }
       }

        /**********************************************************************/
        /*  Construct zero-index for card font match number (LCID)            */
        /**********************************************************************/
        MatchNo.CPIndex     = INVALID_CODEPAGE_INDEX;
        MatchNo.BaseMatchNo = 0;
        MatchNo.EngineAttrs = 0;
        prdm_PutLCIDFontType(MatchNo, FT_CARD);

       /***********************************************************************/
       /*  Loop thru each card font                                           */
       /***********************************************************************/
        SystemCodePage = (SHORT)WinQueryProcessCP();
        SystemCodePage1 = (SHORT)WinQueryProcessCP();
        SystemCodePage2 = (SHORT)WinQueryProcessCP();

        /**********************************************************************/
        /*  PD00737 : Initialize FacenameFlag.                                */
        /**********************************************************************/
        FacenameFlag = TRUE;

        for (Index = 0 ; Index < PrinterData->CardFontCount ; Index++)
        {
            /******************************************************************/
            /* PD00507: If queued raw then do not return a font from a card   */
            /*          that is not selected.                                 */
            /******************************************************************/
            CardIsSelected = TRUE;
            if (DCIData->Flags & QUEUED_RAW)
            {
               CardIsSelected = FALSE;
               for (NumberOfSlots = 0 ; NumberOfSlots < pDDT->DDTNoOfCardSlots;
                    NumberOfSlots++)
               {
                  if ( PrinterData->SlotInfo[NumberOfSlots].OwnedCardIndex ==
                                    NO_CARD_IN_SLOT ) /* CON3203 */
                     continue;
                  if (!prdu_strcmp(PrinterData->CardData[Index].pCardName,
                     PrinterData->CardData[PrinterData->SlotInfo[NumberOfSlots].
                     FontIndex].pCardName) )
                  {
                     CardIsSelected = TRUE;
                  }
               }
            }
            if (!CardIsSelected)
            {
               continue;
            }
            /******************************************************************/
            /*  Pick up the FMF pointer for this font.                        */
            /******************************************************************/
            pFont = PrinterData->CardData[Index].pFMFData;

            /**************************************************************/
            /*  Font is image.                                            */
            /**************************************************************/
            Attrs = pDDT->DDTCardImageAttrs;

            /******************************************************************/
            /*  Put FontIndex into the LCID                                   */
            /******************************************************************/
            prdm_PutLCIDFontIndex(MatchNo, Index);

            /******************************************************************/
            /*  Process device attributes                                     */
            /******************************************************************/
            if ( (pDDT->DDTDialogFlags & DDT_LIMIT_FONTS) &&
                 (pDDT->DDTPrinterFonts == DEV_FONTS_LIMITED) )
            {
                FMFCodePage = pFont->Metrics.usCodePage;

                SystemCodePageInCard = FALSE;
                SaveIndex = 0;
                for (l = 0 ; l < PrinterData->CardFontCount ; l++)
                {
                    if (SystemCodePage == PrinterData->CardData[l].pFMFData->
                                                            Metrics.usCodePage)
                    {
                        SystemCodePageInCard = TRUE;
                        SaveIndex = l;
                    }
                }

                if (((SystemCodePage1 == 437) ||
                     (SystemCodePage1 == 850) ||
                     (SystemCodePageInCard)) &&
                     FirstTime && SecondTime )
                {
                  if (SystemCodePageInCard)
                  {
                    if (prdu_strcmp(PrinterData->CardData[Index].pCardName,
                                  PrinterData->
                                      CardData[SaveIndex].pCardName) != 0)
                    {
                        SystemCodePage1 = FMFCodePage;
                        FirstTime = FALSE;
                        FirstCardName = PrinterData->CardData[Index].pCardName;
                    }
                  }
                  else
                  {
                      SystemCodePage1 = FMFCodePage;
                      FirstTime = FALSE;
                      FirstCardName = PrinterData->CardData[Index].pCardName;
                  }
                }
                else if (((SystemCodePage2 == 437) ||
                          (SystemCodePage2 == 850) ||
                          (SystemCodePageInCard)) &&
                          (prdu_strcmp(FirstCardName,
                             PrinterData->CardData[Index].pCardName)!=0) &&
                          SecondTime )
                {
                  if (SystemCodePageInCard)
                  {
                    if (prdu_strcmp(PrinterData->CardData[Index].pCardName,
                                  PrinterData->
                                      CardData[SaveIndex].pCardName) != 0)
                    {
                        SystemCodePage2 = FMFCodePage;
                        SecondTime = FALSE;
                    }
                  }
                  else
                  {
                      SystemCodePage2 = FMFCodePage;
                      SecondTime = FALSE;
                  }
                }

                /**************************************************************/
                /*  PD00740 : Change from FacenameFlag to !FacenameFlag       */
                /**************************************************************/
                if ( ( (FMFCodePage == 437) || (FMFCodePage == 850) ||
                       (FMFCodePage == SystemCodePage1) ||
                       (FMFCodePage == SystemCodePage2) ) &&
                     (!FacenameFlag) )
                {
                    Result = prda_ProcessAttributes(DcH, ArgFilter,
                                                    (PPFONTMETRICS)&pfmMetrics,
                                                    ArgSize, ArgCount, DCIData,
                                                    FunN, pFont, MatchNo,
                                                    Attrs, &Returned,
                                                    &Remaining,
                                                    &BytesSoFarInSeg);
                }

                if ( !FacenameFlag )
                {
                    /**********************************************************/
                    /*  PD00737 : set FacenameFlag to false                   */
                    /*  PD00740 : Change from FALSE to TRUE here and vis-versa*/
                    /*  on the next one.                                      */
                    /**********************************************************/
                    FacenameFlag = TRUE;
                }
                else
                {
                   FacenameFlag = FALSE;
                }

            }
            else
            {
                Result = prda_ProcessAttributes(DcH, ArgFilter,
                                                (PPFONTMETRICS)&pfmMetrics,
                                                ArgSize, ArgCount, DCIData,
                                                FunN, pFont, MatchNo,
                                                Attrs, &Returned, &Remaining,
                                                &BytesSoFarInSeg);
            }
        }

        /**********************************************************************/
        /*  Construct zero index download font match number (LCID)            */
        /**********************************************************************/
        MatchNo.CPIndex     = INVALID_CODEPAGE_INDEX;
        MatchNo.BaseMatchNo = 0;
        MatchNo.EngineAttrs = 0;
        prdm_PutLCIDFontType(MatchNo, FT_DOWNLOAD);

       /***********************************************************************/
       /*  Loop thru each download font                                       */
       /***********************************************************************/
        for (Index = 0 ; Index < PrinterData->DownFontCount ; Index++)
        {

            /******************************************************************/
            /*  Pick up the FMF pointer for this font.                        */
            /******************************************************************/
            pFont = PrinterData->DownFontData[Index].pFMFData;

            /******************************************************************/
            /*  Get device attributes from DDT for download image font and    */
            /*  process them by calling prda_processAttributes.               */
            /******************************************************************/
            Attrs = pDDT->DDTDownImageAttrs;

            /******************************************************************/
            /*  Put the FontIndex into the LCID                               */
            /******************************************************************/
            prdm_PutLCIDFontIndex(MatchNo, Index);

            Result = prda_ProcessAttributes(DcH, ArgFilter,
                                            (PPFONTMETRICS)&pfmMetrics, ArgSize,
                                            ArgCount, DCIData, FunN, pFont,
                                            MatchNo, Attrs, &Returned,
                                            &Remaining, &BytesSoFarInSeg);

            /******************************************************************/
            /*  Increment the FontIndex field in the LCID                     */
            /******************************************************************/
            prdm_PutLCIDFontIndex(MatchNo, Index);
        }
    }

    /**************************************************************************/
    /*  Set ArgCount to number of metrics returned and return number of       */
    /*  metrics remaining.                                                    */
    /**************************************************************************/
    *ArgCount = (ULONG)Returned;

    /**************************************************************************/
    /*  All done.                                                             */
    /**************************************************************************/
    prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,93)
#endif
    return (Remaining);
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prda_ProcessAttributes                                          */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  HDC             DcH;                                                      */
/*  ULONG           ArgOptions                                                */
/*  PSZ             ArgFilter;                                                */
/*  PVOID           lppfmMetrics;                                             */
/*  ULONG           ArgSize;                                                  */
/*  PULONG          ArgCount;                                                 */
/*  lpDCI           DCIData;                                                  */
/*  ULONG           FunN;                                                     */
/*  lpFMFFileStruc  pFont;              Pointer to FMF for this font          */
/*  LCIDType        MatchNo;            4-byte match number                   */
/*  USHORT          Attrs;              Input device attributes               */
/*  PSHORT          pReturned;          No. of fonts returned                 */
/*  PUSHORT         pRemaining;                                               */
/*  PULONG          pBytesSoFarInSeg;   Byte count into ArgMetrics for        */
/*                                      checking when 64K boundary has been   */
/*                                      reached to split copy into two        */
/*                                      chunks.  Initialized in               */
/*                                      DeviceQueryFonts, used in             */
/*                                      prda_ReturnMetrics.                   */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  The input device attributes (Attrs) are processed and metrics added to the*/
/*  ArgMetrics buffer for any attribute supported by this font (pFont).  The  */
/*  following parms are updated: ArgMetrics, Returned, Remaining, and         */
/*  BytesSoFarInSeg.  The input device attributes(Attrs) are included in the  */
/*  returned Argmetrics in the match number variable.                         */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
USHORT prda_ProcessAttributes( HDC             DcH,
                               PSZ             ArgFilter,
                               PPFONTMETRICS   lplpMetrics,
                               ULONG           ArgSize,
                               PULONG          ArgCount,
                               lpDCI           DCIData,
                               ULONG           FunN,
                               lpFMFFileStruc  pFont,
                               LCIDType        MatchNo,
                               USHORT          DeviceAttrs,
                               PSHORT          pReturned,
                               PUSHORT         pRemaining,
                               PULONG          pBytesSoFarInSeg )

{
#define TFUNC "prda_ProcessAttributes"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    FONTMETRICS   MetricsBuffer;       /* Temp metrics buffer                 */
    PFONTMETRICS  pMetricsBuffer;      /* Pointer to temp metrics buffer      */
    USHORT        Attr;
    lpDDTType     pDDT;
    ULONG         ArgSizeReturn;       /* PD00673                             */

    pMetricsBuffer = &MetricsBuffer;
    pDDT           = &DCIData->DCIPdbInstance->DDT;

    /**************************************************************************/
    /* PD00673: Save the requested size, since it can be larger than the      */
    /* sizeof FONTMETRICS structure for OS2 2.0 .  New fields have been added */
    /* to this structure for 2.0 that are not in our metrics.                 */
    /**************************************************************************/
    ArgSizeReturn = ArgSize;

    /**************************************************************************/
    /* PD00673 : Moved this if statment form top of Prda_DeviceQueryFonts.    */
    /* Put a bound on ArgSize.                                                */
    /**************************************************************************/
    if (ArgSize > sizeof(FONTMETRICS))
        ArgSize = sizeof(FONTMETRICS);

    /**************************************************************************/
    /*  Now loop through the attributes, seeing which are possible for this   */
    /*  font.                                                                 */
    /**************************************************************************/
    for (Attr = 0; Attr < MAX_DEVICE_ATTRIBUTE ; Attr++)
    {
        /**********************************************************************/
        /* PD00604 : For the 239X printers when Limited Code Pages button     */
        /* is selected in Printer Fonts box, and the font is available in     */
        /* both DW and DH, only return normal and DWDH fonts.  Do not return  */
        /* DW font or DH font.                                                */
        /**********************************************************************/
        if ( ( pDDT->DDTPrinterFonts == DEV_FONTS_LIMITED ) &&
             ( (pDDT->DDTDriverType == DDT_IBM42XX_DRV) &&
               ( (DCIData->DCIPdbInstance->PrinterType == IBM_NILE_24 ) ||
                 (DCIData->DCIPdbInstance->PrinterType == IBM_TIBER_24) ||
                 (DCIData->DCIPdbInstance->PrinterType == IBM_2390_PS1) ) ) &&
                 ( ( DeviceAttrs & FATT_DOUBLE_HIGH ) &&
                   ( DeviceAttrs & FATT_DOUBLE_WIDE ) ) )
        {
             if (Attr == 0 || Attr == FATT_BOTH)
             {
                /**************************************************************/
                /*  Add device attributes to BaseMatchNo.                     */
                /**************************************************************/
                prdm_PutLCIDFontDevAttrs(MatchNo, (BYTE)Attr);

                /**************************************************************/
                /*  Check to see if the facename in ArgFilter matches the     */
                /*  facename of this font.                                    */
                /**************************************************************/
                if (prda_MatchFaceNames(DCIData, pFont, ArgFilter, Attr, MatchNo))
                {
                    if (*pReturned < (SHORT)(USHORT)*ArgCount)
                    {

                        /******************************************************/
                        /*  Copy the metrics for the current font to the local*/
                        /*  temp metric buffer                                */
                        /******************************************************/
                        if (prda_CopyMetrics(DcH, (ULONG)USE_CHAR_BOX,
                                             pMetricsBuffer, ArgSize, pFont,
                                             DCIData, MatchNo, FunN) != OK)
                        {
                            return (ERROR_ZERO);
                        }

                        /******************************************************/
                        /*  Write base match number into temp metrics         */
                        /******************************************************/
                        prdu_memcpy((PBYTE)&pMetricsBuffer->lMatch,
                                    (PBYTE)&MatchNo,
                                    4);

                        /******************************************************/
                        /*  Copy metrics from local temp buffer to the return */
                        /*  ArgMetrics buffer.                                */
                        /******************************************************/
                        /******************************************************/
                        /* PD00673 : Changed ArgSize argument to ArgSizeReturn*/
                        /* to allow for filling the return buffer when        */
                        /* ArgSizeReturn is larger than sizeof(FONTMETRICS).  */
                        /******************************************************/
                     /* prda_ReturnMetrics(pMetricsBuffer, lplpMetrics,       */
                     /*                    ArgSizeReturn, pBytesSoFarInSeg);  */
        /* CON3201 - Take out the pBytesSoFarInSeg and just copy to buffer in */
        /*           one shot - Leave for now just don't use pBytesSoFarInSeg */
                        prda_ReturnMetrics(pMetricsBuffer, lplpMetrics,
                                           ArgSizeReturn, pBytesSoFarInSeg);
                        (*pReturned)++;
                    }
                    else
                    {

                        /******************************************************/
                        /*  No more to be returned, increment number remaining*/
                        /******************************************************/
                        (*pRemaining)++;
                    }
                }
             }
        }
        else if ( (DeviceAttrs == (BYTE)Attr) || (DeviceAttrs == 3) ||
                 (Attr == 0) )
        {

            /******************************************************************/
            /*  Add device attributes to BaseMatchNo.                         */
            /******************************************************************/
            prdm_PutLCIDFontDevAttrs(MatchNo, (BYTE)Attr);

            /******************************************************************/
            /*  Check to see if the facename in ArgFilter matches the facename*/
            /*  of this font.                                                 */
            /******************************************************************/
            if (prda_MatchFaceNames(DCIData, pFont, ArgFilter, Attr, MatchNo))
            {
                if (*pReturned < (SHORT)(USHORT)*ArgCount)
                {

                    /**********************************************************/
                    /*  Copy the metrics for the current font to the local    */
                    /*  temp metric buffer                                    */
                    /**********************************************************/
                    if (prda_CopyMetrics(DcH, (ULONG)USE_CHAR_BOX,
                                         pMetricsBuffer, ArgSize, pFont,
                                         DCIData, MatchNo, FunN) != OK)
                    {
                        return (ERROR_ZERO);
                    }

                    /**********************************************************/
                    /*  Write base match number into temp metrics             */
                    /**********************************************************/
                    prdu_memcpy((PBYTE)&pMetricsBuffer->lMatch, (PBYTE)&MatchNo,
                                4);

                    /**********************************************************/
                    /*  Copy metrics from local temp buffer to the return     */
                    /*  ArgMetrics buffer.                                    */
                    /*  PD00673 : Changed ArgSize to ArgSizeReturn            */
                    /**********************************************************/
                 /* prda_ReturnMetrics(pMetricsBuffer, lplpMetrics,           */
                 /*                    ArgSizeReturn, pBytesSoFarInSeg);      */
        /* CON3201 - Take out the pBytesSoFarInSeg and just copy to buffer in */
        /*           one shot - Leave for now just don't use pBytesSoFarInSeg */
                    prda_ReturnMetrics(pMetricsBuffer, lplpMetrics,
                                       ArgSizeReturn, pBytesSoFarInSeg);
                    (*pReturned)++;
                }
                else
                {

                    /**********************************************************/
                    /*  No more to be returned, increment number remaining.   */
                    /**********************************************************/
                    (*pRemaining)++;
                }
            }
        }
    }
}
#undef TFUNC


/******************************************************************************/
/*  FUNCTION: prda_MatchFaceNames                                             */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  lpDCI           DCIData;                                                  */
/*  lpFMFFileStruc  pFont;                                                    */
/*  PSZ             ArgFilter;                                                */
/*  USHORT          Attr;                                                     */
/*  LCIDType        MatchNo;                                                  */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function compares the font face name in ArgFilter to the face name in*/
/*  the pFont FMF and returns TRUE or FALSE.                                  */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
BOOL prda_MatchFaceNames( lpDCI            DCIData,
                          lpFMFFileStruc   pFont,
                          PSZ              ArgFilter,
                          USHORT           Attr,
                          LCIDType         MatchNo )

{
#define TFUNC "prda_MatchFaceNames"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    BOOL    Match;
    BYTE    AdjFaceName[32];           /* FaceName plus quality and attribute */
                                       /* description                         */
    CHAR    FaceChar;
    USHORT  i;
    lpPDBI  PDBInstance;               /* pointer to PDB                      */

    PDBInstance = DCIData->DCIPdbInstance;

    /**************************************************************************/
    /*  Determine whether the facename matches the supplied filter.  The      */
    /*  facename may vary with the font quality and attribute so set up an    */
    /*  adjusted facename before doing the comparison.  Dont bother to do this*/
    /*  check if there is no filter since then all fonts match.               */
    /**************************************************************************/
    Match = ((!ArgFilter) || (*ArgFilter == '\0'));
    if (!Match)
    {

        /**********************************************************************/
        /*  Copy across the facename from the source metrics to our local     */
        /*  facename buffer.                                                  */
        /**********************************************************************/
        for (i = 0; i < 32; i++)
        {
            FaceChar = pFont->Metrics.szFacename[i];
            AdjFaceName[i] = (FaceChar == '*') ? (BYTE)'.' : FaceChar;
        }
        prda_AdjustFaceName(AdjFaceName, MatchNo, PDBInstance);

        /**********************************************************************/
        /*  Give Match a second chance to be true.                            */
        /**********************************************************************/
        Match = (!prdu_strcmp((PBYTE)ArgFilter, (PBYTE)AdjFaceName));
    }

    /**************************************************************************/
    /*  CODE1 : Ensure comments are not between if and the processing arm.    */
    /*  Facename matches (or no filter).                                      */
    /**************************************************************************/
    if (Match)
        return(TRUE);
    else
        return(FALSE);
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prda_ReturnMetrics                                              */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  PFONTMETRICS  pMetricsBuffer;    Input Temp metrics buffer                */
/*  PVOID         lplpMetrics;       Pointer to return metrics buffer         */
/*  ULONG         ArgSizeReturn;                                              */
/*  PULONG        pBytesSoFarInSeg;  Number of bytes written                  */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function copies the metrics from the temp buffer to the return       */
/*  lplpMetrics buffer taking into account a segment boundary.                */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
VOID prda_ReturnMetrics( PFONTMETRICS   pMetricsBuffer,
                         PPFONTMETRICS  lplpMetrics,
                         ULONG          ArgSizeReturn,
                         PULONG         pBytesSoFarInSeg )

{
#define TFUNC "prda_ReturnMetrics"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    ULONG  CopyCountA;
    ULONG  CopyCountB;
    ULONG  ArgSize;                         /* PD00673                        */
    ULONG  BytesToFill;                     /* PD00673                        */
    PBYTE  pbTemp;                          /* CON3201                        */

    /**************************************************************************/
    /*  NOTE: The DDI spec.  says that the code page should be set to zero -  */
    /*  but in that case the driver has no way of reporting back the fact that*/
    /*  our fonts come in different code pages.  Looks as though this DDI     */
    /*  feature is tailored for the MS drivers which handle code pages        */
    /*  differently.                                                          */
    /*                                                                        */
    /*     pMetricsBuffer->usCodePage = 0;                                    */
    /**************************************************************************/

    /**************************************************************************/
    /* PD00673: ArgSizeReturn can be larger than our Fontmetrics structure.   */
    /* New fields have been added to this structure for 2.0 that are not in   */
    /* our device metrics so we must use the old shorter Fontmetrics struc.   */
    /**************************************************************************/
    ArgSize = ArgSizeReturn;

    /**************************************************************************/
    /* PD00673 :  Put a bound on ArgSize                                      */
    /**************************************************************************/
    if (ArgSize > sizeof(FONTMETRICS))
        ArgSize = sizeof(FONTMETRICS);

    /**************************************************************************/
    /*  Check if we need to split the copy into two chunks                    */
    /**************************************************************************/
#if 0
/*  CON3201 - We will just fill it in one shot, no splitting the copy         */
    if (*pBytesSoFarInSeg + ArgSize >= 0x10000)
    {
        CopyCountA = 0x10000 - *pBytesSoFarInSeg;
        CopyCountB = ArgSize - CopyCountA;
        prdu_memcpy((PBYTE)(*lplpMetrics), (PBYTE)pMetricsBuffer,
                    (USHORT)CopyCountA);
        SELECTOROF(*lplpMetrics) += prdd_HugeInc;
        OFFSETOF(*lplpMetrics)    = 0;
        if (CopyCountB != 0)
        {
            prdu_memcpy((PBYTE)(*lplpMetrics),
                        (PBYTE)((PBYTE)pMetricsBuffer + CopyCountA),
                        (USHORT)CopyCountB);
        }
        (PBYTE)(*lplpMetrics) += CopyCountB;
        *pBytesSoFarInSeg      = CopyCountB;
    }
    else
    {
        prdu_memcpy((PBYTE)(*lplpMetrics), (PBYTE)pMetricsBuffer,
                    (USHORT)ArgSize);

        (PBYTE)(*lplpMetrics) += ArgSize;
        *pBytesSoFarInSeg     += ArgSize;
    }
#endif
    /* CON3201 - Copy the buffer                         ************/
    prdu_memcpy((PBYTE)(*lplpMetrics), (PBYTE)pMetricsBuffer, ArgSize);
    pbTemp =  (PBYTE)(*lplpMetrics);        /* CON3201 */
    pbTemp += ArgSize;                      /* CON3201 */
    *lplpMetrics = (PFONTMETRICS)pbTemp;    /* CON3201 */
    /**************************************************************************/
    /* PD00673 : Fill rest of return buffer with zeroes when ArgSizeReturn is */
    /* larger than our FontMetrics structure. This happens with some OS/2 2.0 */
    /* apps.                                                                  */
    /**************************************************************************/
    if ( ArgSizeReturn > ArgSize )
    {
        /**********************************************************************/
        /* Calculate the number of bytes to fill with zeroes                  */
        /**********************************************************************/
        BytesToFill = ArgSizeReturn - ArgSize;

        /**************************************************************************/
        /*  Check if we need to split the copy into two chunks                    */
        /**************************************************************************/
#if 0
/*  CON3201 - We will just fill it in one shot, no splitting the copy         */
        if (*pBytesSoFarInSeg + BytesToFill >= 0x10000)
        {
            CopyCountA = 0x10000 - *pBytesSoFarInSeg;
            CopyCountB = BytesToFill - CopyCountA;
            prdu_memset((PBYTE)(*lplpMetrics), 0, (USHORT)CopyCountA);
            SELECTOROF(*lplpMetrics) += prdd_HugeInc;
            OFFSETOF(*lplpMetrics)    = 0;
            if (CopyCountB != 0)
            {
                prdu_memset((PBYTE)(*lplpMetrics), 0, (USHORT)CopyCountB);
            }
            (PBYTE)(*lplpMetrics) += CopyCountB;
            *pBytesSoFarInSeg      = CopyCountB;
        }
        else
        {
            prdu_memset((PBYTE)(*lplpMetrics), 0, (USHORT)BytesToFill);

            (PBYTE)(*lplpMetrics) += BytesToFill;
            *pBytesSoFarInSeg     += BytesToFill;
        }
#endif
        /* CON3201 Fill the remainder of the buffer with zeros   */
        prdu_memset((PBYTE)(*lplpMetrics), 0, BytesToFill);
/*        (PBYTE)(*lplpMetrics) += BytesToFill;    CON3201 */
        pbTemp =  (PBYTE)(*lplpMetrics);         /* CON3201 */
        pbTemp += BytesToFill;                   /* CON3201 */
        *lplpMetrics = (PFONTMETRICS)pbTemp;     /* CON3201 */
    }

    /**************************************************************************/
    /*  All done.                                                             */
    /**************************************************************************/
    return;
}
#undef TFUNC

/******************************************************************************/
/*   FUNCTION: prda_CopyMetrics                                               */
/*                                                                            */
/*   PARAMETERS:                                                              */
/*                                                                            */
/*   HDC             DcH;                                                     */
/*   ULONG           flFlags;                                                 */
/*   PFONTMETRICS    pTrgMetrics;  Target buffer for copy                     */
/*   ULONG           ArgSize;      Size of target buffer                      */
/*   lpFMFFileStruc  pFont;        Current font FMF pointer                   */
/*   lpDCI           DCIData;                                                 */
/*   LCIDType        MatchNo;      4-byte MatchNo Structure                   */
/*   ULONG           FunN;                                                    */
/*   DESCRIPTION:                                                             */
/*                                                                            */
/*  Function copies font metrics from SrcMetrics (type PFOCAMETRICS) to       */
/*  TrgMetrics (type PFONTMETRICS) casting fields where necessary.  The       */
/*  function does not write data into TrgMetrics beyond the limit imposed by  */
/*  ArgSize.  The function uses standard OK / ERROR_ZERO return codes.        */
/*                                                                            */
/*  ASSUMPTIONS:                                                              */
/*                                                                            */
/*  - ArgSize is bounded by sizeof(FONTMETRICS)                               */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
USHORT prda_CopyMetrics( HDC             DcH,
                         ULONG           flFlags,
                         PFONTMETRICS    pTrgMetrics,
                         ULONG           ArgSize,
                         lpFMFFileStruc  pFont,
                         lpDCI           DCIData,
                         LCIDType        MatchNo,
                         ULONG           FunN )

{
#define TFUNC "prda_CopyMetrics"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    PFOCAMETRICS    pSrcMetrics;
    FONTMETRICS     TargetBuffer;
    PFONTMETRICS    pTargetBuffer;
    lpPDBI          PDBInstance;       /* Pointer to the PDB                  */
    lpDDTType       pDDT;              /* Pointer to the DDT                  */
    BYTE            fsAttrs;           /* The font attribute in terms of bit  */
                                       /* flags                               */
    USHORT          i;                 /* Loop variable                       */
    CHAR            FaceChar;
    BYTE            AdjFaceName[32];   /* FaceName plus quality and attribute */
                                       /* description                         */
    PSHORT          psSrcElement;      /* Pointer to field in source metrics  */
                                       /* structure                           */
    PLONG           plTrgElement;      /* Pointer to field in target metrics  */
                                       /* structure                           */
    USHORT          ItalicIndex;       /* Index into DVTItalicSlope list      */
    lpFontListType  pResFontInfo;      /* Pointer to resident font list       */
    XFORM           xfm;               /* Transformation matrix               */
    USHORT          fsXform;
    USHORT         FontIndex;

    /**************************************************************************/
    /*  Return immediately if zero length buffer.                             */
    /**************************************************************************/
    if (ArgSize == 0)
        return (OK);

    /**************************************************************************/
    /*  Set up pointers.                                                      */
    /**************************************************************************/
    PDBInstance   = DCIData->DCIPdbInstance;
    pDDT          = &PDBInstance->DDT;
    pTargetBuffer = &TargetBuffer;
    pSrcMetrics   = &pFont->Metrics;

    /**************************************************************************/
    /*  Zero the target buffer.                                               */
    /**************************************************************************/
    (VOID)prdu_memset((PBYTE)pTargetBuffer, 0, sizeof(FONTMETRICS));

    /**************************************************************************/
    /*  Copy across FamilyName.                                               */
    /**************************************************************************/
    prdu_memcpy((PBYTE)pTargetBuffer->szFamilyname,
                 (PBYTE)pSrcMetrics->szFamilyname, 32);

    /**************************************************************************/
    /*  Adjust FaceName so that asterisks are converted to a decimal point -  */
    /*  the one returned here is always ".".  It does not vary with the       */
    /*  country as when we pass and receive facenames with the engine we      */
    /*  always use a ".".                                                     */
    /*                                                                        */
    /*  Adjust FaceName to add a description of the quality type (if          */
    /*  necessary) and a description of the attribute type (e.g.  " DW DH" ). */
    /*  Then copy it across.                                                  */
    /**************************************************************************/

    /**************************************************************************/
    /*  Copy across the facename from the source metrics to our local facename*/
    /*  buffer.                                                               */
    /**************************************************************************/
    for (i = 0; i < 32; i++)
    {
        FaceChar       = pSrcMetrics->szFacename[i];
        AdjFaceName[i] = (FaceChar == '*') ? (BYTE)'.' : FaceChar;
    }
    prda_AdjustFaceName(AdjFaceName, MatchNo, PDBInstance);
    prdu_memcpy((PBYTE)pTargetBuffer->szFacename, (PBYTE)AdjFaceName, 32);

    /**************************************************************************/
    /*  Copy across RegistryId and CodePage - both USHORTs.                   */
    /**************************************************************************/
    prdu_memcpy((PBYTE)&pTargetBuffer->idRegistry,
                (PBYTE)&pSrcMetrics->usRegistryId, 4);

    /**************************************************************************/
    /*  The 12 fields from EmHeight to MaxBaselineExt must be changed from    */
    /*  SHORT to LONG.                                                        */
    /*                                                                        */
    /*  The increment on plTrgElement and psSrcElement works correctly because*/
    /*  of their types.                                                       */
    /**************************************************************************/
    plTrgElement = &pTargetBuffer->lEmHeight;
    psSrcElement = &pSrcMetrics->yEmHeight;

    for (i = 0; i < 12; i++)
        *plTrgElement++ = (LONG)*psSrcElement++;

    /**************************************************************************/
    /*  The 18 values from CharSlope to Capabilities are identical and are all*/
    /*  USHORTs.                                                              */
    /**************************************************************************/
    prdu_memcpy((PBYTE)&pTargetBuffer->sCharSlope,
                (PBYTE)&pSrcMetrics->sCharSlope, 36);

    /**************************************************************************/
    /*  All our fonts can be mixed with graphics so reset the FM_CAP NOMIX    */
    /*  flag.                                                                 */
    /**************************************************************************/
    pTargetBuffer->fsCapabilities &= ~FM_CAP_NOMIX;

    /**************************************************************************/
    /*  Clear FM_DEFN_GENERIC flag, since all fonts are device fonts. PD00687 */
    /**************************************************************************/
    pTargetBuffer->fsDefn &= ~FM_DEFN_GENERIC;

    /**************************************************************************/
    /*  The 12 fields from SubscriptXSize to StrikeoutPosition must be changed*/
    /*  from SHORT to LONG.                                                   */
    /**************************************************************************/
    plTrgElement = (PLONG)&pTargetBuffer->lSubscriptXSize;
    psSrcElement = (PSHORT)&pSrcMetrics->ySubscriptXSize;
    for (i = 0; i < 12; i++)
        *plTrgElement++ = (LONG)*psSrcElement++;

    /**************************************************************************/
    /*  The remaining field can be copied directly - oh joy, deep deep joy.   */
    /**************************************************************************/
    pTargetBuffer->sKerningPairs = pSrcMetrics->usKerningPairs;

    /**************************************************************************/
    /*  Get the font attribute in terms of bit flags from the MatchNo.        */
    /**************************************************************************/
    fsAttrs = prdm_GetLCIDFontDevAttrs(MatchNo);

    /**************************************************************************/
    /*  Adjust the metrics for the StrikeOut Attribute.                       */
    /**************************************************************************/

    /**************************************************************************/
    /*  Setup strikeout fields if zero                                        */
    /**************************************************************************/
    if ((pTargetBuffer->lStrikeoutSize == 0) &&
        (pTargetBuffer->lStrikeoutPosition == 0))
    {
        pTargetBuffer->lStrikeoutSize = (pTargetBuffer->lMaxAscender > 10) ?
                                        (pTargetBuffer->lMaxAscender/10) : 1;
        pTargetBuffer->lStrikeoutPosition = (pTargetBuffer->lMaxAscender > 4) ?
                                            (pTargetBuffer->lMaxAscender/4) : 1;
    }

    /**************************************************************************/
    /*  Setup underscore fields if zero                               PD00677 */
    /*                                                                        */
    /*  Note: Underscore paints up from position, while strikeout paints      */
    /*        down from position, per M. Cooper 3/25/92                       */
    /**************************************************************************/
    if ((pTargetBuffer->lUnderscoreSize == 0) &&
        (pTargetBuffer->lUnderscorePosition == 0))
    {
        pTargetBuffer->lUnderscoreSize     = pTargetBuffer->lStrikeoutSize;
        pTargetBuffer->lUnderscorePosition = pTargetBuffer->lLowerCaseDescent +
                                             pTargetBuffer->lUnderscoreSize;
        if (pTargetBuffer->lUnderscorePosition > pTargetBuffer->lMaxDescender)
        {
            pTargetBuffer->lUnderscorePosition = pTargetBuffer->lMaxDescender;
        }
    }

    /**************************************************************************/
    /*  Adjust the metrics for the Double Wide attribute.                     */
    /**************************************************************************/
    if (fsAttrs & FATT_DOUBLE_WIDE)
    {
        pTargetBuffer->lAveCharWidth      *= 2;
        pTargetBuffer->lMaxCharInc        *= 2;
        pTargetBuffer->lEmInc             *= 2;
        pTargetBuffer->lSubscriptXOffset  *= 2;
        pTargetBuffer->lSubscriptXSize    *= 2;
        pTargetBuffer->lSuperscriptXOffset*= 2;
        pTargetBuffer->lSuperscriptXSize  *= 2;

        /**********************************************************************/
        /*  A font that is only double wide has a width class of 9.           */
        /**********************************************************************/
        if (!(fsAttrs & FATT_DOUBLE_HIGH))
            pTargetBuffer->usWidthClass = 9;
    }

    /**************************************************************************/
    /*  Adjust the metrics for the Double High attribute.                     */
    /**************************************************************************/
    if (fsAttrs & FATT_DOUBLE_HIGH)
    {
        pTargetBuffer->lEmHeight          *= 2;
        pTargetBuffer->lXHeight           *= 2;
        pTargetBuffer->lMaxAscender       *= 2;
        pTargetBuffer->lMaxDescender      *= 2;
        pTargetBuffer->lLowerCaseAscent   *= 2;
        pTargetBuffer->lLowerCaseDescent  *= 2;
        pTargetBuffer->lMaxBaselineExt    *= 2;
        pTargetBuffer->sNominalPointSize  *= 2; /* PD00369...                 */
        pTargetBuffer->sMinimumPointSize  *= 2; /* PD00369...                 */
        pTargetBuffer->sMaximumPointSize  *= 2; /* PD00369...                 */
        pTargetBuffer->lInternalLeading   *= 2;
        pTargetBuffer->lExternalLeading   *= 2;
        pTargetBuffer->lUnderscoreSize    *= 2;
        pTargetBuffer->lUnderscorePosition*= 2;
        pTargetBuffer->lStrikeoutSize     *= 2;
        pTargetBuffer->lStrikeoutPosition *= 2;
        pTargetBuffer->lSubscriptYOffset  *= 2;
        pTargetBuffer->lSubscriptYSize    *= 2;
        pTargetBuffer->lSuperscriptYOffset*= 2;
        pTargetBuffer->lSuperscriptYSize  *= 2;

        /**********************************************************************/
        /*  If the font is both double high and double wide then it has a     */
        /*  "normal" aspect ratio; the same as the base font so leave the     */
        /*  width class alone.  A font that is only double high has a width   */
        /*  class of 1.                                                       */
        /**********************************************************************/
        if (!(fsAttrs & FATT_DOUBLE_WIDE))
            pTargetBuffer->usWidthClass = 1;
    }

    /**********************************************************************/
    /*  Ignore the CharBox.  The metrics in TargetBuffer are in font      */
    /*  coords; the coords they should be returned in depend on the       */
    /*  COM_TRANSFORM bit.                                                */
    /**********************************************************************/
    if (FunN & COM_TRANSFORM)
        fsXform = FONT_TO_WORLD;
     else
        fsXform = FONT_TO_DEVICE;

    if (fsXform)
    {

        /**********************************************************************/
        /*  We are converting widths and heights, not coords, so ignore the   */
        /*  origin shift.                                                     */
        /**********************************************************************/
        fsXform |= IGNORE_ORIGIN_SHIFT;
        if (prdg_GetXformMatrix(DcH, fsXform, (PXFORM)&xfm, DCIData) != OK)
            return(ERROR_ZERO);

        /**********************************************************************/
        /*  Convert the metrics as required - xform_metrics works a little    */
        /*  harder than necessary as it handles an origin shift.              */
        /**********************************************************************/
        (VOID)xform_metrics(DcH, pTargetBuffer, (PXFORM)&xfm);
    }

    /**********************************************************************/
    /*  Set the resolutions to be the current DEVICE resolution.  These   */
    /*  fields are constant for outline fonts.                            */
    /**********************************************************************/
    pTargetBuffer->sXDeviceRes = pDDT->DDTRasterMode->ResWidth;
    pTargetBuffer->sYDeviceRes = pDDT->DDTRasterMode->ResDepth;

    /**************************************************************************/
    /*  Copy ArgSize bytes from the transformed buffer to the Target Metrics  */
    /*  buffer.                                                               */
    /**************************************************************************/
    prdu_memcpy((PBYTE)pTrgMetrics, (PBYTE)pTargetBuffer, ArgSize);
    return (OK);
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prda_AdjustFaceName                                             */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  PBYTE     FaceName;     Facename buffer                                   */
/*  LCIDType  MatchNo;      4-byte LCID structure                             */
/*  lpPDBI    PDBInstance;                                                    */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function adds a description of the font quality and then the font    */
/*  attribute of the facename.                                                */
/*  ASSUMPTIONS:                                                              */
/*  The total facename length will not exceed 32 characters (including the  */
/*  null terminator) after quality and attribute descriptions have been added.*/
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
VOID prda_AdjustFaceName( PBYTE     FaceName,
                          LCIDType  MatchNo,
                          lpPDBI    PDBInstance )

{
#define TFUNC "prda_AdjFaceNme"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    PBYTE   pSource, pDest;            /* Working pointers                    */
    BYTE    fsAttrs;                   /* The font attribute in terms of bit  */
                                       /* flags                               */
    USHORT  FontIndex;
    USHORT  NumCharacters;             /* INKJET: Count the number of chars   */
                                       /* in the facename                     */
    USHORT  TempCount;                 /*  PD00731  */

    CHAR    PitchStr[4];               /* PD00732                             */
    CHAR    fname[32];                 /* PD00732                             */
    USHORT  j;                         /* PD00732                             */
    USHORT  PreDCTCmd;                 /* PD00732                             */

    /**************************************************************************/
    /*  Move our working pointer to the end of the facename.                  */
    /*  INKJET: Initialise NumCharacters and increment it with pDest.         */
    /**************************************************************************/
    NumCharacters = 0;
    for (pDest = FaceName; *pDest != '\0'; pDest++)
    {
        NumCharacters++;
    }

    /**************************************************************************/
    /*  Setup fsAttrs for later use                                   PD00731 */
    /**************************************************************************/
    fsAttrs = prdm_GetLCIDFontDevAttrs(MatchNo);


    /**************************************************************************/
    /*  Now add on any attribute desription.  Add the Bold description if     */
    /*  either of the Emphasised or Double Strike flags are set - dual flags  */
    /*  since different printers achieve the boldness attribute with different*/
    /*  escape sequences.                                                     */
    /**************************************************************************/

    /**************************************************************************/
    /*  CODE1 : Ensure that when a FOR follows an IF there are braces around  */
    /*  the IF arm                                                            */
    /**************************************************************************/
    if (fsAttrs & FATT_DOUBLE_WIDE)
    {
        for (pSource = szDWideString; *pSource != '\0';)
        {
            *pDest++ = *pSource++;
            /**************************************************************/
            /*  Increment NumCharacters as pDest increases.               */
            /**************************************************************/
            NumCharacters++;
        }
    }

    /**************************************************************************/
    /*  CODE1 : Ensure that when a FOR follows an IF there are braces around  */
    /*  the IF arm                                                            */
    /**************************************************************************/
    if (fsAttrs & FATT_DOUBLE_HIGH)
    {
        for (pSource = szDHighString; *pSource != '\0';)
        {
            *pDest++ = *pSource++;
            /**************************************************************/
            /*  Increment NumCharacters as pDest increases.               */
            /**************************************************************/
            NumCharacters++;
        }
    }

    /**************************************************************************/
    /*  Check on the length of pDest incase it is too long - INKJET           */
    /**************************************************************************/
    if (NumCharacters >= 32)
    {
        for (; NumCharacters >= 32; NumCharacters--)
        {
            *pDest--;
        }
    }

    /**************************************************************************/
    /*  Finish off, not with a bang but with a whimper.                       */
    /**************************************************************************/
    *pDest = '\0';

    /**************************************************************************/
    /*  hmmm-mmm, all done.                                                   */
    /**************************************************************************/
    return;
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prda_AdjustForCharBox                                           */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  PFONTMETRICS    TrgMetrics;  Target buffer for copy                       */
/*  ULONG           ArgSize;     Size of target buffer                        */
/*  lpFontInfoType  pFontInfo;   Current font info                            */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This routine scales outline font metrics by the character box as follows: */
/*  - height fields scaled by (CharBox height / yEmHeight)                    */
/*  - width fields scaled by (CharBox width / yEmInc)                         */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
VOID prda_AdjustForCharBox( PFONTMETRICS  pTargetBuffer,
                            lpDCI         DCIData,
                            USHORT        flflags )

{
#define TFUNC "prda_AdjustForCharBox"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    LONG  CharBoxWidth;
    LONG  CharBoxHeight;
    LONG  WidthDivisor;
    LONG  HeightDivisor;
    POINTL CharBox;
    USHORT fsXform;
    XFORM  xfm;

    /**************************************************************************/
    /*  Get a local copy of the CharBox.                                      */
    /**************************************************************************/
    /**************************************************************************/
    /*  PD00137 Def outline font pointsize selection                          */
    /**************************************************************************/
    /**************************************************************************/
    /*  IF flflag has been set to scale to pointsize, then find the new       */
    /*  charbox ( (pointsize / 72) * resolution ).  Else use the charbox      */
    /**************************************************************************/
    if (flflags == USE_POINT_SIZE)
    {
      CharBox.x     = prdg_ScaleValue((LONG)DCIData->DCIPdbInstance->
                                                     DfltFontPointSz,
                                      (LONG)DCIData->DCIPdbInstance->
                                      DDT.DDTRasterMode->ResWidth, 72L);
      CharBox.y     = 0;

      /**********************************************************************/
      /* Convert CharBox   from device to world coords.                     */
      /*                                                                    */
      /* Get Device->World transform matrix.                                */
      /**********************************************************************/
      fsXform = DEVICE_TO_WORLD | IGNORE_ORIGIN_SHIFT;

      prdg_GetXformMatrix( (HDC)DCIData->DcH,
                                fsXform,
                                (PXFORM)&xfm,
                                DCIData );

      /**********************************************************************/
      /* Use prdg_XformPoint to convert this vector to a length in world    */
      /* coords.                                                            */
      /**********************************************************************/
      CharBox.x = prdg_XformPoint( (HDC)DCIData->DcH, (PPOINTL)&CharBox,
                                     (PXFORM)&xfm );
      CharBoxWidth = CharBox.x;
      CharBoxHeight = CharBoxWidth;

      /************************************************************************/
      /*  Work out the divisors.                                              */
      /************************************************************************/
      WidthDivisor  = (LONG)pTargetBuffer->lEmInc;
      HeightDivisor = (LONG)pTargetBuffer->lEmHeight;
      pTargetBuffer->lEmInc = CharBoxWidth;
      pTargetBuffer->lEmHeight = CharBoxHeight;
    }
    else
    {
      CharBoxWidth  = (LONG)DCIData->DCICurTxtAts->cbnd.sizfxCell.cx;
      CharBoxHeight = (LONG)DCIData->DCICurTxtAts->cbnd.sizfxCell.cy;

      /************************************************************************/
      /*  Work out the divisors.  The << 16 (or * 0x10000) is because         */
      /*  CharBoxWidth and CharBoxHeight values are in FIXED type.            */
      /************************************************************************/
      WidthDivisor  = (LONG)pTargetBuffer->lEmInc << 16;
      HeightDivisor = (LONG)pTargetBuffer->lEmHeight << 16;
      pTargetBuffer->lEmInc = CharBoxWidth >> 16;
      pTargetBuffer->lEmHeight = CharBoxHeight >> 16;
    }

    /**************************************************************************/
    /*  Scale the width fields.                                               */
    /**************************************************************************/
    pTargetBuffer->lAveCharWidth       = prdg_ScaleValue(pTargetBuffer->
                                                         lAveCharWidth,
                                                         CharBoxWidth,
                                                         WidthDivisor);
    pTargetBuffer->lMaxCharInc         = prdg_ScaleValue(pTargetBuffer->
                                                         lMaxCharInc,
                                                         CharBoxWidth,
                                                         WidthDivisor);
    pTargetBuffer->lSubscriptXOffset   = prdg_ScaleValue(pTargetBuffer->
                                                         lSubscriptXOffset,
                                                         CharBoxWidth,
                                                         HeightDivisor);
    pTargetBuffer->lSubscriptXSize     = prdg_ScaleValue(pTargetBuffer->
                                                         lSubscriptXSize,
                                                         CharBoxWidth,
                                                         HeightDivisor);
    pTargetBuffer->lSuperscriptXOffset = prdg_ScaleValue(pTargetBuffer->
                                                         lSuperscriptXOffset,
                                                         CharBoxWidth,
                                                         HeightDivisor);
    pTargetBuffer->lSuperscriptXSize   = prdg_ScaleValue(pTargetBuffer->
                                                         lSuperscriptXSize,
                                                         CharBoxWidth,
                                                         HeightDivisor);

    /**************************************************************************/
    /*  Scale the height fields.                                              */
    /**************************************************************************/
    pTargetBuffer->lXHeight            = prdg_ScaleValue(pTargetBuffer->
                                                         lXHeight,
                                                         CharBoxHeight,
                                                         HeightDivisor);
    pTargetBuffer->lMaxAscender        = prdg_ScaleValue(pTargetBuffer->
                                                         lMaxAscender,
                                                         CharBoxHeight,
                                                         HeightDivisor);
    pTargetBuffer->lMaxDescender       = prdg_ScaleValue(pTargetBuffer->
                                                         lMaxDescender,
                                                         CharBoxHeight,
                                                         HeightDivisor);
    pTargetBuffer->lLowerCaseAscent    = prdg_ScaleValue(pTargetBuffer->
                                                         lLowerCaseAscent,
                                                         CharBoxHeight,
                                                         HeightDivisor);
    pTargetBuffer->lLowerCaseDescent   = prdg_ScaleValue(pTargetBuffer->
                                                         lLowerCaseDescent,
                                                         CharBoxHeight,
                                                         HeightDivisor);
    pTargetBuffer->lMaxBaselineExt     = prdg_ScaleValue(pTargetBuffer->
                                                         lMaxBaselineExt,
                                                         CharBoxHeight,
                                                         HeightDivisor);
    pTargetBuffer->lInternalLeading    = prdg_ScaleValue(pTargetBuffer->
                                                         lInternalLeading,
                                                         CharBoxHeight,
                                                         HeightDivisor);
    pTargetBuffer->lExternalLeading    = prdg_ScaleValue(pTargetBuffer->
                                                         lExternalLeading,
                                                         CharBoxHeight,
                                                         HeightDivisor);
    pTargetBuffer->lUnderscoreSize     = prdg_ScaleValue(pTargetBuffer->
                                                         lUnderscoreSize,
                                                         CharBoxHeight,
                                                         HeightDivisor);
    pTargetBuffer->lUnderscorePosition = prdg_ScaleValue(pTargetBuffer->
                                                         lUnderscorePosition,
                                                         CharBoxHeight,
                                                         HeightDivisor);
    pTargetBuffer->lStrikeoutSize      = prdg_ScaleValue(pTargetBuffer->
                                                         lStrikeoutSize,
                                                         CharBoxHeight,
                                                         HeightDivisor);
    pTargetBuffer->lStrikeoutPosition  = prdg_ScaleValue(pTargetBuffer->
                                                         lStrikeoutPosition,
                                                         CharBoxHeight,
                                                         HeightDivisor);
    pTargetBuffer->lSubscriptYOffset   = prdg_ScaleValue(pTargetBuffer->
                                                         lSubscriptYOffset,
                                                         CharBoxHeight,
                                                         HeightDivisor);
    pTargetBuffer->lSubscriptYSize     = prdg_ScaleValue(pTargetBuffer->
                                                         lSubscriptYSize,
                                                         CharBoxHeight,
                                                         HeightDivisor);

    pTargetBuffer->lSuperscriptYOffset = prdg_ScaleValue(pTargetBuffer->
                                                         lSuperscriptYOffset,
                                                         CharBoxHeight,
                                                         HeightDivisor);

    pTargetBuffer->lSuperscriptYSize   = prdg_ScaleValue(pTargetBuffer->
                                                         lSuperscriptYSize,
                                                         CharBoxHeight,
                                                         HeightDivisor);
    return;
}
#undef TFUNC
