/*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 = PRDARSUB
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   prda_RealizeDeviceFont
 *             prda_MatchBaseFont
 *             prda_DefaultFontSwitch
 *             prda_MatchFattrStructure
 *             prda_MatchEngineAttributes
 *             prda_InfoFromMatchNumber
 *             prda_ChangeMatchNumber
 *             prda_MatchMetrics
 *
 * 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
#include <os2.h>
#undef INCL_DOSPROCESS            /* CON3201 */
#undef INCL_DOSSEMAPHORES
#undef INCL_GPIPRIMITIVES
#undef INCL_WINHEAP
#undef INCL_GPIBITMAPS
#undef INCL_GPIERRORS

#define INCL_DDIBUNDLES
#define INCL_DDIFONTSTRUCS
#define INCL_DDIDEFS
#define INCL_DDIMISC
#define INCL_DDIMISC2
#define INCL_GRE_XFORMS
#define INCL_GRE_FONTS
#include <pmddi.h>
#undef INCL_DDIBUNDLES
#undef INCL_DDIFONTSTRUCS
#undef INCL_DDIDEFS
#undef INCL_DDIMISC
#undef INCL_DDIMISC2
#undef INCL_GRE_XFORMS
#undef INCL_GRE_FONTS

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

#define INCL_DOSINFOSEG
#define INCL_NOCOMMON
#include <bsedos.h>
#undef INCL_DOSINFOSEG
#define INCL_NOCOMMON
#include <prdgpart.h>      /* CON3201 - bring in enum constants */
#include <prdconty.h>
#include <prdconse.h>
#include <prdacone.h>
#include <prddcone.h>
#include <prdtcone.h>
#include <prdttypt.h>
#include <prddtypt.h>
#include <prdtypet.h>
#include <prdetypt.h>
#include <prdptypt.h>
#include <prdmtypt.h>
#include <prdjtypt.h>
#include <prdctypt.h>
#include <prdatypt.h>
#include <prddct.h>
#include <prdbtypt.h>
#include <prdaextf.h>
#include <prdeextf.h>
#include <prdgextf.h>
#include <prdtextf.h>
#include <prduextf.h>
#include <prdmextf.h>
#include <prdmacro.h>
#include <prderre.h>

extern lplpFontCPListType  DVTFontCPList[];
extern DVTCPListType       DVTCodePageList[];

/******************************************************************************/
/*  Set up access to engine convert function                                  */
/******************************************************************************/
extern PFNL                da_ConvertWithMatrix;

/******************************************************************************/
/*  FUNCTION: prda_RealizeDeviceFont                                          */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  PFATTRS  LogFont                                                          */
/*  lpDCI    DCIData                                                          */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function is used to realize a device font.  We'll either return      */
/*  NO_FONT_MATCH or the LCID of the font matched.                            */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
ULONG prda_RealizeDeviceFont( PFATTRS  LogFont,
                              lpDCI    DCIData )

