/*DDK*************************************************************************/
/*                                                                           */
/* 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.                                */
/*                                                                           */
/*****************************************************************************/
/**********************************************************************/
/*                                                                    */
/*   Module          = EDDVSUBR                                       */
/*                                                                    */
/*   Description     = Display Device Driver AVIO subroutine          */
/*                     CheckFont                                      */
/*                                                                    */
/*   Function        = Ensures that the correct AVIO font is selected */
/*                                                                    */
/*   Reference       = Winthorn Functional Specification              */
/*                     Device Driver Interface Specification          */
/*                     Display Device Driver Design Specification     */
/*                                                                    */
/*                                                                    */
/**********************************************************************/
#define INCL_DDICOMFLAGS
#define INCL_DDIMISC
#define INCL_GRE_FONTS
#include <eddinclt.h>

#include <edddtypt.h>
#include <eddttypt.h>

#include <eddmcone.h>
#include <eddvcone.h>

#include <eddbextf.h>
#include <eddmextf.h>
#include <eddtextf.h>
#include <eddvextf.h>

#include <eddhcone.h>
#include <eddhtype.h>
#include <eddhmacr.h>

#include <cursor.h>

#include <eddesres.h>

#ifndef DBCS                                                

extern AvioFontTableType        AvioBaseFont[NO_OF_AVIO_FONTS];

#else 

#include <eddjdef.h>
#include <eddjfm.h>
#include <eddjcp.h>
#include <eddjfont.h>
#include <eddjcach.h>
#ifndef PALETTE_MGR
#error "PALETTE_MGR is not defined. This file can't be built without \
Palette Manager."
#endif /* end PALETTE_MGR */
#include <eddvjtyp.h>

LONG   lQualifier;              /* these variables are used for IBM-J */
ULONG  ulPhysColor;             /* Vio format. These are referred in  */
                                /* asm routines.                      */

#ifdef TMP                                                  
ULONG  ulPhysColorIndex;
ULONG NearestMatchAVIOIndexFromRGB2 (ULONG color);
#endif 

extern ULONG NearestDirectDefaultPhysicalIndex(ULONG  RGBColor);
                                /* Actually NearestDirectDefaultIndex */
                                /* needs RGB2 structure, but same as  */
                                /* ULONG                              */

extern AvioFontTableType        AvioBaseFont[];
extern BYTE                     DefaultNormalFont;
                                       /* For DBCS, number of Avio    */
                                       /* base font and index of Avio */
                                       /* default font is determined  */
                                       /* by initialize routine.      */
#endif 
extern AvioDefaultFontTableType AvioDefaultFont[NO_OF_VIDEO_MODES];

extern PFONTCACHEINFO           pFontCacheInfo;
extern DDTType                  DDT;

extern ULONG                    FreeVRAM;
extern AVIOPB                   AIxfer;
extern USHORT                   usDefaultCodePage;

#ifdef BPP24
ULONG                           CouldntCache;
#endif

/**********************************************************************/
/* CheckFonts is a function called by the AVIO drawing routines.      */
/* It looks at the cell size in the VioPS and sets up the current     */
/* fonts accordingly.                                                 */
/* If the VioPS cell size does not match any of                       */
/* the base AVIO fonts exactly then the  values in the VioPS are      */
/* altered to match the size of the nearest AVIO font that is smaller */
/* than the requested size.                                           */
/* If any of the logical fonts 1..3 have been defined and are the     */
/* same size as the current cell size, then they are set up,          */
/* otherwise they are set up to use the base font  (as used by LCID 0)*/
/*                                                                    */
/* NOTE big changes: no locking now. If base font has changed, must   */
/* free old from cache, and set in the new. Also for the 3 extended   */
/* attribute fonts...                                                 */
/* If only cp has changed , no need to change lcid fonts.             */
/**********************************************************************/

VOID DRIVERCALL CheckAVIOFonts(PVIOPS  VioPS)

