/*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 = PRDARFNT
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   prda_RealizeFont
 *             prda_MatchFont
 *
 * 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
#include <pmddi.h>
#undef INCL_DDIBUNDLES
#undef INCL_DDIFONTSTRUCS
#undef INCL_DDIDEFS
#undef INCL_DDIMISC
#undef INCL_DDIMISC2
#undef INCL_GRE_XFORMS

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

#include <prdconse.h>
#include <prddcone.h>
#include <prdacone.h>
#include <prdtcone.h>
#include <prdmcone.h>

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

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

extern lplpFontCPListType  DVTFontCPList[];
extern lpDVTCPSource       DVTCodePageCaps[];
extern USHORT              DRIVER_TYPE;

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

/******************************************************************************/
/*  FUNCTION: prda_RealizeFont                                                */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  See "OS/2 Technical Reference: I/O Subsytems and Device Drivers"          */
/*                                                                            */
/*  HDC      DcH;                                                             */
/*  ULONG    ArgCommand;                                                      */
/*  PFATTRS  LogFont;                                                         */
/*  ULONG    EngFont;                                                         */
/*  lpDCI    DCIData;                                                         */
/*  ULONG    FunN;                                                            */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function is used to realize or delete fonts.  It can realize a       */
/*  printer font or an engine font and delete a font.                         */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
ULONG EXPENTRY prda_RealizeFont( HDC         DcH,
                                 ULONG       ArgCommand,
                                 PFATTRS     LogFont,
                                 ULONG       EngFont,
                                 lpDCI       DCIData,
                                 ULONG       FunN )

{
#define TFUNC "prda_RealizeFnt"

    /**************************************************************************/
    /*  Local variables                                                       */
    /**************************************************************************/
    ULONG  RetVal;                     /* Function call return values         */
    ULONG  ulAbsMatch;
    USHORT DevAttr;
    ULONG  EngAttr;
    USHORT FtIndex;
    USHORT AttrFlag;
    USHORT FontNumber;
    ULONG  NumberOfFontsSoFar;
    BYTE   i;
    USHORT DownLoad;

#ifdef PRD_TIMING
    DEKHOOK0(A,7,20)
#endif
    prdm_EnterDriver(DCIData);

    /**************************************************************************/
    /*  Select option according to which bit is set in ArgCommand             */
    /**************************************************************************/
    switch ((USHORT)ArgCommand)
    {
        case REALIZE_FONT:
            if ((DCIData->DCIPdbInstance->FontCount == 0) ||
                (LogFont->lMatch > 0))
            {

                /**************************************************************/
                /*  No device fonts available or asking for an engine font.   */
                /*  Either way let the engine do the work.                    */
                /**************************************************************/
                RetVal = NO_FONT_MATCH;
            }
            else
            {
                /**************************************************************/
                /*  Before actually trying to realize the font, a check must  */
                /*  be done to see if the match number passed in is a match   */
                /*  number for the old (< 1.200) driver.  If it is then       */
                /*  convert it to a new valid match number.                   */
                /**************************************************************/
                if ( LogFont->lMatch & 0x00800000 )
                {
                   prda_ConvertOld42XXMatch( LogFont, DCIData );
                }
                /**************************************************************/
                /*  If the match number is negative this matches a device font*/
                /*  directly.  If the match number is 0 try to match on a     */
                /*  device font with the given characteristics.               */
                /**************************************************************/
                RetVal = prda_RealizeDeviceFont(LogFont, DCIData);
            }
            break;
        case DELETE_FONT:

            /******************************************************************/
            /*  Return an error if there are no fonts in this DC.             */
            /******************************************************************/
            if (DCIData->DCIPdbInstance->FontCount == 0)
                RetVal = GPI_ERROR;
            else
                RetVal = GPI_OK;
            break;
        case REALIZE_ENGINE_FONT:
            RetVal = NO_FONT_MATCH;
            break;
        default:
            RetVal = GPI_OK;
            break;
    }
    prdm_LeaveDriver(DCIData);
#ifdef PRD_TIMING
    DEKHOOK0(A,7,A0)
#endif
    return (RetVal);
}
#undef TFUNC

