Commit 37e3f877 authored by Albert Astals Cid's avatar Albert Astals Cid

Handle Streams in CMap definitions

Fixes bug 22334
parent 47de8eef
......@@ -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();
}
......
......@@ -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:
......
......@@ -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) {
......
......@@ -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;
}
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment