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. --- Makethird | 4 +- include/mupdf/fitz/font.h | 3 ++ platform/win32/libmupdf.vcproj | 4 ++ platform/win32/libthirdparty.vcproj | 6 +-- source/fitz/harfbuzz.c | 98 +++++++++++++++++++++++++++++++++++++ thirdparty/harfbuzz | 2 +- 6 files changed, 112 insertions(+), 5 deletions(-) create mode 100644 source/fitz/harfbuzz.c diff --git a/Makethird b/Makethird index f6f0cbbe..facd0c8e 100644 --- a/Makethird +++ b/Makethird @@ -157,7 +157,9 @@ $(HARFBUZZ_OUT): $(MKDIR_CMD) $(HARFBUZZ_OUT)/%.o: $(HARFBUZZ_DIR)/src/%.cc | $(HARFBUZZ_OUT) $(CC_CMD) -DHAVE_OT -DHAVE_UCDN -DHB_NO_MT $(FREETYPE_CFLAGS) \ - -fno-rtti -fno-exceptions -fvisibility-inlines-hidden --std=c++0x + -Dhb_malloc_impl=hb_malloc -Dhb_calloc_impl=hb_calloc \ + -Dhb_free_impl=hb_free -Dhb_realloc_impl=hb_realloc \ + -fno-rtti -fno-exceptions -fvisibility-inlines-hidden --std=c++0x HARFBUZZ_CFLAGS := -I$(HARFBUZZ_DIR)/src else diff --git a/include/mupdf/fitz/font.h b/include/mupdf/fitz/font.h index 2371b485..47866f9e 100644 --- a/include/mupdf/fitz/font.h +++ b/include/mupdf/fitz/font.h @@ -117,4 +117,7 @@ int fz_encode_character_with_fallback(fz_context *ctx, fz_font *font, int unicod void fz_print_font(fz_context *ctx, fz_output *out, fz_font *font); +void hb_lock(fz_context *ctx); +void hb_unlock(fz_context *ctx); + #endif diff --git a/platform/win32/libmupdf.vcproj b/platform/win32/libmupdf.vcproj index 9dd64b6f..5de9c62b 100644 --- a/platform/win32/libmupdf.vcproj +++ b/platform/win32/libmupdf.vcproj @@ -890,6 +890,10 @@ RelativePath="..\..\source\fitz\halftone.c" > + + diff --git a/platform/win32/libthirdparty.vcproj b/platform/win32/libthirdparty.vcproj index 934a88f3..468fdee5 100644 --- a/platform/win32/libthirdparty.vcproj +++ b/platform/win32/libthirdparty.vcproj @@ -43,7 +43,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="..\..\scripts\freetype;..\..\scripts\jpeg;..\..\scripts\openjpeg;..\..\thirdparty\jbig2dec;..\..\thirdparty\jpeg;..\..\thirdparty\openjpeg\libopenjpeg;..\..\thirdparty\zlib;..\..\thirdparty\freetype\include;..\..\thirdparty\freetype\include\freetype;..\..\include\" - PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H=\"slimftmodules.h\";FT_CONFIG_OPTIONS_H=\"slimftoptions.h\";DEBUG=1;verbose=-1;JBIG_EXTERNAL_MEMENTO_H=\"memento.h\";HAVE_OT;HAVE_UCDN;HB_NO_MT" + PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H=\"slimftmodules.h\";FT_CONFIG_OPTIONS_H=\"slimftoptions.h\";DEBUG=1;verbose=-1;JBIG_EXTERNAL_MEMENTO_H=\"memento.h\";HAVE_OT;HAVE_UCDN;HB_NO_MT;hb_malloc_impl=hb_malloc;hb_calloc_impl=hb_calloc;hb_realloc_impl=hb_realloc;hb_free_impl=hb_free" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="1" @@ -168,7 +168,7 @@ Optimization="2" EnableIntrinsicFunctions="true" AdditionalIncludeDirectories="..\..\scripts\freetype;..\..\scripts\jpeg;..\..\scripts\openjpeg;..\..\thirdparty\jbig2dec;..\..\thirdparty\jpeg;..\..\thirdparty\openjpeg\libopenjpeg;..\..\thirdparty\zlib;..\..\thirdparty\freetype\include;..\..\thirdparty\freetype\include\freetype;..\..\include\" - PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H=\"slimftmodules.h\";FT_CONFIG_OPTIONS_H=\"slimftoptions.h\";verbose=-1;JBIG_EXTERNAL_MEMENTO_H=\"memento.h\";HAVE_OT;HAVE_UCDN;HB_NO_MT" + PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H=\"slimftmodules.h\";FT_CONFIG_OPTIONS_H=\"slimftoptions.h\";verbose=-1;JBIG_EXTERNAL_MEMENTO_H=\"memento.h\";HAVE_OT;HAVE_UCDN;HB_NO_MT;hb_malloc_impl=hb_malloc;hb_calloc_impl=hb_calloc;hb_realloc_impl=hb_realloc;hb_free_impl=hb_free" RuntimeLibrary="0" EnableFunctionLevelLinking="true" WarningLevel="3" @@ -291,7 +291,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="..\..\scripts\freetype;..\..\scripts\jpeg;..\..\scripts\openjpeg;..\..\thirdparty\jbig2dec;..\..\thirdparty\jpeg;..\..\thirdparty\openjpeg\libopenjpeg;..\..\thirdparty\zlib;..\..\thirdparty\freetype\include;..\..\thirdparty\freetype\include\freetype;..\..\include\" - PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H=\"slimftmodules.h\";FT_CONFIG_OPTIONS_H=\"slimftoptions.h\";MEMENTO=1;DEBUG=1;verbose=-1;JBIG_EXTERNAL_MEMENTO_H=\"memento.h\";HAVE_OT;HAVE_UCDN;HB_NO_MT" + PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H=\"slimftmodules.h\";FT_CONFIG_OPTIONS_H=\"slimftoptions.h\";MEMENTO=1;DEBUG=1;verbose=-1;JBIG_EXTERNAL_MEMENTO_H=\"memento.h\";HAVE_OT;HAVE_UCDN;HB_NO_MT;hb_malloc_impl=hb_malloc;hb_calloc_impl=hb_calloc;hb_realloc_impl=hb_realloc;hb_free_impl=hb_free" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="1" 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); +} diff --git a/thirdparty/harfbuzz b/thirdparty/harfbuzz index 7b98e93e..2ec7f66c 160000 --- a/thirdparty/harfbuzz +++ b/thirdparty/harfbuzz @@ -1 +1 @@ -Subproject commit 7b98e93ea5e2d08377ec481006a87a3bc05df789 +Subproject commit 2ec7f66c6124219c83ce4ff64d96b75f0cf59561 -- cgit v1.2.3