fofi/FoFiTrueType.cc | 13 ++++++++++++- fofi/FoFiTrueType.h | 2 ++ poppler/PSOutputDev.cc | 26 ++++++++++++++++++++++++++ poppler/PSOutputDev.h | 1 + 4 files changed, 41 insertions(+), 1 deletion(-)
New commits: commit 2cf901c817fc99e1fa57745c11aa79cdfb4e8c99 Author: William Bader <[email protected]> Date: Thu Dec 8 21:45:18 2016 +0100 Fix PS conversion for some files Bug #63963 diff --git a/fofi/FoFiTrueType.cc b/fofi/FoFiTrueType.cc index 4905826..f1a15e0 100644 --- a/fofi/FoFiTrueType.cc +++ b/fofi/FoFiTrueType.cc @@ -22,7 +22,7 @@ // Copyright (C) 2012 Adrian Johnson <[email protected]> // Copyright (C) 2014 Thomas Freitag <[email protected]> // Copyright (C) 2015 Aleksei Volkov <Aleksei Volkov> -// Copyright (C) 2015 William Bader <[email protected]> +// Copyright (C) 2015, 2016 William Bader <[email protected]> // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -727,12 +727,15 @@ void FoFiTrueType::convertToCIDType0(char *psName, int *cidMap, int nCIDs, void FoFiTrueType::convertToType0(char *psName, int *cidMap, int nCIDs, GBool needVerticalMetrics, + int *maxValidGlyph, FoFiOutputFunc outputFunc, void *outputStream) { GooString *buf; GooString *sfntsName; int maxUsedGlyph, n, i, j; + *maxValidGlyph = -1; + if (openTypeCFF) { return; } @@ -754,6 +757,13 @@ void FoFiTrueType::convertToType0(char *psName, int *cidMap, int nCIDs, // that refers to one of the unused glyphs -- this results in PS // errors if we simply use maxUsedGlyph+1 for the Type 0 font. So // we compromise by always defining at least 256 glyphs.) + // Some fonts have a large nGlyphs but maxUsedGlyph of 0. + // These fonts might reference any glyph. + // Return the last written glyph number in maxValidGlyph. + // PSOutputDev::drawString() can use maxValidGlyph to avoid + // referencing zero-length glyphs that we trimmed. + // This allows pdftops to avoid writing huge files while still + // handling the rare PDF that uses a zero-length glyph. if (cidMap) { n = nCIDs; } else if (nGlyphs > maxUsedGlyph + 256) { @@ -765,6 +775,7 @@ void FoFiTrueType::convertToType0(char *psName, int *cidMap, int nCIDs, } else { n = nGlyphs; } + *maxValidGlyph = n-1; for (i = 0; i < n; i += 256) { (*outputFunc)(outputStream, "10 dict begin\n", 14); (*outputFunc)(outputStream, "/FontName /", 11); diff --git a/fofi/FoFiTrueType.h b/fofi/FoFiTrueType.h index b40a44a..a4e28f2 100644 --- a/fofi/FoFiTrueType.h +++ b/fofi/FoFiTrueType.h @@ -17,6 +17,7 @@ // Copyright (C) 2007 Koji Otani <[email protected]> // Copyright (C) 2011, 2012 Albert Astals Cid <[email protected]> // Copyright (C) 2012 Suzuki Toshiya <[email protected]> +// Copyright (C) 2016 William Bader <[email protected]> // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -144,6 +145,7 @@ public: // <nCIDs> entries. (Not useful for OpenType CFF fonts.) void convertToType0(char *psName, int *cidMap, int nCIDs, GBool needVerticalMetrics, + int *maxValidGlyph, FoFiOutputFunc outputFunc, void *outputStream); // Convert to a Type 0 (but non-CID) composite font, suitable for diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc index ea0b043..246244f 100644 --- a/poppler/PSOutputDev.cc +++ b/poppler/PSOutputDev.cc @@ -1103,6 +1103,7 @@ PSOutputDev::PSOutputDev(const char *fileName, PDFDoc *doc, fontIDs = NULL; fontNames = new GooHash(gTrue); + fontMaxValidGlyph = new GooHash(gTrue); t1FontNames = NULL; font8Info = NULL; font16Enc = NULL; @@ -1171,6 +1172,7 @@ PSOutputDev::PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA, fontIDs = NULL; fontNames = new GooHash(gTrue); + fontMaxValidGlyph = new GooHash(gTrue); t1FontNames = NULL; font8Info = NULL; font16Enc = NULL; @@ -1497,6 +1499,7 @@ PSOutputDev::~PSOutputDev() { gfree(fontIDs); } delete fontNames; + delete fontMaxValidGlyph; if (t1FontNames) { for (i = 0; i < t1FontNameLen; ++i) { delete t1FontNames[i].psName; @@ -2610,10 +2613,15 @@ void PSOutputDev::setupExternalCIDTrueTypeFont(GfxFont *font, outputFunc, outputStream); } else { // otherwise: use a non-CID composite font + int maxValidGlyph = -1; ffTT->convertToType0(psName->getCString(), codeToGID, codeToGIDLen, needVerticalMetrics, + &maxValidGlyph, outputFunc, outputStream); + if (maxValidGlyph >= 0 && font->getName()) { + fontMaxValidGlyph->replace(font->getName()->copy(), maxValidGlyph); + } } gfree(codeToGID); } else { @@ -2706,11 +2714,16 @@ void PSOutputDev::setupEmbeddedCIDTrueTypeFont(GfxFont *font, Ref *id, outputFunc, outputStream); } else { // otherwise: use a non-CID composite font + int maxValidGlyph = -1; ffTT->convertToType0(psName->getCString(), ((GfxCIDFont *)font)->getCIDToGID(), ((GfxCIDFont *)font)->getCIDToGIDLen(), needVerticalMetrics, + &maxValidGlyph, outputFunc, outputStream); + if (maxValidGlyph > 0 && font->getName()) { + fontMaxValidGlyph->replace(font->getName()->copy(), maxValidGlyph); + } } delete ffTT; } @@ -5051,6 +5064,8 @@ void PSOutputDev::drawString(GfxState *state, GooString *s) { char buf[8]; double *dxdy; int dxdySize, len, nChars, uLen, n, m, i, j; + int maxGlyphInt; + CharCode maxGlyph; // for pdftohtml, output PS without text if( displayText == gFalse ) @@ -5070,6 +5085,9 @@ void PSOutputDev::drawString(GfxState *state, GooString *s) { if (!(font = state->getFont())) { return; } + maxGlyphInt = (font->getName()? fontMaxValidGlyph->lookupInt(font->getName()): 0); + if (maxGlyphInt < 0) maxGlyphInt = 0; + maxGlyph = (CharCode) maxGlyphInt; wMode = font->getWMode(); // check for a subtitute 16-bit font @@ -5144,6 +5162,14 @@ void PSOutputDev::drawString(GfxState *state, GooString *s) { dxdy[2 * nChars + 1] = dy; ++nChars; } + } else if (maxGlyph > 0 && code > maxGlyph) { + // Ignore this code. + // Using it will exceed the number of glyphs in the font and generate + // /rangecheck in --xyshow-- + if (nChars > 0) { + dxdy[2 * (nChars-1) ] += dx; + dxdy[2 * (nChars-1) + 1 ] += dy; + } } else { if (nChars + 1 > dxdySize) { dxdySize *= 2; diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h index c27c90f..072608a 100644 --- a/poppler/PSOutputDev.h +++ b/poppler/PSOutputDev.h @@ -473,6 +473,7 @@ private: int fontIDSize; // size of fontIDs array std::set<int> resourceIDs; // list of object IDs of objects containing Resources we've already set up GooHash *fontNames; // all used font names + GooHash *fontMaxValidGlyph; // max valid glyph of each font PST1FontName *t1FontNames; // font names for Type 1/1C fonts int t1FontNameLen; // number of entries in t1FontNames array int t1FontNameSize; // size of t1FontNames array _______________________________________________ poppler mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/poppler
