summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Astals Cid <aacid@kde.org>2009-06-19 00:37:21 +0200
committerAlbert Astals Cid <aacid@kde.org>2009-06-19 00:37:21 +0200
commit37e3f877ee725648734ff41e1e83870a210bcbd7 (patch)
tree06fd8e637cc8bd3b9bd9bbd41b3bfb9e512eeb96
parent47de8eef46300832556ce5ed869e391e477fd843 (diff)
Handle Streams in CMap definitions
Fixes bug 22334
-rw-r--r--poppler/CMap.cc50
-rw-r--r--poppler/CMap.h17
-rw-r--r--poppler/GfxFont.cc41
-rw-r--r--poppler/GlobalParams.cc6
-rw-r--r--poppler/GlobalParams.h5
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);