X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=pdf2swf%2Fxpdf%2FFoFiType1C.cc;h=a173e7caff44f6784edbdf4a362944c2f53aa821;hb=ebe12c095d5a5274feb5f4475b3782aa64a07d0a;hp=a1cec3132dfc8e18b70fb07a07445f50435b1341;hpb=f397c7898781fb87dd51d7ba3106c12e8c51059e;p=swftools.git diff --git a/pdf2swf/xpdf/FoFiType1C.cc b/pdf2swf/xpdf/FoFiType1C.cc index a1cec31..a173e7c 100644 --- a/pdf2swf/xpdf/FoFiType1C.cc +++ b/pdf2swf/xpdf/FoFiType1C.cc @@ -120,7 +120,7 @@ Gushort *FoFiType1C::getCIDToGIDMap(int *nCIDs) { } } ++n; - map = (Gushort *)gmalloc(n * sizeof(Gushort)); + map = (Gushort *)gmallocn(n, sizeof(Gushort)); memset(map, 0, n * sizeof(Gushort)); for (i = 0; i < nGlyphs; ++i) { map[charset[i]] = i; @@ -406,7 +406,7 @@ void FoFiType1C::convertToCIDType0(char *psName, nCIDs = charset[i] + 1; } } - cidMap = (int *)gmalloc(nCIDs * sizeof(int)); + cidMap = (int *)gmallocn(nCIDs, sizeof(int)); for (i = 0; i < nCIDs; ++i) { cidMap[i] = -1; } @@ -416,7 +416,7 @@ void FoFiType1C::convertToCIDType0(char *psName, // build the charstrings charStrings = new GString(); - charStringOffsets = (int *)gmalloc((nCIDs + 1) * sizeof(int)); + charStringOffsets = (int *)gmallocn(nCIDs + 1, sizeof(int)); for (i = 0; i < nCIDs; ++i) { charStringOffsets[i] = charStrings->getLength(); if ((gid = cidMap[i]) >= 0) { @@ -479,10 +479,18 @@ void FoFiType1C::convertToCIDType0(char *psName, sprintf(buf, " /Supplement %d def\n", topDict.supplement); (*outputFunc)(outputStream, buf, strlen(buf)); (*outputFunc)(outputStream, "end def\n", 8); - sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] 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)); + if (topDict.hasFontMatrix) { + sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] 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)); + } else if (privateDicts[0].hasFontMatrix) { + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + } else { + (*outputFunc)(outputStream, + "/FontMatrix [0.001 0 0 0.001 0 0] def\n", 38); + } sprintf(buf, "/FontBBox [%g %g %g %g] def\n", topDict.fontBBox[0], topDict.fontBBox[1], topDict.fontBBox[2], topDict.fontBBox[3]); @@ -512,7 +520,18 @@ void FoFiType1C::convertToCIDType0(char *psName, sprintf(buf, "dup %d 10 dict begin\n", i); (*outputFunc)(outputStream, buf, strlen(buf)); (*outputFunc)(outputStream, "/FontType 1 def\n", 16); - (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + if (privateDicts[i].hasFontMatrix) { + sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n", + privateDicts[i].fontMatrix[0], + privateDicts[i].fontMatrix[1], + privateDicts[i].fontMatrix[2], + privateDicts[i].fontMatrix[3], + privateDicts[i].fontMatrix[4], + privateDicts[i].fontMatrix[5]); + (*outputFunc)(outputStream, buf, strlen(buf)); + } else { + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + } sprintf(buf, "/PaintType %d def\n", topDict.paintType); (*outputFunc)(outputStream, buf, strlen(buf)); (*outputFunc)(outputStream, "/Private 32 dict begin\n", 23); @@ -673,7 +692,7 @@ void FoFiType1C::convertToType0(char *psName, nCIDs = charset[i] + 1; } } - cidMap = (int *)gmalloc(nCIDs * sizeof(int)); + cidMap = (int *)gmallocn(nCIDs, sizeof(int)); for (i = 0; i < nCIDs; ++i) { cidMap[i] = -1; } @@ -702,11 +721,21 @@ void FoFiType1C::convertToType0(char *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", - topDict.fontMatrix[0], topDict.fontMatrix[1], - topDict.fontMatrix[2], topDict.fontMatrix[3], - topDict.fontMatrix[4], topDict.fontMatrix[5]); - (*outputFunc)(outputStream, buf, strlen(buf)); + if (privateDicts[fd].hasFontMatrix) { + sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n", + privateDicts[fd].fontMatrix[0], + privateDicts[fd].fontMatrix[1], + privateDicts[fd].fontMatrix[2], + privateDicts[fd].fontMatrix[3], + privateDicts[fd].fontMatrix[4], + privateDicts[fd].fontMatrix[5]); + (*outputFunc)(outputStream, buf, strlen(buf)); + } else if (topDict.hasFontMatrix) { + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + } else { + (*outputFunc)(outputStream, + "/FontMatrix [0.001 0 0 0.001 0 0] def\n", 38); + } sprintf(buf, "/FontBBox [%g %g %g %g] def\n", topDict.fontBBox[0], topDict.fontBBox[1], topDict.fontBBox[2], topDict.fontBBox[3]); @@ -890,7 +919,15 @@ void FoFiType1C::convertToType0(char *psName, (*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); + if (topDict.hasFontMatrix) { + sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] 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)); + } else { + (*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) { @@ -950,6 +987,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, nOps = 0; nHints = 0; firstOp = gTrue; + openPath = gFalse; } pos = offset; @@ -973,6 +1011,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, d = 0; dFP = gFalse; for (k = 0; k < nOps; k += 2) { + // convert Type 2 edge hints (-20 or -21) to Type 1 ghost hints if (ops[k+1].num < 0) { d += ops[k].num + ops[k+1].num; dFP |= ops[k].isFP | ops[k+1].isFP; @@ -1002,6 +1041,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, d = 0; dFP = gFalse; for (k = 0; k < nOps; k += 2) { + // convert Type 2 edge hints (-20 or -21) to Type 1 ghost hints if (ops[k+1].num < 0) { d += ops[k].num + ops[k+1].num; dFP |= ops[k].isFP | ops[k+1].isFP; @@ -1025,6 +1065,10 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, cvtGlyphWidth(nOps == 2, charBuf, pDict); firstOp = gFalse; } + if (openPath) { + charBuf->append((char)9); + openPath = gFalse; + } if (nOps != 1) { //~ error(-1, "Wrong number of args (%d) to Type 2 vmoveto", nOps); } @@ -1042,6 +1086,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, charBuf->append((char)5); } nOps = 0; + openPath = gTrue; break; case 0x0006: // hlineto if (nOps < 1) { @@ -1052,6 +1097,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, charBuf->append((char)((k & 1) ? 7 : 6)); } nOps = 0; + openPath = gTrue; break; case 0x0007: // vlineto if (nOps < 1) { @@ -1062,6 +1108,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, charBuf->append((char)((k & 1) ? 6 : 7)); } nOps = 0; + openPath = gTrue; break; case 0x0008: // rrcurveto if (nOps < 6 || nOps % 6 != 0) { @@ -1077,6 +1124,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, charBuf->append((char)8); } nOps = 0; + openPath = gTrue; break; case 0x000a: // callsubr if (nOps >= 1) { @@ -1102,6 +1150,10 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, cvtGlyphWidth(nOps == 1 || nOps == 5, charBuf, pDict); firstOp = gFalse; } + if (openPath) { + charBuf->append((char)9); + openPath = gFalse; + } if (nOps == 4) { cvtNum(0, gFalse, charBuf); cvtNum(ops[0].num, ops[0].isFP, charBuf); @@ -1177,6 +1229,10 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, cvtGlyphWidth(nOps == 3, charBuf, pDict); firstOp = gFalse; } + if (openPath) { + charBuf->append((char)9); + openPath = gFalse; + } if (nOps != 2) { //~ error(-1, "Wrong number of args (%d) to Type 2 rmoveto", nOps); } @@ -1190,6 +1246,10 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, cvtGlyphWidth(nOps == 2, charBuf, pDict); firstOp = gFalse; } + if (openPath) { + charBuf->append((char)9); + openPath = gFalse; + } if (nOps != 1) { //~ error(-1, "Wrong number of args (%d) to Type 2 hmoveto", nOps); } @@ -1226,6 +1286,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, cvtNum(ops[k+1].num, ops[k].isFP, charBuf); charBuf->append((char)5); nOps = 0; + openPath = gTrue; break; case 0x0019: // rlinecurve if (nOps < 8 || (nOps - 6) % 2 != 0) { @@ -1244,6 +1305,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, cvtNum(ops[k+5].num, ops[k+5].isFP, charBuf); charBuf->append((char)8); nOps = 0; + openPath = gTrue; break; case 0x001a: // vvcurveto if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) { @@ -1271,6 +1333,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, charBuf->append((char)8); } nOps = 0; + openPath = gTrue; break; case 0x001b: // hhcurveto if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) { @@ -1298,6 +1361,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, charBuf->append((char)8); } nOps = 0; + openPath = gTrue; break; case 0x001d: // callgsubr if (nOps >= 1) { @@ -1351,6 +1415,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, charBuf->append((char)8); } nOps = 0; + openPath = gTrue; break; case 0x001f: // hvcurveto if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) { @@ -1390,6 +1455,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, charBuf->append((char)8); } nOps = 0; + openPath = gTrue; break; case 0x0c00: // dotsection (should be Type 1 only?) // ignored @@ -1439,6 +1505,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, cvtNum(0, gFalse, charBuf); charBuf->append((char)8); nOps = 0; + openPath = gTrue; break; case 0x0c23: // flex if (nOps != 13) { @@ -1459,6 +1526,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, cvtNum(ops[11].num, ops[11].isFP, charBuf); charBuf->append((char)8); nOps = 0; + openPath = gTrue; break; case 0x0c24: // hflex1 if (nOps != 9) { @@ -1480,6 +1548,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, ops[1].isFP | ops[3].isFP | ops[7].isFP, charBuf); charBuf->append((char)8); nOps = 0; + openPath = gTrue; break; case 0x0c25: // flex1 if (nOps != 11) { @@ -1509,6 +1578,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, } charBuf->append((char)8); nOps = 0; + openPath = gTrue; break; default: //~ error(-1, "Illegal Type 2 charstring op: %04x", @@ -1695,7 +1765,7 @@ GBool FoFiType1C::parse() { } nFDs = fdIdx.len; privateDicts = (Type1CPrivateDict *) - gmalloc(nFDs * sizeof(Type1CPrivateDict)); + gmallocn(nFDs, sizeof(Type1CPrivateDict)); for (i = 0; i < nFDs; ++i) { getIndexVal(&fdIdx, i, &val, &parsedOk); if (!parsedOk) { @@ -1776,6 +1846,7 @@ void FoFiType1C::readTopDict() { 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; @@ -1824,7 +1895,8 @@ void FoFiType1C::readTopDict() { topDict.fontMatrix[2] = ops[2].num; topDict.fontMatrix[3] = ops[3].num; topDict.fontMatrix[4] = ops[4].num; - topDict.fontMatrix[5] = ops[5].num; break; + 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; @@ -1848,10 +1920,14 @@ void FoFiType1C::readTopDict() { } // Read a CID font dict (FD) - this pulls out the private dict -// pointer, and reads 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; @@ -1869,17 +1945,35 @@ void FoFiType1C::readFD(int offset, int length, Type1CPrivateDict *pDict) { 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 = 0; @@ -1898,9 +1992,9 @@ void FoFiType1C::readPrivateDict(int offset, int length, pDict->initialRandomSeed = 0; pDict->subrsOffset = 0; pDict->defaultWidthX = 0; - pDict->defaultWidthXFP = 0; + pDict->defaultWidthXFP = gFalse; pDict->nominalWidthX = 0; - pDict->nominalWidthXFP = 0; + pDict->nominalWidthXFP = gFalse; // no dictionary if (offset == 0 || length == 0) { @@ -1979,9 +2073,11 @@ void FoFiType1C::readPrivateDict(int offset, int length, break; case 0x0014: pDict->defaultWidthX = ops[0].num; + pDict->defaultWidthXFP = ops[0].isFP; break; case 0x0015: pDict->nominalWidthX = ops[0].num; + pDict->nominalWidthXFP = ops[0].isFP; break; } nOps = 0; @@ -2052,7 +2148,7 @@ void FoFiType1C::buildEncoding() { encoding = fofiType1ExpertEncoding; } else { - encoding = (char **)gmalloc(256 * sizeof(char *)); + encoding = (char **)gmallocn(256, sizeof(char *)); for (i = 0; i < 256; ++i) { encoding[i] = NULL; } @@ -2139,7 +2235,7 @@ GBool FoFiType1C::readCharset() { } else if (topDict.charsetOffset == 2) { charset = fofiType1CExpertSubsetCharset; } else { - charset = (Gushort *)gmalloc(nGlyphs * sizeof(Gushort)); + charset = (Gushort *)gmallocn(nGlyphs, sizeof(Gushort)); for (i = 0; i < nGlyphs; ++i) { charset[i] = 0; } @@ -2324,9 +2420,9 @@ void FoFiType1C::getIndex(int pos, Type1CIndex *idx, GBool *ok) { idx->pos = pos; idx->len = getU16BE(pos, ok); if (idx->len == 0) { - // empty indexes are legal + // empty indexes are legal and contain just the length field idx->offSize = 0; - idx->startPos = idx->endPos = 0; + idx->startPos = idx->endPos = pos + 2; } else { idx->offSize = getU8(pos + 2, ok); if (idx->offSize < 1 || idx->offSize > 4) { @@ -2356,7 +2452,7 @@ void FoFiType1C::getIndexVal(Type1CIndex *idx, int i, idx->offSize, ok); pos1 = idx->startPos + getUVarBE(idx->pos + 3 + (i + 1) * idx->offSize, idx->offSize, ok); - if (pos0 < idx->startPos || pos0 >= idx->endPos || + if (pos0 < idx->startPos || pos0 > idx->endPos || pos1 <= idx->startPos || pos1 > idx->endPos || pos1 < pos0) { *ok = gFalse; @@ -2374,7 +2470,7 @@ char *FoFiType1C::getString(int sid, char *buf, GBool *ok) { } else { sid -= 391; getIndexVal(&stringIdx, sid, &val, ok); - if (ok) { + if (*ok) { if ((n = val.len) > 255) { n = 255; }