{
    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    ULONG last_avio_font;
    ULONG        i;                 /* Loop variable                  */
    ULONG        NearestFont;       /* Stores best match font         */
    PFONTDETAILS pfdBaseFont;       /* pointer from DC data base font */
    PFONTDETAILS pfdLoadableFont;   /* pointer for loadable font      */
    PAVIOINFO    pAvioInfo;         /* local variable                 */


    /******************************************************************/
    /* Scan through the base AVIO fonts and select the one which is   */
    /* closest to, but not bigger than, the cell size given in the    */
    /* VioPS.                                                         */
    /* Initialise NearestFont to the default font for the current     */
    /* screen mode.  This value will be returned if the requested     */
    /* font is smaller than any that we support.  This is necessary   */
    /* because when the engine calls us with a font size of (0,0) it  */
    /* expects us to return the default font.                         */
    /******************************************************************/
#ifdef DBCS                                                 
    if(CHECKENV(ENV_DBCS_CAPABLE))
    {
        /**************************************************************/
        /* For DBCS Driver, Avio default font is determined by        */
        /* initialize routine.                                        */
        /**************************************************************/
        NearestFont = (ULONG)DefaultNormalFont;

         for (i = 0;
         (i < AVIOFonts) &&
           (AvioBaseFont[i].CellWidth <= (BYTE)VioPS->CellImageWidth);
         i++)
         {
            if (AvioBaseFont[i].CellHeight
                    <= (BYTE)VioPS->CellImageHeight)
            {
                /******************************************************/
                /* This font is a better match than any previous ones.*/
                /******************************************************/
                NearestFont = i;
            }
        }
    }
    else
    {
        /**************************************************************/
        /* SBCS original code                                         */
        /**************************************************************/
#endif 
    if ( DDT.ScreenWidth <= LO_RES_WIDTH )
    {
       NearestFont = AvioDefaultFont[LO_RES_AVIO_FONT_INDEX].NormalFont;
    }
    else if ( DDT.ScreenWidth <= RES_800_WIDTH )
    {
       NearestFont = AvioDefaultFont[RES_800_AVIO_FONT_INDEX].NormalFont;
    }
    else
    {
       NearestFont = AvioDefaultFont[HI_RES_AVIO_FONT_INDEX].NormalFont;
    }

    if ( DDT.ScreenWidth < HI_RES_WIDTH )
    {
      i = 0;
      last_avio_font = MAX_AVIO_FONTS_LOADED;
    }
    else
    {
      i = NO_OF_AVIO_FONTS - MAX_AVIO_FONTS_LOADED;
      last_avio_font = MAX_AVIO_FONTS_LOADED + i;
    }
    for ( ;
         (i < last_avio_font) &&
           (AvioBaseFont[i].CellWidth <= (BYTE)VioPS->CellImageWidth);
         i++)
    {
        if (AvioBaseFont[i].CellHeight <= (BYTE)VioPS->CellImageHeight)
        {
            /**********************************************************/
            /* This font is a better match than any previous ones.    */
            /**********************************************************/
            NearestFont = i;
        }
    }
#ifdef DBCS                                                 
    }
#endif 

    /******************************************************************/
    /* The font to be used is now in NearestFont.                     */
    /* Store its dimensions in the VioPS.                             */
    /******************************************************************/
    VioPS->CellImageWidth = (USHORT)AvioBaseFont[NearestFont].CellWidth;
    VioPS->CellImageHeight = (USHORT)AvioBaseFont[NearestFont].CellHeight;

    /******************************************************************/
    /* Check if the cell height has changed. If so, we adjust the     */
    /* cursor start/end position to match the new cell size.          */
    /******************************************************************/
    if (VioPS->CellImageHeight != VioPS->CellHeightLatch)
    {
        VioPS->CellHeightLatch = VioPS->CellImageHeight;

        VioPS->TextCursorStartLine =
        VioPS->TextCursorEndLine   = VioPS->CellImageHeight - (USHORT)1;

        /**************************************************************/
        /* Make the cursor two pels high for fonts >8 pels high.      */
        /**************************************************************/
        if (VioPS->CellImageHeight > 8)
        {
            VioPS->TextCursorStartLine--;
        }
    }

    /******************************************************************/
    /* Ensure that the cursor width matches the font cell width.      */
    /******************************************************************/
    VioPS->TextCursorWidth = VioPS->CellImageWidth;

    pfdBaseFont = &pdc->DCIAvioFonts[0];
    pAvioInfo = &pdc->DCIAvioInfo;

    if ((pAvioInfo->bCellWidth  != (BYTE)VioPS->CellImageWidth) ||
        (pAvioInfo->bCellHeight != (BYTE)VioPS->CellImageHeight) ||
        (VioPS->CodepageID != pfdBaseFont->usCodePage) )

    {
        /**************************************************************/
        /* The base font is changing, so free the old one and setup   */
        /* cache info for this new one. If the size has changed       */
        /* then also kill the 3 lcid fonts.                           */
        /**************************************************************/
        if (pfdBaseFont->pFocaFont)
        {
            /**********************************************************/
            /* There was a previous font - free from cache            */
            /**********************************************************/
            eddt_FreeCachedFont( pfdBaseFont->usFontID,
                                 pfdBaseFont->usCachedFontIndex );
        }

#ifndef DBCS                                                
        /**************************************************************/
        /* Set new codepage, and get codepage vector from engine.     */
        /**************************************************************/
        pfdBaseFont->usCodePage = VioPS->CodepageID;
        if (pfdBaseFont->usCodePage)
        {
            pfdBaseFont->pCodePageVector =
                     (PUSHORT)GreQueryCodePageVector(pfdBaseFont->usCodePage);
        }
        else
        {
            /**********************************************************/
            /* CodePageID is null - use the codepage returned by      */
            /* DosGetCntryInfo.                                       */
            /**********************************************************/
            pfdBaseFont->pCodePageVector =
                     (PUSHORT)GreQueryCodePageVector(usDefaultCodePage);
        }
#else 
        /**************************************************************/
        /* The old font LCID 0 has been evicted. Now we call          */
        /* CheckCodePage to validate codepage value in                */
        /* VioPresentationSpace structure. This subroutine also gives */
        /* us pointer to codepage mapping vector table corresponds to */
        /* validated codepage.                                        */
        /**************************************************************/
        CheckCodePage(VioPS, pfdBaseFont);
#endif 

        /**************************************************************/
        /* Now get metrics and stuff from AvioBaseFont table.  Note   */
        /* new format for this.                                       */
        /* No copying - this is read-only...?                         */
        /**************************************************************/
        pfdBaseFont->pFocaFont = AvioBaseFont[NearestFont].pResourceData;

#ifdef DBCS                                                 
        /**************************************************************/
        /* Before calling eddt_LocateCachedFont, we call              */
        /* eddj_QueryFontProfile with pfdBaseFont->pFocaFont and set  */
        /* NLSFontFlag and FMCacheSize.                               */
        /**************************************************************/
        eddj_QueryFontProfile(pfdBaseFont->pFocaFont,
                              &pfdBaseFont->NLSFontFlag,
                              &pfdBaseFont->FMCacheSize);
#endif 

        /**************************************************************/
        /* Now setup cache table info.                                */
        /**************************************************************/
        eddt_LocateCachedFont(pfdBaseFont);
#ifndef DBCS                                                
        /**************************************************************/
        /*We no longer use pfciTable.                                 */
        /**************************************************************/
        pAvioInfo->pfciTable[0] =
                     &( pFontCacheInfo[pfdBaseFont->usCachedFontIndex] );
#endif 

        /**************************************************************/
        /* If the base font size has changed then invalidate the      */
        /* loadable fonts.                                            */
        /**************************************************************/
        if ((VioPS->CellByteSize == 4) &&
            ( (pAvioInfo->bCellWidth != (BYTE)VioPS->CellImageWidth) ||
              (pAvioInfo->bCellHeight != (BYTE)VioPS->CellImageHeight) ) )
        {
            for ( i = 1; i <= CNT_LOADABLE_LCIDS; i++ )
            {
                pfdLoadableFont = &pdc->DCIAvioFonts[i];

                if (pfdLoadableFont->pFocaFont)
                {
                    eddt_FreeCachedFont(
                                pfdLoadableFont->usFontID,
                                pfdLoadableFont->usCachedFontIndex );
                }
#ifdef DBCS                                                 
                /******************************************************/
                /* We have to clear npMapFontsLoaded, selFontsLoaded, */
                /* DBCSEvInfo fields in VioPresentationSpace structure*/
                /* which corresponds to AvioLCID. (DCR 150 for JP20)  */
                /******************************************************/
                VioPS->pMapFontsLoaded[i-1] = FNULL;
                VioPS->pFontsLoaded[i-1]    = FNULL;
#endif 

                /******************************************************/
                /* we will use default font for these until a         */
                /* DeviceSetAvioFont2 sets them up.                   */
                /******************************************************/
                pfdLoadableFont->pFocaFont = FNULL;
#ifndef DBCS                                                
                /******************************************************/
                /* We no longer use pfciTable.                        */
                /******************************************************/
                pAvioInfo->pfciTable[i]    = FNULL;
#endif 
            }
        }

        /**************************************************************/
        /* The font size has changed so set up the correct entries in */
        /* our AVIOParms data.                                        */
        /**************************************************************/
        pAvioInfo->bCellWidth  = (BYTE)VioPS->CellImageWidth;
        pAvioInfo->bCellHeight = (BYTE)VioPS->CellImageHeight;

    }

    /******************************************************************/
    /* Calculate the grid offsets before returning.                   */
    /******************************************************************/
    CalculateGridOffsets(pAvioInfo, VioPS);
}

