#include "error.h"
#include "font.h"

int Font_getFontOffset0(Font *f,BYTE *cc);
int Font_getFontOffset2(Font *f,BYTE *cc);

/*
   This function translates two-byte character codes into
   location offsets in the Glyph Data.

   int Font_getFontOffset(Font *f,BYTE *cc);

   You can use
      off = Font_getFontOffset(f,cc);
      Font_load_GLYF(f,fp,off);
   to fetch data in f->glyf

*/

void Font_select_CMAP(Font *f,USHORT platId,USHORT encId)
{
  int i;
  for(i=0;i<f->numberOfEncoding;i++)
  {
    if ((f->cmap[i].PlateformID == platId)||(f->cmap[i].EncodingID==encId))
      break;
  }
  if (i == f->numberOfEncoding)
    f->curmap = &f->cmap[0];
  else
    f->curmap = &f->cmap[i];
}

int Font_getFontOffset(Font *f,BYTE *cc)
{
  switch(f->curmap->format)
  {
  case 0:
    return Font_getFontOffset0(f,cc);
  case 2:
    return Font_getFontOffset2(f,cc);
    /*
      case 4:
        return Font_getFontOffset4(cm,cc);
      case 6:
        return Font_getFontOffset6(cm,cc);
    */
  default:
    return -1;
  }
}

int Font_getFontOffset0(Font *f,BYTE *cc)
{
  BYTE index;

  index = f->curmap->map.cmap0->glyphIdArray[*cc];
  return f->indexToLocation[index];
}

int Font_getFontOffset2(Font *f,BYTE *cc)
{
  USHORT index;
  USHORT index1,firstCode,entryCount;
  SHORT idDelta;
  USHORT idRangeOffset;
  CMAP *cm;

  cm = f->curmap;
  index1 = cm->map.cmap2->subHeaderKeys[*cc];
    
  if (index1 == 0)
    index = cm->map.cmap2->glyphIdArray[*cc];
  else
  {
    firstCode = cm->map.cmap2->data[index1*4];
    entryCount = cm->map.cmap2->data[index1*4+1];
    idDelta = ((SHORT *)cm->map.cmap2->data)[index1*4+2];
    idRangeOffset = cm->map.cmap2->data[index1*4+3];

    if (cc[1] < firstCode)
      return -1;

    if (cc[1] >= firstCode+entryCount)
      return -1;
    index = cm->map.cmap2->glyphIdArray[idRangeOffset/2+cc[1]-firstCode]
            +idDelta;
  }
  if (index > f->profile->numglyphs)
  {
    Error_throw(error_invalid_index);
    return -1;
  }
  return f->indexToLocation[index];
}
