diff options
-rw-r--r-- | win32/libmupdf.vcproj | 4 | ||||
-rw-r--r-- | xps/muxps.h | 28 | ||||
-rw-r--r-- | xps/xps_glyphs.c | 29 | ||||
-rw-r--r-- | xps/xps_hash.c | 189 | ||||
-rw-r--r-- | xps/xps_zip.c | 34 |
5 files changed, 48 insertions, 236 deletions
diff --git a/win32/libmupdf.vcproj b/win32/libmupdf.vcproj index 41f10f81..6bbf11b1 100644 --- a/win32/libmupdf.vcproj +++ b/win32/libmupdf.vcproj @@ -491,10 +491,6 @@ > </File> <File - RelativePath="..\xps\xps_hash.c" - > - </File> - <File RelativePath="..\xps\xps_image.c" > </File> diff --git a/xps/muxps.h b/xps/muxps.h index f456baf5..28603aea 100644 --- a/xps/muxps.h +++ b/xps/muxps.h @@ -33,20 +33,6 @@ int xps_strcasecmp(char *a, char *b); void xps_absolute_path(char *output, char *base_uri, char *path, int output_size); /* - * Generic hashtable. - */ - -typedef struct xps_hash_table_s xps_hash_table; - -xps_hash_table *xps_hash_new(void); -void *xps_hash_lookup(xps_hash_table *table, char *key); -int xps_hash_insert(xps_hash_table *table, char *key, void *value); -void xps_hash_free(xps_hash_table *table, - void (*free_key)(void *), - void (*free_value)(void *)); -void xps_hash_debug(xps_hash_table *table); - -/* * XML document model */ @@ -116,6 +102,15 @@ int xps_decode_jpeg(fz_pixmap **imagep, byte *rbuf, int rlen); int xps_decode_png(fz_pixmap **imagep, byte *rbuf, int rlen); int xps_decode_tiff(fz_pixmap **imagep, byte *rbuf, int rlen); +typedef struct xps_font_cache_s xps_font_cache; + +struct xps_font_cache_s +{ + char *name; + fz_font *font; + xps_font_cache *next; +}; + typedef struct xps_glyph_metrics_s xps_glyph_metrics; struct xps_glyph_metrics_s @@ -215,9 +210,8 @@ struct xps_context_s char *base_uri; /* base uri for parsing XML and resolving relative paths */ char *part_uri; /* part uri for parsing metadata relations */ - /* We cache font and colorspace resources */ - xps_hash_table *font_table; - xps_hash_table *colorspace_table; + /* We cache font resources */ + xps_font_cache *font_table; /* Opacity attribute stack */ float opacity[64]; diff --git a/xps/xps_glyphs.c b/xps/xps_glyphs.c index 9222d922..71c0b2a8 100644 --- a/xps/xps_glyphs.c +++ b/xps/xps_glyphs.c @@ -68,6 +68,26 @@ xps_measure_font_glyph(xps_context *ctx, fz_font *font, int gid, xps_glyph_metri mtx->vorg = face->ascender / (float) face->units_per_EM; } +static fz_font * +xps_lookup_font(xps_context *ctx, char *name) +{ + xps_font_cache *cache; + for (cache = ctx->font_table; cache; cache = cache->next) + if (!xps_strcasecmp(cache->name, name)) + return fz_keep_font(cache->font); + return NULL; +} + +static void +xps_insert_font(xps_context *ctx, char *name, fz_font *font) +{ + xps_font_cache *cache = fz_malloc(sizeof(xps_font_cache)); + cache->name = fz_strdup(name); + cache->font = fz_keep_font(font); + cache->next = ctx->font_table; + ctx->font_table = cache; +} + /* * Some fonts in XPS are obfuscated by XOR:ing the first 32 bytes of the * data with the GUID in the fontname. @@ -461,7 +481,7 @@ xps_parse_glyphs(xps_context *ctx, fz_matrix ctm, *subfont = 0; } - font = xps_hash_lookup(ctx->font_table, partname); + font = xps_lookup_font(ctx, partname); if (!font) { part = xps_read_part(ctx, partname); @@ -485,11 +505,12 @@ xps_parse_glyphs(xps_context *ctx, fz_matrix ctm, xps_select_best_font_encoding(font); - xps_hash_insert(ctx->font_table, part->name, font); + xps_insert_font(ctx, part->name, font); - /* NOTE: we keep part->name in the hashtable and part->data in the font */ + /* NOTE: we keep part->data in the font */ font->ft_data = part->data; font->ft_size = part->size; + fz_free(part->name); fz_free(part); } @@ -558,4 +579,6 @@ xps_parse_glyphs(xps_context *ctx, fz_matrix ctm, if (clip_att || clip_tag) fz_pop_clip(ctx->dev); + + fz_drop_font(font); } diff --git a/xps/xps_hash.c b/xps/xps_hash.c deleted file mode 100644 index c750717a..00000000 --- a/xps/xps_hash.c +++ /dev/null @@ -1,189 +0,0 @@ -/* Linear probe hash table. - * - * Simple hashtable with open adressing linear probe. - * Does not manage memory of key/value pointers. - * Does not support deleting entries. - */ - -#include "fitz.h" -#include "muxps.h" - -static const unsigned primes[] = -{ - 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381, 32749, 65521, - 131071, 262139, 524287, 1048573, 2097143, 4194301, 8388593, 0 -}; - -typedef struct xps_hash_entry_s xps_hash_entry; - -struct xps_hash_entry_s -{ - char *key; - void *value; -}; - -struct xps_hash_table_s -{ - void *ctx; - unsigned int size; - unsigned int load; - xps_hash_entry *entries; -}; - -static inline int xps_tolower(int c) -{ - if (c >= 'A' && c <= 'Z') - return c + 32; - return c; -} - -static unsigned int -xps_hash(char *s) -{ - unsigned int h = 0; - while (*s) - h = xps_tolower(*s++) + (h << 6) + (h << 16) - h; - return h; -} - -xps_hash_table * -xps_hash_new(void) -{ - xps_hash_table *table; - - table = fz_malloc(sizeof(xps_hash_table)); - table->size = primes[0]; - table->load = 0; - - table->entries = fz_calloc(table->size, sizeof(xps_hash_entry)); - memset(table->entries, 0, table->size * sizeof(xps_hash_entry)); - - return table; -} - -static int -xps_hash_double(xps_hash_table *table) -{ - xps_hash_entry *old_entries; - xps_hash_entry *new_entries; - unsigned int old_size = table->size; - unsigned int new_size = table->size * 2; - unsigned int i; - - for (i = 0; primes[i] != 0; i++) - { - if (primes[i] > old_size) - { - new_size = primes[i]; - break; - } - } - - old_entries = table->entries; - new_entries = fz_calloc(new_size, sizeof(xps_hash_entry)); - - table->size = new_size; - table->entries = new_entries; - table->load = 0; - - memset(table->entries, 0, table->size * sizeof(xps_hash_entry)); - - for (i = 0; i < old_size; i++) - if (old_entries[i].value) - xps_hash_insert(table, old_entries[i].key, old_entries[i].value); - - fz_free(old_entries); - - return 0; -} - -void -xps_hash_free(xps_hash_table *table, - void (*free_key)(void *), - void (*free_value)(void *)) -{ - unsigned int i; - - for (i = 0; i < table->size; i++) - { - if (table->entries[i].key && free_key) - free_key(table->entries[i].key); - if (table->entries[i].value && free_value) - free_value(table->entries[i].value); - } - - fz_free(table->entries); - fz_free(table); -} - -void * -xps_hash_lookup(xps_hash_table *table, char *key) -{ - xps_hash_entry *entries = table->entries; - unsigned int size = table->size; - unsigned int pos = xps_hash(key) % size; - - while (1) - { - if (!entries[pos].value) - return NULL; - - if (xps_strcasecmp(key, entries[pos].key) == 0) - return entries[pos].value; - - pos = (pos + 1) % size; - } -} - -int -xps_hash_insert(xps_hash_table *table, char *key, void *value) -{ - xps_hash_entry *entries; - unsigned int size, pos; - - /* Grow the table at 80% load */ - if (table->load > table->size * 8 / 10) - { - if (xps_hash_double(table) < 0) - return fz_rethrow(-1, "cannot grow hash table"); - } - - entries = table->entries; - size = table->size; - pos = xps_hash(key) % size; - - while (1) - { - if (!entries[pos].value) - { - entries[pos].key = key; - entries[pos].value = value; - table->load ++; - return 0; - } - - if (xps_strcasecmp(key, entries[pos].key) == 0) - { - return 0; - } - - pos = (pos + 1) % size; - } -} - -void -xps_hash_debug(xps_hash_table *table) -{ - unsigned int i; - - printf("hash table load %d / %d\n", table->load, table->size); - - for (i = 0; i < table->size; i++) - { - if (!table->entries[i].value) - printf("table % 4d: empty\n", i); - else - printf("table % 4d: key=%s value=%p\n", i, - table->entries[i].key, table->entries[i].value); - } -} diff --git a/xps/xps_zip.c b/xps/xps_zip.c index 57769b59..a0c981bf 100644 --- a/xps/xps_zip.c +++ b/xps/xps_zip.c @@ -398,9 +398,6 @@ xps_open_directory(xps_context **ctxp, char *directory) ctx = fz_malloc(sizeof(xps_context)); memset(ctx, 0, sizeof(xps_context)); - ctx->font_table = xps_hash_new(); - ctx->colorspace_table = xps_hash_new(); - ctx->start_part = NULL; ctx->directory = fz_strdup(directory); @@ -423,9 +420,6 @@ xps_open_stream(xps_context **ctxp, fz_stream *file) ctx = fz_malloc(sizeof(xps_context)); memset(ctx, 0, sizeof(xps_context)); - ctx->font_table = xps_hash_new(); - ctx->colorspace_table = xps_hash_new(); - ctx->start_part = NULL; ctx->file = fz_keep_stream(file); @@ -476,24 +470,10 @@ xps_open_file(xps_context **ctxp, char *filename) return fz_okay; } -static void xps_free_key_func(void *ptr) -{ - fz_free(ptr); -} - -static void xps_free_font_func(void *ptr) -{ - fz_drop_font(ptr); -} - -static void xps_free_colorspace_func(void *ptr) -{ - fz_drop_colorspace(ptr); -} - void xps_free_context(xps_context *ctx) { + xps_font_cache *font, *next; int i; if (ctx->file) @@ -503,8 +483,16 @@ xps_free_context(xps_context *ctx) fz_free(ctx->zip_table[i].name); fz_free(ctx->zip_table); - xps_hash_free(ctx->font_table, xps_free_key_func, xps_free_font_func); - xps_hash_free(ctx->colorspace_table, xps_free_key_func, xps_free_colorspace_func); + font = ctx->font_table; + while (font) + { + next = font->next; + fz_drop_font(font->font); + fz_free(font->name); + fz_free(font); + font = next; + } + xps_free_page_list(ctx); fz_free(ctx->start_part); |