//
//  TTFont.h
//  GSFontTools
//
//  Created by Georg Seifert on 23.07.11.
//  Copyright 2011 schriftgestaltung.de. All rights reserved.
//

@class GSXMLWriter;
@class SFNTReader;
@class TTGlyph;
@class TTTable;

@class table__a_v_a_r;
@class table_B_A_S_E_;
@class table_C_F_F_;
@class table_C_F_F__2;
@class table__c_m_a_p;
@class table_C_O_L_R_;
@class table_C_P_A_L_;
@class table__c_v_a_r;
@class table__c_v_t;
//@class table_D_S_I_G_;  // For some reason, the specific type does not exist.
@class table__f_e_a_t;
@class table__f_p_g_m;
@class table__f_v_a_r;
@class table__g_a_s_p;
@class table_G_D_E_F_;
@class table__g_l_y_f;
@class table_G_P_O_S_;
@class table_G_S_U_B_;
@class table__g_v_a_r;
@class table__h_d_m_x;
@class table__h_e_a_d;
@class table__h_h_e_a;
@class table__h_m_t_x;
@class table_H_V_A_R_;
@class table__k_e_r_n;
@class table__l_o_c_a;
@class table_L_T_S_H_;
@class table_M_A_T_H_;
@class table__m_a_x_p;
@class table__m_e_t_a;
@class table__m_o_r_x;
@class table_M_V_A_R_;
@class table__n_a_m_e;
@class table_O_S_2f_2;
@class table_P_C_L_T_;
@class table__p_o_s_t;
@class table__p_r_e_p;
@class table__s_b_i_x;
@class table_S_T_A_T_;
@class table_S_V_G_;
@class table_V_D_M_X_;
@class table_V_O_R_G_;
@class table__v_h_e_a;
@class table__v_m_t_x;

@protocol SFNTWriter;

#define TTsfntVersionCFF @"OTTO"
#define TTsfntVersionTrueType @"0100"
#define TTsfntVersionTTCubic @"CUBE"
#define TTsfntVersionAppleTrueType @"true"
#define TTsfntVersionTTC @"ttcf"

typedef NSString *const OTTableName;
typedef NSString *const OTFeatureTag;

NS_ASSUME_NONNULL_BEGIN

FOUNDATION_EXPORT OTTableName kOTTableKeyAvar;
FOUNDATION_EXPORT OTTableName kOTTableKeyBASE;
FOUNDATION_EXPORT OTTableName kOTTableKeyCFF2;
FOUNDATION_EXPORT OTTableName kOTTableKeyCFF;
FOUNDATION_EXPORT OTTableName kOTTableKeyCmap;
FOUNDATION_EXPORT OTTableName kOTTableKeyCOLR;
FOUNDATION_EXPORT OTTableName kOTTableKeyCPAL;
FOUNDATION_EXPORT OTTableName kOTTableKeyCvar;
FOUNDATION_EXPORT OTTableName kOTTableKeyCvt;
FOUNDATION_EXPORT OTTableName kOTTableKeyDSIG;
FOUNDATION_EXPORT OTTableName kOTTableKeyFeat;
FOUNDATION_EXPORT OTTableName kOTTableKeyFpgm;
FOUNDATION_EXPORT OTTableName kOTTableKeyFvar;
FOUNDATION_EXPORT OTTableName kOTTableKeyGasp;
FOUNDATION_EXPORT OTTableName kOTTableKeyGDEF;
FOUNDATION_EXPORT OTTableName kOTTableKeyGlyf;
FOUNDATION_EXPORT OTTableName kOTTableKeyGPOS;
FOUNDATION_EXPORT OTTableName kOTTableKeyGSUB;
FOUNDATION_EXPORT OTTableName kOTTableKeyGvar;
FOUNDATION_EXPORT OTTableName kOTTableKeyHdmx;
FOUNDATION_EXPORT OTTableName kOTTableKeyHead;
FOUNDATION_EXPORT OTTableName kOTTableKeyHhea;
FOUNDATION_EXPORT OTTableName kOTTableKeyHmtx;
FOUNDATION_EXPORT OTTableName kOTTableKeyHVAR;
FOUNDATION_EXPORT OTTableName kOTTableKeyKern;
FOUNDATION_EXPORT OTTableName kOTTableKeyLoca;
FOUNDATION_EXPORT OTTableName kOTTableKeyLTSH;
FOUNDATION_EXPORT OTTableName kOTTableKeyMATH;
FOUNDATION_EXPORT OTTableName kOTTableKeyMaxp;
FOUNDATION_EXPORT OTTableName kOTTableKeyMeta;
FOUNDATION_EXPORT OTTableName kOTTableKeyMorx;
FOUNDATION_EXPORT OTTableName kOTTableKeyMVAR;
FOUNDATION_EXPORT OTTableName kOTTableKeyName;
FOUNDATION_EXPORT OTTableName kOTTableKeyOS_2;
FOUNDATION_EXPORT OTTableName kOTTableKeyPCLT;
FOUNDATION_EXPORT OTTableName kOTTableKeyPost;
FOUNDATION_EXPORT OTTableName kOTTableKeyPrep;
FOUNDATION_EXPORT OTTableName kOTTableKeySbix;
FOUNDATION_EXPORT OTTableName kOTTableKeySTAT;
FOUNDATION_EXPORT OTTableName kOTTableKeySVG;
FOUNDATION_EXPORT OTTableName kOTTableKeyVDMX;
FOUNDATION_EXPORT OTTableName kOTTableKeyVORG;
FOUNDATION_EXPORT OTTableName kOTTableKeyVhea;
FOUNDATION_EXPORT OTTableName kOTTableKeyVmtx;

