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