}
}
++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;
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;
}
// 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) {
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]);
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);
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;
}
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]);
(*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) {
nOps = 0;
nHints = 0;
firstOp = gTrue;
+ openPath = gFalse;
}
pos = offset;
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;
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;
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);
}
charBuf->append((char)5);
}
nOps = 0;
+ openPath = gTrue;
break;
case 0x0006: // hlineto
if (nOps < 1) {
charBuf->append((char)((k & 1) ? 7 : 6));
}
nOps = 0;
+ openPath = gTrue;
break;
case 0x0007: // vlineto
if (nOps < 1) {
charBuf->append((char)((k & 1) ? 6 : 7));
}
nOps = 0;
+ openPath = gTrue;
break;
case 0x0008: // rrcurveto
if (nOps < 6 || nOps % 6 != 0) {
charBuf->append((char)8);
}
nOps = 0;
+ openPath = gTrue;
break;
case 0x000a: // callsubr
if (nOps >= 1) {
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);
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);
}
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);
}
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) {
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)) {
charBuf->append((char)8);
}
nOps = 0;
+ openPath = gTrue;
break;
case 0x001b: // hhcurveto
if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) {
charBuf->append((char)8);
}
nOps = 0;
+ openPath = gTrue;
break;
case 0x001d: // callgsubr
if (nOps >= 1) {
charBuf->append((char)8);
}
nOps = 0;
+ openPath = gTrue;
break;
case 0x001f: // hvcurveto
if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) {
charBuf->append((char)8);
}
nOps = 0;
+ openPath = gTrue;
break;
case 0x0c00: // dotsection (should be Type 1 only?)
// ignored
cvtNum(0, gFalse, charBuf);
charBuf->append((char)8);
nOps = 0;
+ openPath = gTrue;
break;
case 0x0c23: // flex
if (nOps != 13) {
cvtNum(ops[11].num, ops[11].isFP, charBuf);
charBuf->append((char)8);
nOps = 0;
+ openPath = gTrue;
break;
case 0x0c24: // hflex1
if (nOps != 9) {
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) {
}
charBuf->append((char)8);
nOps = 0;
+ openPath = gTrue;
break;
default:
//~ error(-1, "Illegal Type 2 charstring op: %04x",
}
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) {
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.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;
}
// 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;
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;
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) {
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;
encoding = fofiType1ExpertEncoding;
} else {
- encoding = (char **)gmalloc(256 * sizeof(char *));
+ encoding = (char **)gmallocn(256, sizeof(char *));
for (i = 0; i < 256; ++i) {
encoding[i] = NULL;
}
} 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;
}
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) {
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;
} else {
sid -= 391;
getIndexVal(&stringIdx, sid, &val, ok);
- if (ok) {
+ if (*ok) {
if ((n = val.len) > 255) {
n = 255;
}