📄 fontfile.cc
字号:
} // write the descendant Type 1 fonts for (i = 0; i < nCIDs; i += 256) { //~ this assumes that all CIDs in this block have the same FD -- //~ to handle multiple FDs correctly, need to somehow divide the //~ font up by FD fd = 0; for (j = 0; j < 256 && i+j < nCIDs; ++j) { if (cidMap[i+j] >= 0) { fd = fdSelect[cidMap[i+j]]; break; } } // font dictionary (unencrypted section) (*outputFunc)(outputStream, "16 dict begin\n", 14); (*outputFunc)(outputStream, "/FontName /", 11); (*outputFunc)(outputStream, psName, strlen(psName)); sprintf(buf, "_%02x def\n", i >> 8); (*outputFunc)(outputStream, buf, strlen(buf)); (*outputFunc)(outputStream, "/FontType 1 def\n", 16); sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n", dict.fontMatrix[0], dict.fontMatrix[1], dict.fontMatrix[2], dict.fontMatrix[3], dict.fontMatrix[4], dict.fontMatrix[5]); (*outputFunc)(outputStream, buf, strlen(buf)); sprintf(buf, "/FontBBox [%g %g %g %g] def\n", dict.fontBBox[0], dict.fontBBox[1], dict.fontBBox[2], dict.fontBBox[3]); (*outputFunc)(outputStream, buf, strlen(buf)); sprintf(buf, "/PaintType %d def\n", dict.paintType); (*outputFunc)(outputStream, buf, strlen(buf)); if (dict.paintType != 0) { sprintf(buf, "/StrokeWidth %g def\n", dict.strokeWidth); (*outputFunc)(outputStream, buf, strlen(buf)); } (*outputFunc)(outputStream, "/Encoding 256 array\n", 20); for (j = 0; j < 256 && i+j < nCIDs; ++j) { sprintf(buf, "dup %d /c%02x put\n", j, j); (*outputFunc)(outputStream, buf, strlen(buf)); } (*outputFunc)(outputStream, "readonly def\n", 13); (*outputFunc)(outputStream, "currentdict end\n", 16); // start the binary section (*outputFunc)(outputStream, "currentfile eexec\n", 18); r1 = 55665; line = 0; // start the private dictionary eexecWrite("\x83\xca\x73\xd5"); eexecWrite("dup /Private 32 dict dup begin\n"); eexecWrite("/RD {string currentfile exch readstring pop} executeonly def\n"); eexecWrite("/ND {noaccess def} executeonly def\n"); eexecWrite("/NP {noaccess put} executeonly def\n"); eexecWrite("/MinFeature {16 16} ND\n"); eexecWrite(privateDicts[fd].dictData->getCString()); defaultWidthX = privateDicts[fd].defaultWidthX; defaultWidthXFP = privateDicts[fd].defaultWidthXFP; nominalWidthX = privateDicts[fd].nominalWidthX; nominalWidthXFP = privateDicts[fd].nominalWidthXFP; // start the CharStrings sprintf(eBuf, "2 index /CharStrings 256 dict dup begin\n"); eexecWrite(eBuf); // write the .notdef CharString idxPtr0 = getIndexValPtr(charStringsIdxPtr, 0); idxPtr1 = getIndexValPtr(charStringsIdxPtr, 1); n = idxPtr1 - idxPtr0; eexecCvtGlyph(".notdef", idxPtr0, n); // write the CharStrings for (j = 0; j < 256 && i+j < nCIDs; ++j) { if (cidMap[i+j] >= 0) { idxPtr0 = getIndexValPtr(charStringsIdxPtr, cidMap[i+j]); idxPtr1 = getIndexValPtr(charStringsIdxPtr, cidMap[i+j]+1); n = idxPtr1 - idxPtr0; sprintf(buf, "c%02x", j); eexecCvtGlyph(buf, idxPtr0, n); } } eexecWrite("end\n"); eexecWrite("end\n"); eexecWrite("readonly put\n"); eexecWrite("noaccess put\n"); eexecWrite("dup /FontName get exch definefont pop\n"); eexecWrite("mark currentfile closefile\n"); // trailer if (line > 0) { (*outputFunc)(outputStream, "\n", 1); } for (j = 0; j < 8; ++j) { (*outputFunc)(outputStream, "0000000000000000000000000000000000000000000000000000000000000000\n", 65); } (*outputFunc)(outputStream, "cleartomark\n", 12); } // write the Type 0 parent font (*outputFunc)(outputStream, "16 dict begin\n", 14); (*outputFunc)(outputStream, "/FontName /", 11); (*outputFunc)(outputStream, psName, strlen(psName)); (*outputFunc)(outputStream, " def\n", 5); (*outputFunc)(outputStream, "/FontType 0 def\n", 16); (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); (*outputFunc)(outputStream, "/FMapType 2 def\n", 16); (*outputFunc)(outputStream, "/Encoding [\n", 12); for (i = 0; i < nCIDs; i += 256) { sprintf(buf, "%d\n", i >> 8); (*outputFunc)(outputStream, buf, strlen(buf)); } (*outputFunc)(outputStream, "] def\n", 6); (*outputFunc)(outputStream, "/FDepVector [\n", 14); for (i = 0; i < nCIDs; i += 256) { (*outputFunc)(outputStream, "/", 1); (*outputFunc)(outputStream, psName, strlen(psName)); sprintf(buf, "_%02x findfont\n", i >> 8); (*outputFunc)(outputStream, buf, strlen(buf)); } (*outputFunc)(outputStream, "] def\n", 6); (*outputFunc)(outputStream, "FontName currentdict end definefont pop\n", 40); // clean up for (i = 0; i < nFDs; ++i) { delete privateDicts[i].dictData; } gfree(privateDicts); gfree(cidMap); gfree(charset); gfree(fdSelect);}void Type1CFontFile::readTopDict(Type1CTopDict *dict) { Guchar *idxPtr0, *idxPtr1, *ptr; double x; GBool isFP; int key; int i; idxPtr0 = getIndexValPtr(topDictIdxPtr, 0); idxPtr1 = getIndexValPtr(topDictIdxPtr, 1); dict->version = 0; dict->notice = 0; dict->copyright = 0; dict->fullName = 0; dict->familyName = 0; dict->weight = 0; dict->isFixedPitch = 0; dict->italicAngle = 0; dict->underlinePosition = -100; dict->underlineThickness = 50; dict->paintType = 0; dict->charstringType = 2; dict->fontMatrix[0] = 0.001; dict->fontMatrix[1] = 0; dict->fontMatrix[2] = 0; dict->fontMatrix[3] = 0.001; dict->fontMatrix[4] = 0; dict->fontMatrix[5] = 0; dict->uniqueID = 0; dict->fontBBox[0] = 0; dict->fontBBox[1] = 0; dict->fontBBox[2] = 0; dict->fontBBox[3] = 0; dict->strokeWidth = 0; dict->charset = 0; dict->encoding = 0; dict->charStrings = 0; dict->privateSize = 0; dict->privateOffset = 0; dict->registry = 0; dict->ordering = 0; dict->supplement = 0; dict->fdArrayOffset = 0; dict->fdSelectOffset = 0; i = 0; ptr = idxPtr0; while (ptr < idxPtr1) { if (*ptr <= 27 || *ptr == 31) { key = *ptr++; if (key == 0x0c) { key = (key << 8) | *ptr++; } switch (key) { case 0x0000: dict->version = (int)op[0]; break; case 0x0001: dict->notice = (int)op[0]; break; case 0x0c00: dict->copyright = (int)op[0]; break; case 0x0002: dict->fullName = (int)op[0]; break; case 0x0003: dict->familyName = (int)op[0]; break; case 0x0004: dict->weight = (int)op[0]; break; case 0x0c01: dict->isFixedPitch = (int)op[0]; break; case 0x0c02: dict->italicAngle = op[0]; break; case 0x0c03: dict->underlinePosition = op[0]; break; case 0x0c04: dict->underlineThickness = op[0]; break; case 0x0c05: dict->paintType = (int)op[0]; break; case 0x0c06: dict->charstringType = (int)op[0]; break; case 0x0c07: dict->fontMatrix[0] = op[0]; dict->fontMatrix[1] = op[1]; dict->fontMatrix[2] = op[2]; dict->fontMatrix[3] = op[3]; dict->fontMatrix[4] = op[4]; dict->fontMatrix[5] = op[5]; break; case 0x000d: dict->uniqueID = (int)op[0]; break; case 0x0005: dict->fontBBox[0] = op[0]; dict->fontBBox[1] = op[1]; dict->fontBBox[2] = op[2]; dict->fontBBox[3] = op[3]; break; case 0x0c08: dict->strokeWidth = op[0]; break; case 0x000f: dict->charset = (int)op[0]; break; case 0x0010: dict->encoding = (int)op[0]; break; case 0x0011: dict->charStrings = (int)op[0]; break; case 0x0012: dict->privateSize = (int)op[0]; dict->privateOffset = (int)op[1]; break; case 0x0c1e: dict->registry = (int)op[0]; dict->ordering = (int)op[1]; dict->supplement = (int)op[2]; break; case 0x0c24: dict->fdArrayOffset = (int)op[0]; break; case 0x0c25: dict->fdSelectOffset = (int)op[0]; break; } i = 0; } else { x = getNum(&ptr, &isFP); if (i < 48) { op[i] = x; fp[i++] = isFP; } } }}void Type1CFontFile::readPrivateDict(Type1CPrivateDict *privateDict, int offset, int size) { Guchar *idxPtr0, *idxPtr1, *ptr; char eBuf[256]; int key; double x; GBool isFP; int i; privateDict->dictData = new GString(); privateDict->subrsOffset = 0; privateDict->defaultWidthX = 0; privateDict->defaultWidthXFP = gFalse; privateDict->nominalWidthX = 0; privateDict->nominalWidthXFP = gFalse; idxPtr0 = (Guchar *)file + offset; idxPtr1 = idxPtr0 + size; ptr = idxPtr0; i = 0; while (ptr < idxPtr1) { if (*ptr <= 27 || *ptr == 31) { key = *ptr++; if (key == 0x0c) { key = (key << 8) | *ptr++; } switch (key) { case 0x0006: getDeltaInt(eBuf, "BlueValues", op, i); privateDict->dictData->append(eBuf); break; case 0x0007: getDeltaInt(eBuf, "OtherBlues", op, i); privateDict->dictData->append(eBuf); break; case 0x0008: getDeltaInt(eBuf, "FamilyBlues", op, i); privateDict->dictData->append(eBuf); break; case 0x0009: getDeltaInt(eBuf, "FamilyOtherBlues", op, i); privateDict->dictData->append(eBuf); break; case 0x0c09: sprintf(eBuf, "/BlueScale %g def\n", op[0]); privateDict->dictData->append(eBuf); break; case 0x0c0a: sprintf(eBuf, "/BlueShift %d def\n", (int)op[0]); privateDict->dictData->append(eBuf); break; case 0x0c0b: sprintf(eBuf, "/BlueFuzz %d def\n", (int)op[0]); privateDict->dictData->append(eBuf); break; case 0x000a: sprintf(eBuf, "/StdHW [%g] def\n", op[0]); privateDict->dictData->append(eBuf); break; case 0x000b: sprintf(eBuf, "/StdVW [%g] def\n", op[0]); privateDict->dictData->append(eBuf); break; case 0x0c0c: getDeltaReal(eBuf, "StemSnapH", op, i); privateDict->dictData->append(eBuf); break; case 0x0c0d: getDeltaReal(eBuf, "StemSnapV", op, i); privateDict->dictData->append(eBuf); break; case 0x0c0e: sprintf(eBuf, "/ForceBold %s def\n", op[0] ? "true" : "false"); privateDict->dictData->append(eBuf); break; case 0x0c0f: sprintf(eBuf, "/ForceBoldThreshold %g def\n", op[0]); privateDict->dictData->append(eBuf); break; case 0x0c11: sprintf(eBuf, "/LanguageGroup %d def\n", (int)op[0]); privateDict->dictData->append(eBuf); break; case 0x0c12: sprintf(eBuf, "/ExpansionFactor %g def\n", op[0]); privateDict->dictData->append(eBuf); break; case 0x0c13: error(-1, "Got Type 1C InitialRandomSeed"); break; case 0x0013: privateDict->subrsOffset = (int)op[0]; break; case 0x0014: privateDict->defaultWidthX = op[0]; privateDict->defaultWidthXFP = fp[0]; break; case 0x0015: privateDict->nominalWidthX = op[0]; privateDict->nominalWidthXFP = fp[0]; break; default: error(-1, "Unknown Type 1C private dict entry %04x", key); break; } i = 0; } else { x = getNum(&ptr, &isFP); if (i < 48) { op[i] = x; fp[i++] = isFP; } } }}Gushort *Type1CFontFile::readCharset(int charset, int nGlyphs) { Gushort *glyphNames; Guchar *ptr; int charsetFormat, c; int nLeft, i, j; if (charset == 0) { glyphNames = type1CISOAdobeCharset; } else if (charset == 1) { glyphNames = type1CExpertCharset; } else if (charset == 2) { glyphNames = type1CExpertSubsetCharset; } else { glyphNames = (Gushort *)gmalloc(nGlyphs * sizeof(Gushort)); glyphNames[0] = 0; ptr = (Guchar *)file + charset; charsetFormat = *ptr++; if (charsetFormat == 0) { for (i = 1; i < nGlyphs; ++i) { glyphNames[i] = getWord(ptr, 2); ptr += 2; } } else if (charsetFormat == 1) { i = 1; while (i < nGlyphs) { c = getWord(ptr, 2); ptr += 2; nLeft = *ptr++; for (j = 0; j <= nLeft && i < nGlyphs; ++j) { glyphNames[i++] = c++; } } } else if (charsetFormat == 2) { i = 1; while (i < nGlyphs) { c = getWord(ptr, 2); ptr += 2; nLeft = getWord(ptr, 2); ptr += 2; for (j = 0; j <= nLeft && i < nGlyphs; ++j) { glyphNames[i++] = c++; } } } } return glyphNames;}void Type1CFontFile::eexecWrite(char *s) { Guchar *p; Guchar x; for (p = (Guchar *)s; *p; ++p) { x = *p ^ (r1 >> 8); r1 = (x + r1) * 52845 + 22719; (*outputFunc)(outputStream, &hexChars[x >> 4], 1); (*outputFunc)(outputStream, &hexChars[x & 0x0f], 1); line += 2; if (line == 64) { (*outputFunc)(outputStream, "\n", 1); line = 0; } }}void Type1CFontFile::eexecCvtGlyph(char *glyphName, Guchar *s, int n) { char eBuf[256]; cvtGlyph(s, n); sprintf(eBuf, "/%s %d RD ", glyphName, charBuf->getLength()); eexecWrite(eBuf); eexecWriteCharstring((Guchar *)charBuf->getCString(), charBuf->getLength()); eexecWrite(" ND\n"); delete charBuf;}void Type1CFontFile::cvtGlyph(Guchar *s, int n) { int nHints; int x; GBool first = gTrue; double d, dx, dy; GBool dFP; Gushort r2; Guchar byte; int i, k; charBuf = new GString(); charBuf->append((char)73); charBuf->append((char)58); charBuf->append((char)147); charBuf->append((char)134); i = 0; nOps = 0; nHints = 0; while (i < n) { if (s[i] == 12) { switch (s[i+1]) { case 0: // dotsection (should be Type 1 only?) // ignored break; case 34: // hflex if (nOps != 7) { error(-1, "Wrong number of args (%d) to Type 2 hflex", nOps); } eexecDumpNum(op[0], fp[0]); eexecDumpNum(0, gFalse); eexecDumpNum(op[1], fp[1]); eexecDumpNum(op[2], fp[2]); eexecDumpNum(op[3], fp[3]); eexecDumpNum(0, gFalse); eexecDumpOp1(8); eexecDumpNum(op[4], fp[4]); eexecDumpNum(0, gFalse); eexecDumpNum(op[5], fp[5]); eexecDumpNum(-op[2], fp[2]); eexecDumpNum(op[6], fp[6]); eexecDumpNum(0, gFalse); eexecDumpOp1(8); break; case 35: // flex if (nOps != 13) { error(-1, "Wrong number of args (%d) to Type 2 flex", nOps); } eexecDumpNum(op[0], fp[0]); eexecDumpNum(op[1], fp[1]); eexecDumpNum(op[2], fp[2]); eexecDumpNum(op[3], fp[3]); eexecDumpNum(op[4], fp[4]); eexecDumpNum(op[5], fp[5]); eexecDumpOp1(8); eexecDumpNum(op[6], fp[6]); eexecDumpNum(op[7], fp[7]); eexecDumpNum(op[8], fp[8]); eexecDumpNum(op[9], fp[9]); eexecDumpNum(op[10], fp[10]); eexecDumpNum(op[11], fp[11]); eexecDumpOp1(8); break; case 36: // hflex1 if (nOps != 9) { error(-1, "Wrong number of args (%d) to Type 2 hflex1", nOps); } eexecDumpNum(op[0], fp[0]); eexecDumpNum(op[1], fp[1]); eexecDumpNum(op[2], fp[2]); eexecDumpNum(op[3], fp[3]); eexecDumpNum(op[4], fp[4]); eexecDumpNum(0, gFalse); eexecDumpOp1(8); eexecDumpNum(op[5], fp[5]); eexecDumpNum(0, gFalse); eexecDumpNum(op[6], fp[6]); eexecDumpNum(op[7], fp[7]); eexecDumpNum(op[8], fp[8]); eexecDumpNum(-(op[1] + op[3] + op[7]), fp[1] | fp[3] | fp[7]); eexecDumpOp1(8); break; case 37: // flex1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -