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.
This commit is contained in:
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
20
meson.build
20
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']
|
||||
|
||||
Reference in New Issue
Block a user