FOUNDATION_EXPORT OTFeatureTag kOTFeatureTagKern;
FOUNDATION_EXPORT OTFeatureTag kOTFeatureTagVkrn;
FOUNDATION_EXPORT OTFeatureTag kOTFeatureTagDist;
FOUNDATION_EXPORT OTFeatureTag kOTFeatureTagAalt;
FOUNDATION_EXPORT OTFeatureTag kOTFeatureTagMark;
FOUNDATION_EXPORT OTFeatureTag kOTFeatureTagMkmk;
FOUNDATION_EXPORT OTFeatureTag kOTFeatureTagInit;
FOUNDATION_EXPORT OTFeatureTag kOTFeatureTagMedi;
FOUNDATION_EXPORT OTFeatureTag kOTFeatureTagFina;
FOUNDATION_EXPORT OTFeatureTag kOTFeatureTagIsol;

// deprecated
FOUNDATION_EXPORT OTFeatureTag kOTFeatureTagMgrk;

// Convenience type definition.
typedef NSString *OTAxisTag NS_TYPED_EXTENSIBLE_ENUM;
extern OTAxisTag const OTAxisTagEngr;
extern OTAxisTag const OTAxisTagHght;
extern OTAxisTag const OTAxisTagItal;
extern OTAxisTag const OTAxisTagOpsz;
extern OTAxisTag const OTAxisTagOtln;
extern OTAxisTag const OTAxisTagRefl;
extern OTAxisTag const OTAxisTagRsec;
extern OTAxisTag const OTAxisTagRxad;
extern OTAxisTag const OTAxisTagRyad;
extern OTAxisTag const OTAxisTagShdw;
extern OTAxisTag const OTAxisTagSlnt;
extern OTAxisTag const OTAxisTagUdln;
extern OTAxisTag const OTAxisTagVotf;
extern OTAxisTag const OTAxisTagVrot;
extern OTAxisTag const OTAxisTagWdth;
extern OTAxisTag const OTAxisTagWght;
extern OTAxisTag const OTAxisTagXOPQ;
extern OTAxisTag const OTAxisTagXTAB;
extern OTAxisTag const OTAxisTagXTCH;
extern OTAxisTag const OTAxisTagXTRA;
extern OTAxisTag const OTAxisTagYOPQ;
extern OTAxisTag const OTAxisTagYTAS;
extern OTAxisTag const OTAxisTagYTCH;
extern OTAxisTag const OTAxisTagYTDE;
extern OTAxisTag const OTAxisTagYTFG;
extern OTAxisTag const OTAxisTagYTLC;
extern OTAxisTag const OTAxisTagYTRA;
extern OTAxisTag const OTAxisTagYTSE;
extern OTAxisTag const OTAxisTagYTUC;
extern OTAxisTag const OTAxisTagYTFI;
extern OTAxisTag const OTAxisTagROND;
extern OTAxisTag const OTAxisTagGRAD;

