summaryrefslogtreecommitdiff
path: root/source/fitz
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2016-01-28 19:28:10 +0000
committerRobin Watts <robin.watts@artifex.com>2016-01-29 14:35:55 +0000
commit773131e104d13718aaa3d47e56c50c75f04e8ee6 (patch)
treead2321b2a63a1113dc25078304cca7020c5b9711 /source/fitz
parent52ed5832db9ea4bcc9dcfd2f0391af89f5aadd95 (diff)
downloadmupdf-773131e104d13718aaa3d47e56c50c75f04e8ee6.tar.xz
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.
Diffstat (limited to 'source/fitz')
-rw-r--r--source/fitz/harfbuzz.c98
1 files changed, 98 insertions, 0 deletions
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);
+}