From 773131e104d13718aaa3d47e56c50c75f04e8ee6 Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Thu, 28 Jan 2016 19:28:10 +0000 Subject: Force all harfbuzz allocations through our allocators. Because of a shortcoming in harfbuzz, we can't easily force all its allocations through our allocators. We fudge it, with the addition of some macros to change malloc/free/calloc into hb_malloc/hb_free/hb_calloc. To prevent thread safety issues, we use our freetype lock around calls to harfbuzz. We stash the current context in a static var. --- source/fitz/harfbuzz.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 source/fitz/harfbuzz.c (limited to 'source/fitz/harfbuzz.c') diff --git a/source/fitz/harfbuzz.c b/source/fitz/harfbuzz.c new file mode 100644 index 00000000..60d75469 --- /dev/null +++ b/source/fitz/harfbuzz.c @@ -0,0 +1,98 @@ +/* + * Some additional glue functions for using Harfbuzz with + * custom allocators. + */ + +#include "mupdf/fitz.h" + +#include "hb.h" + +/* Potentially we can write different versions + * of get_context and set_context for different + * threading systems. + * + * This simple version relies on harfbuzz never + * trying to make 2 allocations at once on + * different threads. The only way that can happen + * is when one of those other threads is someone + * outside MuPDF calling harfbuzz while MuPDF + * is running. + * + * If this is actually a problem, then we can + * reimplement set_context/get_context using + * Thread Local Storage. + */ + +static fz_context *hb_secret = NULL; + +static void set_context(fz_context *ctx) +{ + hb_secret = ctx; +} + +static fz_context *get_context() +{ + return hb_secret; +} + +void hb_lock(fz_context *ctx) +{ + fz_lock(ctx, FZ_LOCK_FREETYPE); + + set_context(ctx); +} + +void hb_unlock(fz_context *ctx) +{ + set_context(NULL); + + fz_unlock(ctx, FZ_LOCK_FREETYPE); +} + +void *hb_malloc(size_t size) +{ + fz_context *ctx = get_context(); + + /* Should never happen, but possibly someone else + * is calling our version of the library. */ + if (ctx == NULL) + return malloc(size); + + return fz_malloc_no_throw(ctx, (unsigned int)size); +} + +void *hb_calloc(size_t n, size_t size) +{ + fz_context *ctx = get_context(); + + /* Should never happen, but possibly someone else + * is calling our version of the library. */ + if (ctx == NULL) + return calloc(n, size); + + return fz_calloc_no_throw(ctx, (unsigned int)n, (unsigned int)size); +} + +void *hb_realloc(void *ptr, size_t size) +{ + fz_context *ctx = get_context(); + + /* Should never happen, but possibly someone else + * is calling our version of the library. */ + if (ctx == NULL) + return realloc(ptr, size); + + return fz_resize_array_no_throw(ctx, ptr, (unsigned int)1, (unsigned int)size); +} + +void hb_free(void *ptr) +{ + fz_context *ctx = get_context(); + + /* Should never happen, but possibly someone else + * is calling our version of the library. */ + if (ctx == NULL) + free(ptr); + else + fz_free(ctx, ptr); +} -- cgit v1.2.3