// roboto flex.
extern OTAxisTag const OTAxisTagXTSP;
extern OTAxisTag const OTAxisTagXOUC;
extern OTAxisTag const OTAxisTagXOLC;
extern OTAxisTag const OTAxisTagXOFI;
extern OTAxisTag const OTAxisTagXTUC;
extern OTAxisTag const OTAxisTagXTLC;
extern OTAxisTag const OTAxisTagXTFI;
extern OTAxisTag const OTAxisTagXUCS;
extern OTAxisTag const OTAxisTagXUCR;
extern OTAxisTag const OTAxisTagXLCS;
extern OTAxisTag const OTAxisTagXLCR;
extern OTAxisTag const OTAxisTagXFIR;
extern OTAxisTag const OTAxisTagYOUC;
extern OTAxisTag const OTAxisTagYOLC;
extern OTAxisTag const OTAxisTagYOFI;
extern OTAxisTag const OTAxisTagYTOS;
extern OTAxisTag const OTAxisTagYTUO;
extern OTAxisTag const OTAxisTagYTLO;
extern OTAxisTag const OTAxisTagYTFO;
extern OTAxisTag const OTAxisTagYTDO;
extern OTAxisTag const OTAxisTagYTAO;
extern OTAxisTag const OTAxisTagXOAC;
extern OTAxisTag const OTAxisTagYOAC;
extern OTAxisTag const OTAxisTagYTUA;
extern OTAxisTag const OTAxisTagYTLA;
extern OTAxisTag const OTAxisTagYUAT;
extern OTAxisTag const OTAxisTagYLAT;
extern OTAxisTag const OTAxisTagUDLN;
extern OTAxisTag const OTAxisTagYTTL;
extern OTAxisTag const OTAxisTagXTTW;

@protocol GlyphSet <NSObject>

- (id)glyphForName:(NSString *)glyphName;
- (NSArray *)allKeys;
- (NSArray *)allValues;
- (NSUInteger)count;

@end

@interface TTFont : NSObject {
	NSString *_path;
	SFNTReader *_reader;
	NSArray <NSString *> *_glyphOrder;
	NSDictionary *_glyph2Index;
	BOOL _disassembleInstructions;
	BOOL _verbose;
	BOOL _ignoreDecompileErrors;
	BOOL _recalcBBoxes;
	NSMutableDictionary *VIDDict;
	NSUInteger last_vid;
	NSMutableDictionary *reverseVIDDict;
	NSDictionary *_reverseGlyphOrderDict;
	NSString *_sfntVersion;
}

@property (retain, nonatomic) NSString *sfntVersion;
@property (retain, nonatomic) NSString *path;
@property (retain, nonatomic) NSDictionary <OTTableName, TTTable *> *tables;
@property (retain, nonatomic) NSArray <NSString *> *glyphOrder;
@property (nonatomic) BOOL verbose;
@property (nonatomic) BOOL ignoreDecompileErrors;
@property (nonatomic, assign) BOOL recalcBBoxes;
@property (nonatomic, assign) NSUInteger fontIndex; // for TTC fonts

@property (nonatomic, readonly) NSArray *allKeys;

@property (readonly) SFNTReader *reader;

