summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChun-wei Fan <fanchunwei@src.gnome.org>2022-07-05 16:35:12 +0800
committerChun-wei Fan <fanchunwei@src.gnome.org>2022-08-01 18:23:33 +0800
commit79de98b717f841cc3343aac14c54d4f5d5755f86 (patch)
treeaffaa34cc0ba21e22d631469f4db8e848327597d
parenta4ed7a545f332822bd869a7ec509fa7cf8814ca3 (diff)
downloadpango2-windows.tar.gz
pangodwrite-fontmap: Add APIs to query font description from Windows fontspango2-windows
Add 2 APIs for querying the Pango2FontDescription that corresponds to the specified Windows LOGFONTW (GDI font) or IDWriteFont, largely using the code that we already have in the DirectWrite support. Notice that with the LOGFONTW path, we use DirectWrite's GDI interop to acquire a IDWriteFont first and then go down the same (existing) route as when we use a IDWriteFont, since it may be necessary to use LOGFONTW's since Windows APIs such as SystemParametersInfoW() return LOGFONTW's instead of IDWriteFont's, but DirectWrite has more fine-grained support for font properties than GDI.
-rw-r--r--pango2/pangodwrite-fontmap.cpp142
-rw-r--r--pango2/pangodwrite-fontmap.h11
2 files changed, 143 insertions, 10 deletions
diff --git a/pango2/pangodwrite-fontmap.cpp b/pango2/pangodwrite-fontmap.cpp
index 6fa51c24..d9321368 100644
--- a/pango2/pangodwrite-fontmap.cpp
+++ b/pango2/pangodwrite-fontmap.cpp
@@ -341,26 +341,53 @@ pango2_direct_write_font_map_populate (Pango2FontMap *map)
G_DEFINE_FINAL_TYPE (Pango2DirectWriteFontMap, pango2_direct_write_font_map, PANGO2_TYPE_FONT_MAP)
-static void
-pango2_direct_write_font_map_init (Pango2DirectWriteFontMap *self)
+struct DirectWriteItems
+{
+ IDWriteFactory *dwrite_factory;
+ IDWriteGdiInterop *gdi_interop;
+};
+
+static struct DirectWriteItems
+init_direct_write (void)
{
HRESULT hr;
+ struct DirectWriteItems dwrite_items = {NULL, NULL};
+ IDWriteFactory *dwrite_factory = NULL;
+ IDWriteGdiInterop *gdi_interop = NULL;
hr = DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED,
UUID_OF_IDWriteFactory,
- reinterpret_cast<IUnknown**> (&self->dwrite_factory));
+ reinterpret_cast<IUnknown**> (&dwrite_factory));
- if (FAILED (hr) || !self->dwrite_factory)
+ if (FAILED (hr) || !dwrite_factory)
g_error ("DWriteCreateFactory failed with error code %x", (unsigned)hr);
-
- if (self->dwrite_factory)
+ else
{
- hr = self->dwrite_factory->GetGdiInterop (&self->gdi_interop);
+ hr = dwrite_factory->GetGdiInterop (&gdi_interop);
- if (FAILED (hr) || !self->gdi_interop)
- g_error ("GdiInterop failed with error code %x", (unsigned)hr);
+ if (FAILED (hr) || !gdi_interop)
+ {
+ dwrite_factory->Release ();
+ g_error ("GdiInterop failed with error code %x", (unsigned)hr);
+ }
+ else
+ {
+ dwrite_items.dwrite_factory = dwrite_factory;
+ dwrite_items.gdi_interop = gdi_interop;
+ }
}
+ return dwrite_items;
+}
+
+static void
+pango2_direct_write_font_map_init (Pango2DirectWriteFontMap *self)
+{
+ struct DirectWriteItems dwrite_items = init_direct_write ();
+
+ self->dwrite_factory = dwrite_items.dwrite_factory;
+ self->gdi_interop = dwrite_items.gdi_interop;
+
pango2_font_map_repopulate (PANGO2_FONT_MAP (self), TRUE);
}
@@ -408,6 +435,103 @@ pango2_direct_write_font_map_new (void)
return (Pango2DirectWriteFontMap *) g_object_new (PANGO2_TYPE_DIRECT_WRITE_FONT_MAP, NULL);
}
+/**
+ * pango2_direct_write_get_font_description_from_dwrite_font:
+ * @dwrite_font: the `IDWriteFont` to query the font description
+ *
+ * Returns a `Pango2FontDescription` that corresonds to the `IDWriteFont`,
+ * this API is normally used from C++ as `IDWriteFont`'s are created or
+ * obtained via the Windows DirectWrite APIs, which are normally only
+ * accessible via C++.
+ *
+ * Return value: the `Pango2FontDescription` corresonding to @dwrite_font,
+ * the returned value should be freed with [method@Pango2.FontDescription.free]
+ */
+Pango2FontDescription *
+pango2_direct_write_get_font_description_from_dwrite_font (gpointer dwrite_font)
+{
+ HRESULT hr;
+ IDWriteFont *font = NULL;
+ IDWriteFontFamily *family = NULL;
+ Pango2FontDescription *desc = NULL;
+
+ g_return_val_if_fail (dwrite_font != NULL, NULL);
+
+ font = static_cast<IDWriteFont*>(dwrite_font);
+
+ hr = font->GetFontFamily (&family);
+
+ if (SUCCEEDED (hr) && family != NULL)
+ {
+ char *family_name = util_dwrite_get_font_family_name (family);
+
+ if (family_name != NULL)
+ desc = util_get_pango2_font_description (font, family_name);
+
+ family->Release ();
+ }
+ else
+ g_error ("IDWriteFont::GetFontFamily failed with error code %x\n", (unsigned)hr);
+
+ return desc;
+}
+
+/**
+ * pango2_direct_write_get_font_description_from_logfontw:
+ * @lfw: the `LOGFONTW` to query the font description
+ * @font_map: (nullable): the `Pango2FontMap` to use
+ *
+ * Returns a `Pango2FontDescription` that corresonds to the `LOGFONTW`. An optional
+ * `Pango2FontMap` of type `Pango2DirectWriteFontMap` may be passed in to indicate
+ * DirectWrite has been set up through Pango, to optimize things.
+ *
+ * Return value: the `Pango2FontDescription` corresonding to @lfw,
+ * the returned value should be freed with [method@Pango2.FontDescription.free]
+ */
+Pango2FontDescription *
+pango2_direct_write_get_font_description_from_logfontw (LOGFONTW *lfw,
+ Pango2FontMap *font_map)
+{
+ HRESULT hr;
+ IDWriteFont *dwrite_font = NULL;
+ Pango2DirectWriteFontMap *dwrite_fontmap = NULL;
+ Pango2FontDescription *desc = NULL;
+ struct DirectWriteItems dwrite_items = {NULL, NULL};
+ IDWriteFactory *dwrite_factory = NULL;
+ IDWriteGdiInterop *gdi_interop = NULL;
+
+ if (PANGO2_IS_DIRECT_WRITE_FONT_MAP (font_map))
+ gdi_interop = PANGO2_DIRECT_WRITE_FONT_MAP (font_map)->gdi_interop;
+ else
+ {
+ struct DirectWriteItems dwrite_items = init_direct_write ();
+
+ dwrite_factory = dwrite_items.dwrite_factory;
+ gdi_interop = dwrite_items.gdi_interop;
+
+ if (dwrite_factory == NULL || gdi_interop == NULL)
+ return NULL;
+ }
+
+ hr = gdi_interop->CreateFontFromLOGFONT (lfw, &dwrite_font);
+
+ if (FAILED (hr) || dwrite_font == NULL)
+ {
+ g_error ("IDWriteFactory::GdiInterop::CreateFontFromLOGFONT failed with error code %x\n", (unsigned)hr);
+ return NULL;
+ }
+
+ desc = pango2_direct_write_get_font_description_from_dwrite_font (dwrite_font);
+ dwrite_font->Release ();
+
+ if (dwrite_factory != NULL)
+ {
+ gdi_interop->Release ();
+ dwrite_factory->Release ();
+ }
+
+ return desc;
+}
/* }}} */
/* vim:set foldmethod=marker expandtab: */
diff --git a/pango2/pangodwrite-fontmap.h b/pango2/pangodwrite-fontmap.h
index c873759d..f79a0816 100644
--- a/pango2/pangodwrite-fontmap.h
+++ b/pango2/pangodwrite-fontmap.h
@@ -21,6 +21,9 @@
#pragma once
+#define WIN32_LEAN_AND_MEAN 1
+
+#include <windows.h>
#include <pango2/pango.h>
G_BEGIN_DECLS
@@ -34,7 +37,13 @@ PANGO2_DECLARE_INTERNAL_TYPE (Pango2DirectWriteFontMap,
Pango2FontMap)
PANGO2_AVAILABLE_IN_ALL
-Pango2DirectWriteFontMap * pango2_direct_write_font_map_new (void);
+Pango2DirectWriteFontMap *pango2_direct_write_font_map_new (void);
+
+PANGO2_AVAILABLE_IN_ALL
+Pango2FontDescription *pango2_direct_write_get_font_description_from_dwrite_font (gpointer dwrite_font);
+PANGO2_AVAILABLE_IN_ALL
+Pango2FontDescription *pango2_direct_write_get_font_description_from_logfontw (LOGFONTW *lfw,
+ Pango2FontMap *font_map);
G_END_DECLS