/**********************************************************************/
/* Calculate the grid offsets.                                        */
/**********************************************************************/
VOID DRIVERCALL CalculateGridOffsets(PAVIOINFO pAvioInfo,
                                     PVIOPS    VioPS)
{
    /******************************************************************/
    /* Calculate the grid x offset.                                   */
    /******************************************************************/
    pAvioInfo->sXoffset = pdc->DCIOrigin.X % VioPS->CellImageWidth;

    if (pAvioInfo->sXoffset > 0)
    {
        pAvioInfo->sXoffset -= VioPS->CellImageWidth;
    }

    /******************************************************************/
    /* Calculate the grid y offset.                                   */
    /******************************************************************/
    pAvioInfo->sYoffset = ((DDT.ScreenHeight - 1 -
                    (pdc->DCIOrigin.Y +
                    (signed CHAR)VioPS->PartialCellAdjust) + 1) %
                                           VioPS->CellImageHeight);
    if (pAvioInfo->sYoffset > 0)
    {
        pAvioInfo->sYoffset -= VioPS->CellImageHeight;
    }
}


/**********************************************************************/
/* Ensure that all the AVIO fonts are in the cache                    */
/**********************************************************************/
VOID DRIVERCALL CheckAVIOFontsCached(PVIOPS  VioPS)
{
    ULONG       i;
    BOOL        AllCached;

    if (VioPS->CellByteSize != 4)
    {
        /**************************************************************/
        /* Just the base font.                                        */
        /**************************************************************/
        if ( pdc->DCIAvioFonts[0].usFontID !=
             pFontCacheInfo[ pdc->DCIAvioFonts[0].usCachedFontIndex
                              ].usFontID )
        {
            /**********************************************************/
            /* Its been evicted - locate it.                          */
            /**********************************************************/
            eddt_LocateCachedFont( &(pdc->DCIAvioFonts[0]) );
#ifndef DBCS                                                
            /**********************************************************/
            /* We no longer use pfciTable.                            */
            /**********************************************************/
            pdc->DCIAvioInfo.pfciTable[0] = &( pFontCacheInfo[
                         pdc->DCIAvioFonts[0].usCachedFontIndex ] );
#endif 
        }
    }
    else
    {
        /**************************************************************/
        /* Extended attribute mode: may have four fonts.              */
        /* Keep caching and checking till all the fonts are cached.   */
        /**************************************************************/
        do
        {
            for (i = 0; i <= CNT_LOADABLE_LCIDS; i++ )
            {
                if ( pdc->DCIAvioFonts[i].pFocaFont &&
                     ( pdc->DCIAvioFonts[i].usFontID !=
                       pFontCacheInfo[ pdc->DCIAvioFonts[i].
                                        usCachedFontIndex].usFontID )  )
                {
                    eddt_LocateCachedFont( &(pdc->DCIAvioFonts[i]) );
#ifndef DBCS                                                
                    /***************************************************/
                    /* We no longer use pfciTable.                     */
                    /***************************************************/
                    pdc->DCIAvioInfo.pfciTable[i] = &(pFontCacheInfo[
                          pdc->DCIAvioFonts[i].usCachedFontIndex ] );
#endif 
                }
            }
            AllCached = TRUE;
            for (i = 0; AllCached && (i <= CNT_LOADABLE_LCIDS); i++ )
            {
                if ( pdc->DCIAvioFonts[i].pFocaFont &&
                     ( pdc->DCIAvioFonts[i].usFontID !=
                       pFontCacheInfo[ pdc->DCIAvioFonts[i].
                                        usCachedFontIndex].usFontID )  )
                {
                    AllCached = FALSE;
                }
            }
        } while ( !AllCached );

    }
}