// Convenience accessors
@property (nonatomic, strong) table__a_v_a_r *avarTable;
@property (nonatomic, strong) table_B_A_S_E_ *BASETable;
@property (nonatomic, strong) table_C_F_F_ *CFFTable;
@property (nonatomic, strong) table_C_F_F__2 *CFF2Table;
@property (nonatomic, strong) table__c_m_a_p *cmapTable;
@property (nonatomic, strong) table_C_O_L_R_ *COLRTable;
@property (nonatomic, strong) table_C_P_A_L_ *CPALTable;
@property (nonatomic, strong) table__c_v_a_r *cvarTable;
@property (nonatomic, strong) table__c_v_t *cvtTable;
@property (nonatomic, strong) TTTable *DSIGTable;  // For some reason, the specific type does not exist.
@property (nonatomic, strong) table__f_e_a_t *featTable;
@property (nonatomic, strong) table__f_p_g_m *fpgmTable;
@property (nonatomic, strong) table__f_v_a_r *fvarTable;
@property (nonatomic, strong) table__g_a_s_p *gaspTable;
@property (nonatomic, strong) table_G_D_E_F_ *GDEFTable;
@property (nonatomic, strong) table__g_l_y_f *glyfTable;
@property (nonatomic, strong) table_G_P_O_S_ *GPOSTable;
@property (nonatomic, strong) table_G_S_U_B_ *GSUBTable;
@property (nonatomic, strong) table__g_v_a_r *gvarTable;
@property (nonatomic, strong) table__h_d_m_x *hdmxTable;
@property (nonatomic, strong) table__h_e_a_d *headTable;
@property (nonatomic, strong) table__h_h_e_a *hheaTable;
@property (nonatomic, strong) table__h_m_t_x *hmtxTable;
@property (nonatomic, strong) table_H_V_A_R_ *HVARTable;
@property (nonatomic, strong) table__k_e_r_n *kernTable;
@property (nonatomic, strong) table__l_o_c_a *locaTable;
@property (nonatomic, strong) table_L_T_S_H_ *LTSHTable;
@property (nonatomic, strong) table_M_A_T_H_ *MATHTable;
@property (nonatomic, strong) table__m_a_x_p *maxpTable;
@property (nonatomic, strong) table__m_e_t_a *metaTable;
@property (nonatomic, strong) table__m_o_r_x *morxTable;
@property (nonatomic, strong) table_M_V_A_R_ *MVARTable;
@property (nonatomic, strong) table__n_a_m_e *nameTable;
@property (nonatomic, strong) table_O_S_2f_2 *OS_2Table;
@property (nonatomic, strong) table_P_C_L_T_ *PCLTTable;
@property (nonatomic, strong) table__p_o_s_t *postTable;
@property (nonatomic, strong) table__p_r_e_p *prepTable;
@property (nonatomic, strong) table__s_b_i_x *sbixTable;
@property (nonatomic, strong) table_S_T_A_T_ *STATTable;
@property (nonatomic, strong) table_S_V_G_ *SVGTable;
@property (nonatomic, strong) table_V_D_M_X_ *VDMXTable;
@property (nonatomic, strong) table_V_O_R_G_ *VORGTable;
@property (nonatomic, strong) table__v_h_e_a *vheaTable;
@property (nonatomic, strong) table__v_m_t_x *vmtxTable;

- (instancetype)initWithPath:(NSString *)path;
- (instancetype)initWithData:(nullable NSData *)data;

- (instancetype)initWithXMLFile:(NSString *)path;

@property (retain) NSArray <NSError *> *errors;

- (void)addError:(NSError *)error;

- (BOOL)saveFont:(NSString *)savePath error:(NSError **)error;
- (nullable NSData *)fontDataError:(NSError **)error;
- (void)saveToXML:(NSString *)XMLPath;
- (void)saveToXML:(NSString *)XMLPath writeTables:(nullable NSArray *)writeTables skipTables:(nullable NSArray *)skipTables splitTables:(BOOL)splitTables disassembleInstructions:(BOOL)disassembleInstructions;
- (BOOL)isLoaded:(NSString *)tag;
- (BOOL)has_key:(NSString *)tag;
//- (NSString *)sfntVersion;
- (NSUInteger)count;
- (nullable TTTable *)tableForKey:(NSString *)key;
- (void)setTable:(TTTable *)table forKey:(NSString *)tag;
- (void)removeTableForKey:(NSString *)tag;
- (NSArray *)glyphNames;
- (NSArray *)glyphNames2;
- (NSString *)glyphNameAtIndex:(NSUInteger)glyphIndex;
- (NSUInteger)indexOfGlyphForName:(NSString *)glyphName;
- (BOOL)_writeTable:(NSString *)tag writer:(id<SFNTWriter>)writer done:(NSMutableArray *)done error:(NSError **)error;
- (nullable NSData *)tableDataForKey:(NSString *)tag error:(NSError **)error;
- (nullable id<GlyphSet>)glyphSet;
- (NSUInteger)numFonts;
- (NSDictionary *)reverseGlyphToIndexMap:(BOOL)rebuild;

+ (NSString *)stringFromSfntVersionChar:(char *)sfntVersion;
@end

Class getTableClass(NSString *tag);

NS_ASSUME_NONNULL_END
