diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc index d454e0e..7b6e14a 100644 --- a/poppler/SplashOutputDev.cc +++ b/poppler/SplashOutputDev.cc @@ -1323,6 +1323,10 @@ T3FontCache::~T3FontCache() { struct T3GlyphStack { Gushort code; // character code + GBool haveDx; // set after seeing a d0/d1 operator + GBool doNotCache; // set if we see a gsave/grestore before + // the d0/d1 + //----- cache info T3FontCache *cache; // font cache for the current font T3FontCacheTag *cacheTag; // pointer to cache tag for the glyph @@ -1600,11 +1604,21 @@ void SplashOutputDev::endPage() { void SplashOutputDev::saveState(GfxState *state) { splash->saveState(); + if (t3GlyphStack && !t3GlyphStack->haveDx) { + t3GlyphStack->doNotCache = gTrue; + error(errSyntaxWarning, -1, + "Save (q) operator before d0/d1 in Type 3 glyph"); + } } void SplashOutputDev::restoreState(GfxState *state) { splash->restoreState(); needFontUpdate = gTrue; + if (t3GlyphStack && !t3GlyphStack->haveDx) { + t3GlyphStack->doNotCache = gTrue; + error(errSyntaxWarning, -1, + "Restore (Q) operator before d0/d1 in Type 3 glyph"); + } } void SplashOutputDev::updateAll(GfxState *state) { @@ -2668,8 +2682,8 @@ GBool SplashOutputDev::beginType3Char(GfxState *state, double x, double y, t3GlyphStack->cache = t3Font; t3GlyphStack->cacheTag = NULL; t3GlyphStack->cacheData = NULL; - - haveT3Dx = gFalse; + t3GlyphStack->haveDx = gFalse; + t3GlyphStack->doNotCache = gFalse; return gFalse; } @@ -2699,7 +2713,7 @@ void SplashOutputDev::endType3Char(GfxState *state) { } void SplashOutputDev::type3D0(GfxState *state, double wx, double wy) { - haveT3Dx = gTrue; + t3GlyphStack->haveDx = gTrue; } void SplashOutputDev::type3D1(GfxState *state, double wx, double wy, @@ -2711,10 +2725,14 @@ void SplashOutputDev::type3D1(GfxState *state, double wx, double wy, int i, j; // ignore multiple d0/d1 operators - if (haveT3Dx) { + if (t3GlyphStack->haveDx) { + return; + } + t3GlyphStack->haveDx = gTrue; + // don't cache if we got a gsave/grestore before the d1 + if (t3GlyphStack->doNotCache) { return; } - haveT3Dx = gTrue; if (unlikely(t3GlyphStack == NULL)) { error(errSyntaxWarning, -1, "t3GlyphStack was null in SplashOutputDev::type3D1"); diff --git a/poppler/SplashOutputDev.h b/poppler/SplashOutputDev.h index e93a20f..5c5512b 100644 --- a/poppler/SplashOutputDev.h +++ b/poppler/SplashOutputDev.h @@ -459,7 +459,6 @@ private: t3FontCache[splashOutT3FontCacheSize]; int nT3Fonts; // number of valid entries in t3FontCache T3GlyphStack *t3GlyphStack; // Type 3 glyph context stack - GBool haveT3Dx; // set after seeing a d0/d1 operator SplashFont *font; // current font GBool needFontUpdate; // set when the font needs to be updated