#ifndef DBCS                                                
/**********************************************************************/
/* CGAText                                                            */
/* Draws a rectangle of avio text in CGA (2 bytes/cell) mode.         */
/* Ensures characters are all cached before calling asm code          */
/**********************************************************************/
VOID DRIVERCALL CGAText(VOID)
{
    PFONTDETAILS pfdBaseFont;  /* pointer to base avio font in DC */
    PAVIOINFO    pAvioInfo;    /* pointer to AVIOINFO in DC       */

    #ifdef  BPP24
    CouldntCache = FALSE;      /* Assume we'll cache the fonts    */
    #endif

    if (!AIxfer.bAcross && !AIxfer.bDown)
    {
        /**************************************************************/
        /* Zero size - nothing to draw.                               */
        /**************************************************************/
        return;
    }

    pAvioInfo   = &pdc->DCIAvioInfo;
    pfdBaseFont = &pdc->DCIAvioFonts[0];

    if ( !update_cache_charrect_2(pfdBaseFont, pAvioInfo) )
    {
        /**************************************************************/
        /* Cache has been trashed: locate font and then try again.    */
        /**************************************************************/
        eddt_LocateCachedFont(  pfdBaseFont );
        pAvioInfo->pfciTable[0] =
                     &( pFontCacheInfo[pfdBaseFont->usCachedFontIndex] );

        if ( !update_cache_charrect_2( pfdBaseFont, pAvioInfo) )
        {
            /**********************************************************/
            /* This should NEVER happen, as the cache is empty!       */
            /* Could log an error here.                               */
            /**********************************************************/
            /* Defect 75086.  In 640x480x16M, we don't have room for  */
            /* large fonts. So, we'll blt them directly (like we do   */
            /* for non-grey). EKF                                     */
            /**********************************************************/
            #ifdef  BPP24
            if ( DDT.BitCount == 24 )
               CouldntCache = TRUE;
            else
               return;
            #else
            return;
            #endif
        }
    }
    /******************************************************************/
    /* Call to 386 code to draw avio rectangle                        */
    /******************************************************************/
    CGATextBlock( pfdBaseFont, pAvioInfo );
}


