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