{
#define TFUNC "prda_RealizeDeviceFont"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    ULONG  lcid;                       /* Return value LCID expanded match no.*/
    BOOL   DefaultFontRealized;        /* PD00681...                          */

    DefaultFontRealized = FALSE;
    if (LogFont->lMatch < 0)
    {

        /**********************************************************************/
        /*  Direct match processing...                                        */
        /**********************************************************************/
        lcid = prda_MatchBaseFont(LogFont, DCIData);
    }
    else
    {
        if (LogFont->idRegistry      == 0 && LogFont->lMaxBaselineExt == 0 &&
            LogFont->lAveCharWidth   == 0 && LogFont->fsType          == 0 &&
            LogFont->szFacename[0]   == 0 && LogFont->fsFontUse       == 0)
        {

            /******************************************************************/
            /*  Default font matching...                                      */
            /******************************************************************/
            lcid = prda_MatchBaseFont(LogFont, DCIData);

            /******************************************************************/
            /*  PD00681 : We need to set a flag on to indicate we've realized */
            /*  the default font...                                           */
            /******************************************************************/
            if (lcid != NO_FONT_MATCH)
            {
                DefaultFontRealized = TRUE;
            }
        }
        else
        {
            /******************************************************************/
            /*  FATTR matching...                                             */
            /******************************************************************/
            lcid = prda_MatchFattrStructure(LogFont, DCIData);
        }
    }
    if (lcid != NO_FONT_MATCH)
    {

        /**********************************************************************/
        /*  Now we have a fully specified match number including the base     */
        /*  match number codepage.  But first get the full LCID as if it were */
        /*  not going to be changed.                                          */
        /*                                                                    */
        /*  PD00681 : Or in the flag to indicate the default font has been    */
        /*  realized if this is the case.                                     */
        /**********************************************************************/
        if (DefaultFontRealized)
        {
            prdm_PutLCIDEngineAttrs(lcid, LogFont->fsSelection |
                                    FATTR_SEL_DEFAULT);
        }
        else
        {
            prdm_PutLCIDEngineAttrs(lcid, LogFont->fsSelection);
        }
    }
    return(lcid);
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prda_MatchBaseFont                                              */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  PFATTRS  LogFont                                                          */
/*  lpDCI    DCIData                                                          */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function is called for two reasons:                                  */
/*                                                                            */
/*  1.  With a negative match number in the FATTRS.  In this case, this       */
/*  specifies a font directly.  We can't say no match to this call.           */
/*                                                                            */
/*  2.  With a zero match number in the FATTRS.  In this case, this is        */
/*  matching on the default font.  We'll say no match to this case if a       */
/*  codepage that cannot be simulated is requested.                           */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
ULONG prda_MatchBaseFont( PFATTRS     LogFont,
                          lpDCI       DCIData )

{
#define TFUNC "prda_MatchBaseFont"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    lpPDBI              PDBInstance;   /* Pointer to the PDB                  */
    lpPrtDataEntry      PrinterData;   /* Pointer to Printer Data             */
    lpDfltFontInfoType  pDfltFont;     /* Pointer to default font info        */
    lpFMFFileStruc      pMetrics;      /* Pointer to font metrics             */
    lpMultiCpType       pMultiCP;      /* Ptr to multi codepage info          */
    BYTE                DeviceAttrs;   /* Device attributes                   */
    lpEngAttrsType      pEngineAttrs;  /* Pointer to eng attrs struct         */
    SHORT               RetVal;        /* CON3203                             */
/*  USHORT              RetVal;           Function call return values         */
    BOOL                DefaultFont;   /* Flag to indicate dflt font          */
    ULONG               lcid;          /* LCID structure                      */
    USHORT              CPVal;         /* Temporary codepage number           */
    USHORT              cpLocal;       /* CODE1 : Make local var              */

    /**************************************************************************/
    /*  Initialize a few variables...                                         */
    /**************************************************************************/
    DefaultFont = FALSE;
    lcid        = 0L;
    prdm_PutLCIDCPIndex(lcid, INVALID_CODEPAGE_INDEX);
    prdm_PutLCIDEngineAttrs(lcid, 0);

    /**************************************************************************/
    /*  Store the supplied match number in the new LCID.                      */
    /**************************************************************************/
    ULTOLCID(lcid).BaseMatchNo = (USHORT)LogFont->lMatch;

    /**************************************************************************/
    /*  Set up a few pointers...                                              */
    /**************************************************************************/
    PDBInstance = DCIData->DCIPdbInstance;
    PrinterData = PDBInstance->PrinterData;
    if (LogFont->lMatch == 0)
    {

        /**********************************************************************/
        /*  We're matching the default font.  May possibly fail....           */
        /**********************************************************************/
        DefaultFont = TRUE;
        pDfltFont   = &PDBInstance->DfltFont;
        if (pDfltFont->Info.Type == FT_ENGINE)
        {

            /******************************************************************/
            /*  if the default font happens to be an engine font              */
            /******************************************************************/
            return(NO_FONT_MATCH);
        }
        else
        {

            /******************************************************************/
            /*  But if it is a device font then just use the LCID             */
            /******************************************************************/
            lcid = LCIDTOUL(pDfltFont->Info.LCID);
        }
    }

    /**************************************************************************/
    /*  Now we have a match number specifying font type and index.  Next job  */
    /*  is to add codepage information.                                       */
    /**************************************************************************/
    RetVal = prda_InfoFromMatchNumber(ULTOLCID(lcid), DCIData, &pMetrics,
                                      &pMultiCP, &DeviceAttrs, &pEngineAttrs);
    if (RetVal == ERROR_NEG)
    {

        /**********************************************************************/
        /*  This occurs if the match number was invalid.                      */
        /**********************************************************************/
        return(NO_FONT_MATCH);
    }
    else
    {

        /******************************************************************/
        /*  We have found a font in a particular codepage.  We now need to*/
        /*  decide whether this is overridden by the FATTR codepage.      */
        /******************************************************************/
        if (LogFont->usCodePage == 0)
        {

            /**************************************************************/
            /*  Clearly if there is no FATTR codepage then there is no    */
            /*  conflict, so just return the LCID.                        */
            /**************************************************************/
            return(lcid);
        }
        else
        {

            /**************************************************************/
            /*  This is the problem.  At least it is if both codepages    */
            /*  specified are different.                                  */
            /**************************************************************/
            if (LogFont->usCodePage == pMetrics->Metrics.usCodePage)
            {
                return(lcid);
            }
            else
            {

                /**********************************************************/
                /*  Now we need to be careful...                          */
                /**********************************************************/
                if (DefaultFont)
                {

                    /******************************************************/
                    /*  Let's go for an exact match - look into           */
                    /*  prda_DefaultFontSwitch()...                       */
                    /******************************************************/
                    return(prda_DefaultFontSwitch(ULTOLCID(lcid), LogFont,
                                                  DCIData));
                }
                else
                {

                    /******************************************************/
                    /*  We've been supplied with a negative match number. */
                    /*  We need to say OK, so we'll use the codepage in   */
                    /*  the font metrics (already in the LCID).           */
                    /******************************************************/
                    return(lcid);
                }
            }
        }
    }
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prda_DefaultFontSwitch                                          */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  LCIDType  lcid                                                            */
/*  PFATTRS   LogFont                                                         */
/*  lpDCI     DCIData                                                         */
/*                                                                            */
/* DESCRIPTION:                                                               */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
ULONG prda_DefaultFontSwitch( LCIDType  lcid,
                              PFATTRS   LogFont,
                              lpDCI     DCIData )

{
#define TFUNC "prda_DefaultFontSwitch"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    lpFMFFileStruc  pMetrics;          /* Pointer to font metrics             */
    lpMultiCpType   pMultiCP;          /* Ptr to multi codepage info          */
    BYTE            DeviceAttrs;       /* Device attributes                   */
    lpEngAttrsType  pEngineAttrs;      /* Pointer to eng attrs struct         */
    FATTRS          LocalFATTRS;       /* Local FATTRS                        */
    SHORT           RetVal;            /* CON3203                             */
/*  USHORT          RetVal;               Function call return values         */
    USHORT          i;
    XFORM           xfm;               /* PD00394 : transform to world coords */
    POINTL          LongCoords;        /* PD00394 : coords for conversion     */

    RetVal = prda_InfoFromMatchNumber(lcid, DCIData, &pMetrics, &pMultiCP,
                                      &DeviceAttrs, &pEngineAttrs);
    if (RetVal == ERROR_NEG) /* CON3203 */
    {
        return(NO_FONT_MATCH);
    }
    else
    {

        /**********************************************************************/
        /*  Need to set up a local FATTRS structure so that we can attempt to */
        /*  match on it.  The info here is based on the info obtained from the*/
        /*  match number that was passed in the parameter list.               */
        /**********************************************************************/
        LocalFATTRS.usRecordLength  = (USHORT)sizeof(FATTRS);
        LocalFATTRS.fsSelection     = lcid.EngineAttrs;
        LocalFATTRS.lMatch          = 0;
        for (i = 0;i <= 31;i++)
        {
            LocalFATTRS.szFacename[i] = pMetrics->Metrics.szFacename[i];
        }
        LocalFATTRS.idRegistry      = pMetrics->Metrics.usRegistryId;
        LocalFATTRS.usCodePage      = LogFont->usCodePage;
        LocalFATTRS.lMaxBaselineExt = pMetrics->Metrics.yMaxBaselineExt;
        LocalFATTRS.lAveCharWidth   = pMetrics->Metrics.xAveCharWidth;
        LocalFATTRS.fsType          = 0;

        /**********************************************************************/
        /*  PD00394 : If this is not an outline font, we need to transform the*/
        /*  values for both MaxBaseLineExt and AveCharWidth so that later on  */
        /*  we stand a chance of matching in prda_MatchMetrics().  Note that  */
        /*  there is no need to consider Double High, Double Wide, or Double  */
        /*  High/Double Wide in these transformations as the default font can */
        /*  not be realized with any of these attributes.                     */
        /**********************************************************************/
        if (!pMetrics->Metrics.fsDefn & FM_DEFN_OUTLINE)
        {

            /******************************************************************/
            /*  Get font to world conversion matrix.                          */
            /******************************************************************/
            prdg_GetXformMatrix((HDC)DCIData->DcH, FONT_TO_WORLD, (PXFORM)&xfm,
                                DCIData);

            /******************************************************************/
            /*  Transform MaxBaselineExt.                                     */
            /******************************************************************/
            if (LocalFATTRS.lMaxBaselineExt != 0)
            {
                LongCoords.x = 0L;
                LongCoords.y = (LONG)LocalFATTRS.lMaxBaselineExt;
                if (!da_ConvertWithMatrix(DCIData->DcH, (PPOINTL)&LongCoords,
                                          1L, (PXFORM)&xfm, 0L,
                                          NGreConvertWithMatrix))
                    return(GPI_ALTERROR);
                LocalFATTRS.lMaxBaselineExt = (USHORT)LongCoords.y;
            }

            /******************************************************************/
            /*  Transform AveCharWidth.                                       */
            /******************************************************************/
            if (LocalFATTRS.lAveCharWidth != 0)
            {
                LongCoords.x = (LONG)LocalFATTRS.lAveCharWidth;
                LongCoords.y = 0L;
                if (!da_ConvertWithMatrix(DCIData->DcH, (PPOINTL)&LongCoords,
                                          1L, (PXFORM)&xfm, 0L,
                                          NGreConvertWithMatrix))
                    return(GPI_ALTERROR);
                LocalFATTRS.lAveCharWidth = (USHORT)LongCoords.x;
            }
        }

        /**********************************************************************/
        /*  It seems to make sense that we'd try to match to an outline font  */
        /*  if the default font is an outline font, so here goes...           */
        /**********************************************************************/
        if (pMetrics->Metrics.fsDefn & FM_DEFN_OUTLINE)
        {
            LocalFATTRS.fsFontUse = FATTR_FONTUSE_OUTLINE;
        }
        else
        {
            LocalFATTRS.fsFontUse = 0;
        }

        /**********************************************************************/
        /*  Now that everything is set up, we try to match on the new FATTRS  */
        /*  that we just filled in.                                           */
        /**********************************************************************/
        return(prda_MatchFattrStructure((PFATTRS)&LocalFATTRS, DCIData));
    }
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prda_MatchFattrStructure                                        */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  PFATTRS  LogFont                                                          */
/*  lpDCI    DCIData                                                          */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
ULONG prda_MatchFattrStructure( PFATTRS  LogFont,
                                lpDCI    DCIData )

{
#define TFUNC "prda_MatchFattrStructure"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    ULONG  RetVal;                     /* Function call return values         */

    if (LogFont->usCodePage == 0)
    {

        /**********************************************************************/
        /*  There is no codepage specified in the match.  We'll try to match  */
        /*  on the system codepage.  If this fails then we need to find a root*/
        /*  codepage.                                                         */
        /**********************************************************************/
        LogFont->usCodePage = DCIData->DCICodePage;
        RetVal = (ULONG)prda_MatchFont( LogFont, DCIData);
        if (RetVal != NO_FONT_MATCH)
            return(RetVal);
        else
        {

            /******************************************************************/
            /*  Well, we couldn't match on the system codepage, so let's try  */
            /*  to match on an ASCII codepage (850) or an EBCDIC codepage     */
            /*  (500).                                                        */
            /******************************************************************/
            LogFont->usCodePage = prda_CodePageType(DCIData->DCICodePage);
            RetVal = (ULONG)prda_MatchFont(LogFont, DCIData);
            if (RetVal == NO_FONT_MATCH)
            {

                /**************************************************************/
                /*  Hmmm, still couldn't match.  Let's return a match that    */
                /*  ignores the codepage i.e.  match on everything else.      */
                /**************************************************************/
                LogFont->usCodePage = 0;
                RetVal = prda_MatchFont(LogFont, DCIData);
            }
            return(RetVal);
        }
    }
    else
    {

        /**********************************************************************/
        /*  The codepage in the fattr is non-zero                             */
        /**********************************************************************/
        RetVal = prda_MatchFont(LogFont, DCIData);
        if (RetVal != NO_FONT_MATCH)
        {
            return(RetVal);
        }
        else
        {
            return(NO_FONT_MATCH);
        }
    }
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prda_MatchEngineAttributes                                      */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  lpDCI     DCIData                                                         */
/*  LCIDType  lcid                                                            */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
ULONG prda_MatchEngineAttributes( lpDCI     DCIData,
                                  LCIDType  lcid )

{
#define TFUNC "prda_MatchEngineAttributes"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    lpFMFFileStruc      pMetrics;      /* Pointer to font metrics             */
    lpMultiCpType       pMultiCP;      /* Ptr to multi codepage info          */
    BYTE                DeviceAttrs;   /* Device attributes                   */
    lpEngAttrsType      pEngineAttrs;  /* Pointer to eng attrs struct         */
    ULONG               RetVal;        /* Function call return values         */
    USHORT              AttrMask;      /* Attribute mask for attrmatch        */
    USHORT              AttrFGID;      /* Attribute match FGID                */

    /**************************************************************************/
    /*  Initialize some variables...                                          */
    /**************************************************************************/
    AttrFGID = FNULL;

    /**************************************************************************/
    /*  At this point the match number is fully set up including base match   */
    /*  number, codepage and the engine attributes requested in the FATTRS.   */
    /*  Let's see if an engine attributes structure exists for this font.     */
    /**************************************************************************/
    (VOID)prda_InfoFromMatchNumber(lcid, DCIData, &pMetrics, &pMultiCP,
                                   &DeviceAttrs, &pEngineAttrs);
    if (pEngineAttrs == FNULL)
    {

        /**********************************************************************/
        /*  If the engine attribute structure does not exist, just return the */
        /*  original match number unchanged.                                  */
        /**********************************************************************/
        return((ULONG)(*(PULONG)&lcid));
    }
    else
    {

        /**********************************************************************/
        /*  OK...  engine attributes structure does exist, therefore we might */
        /*  be able to substitute a real FGID for some of engine attributes - */
        /*  let see...                                                        */
        /**********************************************************************/
        if ((lcid.EngineAttrs & FATTR_SEL_ITALIC) &&
            (lcid.EngineAttrs & FATTR_SEL_BOLD))
        {

            /******************************************************************/
            /*  Italics/Bold may be supported either by a unique FGID of an   */
            /*  italicized and bolded font OR a combination of an italicized  */
            /*  font we'll bold on the fly or a bolded font we can't          */
            /*  italicize.  If it's there, use it; if not, fake it as best as */
            /*  we can...                                                     */
            /******************************************************************/
            if (pEngineAttrs->usFGIDItalicBold != FNULL)
            {

                /**************************************************************/
                /*  We're lucky...  the combination is supported in one font. */
                /**************************************************************/
                AttrFGID = pEngineAttrs->usFGIDItalicBold;
                AttrMask = FATTR_SEL_ITALIC | FATTR_SEL_BOLD;
            }
            else
            {
                if (pEngineAttrs->usFGIDItalic != FNULL)
                {

                    /**********************************************************/
                    /*  We're still OK...  we can bold the font on the fly.   */
                    /**********************************************************/
                    AttrFGID = pEngineAttrs->usFGIDItalic;
                    AttrMask = FATTR_SEL_ITALIC;
                }
                else
                {

                    /**********************************************************/
                    /*  Now we're in trouble - the font only exists as a      */
                    /*  bolded font.  Since we can't italicize on the fly,    */
                    /*  we'll have to lie later on and just ignore the italics*/
                    /*  flag.  Note that since EngineAttrs is not null we do  */
                    /*  not need to check to see if usFGIDBold is null - we   */
                    /*  are guaranteed to find an FGID here.                  */
                    /**********************************************************/
                    AttrFGID = pEngineAttrs->usFGIDBold;
                    AttrMask = FATTR_SEL_BOLD;
                }
            }
        }
        else
        {

            /******************************************************************/
            /*  Italics...                                                    */
            /******************************************************************/
            if ((lcid.EngineAttrs & FATTR_SEL_ITALIC) &&
                (pEngineAttrs->usFGIDItalic != FNULL))
            {
                AttrFGID = pEngineAttrs->usFGIDItalic;
                AttrMask = FATTR_SEL_ITALIC;
            }
            else
            {

                /**************************************************************/
                /*  Bold...                                                   */
                /**************************************************************/
                if ((lcid.EngineAttrs & FATTR_SEL_BOLD) &&
                    (pEngineAttrs->usFGIDBold != FNULL))
                {
                    AttrFGID = pEngineAttrs->usFGIDBold;
                    AttrMask = FATTR_SEL_BOLD;
                }
            }
        }
        if (AttrFGID != FNULL)
        {

            /******************************************************************/
            /*  If we now have a new FGID, we need to change the match number */
            /*  to reflect this - we'll do this in prda_ChangeMatchNumber().  */
            /*  Note that at this point we should be guaranteed a match as the*/
            /*  FGID we now have is from either our static font tables or     */
            /*  dynamic information that should be automagically set up.  But */
            /*  in the event we can't obtain a new match number, we'll return */
            /*  NO_FONT_MATCH so we can straighten this out pronto.           */
            /******************************************************************/
            RetVal = (ULONG)prda_ChangeMatchNumber(AttrFGID, lcid, pMetrics,
                                                   DCIData);
            if (RetVal == NO_FONT_MATCH)
            {
                return(RetVal);
            }
            else
            {

                /**************************************************************/
                /*  Now, switch off any attributes in the match number that we*/
                /*  just substituted with the new FGID.                       */
                /**************************************************************/
                (ULTOLCID(RetVal)).EngineAttrs &= ~AttrMask;
            }
            return(RetVal);
        }
        else
        {

            /******************************************************************/
            /*  Hmmm...  we should never get here, but let's do this for      */
            /*  completeness.  If we get here, this says there WAS an engine  */
            /*  attribute structure but we couldn't switch FGIDs for any of   */
            /*  the attributes.  The only thing we can do is return the       */
            /*  original match number and scratch our heads...                */
            /******************************************************************/
            return((ULONG)(*(PULONG)(&lcid)));
        }
    }
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prda_InfoFromMatchNumber                                        */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  LCIDType           lcid                                                   */
/*  lpDCI              DCIData                                                */
/*  lpFMFFileStruc     pMetrics                                               */
/*  lpMultiCpType      pMultiCP                                               */
/*  PBYTE              pbDeviceAttrs                                          */
/*  lpEngineAttrsType  pEngineAttrs                                           */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
USHORT prda_InfoFromMatchNumber( LCIDType          lcid2,
                                 lpDCI             DCIData,
                                 lpFMFFileStruc   *ppMetrics,
                                 lpMultiCpType    *ppMultiCP,
                                 PBYTE             pDeviceAttrs,
                                 lpEngAttrsType   *ppEngineAttrs )

{
#define TFUNC "prda_InfoFromMatchNumber"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    lpCardFontListType  pCardData;
    lpFontListType      pFontList;
    lplpFontCPListType  FontCPList;
    lpFontCPListType    CPList;
    lpFontCPListType    pCPData;
    lpPDBI              PDBInstance;   /* Pointer to the PDB                  */
    lpPrtDataEntry      PrinterData;   /* Pointer to Printer Data             */
    USHORT              usCPIndex;     /* Local codepage index                */
    USHORT              usFontIndex;   /* Local codepage font index           */
    FontInfoType        FontInfo;
    ULONG               lcid;

    /**************************************************************************/
    /*  Set up a few pointers...                                              */
    /**************************************************************************/
    PDBInstance = DCIData->DCIPdbInstance;
    PrinterData = PDBInstance->PrinterData;
    lcid = (ULONG)(*(PULONG)&lcid2);

    /**************************************************************************/
    /*  Need to determine what type of font we're dealing with - mask off the */
    /*  font type bits (top two bits in MSB of FontIndex word).               */
    /**************************************************************************/
    switch (prdm_GetLCIDFontType(lcid))
    {
        case FT_RESIDENT  :

            /******************************************************************/
            /*  Index is into the resident font list.                         */
            /******************************************************************/
            if (prdm_GetLCIDFontIndex(lcid) < PDBInstance->
                                              DDT.DDTNoOfResidentFonts)
            {
                pFontList = PDBInstance->FontList[prdm_GetLCIDFontIndex(lcid)];

                /**************************************************************/
                /*  PD00265 : Some printers' PS italic fonts have different   */
                /*  metrics, so grab italic metrics if FATT_SEL_ITALIC is set */
                /*  and pItalicFMF is not null                                */
                /**************************************************************/
                if ((lcid2.EngineAttrs & FATTR_SEL_ITALIC) &&
                    (pFontList->pItalicFMF != FNULL))
                {
                    *ppMetrics = pFontList->pItalicFMF;
                }
                else
                    *ppMetrics = pFontList->pFMFData;
                *ppMultiCP = pFontList->pMultiCp;
                *pDeviceAttrs = (BYTE)pFontList->Attrs;
                *ppEngineAttrs = pFontList->pEngAttrs;
            }
            else
                return(ERROR_NEG);
            break;
        case FT_CODE_PAGE :

            /******************************************************************/
            /*  We're dealing with a codepage font - that means that the Font-*/
            /*  Index number unpacks into a font index for the resident fonts */
            /*  and a codepage index into the global codepage table.          */
            /******************************************************************/
            usFontIndex = prdm_GetLCIDCPFontIndex(lcid);
            usCPIndex = prdm_GetLCIDGCPIndex(lcid);

            /******************************************************************/
            /*  OK...  now we have both indices.  Now we need to ensure that  */
            /*  the FontIndex is in the right range for resident fonts...     */
            /******************************************************************/
            if ((usFontIndex < PDBInstance->DDT.DDTFontsInCodePage) &&
                (usCPIndex <= MAX_CODEPAGE_FONT_INDEX))
            {

                /**************************************************************/
                /*  ...and that the codepage is in the right range and that   */
                /*  the codepage has been installed.  If the index is 1, we   */
                /*  know we're OK 'cause that's codepage 850.  Otherwise, we  */
                /*  need to be sure something's not gone south...             */
                /*  PD00091 : Decrement usCPIndex by 1 to allow for the fact  */
                /*  that codepage 437 does not exist in the codepage list.    */
                /**************************************************************/
                if ((usCPIndex == 1) || ( (usCPIndex >= 2) &&
                    (PrinterData->CPPathList[usCPIndex - 1] != FNULL)))
                {
                    FontCPList =DVTFontCPList[PDBInstance->PrinterType];
                    CPList = FontCPList[usFontIndex];
                    pCPData = &CPList[usCPIndex - 1];
                    *ppMetrics = pCPData->pFMFData;

                    /**********************************************************/
                    /*  For Download CodePage Fonts there are never multi-    */
                    /*  codepage fonts or engine attributes.                  */
                    /**********************************************************/
                    *ppMultiCP = FNULL;

                    /**********************************************************/
                    /*  FIX: AK 4/23/91.  (Aldus traps) Use usFontIndex, not  */
                    /*  prdm_GetLCIDFontIndex.                                */
                    /**********************************************************/
                    pFontList = PDBInstance->FontList[ usFontIndex ];
                    *pDeviceAttrs = (BYTE)pFontList->Attrs;
                    *ppEngineAttrs = FNULL;
                }
                else
                    return(ERROR_NEG);
            }
            else
                return(ERROR_NEG);
            break;
    }
    return( OK );
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prda_ChangeMatchNumber                                          */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  USHORT    FGID                                                            */
/*  LCIDType  lcid                                                            */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
ULONG prda_ChangeMatchNumber( USHORT          TargetFGID,
                              LCIDType        lcid,
                              lpFMFFileStruc  pMetrics,
                              lpDCI           DCIData )

{
#define TFUNC "prda_ChangeMatchNumber"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    lpDDTType       pDDT;
    lpPDBI          PDBInstance;       /* Pointer to the PDB                  */
    lpPrtDataEntry  PrinterData;       /* Pointer to Printer Data             */
    LCIDType        New_lcid;          /* Temporary LCID for return           */
    USHORT          Index;             /* Loop index                          */
    BOOL            Found;             /* Flag for  matching FGIDs            */
    USHORT          TrgCP;
    lpFMFFileStruc  pFMFData;

    /**************************************************************************/
    /*  Initialize a few variables...                                         */
    /**************************************************************************/
    Found       = FALSE;
    PDBInstance = DCIData->DCIPdbInstance;
    pDDT        = &PDBInstance->DDT;
    PrinterData = PDBInstance->PrinterData;
    TrgCP       = pMetrics->Metrics.usCodePage;

    /**************************************************************************/
    /*  Two ways to do this.  The first is that we have an FGID that uniquely */
    /*  appears in the font list, this needs searching for somewhere.  The    */
    /*  other way says that we actually have the resident font index in the   */
    /*  engine attribute structure thus finding the entry is absurdly easy.   */
    /*  This is the method used by the 3816 which has repeated FGIDs for bold */
    /*  fonts and fonts in a different codepage.                              */
    /**************************************************************************/
    if (pDDT->DDTFontFlags & DDT_ENGINE_ATTR_INDEX)
    {

        /**********************************************************************/
        /*  This is easy.  Just reconstruct a new LCID.                       */
        /**********************************************************************/
        prdm_PutLCIDFontIndex(New_lcid, TargetFGID);
        prdm_PutLCIDFontType(New_lcid, FT_RESIDENT);
    }
    else
    {

        /**********************************************************************/
        /*  Search through the resident fonts for a matching FGID.  Codepage  */
        /*  of the font must match the target.                                */
        /**********************************************************************/
        for (Index = 0; Index < PDBInstance->DDT.DDTNoOfResidentFonts; Index++)
        {

            /******************************************************************/
            /*  Local pointer simply for readability                          */
            /******************************************************************/
            pFMFData = PDBInstance->FontList[Index]->pFMFData;

            /******************************************************************/
            /* PD00605 : Added check to make sure family name matches also.   */
            /* This is to insure that we get the correct FGID for the new     */
            /* Swiss Helv and Roman Tms Rmn fonts that are duplicates of the  */
            /* Helvetica and Times New Roman except for family and face names.*/
            /******************************************************************/
            if ((TargetFGID == (USHORT)pFMFData->Metrics.usRegistryId) &&
                (TrgCP == pFMFData->Metrics.usCodePage) &&
                (prdu_strcmp(pMetrics->Metrics.szFamilyname,
                        pFMFData->Metrics.szFamilyname) == 0) )
            {

                /**************************************************************/
                /*  We've found the matching FGID, so let's store the index   */
                /*  and type in a new LCID to be returned in a minute, then   */
                /*  break out of the loop...                                  */
                /**************************************************************/
                prdm_PutLCIDFontIndex(New_lcid, Index);
                prdm_PutLCIDFontType(New_lcid, FT_RESIDENT);
                Found = TRUE;
                break;
            }
        }

        /**********************************************************************/
        /*  Search through the card fonts for a matching FGID.                */
        /**********************************************************************/
        if (!Found)
        {
            for (Index = 0; Index < PrinterData->CardFontCount; Index++)
            {

                /**************************************************************/
                /*  Local pointer for readability                             */
                /**************************************************************/
                pFMFData = PrinterData->CardData[Index].pFMFData;
                if (TargetFGID == (USHORT)pFMFData->Metrics.usRegistryId)
                {

                    /**********************************************************/
                    /*  We've found the matching FGID, so let's store the     */
                    /*  index and type in a new LCID to be returned in a      */
                    /*  minute, then break out of the loop...                 */
                    /**********************************************************/
                    prdm_PutLCIDFontIndex(New_lcid, Index);
                    prdm_PutLCIDFontType(New_lcid, FT_CARD);
                    Found = TRUE;
                    break;
                }
            }
        }
        if (!Found)
        {

            /******************************************************************/
            /*  We should never get here - there should always be a match     */
            /*  either in the resident font list or the card list.  If no     */
            /*  match is found then we have a problem with our static font    */
            /*  tables or the card info is     or something...  gotta return  */
            /*  NO_FONT_MATCH.                                                */
            /******************************************************************/
            return(NO_FONT_MATCH);
        }
    }

    /**************************************************************************/
    /*  OK, we've found the matching FGID.  All there's left to do is to fill */
    /*  in some info in the LCID we're returning...  most is from the old LCID*/
    /*  we were passed.  We picked up the new font index and font type in the */
    /*  loops...  Thank goodness for macros...                                */
    /**************************************************************************/
    prdm_PutLCIDFontDevAttrs( New_lcid,prdm_GetLCIDFontDevAttrs(lcid));
    prdm_PutLCIDCPIndex(New_lcid,prdm_GetLCIDCPIndex(lcid));
    prdm_PutLCIDEngineAttrs(New_lcid,prdm_GetLCIDEngineAttrs(lcid));

    /**************************************************************************/
    /*  All done.                                                             */
    /**************************************************************************/
    return(LCIDTOUL(New_lcid));
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prda_MatchMetrics                                               */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  BYTE            DeviceAttrs                                               */
/*  PFATTRS         LogFont                                                   */
/*  LCIDType        TargetLCID                                                */
/*  lpFMFFileStruc  TargetMetrics                                             */
/*  lpMultiCpType   pMultiCP                                                  */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
ULONG prda_MatchMetrics( BYTE            DeviceAttrs,
                         PFATTRS         LogFont,
                         LCIDType        TargetLCID,
                         lpFMFFileStruc  TargetMetrics,
                         lpMultiCpType   pMultiCP,
                         lpDCI           DCIData )

{
#define TFUNC "prda_MatchMetrics"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    LCIDType         lcid;
    lpPDBI           PDBInstance;      /* Pointer to the PDB                  */
    lpPrtDataEntry   PrinterData;      /* Pointer to Printer Data             */
    PFOCAMETRICS     pMetrics;
    POINTL           LongCoords;       /* for font-world conversion           */
    CHAR             FaceChar;
    BYTE             AdjFaceName[32];
    XFORM            xfm;
    USHORT           Attr;             /* Loop counter                        */
    USHORT           MaxBaselineExt;
    USHORT           AveCharWidth;
    USHORT           i;
    USHORT           CPIndex;
    USHORT           FaceNameLen;

    /**************************************************************************/
    /*  Set up pointers.                                                      */
    /*                                                                        */
    /*  PD00788 : Initialize the LCID...                                      */
    /**************************************************************************/
    PDBInstance    = DCIData->DCIPdbInstance;
    PrinterData    = PDBInstance->PrinterData;
    LCIDTOUL(lcid) = 0L;

    /**************************************************************************/
    /*  We need to check some basics between the FATTR we've been given and   */
    /*  the target metrics to see if there's anything that would indicate we  */
    /*  don't match right away.  In succession we'll check the FGID, codepage,*/
    /*  font type (i.e.  outline v/s image) and kerning.  If we hit a mismatch*/
    /*  in any of these elements, we 're going to just return NO_FONT_MATCH.  */
    /*  First, look at the FGID.                                              */
    /**************************************************************************/
    if ((LogFont->idRegistry != 0) &&
        (LogFont->idRegistry != (USHORT)TargetMetrics->Metrics.usRegistryId))
        return(NO_FONT_MATCH);

    /**************************************************************************/
    /*  Next, check the codepage.  We need to be careful here - a 0 codepage  */
    /*  in the target metrics indicates that this is a request to match a     */
    /*  multi-codepage font, so we'll have to handle it.                      */
    /**************************************************************************/
    if (TargetMetrics->Metrics.usCodePage == 0)
    {

        /**********************************************************************/
        /*  This is a multi-codepage font.  Check to see if requested codepage*/
        /*  is available.                                                     */
        /**********************************************************************/
        if (!prda_MultiCodePageSupported(LogFont->usCodePage, pMultiCP))
        {
            return(NO_FONT_MATCH);
        }

        /**********************************************************************/
        /*  Copy the codepage into the lcid - this will either be the         */
        /*  DCICodePage, if the Fattrs Cp is zero; or the fattrs codepage.    */
        /**********************************************************************/
        if (LogFont->usCodePage == 0)
        {
            CPIndex = prda_GetCPIndexFromCodePage(DCIData->DCICodePage);
        }
        else
        {
            CPIndex = prda_GetCPIndexFromCodePage(LogFont->usCodePage);
        }
        prdm_PutLCIDCPIndex(lcid, CPIndex);
    }
    else
    {

        /**********************************************************************/
        /*  This is a normal codepage, similar tests as above...  Copy it into*/
        /*  the lcid.                                                         */
        /**********************************************************************/
        if ((LogFont->usCodePage != 0) &&
            (LogFont->usCodePage != TargetMetrics->Metrics.usCodePage))
        {
            return(NO_FONT_MATCH);
        }
        prdm_PutLCIDCPIndex(lcid, 0xff);
    }

    /**************************************************************************/
    /*  Now check for the font type (outline or image).                       */
    /*                                                                        */
    /*  PD00788: Added check for FONTUSE_TRANSFORMABLE                        */
    /**************************************************************************/
    if (((LogFont->fsFontUse & FATTR_FONTUSE_OUTLINE      ) ||
         (LogFont->fsFontUse & FATTR_FONTUSE_TRANSFORMABLE)   ) &&
        !(TargetMetrics->Metrics.fsDefn & FM_DEFN_OUTLINE     )   )
        return(NO_FONT_MATCH);

    /**************************************************************************/
    /*  Finally, check the kerning status.                                    */
    /**************************************************************************/
    if ((LogFont->fsType & FATTR_TYPE_KERNING) &&                  /* PD00686 */
        (TargetMetrics->Metrics.usKerningPairs == 0))
        return(NO_FONT_MATCH);

    /**************************************************************************/
    /*  Now we need to initialize a couple of pointers before we go into the  */
    /*  loop...                                                               */
    /**************************************************************************/
    pMetrics = &TargetMetrics->Metrics;

    /**************************************************************************/
    /*  This section could be put into a separate function...  Naaaaaaaahhh...*/
    /**************************************************************************/
    for (Attr = 0;Attr <= ALL_DEVICE_ATTRIBUTES;Attr++)
    {

        /**********************************************************************/
        /*  Do we support this attribute?                                     */
        /**********************************************************************/
        if ((DeviceAttrs == (BYTE)Attr) || (DeviceAttrs == 3) || (Attr == 0))
        {

            /******************************************************************/
            /*  We'll construct a new LCID to hopefully return if all goes    */
            /*  according to plan.                                            */
            /******************************************************************/
            prdm_PutLCIDFontIndex(lcid, prdm_GetLCIDFontIndex(TargetLCID));
            prdm_PutLCIDFontType(lcid, prdm_GetLCIDFontType(TargetLCID));
            prdm_PutLCIDFontDevAttrs(lcid, Attr);
            if (LogFont->szFacename[0] != 0)
            {

                /**************************************************************/
                /*  Do they have the same facenames?  Set up the facename used*/
                /*  for comparison - first copy across the facename from the  */
                /*  source metrics to the local facename buffer.              */
                /**************************************************************/
                for (i = 0;i < 32;i++)
                {
                    FaceChar = pMetrics->szFacename[i];
                    AdjFaceName[i] = (FaceChar == '*') ? (BYTE)'.' : FaceChar;
                }

                /**************************************************************/
                /* PD00360 : Strip the ' B' off of the facenames.  This is the*/
                /* only difference between old and new facenames.             */
                /**************************************************************/

                FaceNameLen = prdu_strlen(LogFont->szFacename);

                if (FaceNameLen > 1)
                {
                   if ( (LogFont->szFacename[FaceNameLen - 1] == 'B') &&
                        (LogFont->szFacename[FaceNameLen - 2] == ' ') )
                   {
                      LogFont->szFacename[FaceNameLen - 2] = 0;
                      LogFont->fsSelection |= FATTR_SEL_BOLD;
                   }
                }

                prda_AdjustFaceName(AdjFaceName, lcid, PDBInstance);

                /**************************************************************/
                /*  Now check the facename.                                   */
                /**************************************************************/
                if (prdu_strcmp((PBYTE)LogFont->szFacename, (PBYTE)AdjFaceName))
                    continue;
            }

            /******************************************************************/
            /*  For outline fonts, ignore the size fields.                    */
            /******************************************************************/
            if (!(pMetrics->fsDefn & FM_DEFN_OUTLINE))
            {

                /**************************************************************/
                /*  Get font to world conversion matrix.                      */
                /**************************************************************/
                prdg_GetXformMatrix((HDC)DCIData->DcH, FONT_TO_WORLD,
                                    (PXFORM)&xfm, DCIData);

                /**************************************************************/
                /*  Check MaxBaselineExt.                                     */
                /**************************************************************/
                if (LogFont->lMaxBaselineExt != 0)
                {
                    MaxBaselineExt = pMetrics->yMaxBaselineExt;
                    LongCoords.x = 0L;
                    LongCoords.y = (LONG)MaxBaselineExt;
                    if (!da_ConvertWithMatrix(DCIData->DcH,
                                              (PPOINTL)&LongCoords, 1L,
                                              (PXFORM)&xfm, 0L,
                                              NGreConvertWithMatrix))
                        return(GPI_ALTERROR);
                    MaxBaselineExt = (USHORT)LongCoords.y;
                    if (Attr & FATT_DOUBLE_HIGH)
                        MaxBaselineExt *= 2;
                    if (LogFont->lMaxBaselineExt != MaxBaselineExt)
                        continue;
                }

                /**************************************************************/
                /*  Check AveCharWidth.                                       */
                /**************************************************************/
                if (LogFont->lAveCharWidth != 0)
                {
                    AveCharWidth = pMetrics->xAveCharWidth;

                    /**********************************************************/
                    /*  Need to convert this to world coords.                 */
                    /**********************************************************/
                    LongCoords.x = (LONG)AveCharWidth;
                    LongCoords.y = 0L;
                    if (!da_ConvertWithMatrix(DCIData->DcH,
                                              (PPOINTL)&LongCoords, 1L,
                                              (PXFORM)&xfm, 0L,
                                              NGreConvertWithMatrix))
                        return(GPI_ALTERROR);
                    AveCharWidth = (USHORT)LongCoords.x;
                    if (Attr & FATT_DOUBLE_WIDE)
                        AveCharWidth *= 2;
                    if (LogFont->lAveCharWidth != AveCharWidth)
                        continue;
                }
            }

            /******************************************************************/
            /*  If we get this far the font must have matched, so just return */
            /*  the LCID.                                                     */
            /******************************************************************/
            return((ULONG)*(PULONG)&lcid);
        }
    }

    /**************************************************************************/
    /*  We've reached the end without a match...                              */
    /**************************************************************************/
    return(NO_FONT_MATCH);
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prda_GetCPIndexFromCodePage                                     */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  PFATTRS         LogFont                                                   */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
USHORT prda_GetCPIndexFromCodePage( USHORT  CodePage )

{
#define TFUNC "prda_GetCPIndexFromCodePage"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    USHORT  Index;

    if (CodePage == 0)
        Index = 0;
    else
        for (Index = 0;Index <= MAX_CODEPAGE_FONT_INDEX;Index++)
            if (DVTCodePageList[Index].Number == CodePage)
                break;
    return(Index);
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prda_GetCodePageType                                            */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  USHORT  CodePage                                                          */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function takes a code page number and returns either 850 or 500      */
/*  depending on whether the input codepage is ASCII or EBCDIC.  The theory   */
/*  being that if we cannot match on a target codepage then at least we can   */
/*  get the correct type.                                                     */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
USHORT prda_CodePageType( USHORT  CodePage )

{
    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    PUSHORT  CodeTable;
    USHORT   NewCodePage;

    /**************************************************************************/
    /*  This is a codetable mapping the target codepage into the Universal    */
    /*  Glyph List.                                                           */
    /**************************************************************************/
    CodeTable = (PUSHORT)GreQueryCodePageVector(CodePage);
    if (!CodeTable)
    {

        /**********************************************************************/
        /*  This really is a wacky codepage.  Just pretend that it is ASCII.  */
        /**********************************************************************/
        NewCodePage = 850;
    }
    else
    {

        /**********************************************************************/
        /*  Use the fact that for an ASCII codepage 'A' occurs in the same    */
        /*  place in the Universal Glyph List as in the code page itself.     */
        /**********************************************************************/
        if (CodeTable[65] == 65)
        {
            NewCodePage = 850;
        }
        else
        {
            NewCodePage = 500;
        }
    }

    /**************************************************************************/
    /*  All done ...                                                          */
    /**************************************************************************/
    return(NewCodePage);
}