/**********************************************************************/
/* MFIText                                                            */
/* Draws a rectangle of avio text in MFI (4 bytes/cell) mode.         */
/* Ensures characters are all cached before calling asm code          */
/**********************************************************************/
VOID DRIVERCALL MFIText(VOID)
{
    PFONTDETAILS pfdBaseFont;  /* pointer to base avio font in DC */
    PAVIOINFO    pAvioInfo;    /* pointer to AVIOINFO in DC       */
    ULONG        i;

    if (!AIxfer.bAcross && !AIxfer.bDown)
    {
        /**************************************************************/
        /* Zero size - nothing to draw.                               */
        /**************************************************************/
        return;
    }

    pAvioInfo   = &pdc->DCIAvioInfo;
    pfdBaseFont = &pdc->DCIAvioFonts[0];

    if ( !update_cache_charrect_4( pfdBaseFont, pAvioInfo) )
    {
        /**************************************************************/
        /* Cache has been trashed: try again                          */
        /**************************************************************/
        for (i = 0; i <= CNT_LOADABLE_LCIDS; i++ )
        {

           /***********************************************************/
           /* Defect 60806 - We may not have CNT_LOADABLE_LCIDS fonts */
           /* defined so we should check before calling off to        */
           /* eddt_LocateCachedFont.                                  */
           /***********************************************************/
           if ( pdc->DCIAvioFonts[i].pFocaFont )
               eddt_LocateCachedFont(  &(pdc->DCIAvioFonts[i]) );

            pAvioInfo->pfciTable[i] =
                   &( pFontCacheInfo[pfdBaseFont->usCachedFontIndex] );
        }

        if ( !update_cache_charrect_4( pfdBaseFont, pAvioInfo) )
        {
            /**********************************************************/
            /* This should NEVER happen, as the cache is empty!       */
            /* Could log an error here.                               */
            /**********************************************************/
            return;
        }
    }

    /******************************************************************/
    /* Call to 386 code to draw avio rectangle                        */
    /******************************************************************/
    MFITextBlock( pfdBaseFont, pAvioInfo );
}
#else 
/**********************************************************************/
/* CGAText                                                            */
/* Draws a rectangle of avio text in CGA (2 bytes/cell) mode.         */
/**********************************************************************/
BOOL DRIVERCALL CGAText(VOID)
{
    PFONTDETAILS pfdBaseFont;  /* pointer to base avio font in DC */
    PAVIOINFO    pAvioInfo;    /* pointer to AVIOINFO in DC       */

    if (!AIxfer.bAcross && !AIxfer.bDown)
    {
        /**************************************************************/
        /* Zero size - nothing to draw.                               */
        /**************************************************************/
        return(OK);
    }

    pAvioInfo   = &pdc->DCIAvioInfo;
    pfdBaseFont = &pdc->DCIAvioFonts[0];

    /******************************************************************/
    /* Call to 386 code to draw avio rectangle                        */
    /******************************************************************/
    if (!(CGATextBlock( pfdBaseFont, pAvioInfo )))
    {
       return(ERROR_ZERO); /*This must be an charecter caching error!*/
    }
    else
    {
       return(OK);
    } /* endif */
}


