fofitype1c.cc
来自「将pdf文档转换为高质量的html文档」· CC 代码 · 共 2,161 行 · 第 1/5 页
CC
2,161 行
//========================================================================//// FoFiType1C.cc//// Copyright 1999-2003 Glyph & Cog, LLC////========================================================================#include <aconf.h>#ifdef USE_GCC_PRAGMAS#pragma implementation#endif#include <stdlib.h>#include <string.h>#include <math.h>#include "gmem.h"#include "GString.h"#include "FoFiEncodings.h"#include "FoFiType1C.h"//------------------------------------------------------------------------static char hexChars[17] = "0123456789ABCDEF";//------------------------------------------------------------------------// FoFiType1C//------------------------------------------------------------------------FoFiType1C *FoFiType1C::make(char *fileA, int lenA) { FoFiType1C *ff; ff = new FoFiType1C(fileA, lenA, gFalse); if (!ff->parse()) { delete ff; return NULL; } return ff;}FoFiType1C *FoFiType1C::load(char *fileName) { FoFiType1C *ff; char *fileA; int lenA; if (!(fileA = FoFiBase::readFile(fileName, &lenA))) { return NULL; } ff = new FoFiType1C(fileA, lenA, gTrue); if (!ff->parse()) { delete ff; return NULL; } return ff;}FoFiType1C::FoFiType1C(char *fileA, int lenA, GBool freeFileDataA): FoFiBase(fileA, lenA, freeFileDataA){ name = NULL; encoding = NULL; privateDicts = NULL; fdSelect = NULL; charset = NULL;}FoFiType1C::~FoFiType1C() { int i; if (name) { delete name; } if (encoding && encoding != fofiType1StandardEncoding && encoding != fofiType1ExpertEncoding) { for (i = 0; i < 256; ++i) { gfree(encoding[i]); } gfree(encoding); } if (privateDicts) { gfree(privateDicts); } if (fdSelect) { gfree(fdSelect); } if (charset && charset != fofiType1CISOAdobeCharset && charset != fofiType1CExpertCharset && charset != fofiType1CExpertSubsetCharset) { gfree(charset); }}char *FoFiType1C::getName() { return name ? name->getCString() : (char *)NULL;}char **FoFiType1C::getEncoding() { return encoding;}Gushort *FoFiType1C::getCIDToGIDMap(int *nCIDs) { Gushort *map; int n, i; // a CID font's top dict has ROS as the first operator if (topDict.firstOp != 0x0c1e) { *nCIDs = 0; return NULL; } // in a CID font, the charset data is the GID-to-CID mapping, so all // we have to do is reverse it n = 0; for (i = 0; i < nGlyphs; ++i) { if (charset[i] > n) { n = charset[i]; } } ++n; map = (Gushort *)gmallocn(n, sizeof(Gushort)); memset(map, 0, n * sizeof(Gushort)); for (i = 0; i < nGlyphs; ++i) { map[charset[i]] = i; } *nCIDs = n; return map;}void FoFiType1C::convertToType1(char **newEncoding, GBool ascii, FoFiOutputFunc outputFunc, void *outputStream) { Type1CEexecBuf eb; Type1CIndex subrIdx; Type1CIndexVal val; char buf[512]; char **enc; GBool ok; int i; // write header and font dictionary, up to encoding ok = gTrue; (*outputFunc)(outputStream, "%!FontType1-1.0: ", 17); (*outputFunc)(outputStream, name->getCString(), name->getLength()); if (topDict.versionSID != 0) { getString(topDict.versionSID, buf, &ok); (*outputFunc)(outputStream, buf, strlen(buf)); } (*outputFunc)(outputStream, "\n", 1); // the dictionary needs room for 12 entries: the following 9, plus // Private and CharStrings (in the eexec section) and FID (which is // added by definefont) (*outputFunc)(outputStream, "12 dict begin\n", 14); (*outputFunc)(outputStream, "/FontInfo 10 dict dup begin\n", 28); if (topDict.versionSID != 0) { (*outputFunc)(outputStream, "/version (", 10); (*outputFunc)(outputStream, buf, strlen(buf)); (*outputFunc)(outputStream, ") readonly def\n", 15); } if (topDict.noticeSID != 0) { getString(topDict.noticeSID, buf, &ok); (*outputFunc)(outputStream, "/Notice (", 9); (*outputFunc)(outputStream, buf, strlen(buf)); (*outputFunc)(outputStream, ") readonly def\n", 15); } if (topDict.copyrightSID != 0) { getString(topDict.copyrightSID, buf, &ok); (*outputFunc)(outputStream, "/Copyright (", 12); (*outputFunc)(outputStream, buf, strlen(buf)); (*outputFunc)(outputStream, ") readonly def\n", 15); } if (topDict.fullNameSID != 0) { getString(topDict.fullNameSID, buf, &ok); (*outputFunc)(outputStream, "/FullName (", 11); (*outputFunc)(outputStream, buf, strlen(buf)); (*outputFunc)(outputStream, ") readonly def\n", 15); } if (topDict.familyNameSID != 0) { getString(topDict.familyNameSID, buf, &ok); (*outputFunc)(outputStream, "/FamilyName (", 13); (*outputFunc)(outputStream, buf, strlen(buf)); (*outputFunc)(outputStream, ") readonly def\n", 15); } if (topDict.weightSID != 0) { getString(topDict.weightSID, buf, &ok); (*outputFunc)(outputStream, "/Weight (", 9); (*outputFunc)(outputStream, buf, strlen(buf)); (*outputFunc)(outputStream, ") readonly def\n", 15); } if (topDict.isFixedPitch) { (*outputFunc)(outputStream, "/isFixedPitch true def\n", 23); } else { (*outputFunc)(outputStream, "/isFixedPitch false def\n", 24); } sprintf(buf, "/ItalicAngle %g def\n", topDict.italicAngle); (*outputFunc)(outputStream, buf, strlen(buf)); sprintf(buf, "/UnderlinePosition %g def\n", topDict.underlinePosition); (*outputFunc)(outputStream, buf, strlen(buf)); sprintf(buf, "/UnderlineThickness %g def\n", topDict.underlineThickness); (*outputFunc)(outputStream, buf, strlen(buf)); (*outputFunc)(outputStream, "end readonly def\n", 17); (*outputFunc)(outputStream, "/FontName /", 11); (*outputFunc)(outputStream, name->getCString(), name->getLength()); (*outputFunc)(outputStream, " def\n", 5); sprintf(buf, "/PaintType %d def\n", topDict.paintType); (*outputFunc)(outputStream, buf, strlen(buf)); (*outputFunc)(outputStream, "/FontType 1 def\n", 16); sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] readonly def\n", topDict.fontMatrix[0], topDict.fontMatrix[1], topDict.fontMatrix[2], topDict.fontMatrix[3], topDict.fontMatrix[4], topDict.fontMatrix[5]); (*outputFunc)(outputStream, buf, strlen(buf)); sprintf(buf, "/FontBBox [%g %g %g %g] readonly def\n", topDict.fontBBox[0], topDict.fontBBox[1], topDict.fontBBox[2], topDict.fontBBox[3]); (*outputFunc)(outputStream, buf, strlen(buf)); sprintf(buf, "/StrokeWidth %g def\n", topDict.strokeWidth); (*outputFunc)(outputStream, buf, strlen(buf)); if (topDict.uniqueID != 0) { sprintf(buf, "/UniqueID %d def\n", topDict.uniqueID); (*outputFunc)(outputStream, buf, strlen(buf)); } // write the encoding (*outputFunc)(outputStream, "/Encoding ", 10); if (!newEncoding && encoding == fofiType1StandardEncoding) { (*outputFunc)(outputStream, "StandardEncoding def\n", 21); } else { (*outputFunc)(outputStream, "256 array\n", 10); (*outputFunc)(outputStream, "0 1 255 {1 index exch /.notdef put} for\n", 40); enc = newEncoding ? newEncoding : encoding; for (i = 0; i < 256; ++i) { if (enc[i]) { sprintf(buf, "dup %d /%s put\n", i, enc[i]); (*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); eb.outputFunc = outputFunc; eb.outputStream = outputStream; eb.ascii = ascii; eb.r1 = 55665; eb.line = 0; // write the private dictionary eexecWrite(&eb, "\x83\xca\x73\xd5"); eexecWrite(&eb, "dup /Private 32 dict dup begin\n"); eexecWrite(&eb, "/RD {string currentfile exch readstring pop}" " executeonly def\n"); eexecWrite(&eb, "/ND {noaccess def} executeonly def\n"); eexecWrite(&eb, "/NP {noaccess put} executeonly def\n"); eexecWrite(&eb, "/MinFeature {16 16} def\n"); eexecWrite(&eb, "/password 5839 def\n"); if (privateDicts[0].nBlueValues) { eexecWrite(&eb, "/BlueValues ["); for (i = 0; i < privateDicts[0].nBlueValues; ++i) { sprintf(buf, "%s%d", i > 0 ? " " : "", privateDicts[0].blueValues[i]); eexecWrite(&eb, buf); } eexecWrite(&eb, "] def\n"); } if (privateDicts[0].nOtherBlues) { eexecWrite(&eb, "/OtherBlues ["); for (i = 0; i < privateDicts[0].nOtherBlues; ++i) { sprintf(buf, "%s%d", i > 0 ? " " : "", privateDicts[0].otherBlues[i]); eexecWrite(&eb, buf); } eexecWrite(&eb, "] def\n"); } if (privateDicts[0].nFamilyBlues) { eexecWrite(&eb, "/FamilyBlues ["); for (i = 0; i < privateDicts[0].nFamilyBlues; ++i) { sprintf(buf, "%s%d", i > 0 ? " " : "", privateDicts[0].familyBlues[i]); eexecWrite(&eb, buf); } eexecWrite(&eb, "] def\n"); } if (privateDicts[0].nFamilyOtherBlues) { eexecWrite(&eb, "/FamilyOtherBlues ["); for (i = 0; i < privateDicts[0].nFamilyOtherBlues; ++i) { sprintf(buf, "%s%d", i > 0 ? " " : "", privateDicts[0].familyOtherBlues[i]); eexecWrite(&eb, buf); } eexecWrite(&eb, "] def\n"); } if (privateDicts[0].blueScale != 0.039625) { sprintf(buf, "/BlueScale %g def\n", privateDicts[0].blueScale); eexecWrite(&eb, buf); } if (privateDicts[0].blueShift != 7) { sprintf(buf, "/BlueShift %d def\n", privateDicts[0].blueShift); eexecWrite(&eb, buf); } if (privateDicts[0].blueFuzz != 1) { sprintf(buf, "/BlueFuzz %d def\n", privateDicts[0].blueFuzz); eexecWrite(&eb, buf); } if (privateDicts[0].hasStdHW) { sprintf(buf, "/StdHW [%g] def\n", privateDicts[0].stdHW); eexecWrite(&eb, buf); } if (privateDicts[0].hasStdVW) { sprintf(buf, "/StdVW [%g] def\n", privateDicts[0].stdVW); eexecWrite(&eb, buf); } if (privateDicts[0].nStemSnapH) { eexecWrite(&eb, "/StemSnapH ["); for (i = 0; i < privateDicts[0].nStemSnapH; ++i) { sprintf(buf, "%s%g", i > 0 ? " " : "", privateDicts[0].stemSnapH[i]); eexecWrite(&eb, buf); } eexecWrite(&eb, "] def\n"); } if (privateDicts[0].nStemSnapV) { eexecWrite(&eb, "/StemSnapV ["); for (i = 0; i < privateDicts[0].nStemSnapV; ++i) { sprintf(buf, "%s%g", i > 0 ? " " : "", privateDicts[0].stemSnapV[i]); eexecWrite(&eb, buf); } eexecWrite(&eb, "] def\n"); } if (privateDicts[0].hasForceBold) { sprintf(buf, "/ForceBold %s def\n", privateDicts[0].forceBold ? "true" : "false"); eexecWrite(&eb, buf); } if (privateDicts[0].forceBoldThreshold != 0) { sprintf(buf, "/ForceBoldThreshold %g def\n", privateDicts[0].forceBoldThreshold); eexecWrite(&eb, buf); } if (privateDicts[0].languageGroup != 0) { sprintf(buf, "/LanguageGroup %d def\n", privateDicts[0].languageGroup); eexecWrite(&eb, buf); } if (privateDicts[0].expansionFactor != 0.06) { sprintf(buf, "/ExpansionFactor %g def\n", privateDicts[0].expansionFactor); eexecWrite(&eb, buf); } // set up subroutines ok = gTrue; getIndex(privateDicts[0].subrsOffset, &subrIdx, &ok); if (!ok) { subrIdx.pos = -1; } // write the CharStrings sprintf(buf, "2 index /CharStrings %d dict dup begin\n", nGlyphs); eexecWrite(&eb, buf); for (i = 0; i < nGlyphs; ++i) { ok = gTrue; getIndexVal(&charStringsIdx, i, &val, &ok); if (ok) { getString(charset[i], buf, &ok); if (ok) { eexecCvtGlyph(&eb, buf, val.pos, val.len, &subrIdx, &privateDicts[0]); } } } eexecWrite(&eb, "end\n"); eexecWrite(&eb, "end\n"); eexecWrite(&eb, "readonly put\n"); eexecWrite(&eb, "noaccess put\n"); eexecWrite(&eb, "dup /FontName get exch definefont pop\n"); eexecWrite(&eb, "mark currentfile closefile\n"); // trailer if (ascii && eb.line > 0) { (*outputFunc)(outputStream, "\n", 1); } for (i = 0; i < 8; ++i) { (*outputFunc)(outputStream, "0000000000000000000000000000000000000000000000000000000000000000\n", 65); } (*outputFunc)(outputStream, "cleartomark\n", 12);}void FoFiType1C::convertToCIDType0(char *psName, FoFiOutputFunc outputFunc, void *outputStream) { int *cidMap; GString *charStrings; int *charStringOffsets; Type1CIndex subrIdx; Type1CIndexVal val; int nCIDs, gdBytes; char buf[512], buf2[512]; GBool ok; int gid, offset, n, i, j, k; // compute the CID count and build the CID-to-GID mapping nCIDs = 0; for (i = 0; i < nGlyphs; ++i) { if (charset[i] >= nCIDs) { nCIDs = charset[i] + 1; } } cidMap = (int *)gmallocn(nCIDs, sizeof(int)); for (i = 0; i < nCIDs; ++i) { cidMap[i] = -1; } for (i = 0; i < nGlyphs; ++i) { cidMap[charset[i]] = i; } // build the charstrings charStrings = new GString(); charStringOffsets = (int *)gmallocn(nCIDs + 1, sizeof(int)); for (i = 0; i < nCIDs; ++i) { charStringOffsets[i] = charStrings->getLength(); if ((gid = cidMap[i]) >= 0) { ok = gTrue; getIndexVal(&charStringsIdx, gid, &val, &ok); if (ok) { getIndex(privateDicts[fdSelect[gid]].subrsOffset, &subrIdx, &ok); if (!ok) { subrIdx.pos = -1; } cvtGlyph(val.pos, val.len, charStrings, &subrIdx, &privateDicts[fdSelect[gid]], gTrue); } } } charStringOffsets[nCIDs] = charStrings->getLength();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?