diff options
author | Tor Andersson <tor@ghostscript.com> | 2010-04-16 01:01:46 +0200 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2010-04-16 01:01:46 +0200 |
commit | ec1ff03d7ff732775bfbd2fadb60694d646b54cf (patch) | |
tree | 414cffaf91b3fe428dfbe03dcd93dc1e6008174f /draw/glyphcache.c | |
parent | 40d24bdf68b6698254eeb5722ecfe2d3df54432d (diff) | |
download | mupdf-ec1ff03d7ff732775bfbd2fadb60694d646b54cf.tar.xz |
Don't cache glyphs bigger than a threshold size, and clear the cache when it is too big.
Diffstat (limited to 'draw/glyphcache.c')
-rw-r--r-- | draw/glyphcache.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/draw/glyphcache.c b/draw/glyphcache.c index 1627682a..9828aa2a 100644 --- a/draw/glyphcache.c +++ b/draw/glyphcache.c @@ -1,10 +1,14 @@ #include "fitz.h" +#define MAXGLYPHSIZE 256 +#define MAXCACHESIZE (1024*1024) + typedef struct fz_glyphkey_s fz_glyphkey; struct fz_glyphcache_s { fz_hashtable *hash; + int total; }; struct fz_glyphkey_s @@ -19,40 +23,43 @@ struct fz_glyphkey_s fz_glyphcache * fz_newglyphcache(void) { - fz_glyphcache *arena; - - arena = fz_malloc(sizeof(fz_glyphcache)); - arena->hash = fz_newhash(509, sizeof(fz_glyphkey)); + fz_glyphcache *cache; + + cache = fz_malloc(sizeof(fz_glyphcache)); + cache->hash = fz_newhash(509, sizeof(fz_glyphkey)); + cache->total = 0; - return arena; + return cache; } void -fz_evictglyphcache(fz_glyphcache *arena) +fz_evictglyphcache(fz_glyphcache *cache) { fz_pixmap *pixmap; int i; - for (i = 0; i < fz_hashlen(arena->hash); i++) + for (i = 0; i < fz_hashlen(cache->hash); i++) { - pixmap = fz_hashgetval(arena->hash, i); + pixmap = fz_hashgetval(cache->hash, i); if (pixmap) fz_droppixmap(pixmap); } - fz_emptyhash(arena->hash); + cache->total = 0; + + fz_emptyhash(cache->hash); } void -fz_freeglyphcache(fz_glyphcache *arena) +fz_freeglyphcache(fz_glyphcache *cache) { - fz_evictglyphcache(arena); - fz_drophash(arena->hash); - fz_free(arena); + fz_evictglyphcache(cache); + fz_drophash(cache->hash); + fz_free(cache); } fz_pixmap * -fz_renderglyph(fz_glyphcache *arena, fz_font *font, int cid, fz_matrix ctm) +fz_renderglyph(fz_glyphcache *cache, fz_font *font, int cid, fz_matrix ctm) { fz_glyphkey key; fz_pixmap *val; @@ -66,7 +73,7 @@ fz_renderglyph(fz_glyphcache *arena, fz_font *font, int cid, fz_matrix ctm) key.e = (ctm.e - floor(ctm.e)) * 256; key.f = (ctm.f - floor(ctm.f)) * 256; - val = fz_hashfind(arena->hash, &key); + val = fz_hashfind(cache->hash, &key); if (val) return fz_keeppixmap(val); @@ -89,9 +96,16 @@ fz_renderglyph(fz_glyphcache *arena, fz_font *font, int cid, fz_matrix ctm) if (val) { - fz_hashinsert(arena->hash, &key, val); - return fz_keeppixmap(val); + if (val->w < MAXGLYPHSIZE && val->h < MAXGLYPHSIZE) + { + if (cache->total + val->w * val->h > MAXCACHESIZE) + fz_evictglyphcache(cache); + fz_hashinsert(cache->hash, &key, val); + cache->total += val->w * val->h; + return fz_keeppixmap(val); + } + return val; } - + return NULL; } |