summaryrefslogtreecommitdiffstats
path: root/libass/ass_directwrite.c
diff options
context:
space:
mode:
authorOleg Oshmyan <chortos@inbox.lv>2021-06-26 18:16:41 +0300
committerOleg Oshmyan <chortos@inbox.lv>2021-07-10 02:36:31 +0300
commit2a2d718e0fd6d47072566e519744634d93621353 (patch)
tree4562f6f4b7bb908061ab56d7f0dfe20da94b4fc6 /libass/ass_directwrite.c
parent979d7b890af66363dcdef2ae814cebe4053f2898 (diff)
downloadlibass-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.c31
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;
}