[gtk/wip/fanc999/fontchooser.win32.gtk3: 1/3] gtk/: Add a utility source to obtain a FT_Face from a PangoFont
- From: Chun-wei Fan <fanchunwei src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/fanc999/fontchooser.win32.gtk3: 1/3] gtk/: Add a utility source to obtain a FT_Face from a PangoFont
- Date: Fri, 4 Jan 2019 11:13:29 +0000 (UTC)
commit e849755883f9c80bcfaf3b6c97c507894b500c26
Author: Chun-wei Fan <fanchunwei src gnome org>
Date: Fri Jan 4 18:23:26 2019 +0800
gtk/: Add a utility source to obtain a FT_Face from a PangoFont
...Which is necessary on Windows when PangoFT2 is not being used. This
is a source file that is included by both gtk/gtkfontchooserwidget.c and
demos/gtk-demo/font_features.c. Define macros in there so that the code
will pick the right code path depending on:
-Whether we are running on Windows.
-If we are on Windows, determine whether we are using PangoFT2 or
PangoWin32, if PangoFT2 support is enabled.
-If PangoFT2 is being used, acquire the FT_Face as we did before.
-Otherwise (on Windows), obtain the FT_Face by using the HFONT that we
obtain from PangoWin32.
gtk/Makefile.am | 3 +-
gtk/gtk-pangofont-ftface-util.c | 228 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 230 insertions(+), 1 deletion(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 8e86bce763..453aa42ad7 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -1171,7 +1171,8 @@ gtk_extra_sources = \
deprecated/gtkstatusicon-quartz.c \
gtkversion.h.in \
gtkmarshalers.list \
- fallback-c89.c
+ fallback-c89.c \
+ gtk-pangofont-ftface-util.c
#
# setup GTK+ sources and their dependencies
diff --git a/gtk/gtk-pangofont-ftface-util.c b/gtk/gtk-pangofont-ftface-util.c
new file mode 100644
index 0000000000..2a2379f2e7
--- /dev/null
+++ b/gtk/gtk-pangofont-ftface-util.c
@@ -0,0 +1,228 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2019 Chun-wei Fan <fanc999 yahoo com tw>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_PANGOFT
+# include <pango/pangofc-font.h>
+
+/* On Windows, we need to check whether the PangoFont is a FontConfig Font or a Win32/GDI font,
+ * and acquire/release the FT_Face accordingly.
+ */
+# ifdef GDK_WINDOWING_WIN32
+# define FT_EXT_ITEM_INIT(f) \
+ PANGO_IS_FC_FONT(f) ? \
+ NULL : \
+ g_new0 (gtk_win32_ft_items, 1)
+
+# define FT_FACE_FROM_PANGO_FONT(i,f,m) \
+ PANGO_IS_FC_FONT(f) ? \
+ pango_fc_font_lock_face (PANGO_FC_FONT (f)) : \
+ pangowin32_font_get_ftface (i, f, m)
+
+# define PANGO_FONT_RELEASE_FT_FACE(i,f) \
+ PANGO_IS_FC_FONT(f) ? \
+ pango_fc_font_unlock_face (PANGO_FC_FONT (f)) : \
+ pangowin32_font_get_ftface_release_ftface (i);
+
+# define RELEASE_EXTRA_FT_ITEMS(i) release_extra_ft_items(i)
+
+# else /* On non-Windows, acquire/release the FT_Face as we did before */
+# define FT_EXT_ITEM_INIT(f) NULL
+# define FT_FACE_FROM_PANGO_FONT(i,f,m) pango_fc_font_lock_face (PANGO_FC_FONT (f))
+# define PANGO_FONT_RELEASE_FT_FACE(i,f) pango_fc_font_unlock_face (PANGO_FC_FONT (f))
+# define RELEASE_EXTRA_FT_ITEMS(i)
+# endif
+#elif defined (GDK_WINDOWING_WIN32)
+
+# define FT_EXT_ITEM_INIT(f) g_new0 (gtk_win32_ft_items, 1)
+# define FT_FACE_FROM_PANGO_FONT(i,f,m) pangowin32_font_get_ftface (i, f, m)
+# define PANGO_FONT_RELEASE_FT_FACE(i,f) pangowin32_font_get_ftface_release_ftface (i)
+# define RELEASE_EXTRA_FT_ITEMS(i) release_extra_ft_items(i)
+#endif
+
+/* Until Pango uses HarfBuzz for shaping on all platforms, we need to go through FreeType */
+#ifdef GDK_WINDOWING_WIN32
+
+#include <pango/pangowin32.h>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_MODULE_H
+
+/* Check for TTC fonts and get their font data */
+# define FONT_TABLE_TTCF (('t' << 0) + ('t' << 8) + ('c' << 16) + ('f' << 24))
+
+typedef struct _gtk_win32_ft_items
+{
+ FT_Library ft_lib;
+ FT_Byte *font_data_stream;
+ FT_Face face;
+ HDC hdc;
+ LOGFONTW *logfont;
+ HFONT hfont;
+ PangoWin32FontCache *cache;
+} gtk_win32_ft_items;
+
+#define WIN32_FT_FACE_FAIL(msg) \
+{ \
+ g_warning(msg); \
+ goto ft_face_fail; \
+}
+
+static FT_Face
+pangowin32_font_get_ftface (gtk_win32_ft_items *item,
+ PangoFont *font,
+ PangoFontMap *font_map)
+{
+ PangoWin32FontCache *cache = NULL;
+ LOGFONTW *logfont = NULL;
+ HFONT hfont = NULL;
+ HFONT hfont_orig = NULL;
+ HDC hdc = NULL;
+ DWORD is_ttc_font;
+ FT_Face face;
+ FT_Byte *font_stream = NULL;
+ unsigned char buf[4];
+ gsize font_size;
+
+ if (item == NULL)
+ item = g_new0 (gtk_win32_ft_items, 1);
+
+ cache = pango_win32_font_map_get_font_cache (font_map);
+
+ if (!cache)
+ WIN32_FT_FACE_FAIL ("Failed to acquire PangoWin32FontCache");
+
+ logfont = pango_win32_font_logfontw (font);
+
+ if (logfont == NULL)
+ WIN32_FT_FACE_FAIL ("Unable to acquire LOGFONT from PangoFont");
+
+ hfont = pango_win32_font_cache_loadw (cache, logfont);
+
+ if (hfont == NULL)
+ WIN32_FT_FACE_FAIL ("Unable to acquire HFONT from PangoWin32FontCache with LOGFONT (LOGFONT invalid?)");
+
+ hdc = GetDC (NULL);
+
+ if (hdc == NULL)
+ WIN32_FT_FACE_FAIL ("Failed to acquire DC");
+
+ if (item->ft_lib == NULL)
+ {
+ if (FT_Init_FreeType (&item->ft_lib) != FT_Err_Ok)
+ WIN32_FT_FACE_FAIL ("Failed to initialize FreeType for PangoWin32Font->FT_Face transformation");
+ }
+
+ hfont_orig = SelectObject (hdc, hfont);
+ if (hfont_orig == HGDI_ERROR)
+ WIN32_FT_FACE_FAIL ("SelectObject() for the PangoFont failed");
+
+ /* is_ttc_font is GDI_ERROR if the HFONT does not refer to a font in a TTC when,
+ * specifying FONT_TABLE_TTCF for the Font Table type, otherwise it is 1,
+ * so try again without specifying FONT_TABLE_TTCF if is_ttc_font is not 1
+ */
+ is_ttc_font = GetFontData (hdc, FONT_TABLE_TTCF, 0, &buf, 1);
+
+ if (is_ttc_font == 1)
+ font_size = GetFontData (hdc, FONT_TABLE_TTCF, 0, NULL, 0);
+ else
+ font_size = GetFontData (hdc, 0, 0, NULL, 0);
+
+ if (font_size == GDI_ERROR)
+ WIN32_FT_FACE_FAIL ("Could not acquire font size from GetFontData()");
+
+ /* Now, get the font data stream that we need for creating the FT_Face */
+ font_stream = g_malloc (font_size);
+ if (GetFontData (hdc,
+ is_ttc_font == 1 ? FONT_TABLE_TTCF : 0,
+ 0,
+ font_stream,
+ font_size) == GDI_ERROR)
+ {
+ WIN32_FT_FACE_FAIL ("Unable to get data stream of font!");
+ }
+
+ /* Finally, create the FT_Face we need */
+ if (FT_New_Memory_Face (item->ft_lib,
+ font_stream,
+ font_size,
+ 0,
+ &face) == FT_Err_Ok)
+ {
+ /* We need to track these because we can only release/free those items *after* we
+ * are done with them in FreeType
+ */
+ item->cache = cache;
+ item->logfont = logfont;
+ item->hdc = hdc;
+ item->hfont = hfont;
+ item->font_data_stream = font_stream;
+ item->face = face;
+ return item->face;
+ }
+
+ else
+ WIN32_FT_FACE_FAIL ("Unable to create FT_Face from font data stream!");
+
+ft_face_fail:
+ if (font_stream != NULL)
+ g_free (font_stream);
+
+ if (hdc != NULL)
+ ReleaseDC (NULL, hdc);
+
+ if (cache != NULL && hfont != NULL)
+ pango_win32_font_cache_unload (cache, hfont);
+
+ if (logfont != NULL)
+ g_free (logfont);
+
+ return NULL;
+}
+
+#undef WIN32_FT_FACE_FAIL
+
+static void
+pangowin32_font_get_ftface_release_ftface (gtk_win32_ft_items *item)
+{
+ FT_Done_Face (item->face);
+ g_free (item->font_data_stream);
+ ReleaseDC (NULL, item->hdc);
+ item->hdc = NULL;
+ pango_win32_font_cache_unload (item->cache, item->hfont);
+ g_free (item->logfont);
+}
+
+static gboolean
+release_extra_ft_items (gpointer *item)
+{
+ if (item != NULL)
+ {
+ gtk_win32_ft_items *ft_item = (gtk_win32_ft_items *) item;
+
+ if (ft_item->ft_lib != NULL)
+ FT_Done_Library (ft_item->ft_lib);
+
+ g_free (item);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+#endif /* GDK_WINDOWING_WIN32 */
\ No newline at end of file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]