📄 fofitype1c.cc
字号:
cvtNum(ops[5].num, ops[5].isFP, charBuf); charBuf->append((char)8); cvtNum(ops[6].num, ops[6].isFP, charBuf); cvtNum(ops[7].num, ops[7].isFP, charBuf); cvtNum(ops[8].num, ops[8].isFP, charBuf); cvtNum(ops[9].num, ops[9].isFP, charBuf); dx = ops[0].num + ops[2].num + ops[4].num + ops[6].num + ops[8].num; dy = ops[1].num + ops[3].num + ops[5].num + ops[7].num + ops[9].num; if (fabs(dx) > fabs(dy)) { cvtNum(ops[10].num, ops[10].isFP, charBuf); cvtNum(-dy, ops[1].isFP | ops[3].isFP | ops[5].isFP | ops[7].isFP | ops[9].isFP, charBuf); } else { cvtNum(-dx, ops[0].isFP | ops[2].isFP | ops[4].isFP | ops[6].isFP | ops[8].isFP, charBuf); cvtNum(ops[10].num, ops[10].isFP, charBuf); } charBuf->append((char)8); nOps = 0; openPath = gTrue; break; default: //~ error(-1, "Illegal Type 2 charstring op: %04x", //~ ops[nOps].op); nOps = 0; break; } } } // charstring encryption if (top) { r2 = 4330; for (i = start; i < charBuf->getLength(); ++i) { byte = charBuf->getChar(i) ^ (r2 >> 8); charBuf->setChar(i, byte); r2 = (byte + r2) * 52845 + 22719; } }}void FoFiType1C::cvtGlyphWidth(GBool useOp, GString *charBuf, Type1CPrivateDict *pDict) { double w; GBool wFP; int i; if (useOp) { w = pDict->nominalWidthX + ops[0].num; wFP = pDict->nominalWidthXFP | ops[0].isFP; for (i = 1; i < nOps; ++i) { ops[i-1] = ops[i]; } --nOps; } else { w = pDict->defaultWidthX; wFP = pDict->defaultWidthXFP; } cvtNum(0, gFalse, charBuf); cvtNum(w, wFP, charBuf); charBuf->append((char)13);}void FoFiType1C::cvtNum(double x, GBool isFP, GString *charBuf) { Guchar buf[12]; int y, n; n = 0; if (isFP) { if (x >= -32768 && x < 32768) { y = (int)(x * 256.0); buf[0] = 255; buf[1] = (Guchar)(y >> 24); buf[2] = (Guchar)(y >> 16); buf[3] = (Guchar)(y >> 8); buf[4] = (Guchar)y; buf[5] = 255; buf[6] = 0; buf[7] = 0; buf[8] = 1; buf[9] = 0; buf[10] = 12; buf[11] = 12; n = 12; } else { //~ error(-1, "Type 2 fixed point constant out of range"); } } else { y = (int)x; if (y >= -107 && y <= 107) { buf[0] = (Guchar)(y + 139); n = 1; } else if (y > 107 && y <= 1131) { y -= 108; buf[0] = (Guchar)((y >> 8) + 247); buf[1] = (Guchar)(y & 0xff); n = 2; } else if (y < -107 && y >= -1131) { y = -y - 108; buf[0] = (Guchar)((y >> 8) + 251); buf[1] = (Guchar)(y & 0xff); n = 2; } else { buf[0] = 255; buf[1] = (Guchar)(y >> 24); buf[2] = (Guchar)(y >> 16); buf[3] = (Guchar)(y >> 8); buf[4] = (Guchar)y; n = 5; } } charBuf->append((char *)buf, n);}void FoFiType1C::eexecWrite(Type1CEexecBuf *eb, char *s) { Guchar *p; Guchar x; for (p = (Guchar *)s; *p; ++p) { x = *p ^ (eb->r1 >> 8); eb->r1 = (x + eb->r1) * 52845 + 22719; if (eb->ascii) { (*eb->outputFunc)(eb->outputStream, &hexChars[x >> 4], 1); (*eb->outputFunc)(eb->outputStream, &hexChars[x & 0x0f], 1); eb->line += 2; if (eb->line == 64) { (*eb->outputFunc)(eb->outputStream, "\n", 1); eb->line = 0; } } else { (*eb->outputFunc)(eb->outputStream, (char *)&x, 1); } }}void FoFiType1C::eexecWriteCharstring(Type1CEexecBuf *eb, Guchar *s, int n) { Guchar x; int i; // eexec encryption for (i = 0; i < n; ++i) { x = s[i] ^ (eb->r1 >> 8); eb->r1 = (x + eb->r1) * 52845 + 22719; if (eb->ascii) { (*eb->outputFunc)(eb->outputStream, &hexChars[x >> 4], 1); (*eb->outputFunc)(eb->outputStream, &hexChars[x & 0x0f], 1); eb->line += 2; if (eb->line == 64) { (*eb->outputFunc)(eb->outputStream, "\n", 1); eb->line = 0; } } else { (*eb->outputFunc)(eb->outputStream, (char *)&x, 1); } }}GBool FoFiType1C::parse() { Type1CIndex fdIdx; Type1CIndexVal val; int i; parsedOk = gTrue; // some tools embed Type 1C fonts with an extra whitespace char at // the beginning if (len > 0 && file[0] != '\x01') { ++file; --len; } // find the indexes getIndex(getU8(2, &parsedOk), &nameIdx, &parsedOk); getIndex(nameIdx.endPos, &topDictIdx, &parsedOk); getIndex(topDictIdx.endPos, &stringIdx, &parsedOk); getIndex(stringIdx.endPos, &gsubrIdx, &parsedOk); if (!parsedOk) { return gFalse; } gsubrBias = (gsubrIdx.len < 1240) ? 107 : (gsubrIdx.len < 33900) ? 1131 : 32768; // read the first font name getIndexVal(&nameIdx, 0, &val, &parsedOk); if (!parsedOk) { return gFalse; } name = new GString((char *)&file[val.pos], val.len); // read the top dict for the first font readTopDict(); // for CID fonts: read the FDArray dicts and private dicts if (topDict.firstOp == 0x0c1e) { if (topDict.fdArrayOffset == 0) { nFDs = 1; privateDicts = (Type1CPrivateDict *)gmalloc(sizeof(Type1CPrivateDict)); readPrivateDict(0, 0, &privateDicts[0]); } else { getIndex(topDict.fdArrayOffset, &fdIdx, &parsedOk); if (!parsedOk) { return gFalse; } nFDs = fdIdx.len; privateDicts = (Type1CPrivateDict *) gmallocn(nFDs, sizeof(Type1CPrivateDict)); for (i = 0; i < nFDs; ++i) { getIndexVal(&fdIdx, i, &val, &parsedOk); if (!parsedOk) { return gFalse; } readFD(val.pos, val.len, &privateDicts[i]); } } // for 8-bit fonts: read the private dict } else { privateDicts = (Type1CPrivateDict *)gmalloc(sizeof(Type1CPrivateDict)); readPrivateDict(topDict.privateOffset, topDict.privateSize, &privateDicts[0]); } // check for parse errors in the private dict(s) if (!parsedOk) { return gFalse; } // get the charstrings index if (topDict.charStringsOffset <= 0) { parsedOk = gFalse; return gFalse; } getIndex(topDict.charStringsOffset, &charStringsIdx, &parsedOk); if (!parsedOk) { return gFalse; } nGlyphs = charStringsIdx.len; // for CID fonts: read the FDSelect table if (topDict.firstOp == 0x0c1e) { readFDSelect(); if (!parsedOk) { return gFalse; } } // read the charset if (!readCharset()) { parsedOk = gFalse; return gFalse; } // for 8-bit fonts: build the encoding if (topDict.firstOp != 0x0c14 && topDict.firstOp != 0x0c1e) { buildEncoding(); if (!parsedOk) { return gFalse; } } return parsedOk;}void FoFiType1C::readTopDict() { Type1CIndexVal topDictPtr; int pos; topDict.firstOp = -1; topDict.versionSID = 0; topDict.noticeSID = 0; topDict.copyrightSID = 0; topDict.fullNameSID = 0; topDict.familyNameSID = 0; topDict.weightSID = 0; topDict.isFixedPitch = 0; topDict.italicAngle = 0; topDict.underlinePosition = -100; topDict.underlineThickness = 50; topDict.paintType = 0; topDict.charstringType = 2; topDict.fontMatrix[0] = 0.001; topDict.fontMatrix[1] = 0; topDict.fontMatrix[2] = 0; topDict.fontMatrix[3] = 0.001; topDict.fontMatrix[4] = 0; topDict.fontMatrix[5] = 0; topDict.hasFontMatrix = gFalse; topDict.uniqueID = 0; topDict.fontBBox[0] = 0; topDict.fontBBox[1] = 0; topDict.fontBBox[2] = 0; topDict.fontBBox[3] = 0; topDict.strokeWidth = 0; topDict.charsetOffset = 0; topDict.encodingOffset = 0; topDict.charStringsOffset = 0; topDict.privateSize = 0; topDict.privateOffset = 0; topDict.registrySID = 0; topDict.orderingSID = 0; topDict.supplement = 0; topDict.fdArrayOffset = 0; topDict.fdSelectOffset = 0; getIndexVal(&topDictIdx, 0, &topDictPtr, &parsedOk); pos = topDictPtr.pos; nOps = 0; while (pos < topDictPtr.pos + topDictPtr.len) { pos = getOp(pos, gFalse, &parsedOk); if (!parsedOk) { break; } if (!ops[nOps - 1].isNum) { --nOps; // drop the operator if (topDict.firstOp < 0) { topDict.firstOp = ops[nOps].op; } switch (ops[nOps].op) { case 0x0000: topDict.versionSID = (int)ops[0].num; break; case 0x0001: topDict.noticeSID = (int)ops[0].num; break; case 0x0c00: topDict.copyrightSID = (int)ops[0].num; break; case 0x0002: topDict.fullNameSID = (int)ops[0].num; break; case 0x0003: topDict.familyNameSID = (int)ops[0].num; break; case 0x0004: topDict.weightSID = (int)ops[0].num; break; case 0x0c01: topDict.isFixedPitch = (int)ops[0].num; break; case 0x0c02: topDict.italicAngle = ops[0].num; break; case 0x0c03: topDict.underlinePosition = ops[0].num; break; case 0x0c04: topDict.underlineThickness = ops[0].num; break; case 0x0c05: topDict.paintType = (int)ops[0].num; break; case 0x0c06: topDict.charstringType = (int)ops[0].num; break; case 0x0c07: topDict.fontMatrix[0] = ops[0].num; topDict.fontMatrix[1] = ops[1].num; topDict.fontMatrix[2] = ops[2].num; topDict.fontMatrix[3] = ops[3].num; topDict.fontMatrix[4] = ops[4].num; topDict.fontMatrix[5] = ops[5].num; topDict.hasFontMatrix = gTrue; break; case 0x000d: topDict.uniqueID = (int)ops[0].num; break; case 0x0005: topDict.fontBBox[0] = ops[0].num; topDict.fontBBox[1] = ops[1].num; topDict.fontBBox[2] = ops[2].num; topDict.fontBBox[3] = ops[3].num; break; case 0x0c08: topDict.strokeWidth = ops[0].num; break; case 0x000f: topDict.charsetOffset = (int)ops[0].num; break; case 0x0010: topDict.encodingOffset = (int)ops[0].num; break; case 0x0011: topDict.charStringsOffset = (int)ops[0].num; break; case 0x0012: topDict.privateSize = (int)ops[0].num; topDict.privateOffset = (int)ops[1].num; break; case 0x0c1e: topDict.registrySID = (int)ops[0].num; topDict.orderingSID = (int)ops[1].num; topDict.supplement = (int)ops[2].num; break; case 0x0c24: topDict.fdArrayOffset = (int)ops[0].num; break; case 0x0c25: topDict.fdSelectOffset = (int)ops[0].num; break; } nOps = 0; } }}// Read a CID font dict (FD) - this pulls out the private dict// pointer, and reads the private dict. It also pulls the FontMatrix// (if any) out of the FD.void FoFiType1C::readFD(int offset, int length, Type1CPrivateDict *pDict) { int pos, pSize, pOffset; double fontMatrix[6]; GBool hasFontMatrix; hasFontMatrix = gFalse; pSize = pOffset = 0; pos = offset; nOps = 0; while (pos < offset + length) { pos = getOp(pos, gFalse, &parsedOk); if (!parsedOk) { return; } if (!ops[nOps - 1].isNum) { if (ops[nOps - 1].op == 0x0012) { if (nOps < 3) { parsedOk = gFalse; return; } pSize = (int)ops[0].num; pOffset = (int)ops[1].num; break; } else if (ops[nOps - 1].op == 0x0c07) { fontMatrix[0] = ops[0].num; fontMatrix[1] = ops[1].num; fontMatrix[2] = ops[2].num; fontMatrix[3] = ops[3].num; fontMatrix[4] = ops[4].num; fontMatrix[5] = ops[5].num; hasFontMatrix = gTrue; } nOps = 0; } } readPrivateDict(pOffset, pSize, pDict); if (hasFontMatrix) { pDict->fontMatrix[0] = fontMatrix[0]; pDict->fontMatrix[1] = fontMatrix[1]; pDict->fontMatrix[2] = fontMatrix[2]; pDict->fontMatrix[3] = fontMatrix[3]; pDict->fontMatrix[4] = fontMatrix[4]; pDict->fontMatrix[5] = fontMatrix[5]; pDict->hasFontMatrix = gTrue; }}void FoFiType1C::readPrivateDict(int offset, int length, Type1CPrivateDict *pDict) { int pos; pDict->hasFontMatrix = gFalse; pDict->nBlueValues = 0; pDict->nOtherBlues = 0; pDict->nFamilyBlues =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -