/*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 Name: FDWIN.C                                                      */
/*                                                                            */
/*      Physical font resource access support routine for OS/2 DBCS PM        */
/*      font drivers.                                                         */
/*                                                                            */
/*  Created: 15-Oct-1991                                                      */
/*  Author:  Soh Ohta     [jl09057 @ ymtvm3, IBM Japan]                       */
/*                                                                            */
/*                        Refer to Copyright Inscruction Form No.G120-2083    */
/*                                                                            */
/*  Exported Functions:   none                                                */
/*                                                                            */
/*  Public Functions:     LoadWINFont                                         */
/*                        FreeWINFont                                         */
/*                        QueryWINWidth                                       */
/*                        QueryDefWINWidth                                    */
/*                        QueryWINImage                                       */
/*                        QueryDefWINImage                                    */
/*                                                                            */
/*  Public Data:          none                                                */
/*                                                                            */
/*  General Description:                                                      */
/*                                                                            */
/* CHANGE ACTIVITY:                                                           */
/* FLAG REASON   RLSE DATE   ORIGIN   COMMENTS                                */
/* ---- -------- ---- ------ -------- ----------------------------------------*/
/* @Y1  PTR6360  R206 930623 YujiWat  Included JIS'90-added two characters    */
/* @NI1 DCR291   R206 930713 N.Iuchi  12 dot WINDOW DBCS font support         */
/******************************************************************************/

#define INCL_PM
#define INCL_DOS
#include <os2.h>
#include <memory.h>
#include "resmap.h"


extern NPBYTE   npImageSrc;             // image mapping work area.
extern NPBYTE   npImageDst;             // image mapping work area.
extern CPINFO   cpInfo;                 // codepage vector.
extern UCHAR    chBootDrive;            // boot drive (A,B,C...).
extern SEL      selDs;                  // FD's shared data segment selector.
extern HHEAP    hHeap;                  // FD's heap handle.

USHORT              InitDiskCache (NPFONTFILEINFO);
VOID                FreeDiskCache (NPFONTFILEINFO);
USHORT              ReadDiskCache (NPFONTFILEINFO,ULONG,NPBYTE,USHORT);
VOID                FontFromBitmap (PBYTE,NPBITSDEF);
NPBITSDEF PASCAL    Bitblt (NPBITSDEF,NPBITSDEF);
VOID      PASCAL    DecompWinImage (NPENCODE,NPBYTE,NPBYTE,USHORT);



/******************************************************************************/
/*  LoadWINFont                                                               */
/*                                                                            */
/*  Load resoures associated to the specified physical font.                  */
/*                                                                            */
/*  Parameter:                                                                */
/*      npFont    = physical font descriptor (font to be modified)            */
/*  Return:                                                                   */
/*      success   = 0                                                         */
/*      error     = -1                                                        */
/******************************************************************************/

USHORT LoadWINFont (NPRESMAP npFont)
{
    register NPFONTFILEINFO npFileInfo;
    USHORT                  LoadWinEncInfo (NPFONTFILEINFO);

    npFileInfo = (NPFONTFILEINFO)npFont->npPrivate;
    npFileInfo->szFile[0] = chBootDrive;

    if (LoadWinEncInfo (npFileInfo) == 0)
        return InitDiskCache (npFileInfo);
    if (npFileInfo->npEncode==INVALID_ADDRESS)                       /* @NI1 */
        return 0;                                                    /* @NI1 */
    return -1;
}

/******************************************************************************/
/*  FreeWINFont                                                               */
/*                                                                            */
/*  Free resoures associated to the specified physical font.                  */
/*                                                                            */
/*  Parameter:                                                                */
/*      npFont    = physical font descriptor (font to be modified)            */
/*  Return:                                                                   */
/*      nothing                                                               */
/******************************************************************************/

