[poppler] fofi/FoFiTrueType.cc fofi/FoFiTrueType.h poppler/PSOutputDev.cc poppler/PSOutputDev.h
Albert Astals Cid
aacid at kemper.freedesktop.org
Thu Dec 8 20:46:14 UTC 2016
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 <william at newspapersystems.com>
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 <ajohnson at redneon.com>
// Copyright (C) 2014 Thomas Freitag <Thomas.Freitag at alfa.de>
// Copyright (C) 2015 Aleksei Volkov <Aleksei Volkov>
-// Copyright (C) 2015 William Bader <williambader at hotmail.com>
+// Copyright (C) 2015, 2016 William Bader <williambader at hotmail.com>
//
// 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 <sho at bbr.jp>
// Copyright (C) 2011, 2012 Albert Astals Cid <aacid at kde.org>
// Copyright (C) 2012 Suzuki Toshiya <mpsuzuki at hiroshima-u.ac.jp>
+// Copyright (C) 2016 William Bader <williambader at hotmail.com>
//
// 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
More information about the poppler
mailing list