/**********************************************************************/
/* MFIText                                                            */
/* Draws a rectangle of avio text in MFI (4 bytes/cell) mode.         */
/**********************************************************************/
BOOL DRIVERCALL MFIText(VOID)
{
    PFONTDETAILS pfdBaseFont;  /* pointer to base avio font in DC */
    PAVIOINFO    pAvioInfo;    /* pointer to AVIOINFO in DC       */

    if (!AIxfer.bAcross && !AIxfer.bDown)
    {
        /**************************************************************/
        /* Zero size - nothing to draw.                               */
        /**************************************************************/
        return(OK);
    }

    pAvioInfo   = &pdc->DCIAvioInfo;
    pfdBaseFont = &pdc->DCIAvioFonts[0];

    /******************************************************************/
    /* Call to 386 code to draw avio rectangle                        */
    /******************************************************************/
    if (!(MFITextBlock( pfdBaseFont, pAvioInfo )))
    {
       return(ERROR_ZERO); /*This must be an charecter caching error!*/
    }
    else
    {
       return(OK);
    } /* endif */
}

/**********************************************************************/
/* DBCSCommonText                                                     */
/* Draws a rectangle of avio text in DBCS Common (4 bytes/cell) mode. */
/**********************************************************************/
BOOL DRIVERCALL DBCSCommonText(VOID)
{
    PFONTDETAILS pfdBaseFont;  /* pointer to base avio font in DC */
    PAVIOINFO    pAvioInfo;    /* pointer to AVIOINFO in DC       */

    if (!AIxfer.bAcross && !AIxfer.bDown)
    {
        /**************************************************************/
        /* Zero size - nothing to draw.                               */
        /**************************************************************/
        return(OK);
    }

    pAvioInfo   = &pdc->DCIAvioInfo;
    pfdBaseFont = &pdc->DCIAvioFonts[0];

    /******************************************************************/
    /* Call to 386 code to draw avio rectangle                        */
    /******************************************************************/
    if (!(DBCSCommonBlock( pfdBaseFont, pAvioInfo )))
    {
       return(ERROR_ZERO); /*This must be an charecter caching error!*/
    }
    else
    {
       return(OK);
    } /* endif */
}


/**********************************************************************/
/* EpochColorText                                                     */
/* Draws a rectangle of avio text in Epoch Color (2 bytes/cell) mode. */
/**********************************************************************/
BOOL DRIVERCALL EpochColorText(PVIOPS VioPS)
{
    PFONTDETAILS pfdBaseFont;  /* pointer to base avio font in DC */
    PAVIOINFO    pAvioInfo;    /* pointer to AVIOINFO in DC       */
    PJVIOPSNLSEXT lpJNLSExt;   /* pointer to JVIOPSNLSEXT         */

    if (!AIxfer.bAcross && !AIxfer.bDown)
    {
        /**************************************************************/
        /* Zero size - nothing to draw.                               */
        /**************************************************************/
        return(OK);
    }

    pAvioInfo   = &pdc->DCIAvioInfo;
    pfdBaseFont = &pdc->DCIAvioFonts[0];

    /******************************************************************/
    /* Here, we have to do someting unique for IBM-J Vio format.      */
    /* At first get screen attribute flag in VioPSNLSExt structure    */
    /* and set it to variable to let ASM routime refer it. Then get   */
    /* grid color (RGB value) in same structure and convert it to     */
    /* index value and set it to a variavle.                          */
    /******************************************************************/
    if ((VioPS->lpNLSExt != FNULL) && CHECKENV(ENV_DBCS_CAPABLE))
    {
        lpJNLSExt  = (PJVIOPSNLSEXT)(VioPS->lpNLSExt);
        lQualifier = lpJNLSExt->scrn_attr_flag;
#ifdef TMP                                                  
        ulPhysColorIndex
         = NearestMatchAVIOIndexFromRGB2 (VioPS->lpNLSExt->grid_color);
#endif 

        ulPhysColor
         = NearestDirectDefaultPhysicalIndex(VioPS->
                                              lpNLSExt->grid_color);
    }

    /******************************************************************/
    /* Call to 386 code to draw avio rectangle                        */
    /******************************************************************/
    if (!(EpochColorBlock( pfdBaseFont, pAvioInfo )))
    {
       return(ERROR_ZERO); /*This must be an charecter caching error!*/
    }
    else
    {
       return(OK);
    } /* endif */
}