VOID FreeWINFont (NPRESMAP npFont)
{
    register NPENCODE   npEncInfo;

    FreeDiskCache ((NPFONTFILEINFO)npFont->npPrivate);
    npEncInfo = (NPENCODE)(((NPFONTFILEINFO)npFont->npPrivate)->npEncode);
    WinFreeMem (hHeap,(NPBYTE)npEncInfo,npEncInfo->cbSize);
}

/******************************************************************************/
/*  QueryWINWidth                                                             */
/*                                                                            */
/*  Return specified character cell width.                                    */
/*                                                                            */
/*  Parameter:                                                                */
/*      index     = glyph index                                               */
/*      npVirtual = virtual  font descriptor (FD font being requested)        */
/*      npFont    = physical font descriptor (font to be modified)            */
/*  Return:                                                                   */
/*      success   = character cell width                                      */
/*      error     = 0                                                         */
/******************************************************************************/

USHORT QueryWINWidth (USHORT index, NPRESMAP npVirtual, NPRESMAP npFont)
{
    return npVirtual->xAveCharWidth;
}

/******************************************************************************/
/*  QueryDefWINWidth                                                          */
/*                                                                            */
/*  Return default character cell width.                                      */
/*                                                                            */
/*  Parameter:                                                                */
/*      npVirtual = virtual  font descriptor (FD font being requested)        */
/*      npFont    = physical font descriptor (font to be modified)            */
/*  Return:                                                                   */
/*      success   = character cell width                                      */
/*      error     = 0                                                         */
/******************************************************************************/

USHORT QueryDefWINWidth (NPRESMAP npVirtual, NPRESMAP npFont)
{
    return npVirtual->xAveCharWidth;
}

/******************************************************************************/
/*  QueryWINImage                                                             */
/*                                                                            */
/*  Get specified character image and return its width.                       */
/*                                                                            */
/*  Parameter:                                                                */
/*      index     = glyph index                                               */
/*      npVirtual = virtual  font descriptor (FD font being requested)        */
/*      npFont    = physical font descriptor (font to be modified)            */
/*      lpBuf     = image buffer into which the font is to be built           */
/*      cbBuf     = image buffer size                                         */
/*  Return:                                                                   */
/*      success   = character cell width                                      */
/*      error     = 0                                                         */
/******************************************************************************/

USHORT QueryWINImage (USHORT index, NPRESMAP npVirtual, NPRESMAP npFont, PBYTE lpBuf, USHORT cbBuf)
{
    register NPFONTFILEINFO npFileInfo;
    register USHORT         cbComp;
    USHORT                  ReadWinImage (NPFONTFILEINFO,USHORT,NPBYTE);

    if (npVirtual->bitsDef.cbScan*npVirtual->bitsDef.nScans <= cbBuf) {

        // setup image mapping work area.
        npVirtual->bitsDef.npBits = npImageDst;
        npFont->bitsDef.npBits    = npImageSrc;

        // get font image.
        npFileInfo = (NPFONTFILEINFO)npFont->npPrivate;
        if (npFileInfo->npEncode == INVALID_ADDRESS)                 /* @NI1 */
            return 0;                                                /* @NI1 */
        if ((cbComp = ReadWinImage (npFileInfo,index,npImageDst)) == 0)
            return 0;
        DecompWinImage ((NPENCODE)npFileInfo->npEncode,npImageSrc,npImageDst,cbComp);

        // do image mapping and convert image to font format.
        FontFromBitmap (lpBuf,Bitblt(&npVirtual->bitsDef,&npFont->bitsDef));
        return npVirtual->xAveCharWidth;
    }
    return 0;
}

/******************************************************************************/
/*  QueryDefWINImage                                                          */
/*                                                                            */
/*  Get default character image and return its width.                         */
/*                                                                            */
/*  Parameter:                                                                */
/*      npVirtual = virtual  font descriptor (FD font being requested)        */
/*      npFont    = physical font descriptor (font to be modified)            */
/*      lpBuf     = image buffer into which the font is to be built           */
/*      cbBuf     = image buffer size                                         */
/*  Return:                                                                   */
/*      success   = character cell width                                      */
/*      error     = 0                                                         */
/******************************************************************************/

