| // 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): 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() |
| { |
| 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() FX_OVERRIDE |
| { |
| delete this; |
| } |
| virtual FX_BOOL GetVerticalGlyph(FX_DWORD glyphnum, FX_DWORD* vglyphnum) FX_OVERRIDE; |
| CFX_CTTGSUBTable m_GsubImp; |
| }; |
| #endif |