[gtk/wip/fanc999/fontchooser.win32: 1391/1393] gtk/gtkfontchooserwidget.c: Support PangoWin32 fonts as well



commit 308d9dae0ad9aa6c15425def20acf7f911e05e07
Author: Chun-wei Fan <fanchunwei src gnome org>
Date:   Thu Jul 26 08:49:58 2018 +0800

    gtk/gtkfontchooserwidget.c: Support PangoWin32 fonts as well
    
    The current font tweaking support here actually assumes that
    PangoFCFonts are used, which is not the case on Windows unless one
    specifically uses the FontConfig backend (set PANGOCAIRO_BACKEND=fc).
    This means that if GTK+ is build with HarfBuzz and PangoFT support
    enabled, the attempting to run the font tweaking support code on Windows
    will crash unless the FontConfig Pango backend is used.
    
    Use the utility code that we just added to support turning the
    PangoWin32Font into a FT_Face, so that we can load it using HarfBuzz,
    which is necessary before Pango is updated to use HarfBuzz for shaping
    on all supported backends at least.  This will also allow the font
    tweaking page to at least display properly even if GTK+ is not built
    with PangoFT support.
    
    Note that for the font tweaking updates to be applied, PangoWin32 needs
    to be updated as well, but at least for the GTK+ front this will pave
    the foundation for this.

 gtk/gtkfontchooserwidget.c | 84 ++++++++++++++++++++++++++++++++++++----------
 gtk/meson.build            | 16 ++++++---
 meson.build                | 20 +++++++++--
 3 files changed, 97 insertions(+), 23 deletions(-)
---
diff --git a/gtk/gtkfontchooserwidget.c b/gtk/gtkfontchooserwidget.c
index 4f9954fd64..2602935d6f 100644
--- a/gtk/gtkfontchooserwidget.c
+++ b/gtk/gtkfontchooserwidget.c
@@ -25,6 +25,7 @@
 
 #include "gtkfontchooserwidget.h"
 #include "gtkfontchooserwidgetprivate.h"
+#include "gtkpangofontutilsprivate.h"
 
 #include "gtkadjustment.h"
 #include "gtkbuildable.h"
@@ -56,16 +57,19 @@
 #include "gtkgesturemultipress.h"
 #include "gtkeventcontrollerscroll.h"
 
-#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT)
-#include <pango/pangofc-font.h>
-#include <hb.h>
-#include <hb-ot.h>
-#include <hb-ft.h>
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_MULTIPLE_MASTERS_H
-#include "language-names.h"
-#include "script-names.h"
+#if defined(HAVE_HARFBUZZ)
+
+# include <hb.h>
+# include <hb-ot.h>
+# include <hb-ft.h>
+# include <ft2build.h>
+# include FT_FREETYPE_H
+# include FT_MULTIPLE_MASTERS_H
+
+# ifdef HAVE_PANGOFT
+#  include "language-names.h"
+#  include "script-names.h"
+# endif
 #endif
 
 #include "open-type-layout.h"
@@ -143,6 +147,8 @@ struct _GtkFontChooserWidgetPrivate
   GList *feature_items;
 
   GAction *tweak_action;
+
+  gpointer ft_extra_items;
 };
 
 enum {
@@ -870,7 +876,7 @@ gtk_font_chooser_widget_init (GtkFontChooserWidget *fontchooser)
   /* Load data and set initial style-dependent parameters */
   gtk_font_chooser_widget_load_fonts (fontchooser, TRUE);
 
-#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT)
+#if defined(HAVE_HARFBUZZ)
   gtk_font_chooser_widget_populate_features (fontchooser);
 #endif
 
@@ -1188,6 +1194,11 @@ gtk_font_chooser_widget_finalize (GObject *object)
 
   g_free (priv->font_features);
 
+#ifdef HAVE_HARFBUZZ
+  if (_gtk_pango_font_release_ft_items (priv->ft_extra_items))
+    g_free (priv->ft_extra_items);
+#endif
+
   G_OBJECT_CLASS (gtk_font_chooser_widget_parent_class)->finalize (object);
 }
 
@@ -1459,7 +1470,7 @@ gtk_font_chooser_widget_ensure_selection (GtkFontChooserWidget *fontchooser)
     }
 }
 
-#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT)
+#if defined(HAVE_HARFBUZZ)
 
 /* OpenType variations */
 
@@ -1610,10 +1621,14 @@ gtk_font_chooser_widget_update_font_variations (GtkFontChooserWidget *fontchoose
 {
   GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
   PangoFont *pango_font;
+ 
   FT_Face ft_face;
   FT_MM_Var *ft_mm_var;
   FT_Error ret;
+  FT_Byte *font_file_data = NULL;
   gboolean has_axis = FALSE;
+  PangoFontMap *font_map = NULL;
+  gpointer ft_extra_items = NULL;
 
   if (priv->updating_variations)
     return FALSE;
@@ -1626,7 +1641,21 @@ gtk_font_chooser_widget_update_font_variations (GtkFontChooserWidget *fontchoose
 
   pango_font = pango_context_load_font (gtk_widget_get_pango_context (GTK_WIDGET (fontchooser)),
                                         priv->font_desc);
-  ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font));
+
+  font_map = priv->font_map;
+  ft_extra_items = priv->ft_extra_items;
+
+  if (!font_map)
+    font_map = pango_cairo_font_map_get_default ();
+
+  if (!ft_extra_items)
+    {
+      ft_extra_items = _gtk_pango_font_init_extra_ft_items (pango_font);
+      if (ft_extra_items != NULL)
+        priv->ft_extra_items = ft_extra_items;
+    }
+
+  ft_face = _gtk_pango_font_get_ft_face (pango_font, font_map, ft_extra_items);
 
   ret = FT_Get_MM_Var (ft_face, &ft_mm_var);
   if (ret == 0)
@@ -1658,7 +1687,8 @@ gtk_font_chooser_widget_update_font_variations (GtkFontChooserWidget *fontchoose
       free (ft_mm_var);
     }
 
-  pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
+  _gtk_pango_font_release_ft_face (pango_font, ft_extra_items);
+
   g_object_unref (pango_font);
 
   return has_axis;
@@ -2130,6 +2160,8 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser)
   GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
   PangoFont *pango_font;
   FT_Face ft_face;