USHORT QueryDefWINImage (NPRESMAP npVirtual, NPRESMAP npFont, PBYTE lpBuf, USHORT cbBuf)
{
    if (npVirtual->fsTypeFlags & FM_TYPE_DBCS)
        // get DBCS default character image.
        return QueryWINImage (cpInfo.usDefaultChar,npVirtual,npFont,lpBuf,cbBuf);
    else
        return 0;   // no SBCS font image.
}

/******************************************************************************/
/*         DBCS WIFE Font Accessing Codes                                     */
/******************************************************************************/

typedef struct _Vf {        /* vf */
    USHORT      nHdr;
    USHORT      nChar;
    BYTE        nRow;
    BYTE        nHeight;
    BYTE        nWidth;
} WINDBCSFONTINFO;

typedef struct _Fh {        /* fh */
    USHORT      nHdr;
    BYTE        nVersion;
    BYTE        nEntry;
    USHORT      HuffData[128];
} WINDBCSCOMPINFO;

WINDBCSFONTINFO FontInfo;
WINDBCSCOMPINFO CompInfo;

#define ulFileSize  (0L)                // DosOpen fixed parameters.
#define usAttribute (0)
#define fsOpenFlags (FILE_OPEN)
#define fsOpenMode  (OPEN_SHARE_DENYWRITE)
#define ulReserved  (0L)

/******************************************************************************/
/*  LoadWinEncInfo                                                            */
/*                                                                            */
/*  Generate font image encoding information table.                           */
/*                                                                            */
/*  Parameter:                                                                */
/*      npFileInfo= font file information table                               */
/*  Return:                                                                   */
/*      success   = 0                                                         */
/*      error     = -1                                                        */
/******************************************************************************/

