poppler/Gfx.cc | 19 +++++++++++++-- poppler/Gfx.h | 2 + poppler/PopplerCache.cc | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ poppler/PopplerCache.h | 16 ++++++++++++ 4 files changed, 95 insertions(+), 2 deletions(-)
New commits: commit 59ff9d66fc3b0c9612b1c12fc1ae4dbb8dc85b39 Author: Carlos Garcia Campos <[email protected]> Date: Sun Jan 24 17:57:48 2010 +0100 Use a small object cache in GfxResources to cache GState objects It drastically improves performance with some documents like page 742 of PDF32000_2008.pdf diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index d8e144f..f0241c7 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -307,7 +307,8 @@ static inline GBool isSameGfxColor(const GfxColor &colorA, const GfxColor &color // GfxResources //------------------------------------------------------------------------ -GfxResources::GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA) { +GfxResources::GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA) : + gStateCache(2, xref) { Object obj1, obj2; Ref r; @@ -480,11 +481,25 @@ GfxShading *GfxResources::lookupShading(char *name, Gfx *gfx) { } GBool GfxResources::lookupGState(char *name, Object *obj) { + Object objRef; + + if (!lookupGStateNF(name, &objRef)) + return gFalse; + + if (!gStateCache.lookup(&objRef, obj)->isNull()) + return gTrue; + obj->free(); + + gStateCache.put(&objRef)->copy(obj); + return gTrue; +} + +GBool GfxResources::lookupGStateNF(char *name, Object *obj) { GfxResources *resPtr; for (resPtr = this; resPtr; resPtr = resPtr->next) { if (resPtr->gStateDict.isDict()) { - if (!resPtr->gStateDict.dictLookup(name, obj)->isNull()) { + if (!resPtr->gStateDict.dictLookupNF(name, obj)->isNull()) { return gTrue; } obj->free(); diff --git a/poppler/Gfx.h b/poppler/Gfx.h index ef1977a..fd4fc6c 100644 --- a/poppler/Gfx.h +++ b/poppler/Gfx.h @@ -113,6 +113,7 @@ public: GfxPattern *lookupPattern(char *name, Gfx *gfx); GfxShading *lookupShading(char *name, Gfx *gfx); GBool lookupGState(char *name, Object *obj); + GBool lookupGStateNF(char *name, Object *obj); GfxResources *getNext() { return next; } @@ -124,6 +125,7 @@ private: Object patternDict; Object shadingDict; Object gStateDict; + PopplerObjectCache gStateCache; Object propertiesDict; GfxResources *next; }; commit 880a4a9a60a10f7aa7d3dc7c2802b31b7ef01e06 Author: Carlos Garcia Campos <[email protected]> Date: Sun Jan 24 17:56:35 2010 +0100 Add a generic cache to store objects by its reference diff --git a/poppler/PopplerCache.cc b/poppler/PopplerCache.cc index b0859aa..bb7f850 100644 --- a/poppler/PopplerCache.cc +++ b/poppler/PopplerCache.cc @@ -100,3 +100,63 @@ PopplerCacheKey *PopplerCache::key(int index) { return keys[index]; } + +class ObjectKey : public PopplerCacheKey { + public: + ObjectKey(int numA, int genA) : num(numA), gen(genA) + { + } + + bool operator==(const PopplerCacheKey &key) const + { + const ObjectKey *k = static_cast<const ObjectKey*>(&key); + return k->num == num && k->gen == gen; + } + + int num, gen; +}; + +class ObjectItem : public PopplerCacheItem { + public: + ObjectItem(Object *obj) + { + obj->copy(&item); + } + + ~ObjectItem() + { + item.free(); + } + + Object item; +}; + +PopplerObjectCache::PopplerObjectCache(int cacheSize, XRef *xrefA) { + cache = new PopplerCache (cacheSize); + xref = xrefA; +} + +PopplerObjectCache::~PopplerObjectCache() { + delete cache; +} + +Object *PopplerObjectCache::put(Object *objRef) { + Ref ref = objRef->getRef(); + Object obj; + objRef->fetch(xref, &obj); + + ObjectKey *key = new ObjectKey(ref.num, ref.gen); + ObjectItem *item = new ObjectItem(&obj); + cache->put(key, item); + obj.free(); + + return &item->item; +} + +Object *PopplerObjectCache::lookup(Object *objRef, Object *obj) { + Ref ref = objRef->getRef(); + ObjectKey key(ref.num, ref.gen); + ObjectItem *item = static_cast<ObjectItem *>(cache->lookup(key)); + + return item ? item->item.copy(obj) : obj->initNull(); +} diff --git a/poppler/PopplerCache.h b/poppler/PopplerCache.h index 5f22409..79c7ce2 100644 --- a/poppler/PopplerCache.h +++ b/poppler/PopplerCache.h @@ -12,6 +12,8 @@ #ifndef POPPLER_CACHE_H #define POPPLER_CACHE_H +#include "Object.h" + class PopplerCacheItem { public: @@ -58,4 +60,18 @@ class PopplerCache int cacheSize; }; +class PopplerObjectCache +{ + public: + PopplerObjectCache (int cacheSizeA, XRef *xrefA); + ~PopplerObjectCache(); + + Object *put(Object *objRef); + Object *lookup(Object *objRef, Object *obj); + + private: + XRef *xref; + PopplerCache *cache; +}; + #endif _______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