/**********************************************************************/
/* EpochMonoText                                                      */
/* Draws a rectangle of avio text in Epoch Mono (2 bytes/cell) mode.  */
/**********************************************************************/
BOOL DRIVERCALL EpochMonoText(PVIOPS VioPS)
{
    PFONTDETAILS pfdBaseFont;  /* pointer to base avio font in DC */
    PAVIOINFO    pAvioInfo;    /* pointer to AVIOINFO in DC       */
    PJVIOPSNLSEXT lpJNLSExt;   /* pointer to JVIOPSNLSEXT         */

    if (!AIxfer.bAcross && !AIxfer.bDown)
    {
        /**************************************************************/
        /* Zero size - nothing to draw.                               */
        /**************************************************************/
        return(OK);
    }

    pAvioInfo   = &pdc->DCIAvioInfo;
    pfdBaseFont = &pdc->DCIAvioFonts[0];

    /******************************************************************/
    /* Here, we have to do someting unique for IBM-J Vio format.      */
    /* At first get screen attribute flag in VioPSNLSExt structure    */
    /* and set it to variable to let ASM routime refer it. Then get   */
    /* grid color (RGB value) in same structure and convert it to     */
    /* index value and set it to a variavle.                          */
    /******************************************************************/
    if ((VioPS->lpNLSExt != FNULL) && CHECKENV(ENV_DBCS_CAPABLE))
    {
       lpJNLSExt  = (PJVIOPSNLSEXT)(VioPS->lpNLSExt);
       lQualifier = lpJNLSExt->scrn_attr_flag;
#ifdef TMP                                                  
        ulPhysColorIndex
         = NearestMatchAVIOIndexFromRGB2 (VioPS->lpNLSExt->grid_color);
#endif 

        ulPhysColor
         = NearestDirectDefaultPhysicalIndex(VioPS->
                                              lpNLSExt->grid_color);
    }

    /******************************************************************/
    /* Call to 386 code to draw avio rectangle                        */
    /******************************************************************/
    if (!(EpochMonoBlock( pfdBaseFont, pAvioInfo )))
    {
       return(ERROR_ZERO); /*This must be an charecter caching error!*/
    }
    else
    {
       return(OK);
    } /* endif */
}
#endif 

#ifdef DBCS
/**********************************************************************/
/* BOOL CheckCodePage(PVIOPS       VioPS,                             */
/*                    PFONTDETAILS pfdBaseFont)                       */
/*                                                                    */
/*                                                                    */
/* This subroutine checks codepage specified in VioPresentationSpace  */
/* structure (This codepage affects codepoint mapping for default     */
/* Avio font LCID 0.) and coerce the codepage if it's required. It    */
/* also gets pointer to codepoint mapping vector table which          */
/* corresponds to the validated codepage. And set pointers to them for*/
/* given font's FontDetails.                                          */
/*                                                                    */
/* Entry - VioPS  : 0:32 pointer to VioPresentationSpace structure.   */
/*                                                                    */
/*                                                                    */
/* Exit  - VioPS->CodepageID   : is validated and may be changed.     */
/*       - pfdBaseFont         : FontDetails pointed by pfdBaseFont   */
/*                               are specified.                       */
/**********************************************************************/
BOOL CheckCodePage(PVIOPS VioPS, PFONTDETAILS pfdBaseFont)
{
    USHORT  CPId;         /* temp variable to keep codepage value in  */
                          /* VioPresentationSpace structure           */


    /******************************************************************/
    /* First we check the codepage value specified in                 */
    /* VioPresentationSpace structure. If it is zero, it means default*/
    /* codepage. So we call ForceValidCP with usDefaultCodePage.      */
    /* We've already checked codepoint mapping with the               */
    /* usDefaultCodePage at initialization time, so this calling must */
    /* not be failed.                                                 */
    /******************************************************************/


    if (VioPS->CodepageID == 0)
    {
        CPId = usDefaultCodePage;
        eddj_QueryCPVectors((ULONG)CPId,
                            &pfdBaseFont->pCodePageVector,
                            &pfdBaseFont->pDBCSMap,
                            &pfdBaseFont->NLSParseFlag);
                                    /* leave 0 in VioPS->CodepageID   */
                                    /* without changing               */
    }
    else
    {
        CPId = VioPS->CodepageID;
                                    /* VioPS->CodepageID will be      */
                                    /* validated and may be changed   */
        if(!(eddj_QueryCPVectors((ULONG)CPId,
                            &pfdBaseFont->pCodePageVector,
                            &pfdBaseFont->pDBCSMap,
                            &pfdBaseFont->NLSParseFlag)))
        {
           VioPS->CodepageID = 0;
           CPId = usDefaultCodePage;
        eddj_QueryCPVectors((ULONG)CPId,
                            &pfdBaseFont->pCodePageVector,
                            &pfdBaseFont->pDBCSMap,
                            &pfdBaseFont->NLSParseFlag);
        }
    }
    if(!(pfdBaseFont->NLSParseFlag & NLSCA_MAP_SBCS))
    {
        pfdBaseFont->pCodePageVector = FNULL;
    }
    if(!(pfdBaseFont->NLSParseFlag & NLSCA_MAP_DBCS))
    {
        pfdBaseFont->pDBCSMap = FNULL;
    }
    pfdBaseFont->usCodePage = VioPS->CodepageID;
    return(OK);
}

