/*
 * @(#)KernTable.cpp	1.1 04/10/13
 *
 * (C) Copyright IBM Corp. 2004-2005 - All Rights Reserved
 *
 */

#include "KernTable.h"

#include "LESwaps.h"

#include <stdio.h>

#define DEBUG 0

U_NAMESPACE_BEGIN

struct PairInfo {
  le_uint32 key;   // sigh, MSVC compiler gags on union here
  le_int16  value; // fword, kern value in funits
};
#define KERN_PAIRINFO_SIZE 6

struct Subtable_0 {
  le_uint16 nPairs;
  le_uint16 searchRange;
  le_uint16 entrySelector;
  le_uint16 rangeShift;
};
#define KERN_SUBTABLE_0_HEADER_SIZE 8

// Kern table version 0 only
struct SubtableHeader {
  le_uint16 version;
  le_uint16 length;
  le_uint16 coverage;
};
#define KERN_SUBTABLE_HEADER_SIZE 6

// Version 0 only, version 1 has different layout
struct KernTableHeader {
  le_uint16 version;
  le_uint16 nTables;
};
#define KERN_TABLE_HEADER_SIZE 4

#define COVERAGE_HORIZONTAL 0x1
#define COVERAGE_MINIMUM 0x2
#define COVERAGE_CROSS 0x4
#define COVERAGE_OVERRIDE 0x8

KernTable::KernTable(const LEFontInstance* font, const void* tableData) 
  : pairs(0), font(font)
{
  const KernTableHeader* header = (const KernTableHeader*)tableData;
  if (header == 0) {
#if DEBUG
    fprintf(stderr, "no kern data\n");
    fflush(stderr);
#endif
    return;
  }

#if DEBUG
  // dump first 32 bytes of header
  for (int i = 0; i < 64; ++i) {
    fprintf(stderr, "%0.2x ", ((const char*)tableData)[i]&0xff);
    if (((i+1)&0xf) == 0) {
      fprintf(stderr, "\n");
    } else if (((i+1)&0x7) == 0) {
      fprintf(stderr, "  ");
    }
  }
  fflush(stderr);
#endif

  if (header->version == 0 && SWAPW(header->nTables) > 0) {
    const SubtableHeader* subhead = (const SubtableHeader*)((char*)tableData + KERN_TABLE_HEADER_SIZE);
    if (subhead->version == 0) {
      coverage = SWAPW(subhead->coverage);
      if (coverage & COVERAGE_HORIZONTAL) { // only handle horizontal kerning
	const Subtable_0* table = (const Subtable_0*)((char*)subhead + KERN_SUBTABLE_HEADER_SIZE);
	nPairs = SWAPW(table->nPairs);
	searchRange = SWAPW(table->searchRange);
	entrySelector = SWAPW(table->entrySelector);
	rangeShift = SWAPW(table->rangeShift);
	pairs = (const PairInfo*)((char*)table + KERN_SUBTABLE_0_HEADER_SIZE);

#if DEBUG
	fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairs);
	fprintf(stderr, "  searchRange: %d entrySelector: %d rangeShift: %d\n", searchRange, entrySelector, rangeShift);
	fflush(stderr);

	{
	  // dump part of the pair list
	  char ids[256];
	  for (int i = 256; --i >= 0;) {
	    LEGlyphID id = font->mapCharToGlyph(i);
	    if (id < 256) {
	      ids[id] = (char)i;
	    }
	  }

	  const PairInfo* p = pairs;
	  for (i = 0; i < nPairs; ++i, p = (const PairInfo*)((char*)p+KERN_PAIRINFO_SIZE)) {
  	    le_uint32 k = SWAPL(p->key);
	    le_uint16 left = (k >> 16) & 0xffff;
	    le_uint16 right = k & 0xffff;
	    if (left < 256 && right < 256) {
	      char c = ids[left];
	      if (c > 0x20 && c < 0x7f) {
		fprintf(stderr, "%c/", c & 0xff);
	      } else {
		fprintf(stderr, "%0.2x/", c & 0xff);
	      }
	      c = ids[right];
	      if (c > 0x20 && c < 0x7f) {
		fprintf(stderr, "%c ", c & 0xff);
	      } else {
		fprintf(stderr, "%0.2x ", c & 0xff);
	      }
	    }
	  }
	  fflush(stderr);
	}
#endif
      }
    }
  }
}
  

/*
 * Process the glyph positions.  The positions array has two floats for each
 * glyph, plus a trailing pair to mark the end of the last glyph.
 */
//void KernTable::process(const LEGlyphID glyphs[], float* positions, le_int32 glyphCount) 
void KernTable::process(LEGlyphStorage& storage) 
{
  if (pairs) {
    LEErrorCode success = LE_NO_ERROR;

    le_uint32 key = storage[0]; // no need to mask off high bits
    float adjust = 0;
    for (int i = 1, e = storage.getGlyphCount(); i < e; ++i) {
      key = key << 16 | (storage[i] & 0xffff);

      // argh, to do a binary search, we need to have the pair list in sorted order
      // but it is not in sorted order on win32 platforms because of the endianness difference
      // so either I have to swap the element each time I examine it, or I have to swap
      // all the elements ahead of time and store them in the font

      const PairInfo* p = pairs;
      const PairInfo* tp = (const PairInfo*)((char*)p + rangeShift);
      if (key > SWAPL(tp->key)) {
	p = tp;
      }

#if DEBUG
      fprintf(stderr, "binary search for %0.8x\n", key);
      fflush(stderr);
#endif

      le_uint32 probe = searchRange;
      while (probe > KERN_PAIRINFO_SIZE) {
        probe >>= 1;
        tp = (const PairInfo*)((char*)p + probe);
	le_uint32 tkey = SWAPL(tp->key);
#if DEBUG
	fprintf(stdout, "   %.3d (%0.8x)\n", ((char*)tp - (char*)pairs)/KERN_PAIRINFO_SIZE, tkey);
	fflush(stdout);
#endif
        if (tkey <= key) {
	  if (tkey == key) {
	    le_int16 value = SWAPW(tp->value);
#if DEBUG
	    fprintf(stdout, "binary found kerning pair %x:%x at %d, value: 0x%x (%g)\n", 
		    storage[i-1], storage[i], i, value & 0xffff, font->xUnitsToPoints(value));
	    fflush(stdout);
#endif
	    adjust += font->xUnitsToPoints(value);
	    break;
	  }
	  p = tp;
        }
      }

      storage.adjustPosition(i, adjust, 0, success);
    }
    storage.adjustPosition(storage.getGlyphCount(), adjust, 0, success);
  }
}

U_NAMESPACE_END

