// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "../../../../third_party/base/nonstd_unique_ptr.h"
#include "../../../include/fxge/fx_ge.h"
#include "../../../include/fxge/fx_freetype.h"
#include "ttgsubtable.h"

CFX_GlyphMap::CFX_GlyphMap()
{
}
CFX_GlyphMap::~CFX_GlyphMap()
{
}
extern "C" {
    static int _CompareInt(const void* p1, const void* p2)
    {
        return (*(FX_DWORD*)p1) - (*(FX_DWORD*)p2);
    }
};
struct _IntPair {
    int32_t key;
    int32_t value;
};
void CFX_GlyphMap::SetAt(int key, int value)
{
    FX_DWORD count = m_Buffer.GetSize() / sizeof(_IntPair);
    _IntPair* buf = (_IntPair*)m_Buffer.GetBuffer();
    _IntPair pair = {key, value};
    if (count == 0 || key > buf[count - 1].key) {
        m_Buffer.AppendBlock(&pair, sizeof(_IntPair));
        return;
    }
    int low = 0, high = count - 1;
    while (low <= high) {
        int mid = (low + high) / 2;
        if (buf[mid].key < key) {
            low = mid + 1;
        } else if (buf[mid].key > key) {
            high = mid - 1;
        } else {
            buf[mid].value = value;
            return;
        }
    }
    m_Buffer.InsertBlock(low * sizeof(_IntPair), &pair, sizeof(_IntPair));
}
bool CFX_GlyphMap::Lookup(int key, int &value)
{
    void* pResult = FXSYS_bsearch(&key, m_Buffer.GetBuffer(), m_Buffer.GetSize() / sizeof(_IntPair),
                                      sizeof(_IntPair), _CompareInt);
    if (pResult == NULL) {
        return false;
    }
    value = ((FX_DWORD*)pResult)[1];
    return true;
}
bool CFX_CTTGSUBTable::LoadGSUBTable(FT_Bytes gsub)
{
    header.Version = gsub[0] << 24 | gsub[1] << 16 | gsub[2] << 8 | gsub[3];
    if(header.Version != 0x00010000) {
        return false;
    }
    header.ScriptList  = gsub[4] << 8 | gsub[5];
    header.FeatureList = gsub[6] << 8 | gsub[7];
    header.LookupList  = gsub[8] << 8 | gsub[9];
    return Parse(
               &gsub[header.ScriptList],
               &gsub[header.FeatureList],
               &gsub[header.LookupList]);
}
bool CFX_CTTGSUBTable::GetVerticalGlyph(TT_uint32_t glyphnum, TT_uint32_t *vglyphnum)
{
    TT_uint32_t tag[] = {
        (TT_uint8_t)'v' << 24 |
        (TT_uint8_t)'r' << 16 |
        (TT_uint8_t)'t' <<  8 |
        (TT_uint8_t)'2',
        (TT_uint8_t)'v' << 24 |
        (TT_uint8_t)'e' << 16 |
        (TT_uint8_t)'r' <<  8 |
        (TT_uint8_t)'t',
    };
    if (!m_bFeautureMapLoad) {
        for (int i = 0; i < ScriptList.ScriptCount; i++) {
            for (int j = 0; j <	(ScriptList.ScriptRecord + i)->Script.LangSysCount; ++j) {
                for (int k = 0; k < ((ScriptList.ScriptRecord + i)->Script.LangSysRecord + j)->LangSys.FeatureCount; ++k) {
                    FX_DWORD index = *(((ScriptList.ScriptRecord + i)->Script.LangSysRecord + j)->LangSys.FeatureIndex + k);
                    if (FeatureList.FeatureRecord[index].FeatureTag == tag[0] || FeatureList.FeatureRecord[index].FeatureTag == tag[1]) {
                        FX_DWORD value;
                        if (!m_featureMap.Lookup(index, value)) {
                            m_featureMap.SetAt(index, index);
                        }
                    }
                }
            }
        }
        if (!m_featureMap.GetStartPosition()) {
            for (int i = 0; i < FeatureList.FeatureCount; i ++) {
                if (FeatureList.FeatureRecord[i].FeatureTag == tag[0] || FeatureList.FeatureRecord[i].FeatureTag == tag[1]) {
                    FX_DWORD value;
                    if (!m_featureMap.Lookup(i, value)) {
                        m_featureMap.SetAt(i, i);
                    }
                }
            }
        }
        m_bFeautureMapLoad = true;
    }
    FX_POSITION pos = m_featureMap.GetStartPosition();
    while (pos) {
        FX_DWORD index, value;
        m_featureMap.GetNextAssoc(pos, index, value);
        if(GetVerticalGlyphSub(glyphnum, vglyphnum,	&FeatureList.FeatureRecord[value].Feature)) {
            return true;
        }
    }
    return false;
}
bool CFX_CTTGSUBTable::GetVerticalGlyphSub(
    TT_uint32_t glyphnum,
    TT_uint32_t *vglyphnum,
    struct TFeature *Feature)
{
    for(int i = 0; i < Feature->LookupCount; i++) {
        int index = Feature->LookupListIndex[i];
        if(index < 0 || LookupList.LookupCount < index) {
            continue;
        }
        if(LookupList.Lookup[index].LookupType == 1) {
            if(GetVerticalGlyphSub2(
                        glyphnum,
                        vglyphnum,
                        &LookupList.Lookup[index])) {
                return true;
            }
        }
    }
    return false;
}
bool CFX_CTTGSUBTable::GetVerticalGlyphSub2(
    TT_uint32_t glyphnum,
    TT_uint32_t *vglyphnum,
    struct TLookup *Lookup)
{
    for(int i = 0; i < Lookup->SubTableCount; i++) {
        switch(Lookup->SubTable[i]->SubstFormat) {
            case 1: {
                    TSingleSubstFormat1 *tbl1 = (TSingleSubstFormat1*)Lookup->SubTable[i];
                    if(GetCoverageIndex(tbl1->Coverage, glyphnum) >= 0) {
                        *vglyphnum = glyphnum + tbl1->DeltaGlyphID;
                        return true;
                    }
                    break;
                }
            case 2: {
                    TSingleSubstFormat2 *tbl2 = (TSingleSubstFormat2*)Lookup->SubTable[i];
                    int index = -1;
                    index = GetCoverageIndex(tbl2->Coverage, glyphnum);
                    if(0 <= index && index < tbl2->GlyphCount) {
                        *vglyphnum = tbl2->Substitute[index];
                        return true;
                    }
                    break;
                }
        }
    }
    return false;
}
int CFX_CTTGSUBTable::GetCoverageIndex(struct TCoverageFormatBase *Coverage, TT_uint32_t g)
{
    int i = 0;
    if(Coverage == NULL) {
        return -1;
    }
    switch(Coverage->CoverageFormat) {
        case 1: {
                TCoverageFormat1 *c1 = (TCoverageFormat1*)Coverage;
                for(i = 0; i < c1->GlyphCount; i++) {
                    if((TT_uint32_t)c1->GlyphArray[i] == g) {
                        return i;
                    }
                }
                return -1;
            }
        case 2: {
                TCoverageFormat2 *c2 = (TCoverageFormat2*)Coverage;
                for(i = 0; i < c2->RangeCount; i++) {
                    TT_uint32_t s = c2->RangeRecord[i].Start;
                    TT_uint32_t e = c2->RangeRecord[i].End;
                    TT_uint32_t si = c2->RangeRecord[i].StartCoverageIndex;
                    if (s <= g && g <= e) {
                        return si + g - s;
                    }
                }
                return -1;
            }
    }
    return -1;
}
bool CFX_CTTGSUBTable::Parse(
    FT_Bytes scriptlist,
    FT_Bytes featurelist,
    FT_Bytes lookuplist)
{
    ParseScriptList(scriptlist, &ScriptList);
    ParseFeatureList(featurelist, &FeatureList);
    ParseLookupList(lookuplist, &LookupList);
    return true;
}
void CFX_CTTGSUBTable::ParseScriptList(FT_Bytes raw, struct TScriptList *rec)
{
    int i;
    FT_Bytes sp = raw;
    rec->ScriptCount = GetUInt16(sp);
    if(rec->ScriptCount <= 0) {
        return;
    }
    rec->ScriptRecord = new struct TScriptRecord[rec->ScriptCount];
    for(i = 0; i < rec->ScriptCount; i++) {
        rec->ScriptRecord[i].ScriptTag = GetUInt32(sp);
        TT_uint16_t offset = GetUInt16(sp);
        ParseScript(
            &raw[offset],
            &rec->ScriptRecord[i].Script);
    }
}
void CFX_CTTGSUBTable::ParseScript(FT_Bytes raw, struct TScript *rec)
{
    int i;
    FT_Bytes sp = raw;
    rec->DefaultLangSys = GetUInt16(sp);
    rec->LangSysCount = GetUInt16(sp);
    if(rec->LangSysCount <= 0) {
        return;
    }
    rec->LangSysRecord = new struct TLangSysRecord[rec->LangSysCount];
    for(i = 0; i < rec->LangSysCount; i++) {
        rec->LangSysRecord[i].LangSysTag = GetUInt32(sp);
        TT_uint16_t offset = GetUInt16(sp);
        ParseLangSys(
            &raw[offset],
            &rec->LangSysRecord[i].LangSys);
    }
}
void CFX_CTTGSUBTable::ParseLangSys(FT_Bytes raw, struct TLangSys *rec)
{
    FT_Bytes sp = raw;
    rec->LookupOrder = GetUInt16(sp);
    rec->ReqFeatureIndex = GetUInt16(sp);
    rec->FeatureCount = GetUInt16(sp);
    if(rec->FeatureCount <= 0) {
        return;
    }
    rec->FeatureIndex = new TT_uint16_t[rec->FeatureCount];
    FXSYS_memset(rec->FeatureIndex, 0, sizeof(TT_uint16_t) * rec->FeatureCount);
    for (int i = 0; i < rec->FeatureCount; ++i) {
        rec->FeatureIndex[i] = GetUInt16(sp);
    }
}
void CFX_CTTGSUBTable::ParseFeatureList(FT_Bytes raw, TFeatureList *rec)
{
    int i;
    FT_Bytes sp = raw;
    rec->FeatureCount = GetUInt16(sp);
    if(rec->FeatureCount <= 0) {
        return;
    }
    rec->FeatureRecord = new struct TFeatureRecord[rec->FeatureCount];
    for(i = 0; i < rec->FeatureCount; i++) {
        rec->FeatureRecord[i].FeatureTag = GetUInt32(sp);
        TT_uint16_t offset = GetUInt16(sp);
        ParseFeature(
            &raw[offset],
            &rec->FeatureRecord[i].Feature);
    }
}
void CFX_CTTGSUBTable::ParseFeature(FT_Bytes raw, TFeature *rec)
{
    int i;
    FT_Bytes sp = raw;
    rec->FeatureParams = GetUInt16(sp);
    rec->LookupCount = GetUInt16(sp);
    if(rec->LookupCount <= 0) {
        return;
    }
    rec->LookupListIndex = new TT_uint16_t[rec->LookupCount];
    for(i = 0; i < rec->LookupCount; i++) {
        rec->LookupListIndex[i] = GetUInt16(sp);
    }
}
void CFX_CTTGSUBTable::ParseLookupList(FT_Bytes raw, TLookupList *rec)
{
    int i;
    FT_Bytes sp = raw;
    rec->LookupCount = GetUInt16(sp);
    if(rec->LookupCount <= 0) {
        return;
    }
    rec->Lookup = new struct TLookup[rec->LookupCount];
    for(i = 0; i < rec->LookupCount; i++) {
        TT_uint16_t offset = GetUInt16(sp);
        ParseLookup(
            &raw[offset],
            &rec->Lookup[i]);
    }
}
void CFX_CTTGSUBTable::ParseLookup(FT_Bytes raw, TLookup *rec)
{
    int i;
    FT_Bytes sp = raw;
    rec->LookupType = GetUInt16(sp);
    rec->LookupFlag = GetUInt16(sp);
    rec->SubTableCount = GetUInt16(sp);
    if(rec->SubTableCount <= 0) {
        return;
    }
    rec->SubTable = new struct TSubTableBase*[rec->SubTableCount];
    for(i = 0; i < rec->SubTableCount; i++) {
        rec->SubTable[i] = NULL;
    }
    if(rec->LookupType != 1) {
        return;
    }
    for(i = 0; i < rec->SubTableCount; i++) {
        TT_uint16_t offset = GetUInt16(sp);
        ParseSingleSubst(
            &raw[offset],
            &rec->SubTable[i]);
    }
}
void CFX_CTTGSUBTable::ParseCoverage(FT_Bytes raw, TCoverageFormatBase **rec)
{
    FT_Bytes sp = raw;
    TT_uint16_t Format = GetUInt16(sp);
    switch(Format) {
        case 1:
            *rec = new TCoverageFormat1();
            ParseCoverageFormat1(raw, (TCoverageFormat1*)*rec);
            break;
        case 2:
            *rec = new TCoverageFormat2();
            ParseCoverageFormat2(raw, (TCoverageFormat2*)*rec);
            break;
    }
}
void CFX_CTTGSUBTable::ParseCoverageFormat1(FT_Bytes raw, TCoverageFormat1 *rec)
{
    int i;
    FT_Bytes sp = raw;
    GetUInt16(sp);
    rec->GlyphCount = GetUInt16(sp);
    if(rec->GlyphCount <= 0) {
        return;
    }
    rec->GlyphArray = new TT_uint16_t[rec->GlyphCount];
    for(i = 0; i < rec->GlyphCount; i++) {
        rec->GlyphArray[i] = GetUInt16(sp);
    }
}
void CFX_CTTGSUBTable::ParseCoverageFormat2(FT_Bytes raw, TCoverageFormat2 *rec)
{
    int i;
    FT_Bytes sp = raw;
    GetUInt16(sp);
    rec->RangeCount = GetUInt16(sp);
    if(rec->RangeCount <= 0) {
        return;
    }
    rec->RangeRecord = new TRangeRecord[rec->RangeCount];
    for(i = 0; i < rec->RangeCount; i++) {
        rec->RangeRecord[i].Start = GetUInt16(sp);
        rec->RangeRecord[i].End = GetUInt16(sp);
        rec->RangeRecord[i].StartCoverageIndex = GetUInt16(sp);
    }
}
void CFX_CTTGSUBTable::ParseSingleSubst(FT_Bytes raw, TSubTableBase **rec)
{
    FT_Bytes sp = raw;
    TT_uint16_t Format = GetUInt16(sp);
    switch(Format) {
        case 1:
            *rec = new TSingleSubstFormat1();
            ParseSingleSubstFormat1(raw, (TSingleSubstFormat1*)*rec);
            break;
        case 2:
            *rec = new TSingleSubstFormat2();
            ParseSingleSubstFormat2(raw, (TSingleSubstFormat2*)*rec);
            break;
    }
}
void CFX_CTTGSUBTable::ParseSingleSubstFormat1(FT_Bytes raw, TSingleSubstFormat1 *rec)
{
    FT_Bytes sp = raw;
    GetUInt16(sp);
    TT_uint16_t offset = GetUInt16(sp);
    ParseCoverage(
        &raw[offset],
        &rec->Coverage);
    rec->DeltaGlyphID = GetInt16(sp);
}
void CFX_CTTGSUBTable::ParseSingleSubstFormat2(FT_Bytes raw, TSingleSubstFormat2 *rec)
{
    int i;
    FT_Bytes sp = raw;
    GetUInt16(sp);
    TT_uint16_t offset = GetUInt16(sp);
    ParseCoverage(
        &raw[offset],
        &rec->Coverage);
    rec->GlyphCount = GetUInt16(sp);
    if(rec->GlyphCount <= 0) {
        return;
    }
    rec->Substitute = new TT_uint16_t[rec->GlyphCount];
    for(i = 0; i < rec->GlyphCount; i++) {
        rec->Substitute[i] = GetUInt16(sp);
    }
}
bool CFX_GSUBTable::GetVerticalGlyph(FX_DWORD glyphnum, FX_DWORD* vglyphnum)
{
    return m_GsubImp.GetVerticalGlyph(glyphnum, vglyphnum);
}
// static
IFX_GSUBTable* IFX_GSUBTable::Create(CFX_Font* pFont)
{
    if (!pFont) {
        return NULL;
    }
    if (NULL == pFont->m_pGsubData) {
        unsigned long length = 0;
        int error = FXFT_Load_Sfnt_Table(pFont->m_Face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0, NULL, &length);
        if (!error) {
            pFont->m_pGsubData = (unsigned char*)FX_Alloc(uint8_t, length);
        }
        if (!pFont->m_pGsubData) {
            return NULL;
        }
    }
    int error = FXFT_Load_Sfnt_Table(pFont->m_Face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0, pFont->m_pGsubData, NULL);
    if (!error && pFont->m_pGsubData) {
        nonstd::unique_ptr<CFX_GSUBTable> pGsubTable(new CFX_GSUBTable);
        if (pGsubTable->m_GsubImp.LoadGSUBTable((FT_Bytes)pFont->m_pGsubData)) {
            return pGsubTable.release();
        }
    }
    return NULL;
}