USHORT LoadWinEncInfo (NPFONTFILEINFO npFileInfo)
{
    NPENCODE        npEncInfo;
    USHORT          cbEncInfo;
    USHORT          nMask;
    register USHORT i,mask;
    HFILE           hFile;
    USHORT          usAction;
    USHORT          cbBytesRead;
    ULONG           ulOffset;

    if (DosOpen (npFileInfo->szFile,&hFile,&usAction,ulFileSize,
                 usAttribute,fsOpenFlags,fsOpenMode,ulReserved) != 0)
        return -1;      // cannot open the font file.

    // read header information.
    if ((DosRead (hFile,&FontInfo,sizeof(WINDBCSFONTINFO),&cbBytesRead) != 0) ||
        (cbBytesRead != sizeof(WINDBCSFONTINFO)) ||
        (DosChgFilePtr (hFile,(LONG)FontInfo.nHdr,FILE_BEGIN,&ulOffset) != 0) ||
        (DosRead (hFile,&CompInfo,sizeof(WINDBCSCOMPINFO),&cbBytesRead) != 0) ||
        (cbBytesRead != sizeof(WINDBCSCOMPINFO)) ||
        (FontInfo.nHeight > MAXHEIGHT) ||
        (CompInfo.nVersion != 1) ||
        (CompInfo.nEntry != 1)) {
        DosClose (hFile);
        return -1;
    }

    // compute heap memory size for this font.
    for(nMask=0; CompInfo.HuffData[nMask++]!=0xffff; )
        ;
    cbEncInfo = sizeof(ENCODE)+
               sizeof(MASKTBL)*nMask+
               sizeof(ULONG)*(FontInfo.nChar/MSTONE+1)+
               sizeof(BYTE)*FontInfo.nChar;

    if ((npEncInfo = (ENCODE NEAR*)WinAllocMem (hHeap,cbEncInfo)) == NULL) {
        DosClose (hFile);
        return -1;      // cannot allocate heap memory.
    }

    // construct EncInfo.
    npEncInfo->cbSize   = cbEncInfo;
    npEncInfo->cx       = FontInfo.nWidth;
    npEncInfo->cy       = FontInfo.nHeight;
    npEncInfo->nChar    = FontInfo.nChar;
    npEncInfo->nMask    = nMask;
    npEncInfo->npMstone = (NPULONG)&npEncInfo->Huff[npEncInfo->nMask];
    npEncInfo->npLenTbl = (NPBYTE)&npEncInfo->npMstone[npEncInfo->nChar/MSTONE+1];

    // npEncInfo->Huff[]
    for(mask=0x0000,i=0; i<nMask-1; i++ ) {
        npEncInfo->Huff[i].mask = mask;
        npEncInfo->Huff[i].len  = (BYTE)(CompInfo.HuffData[i]&0xff);
        npEncInfo->Huff[i].data = (BYTE)(CompInfo.HuffData[i]>>8);
        mask += (1<<(16-npEncInfo->Huff[i].len));
    }
    npEncInfo->Huff[i].mask = 0xffff;
    npEncInfo->Huff[i].len  = 0xff;
    npEncInfo->Huff[i].data = 0xff;

    // npEncInfo->Dcmp[] and npEncInfo->npLenTbl[]
    if ((DosChgFilePtr (hFile,(LONG)FontInfo.nHdr+CompInfo.nHdr,FILE_BEGIN,&ulOffset) != 0) ||
        (DosRead (hFile,npEncInfo->Dcmp,MAXTBL/2,&cbBytesRead) != 0) ||
        (cbBytesRead != MAXTBL/2) ||
        (DosRead (hFile,npEncInfo->npLenTbl,npEncInfo->nChar,&cbBytesRead) != 0) ||
        (cbBytesRead != npEncInfo->nChar)) {
        WinFreeMem (hHeap,(NPBYTE)npEncInfo,cbEncInfo);
        DosClose (hFile);
        return -1;
    }

    // npEncInfo->npMstone
    ulOffset = (LONG)FontInfo.nHdr+CompInfo.nHdr+MAXTBL/2+npEncInfo->nChar;
    for (i=0; i<npEncInfo->nChar; i++) {
        if (i%MSTONE == 0)
            npEncInfo->npMstone[i/MSTONE] = ulOffset;
        ulOffset += npEncInfo->npLenTbl[i];
    }

    DosClose (hFile);
    npFileInfo->npEncode = (NPBYTE)npEncInfo;
    return 0;       // success.
}

/******************************************************************************/
/*  ReadWinImage                                                              */
/*                                                                            */
/*  Read compressed font image.                                               */
/*                                                                            */
/*  Parameter:                                                                */
/*      npFileInfo= font file information table                               */
/*      index     = glyph index                                               */
/*      npBuf     = address to save compressed font image                     */
/*  Return:                                                                   */
/*      success   = number of bytes read                                      */
/*      error     = 0                                                         */
/******************************************************************************/

USHORT ReadWinImage (NPFONTFILEINFO npFileInfo, USHORT index, NPBYTE npBuf)
{
    register USHORT     i;
    register NPENCODE   npEncInfo;
    ULONG               ulOffset;
    USHORT              FontIndexFromGlyph (USHORT);

    npEncInfo = (NPENCODE)npFileInfo->npEncode;

    if (((index = FontIndexFromGlyph (index)) >= npEncInfo->nChar) ||
        (npEncInfo->npLenTbl[index] == 0))
        return 0;

    i = index/MSTONE;
    ulOffset = npEncInfo->npMstone[i];
    for (i*=MSTONE; i<index; i++)
        ulOffset += npEncInfo->npLenTbl[i];

    // read compressed image.
    return ReadDiskCache (npFileInfo,ulOffset,npBuf,npEncInfo->npLenTbl[index]);
}

