// 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

#ifndef TTGSUBTable_H
#define TTGSUBTable_H
#include "../../fx_freetype.h"
#include "../../../include/fxcrt/fx_basic.h"
#include "common.h"
class CFX_GlyphMap
{
public:
    CFX_GlyphMap();
    ~CFX_GlyphMap();
    void	SetAt(int key, int value);
    FX_BOOL	Lookup(int key, int &value);
protected:
    CFX_BinaryBuf	m_Buffer;
};
class CFX_CTTGSUBTable : public CFX_Object
{
public:
    CFX_CTTGSUBTable(void): loaded(false), m_bFeautureMapLoad(FALSE) {};
    CFX_CTTGSUBTable(FT_Bytes gsub): loaded(false), m_bFeautureMapLoad(FALSE)
    {
        LoadGSUBTable(gsub);
    }
    virtual ~CFX_CTTGSUBTable() {}
    bool IsOk(void) const
    {
        return loaded;
    }
    bool LoadGSUBTable(FT_Bytes gsub);
    bool GetVerticalGlyph(TT_uint32_t glyphnum, TT_uint32_t *vglyphnum);
private:
    struct tt_gsub_header {
        TT_uint32_t Version;
        TT_uint16_t ScriptList;
        TT_uint16_t FeatureList;
        TT_uint16_t LookupList;
    };
    struct TLangSys {
        TT_uint16_t LookupOrder;
        TT_uint16_t ReqFeatureIndex;
        TT_uint16_t FeatureCount;
        TT_uint16_t *FeatureIndex;
        TLangSys(): LookupOrder(0), ReqFeatureIndex(0), FeatureCount(0), FeatureIndex(NULL) {}
        ~TLangSys()
        {
            if(FeatureIndex) {
                delete[] FeatureIndex;
            }
        }
    private:
        TLangSys(const TLangSys&);
        TLangSys& operator=(const TLangSys&);
    };
    struct TLangSysRecord {
        TT_uint32_t LangSysTag;
        struct TLangSys LangSys;
        TLangSysRecord(): LangSysTag(0) {}
    private:
        TLangSysRecord(const TLangSysRecord&);
        TLangSysRecord& operator=(const TLangSysRecord&);
    };
    struct TScript {
        TT_uint16_t DefaultLangSys;
        TT_uint16_t LangSysCount;
        struct TLangSysRecord *LangSysRecord;
        TScript(): DefaultLangSys(0), LangSysCount(0), LangSysRecord(NULL) {}
        ~TScript()
        {
            if(LangSysRecord) {
                delete[] LangSysRecord;
            }
        }
    private:
        TScript(const TScript&);
        TScript& operator=(const TScript&);
    };
    struct TScriptRecord {
        TT_uint32_t ScriptTag;
        struct TScript Script;
        TScriptRecord(): ScriptTag(0) {}
    private:
        TScriptRecord(const TScriptRecord&);
        TScriptRecord& operator=(const TScriptRecord&);
    };
    struct TScriptList {
        TT_uint16_t ScriptCount;
        struct TScriptRecord *ScriptRecord;
        TScriptList(): ScriptCount(0), ScriptRecord(NULL) {}
        ~TScriptList()
        {
            if(ScriptRecord) {
                delete[] ScriptRecord;
            }
        }
    private:
        TScriptList(const TScriptList&);
        TScriptList& operator=(const TScriptList&);
    };
    struct TFeature {
        TT_uint16_t FeatureParams;
        int LookupCount;
        TT_uint16_t *LookupListIndex;
        TFeature(): FeatureParams(0), LookupCount(0), LookupListIndex(NULL) {}
        ~TFeature()
        {
            if(LookupListIndex) {
                delete[] LookupListIndex;
            }
        }
    private:
        TFeature(const TFeature&);
        TFeature& operator=(const TFeature&);
    };
    struct TFeatureRecord {
        TT_uint32_t FeatureTag;
        struct TFeature Feature;
        TFeatureRecord(): FeatureTag(0) {}
    private:
        TFeatureRecord(const TFeatureRecord&);
        TFeatureRecord& operator=(const TFeatureRecord&);
    };
    struct TFeatureList {
        int FeatureCount;
        struct TFeatureRecord *FeatureRecord;
        TFeatureList(): FeatureCount(0), FeatureRecord(NULL) {}
        ~TFeatureList()
        {
            if(FeatureRecord) {
                delete[] FeatureRecord;
            }
        }
    private:
        TFeatureList(const TFeatureList&);
        TFeatureList& operator=(const TFeatureList&);
    };
    enum TLookupFlag {
        LOOKUPFLAG_RightToLeft = 0x0001,
        LOOKUPFLAG_IgnoreBaseGlyphs = 0x0002,
        LOOKUPFLAG_IgnoreLigatures = 0x0004,
        LOOKUPFLAG_IgnoreMarks = 0x0008,
        LOOKUPFLAG_Reserved = 0x00F0,
        LOOKUPFLAG_MarkAttachmentType = 0xFF00,
    };
    struct TCoverageFormatBase {
        TT_uint16_t CoverageFormat;
        CFX_GlyphMap m_glyphMap;
        TCoverageFormatBase(): CoverageFormat(0) {}
        virtual ~TCoverageFormatBase() {}
    private:
        TCoverageFormatBase(const TCoverageFormatBase&);
        TCoverageFormatBase& operator=(const TCoverageFormatBase&);
    };
    struct TCoverageFormat1: public TCoverageFormatBase {
        TT_uint16_t GlyphCount;
        TT_uint16_t *GlyphArray;
        TCoverageFormat1(): GlyphCount(0), GlyphArray(NULL)
        {
            CoverageFormat = 1;
        }
        ~TCoverageFormat1()
        {
            if(GlyphArray) {
                delete[] GlyphArray;
            }
        }
    private:
        TCoverageFormat1(const TCoverageFormat1&);
        TCoverageFormat1& operator=(const TCoverageFormat1&);
    };
    struct TRangeRecord {
        TT_uint16_t Start;
        TT_uint16_t End;
        TT_uint16_t StartCoverageIndex;
        TRangeRecord(): Start(0), End(0), StartCoverageIndex(0) {}
        friend bool operator > (const TRangeRecord &r1, const TRangeRecord &r2)
        {
            return r1.Start > r2.Start;
        }
    private:
        TRangeRecord(const TRangeRecord&);
    };
    struct TCoverageFormat2: public TCoverageFormatBase {
        TT_uint16_t RangeCount;
        struct TRangeRecord *RangeRecord;
        TCoverageFormat2(): RangeCount(0), RangeRecord(NULL)
        {
            CoverageFormat = 2;
        }
        ~TCoverageFormat2()
        {
            if(RangeRecord) {
                delete[] RangeRecord;
            }
        }
    private:
        TCoverageFormat2(const TCoverageFormat2&);
        TCoverageFormat2& operator=(const TCoverageFormat2&);
    };
    struct TClassDefFormatBase {
        TT_uint16_t ClassFormat;
        TClassDefFormatBase(): ClassFormat(0) {}
        virtual ~TClassDefFormatBase() {}
    private:
        TClassDefFormatBase(const TClassDefFormatBase&);
        TClassDefFormatBase& operator=(const TClassDefFormatBase&);
    };
    struct TClassDefFormat1: public TClassDefFormatBase {
        TT_uint16_t StartGlyph;
        TT_uint16_t GlyphCount;
        TT_uint16_t *ClassValueArray;
        TClassDefFormat1(): StartGlyph(0), GlyphCount(0), ClassValueArray(NULL)
        {
            ClassFormat = 1;
        }
        ~TClassDefFormat1()
        {
            if(ClassValueArray) {
                delete[] ClassValueArray;
            }
        }
    private:
        TClassDefFormat1(const TClassDefFormat1&);
        TClassDefFormat1& operator=(const TClassDefFormat1&);
    };
    struct TClassRangeRecord {
        TT_uint16_t Start;
        TT_uint16_t End;
        TT_uint16_t Class;
        TClassRangeRecord(): Start(0), End(0), Class(0) {}
    private:
        TClassRangeRecord(const TClassRangeRecord&);
        TClassRangeRecord& operator=(const TClassRangeRecord&);
    };
    struct TClassDefFormat2: public TClassDefFormatBase {
        TT_uint16_t ClassRangeCount;
        struct TClassRangeRecord *ClassRangeRecord;
        TClassDefFormat2(): ClassRangeCount(0), ClassRangeRecord(NULL)
        {
            ClassFormat = 2;
        }
        ~TClassDefFormat2()
        {
            if(ClassRangeRecord) {
                delete[] ClassRangeRecord;
            }
        }
    private:
        TClassDefFormat2(const TClassDefFormat2&);
        TClassDefFormat2& operator=(const TClassDefFormat2&);
    };
    struct TDevice {
        TT_uint16_t StartSize;
        TT_uint16_t EndSize;
        TT_uint16_t DeltaFormat;
        TDevice(): StartSize(0), EndSize(0), DeltaFormat(0) {}
    private:
        TDevice(const TDevice&);
        TDevice& operator=(const TDevice&);
    };
    struct TSubTableBase {
        TT_uint16_t SubstFormat;
        TSubTableBase(): SubstFormat(0) {}
        virtual ~TSubTableBase() {}
    private:
        TSubTableBase(const TSubTableBase&);
        TSubTableBase& operator=(const TSubTableBase&);
    };
    struct TSingleSubstFormat1: public TSubTableBase {
        TCoverageFormatBase *Coverage;
        TT_int16_t DeltaGlyphID;
        TSingleSubstFormat1(): DeltaGlyphID(0), Coverage(NULL)
        {
            SubstFormat = 1;
        }
        ~TSingleSubstFormat1()
        {
            if(Coverage) {
                delete Coverage;
            }
        }
    private:
        TSingleSubstFormat1(const TSingleSubstFormat1&);
        TSingleSubstFormat1& operator=(const TSingleSubstFormat1&);
    };
    struct TSingleSubstFormat2: public TSubTableBase {
        TCoverageFormatBase *Coverage;
        TT_uint16_t GlyphCount;
        TT_uint16_t *Substitute;
        TSingleSubstFormat2(): Coverage(NULL), GlyphCount(0), Substitute(NULL)
        {
            SubstFormat = 2;
        }
        ~TSingleSubstFormat2()
        {
            if(Coverage) {
                delete Coverage;
            }
            if(Substitute) {
                delete[] Substitute;
            }
        }
    private:
        TSingleSubstFormat2(const TSingleSubstFormat2&);
        TSingleSubstFormat2& operator=(const TSingleSubstFormat2&);
    };
    struct TLookup {
        TT_uint16_t LookupType;
        TT_uint16_t LookupFlag;
        TT_uint16_t SubTableCount;
        struct TSubTableBase **SubTable;
        TLookup(): LookupType(0), LookupFlag(0), SubTableCount(0), SubTable(NULL) {}
        ~TLookup()
        {
            if(SubTableCount > 0 && SubTable != NULL) {
                for(int i = 0; i < SubTableCount; i++) {
                    delete SubTable[i];
                }
                delete[] SubTable;
            }
        }
    private:
        TLookup(const TLookup&);
        TLookup& operator=(const TLookup&);
    };
    struct TLookupList {
        int LookupCount;
        struct TLookup *Lookup;
        TLookupList(): LookupCount(0), Lookup(NULL) {}
        ~TLookupList()
        {
            if(Lookup) {
                delete[] Lookup;
            }
        }
    private:
        TLookupList(const TLookupList&);
        TLookupList& operator=(const TLookupList&);
    };
    bool Parse(
        FT_Bytes scriptlist,
        FT_Bytes featurelist,
        FT_Bytes lookuplist);
    void ParseScriptList(FT_Bytes raw, TScriptList *rec);
    void ParseScript(FT_Bytes raw, TScript *rec);
    void ParseLangSys(FT_Bytes raw, TLangSys *rec);
    void ParseFeatureList(FT_Bytes raw, TFeatureList *rec);
    void ParseFeature(FT_Bytes raw, TFeature *rec);
    void ParseLookupList(FT_Bytes raw, TLookupList *rec);
    void ParseLookup(FT_Bytes raw, TLookup *rec);
    void ParseCoverage(FT_Bytes raw, TCoverageFormatBase **rec);
    void ParseCoverageFormat1(FT_Bytes raw, TCoverageFormat1 *rec);
    void ParseCoverageFormat2(FT_Bytes raw, TCoverageFormat2 *rec);
    void ParseSingleSubst(FT_Bytes raw, TSubTableBase **rec);
    void ParseSingleSubstFormat1(FT_Bytes raw, TSingleSubstFormat1 *rec);
    void ParseSingleSubstFormat2(FT_Bytes raw, TSingleSubstFormat2 *rec);
    bool GetVerticalGlyphSub(
        TT_uint32_t glyphnum,
        TT_uint32_t *vglyphnum,
        struct TFeature *Feature);
    bool GetVerticalGlyphSub2(
        TT_uint32_t glyphnum,
        TT_uint32_t *vglyphnum,
        struct TLookup *Lookup);
    int GetCoverageIndex(struct TCoverageFormatBase *Coverage, TT_uint32_t g);
    TT_uint8_t GetUInt8(FT_Bytes& p) const
    {
        TT_uint8_t ret = p[0];
        p += 1;
        return ret;
    }
    TT_int16_t GetInt16(FT_Bytes& p) const
    {
        TT_uint16_t ret = p[0] << 8 | p[1];
        p += 2;
        return *(TT_int16_t*)&ret;
    }
    TT_uint16_t GetUInt16(FT_Bytes& p) const
    {
        TT_uint16_t ret = p[0] << 8 | p[1];
        p += 2;
        return ret;
    }
    TT_int32_t GetInt32(FT_Bytes& p) const
    {
        TT_uint32_t ret = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
        p += 4;
        return *(TT_int32_t*)&ret;
    }
    TT_uint32_t GetUInt32(FT_Bytes& p) const
    {
        TT_uint32_t ret = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
        p += 4;
        return ret;
    }
    CFX_CMapDWordToDWord m_featureMap;
    FX_BOOL	m_bFeautureMapLoad;
    bool loaded;
    struct tt_gsub_header header;
    struct TScriptList ScriptList;
    struct TFeatureList FeatureList;
    struct TLookupList LookupList;
};
class CFX_GSUBTable FX_FINAL : public IFX_GSUBTable, public CFX_Object
{
public:
    virtual void	Release()
    {
        delete this;
    }
    virtual FX_BOOL GetVerticalGlyph(FX_DWORD glyphnum, FX_DWORD* vglyphnum);
    CFX_CTTGSUBTable m_GsubImp;
};
#endif
