[poppler] poppler/CMap.cc poppler/CMap.h poppler/GfxFont.cc poppler/GlobalParams.cc poppler/GlobalParams.h

Albert Astals Cid aacid at kemper.freedesktop.org
Thu Jun 18 15:37:43 PDT 2009


 poppler/CMap.cc         |   50 +++++++++++++++++++++++++++++-------------------
 poppler/CMap.h          |   17 +++++++++++-----
 poppler/GfxFont.cc      |   41 ++++++++++++++++++++++++++-------------
 poppler/GlobalParams.cc |    6 ++---
 poppler/GlobalParams.h  |    5 ++--
 5 files changed, 77 insertions(+), 42 deletions(-)

New commits:
commit 37e3f877ee725648734ff41e1e83870a210bcbd7
Author: Albert Astals Cid <aacid at kde.org>
Date:   Fri Jun 19 00:37:21 2009 +0200

    Handle Streams in CMap definitions
    
    Fixes bug 22334

diff --git a/poppler/CMap.cc b/poppler/CMap.cc
index 731abd1..0e861c0 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 at bbr.jp>
-// Copyright (C) 2008 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2008, 2009 Albert Astals Cid <aacid at 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 96257a3..9de0a87 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 at bbr.jp>
+// Copyright (C) 2009 Albert Astals Cid <aacid at 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 d5782dc..02af312 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 13a54d2..177bc8a 100644
--- a/poppler/GlobalParams.cc
+++ b/poppler/GlobalParams.cc
@@ -12,7 +12,7 @@
 //
 // Copyright (C) 2005 Martin Kretzschmar <martink at gnome.org>
 // Copyright (C) 2005, 2006 Kristian Høgsberg <krh at redhat.com>
-// Copyright (C) 2005, 2007, 2008 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2005, 2007-2009 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2005 Jonathan Blandford <jrb at redhat.com>
 // Copyright (C) 2006, 2007 Jeff Muizelaar <jeff at infidigm.net>
 // Copyright (C) 2006 Takashi Iwai <tiwai at 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 ebc16fb..5a724af 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 at kde.org>
+// Copyright (C) 2005, 2007-2009 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2005 Jonathan Blandford <jrb at redhat.com>
 // Copyright (C) 2006 Takashi Iwai <tiwai at suse.de>
 // Copyright (C) 2006 Kristian Høgsberg <krh at 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);


More information about the poppler mailing list