// 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/fxge/include/fx_font.h"
#include "core/fxge/include/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;
};

#endif  // CORE_FPDFAPI_FPDF_FONT_TTGSUBTABLE_H_
