diff options
author | Albert Astals Cid <aacid@kde.org> | 2009-06-19 00:37:21 +0200 |
---|---|---|
committer | Albert Astals Cid <aacid@kde.org> | 2009-06-19 00:37:21 +0200 |
commit | 37e3f877ee725648734ff41e1e83870a210bcbd7 (patch) | |
tree | 06fd8e637cc8bd3b9bd9bbd41b3bfb9e512eeb96 | |
parent | 47de8eef46300832556ce5ed869e391e477fd843 (diff) |
Handle Streams in CMap definitions
Fixes bug 22334
-rw-r--r-- | poppler/CMap.cc | 50 | ||||
-rw-r--r-- | poppler/CMap.h | 17 | ||||
-rw-r--r-- | poppler/GfxFont.cc | 41 | ||||
-rw-r--r-- | poppler/GlobalParams.cc | 6 | ||||
-rw-r--r-- | poppler/GlobalParams.h | 5 |
5 files changed, 77 insertions, 42 deletions
diff --git a/poppler/CMap.cc b/poppler/CMap.cc index 731abd1b..0e861c01 100644 --- a/poppler/CMap.cc +++ b/poppler/CMap.cc @@ -14,7 +14,7 @@ // under GPL version 2 or later // // Copyright (C) 2008 Koji Otani <sho@bbr.jp> -// Copyright (C) 2008 Albert Astals Cid <aacid@kde.org> +// Copyright (C) 2008, 2009 Albert Astals Cid <aacid@kde.org> // // 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 @@ -38,6 +38,7 @@ #include "GlobalParams.h" #include "PSTokenizer.h" #include "CMap.h" +#include "Object.h" //------------------------------------------------------------------------ @@ -55,35 +56,44 @@ static int getCharFromFile(void *data) { return fgetc((FILE *)data); } +static int getCharFromStream(void *data) { + return ((Stream *)data)->getChar(); +} + //------------------------------------------------------------------------ CMap *CMap::parse(CMapCache *cache, GooString *collectionA, - GooString *cMapNameA) { - FILE *f; + GooString *cMapNameA, Stream *stream) { + FILE *f = NULL; CMap *cmap; PSTokenizer *pst; char tok1[256], tok2[256], tok3[256]; int n1, n2, n3; Guint start, end, code; - if (!(f = globalParams->findCMapFile(collectionA, cMapNameA))) { + if (stream) { + stream->reset(); + pst = new PSTokenizer(&getCharFromStream, stream); + } else { + if (!(f = globalParams->findCMapFile(collectionA, cMapNameA))) { - // Check for an identity CMap. - if (!cMapNameA->cmp("Identity") || !cMapNameA->cmp("Identity-H")) { - return new CMap(collectionA->copy(), cMapNameA->copy(), 0); - } - if (!cMapNameA->cmp("Identity-V")) { - return new CMap(collectionA->copy(), cMapNameA->copy(), 1); - } + // Check for an identity CMap. + if (!cMapNameA->cmp("Identity") || !cMapNameA->cmp("Identity-H")) { + return new CMap(collectionA->copy(), cMapNameA->copy(), 0); + } + if (!cMapNameA->cmp("Identity-V")) { + return new CMap(collectionA->copy(), cMapNameA->copy(), 1); + } - error(-1, "Couldn't find '%s' CMap file for '%s' collection", - cMapNameA->getCString(), collectionA->getCString()); - return NULL; + error(-1, "Couldn't find '%s' CMap file for '%s' collection", + cMapNameA->getCString(), collectionA->getCString()); + return NULL; + } + pst = new PSTokenizer(&getCharFromFile, f); } cmap = new CMap(collectionA->copy(), cMapNameA->copy()); - pst = new PSTokenizer(&getCharFromFile, f); pst->getToken(tok1, sizeof(tok1), &n1); while (pst->getToken(tok2, sizeof(tok2), &n2)) { if (!strcmp(tok2, "usecmap")) { @@ -166,7 +176,9 @@ CMap *CMap::parse(CMapCache *cache, GooString *collectionA, } delete pst; - fclose(f); + if (f) { + fclose(f); + } return cmap; } @@ -204,7 +216,7 @@ void CMap::useCMap(CMapCache *cache, char *useName) { CMap *subCMap; useNameStr = new GooString(useName); - subCMap = cache->getCMap(collection, useNameStr); + subCMap = cache->getCMap(collection, useNameStr, NULL); delete useNameStr; if (!subCMap) { return; @@ -423,7 +435,7 @@ CMapCache::~CMapCache() { } } -CMap *CMapCache::getCMap(GooString *collection, GooString *cMapName) { +CMap *CMapCache::getCMap(GooString *collection, GooString *cMapName, Stream *stream) { CMap *cmap; int i, j; @@ -442,7 +454,7 @@ CMap *CMapCache::getCMap(GooString *collection, GooString *cMapName) { return cmap; } } - if ((cmap = CMap::parse(this, collection, cMapName))) { + if ((cmap = CMap::parse(this, collection, cMapName, stream))) { if (cache[cMapCacheSize - 1]) { cache[cMapCacheSize - 1]->decRefCnt(); } diff --git a/poppler/CMap.h b/poppler/CMap.h index 96257a3e..9de0a870 100644 --- a/poppler/CMap.h +++ b/poppler/CMap.h @@ -14,6 +14,7 @@ // under GPL version 2 or later // // Copyright (C) 2008 Koji Otani <sho@bbr.jp> +// Copyright (C) 2009 Albert Astals Cid <aacid@kde.org> // // 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 @@ -38,6 +39,7 @@ class GooString; struct CMapVectorEntry; class CMapCache; +class Stream; //------------------------------------------------------------------------ @@ -45,9 +47,12 @@ class CMap { public: // Create the CMap specified by <collection> and <cMapName>. Sets - // the initial reference count to 1. Returns NULL on failure. + // the initial reference count to 1. + // Stream is a stream containing the CMap, can be NULL and + // this means the CMap will be searched in the CMap files + // Returns NULL on failure. static CMap *parse(CMapCache *cache, GooString *collectionA, - GooString *cMapNameA); + GooString *cMapNameA, Stream *stream); ~CMap(); @@ -107,9 +112,11 @@ public: // Get the <cMapName> CMap for the specified character collection. // Increments its reference count; there will be one reference for - // the cache plus one for the caller of this function. Returns NULL - // on failure. - CMap *getCMap(GooString *collection, GooString *cMapName); + // the cache plus one for the caller of this function. + // Stream is a stream containing the CMap, can be NULL and + // this means the CMap will be searched in the CMap files + // Returns NULL on failure. + CMap *getCMap(GooString *collection, GooString *cMapName, Stream *stream); private: diff --git a/poppler/GfxFont.cc b/poppler/GfxFont.cc index d5782dc4..02af3123 100644 --- a/poppler/GfxFont.cc +++ b/poppler/GfxFont.cc @@ -1428,24 +1428,39 @@ GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GooString *nameA, } // encoding (i.e., CMap) - //~ need to handle a CMap stream here //~ also need to deal with the UseCMap entry in the stream dict if (!fontDict->lookup("Encoding", &obj1)->isName()) { - error(-1, "Missing or invalid Encoding entry in Type 0 font"); - delete collection; - goto err3; - } - cMapName = new GooString(obj1.getName()); - obj1.free(); - if (!(cMap = globalParams->getCMap(collection, cMapName))) { - error(-1, "Unknown CMap '%s' for character collection '%s'", - cMapName->getCString(), collection->getCString()); - delete collection; - delete cMapName; - goto err2; + GBool success = gFalse; + if (obj1.isStream()) { + Object objName; + Stream *s = obj1.getStream(); + s->getDict()->lookup("CMapName", &objName); + if (objName.isName()) + { + cMapName = new GooString(objName.getName()); + cMap = globalParams->getCMap(collection, cMapName, s); + success = gTrue; + } + objName.free(); + } + + if (!success) { + error(-1, "Missing or invalid Encoding entry in Type 0 font"); + delete collection; + goto err3; + } + } else { + cMapName = new GooString(obj1.getName()); + cMap = globalParams->getCMap(collection, cMapName); } delete collection; delete cMapName; + if (!cMap) { + error(-1, "Unknown CMap '%s' for character collection '%s'", + cMapName->getCString(), collection->getCString()); + goto err2; + } + obj1.free(); // CIDToGIDMap (for embedded TrueType fonts) if (type == fontCIDType2 || type == fontCIDType2OT) { diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc index 13a54d22..177bc8ac 100644 --- a/poppler/GlobalParams.cc +++ b/poppler/GlobalParams.cc @@ -12,7 +12,7 @@ // // Copyright (C) 2005 Martin Kretzschmar <martink@gnome.org> // Copyright (C) 2005, 2006 Kristian Høgsberg <krh@redhat.com> -// Copyright (C) 2005, 2007, 2008 Albert Astals Cid <aacid@kde.org> +// Copyright (C) 2005, 2007-2009 Albert Astals Cid <aacid@kde.org> // Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com> // Copyright (C) 2006, 2007 Jeff Muizelaar <jeff@infidigm.net> // Copyright (C) 2006 Takashi Iwai <tiwai@suse.de> @@ -1565,11 +1565,11 @@ UnicodeMap *GlobalParams::getUnicodeMap2(GooString *encodingName) { return map; } -CMap *GlobalParams::getCMap(GooString *collection, GooString *cMapName) { +CMap *GlobalParams::getCMap(GooString *collection, GooString *cMapName, Stream *stream) { CMap *cMap; lockCMapCache; - cMap = cMapCache->getCMap(collection, cMapName); + cMap = cMapCache->getCMap(collection, cMapName, stream); unlockCMapCache; return cMap; } diff --git a/poppler/GlobalParams.h b/poppler/GlobalParams.h index ebc16fb2..5a724af3 100644 --- a/poppler/GlobalParams.h +++ b/poppler/GlobalParams.h @@ -13,7 +13,7 @@ // All changes made under the Poppler project to this file are licensed // under GPL version 2 or later // -// Copyright (C) 2005, 2007, 2008 Albert Astals Cid <aacid@kde.org> +// Copyright (C) 2005, 2007-2009 Albert Astals Cid <aacid@kde.org> // Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com> // Copyright (C) 2006 Takashi Iwai <tiwai@suse.de> // Copyright (C) 2006 Kristian Høgsberg <krh@redhat.com> @@ -59,6 +59,7 @@ class CMapCache; struct XpdfSecurityHandler; class GlobalParams; class GfxFont; +class Stream; #ifdef WIN32 class WinFontList; #endif @@ -220,7 +221,7 @@ public: CharCodeToUnicode *getCIDToUnicode(GooString *collection); CharCodeToUnicode *getUnicodeToUnicode(GooString *fontName); UnicodeMap *getUnicodeMap(GooString *encodingName); - CMap *getCMap(GooString *collection, GooString *cMapName); + CMap *getCMap(GooString *collection, GooString *cMapName, Stream *stream = NULL); UnicodeMap *getTextEncoding(); #ifdef ENABLE_PLUGINS GBool loadPlugin(char *type, char *name); |