// 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 CORE_SRC_FPDFAPI_FPDF_FONT_TTGSUBTABLE_H_
#define CORE_SRC_FPDFAPI_FPDF_FONT_TTGSUBTABLE_H_

#include "../../../include/fxge/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_CTTGSUBTable(void): m_bFeautureMapLoad(FALSE), loaded(false) {};
    CFX_CTTGSUBTable(FT_Bytes gsub): m_bFeautureMapLoad(FALSE), loaded(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(): Coverage(NULL), DeltaGlyphID(0)
        {
            SubstFormat = 1;
        }
        ~TSingleSubstFormat1()
        {
            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()
        {
            delete Coverage;
            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 final : public IFX_GSUBTable
{
public:
    ~CFX_GSUBTable() override {}
    virtual FX_BOOL GetVerticalGlyph(FX_DWORD glyphnum, FX_DWORD* vglyphnum) override;

    CFX_CTTGSUBTable m_GsubImp;
};

#endif  // CORE_SRC_FPDFAPI_FPDF_FONT_TTGSUBTABLE_H_
