summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2011-04-10 00:55:32 +0200
committerTor Andersson <tor.andersson@artifex.com>2011-04-10 00:55:32 +0200
commite8e507b38b8c4429abd6e7b32fe8e3029bfab065 (patch)
treefa68533001685c2c48aa556687a020bc407a988a
parentf6e4a9614978334ca4a8e212bb8b44f34ac94ce2 (diff)
downloadmupdf-e8e507b38b8c4429abd6e7b32fe8e3029bfab065.tar.xz
xps: Use specific font cache struct instead of hash table.
-rw-r--r--win32/libmupdf.vcproj4
-rw-r--r--xps/muxps.h28
-rw-r--r--xps/xps_glyphs.c29
-rw-r--r--xps/xps_hash.c189
-rw-r--r--xps/xps_zip.c34
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);