diff options
author | Oleg Oshmyan <chortos@inbox.lv> | 2021-06-26 18:16:41 +0300 |
---|---|---|
committer | Oleg Oshmyan <chortos@inbox.lv> | 2021-07-10 02:36:31 +0300 |
commit | 2a2d718e0fd6d47072566e519744634d93621353 (patch) | |
tree | 4562f6f4b7bb908061ab56d7f0dfe20da94b4fc6 /libass/ass_directwrite.c | |
parent | 979d7b890af66363dcdef2ae814cebe4053f2898 (diff) | |
download | libass-2a2d718e0fd6d47072566e519744634d93621353.tar.bz2 libass-2a2d718e0fd6d47072566e519744634d93621353.tar.xz |
directwrite: support WinRT/UWP, which forbid LoadLibrary
Normally, we delay loading Dwrite.dll until runtime to allow building
and running DirectWrite-enabled libass binaries on old Windows versions
that lack DirectWrite. However, this is forbidden in WinRT/UWP.
DirectWrite is present in all versions of Windows that support WinRT/UWP,
so we lose nothing by requiring it.
Older Windows SDKs (Microsoft and MinGW alike) lack <winapifamily.h>,
so include it only if we really need it.
Based on VLC patch for libass:
https://github.com/videolan/vlc/commit/eedb57aa96d2bc0046a6da2e081c75ae9edf8fd5
and on this autoconf code:
https://github.com/lu-zero/mfx_dispatch/commit/c51a54c15f51579804030c70592c0a26065f1242
Note: the VLC patch retained an unconditional call to FreeLibrary
in destroy_provider. However, FreeLibrary does not actually expect
NULL as argument, so this commit adds a guard to that call.
Perhaps FreeLibrary(NULL) simply fails cleanly and that's why
this has not caused VLC problems, but we should not rely on this.
Diffstat (limited to 'libass/ass_directwrite.c')
-rw-r--r-- | libass/ass_directwrite.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/libass/ass_directwrite.c b/libass/ass_directwrite.c index 55fce52..e6ee298 100644 --- a/libass/ass_directwrite.c +++ b/libass/ass_directwrite.c @@ -45,7 +45,9 @@ typedef struct { } FontPrivate; typedef struct { +#if ASS_WINAPI_DESKTOP HMODULE directwrite_lib; +#endif IDWriteFactory *factory; IDWriteGdiInterop *gdi_interop; } ProviderPrivate; @@ -389,7 +391,9 @@ static void destroy_provider(void *priv) ProviderPrivate *provider_priv = (ProviderPrivate *)priv; provider_priv->gdi_interop->lpVtbl->Release(provider_priv->gdi_interop); provider_priv->factory->lpVtbl->Release(provider_priv->factory); +#if ASS_WINAPI_DESKTOP FreeLibrary(provider_priv->directwrite_lib); +#endif free(provider_priv); } @@ -726,7 +730,15 @@ static ASS_FontProviderFuncs directwrite_callbacks = { .get_font_index = get_font_index, }; -typedef HRESULT (WINAPI *DWriteCreateFactoryFn)( +#if ASS_WINAPI_DESKTOP +typedef HRESULT (WINAPI *DWriteCreateFactoryFn) +#else +// LoadLibrary is forbidden in WinRT/UWP apps, so use DirectWrite directly. +// These apps cannot run on older Windows that lacks DirectWrite, +// so we lose nothing. +HRESULT WINAPI DWriteCreateFactory +#endif +( DWRITE_FACTORY_TYPE factoryType, REFIID iid, IUnknown **factory @@ -747,22 +759,23 @@ ASS_FontProvider *ass_directwrite_add_provider(ASS_Library *lib, IDWriteFactory *dwFactory = NULL; IDWriteGdiInterop *dwGdiInterop = NULL; ASS_FontProvider *provider = NULL; - DWriteCreateFactoryFn DWriteCreateFactoryPtr = NULL; ProviderPrivate *priv = NULL; +#if ASS_WINAPI_DESKTOP HMODULE directwrite_lib = LoadLibraryW(L"Dwrite.dll"); if (!directwrite_lib) goto cleanup; - DWriteCreateFactoryPtr = + DWriteCreateFactoryFn DWriteCreateFactory = (DWriteCreateFactoryFn)(void *)GetProcAddress(directwrite_lib, "DWriteCreateFactory"); - if (!DWriteCreateFactoryPtr) + if (!DWriteCreateFactory) goto cleanup; +#endif - hr = DWriteCreateFactoryPtr(DWRITE_FACTORY_TYPE_SHARED, - &IID_IDWriteFactory, - (IUnknown **) (&dwFactory)); + hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, + &IID_IDWriteFactory, + (IUnknown **) (&dwFactory)); if (FAILED(hr) || !dwFactory) { ass_msg(lib, MSGL_WARN, "Failed to initialize directwrite."); dwFactory = NULL; @@ -781,7 +794,9 @@ ASS_FontProvider *ass_directwrite_add_provider(ASS_Library *lib, if (!priv) goto cleanup; +#if ASS_WINAPI_DESKTOP priv->directwrite_lib = directwrite_lib; +#endif priv->factory = dwFactory; priv->gdi_interop = dwGdiInterop; @@ -798,8 +813,10 @@ cleanup: dwGdiInterop->lpVtbl->Release(dwGdiInterop); if (dwFactory) dwFactory->lpVtbl->Release(dwFactory); +#if ASS_WINAPI_DESKTOP if (directwrite_lib) FreeLibrary(directwrite_lib); +#endif return NULL; } |