// 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_FPDFAPI_FPDF_FONT_TTGSUBTABLE_H_
#define CORE_FPDFAPI_FPDF_FONT_TTGSUBTABLE_H_

#include <stdint.h>

#include <map>

#include "core/fxcrt/include/fx_basic.h"
#include "core/include/fxge/fx_font.h"
#include "core/include/fxge/fx_freetype.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(uint32_t glyphnum, uint32_t* vglyphnum);

 private:
  struct tt_gsub_header {
    uint32_t Version;
    uint16_t ScriptList;
    uint16_t FeatureList;
    uint16_t LookupList;
  };
  struct TLangSys {
    uint16_t LookupOrder;
    uint16_t ReqFeatureIndex;
    uint16_t FeatureCount;
    uint16_t* FeatureIndex;
    TLangSys()
        : LookupOrder(0),
          ReqFeatureIndex(0),
          FeatureCount(0),
          FeatureIndex(NULL) {}
    ~TLangSys() { delete[] FeatureIndex; }

   private:
    TLangSys(const TLangSys&);
    TLangSys& operator=(const TLangSys&);
  };
  struct TLangSysRecord {
    uint32_t LangSysTag;
    struct TLangSys LangSys;
    TLangSysRecord() : LangSysTag(0) {}

   private:
    TLangSysRecord(const TLangSysRecord&);
    TLangSysRecord& operator=(const TLangSysRecord&);
  };
  struct TScript {
    uint16_t DefaultLangSys;
    uint16_t LangSysCount;
    struct TLangSysRecord* LangSysRecord;
    TScript() : DefaultLangSys(0), LangSysCount(0), LangSysRecord(NULL) {}
    ~TScript() { delete[] LangSysRecord; }

   private:
    TScript(const TScript&);
    TScript& operator=(const TScript&);
  };
  struct TScriptRecord {
    uint32_t ScriptTag;
    struct TScript Script;
    TScriptRecord() : ScriptTag(0) {}

   private:
    TScriptRecord(const TScriptRecord&);
    TScriptRecord& operator=(const TScriptRecord&);
  };
  struct TScriptList {
    uint16_t ScriptCount;
    struct TScriptRecord* ScriptRecord;
    TScriptList() : ScriptCount(0), ScriptRecord(NULL) {}
    ~TScriptList() { delete[] ScriptRecord; }

   private:
    TScriptList(const TScriptList&);
    TScriptList& operator=(const TScriptList&);
  };
  struct TFeature {
    uint16_t FeatureParams;
    int LookupCount;
    uint16_t* LookupListIndex;
    TFeature() : FeatureParams(0), LookupCount(0), LookupListIndex(NULL) {}
    ~TFeature() { delete[] LookupListIndex; }

   private:
    TFeature(const TFeature&);
    TFeature& operator=(const TFeature&);
  };
  struct TFeatureRecord {
    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() { 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 {
    uint16_t CoverageFormat;
    CFX_GlyphMap m_glyphMap;
    TCoverageFormatBase() : CoverageFormat(0) {}
    virtual ~TCoverageFormatBase() {}

   private:
    TCoverageFormatBase(const TCoverageFormatBase&);
    TCoverageFormatBase& operator=(const TCoverageFormatBase&);
  };
  struct TCoverageFormat1 : public TCoverageFormatBase {
    uint16_t GlyphCount;
    uint16_t* GlyphArray;
    TCoverageFormat1() : GlyphCount(0), GlyphArray(NULL) { CoverageFormat = 1; }
    ~TCoverageFormat1() override { delete[] GlyphArray; }

   private:
    TCoverageFormat1(const TCoverageFormat1&);
    TCoverageFormat1& operator=(const TCoverageFormat1&);
  };
  struct TRangeRecord {
    uint16_t Start;
    uint16_t End;
    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 {
    uint16_t RangeCount;
    struct TRangeRecord* RangeRecord;
    TCoverageFormat2() : RangeCount(0), RangeRecord(NULL) {
      CoverageFormat = 2;
    }
    ~TCoverageFormat2() override { delete[] RangeRecord; }

   private:
    TCoverageFormat2(const TCoverageFormat2&);
    TCoverageFormat2& operator=(const TCoverageFormat2&);
  };
  struct TClassDefFormatBase {
    uint16_t ClassFormat;
    TClassDefFormatBase() : ClassFormat(0) {}
    virtual ~TClassDefFormatBase() {}

   private:
    TClassDefFormatBase(const TClassDefFormatBase&);
    TClassDefFormatBase& operator=(const TClassDefFormatBase&);
  };
  struct TClassDefFormat1 : public TClassDefFormatBase {
    uint16_t StartGlyph;
    uint16_t GlyphCount;
    uint16_t* ClassValueArray;
    TClassDefFormat1() : StartGlyph(0), GlyphCount(0), ClassValueArray(NULL) {
      ClassFormat = 1;
    }
    ~TClassDefFormat1() override { delete[] ClassValueArray; }

   private:
    TClassDefFormat1(const TClassDefFormat1&);
    TClassDefFormat1& operator=(const TClassDefFormat1&);
  };
  struct TClassRangeRecord {
    uint16_t Start;
    uint16_t End;
    uint16_t Class;
    TClassRangeRecord() : Start(0), End(0), Class(0) {}

   private:
    TClassRangeRecord(const TClassRangeRecord&);
    TClassRangeRecord& operator=(const TClassRangeRecord&);
  };
  struct TClassDefFormat2 : public TClassDefFormatBase {
    uint16_t ClassRangeCount;
    struct TClassRangeRecord* ClassRangeRecord;
    TClassDefFormat2() : ClassRangeCount(0), ClassRangeRecord(NULL) {
      ClassFormat = 2;
    }
    ~TClassDefFormat2() override { delete[] ClassRangeRecord; }

   private:
    TClassDefFormat2(const TClassDefFormat2&);
    TClassDefFormat2& operator=(const TClassDefFormat2&);
  };
  struct TDevice {
    uint16_t StartSize;
    uint16_t EndSize;
    uint16_t DeltaFormat;
    TDevice() : StartSize(0), EndSize(0), DeltaFormat(0) {}

   private:
    TDevice(const TDevice&);
    TDevice& operator=(const TDevice&);
  };
  struct TSubTableBase {
    uint16_t SubstFormat;
    TSubTableBase() : SubstFormat(0) {}
    virtual ~TSubTableBase() {}

   private:
    TSubTableBase(const TSubTableBase&);
    TSubTableBase& operator=(const TSubTableBase&);
  };
  struct TSingleSubstFormat1 : public TSubTableBase {
    TCoverageFormatBase* Coverage;
    int16_t DeltaGlyphID;
    TSingleSubstFormat1() : Coverage(NULL), DeltaGlyphID(0) { SubstFormat = 1; }
    ~TSingleSubstFormat1() override { delete Coverage; }

   private:
    TSingleSubstFormat1(const TSingleSubstFormat1&);
    TSingleSubstFormat1& operator=(const TSingleSubstFormat1&);
  };
  struct TSingleSubstFormat2 : public TSubTableBase {
    TCoverageFormatBase* Coverage;
    uint16_t GlyphCount;
    uint16_t* Substitute;
    TSingleSubstFormat2() : Coverage(NULL), GlyphCount(0), Substitute(NULL) {
      SubstFormat = 2;
    }
    ~TSingleSubstFormat2() override {
      delete Coverage;
      delete[] Substitute;
    }

   private:
    TSingleSubstFormat2(const TSingleSubstFormat2&);
    TSingleSubstFormat2& operator=(const TSingleSubstFormat2&);
  };
  struct TLookup {
    uint16_t LookupType;
    uint16_t LookupFlag;
    uint16_t SubTableCount;
    struct TSubTableBase** SubTable;
    TLookup()
        : LookupType(0), LookupFlag(0), SubTableCount(0), SubTable(NULL) {}
    ~TLookup() {
      if (SubTable) {
        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() { 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(uint32_t glyphnum,
                           uint32_t* vglyphnum,
                           struct TFeature* Feature);
  bool GetVerticalGlyphSub2(uint32_t glyphnum,
                            uint32_t* vglyphnum,
                            struct TLookup* Lookup);
  int GetCoverageIndex(struct TCoverageFormatBase* Coverage, uint32_t g);
  uint8_t GetUInt8(FT_Bytes& p) const {
    uint8_t ret = p[0];
    p += 1;
    return ret;
  }
  int16_t GetInt16(FT_Bytes& p) const {
    uint16_t ret = p[0] << 8 | p[1];
    p += 2;
    return *(int16_t*)&ret;
  }
  uint16_t GetUInt16(FT_Bytes& p) const {
    uint16_t ret = p[0] << 8 | p[1];
    p += 2;
    return ret;
  }
  int32_t GetInt32(FT_Bytes& p) const {
    uint32_t ret = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
    p += 4;
    return *(int32_t*)&ret;
  }
  uint32_t GetUInt32(FT_Bytes& p) const {
    uint32_t ret = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
    p += 4;
    return ret;
  }
  std::map<uint32_t, uint32_t> 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 {}
  FX_BOOL GetVerticalGlyph(uint32_t glyphnum, uint32_t* vglyphnum) override;

  CFX_CTTGSUBTable m_GsubImp;
};

#endif  // CORE_FPDFAPI_FPDF_FONT_TTGSUBTABLE_H_
