1// SPDX-License-Identifier: MIT OR MPL-2.0 OR LGPL-2.1-or-later OR GPL-2.0-or-later
2// Copyright 2010, SIL International, All rights reserved.
3/*
4Responsibility: Alan Ward
5Last reviewed: Not yet.
6
7Description:
8 Utility class for handling TrueType font files.
9*/
10#pragma once
11
12
13#include <cstddef>
14
15namespace graphite2
16{
17namespace TtfUtil
18{
19
20#define OVERFLOW_OFFSET_CHECK(p, o) (o + reinterpret_cast<size_t>(p) < reinterpret_cast<size_t>(p))
21
22typedef long fontTableId32;
23typedef unsigned short gid16;
24
25#define TTF_TAG(a,b,c,d) ((a << 24UL) + (b << 16UL) + (c << 8UL) + (d))
26
27// Enumeration used to specify a table in a TTF file
28class Tag
29{
30 unsigned int _v;
31public:
32 Tag(const char n[5]) throw() : _v(TTF_TAG(n[0],n[1],n[2],n[3])) {}
33 Tag(const unsigned int tag) throw() : _v(tag) {}
34
35 operator unsigned int () const throw () { return _v; }
36
37 enum
38 {
39 Feat = TTF_TAG('F','e','a','t'),
40 Glat = TTF_TAG('G','l','a','t'),
41 Gloc = TTF_TAG('G','l','o','c'),
42 Sile = TTF_TAG('S','i','l','e'),
43 Silf = TTF_TAG('S','i','l','f'),
44 Sill = TTF_TAG('S','i','l','l'),
45 cmap = TTF_TAG('c','m','a','p'),
46 cvt = TTF_TAG('c','v','t',' '),
47 cryp = TTF_TAG('c','r','y','p'),
48 head = TTF_TAG('h','e','a','d'),
49 fpgm = TTF_TAG('f','p','g','m'),
50 gdir = TTF_TAG('g','d','i','r'),
51 glyf = TTF_TAG('g','l','y','f'),
52 hdmx = TTF_TAG('h','d','m','x'),
53 hhea = TTF_TAG('h','h','e','a'),
54 hmtx = TTF_TAG('h','m','t','x'),
55 loca = TTF_TAG('l','o','c','a'),
56 kern = TTF_TAG('k','e','r','n'),
57 LTSH = TTF_TAG('L','T','S','H'),
58 maxp = TTF_TAG('m','a','x','p'),
59 name = TTF_TAG('n','a','m','e'),
60 OS_2 = TTF_TAG('O','S','/','2'),
61 post = TTF_TAG('p','o','s','t'),
62 prep = TTF_TAG('p','r','e','p')
63 };
64};
65
66/*----------------------------------------------------------------------------------------------
67 Class providing utility methods to parse a TrueType font file (TTF).
68 Callling application handles all file input and memory allocation.
69 Assumes minimal knowledge of TTF file format.
70----------------------------------------------------------------------------------------------*/
71 ////////////////////////////////// tools to find & check TTF tables
72 bool GetHeaderInfo(size_t & lOffset, size_t & lSize);
73 bool CheckHeader(const void * pHdr);
74 bool GetTableDirInfo(const void * pHdr, size_t & lOffset, size_t & lSize);
75 bool GetTableInfo(const Tag TableTag, const void * pHdr, const void * pTableDir,
76 size_t & lOffset, size_t & lSize);
77 bool CheckTable(const Tag TableId, const void * pTable, size_t lTableSize);
78
79 ////////////////////////////////// simple font wide info
80 size_t GlyphCount(const void * pMaxp);
81#ifdef ALL_TTFUTILS
82 size_t MaxCompositeComponentCount(const void * pMaxp);
83 size_t MaxCompositeLevelCount(const void * pMaxp);
84 size_t LocaGlyphCount(size_t lLocaSize, const void * pHead); // throw (std::domain_error);
85#endif
86 int DesignUnits(const void * pHead);
87#ifdef ALL_TTFUTILS
88 int HeadTableCheckSum(const void * pHead);
89 void HeadTableCreateTime(const void * pHead, unsigned int * pnDateBC, unsigned int * pnDateAD);
90 void HeadTableModifyTime(const void * pHead, unsigned int * pnDateBC, unsigned int * pnDateAD);
91 bool IsItalic(const void * pHead);
92 int FontAscent(const void * pOs2);
93 int FontDescent(const void * pOs2);
94 bool FontOs2Style(const void *pOs2, bool & fBold, bool & fItalic);
95 bool Get31EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize);
96 bool Get31EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize);
97 bool Get30EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize);
98 bool Get30EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize);
99 int PostLookup(const void * pPost, size_t lPostSize, const void * pMaxp,
100 const char * pPostName);
101#endif
102
103 ////////////////////////////////// utility methods helpful for name table
104 bool GetNameInfo(const void * pName, int nPlatformId, int nEncodingId,
105 int nLangId, int nNameId, size_t & lOffset, size_t & lSize);
106 //size_t NameTableLength(const byte * pTable);
107#ifdef ALL_TTFUTILS
108 int GetLangsForNames(const void * pName, int nPlatformId, int nEncodingId,
109 int *nameIdList, int cNameIds, short *langIdList);
110 void SwapWString(void * pWStr, size_t nSize = 0); // throw (std::invalid_argument);
111#endif
112
113 ////////////////////////////////// cmap lookup tools
114 const void * FindCmapSubtable(const void * pCmap, int nPlatformId = 3,
115 int nEncodingId = 1, size_t length = 0);
116 bool CheckCmapSubtable4(const void * pCmap31, const void * pCmapEnd /*, unsigned int maxgid*/);
117 gid16 CmapSubtable4Lookup(const void * pCmapSubtabel4, unsigned int nUnicodeId, int rangeKey = 0);
118 unsigned int CmapSubtable4NextCodepoint(const void *pCmap31, unsigned int nUnicodeId,
119 int * pRangeKey = 0);
120 bool CheckCmapSubtable12(const void *pCmap310, const void * pCmapEnd /*, unsigned int maxgid*/);
121 gid16 CmapSubtable12Lookup(const void * pCmap310, unsigned int uUnicodeId, int rangeKey = 0);
122 unsigned int CmapSubtable12NextCodepoint(const void *pCmap310, unsigned int nUnicodeId,
123 int * pRangeKey = 0);
124
125 ///////////////////////////////// horizontal metric data for a glyph
126 bool HorMetrics(gid16 nGlyphId, const void * pHmtx, size_t lHmtxSize,
127 const void * pHhea, int & nLsb, unsigned int & nAdvWid);
128
129 ////////////////////////////////// primitives for loca and glyf lookup
130 size_t LocaLookup(gid16 nGlyphId, const void * pLoca, size_t lLocaSize,
131 const void * pHead); // throw (std::out_of_range);
132 void * GlyfLookup(const void * pGlyf, size_t lGlyfOffset, size_t lTableLen);
133
134 ////////////////////////////////// primitves for simple glyph data
135 bool GlyfBox(const void * pSimpleGlyf, int & xMin, int & yMin,
136 int & xMax, int & yMax);
137
138#ifdef ALL_TTFUTILS
139 int GlyfContourCount(const void * pSimpleGlyf);
140 bool GlyfContourEndPoints(const void * pSimpleGlyf, int * prgnContourEndPoint,
141 int cnPointsTotal, size_t & cnPoints);
142 bool GlyfPoints(const void * pSimpleGlyf, int * prgnX, int * prgnY,
143 char * prgbFlag, int cnPointsTotal, int & cnPoints);
144
145 // primitive to find the glyph ids in a composite glyph
146 bool GetComponentGlyphIds(const void * pSimpleGlyf, int * prgnCompId,
147 size_t cnCompIdTotal, size_t & cnCompId);
148 // primitive to find the placement data for a component in a composite glyph
149 bool GetComponentPlacement(const void * pSimpleGlyf, int nCompId,
150 bool fOffset, int & a, int & b);
151 // primitive to find the transform data for a component in a composite glyph
152 bool GetComponentTransform(const void * pSimpleGlyf, int nCompId,
153 float & flt11, float & flt12, float & flt21, float & flt22, bool & fTransOffset);
154#endif
155
156 ////////////////////////////////// operate on composite or simple glyph (auto glyf lookup)
157 void * GlyfLookup(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
158 size_t lGlyfSize, size_t lLocaSize, const void * pHead); // primitive used by below methods
159
160#ifdef ALL_TTFUTILS
161 // below are primary user methods for handling glyf data
162 bool IsSpace(gid16 nGlyphId, const void * pLoca, size_t lLocaSize, const void * pHead);
163 bool IsDeepComposite(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
164 size_t lGlyfSize, size_t lLocaSize, const void * pHead);
165
166 bool GlyfBox(gid16 nGlyphId, const void * pGlyf, const void * pLoca, size_t lGlyfSize, size_t lLocaSize,
167 const void * pHead, int & xMin, int & yMin, int & xMax, int & yMax);
168 bool GlyfContourCount(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
169 size_t lGlyfSize, size_t lLocaSize, const void *pHead, size_t & cnContours);
170 bool GlyfContourEndPoints(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
171 size_t lGlyfSize, size_t lLocaSize, const void * pHead, int * prgnContourEndPoint, size_t cnPoints);
172 bool GlyfPoints(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
173 size_t lGlyfSize, size_t lLocaSize, const void * pHead, const int * prgnContourEndPoint, size_t cnEndPoints,
174 int * prgnX, int * prgnY, bool * prgfOnCurve, size_t cnPoints);
175
176 // utitily method used by high-level GlyfPoints
177 bool SimplifyFlags(char * prgbFlags, int cnPoints);
178 bool CalcAbsolutePoints(int * prgnX, int * prgnY, int cnPoints);
179#endif
180
181} // end of namespace TtfUtil
182} // end of namespace graphite2
183