/******************************************************************************/
/*  FontIndexFromGlyph                                                        */
/*                                                                            */
/*  Convert DBCS glyph index to         DBCS WIFE font index.                 */
/*                                                                            */
/*  Parameter:                                                                */
/*      index     = glyph index                                               */
/*  Return:                                                                   */
/*      success   =         DBCS WIFE font index                              */
/*                = -2 (user defined index)                                   */
/*      error     = -1                                                        */
/******************************************************************************/

USHORT FontIndexFromGlyph (USHORT index)
{
    USHORT  iFont;

    switch (cpInfo.usCodePage)
    {
        default:
            return -1;

        case 932:
            /******************************************************************/
            //  <codepage 932: codepoint ranges>
            //
            //       Ku Range   Code Range        Type         Char Non-Char
            //      --------------------------------------------------------
            //      001        8140h - 84BEh  JIS Non-Kanji     690
            //          - 008  84BFh - 84FCh  JIS Reserved                62
            //      009 - 015  8540h - 889Eh  JIS Reserved               658
            // @Y1D 016        889Fh - EAA2h  JIS Kanji        6396
            // @Y1D     - 084  EAA3h - EAFCh  JIS Reserved                90
            // @Y1A 016        889Fh - EAA4h  JIS Kanji        6398
            // @Y1A     - 084  EAA5h - EAFCh  JIS Reserved                88
            //      085 - 094  EB40h - EFFCh  JIS Reserved               940
            //      --------------------------------------------------------
            //      095 - 114  F040h - F9FCh  IBM User Defined          1880
            //      115        FA40h - FC4Bh  IBM Selected      388
            //          - 120  FC4Ch - FCFCh  IBM Reserved               176
            //      --------------------------------------------------------
            // @Y1D                           Total: 11280  =  7474  +  3806
            // @Y1A                           Total: 11280  =  7476  +  3804
            /******************************************************************/
            _asm {

            // Compute         WIFE DBCS font index for codepage 932.

                mov     ax,index        // ax = index
                mov     bx,ax

            // Check DBCS trailing byte range.
            // Valid range is:  40h..7Eh and 80h..FCh (188 chars)

                sub     bl,040h
                jb      invalid_index
                cmp     al,07fh
                jb      lo_valid_932
                je      invalid_index
                cmp     al,0fch
                ja      invalid_index
                dec     bl
            lo_valid_932:

            // Check DBCS leading byte range.
            // Valid range is:  81h..9Fh and E0h..FCh

                sub     bh,081h
                jb      invalid_index
                cmp     ah,0a0h
                jb      hi_valid_932
                cmp     ah,0e0h
                jb      invalid_index
                sub     bh,0e0h-0a0h
            hi_valid_932:

            // Check whether the verified index is within the defined
            // code range or not, and then compute the font index.
            // Be sure that the WIFE font file doesn't include any
            // undefined characters.

                xor     dx,dx           // dx = base index of defined range
                cmp     ax,084beh
                jbe     defined_932     // 8140h..84BEh (JIS non kanji)
                cmp     ax,0889fh
                jb      invalid_index
                add     dx,62+658
                cmp     ax,0eaa4h       // Changed from 0eaa2h to 0eaa4h  @Y1C
                                        // to include JIS'90 two chars    @Y1A
                jbe     defined_932     // 889Fh..EAA4h (JIS kanji)       @Y1C
                cmp     ax,0f040h
                jb      invalid_index
                cmp     ax,0f9fch
                jbe     user_defined    // F040h..F9FCh (IBM user defined)
                cmp     ax,0fc4bh
                ja      invalid_index
                add     dx,88+940+1880  // FA40h..FC4Bh (IBM selected)    @Y1C
                                        // Changed from 90+... to 88+...  @Y1A
                                        // to include JIS'90 two chars    @Y1A

            // Compute font index for given index.

            defined_932:
                mov     al,188          // 188 chars in XX00h..XXFFh
                mul     bh
                xor     bh,bh
                add     ax,bx
                sub     ax,dx
                mov     iFont,ax
            }
            return iFont;
    }

    invalid_index:
        return -1;
    user_defined:
        return -2;
}

