1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 PDFium Authors. All rights reserved.
2c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// found in the LICENSE file.
4c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
7c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#ifndef TTGSUBTable_H
8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#define TTGSUBTable_H
9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "../../fx_freetype.h"
10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "../../../include/fxcrt/fx_basic.h"
11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "common.h"
1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class CFX_GlyphMap
13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch{
14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochpublic:
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    CFX_GlyphMap();
16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ~CFX_GlyphMap();
17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    void	SetAt(int key, int value);
18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    FX_BOOL	Lookup(int key, int &value);
19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochprotected:
20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    CFX_BinaryBuf	m_Buffer;
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass CFX_CTTGSUBTable : public CFX_Object
23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch{
24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochpublic:
25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    CFX_CTTGSUBTable(void): loaded(false), m_bFeautureMapLoad(FALSE) {};
26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    CFX_CTTGSUBTable(FT_Bytes gsub): loaded(false), m_bFeautureMapLoad(FALSE)
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    {
28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        LoadGSUBTable(gsub);
29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    virtual ~CFX_CTTGSUBTable() {}
31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    bool IsOk(void) const
32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    {
33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        return loaded;
34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    bool LoadGSUBTable(FT_Bytes gsub);
36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    bool GetVerticalGlyph(TT_uint32_t glyphnum, TT_uint32_t *vglyphnum);
37private:
38    struct tt_gsub_header {
39        TT_uint32_t Version;
40        TT_uint16_t ScriptList;
41        TT_uint16_t FeatureList;
42        TT_uint16_t LookupList;
43    };
44    struct TLangSys {
45        TT_uint16_t LookupOrder;
46        TT_uint16_t ReqFeatureIndex;
47        TT_uint16_t FeatureCount;
48        TT_uint16_t *FeatureIndex;
49        TLangSys(): LookupOrder(0), ReqFeatureIndex(0), FeatureCount(0), FeatureIndex(NULL) {}
50        ~TLangSys()
51        {
52            if(FeatureIndex) {
53                delete[] FeatureIndex;
54            }
55        }
56    private:
57        TLangSys(const TLangSys&);
58        TLangSys& operator=(const TLangSys&);
59    };
60    struct TLangSysRecord {
61        TT_uint32_t LangSysTag;
62        struct TLangSys LangSys;
63        TLangSysRecord(): LangSysTag(0) {}
64    private:
65        TLangSysRecord(const TLangSysRecord&);
66        TLangSysRecord& operator=(const TLangSysRecord&);
67    };
68    struct TScript {
69        TT_uint16_t DefaultLangSys;
70        TT_uint16_t LangSysCount;
71        struct TLangSysRecord *LangSysRecord;
72        TScript(): DefaultLangSys(0), LangSysCount(0), LangSysRecord(NULL) {}
73        ~TScript()
74        {
75            if(LangSysRecord) {
76                delete[] LangSysRecord;
77            }
78        }
79    private:
80        TScript(const TScript&);
81        TScript& operator=(const TScript&);
82    };
83    struct TScriptRecord {
84        TT_uint32_t ScriptTag;
85        struct TScript Script;
86        TScriptRecord(): ScriptTag(0) {}
87    private:
88        TScriptRecord(const TScriptRecord&);
89        TScriptRecord& operator=(const TScriptRecord&);
90    };
91    struct TScriptList {
92        TT_uint16_t ScriptCount;
93        struct TScriptRecord *ScriptRecord;
94        TScriptList(): ScriptCount(0), ScriptRecord(NULL) {}
95        ~TScriptList()
96        {
97            if(ScriptRecord) {
98                delete[] ScriptRecord;
99            }
100        }
101    private:
102        TScriptList(const TScriptList&);
103        TScriptList& operator=(const TScriptList&);
104    };
105    struct TFeature {
106        TT_uint16_t FeatureParams;
107        int LookupCount;
108        TT_uint16_t *LookupListIndex;
109        TFeature(): FeatureParams(0), LookupCount(0), LookupListIndex(NULL) {}
110        ~TFeature()
111        {
112            if(LookupListIndex) {
113                delete[] LookupListIndex;
114            }
115        }
116    private:
117        TFeature(const TFeature&);
118        TFeature& operator=(const TFeature&);
119    };
120    struct TFeatureRecord {
121        TT_uint32_t FeatureTag;
122        struct TFeature Feature;
123        TFeatureRecord(): FeatureTag(0) {}
124    private:
125        TFeatureRecord(const TFeatureRecord&);
126        TFeatureRecord& operator=(const TFeatureRecord&);
127    };
128    struct TFeatureList {
129        int FeatureCount;
130        struct TFeatureRecord *FeatureRecord;
131        TFeatureList(): FeatureCount(0), FeatureRecord(NULL) {}
132        ~TFeatureList()
133        {
134            if(FeatureRecord) {
135                delete[] FeatureRecord;
136            }
137        }
138    private:
139        TFeatureList(const TFeatureList&);
140        TFeatureList& operator=(const TFeatureList&);
141    };
142    enum TLookupFlag {
143        LOOKUPFLAG_RightToLeft = 0x0001,
144        LOOKUPFLAG_IgnoreBaseGlyphs = 0x0002,
145        LOOKUPFLAG_IgnoreLigatures = 0x0004,
146        LOOKUPFLAG_IgnoreMarks = 0x0008,
147        LOOKUPFLAG_Reserved = 0x00F0,
148        LOOKUPFLAG_MarkAttachmentType = 0xFF00,
149    };
150    struct TCoverageFormatBase {
151        TT_uint16_t CoverageFormat;
152        CFX_GlyphMap m_glyphMap;
153        TCoverageFormatBase(): CoverageFormat(0) {}
154        virtual ~TCoverageFormatBase() {}
155    private:
156        TCoverageFormatBase(const TCoverageFormatBase&);
157        TCoverageFormatBase& operator=(const TCoverageFormatBase&);
158    };
159    struct TCoverageFormat1: public TCoverageFormatBase {
160        TT_uint16_t GlyphCount;
161        TT_uint16_t *GlyphArray;
162        TCoverageFormat1(): GlyphCount(0), GlyphArray(NULL)
163        {
164            CoverageFormat = 1;
165        }
166        ~TCoverageFormat1()
167        {
168            if(GlyphArray) {
169                delete[] GlyphArray;
170            }
171        }
172    private:
173        TCoverageFormat1(const TCoverageFormat1&);
174        TCoverageFormat1& operator=(const TCoverageFormat1&);
175    };
176    struct TRangeRecord {
177        TT_uint16_t Start;
178        TT_uint16_t End;
179        TT_uint16_t StartCoverageIndex;
180        TRangeRecord(): Start(0), End(0), StartCoverageIndex(0) {}
181        friend bool operator > (const TRangeRecord &r1, const TRangeRecord &r2)
182        {
183            return r1.Start > r2.Start;
184        }
185    private:
186        TRangeRecord(const TRangeRecord&);
187    };
188    struct TCoverageFormat2: public TCoverageFormatBase {
189        TT_uint16_t RangeCount;
190        struct TRangeRecord *RangeRecord;
191        TCoverageFormat2(): RangeCount(0), RangeRecord(NULL)
192        {
193            CoverageFormat = 2;
194        }
195        ~TCoverageFormat2()
196        {
197            if(RangeRecord) {
198                delete[] RangeRecord;
199            }
200        }
201    private:
202        TCoverageFormat2(const TCoverageFormat2&);
203        TCoverageFormat2& operator=(const TCoverageFormat2&);
204    };
205    struct TClassDefFormatBase {
206        TT_uint16_t ClassFormat;
207        TClassDefFormatBase(): ClassFormat(0) {}
208        virtual ~TClassDefFormatBase() {}
209    private:
210        TClassDefFormatBase(const TClassDefFormatBase&);
211        TClassDefFormatBase& operator=(const TClassDefFormatBase&);
212    };
213    struct TClassDefFormat1: public TClassDefFormatBase {
214        TT_uint16_t StartGlyph;
215        TT_uint16_t GlyphCount;
216        TT_uint16_t *ClassValueArray;
217        TClassDefFormat1(): StartGlyph(0), GlyphCount(0), ClassValueArray(NULL)
218        {
219            ClassFormat = 1;
220        }
221        ~TClassDefFormat1()
222        {
223            if(ClassValueArray) {
224                delete[] ClassValueArray;
225            }
226        }
227    private:
228        TClassDefFormat1(const TClassDefFormat1&);
229        TClassDefFormat1& operator=(const TClassDefFormat1&);
230    };
231    struct TClassRangeRecord {
232        TT_uint16_t Start;
233        TT_uint16_t End;
234        TT_uint16_t Class;
235        TClassRangeRecord(): Start(0), End(0), Class(0) {}
236    private:
237        TClassRangeRecord(const TClassRangeRecord&);
238        TClassRangeRecord& operator=(const TClassRangeRecord&);
239    };
240    struct TClassDefFormat2: public TClassDefFormatBase {
241        TT_uint16_t ClassRangeCount;
242        struct TClassRangeRecord *ClassRangeRecord;
243        TClassDefFormat2(): ClassRangeCount(0), ClassRangeRecord(NULL)
244        {
245            ClassFormat = 2;
246        }
247        ~TClassDefFormat2()
248        {
249            if(ClassRangeRecord) {
250                delete[] ClassRangeRecord;
251            }
252        }
253    private:
254        TClassDefFormat2(const TClassDefFormat2&);
255        TClassDefFormat2& operator=(const TClassDefFormat2&);
256    };
257    struct TDevice {
258        TT_uint16_t StartSize;
259        TT_uint16_t EndSize;
260        TT_uint16_t DeltaFormat;
261        TDevice(): StartSize(0), EndSize(0), DeltaFormat(0) {}
262    private:
263        TDevice(const TDevice&);
264        TDevice& operator=(const TDevice&);
265    };
266    struct TSubTableBase {
267        TT_uint16_t SubstFormat;
268        TSubTableBase(): SubstFormat(0) {}
269        virtual ~TSubTableBase() {}
270    private:
271        TSubTableBase(const TSubTableBase&);
272        TSubTableBase& operator=(const TSubTableBase&);
273    };
274    struct TSingleSubstFormat1: public TSubTableBase {
275        TCoverageFormatBase *Coverage;
276        TT_int16_t DeltaGlyphID;
277        TSingleSubstFormat1(): DeltaGlyphID(0), Coverage(NULL)
278        {
279            SubstFormat = 1;
280        }
281        ~TSingleSubstFormat1()
282        {
283            if(Coverage) {
284                delete Coverage;
285            }
286        }
287    private:
288        TSingleSubstFormat1(const TSingleSubstFormat1&);
289        TSingleSubstFormat1& operator=(const TSingleSubstFormat1&);
290    };
291    struct TSingleSubstFormat2: public TSubTableBase {
292        TCoverageFormatBase *Coverage;
293        TT_uint16_t GlyphCount;
294        TT_uint16_t *Substitute;
295        TSingleSubstFormat2(): Coverage(NULL), GlyphCount(0), Substitute(NULL)
296        {
297            SubstFormat = 2;
298        }
299        ~TSingleSubstFormat2()
300        {
301            if(Coverage) {
302                delete Coverage;
303            }
304            if(Substitute) {
305                delete[] Substitute;
306            }
307        }
308    private:
309        TSingleSubstFormat2(const TSingleSubstFormat2&);
310        TSingleSubstFormat2& operator=(const TSingleSubstFormat2&);
311    };
312    struct TLookup {
313        TT_uint16_t LookupType;
314        TT_uint16_t LookupFlag;
315        TT_uint16_t SubTableCount;
316        struct TSubTableBase **SubTable;
317        TLookup(): LookupType(0), LookupFlag(0), SubTableCount(0), SubTable(NULL) {}
318        ~TLookup()
319        {
320            if(SubTableCount > 0 && SubTable != NULL) {
321                for(int i = 0; i < SubTableCount; i++) {
322                    delete SubTable[i];
323                }
324                delete[] SubTable;
325            }
326        }
327    private:
328        TLookup(const TLookup&);
329        TLookup& operator=(const TLookup&);
330    };
331    struct TLookupList {
332        int LookupCount;
333        struct TLookup *Lookup;
334        TLookupList(): LookupCount(0), Lookup(NULL) {}
335        ~TLookupList()
336        {
337            if(Lookup) {
338                delete[] Lookup;
339            }
340        }
341    private:
342        TLookupList(const TLookupList&);
343        TLookupList& operator=(const TLookupList&);
344    };
345    bool Parse(
346        FT_Bytes scriptlist,
347        FT_Bytes featurelist,
348        FT_Bytes lookuplist);
349    void ParseScriptList(FT_Bytes raw, TScriptList *rec);
350    void ParseScript(FT_Bytes raw, TScript *rec);
351    void ParseLangSys(FT_Bytes raw, TLangSys *rec);
352    void ParseFeatureList(FT_Bytes raw, TFeatureList *rec);
353    void ParseFeature(FT_Bytes raw, TFeature *rec);
354    void ParseLookupList(FT_Bytes raw, TLookupList *rec);
355    void ParseLookup(FT_Bytes raw, TLookup *rec);
356    void ParseCoverage(FT_Bytes raw, TCoverageFormatBase **rec);
357    void ParseCoverageFormat1(FT_Bytes raw, TCoverageFormat1 *rec);
358    void ParseCoverageFormat2(FT_Bytes raw, TCoverageFormat2 *rec);
359    void ParseSingleSubst(FT_Bytes raw, TSubTableBase **rec);
360    void ParseSingleSubstFormat1(FT_Bytes raw, TSingleSubstFormat1 *rec);
361    void ParseSingleSubstFormat2(FT_Bytes raw, TSingleSubstFormat2 *rec);
362    bool GetVerticalGlyphSub(
363        TT_uint32_t glyphnum,
364        TT_uint32_t *vglyphnum,
365        struct TFeature *Feature);
366    bool GetVerticalGlyphSub2(
367        TT_uint32_t glyphnum,
368        TT_uint32_t *vglyphnum,
369        struct TLookup *Lookup);
370    int GetCoverageIndex(struct TCoverageFormatBase *Coverage, TT_uint32_t g);
371    TT_uint8_t GetUInt8(FT_Bytes& p) const
372    {
373        TT_uint8_t ret = p[0];
374        p += 1;
375        return ret;
376    }
377    TT_int16_t GetInt16(FT_Bytes& p) const
378    {
379        TT_uint16_t ret = p[0] << 8 | p[1];
380        p += 2;
381        return *(TT_int16_t*)&ret;
382    }
383    TT_uint16_t GetUInt16(FT_Bytes& p) const
384    {
385        TT_uint16_t ret = p[0] << 8 | p[1];
386        p += 2;
387        return ret;
388    }
389    TT_int32_t GetInt32(FT_Bytes& p) const
390    {
391        TT_uint32_t ret = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
392        p += 4;
393        return *(TT_int32_t*)&ret;
394    }
395    TT_uint32_t GetUInt32(FT_Bytes& p) const
396    {
397        TT_uint32_t ret = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
398        p += 4;
399        return ret;
400    }
401    CFX_CMapDWordToDWord m_featureMap;
402    FX_BOOL	m_bFeautureMapLoad;
403    bool loaded;
404    struct tt_gsub_header header;
405    struct TScriptList ScriptList;
406    struct TFeatureList FeatureList;
407    struct TLookupList LookupList;
408};
409class CFX_GSUBTable : public IFX_GSUBTable, public CFX_Object
410{
411public:
412    virtual void	Release()
413    {
414        delete this;
415    }
416    virtual FX_BOOL GetVerticalGlyph(FX_DWORD glyphnum, FX_DWORD* vglyphnum);
417    CFX_CTTGSUBTable m_GsubImp;
418};
419#endif
420