/**********************************************************************/
/* LONG DRIVERCALL AvioForceCharInCache(PFONTDETAILS pFontDetails,    */
/*                                      ULONG        ulCodePoint)     */
/*                                                                    */
/* This routine checks character image correponds to given codepoint  */
/* is in cache or not. If it's not in cache, this routine caches the  */
/* char image and return offset in cache. In case the font itself is  */
/* flashed, this routine locates font and return error. (may be called*/
/* once more.)                                                        */
/*                                                                    */
/* Entry - pFontDetails     : FONTDETAILS to be checked               */
/*       - ulCodePoint      : cp value (SBCS/DBCS) to be cached       */
/*                                                                    */
/* Exit  - lCacheIndex      : char image's offset in cahce            */
/*                            (on error: 0FFFFFFFFh)                  */
/**********************************************************************/
LONG DRIVERCALL AvioForceCharInCache(PFONTDETAILS pFontDetails,
                                     ULONG        ulCodePoint)
{
    LONG    lCacheIndex;

    /******************************************************************/
    /* First, We call eddj_LocateInCache and check already located    */
    /* in cache.                                                      */
    /******************************************************************/
    lCacheIndex = eddj_LocateInCache(pFontCacheInfo
                                     + pFontDetails->usCachedFontIndex,
                                     (USHORT)ulCodePoint);
    if (lCacheIndex >= 0)
    {
       /***************************************************************/
       /* Already located in cache. Return lCacheIndex.               */
       /***************************************************************/
       return(lCacheIndex);
    }
    else if ((lCacheIndex != ERROR_CACHE_FULL) &
             ((lCacheIndex & FLAG_NOT_IN_CACHE) == FLAG_NOT_IN_CACHE))
    {
       /***************************************************************/
       /* Maybe haven't been cached yet. So try caching.              */
       /***************************************************************/
       lCacheIndex &= ~FLAG_NOT_IN_CACHE;
       lCacheIndex
           = eddt_CacheCharacter((USHORT)ulCodePoint, pFontDetails,
                                                      lCacheIndex);
       if (lCacheIndex >= 0)
       {
          /************************************************************/
          /* Caching succeeded. Return lCacheIndex.                   */
          /************************************************************/
          return(lCacheIndex);
       }
       else
       {
          /************************************************************/
          /* Cache came to be full and flushed during caching. Locate */
          /* required font and report error to caller. Next time chars*/
          /* are cached by row.                                       */
          /************************************************************/
          eddt_LocateCachedFont(pFontDetails);
          return(ERROR_NEG);
       }
    }
    else if (lCacheIndex == ERROR_CACHE_FULL)
    {
       /***************************************************************/
       /* Cache is full, so must be flushed. Invalidate cache and     */
       /* locate font, then report cached is flushed to caller.       */
       /* Next time chars are cached by row.                          */
       /***************************************************************/
       eddt_InvalidateCache();
       eddt_LocateCachedFont(pFontDetails);
       return(ERROR_NEG);
    }
}

#ifdef TMP                                                  

#define ABS(a)      (((a) < 0) ? -(a) : (a))

ULONG NearestMatchAVIOIndexFromRGB2 (ULONG color)
{
    BYTE    bBlue, bGreen, bRed;
    INT     i;
    ULONG   diff, diff_save;
    ULONG   best_index;
    extern RGB2 AVIOColorTable [];


    bBlue  = ((PRGB2)&color)->bBlue;
    bGreen = ((PRGB2)&color)->bGreen;
    bRed   = ((PRGB2)&color)->bRed;

    diff_save = (ULONG)-1L;

    for (i = 0; i < AVIO_PALETTE_SIZE; i++)
    {
        diff = ABS (AVIOColorTable[i].bBlue  - bBlue) +
               ABS (AVIOColorTable[i].bGreen - bGreen) +
               ABS (AVIOColorTable[i].bRed   - bRed);

        if (diff < diff_save)
        {
            diff_save = diff;
            best_index = i;
        }
    }

    return best_index;
}

#endif 
#endif 

