blob: a1f0e8867af9d157faabcc9c1ffdd7820267750c [file] [log] [blame]
// 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