1 /*  GRAPHITE2 LICENSING
2 
3     Copyright 2010, SIL International
4     All rights reserved.
5 
6     This library is free software; you can redistribute it and/or modify
7     it under the terms of the GNU Lesser General Public License as published
8     by the Free Software Foundation; either version 2.1 of License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14     Lesser General Public License for more details.
15 
16     You should also have received a copy of the GNU Lesser General Public
17     License along with this library in the file named "LICENSE".
18     If not, write to the Free Software Foundation, 51 Franklin Street,
19     Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
20     internet at http://www.fsf.org/licenses/lgpl.html.
21 
22 Alternatively, the contents of this file may be used under the terms of the
23 Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
24 License, as published by the Free Software Foundation, either version 2
25 of the License or (at your option) any later version.
26 */
27 #pragma once
28 /*--------------------------------------------------------------------*//*:Ignore this sentence.
29 
30 File: TtfUtil.h
31 Responsibility: Alan Ward
32 Last reviewed: Not yet.
33 
34 Description:
35     Utility class for handling TrueType font files.
36 ----------------------------------------------------------------------------------------------*/
37 
38 
39 #include <cstddef>
40 
41 namespace graphite2
42 {
43 namespace TtfUtil
44 {
45 
46 typedef long fontTableId32;
47 typedef unsigned short gid16;
48 
49 #define TTF_TAG(a,b,c,d) ((a << 24UL) + (b << 16UL) + (c << 8UL) + (d))
50 
51 // Enumeration used to specify a table in a TTF file
52 class Tag
53 {
54     unsigned long _v;
55 public:
Tag(const char n[5])56     Tag(const char n[5]) throw()            : _v(TTF_TAG(n[0],n[1],n[2],n[3])) {}
throw()57     Tag(const unsigned long tag) throw()    : _v(tag) {}
58 
throw()59     operator unsigned long () const throw () { return _v; }
60 
61     enum
62     {
63         Feat = TTF_TAG('F','e','a','t'),
64         Glat = TTF_TAG('G','l','a','t'),
65         Gloc = TTF_TAG('G','l','o','c'),
66         Sile = TTF_TAG('S','i','l','e'),
67         Silf = TTF_TAG('S','i','l','f'),
68         Sill = TTF_TAG('S','i','l','l'),
69         cmap = TTF_TAG('c','m','a','p'),
70         cvt  = TTF_TAG('c','v','t',' '),
71         cryp = TTF_TAG('c','r','y','p'),
72         head = TTF_TAG('h','e','a','d'),
73         fpgm = TTF_TAG('f','p','g','m'),
74         gdir = TTF_TAG('g','d','i','r'),
75         glyf = TTF_TAG('g','l','y','f'),
76         hdmx = TTF_TAG('h','d','m','x'),
77         hhea = TTF_TAG('h','h','e','a'),
78         hmtx = TTF_TAG('h','m','t','x'),
79         loca = TTF_TAG('l','o','c','a'),
80         kern = TTF_TAG('k','e','r','n'),
81         LTSH = TTF_TAG('L','T','S','H'),
82         maxp = TTF_TAG('m','a','x','p'),
83         name = TTF_TAG('n','a','m','e'),
84         OS_2 = TTF_TAG('O','S','/','2'),
85         post = TTF_TAG('p','o','s','t'),
86         prep = TTF_TAG('p','r','e','p')
87     };
88 };
89 
90 /*----------------------------------------------------------------------------------------------
91     Class providing utility methods to parse a TrueType font file (TTF).
92     Callling application handles all file input and memory allocation.
93     Assumes minimal knowledge of TTF file format.
94 ----------------------------------------------------------------------------------------------*/
95     ////////////////////////////////// tools to find & check TTF tables
96     bool GetHeaderInfo(size_t & lOffset, size_t & lSize);
97     bool CheckHeader(const void * pHdr);
98     bool GetTableDirInfo(const void * pHdr, size_t & lOffset, size_t & lSize);
99     bool GetTableInfo(const Tag TableTag, const void * pHdr, const void * pTableDir,
100         size_t & lOffset, size_t & lSize);
101     bool CheckTable(const Tag TableId, const void * pTable, size_t lTableSize);
102 
103     ////////////////////////////////// simple font wide info
104     size_t  GlyphCount(const void * pMaxp);
105 #ifdef ALL_TTFUTILS
106     size_t  MaxCompositeComponentCount(const void * pMaxp);
107     size_t  MaxCompositeLevelCount(const void * pMaxp);
108     size_t  LocaGlyphCount(size_t lLocaSize, const void * pHead); // throw (std::domain_error);
109 #endif
110     int DesignUnits(const void * pHead);
111 #ifdef ALL_TTFUTILS
112     int HeadTableCheckSum(const void * pHead);
113     void HeadTableCreateTime(const void * pHead, unsigned int * pnDateBC, unsigned int * pnDateAD);
114     void HeadTableModifyTime(const void * pHead, unsigned int * pnDateBC, unsigned int * pnDateAD);
115     bool IsItalic(const void * pHead);
116     int FontAscent(const void * pOs2);
117     int FontDescent(const void * pOs2);
118     bool FontOs2Style(const void *pOs2, bool & fBold, bool & fItalic);
119     bool Get31EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize);
120     bool Get31EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize);
121     bool Get30EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize);
122     bool Get30EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize);
123     int PostLookup(const void * pPost, size_t lPostSize, const void * pMaxp,
124         const char * pPostName);
125 #endif
126 
127     ////////////////////////////////// utility methods helpful for name table
128     bool GetNameInfo(const void * pName, int nPlatformId, int nEncodingId,
129         int nLangId, int nNameId, size_t & lOffset, size_t & lSize);
130     //size_t NameTableLength(const byte * pTable);
131 #ifdef ALL_TTFUTILS
132     int GetLangsForNames(const void * pName, int nPlatformId, int nEncodingId,
133         int *nameIdList, int cNameIds, short *langIdList);
134     void SwapWString(void * pWStr, size_t nSize = 0); // throw (std::invalid_argument);
135 #endif
136 
137     ////////////////////////////////// cmap lookup tools
138     const void * FindCmapSubtable(const void * pCmap, int nPlatformId = 3,
139         int nEncodingId = 1, size_t length = 0);
140     bool CheckCmapSubtable4(const void * pCmap31, const void * pCmapEnd /*, unsigned int maxgid*/);
141     gid16 CmapSubtable4Lookup(const void * pCmapSubtabel4, unsigned int nUnicodeId, int rangeKey = 0);
142     unsigned int CmapSubtable4NextCodepoint(const void *pCmap31, unsigned int nUnicodeId,
143         int * pRangeKey = 0);
144     bool CheckCmapSubtable12(const void *pCmap310, const void * pCmapEnd /*, unsigned int maxgid*/);
145     gid16 CmapSubtable12Lookup(const void * pCmap310, unsigned int uUnicodeId, int rangeKey = 0);
146     unsigned int CmapSubtable12NextCodepoint(const void *pCmap310, unsigned int nUnicodeId,
147         int * pRangeKey = 0);
148 
149     ///////////////////////////////// horizontal metric data for a glyph
150     bool HorMetrics(gid16 nGlyphId, const void * pHmtx, size_t lHmtxSize,
151         const void * pHhea, int & nLsb, unsigned int & nAdvWid);
152 
153     ////////////////////////////////// primitives for loca and glyf lookup
154     size_t LocaLookup(gid16 nGlyphId, const void * pLoca, size_t lLocaSize,
155         const void * pHead); // throw (std::out_of_range);
156     void * GlyfLookup(const void * pGlyf, size_t lGlyfOffset, size_t lTableLen);
157 
158     ////////////////////////////////// primitves for simple glyph data
159     bool GlyfBox(const void * pSimpleGlyf, int & xMin, int & yMin,
160         int & xMax, int & yMax);
161 
162 #ifdef ALL_TTFUTILS
163     int GlyfContourCount(const void * pSimpleGlyf);
164     bool GlyfContourEndPoints(const void * pSimpleGlyf, int * prgnContourEndPoint,
165         int cnPointsTotal, size_t & cnPoints);
166     bool GlyfPoints(const void * pSimpleGlyf, int * prgnX, int * prgnY,
167         char * prgbFlag, int cnPointsTotal, int & cnPoints);
168 
169     // primitive to find the glyph ids in a composite glyph
170     bool GetComponentGlyphIds(const void * pSimpleGlyf, int * prgnCompId,
171         size_t cnCompIdTotal, size_t & cnCompId);
172     // primitive to find the placement data for a component in a composite glyph
173     bool GetComponentPlacement(const void * pSimpleGlyf, int nCompId,
174         bool fOffset, int & a, int & b);
175     // primitive to find the transform data for a component in a composite glyph
176     bool GetComponentTransform(const void * pSimpleGlyf, int nCompId,
177         float & flt11, float & flt12, float & flt21, float & flt22, bool & fTransOffset);
178 #endif
179 
180     ////////////////////////////////// operate on composite or simple glyph (auto glyf lookup)
181     void * GlyfLookup(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
182         size_t lGlyfSize, size_t lLocaSize, const void * pHead); // primitive used by below methods
183 
184 #ifdef ALL_TTFUTILS
185     // below are primary user methods for handling glyf data
186     bool IsSpace(gid16 nGlyphId, const void * pLoca, size_t lLocaSize, const void * pHead);
187     bool IsDeepComposite(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
188         size_t lGlyfSize, size_t lLocaSize, const void * pHead);
189 
190     bool GlyfBox(gid16 nGlyphId, const void * pGlyf, const void * pLoca, size_t lGlyfSize, size_t lLocaSize,
191         const void * pHead, int & xMin, int & yMin, int & xMax, int & yMax);
192     bool GlyfContourCount(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
193         size_t lGlyfSize, size_t lLocaSize, const void *pHead, size_t & cnContours);
194     bool GlyfContourEndPoints(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
195         size_t lGlyfSize, size_t lLocaSize, const void * pHead, int * prgnContourEndPoint, size_t cnPoints);
196     bool GlyfPoints(gid16 nGlyphId, const void * pGlyf, const void * pLoca,
197         size_t lGlyfSize, size_t lLocaSize, const void * pHead, const int * prgnContourEndPoint, size_t cnEndPoints,
198         int * prgnX, int * prgnY, bool * prgfOnCurve, size_t cnPoints);
199 
200     // utitily method used by high-level GlyfPoints
201     bool SimplifyFlags(char * prgbFlags, int cnPoints);
202     bool CalcAbsolutePoints(int * prgnX, int * prgnY, int cnPoints);
203 #endif
204 
205 } // end of namespace TtfUtil
206 } // end of namespace graphite2
207