From 601b6825b05f67354b48dd3629b95e0d8bf68a14 Mon Sep 17 00:00:00 2001 From: Carlo Bramini <30959007+carlo-bramini@users.noreply.github.com> Date: Sun, 30 Jun 2019 15:03:44 +0200 Subject: [PATCH 1/5] Dynamically load DWRITE Also checks if DWriteCreateFactory() has been executed successfully. --- src/hb-directwrite.cc | 45 +++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/src/hb-directwrite.cc b/src/hb-directwrite.cc index 9b851148b..1f00aa478 100644 --- a/src/hb-directwrite.cc +++ b/src/hb-directwrite.cc @@ -33,6 +33,13 @@ #include "hb-directwrite.h" +/* Declare object creator for dynamic support of DWRITE */ +typedef HRESULT (* WINAPI t_DWriteCreateFactory)( + DWRITE_FACTORY_TYPE factoryType, + REFIID iid, + IUnknown **factory +); + /* * hb-directwrite uses new/delete syntatically but as we let users * to override malloc/free, we will redefine new/delete so users @@ -138,6 +145,7 @@ public: struct hb_directwrite_face_data_t { + HMODULE dwrite_dll; IDWriteFactory *dwriteFactory; IDWriteFontFile *fontFile; DWriteFontFileStream *fontFileStream; @@ -153,12 +161,33 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face) if (unlikely (!data)) return nullptr; - // TODO: factory and fontFileLoader should be cached separately - IDWriteFactory* dwriteFactory; - DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), - (IUnknown**) &dwriteFactory); +#define FAIL(...) \ + HB_STMT_START { \ + DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \ + return nullptr; \ + } HB_STMT_END + + data->dwrite_dll = LoadLibrary(TEXT("DWRITE")); + if (data->dwrite_dll == NULL) + FAIL ("Cannot find DWrite.DLL"); + + t_DWriteCreateFactory p_DWriteCreateFactory; + + p_DWriteCreateFactory = (t_DWriteCreateFactory) + GetProcAddress(data->dwrite_dll, "DWriteCreateFactory"); + if (p_DWriteCreateFactory == NULL) + FAIL ("Cannot find DWriteCreateFactory()."); HRESULT hr; + + // TODO: factory and fontFileLoader should be cached separately + IDWriteFactory* dwriteFactory; + hr = p_DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), + (IUnknown**) &dwriteFactory); + + if (hr != S_OK) + FAIL ("Failed to run DWriteCreateFactory()."); + hb_blob_t *blob = hb_face_reference_blob (face); DWriteFontFileStream *fontFileStream; fontFileStream = new DWriteFontFileStream ((uint8_t *) hb_blob_get_data (blob, nullptr), @@ -172,12 +201,6 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face) hr = dwriteFactory->CreateCustomFontFileReference (&fontFileKey, sizeof (fontFileKey), fontFileLoader, &fontFile); -#define FAIL(...) \ - HB_STMT_START { \ - DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \ - return nullptr; \ - } HB_STMT_END - if (FAILED (hr)) FAIL ("Failed to load font file from data!"); @@ -224,6 +247,8 @@ _hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data) delete data->fontFileStream; if (data->faceBlob) hb_blob_destroy (data->faceBlob); + if (data->dwrite_dll != NULL) + FreeLibrary(data->dwrite_dll); if (data) delete data; } From a4543d408b31376c38bab878b2f72d4323abc564 Mon Sep 17 00:00:00 2001 From: Carlo Bramini <30959007+carlo-bramini@users.noreply.github.com> Date: Sun, 30 Jun 2019 15:06:30 +0200 Subject: [PATCH 2/5] Empty DIRECTWRITE_LIBS Not used anymore since DWRITE is loaded dynamically. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 0dc672a81..09ce4e6ec 100644 --- a/configure.ac +++ b/configure.ac @@ -376,7 +376,7 @@ if test "x$with_directwrite" = "xyes" -a "x$have_directwrite" != "xtrue"; then fi if $have_directwrite; then DIRECTWRITE_CXXFLAGS= - DIRECTWRITE_LIBS="-ldwrite" + DIRECTWRITE_LIBS= AC_SUBST(DIRECTWRITE_CXXFLAGS) AC_SUBST(DIRECTWRITE_LIBS) AC_DEFINE(HAVE_DIRECTWRITE, 1, [Have DirectWrite library]) From 693dacbb1c0bc805e3e6aedaca5a57f04eb6ec9c Mon Sep 17 00:00:00 2001 From: Carlo Bramini <30959007+carlo-bramini@users.noreply.github.com> Date: Mon, 1 Jul 2019 13:31:26 +0200 Subject: [PATCH 3/5] Use lower case file name with #include I tried to cross compile harfbuzz for Windows and an error was generated because `DWrite_1.h` was not found. This happened because the filesystem is case sensitive and for this reason that include file was not found. The right name of the file to be used is `dwrite_1.h`, with all letters not capitalized: https://docs.microsoft.com/en-us/windows/desktop/api/dwrite_1/ I also verified in the installation of VS2017 with Windows Kit v10 and in that place it was also lower case. So, in my opinion it should be better to change this. --- src/hb-directwrite.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-directwrite.cc b/src/hb-directwrite.cc index 1f00aa478..1b2bd1964 100644 --- a/src/hb-directwrite.cc +++ b/src/hb-directwrite.cc @@ -28,7 +28,7 @@ #include "hb-shaper-impl.hh" -#include +#include #include "hb-directwrite.h" From 5ebd265e66cbcd167469837dcf8647484310dfb5 Mon Sep 17 00:00:00 2001 From: Carlo Bramini <30959007+carlo-bramini@users.noreply.github.com> Date: Mon, 1 Jul 2019 16:06:43 +0200 Subject: [PATCH 4/5] Fix error rised by GCC8+ --- src/hb-directwrite.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/hb-directwrite.cc b/src/hb-directwrite.cc index 1b2bd1964..865100aa2 100644 --- a/src/hb-directwrite.cc +++ b/src/hb-directwrite.cc @@ -173,8 +173,18 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face) t_DWriteCreateFactory p_DWriteCreateFactory; +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + p_DWriteCreateFactory = (t_DWriteCreateFactory) GetProcAddress(data->dwrite_dll, "DWriteCreateFactory"); + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + if (p_DWriteCreateFactory == NULL) FAIL ("Cannot find DWriteCreateFactory()."); From 4ab2d1d6767568c45495be515e016805cce0c69a Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 1 Jul 2019 19:30:21 +0430 Subject: [PATCH 5/5] [dwrite] Apply minor style improves --- src/hb-directwrite.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hb-directwrite.cc b/src/hb-directwrite.cc index 865100aa2..a625763da 100644 --- a/src/hb-directwrite.cc +++ b/src/hb-directwrite.cc @@ -167,8 +167,8 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face) return nullptr; \ } HB_STMT_END - data->dwrite_dll = LoadLibrary(TEXT("DWRITE")); - if (data->dwrite_dll == NULL) + data->dwrite_dll = LoadLibrary (TEXT ("DWRITE")); + if (unlikely (!data->dwrite_dll)) FAIL ("Cannot find DWrite.DLL"); t_DWriteCreateFactory p_DWriteCreateFactory; @@ -179,13 +179,13 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face) #endif p_DWriteCreateFactory = (t_DWriteCreateFactory) - GetProcAddress(data->dwrite_dll, "DWriteCreateFactory"); + GetProcAddress (data->dwrite_dll, "DWriteCreateFactory"); #if defined(__GNUC__) #pragma GCC diagnostic pop #endif - if (p_DWriteCreateFactory == NULL) + if (unlikely (!p_DWriteCreateFactory)) FAIL ("Cannot find DWriteCreateFactory()."); HRESULT hr; @@ -193,9 +193,9 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face) // TODO: factory and fontFileLoader should be cached separately IDWriteFactory* dwriteFactory; hr = p_DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), - (IUnknown**) &dwriteFactory); + (IUnknown**) &dwriteFactory); - if (hr != S_OK) + if (unlikely (hr != S_OK)) FAIL ("Failed to run DWriteCreateFactory()."); hb_blob_t *blob = hb_face_reference_blob (face); @@ -257,8 +257,8 @@ _hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data) delete data->fontFileStream; if (data->faceBlob) hb_blob_destroy (data->faceBlob); - if (data->dwrite_dll != NULL) - FreeLibrary(data->dwrite_dll); + if (data->dwrite_dll) + FreeLibrary (data->dwrite_dll); if (data) delete data; }