// Copyright (C) 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/***************************************************************************
*
*   Copyright (C) 1998-2002, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
************************************************************************/

#include <stdio.h>

#include "LETypes.h"
#include "FontObject.h"
#include "LESwaps.h"

FontObject::FontObject(char *fileName)
  : directory(NULL), numTables(0), searchRange(0),entrySelector(0),
    cmapTable(NULL), cmSegCount(0), cmSearchRange(0), cmEntrySelector(0),
    cmEndCodes(NULL), cmStartCodes(NULL), cmIdDelta(0), cmIdRangeOffset(0),
    headTable(NULL), hmtxTable(NULL), numGlyphs(0), numOfLongHorMetrics(0), file(NULL)
{
    file = fopen(fileName, "rb");

    if (file == NULL) {
        printf("?? Couldn't open %s", fileName);
        return;
    }

    SFNTDirectory tempDir;

    fread(&tempDir, sizeof tempDir, 1, file);

    numTables       = SWAPW(tempDir.numTables);
    searchRange     = SWAPW(tempDir.searchRange) >> 4;
    entrySelector   = SWAPW(tempDir.entrySelector);
    rangeShift      = SWAPW(tempDir.rangeShift) >> 4;

    int dirSize = sizeof tempDir + ((numTables - ANY_NUMBER) * sizeof(DirectoryEntry));

    directory = (SFNTDirectory *) new char[dirSize];

    fseek(file, 0L, SEEK_SET);
    fread(directory, sizeof(char), dirSize, file);

    initUnicodeCMAP();
}

FontObject::~FontObject()
{
    fclose(file);
    delete[] directory;
    delete[] cmapTable;
    delete[] headTable;
    delete[] hmtxTable;
}

void FontObject::deleteTable(void *table)
{
    delete[] (char *) table;
}

DirectoryEntry *FontObject::findTable(LETag tag)
{
    le_uint16 table = 0;
    le_uint16 probe = 1 << entrySelector;

    if (SWAPL(directory->tableDirectory[rangeShift].tag) <= tag) {
        table = rangeShift;
    }

    while (probe > (1 << 0)) {
        probe >>= 1;

        if (SWAPL(directory->tableDirectory[table + probe].tag) <= tag) {
            table += probe;
        }
    }

    if (SWAPL(directory->tableDirectory[table].tag) == tag) {
        return &directory->tableDirectory[table];
    }

    return NULL;
}

void *FontObject::readTable(LETag tag, le_uint32 *length)
{
    DirectoryEntry *entry = findTable(tag);

    if (entry == NULL) {
        *length = 0;
        return NULL;
    }

    *length = SWAPL(entry->length);

    void *table = new char[*length];

    fseek(file, SWAPL(entry->offset), SEEK_SET);
    fread(table, sizeof(char), *length, file);

    return table;
}

CMAPEncodingSubtable *FontObject::findCMAP(le_uint16 platformID, le_uint16 platformSpecificID)
{
    LETag cmapTag = 0x636D6170; // 'cmap'

    if (cmapTable == NULL) {
        le_uint32 length;

        cmapTable = (CMAPTable *) readTable(cmapTag, &length);
    }

    if (cmapTable != NULL) {
        le_uint16 i;
        le_uint16 nSubtables = SWAPW(cmapTable->numberSubtables);


        for (i = 0; i < nSubtables; i += 1) {
            CMAPEncodingSubtableHeader *esh = &cmapTable->encodingSubtableHeaders[i];

            if (SWAPW(esh->platformID) == platformID &&
                SWAPW(esh->platformSpecificID) == platformSpecificID) {
                return (CMAPEncodingSubtable *) ((char *) cmapTable + SWAPL(esh->encodingOffset));
            }
        }
    }

    return NULL;
}

void FontObject::initUnicodeCMAP()
{
    CMAPEncodingSubtable *encodingSubtable = findCMAP(3, 1);

    if (encodingSubtable == 0 ||
        SWAPW(encodingSubtable->format) != 4) {
        printf("Can't find unicode 'cmap'");
        return;
    }

    CMAPFormat4Encoding *header = (CMAPFormat4Encoding *) encodingSubtable;

    cmSegCount = SWAPW(header->segCountX2) / 2;
    cmSearchRange = SWAPW(header->searchRange);
    cmEntrySelector = SWAPW(header->entrySelector);
    cmRangeShift = SWAPW(header->rangeShift) / 2;
    cmEndCodes = &header->endCodes[0];
    cmStartCodes = &header->endCodes[cmSegCount + 1]; // + 1 for reservedPad...
    cmIdDelta = &cmStartCodes[cmSegCount];
    cmIdRangeOffset = &cmIdDelta[cmSegCount];
}

LEGlyphID FontObject::unicodeToGlyph(LEUnicode32 unicode32)
{
    if (unicode32 >= 0x10000) {
        return 0;
    }

    LEUnicode16 unicode = (LEUnicode16) unicode32;
    le_uint16 index = 0;
    le_uint16 probe = 1 << cmEntrySelector;
    LEGlyphID result = 0;

    if (SWAPW(cmStartCodes[cmRangeShift]) <= unicode) {
        index = cmRangeShift;
    }

    while (probe > (1 << 0)) {
        probe >>= 1;

        if (SWAPW(cmStartCodes[index + probe]) <= unicode) {
            index += probe;
        }
    }

    if (unicode >= SWAPW(cmStartCodes[index]) && unicode <= SWAPW(cmEndCodes[index])) {
        if (cmIdRangeOffset[index] == 0) {
            result = (LEGlyphID) unicode;
        } else {
            le_uint16 offset = unicode - SWAPW(cmStartCodes[index]);
            le_uint16 rangeOffset = SWAPW(cmIdRangeOffset[index]);
            le_uint16 *glyphIndexTable = (le_uint16 *) ((char *) &cmIdRangeOffset[index] + rangeOffset);

            result = SWAPW(glyphIndexTable[offset]);
        }

        result += SWAPW(cmIdDelta[index]);
    } else {
        result = 0;
    }

    return result;
}

le_uint16 FontObject::getUnitsPerEM()
{
    if (headTable == NULL) {
        LETag headTag = 0x68656164; // 'head'
        le_uint32 length;

        headTable = (HEADTable *) readTable(headTag, &length);
    }

    return SWAPW(headTable->unitsPerEm);
}

le_uint16 FontObject::getGlyphAdvance(LEGlyphID glyph)
{
    if (hmtxTable == NULL) {
        LETag maxpTag = 0x6D617870; // 'maxp'
        LETag hheaTag = 0x68686561; // 'hhea'
        LETag hmtxTag = 0x686D7478; // 'hmtx'
        le_uint32 length;
        HHEATable *hheaTable;
        MAXPTable *maxpTable = (MAXPTable *) readTable(maxpTag, &length);

        numGlyphs = SWAPW(maxpTable->numGlyphs);
        deleteTable(maxpTable);

        hheaTable = (HHEATable *) readTable(hheaTag, &length);
        numOfLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
        deleteTable(hheaTable);

        hmtxTable = (HMTXTable *) readTable(hmtxTag, &length);
    }

    le_uint16 index = glyph;

    if (glyph >= numGlyphs) {
        return 0;
    }

    if (glyph >= numOfLongHorMetrics) {
        index = numOfLongHorMetrics - 1;
    }

    return SWAPW(hmtxTable->hMetrics[index].advanceWidth);
}