/******************************************************************************/
/*  FUNCTION: prda_MatchFont                                                  */
/*                                                                            */
/*  PARAMETERS:                                                               */
/*                                                                            */
/*  PFATTRS  LogFont;         Details of font to be matched                   */
/*  lpDCI    DCIData;         Pointer to DC Instance data                     */
/*                                                                            */
/*  DESCRIPTION:                                                              */
/*                                                                            */
/*  This function tries to find a font which matches the given attributes.    */
/*  If it finds one it returns the match number.                              */
/*                                                                            */
/*  This function should not be called if this DC does not support device     */
/*  fonts; i.e. if the PDB font count is zero (in this case the attributed    */
/*  font totals may not be set up correctly).                                 */
/******************************************************************************/
/*   CON3201  Convert to C/SET2                                               */
LONG prda_MatchFont ( PFATTRS     LogFont,
                      lpDCI       DCIData )

{
#define TFUNC "prda_MatchFont"

    /**************************************************************************/
    /*  Local Variables                                                       */
    /**************************************************************************/
    lpPDBI              PDBInstance;   /* Pointer to the PDB                  */
    lpPrtDataEntry      PrinterData;   /* Pointer to Printer Data             */
    lplpFontCPListType  FontCPList;
    lpFontCPListType    CPList;
    lpFontCPListType    pCPData;
    lpMultiCpType       pMultiCp;      /* Ptr to multi codepage info          */
    LCIDType            lcid;
    lpFMFFileStruc      pMetrics;
    lpDVTCPSource       lpCodePageCaps;/* Pointer to local CodePageCaps struct*/
    USHORT              Index;         /* Index for font type loops           */
    USHORT              DeviceAttrs;   /* Attrs supported by current font     */
    ULONG               RetVal;
    USHORT              CPIndex;

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

    /**************************************************************************/
    /*  Search the resident fonts to see if one exactly matches the required  */
    /*  logical font.  First check the fields that don't depend on the        */
    /*  metrics...  check that the size of the font descriptor is valid.      */
    /**************************************************************************/
    if (LogFont->usRecordLength != sizeof(FATTRS))
        return(NO_FONT_MATCH);

    /**************************************************************************/
    /*  If a request has been made for a transformable font return            */
    /*  NO_FONT_MATCH.                                                        */
    /*                                                                        */
    /*  PD00788: remove check here, added to PRDARSUB.C                       */
    /**************************************************************************/
/*  if (LogFont->fsFontUse & FATTR_FONTUSE_TRANSFORMABLE)  */
/*      return(NO_FONT_MATCH);                             */

    /**************************************************************************/
    /*  Now, loop through all the base fonts in order, looking for a match on */
    /*  the FATTR we've been passed.  Do this by calling function             */
    /*  prda_MatchMetrics().  If we get through all the following loops, then */
    /*  we couldn't match, so return NO_FONT_MATCH.  First, resident fonts... */
    /**************************************************************************/
    for (Index = 0; Index < PDBInstance->DDT.DDTNoOfResidentFonts; Index++)
    {
        pMetrics    = PDBInstance->FontList[Index]->pFMFData;
        pMultiCp    = PDBInstance->FontList[Index]->pMultiCp;
        DeviceAttrs = PDBInstance->FontList[Index]->Attrs;

        /**********************************************************************/
        /*  Now construct a bare-bones LCID for prda_MatchMetrics() to use... */
        /**********************************************************************/
        prdm_PutLCIDFontType(lcid, FT_RESIDENT);
        prdm_PutLCIDFontIndex(lcid, Index);
        RetVal = prda_MatchMetrics((BYTE)DeviceAttrs, LogFont, lcid, pMetrics,
                                   pMultiCp, DCIData);
        if (RetVal != NO_FONT_MATCH)
            return(RetVal);
    }

    /**************************************************************************/
    /*  Next, Download Codepage fonts...  this gets tricky, so hold on...     */
    /**************************************************************************/
    CPIndex = prda_GetCPIndexFromCodePage(LogFont->usCodePage);

    /**************************************************************************/
    /*  Note that here a zero codepage indicates we're not looking for a      */
    /*  specific codepage - if the user had wanted a specific codepage it     */
    /*  would have matched in prdaMatchMetrics() above...                     */
    /*                                                                        */
    /*  PD00091 : Decrement usCPIndex by 1 to allow for the fact that         */
    /*  codepage 437 does not exist in the codepage list.                     */
    /*                                                                        */
    /*  PD00376 : Hmmm... we need to change the conditions under which we go  */
    /*  into the download codepage tests that follow to avoid nasty traps so  */
    /*  we need to check to see if the printer supports download codepage     */
    /*  fonts and if the font being checked is either resource or download    */
    /*  and if it is download we need to ensure that the font is installed.   */
    /*  If none of the above, then don't perform these tests...               */
    /*                                                                        */
    /*  PD00448 : If memory is not available, then we should not go through   */
    /*  this arm as no fmfs are loaded. This causes us to trap on the Pro I   */
    /*  when Memory Not Available is selected.                                */
    /**************************************************************************/
    if ( (PDBInstance->DDT.DDTFontFlags & DDT_ADD_CODE_PAGE_OPTION) &&
         ( (PrinterData->CPMemAvail == DOWN_CP_MEM_AVAIL ) ||
           (PDBInstance->DDT.DDTFontFlags & DDT_DOWN_CP_MEM_SUBSET_AVAIL) ) )
    {
        lpCodePageCaps = DVTCodePageCaps[PrinterData->PrinterType];
        if ((lpCodePageCaps[CPIndex].CPSource == CP_RESOURCE ||
            ((lpCodePageCaps[CPIndex].CPSource == CP_DOWNLOAD) &&
             (PrinterData->CPPathList[CPIndex - 1]) != FNULL)))
        {
            for (Index = 0; Index < PDBInstance->DDT.DDTFontsInCodePage;
                 Index++)
            {
                FontCPList  = DVTFontCPList[PDBInstance->PrinterType];
                CPList      = FontCPList[Index];
                pCPData     = &CPList[CPIndex - 1];
                pMetrics    = pCPData->pFMFData;
                pMultiCp    = NULL;
                DeviceAttrs = PDBInstance->FontList[Index]->Attrs;

                /**************************************************************/
                /*  Now construct a bare-bones LCID for prda_MatchMetrics() to*/
                /*  use...                                                    */
                /**************************************************************/
                prdm_PutLCIDFontType(lcid, FT_CODE_PAGE);
                prdm_PutLCIDCPFontIndex(lcid, Index);
                prdm_PutLCIDGCPIndex(lcid, CPIndex);
                RetVal = prda_MatchMetrics((BYTE)DeviceAttrs, LogFont, lcid,
                                           pMetrics, pMultiCp, DCIData);
                if (RetVal != NO_FONT_MATCH)
                    return(RetVal);
            }
        }
    }

    /**************************************************************************/
    /*  Next, Card fonts...                                                   */
    /**************************************************************************/
    for (Index = 0; Index < PrinterData->CardFontCount; Index++)
    {
        pMetrics = PrinterData->CardData[Index].pFMFData;
        pMultiCp = PrinterData->CardData[Index].pMultiCp;
        DeviceAttrs = PDBInstance->DDT.DDTCardImageAttrs;

        /**********************************************************************/
        /*  Now construct a bare-bones LCID for prda_MatchMetrics() to use... */
        /**********************************************************************/
        prdm_PutLCIDFontType(lcid, FT_CARD);
        prdm_PutLCIDFontIndex(lcid, Index);
        RetVal = prda_MatchMetrics((BYTE)DeviceAttrs, LogFont, lcid, pMetrics,
                                   pMultiCp, DCIData);
        if (RetVal != NO_FONT_MATCH)
            return(RetVal);
    }

    /**************************************************************************/
    /*  And finally, Download fonts.                                          */
    /**************************************************************************/
    for (Index = 0; Index < PrinterData->DownFontCount; Index++)
    {
        pMetrics = PrinterData->DownFontData[Index].pFMFData;
        pMultiCp = NULL;
        DeviceAttrs = PDBInstance->DDT.DDTCardImageAttrs;

        /**********************************************************************/
        /*  Now construct a bare-bones LCID for prda_MatchMetrics() to use... */
        /**********************************************************************/
        prdm_PutLCIDFontType(lcid, FT_DOWNLOAD);
        prdm_PutLCIDFontIndex(lcid, Index);
        RetVal = prda_MatchMetrics((BYTE)DeviceAttrs, LogFont, lcid, pMetrics,
                                   pMultiCp, DCIData);
        if (RetVal != NO_FONT_MATCH)
            return(RetVal);
    }

    /**************************************************************************/
    /*  If we got this far then none of the fonts can have matched.           */
    /**************************************************************************/
    return(NO_FONT_MATCH);
}
#undef TFUNC