+  FT_Byte *font_file_data = NULL;
+
   hb_font_t *hb_font;
   hb_tag_t script_tag;
   hb_tag_t lang_tag;
@@ -2138,6 +2170,8 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser)
   int i, j;
   GList *l;
   gboolean has_feature = FALSE;
+  PangoFontMap *font_map = NULL;
+  gpointer ft_extra_items = NULL;
 
   for (l = priv->feature_items; l; l = l->next)
     {
@@ -2151,7 +2185,22 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser)
 
   pango_font = pango_context_load_font (gtk_widget_get_pango_context (GTK_WIDGET (fontchooser)),
                                         priv->font_desc);
-  ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)),
+
+  font_map = priv->font_map;
+  ft_extra_items = priv->ft_extra_items;
+
+  if (!font_map)
+    font_map = pango_cairo_font_map_get_default ();
+
+  if (!ft_extra_items)
+    {
+      ft_extra_items = _gtk_pango_font_init_extra_ft_items (pango_font);
+      if (ft_extra_items != NULL)
+        priv->ft_extra_items = ft_extra_items;
+    }
+
+  ft_face = _gtk_pango_font_get_ft_face (pango_font, font_map, ft_extra_items);
+
   hb_font = hb_ft_font_create (ft_face, NULL);
 
   if (hb_font)
@@ -2215,7 +2264,8 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser)
       hb_font_destroy (hb_font);
     }
 
-  pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
+  _gtk_pango_font_release_ft_face (pango_font, ft_extra_items);
+
   g_object_unref (pango_font);
 
   return has_feature;
@@ -2315,7 +2365,7 @@ gtk_font_chooser_widget_merge_font_desc (GtkFontChooserWidget       *fontchooser
 
       gtk_font_chooser_widget_update_marks (fontchooser);
 
-#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT)
+#if defined(HAVE_HARFBUZZ)
       if (gtk_font_chooser_widget_update_font_features (fontchooser))
         has_tweak = TRUE;
       if (gtk_font_chooser_widget_update_font_variations (fontchooser))
diff --git a/gtk/meson.build b/gtk/meson.build
index 76fef838f5..cb7defd69c 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -901,12 +901,20 @@ gtk_deps = [
   graphene_dep,
 ]
 
-if harfbuzz_dep.found() and pangoft_dep.found()
-  gtk_deps += [ harfbuzz_dep, pangoft_dep ]
+if build_with_harfbuzz
   gtk_sources += files([
-  'language-names.c',
-  'script-names.c',
+    'gtkpangofontutils.c',
   ])
+  gtk_deps += [ harfbuzz_dep ]
+  if pangoft_dep.found()
+    gtk_deps += [ pangoft_dep ]
+    gtk_sources += files([
+    'language-names.c',
+    'script-names.c',
+    ])
+  elif add_freetype_lib
+    gtk_deps += [ ft2_dep ]
+  endif
 endif
 
 if x11_enabled
diff --git a/meson.build b/meson.build
index 711b1cbbaa..6ec954f279 100644
--- a/meson.build
+++ b/meson.build
@@ -333,7 +333,9 @@ fribidi_dep    = dependency('fribidi', version: fribidi_req,
 require_pangoft2 = wayland_enabled or x11_enabled
 pangoft_dep    = dependency('pangoft2', required: false)
 
-if pangoft_dep.found()
+ft2_dep = []
+
+if pangoft_dep.found() or os_win32
   # Need at least 2.7.1 for FT_Get_Var_Design_Coordinates()
   # We get the dependency itself from pango, but pango doesn't care
   # about ft2 version, so an extra check is needed.
@@ -428,6 +430,9 @@ if cairogobj_dep.found()
 endif
 
 cairo_libs = []
+
+add_freetype_lib = false
+
 if cc.get_id() == 'msvc'
   # Fallback depedency discovery for those on Visual Studio that do not generate
   # pkg-config files in their build systems for MSVC
@@ -455,6 +460,9 @@ if cc.get_id() == 'msvc'
   if not harfbuzz_dep.found()
     if cc.has_header('hb.h')
       harfbuzz_dep = cc.find_library('harfbuzz', required : false)
+      if harfbuzz_dep.found()
+        add_freetype_lib = true
+      endif
     endif
   endif
 endif
@@ -464,7 +472,15 @@ if not harfbuzz_dep.found()
                             fallback: ['harfbuzz', 'libharfbuzz_dep'])
 endif
 
-cdata.set('HAVE_HARFBUZZ', harfbuzz_dep.found())
+build_with_harfbuzz = false
+
+if pangoft_dep.found()
+  build_with_harfbuzz = true
+elif os_win32 and harfbuzz_dep.found() and ft2_dep.found()
+  build_with_harfbuzz = cc.has_header_symbol('hb-ft.h', 'hb_ft_face_create', dependencies : harfbuzz_dep)
+endif
+
+cdata.set('HAVE_HARFBUZZ', build_with_harfbuzz)
 cdata.set('HAVE_PANGOFT', pangoft_dep.found())
 
 atk_pkgs = ['atk']


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]