📄 fofitruetype.cc
字号:
//========================================================================//// FoFiTrueType.cc//// Copyright 1999-2003 Glyph & Cog, LLC////========================================================================#include <aconf.h>#ifdef USE_GCC_PRAGMAS#pragma implementation#endif#include <stdlib.h>#include <string.h>#include "gtypes.h"#include "gmem.h"#include "GString.h"#include "GHash.h"#include "FoFiType1C.h"#include "FoFiTrueType.h"//// Terminology// -----------//// character code = number used as an element of a text string//// character name = glyph name = name for a particular glyph within a// font//// glyph index = GID = position (within some internal table in the font)// where the instructions to draw a particular glyph are// stored//// Type 1 fonts// ------------//// Type 1 fonts contain://// Encoding: array of glyph names, maps char codes to glyph names//// Encoding[charCode] = charName//// CharStrings: dictionary of instructions, keyed by character names,// maps character name to glyph data//// CharStrings[charName] = glyphData//// TrueType fonts// --------------//// TrueType fonts contain://// 'cmap' table: mapping from character code to glyph index; there may// be multiple cmaps in a TrueType font//// cmap[charCode] = gid//// 'post' table: mapping from glyph index to glyph name//// post[gid] = glyphName//// Type 42 fonts// -------------//// Type 42 fonts contain://// Encoding: array of glyph names, maps char codes to glyph names//// Encoding[charCode] = charName//// CharStrings: dictionary of glyph indexes, keyed by character names,// maps character name to glyph index//// CharStrings[charName] = gid////------------------------------------------------------------------------#define ttcfTag 0x74746366//------------------------------------------------------------------------struct TrueTypeTable { Guint tag; Guint checksum; int offset; int origOffset; int len;};struct TrueTypeCmap { int platform; int encoding; int offset; int len; int fmt;};struct TrueTypeLoca { int idx; int origOffset; int newOffset; int len;};#define cmapTag 0x636d6170#define glyfTag 0x676c7966#define headTag 0x68656164#define hheaTag 0x68686561#define hmtxTag 0x686d7478#define locaTag 0x6c6f6361#define nameTag 0x6e616d65#define os2Tag 0x4f532f32#define postTag 0x706f7374static int cmpTrueTypeLocaOffset(const void *p1, const void *p2) { TrueTypeLoca *loca1 = (TrueTypeLoca *)p1; TrueTypeLoca *loca2 = (TrueTypeLoca *)p2; if (loca1->origOffset == loca2->origOffset) { return loca1->idx - loca2->idx; } return loca1->origOffset - loca2->origOffset;}static int cmpTrueTypeLocaIdx(const void *p1, const void *p2) { TrueTypeLoca *loca1 = (TrueTypeLoca *)p1; TrueTypeLoca *loca2 = (TrueTypeLoca *)p2; return loca1->idx - loca2->idx;}static int cmpTrueTypeTableTag(const void *p1, const void *p2) { TrueTypeTable *tab1 = (TrueTypeTable *)p1; TrueTypeTable *tab2 = (TrueTypeTable *)p2; return (int)tab1->tag - (int)tab2->tag;}//------------------------------------------------------------------------struct T42Table { char *tag; // 4-byte tag GBool required; // required by the TrueType spec?};// TrueType tables to be embedded in Type 42 fonts.// NB: the table names must be in alphabetical order here.#define nT42Tables 11static T42Table t42Tables[nT42Tables] = { { "cvt ", gTrue }, { "fpgm", gTrue }, { "glyf", gTrue }, { "head", gTrue }, { "hhea", gTrue }, { "hmtx", gTrue }, { "loca", gTrue }, { "maxp", gTrue }, { "prep", gTrue }, { "vhea", gFalse }, { "vmtx", gFalse }};#define t42HeadTable 3#define t42LocaTable 6#define t42GlyfTable 2#define t42VheaTable 9#define t42VmtxTable 10//------------------------------------------------------------------------// Glyph names in some arbitrary standard order that Apple uses for// their TrueType fonts.static char *macGlyphNames[258] = { ".notdef", "null", "CR", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex", "adieresis", "atilde", "aring", "ccedilla", "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave", "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", "section", "bullet", "paragraph", "germandbls", "registered", "copyright", "trademark", "acute", "dieresis", "notequal", "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen", "mu1", "partialdiff", "summation", "product", "pi", "integral", "ordfeminine", "ordmasculine", "Ohm", "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical", "florin", "approxequal", "increment", "guillemotleft", "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde", "Otilde", "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide", "lozenge", "ydieresis", "Ydieresis", "fraction", "currency", "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex", "applelogo", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi", "circumflex", "tilde", "overscore", "breve", "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron", "Zcaron", "zcaron", "brokenbar", "Eth", "eth", "Yacute", "yacute", "Thorn", "thorn", "minus", "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", "onequarter", "threequarters", "franc", "Gbreve", "gbreve", "Idot", "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron", "ccaron", "dmacron"};//------------------------------------------------------------------------// FoFiTrueType//------------------------------------------------------------------------FoFiTrueType *FoFiTrueType::make(char *fileA, int lenA) { FoFiTrueType *ff; ff = new FoFiTrueType(fileA, lenA, gFalse); if (!ff->parsedOk) { delete ff; return NULL; } return ff;}FoFiTrueType *FoFiTrueType::load(char *fileName) { FoFiTrueType *ff; char *fileA; int lenA; if (!(fileA = FoFiBase::readFile(fileName, &lenA))) { return NULL; } ff = new FoFiTrueType(fileA, lenA, gTrue); if (!ff->parsedOk) { delete ff; return NULL; } return ff;}FoFiTrueType::FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA): FoFiBase(fileA, lenA, freeFileDataA){ tables = NULL; nTables = 0; cmaps = NULL; nCmaps = 0; nameToGID = NULL; parsedOk = gFalse; parse();}FoFiTrueType::~FoFiTrueType() { gfree(tables); gfree(cmaps); if (nameToGID) { delete nameToGID; }}int FoFiTrueType::getNumCmaps() { return nCmaps;}int FoFiTrueType::getCmapPlatform(int i) { return cmaps[i].platform;}int FoFiTrueType::getCmapEncoding(int i) { return cmaps[i].encoding;}int FoFiTrueType::findCmap(int platform, int encoding) { int i; for (i = 0; i < nCmaps; ++i) { if (cmaps[i].platform == platform && cmaps[i].encoding == encoding) { return i; } } return -1;}Gushort FoFiTrueType::mapCodeToGID(int i, int c) { Gushort gid; int segCnt, segEnd, segStart, segDelta, segOffset; int cmapFirst, cmapLen; int pos, a, b, m; GBool ok; if (i < 0 || i >= nCmaps) { return 0; } ok = gTrue; pos = cmaps[i].offset; switch (cmaps[i].fmt) { case 0: if (c < 0 || c >= cmaps[i].len - 6) { return 0; } gid = getU8(cmaps[i].offset + 6 + c, &ok); break; case 4: segCnt = getU16BE(pos + 6, &ok) / 2; a = -1; b = segCnt - 1; segEnd = getU16BE(pos + 14 + 2*b, &ok); if (c > segEnd) { // malformed font -- the TrueType spec requires the last segEnd // to be 0xffff return 0; } // invariant: seg[a].end < code <= seg[b].end while (b - a > 1 && ok) { m = (a + b) / 2; segEnd = getU16BE(pos + 14 + 2*m, &ok); if (segEnd < c) { a = m; } else { b = m; } } segStart = getU16BE(pos + 16 + 2*segCnt + 2*b, &ok); segDelta = getU16BE(pos + 16 + 4*segCnt + 2*b, &ok); segOffset = getU16BE(pos + 16 + 6*segCnt + 2*b, &ok); if (c < segStart) { return 0; } if (segOffset == 0) { gid = (c + segDelta) & 0xffff; } else { gid = getU16BE(pos + 16 + 6*segCnt + 2*b + segOffset + 2 * (c - segStart), &ok); if (gid != 0) { gid = (gid + segDelta) & 0xffff; } } break; case 6: cmapFirst = getU16BE(pos + 6, &ok); cmapLen = getU16BE(pos + 8, &ok); if (c < cmapFirst || c >= cmapFirst + cmapLen) { return 0; } gid = getU16BE(pos + 10 + 2 * (c - cmapFirst), &ok); break; default: return 0; } if (!ok) { return 0; } return gid;}int FoFiTrueType::mapNameToGID(char *name) { if (!nameToGID) { return 0; } return nameToGID->lookupInt(name);}Gushort *FoFiTrueType::getCIDToGIDMap(int *nCIDs) { FoFiType1C *ff; Gushort *map; int i; *nCIDs = 0; if (!openTypeCFF) { return NULL; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -