michael@0: /* GRAPHITE2 LICENSING michael@0: michael@0: Copyright 2010, SIL International michael@0: All rights reserved. michael@0: michael@0: This library is free software; you can redistribute it and/or modify michael@0: it under the terms of the GNU Lesser General Public License as published michael@0: by the Free Software Foundation; either version 2.1 of License, or michael@0: (at your option) any later version. michael@0: michael@0: This program is distributed in the hope that it will be useful, michael@0: but WITHOUT ANY WARRANTY; without even the implied warranty of michael@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU michael@0: Lesser General Public License for more details. michael@0: michael@0: You should also have received a copy of the GNU Lesser General Public michael@0: License along with this library in the file named "LICENSE". michael@0: If not, write to the Free Software Foundation, 51 Franklin Street, michael@0: Suite 500, Boston, MA 02110-1335, USA or visit their web page on the michael@0: internet at http://www.fsf.org/licenses/lgpl.html. michael@0: michael@0: Alternatively, the contents of this file may be used under the terms of the michael@0: Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public michael@0: License, as published by the Free Software Foundation, either version 2 michael@0: of the License or (at your option) any later version. michael@0: */ michael@0: #pragma once michael@0: /*--------------------------------------------------------------------*//*:Ignore this sentence. michael@0: michael@0: File: TtfUtil.h michael@0: Responsibility: Alan Ward michael@0: Last reviewed: Not yet. michael@0: michael@0: Description: michael@0: Utility class for handling TrueType font files. michael@0: ----------------------------------------------------------------------------------------------*/ michael@0: michael@0: michael@0: #include michael@0: michael@0: namespace graphite2 michael@0: { michael@0: namespace TtfUtil michael@0: { michael@0: michael@0: typedef long fontTableId32; michael@0: typedef unsigned short gid16; michael@0: michael@0: #define TTF_TAG(a,b,c,d) ((a << 24UL) + (b << 16UL) + (c << 8UL) + (d)) michael@0: michael@0: // Enumeration used to specify a table in a TTF file michael@0: class Tag michael@0: { michael@0: unsigned long _v; michael@0: public: michael@0: Tag(const char n[5]) throw() : _v(TTF_TAG(n[0],n[1],n[2],n[3])) {} michael@0: Tag(const unsigned long tag) throw() : _v(tag) {} michael@0: michael@0: operator unsigned long () const throw () { return _v; } michael@0: michael@0: enum michael@0: { michael@0: Feat = TTF_TAG('F','e','a','t'), michael@0: Glat = TTF_TAG('G','l','a','t'), michael@0: Gloc = TTF_TAG('G','l','o','c'), michael@0: Sile = TTF_TAG('S','i','l','e'), michael@0: Silf = TTF_TAG('S','i','l','f'), michael@0: Sill = TTF_TAG('S','i','l','l'), michael@0: cmap = TTF_TAG('c','m','a','p'), michael@0: cvt = TTF_TAG('c','v','t',' '), michael@0: cryp = TTF_TAG('c','r','y','p'), michael@0: head = TTF_TAG('h','e','a','d'), michael@0: fpgm = TTF_TAG('f','p','g','m'), michael@0: gdir = TTF_TAG('g','d','i','r'), michael@0: glyf = TTF_TAG('g','l','y','f'), michael@0: hdmx = TTF_TAG('h','d','m','x'), michael@0: hhea = TTF_TAG('h','h','e','a'), michael@0: hmtx = TTF_TAG('h','m','t','x'), michael@0: loca = TTF_TAG('l','o','c','a'), michael@0: kern = TTF_TAG('k','e','r','n'), michael@0: LTSH = TTF_TAG('L','T','S','H'), michael@0: maxp = TTF_TAG('m','a','x','p'), michael@0: name = TTF_TAG('n','a','m','e'), michael@0: OS_2 = TTF_TAG('O','S','/','2'), michael@0: post = TTF_TAG('p','o','s','t'), michael@0: prep = TTF_TAG('p','r','e','p') michael@0: }; michael@0: }; michael@0: michael@0: /*---------------------------------------------------------------------------------------------- michael@0: Class providing utility methods to parse a TrueType font file (TTF). michael@0: Callling application handles all file input and memory allocation. michael@0: Assumes minimal knowledge of TTF file format. michael@0: ----------------------------------------------------------------------------------------------*/ michael@0: ////////////////////////////////// tools to find & check TTF tables michael@0: bool GetHeaderInfo(size_t & lOffset, size_t & lSize); michael@0: bool CheckHeader(const void * pHdr); michael@0: bool GetTableDirInfo(const void * pHdr, size_t & lOffset, size_t & lSize); michael@0: bool GetTableInfo(const Tag TableTag, const void * pHdr, const void * pTableDir, michael@0: size_t & lOffset, size_t & lSize); michael@0: bool CheckTable(const Tag TableId, const void * pTable, size_t lTableSize); michael@0: michael@0: ////////////////////////////////// simple font wide info michael@0: size_t GlyphCount(const void * pMaxp); michael@0: #ifdef ALL_TTFUTILS michael@0: size_t MaxCompositeComponentCount(const void * pMaxp); michael@0: size_t MaxCompositeLevelCount(const void * pMaxp); michael@0: size_t LocaGlyphCount(size_t lLocaSize, const void * pHead); // throw (std::domain_error); michael@0: #endif michael@0: int DesignUnits(const void * pHead); michael@0: #ifdef ALL_TTFUTILS michael@0: int HeadTableCheckSum(const void * pHead); michael@0: void HeadTableCreateTime(const void * pHead, unsigned int * pnDateBC, unsigned int * pnDateAD); michael@0: void HeadTableModifyTime(const void * pHead, unsigned int * pnDateBC, unsigned int * pnDateAD); michael@0: bool IsItalic(const void * pHead); michael@0: int FontAscent(const void * pOs2); michael@0: int FontDescent(const void * pOs2); michael@0: bool FontOs2Style(const void *pOs2, bool & fBold, bool & fItalic); michael@0: bool Get31EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize); michael@0: bool Get31EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize); michael@0: bool Get30EngFamilyInfo(const void * pName, size_t & lOffset, size_t & lSize); michael@0: bool Get30EngFullFontInfo(const void * pName, size_t & lOffset, size_t & lSize); michael@0: int PostLookup(const void * pPost, size_t lPostSize, const void * pMaxp, michael@0: const char * pPostName); michael@0: #endif michael@0: michael@0: ////////////////////////////////// utility methods helpful for name table michael@0: bool GetNameInfo(const void * pName, int nPlatformId, int nEncodingId, michael@0: int nLangId, int nNameId, size_t & lOffset, size_t & lSize); michael@0: //size_t NameTableLength(const byte * pTable); michael@0: #ifdef ALL_TTFUTILS michael@0: int GetLangsForNames(const void * pName, int nPlatformId, int nEncodingId, michael@0: int *nameIdList, int cNameIds, short *langIdList); michael@0: void SwapWString(void * pWStr, size_t nSize = 0); // throw (std::invalid_argument); michael@0: #endif michael@0: michael@0: ////////////////////////////////// cmap lookup tools michael@0: const void * FindCmapSubtable(const void * pCmap, int nPlatformId = 3, michael@0: int nEncodingId = 1, size_t length = 0); michael@0: bool CheckCmapSubtable4(const void * pCmap31); michael@0: gid16 CmapSubtable4Lookup(const void * pCmapSubtabel4, unsigned int nUnicodeId, int rangeKey = 0); michael@0: unsigned int CmapSubtable4NextCodepoint(const void *pCmap31, unsigned int nUnicodeId, michael@0: int * pRangeKey = 0); michael@0: bool CheckCmapSubtable12(const void *pCmap310); michael@0: gid16 CmapSubtable12Lookup(const void * pCmap310, unsigned int uUnicodeId, int rangeKey = 0); michael@0: unsigned int CmapSubtable12NextCodepoint(const void *pCmap310, unsigned int nUnicodeId, michael@0: int * pRangeKey = 0); michael@0: michael@0: ///////////////////////////////// horizontal metric data for a glyph michael@0: bool HorMetrics(gid16 nGlyphId, const void * pHmtx, size_t lHmtxSize, michael@0: const void * pHhea, int & nLsb, unsigned int & nAdvWid); michael@0: michael@0: ////////////////////////////////// primitives for loca and glyf lookup michael@0: size_t LocaLookup(gid16 nGlyphId, const void * pLoca, size_t lLocaSize, michael@0: const void * pHead); // throw (std::out_of_range); michael@0: void * GlyfLookup(const void * pGlyf, size_t lGlyfOffset, size_t lTableLen); michael@0: michael@0: ////////////////////////////////// primitves for simple glyph data michael@0: bool GlyfBox(const void * pSimpleGlyf, int & xMin, int & yMin, michael@0: int & xMax, int & yMax); michael@0: michael@0: #ifdef ALL_TTFUTILS michael@0: int GlyfContourCount(const void * pSimpleGlyf); michael@0: bool GlyfContourEndPoints(const void * pSimpleGlyf, int * prgnContourEndPoint, michael@0: int cnPointsTotal, size_t & cnPoints); michael@0: bool GlyfPoints(const void * pSimpleGlyf, int * prgnX, int * prgnY, michael@0: char * prgbFlag, int cnPointsTotal, int & cnPoints); michael@0: michael@0: // primitive to find the glyph ids in a composite glyph michael@0: bool GetComponentGlyphIds(const void * pSimpleGlyf, int * prgnCompId, michael@0: size_t cnCompIdTotal, size_t & cnCompId); michael@0: // primitive to find the placement data for a component in a composite glyph michael@0: bool GetComponentPlacement(const void * pSimpleGlyf, int nCompId, michael@0: bool fOffset, int & a, int & b); michael@0: // primitive to find the transform data for a component in a composite glyph michael@0: bool GetComponentTransform(const void * pSimpleGlyf, int nCompId, michael@0: float & flt11, float & flt12, float & flt21, float & flt22, bool & fTransOffset); michael@0: #endif michael@0: michael@0: ////////////////////////////////// operate on composite or simple glyph (auto glyf lookup) michael@0: void * GlyfLookup(gid16 nGlyphId, const void * pGlyf, const void * pLoca, michael@0: size_t lGlyfSize, size_t lLocaSize, const void * pHead); // primitive used by below methods michael@0: michael@0: #ifdef ALL_TTFUTILS michael@0: // below are primary user methods for handling glyf data michael@0: bool IsSpace(gid16 nGlyphId, const void * pLoca, size_t lLocaSize, const void * pHead); michael@0: bool IsDeepComposite(gid16 nGlyphId, const void * pGlyf, const void * pLoca, michael@0: size_t lGlyfSize, size_t lLocaSize, const void * pHead); michael@0: michael@0: bool GlyfBox(gid16 nGlyphId, const void * pGlyf, const void * pLoca, size_t lGlyfSize, size_t lLocaSize, michael@0: const void * pHead, int & xMin, int & yMin, int & xMax, int & yMax); michael@0: bool GlyfContourCount(gid16 nGlyphId, const void * pGlyf, const void * pLoca, michael@0: size_t lGlyfSize, size_t lLocaSize, const void *pHead, size_t & cnContours); michael@0: bool GlyfContourEndPoints(gid16 nGlyphId, const void * pGlyf, const void * pLoca, michael@0: size_t lGlyfSize, size_t lLocaSize, const void * pHead, int * prgnContourEndPoint, size_t cnPoints); michael@0: bool GlyfPoints(gid16 nGlyphId, const void * pGlyf, const void * pLoca, michael@0: size_t lGlyfSize, size_t lLocaSize, const void * pHead, const int * prgnContourEndPoint, size_t cnEndPoints, michael@0: int * prgnX, int * prgnY, bool * prgfOnCurve, size_t cnPoints); michael@0: michael@0: // utitily method used by high-level GlyfPoints michael@0: bool SimplifyFlags(char * prgbFlags, int cnPoints); michael@0: bool CalcAbsolutePoints(int * prgnX, int * prgnY, int cnPoints); michael@0: #endif michael@0: michael@0: } // end of namespace TtfUtil michael@0: } // end of namespace graphite2