/*======================================================
FILE:  AEEBitFont.c

SERVICES:  AEEBitFont class

GENERAL DESCRIPTION:
   BREW bitmapped font implementation. Dispatches to appropriate
   IFont implementation depending on BBF version.

PUBLIC CLASSES AND STATIC FUNCTIONS:

   AEEBitFont_New()

   
INITIALIZATION & SEQUENCING REQUIREMENTS:

	See Exported Routines

        Copyright ?1999-2004 QUALCOMM Incorporated.
               All Rights Reserved.
            QUALCOMM Proprietary/GTDR
=====================================================*/

// Todo:
//   - Test IBitFontFoundry
//   - Use IBitFontFoundry as an entrypoint not AEEBitFont_NewFromBBF()
//   - Add methods to IBitFontFoundry for NewFromDIB/NewFromBMP
//   - Add MIME handlers for bbf and methods to IBitFontFoundry to new from File
//   - Add a const file mapper, to access data through IPeek to save RAM for ROM

#include "AEEFont.h"
#include "AEEBridle.h"
#include "AEEStdLib.h"
#include "AEEBBF.h"
#include "AEEBitFont_priv.h"
#include "AEEBitFontFoundry.h"


//----  Helper functions
//
//


// Map a character value to a glyph index, given a range array.
//
// Return -1 on error.
//
// Note: This does not validate glyph values.
//
int32 CharToGlyph(uint16 wChar, AEEBBFRange *pRanges, int cntRanges)
{
   int32 wGlyph = 0;
   
   for ( ; cntRanges; --cntRanges, ++pRanges) {

      uint16 wBase = pRanges->wCharBase;
      uint16 wCount = pRanges->wCount;

      if (wCount < AEEBBF_INDEXFREEZE) {

         // normal range
         uint16 uOffset = wChar - wBase;
         
         if (uOffset < wCount)
            return wGlyph + uOffset;      // success

         wGlyph += wCount;

      } else {
         // FREEZE or RESET
         
         wGlyph = (int32) wBase;

         if (wCount == AEEBBF_INDEXFREEZE) {

            // Read ahead without incrementing  (stop at FREEZE or RESET)
            while (cntRanges > 1 && pRanges[1].wCount < AEEBBF_INDEXFREEZE) {
               if ( (uint16) (wChar - pRanges[1].wCharBase) < pRanges[1].wCount)
                  return wGlyph;
               ++pRanges;
               --cntRanges;
            }

         }
      }
   }
   
   return -1;   // error; character not defined
}

int AEEBitFont_NewFromBBF(const byte *pbyMem, int cbMem, void *pvStorage, PFNREALLOC pfnRealloc, IFont **ppIFont)
{
   int            nRet = EFAILED;
   AEEBBFHdr *    phdrBBF;

   if( ((phdrBBF = (AEEBBFHdr *)pbyMem) == NULL) ){
      nRet = EBADPARM;
   }else{
      if (phdrBBF->byCookie0 != 'B' ||
          phdrBBF->byCookie1 != 'F' ||
          phdrBBF->byDepth != 1 ||
          phdrBBF->wGlyphCount == 0){
         nRet = EINVALIDFORMAT;
      }else{
         switch( phdrBBF->byVersion ){
         case 0:
         case 1:
            nRet = AEEVarBitFont_NewFromBBF(pbyMem, cbMem, pvStorage, pfnRealloc, ppIFont);
            break;
         case 2:
            nRet = AEEMonoBitFont_NewFromBBF(pbyMem, cbMem, pvStorage, pfnRealloc, ppIFont);
            break;
         default:
            nRet = EUNSUPPORTED;
            break;
         }
      }
   }
   return nRet;
}

//--------  IBitFontFoundry : Creates IFonts from BBF data
//


struct _IBitFontFoundry {
   const AEEVTBL(IBitFontFoundry) *pvt;
};


static uint32
AEEBitFontFoundry_AddRef(IBitFontFoundry *me)
{
   return 1;
}


static uint32
AEEBitFontFoundry_Release(IBitFontFoundry *me)
{
   return 1;
}


static int
AEEBitFontFoundry_CreateFromBBF(IBitFontFoundry *me, byte *pbyMem, int cbMem, void *pvStorage, IFont **ppIFont)
{
   return AEEBitFont_NewFromBBF(pbyMem, cbMem, pvStorage, 0, ppIFont);
}


static const VTBL(IBitFontFoundry) gAEEBitFontFoundryFuncs = {
   AEEBitFontFoundry_AddRef,
   AEEBitFontFoundry_Release,
   AEEBitFontFoundry_CreateFromBBF
};


static IBitFontFoundry gAEEBitFontFoundry = {
   &gAEEBitFontFoundryFuncs
};



//
//--------   New function for AEEStaticClass
//

int AEEBitFontFoundry_New(IShell * piShell, AEECLSID cls, void **ppif)
{
   if (cls == AEECLSID_BITFONTFOUNDRY) {
      *ppif = &gAEEBitFontFoundry;
      return SUCCESS;
   }

   *ppif = 0;
   return ECLASSNOTSUPPORT;
}
