From e1422d73b12c400c15d64ed0dc0892c7e856d744 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Thu, 25 Nov 2021 12:28:27 +0800 Subject: [PATCH 1/9] gtkfontchooserwidget.c: Always enable font features with later Pango This is a backport of the code in GTK4 where we can use the font features that is given to us via HarfBuzz if we have Pango 1.44.x and HarfBuzz 2.2.0 or later installed, even if we do not have PangoFT2 aavilable. Since Pango 1.44.x depends on HarfBuzz for all platforms after 1.44.0, we could take advantage of that and build the support in GtkFontChooserWidget. Add a directive that is to be used by Visual Studio compilers via the Visual Studio projects to link to harfbuzz.lib automatically, so that this support can be linked properly if we have the required Pango and HarfBuzz headers and lib's installed. Meson builds via Visual Studio should handle this automatically, since pkg-config is being used there. Since HAVE_PANGOFT2 and HAVE_HARFBUZZ is not defined by default in the Visaul Studio projects, we will leave it up to the user to enable them themselves and put in pangoft2-1.0.lib and harfbuzz.lib in the project settings by themselves, or they could use Meson, as we did before. --- gtk/gtkfontchooserwidget.c | 339 +++++++++++++++++++++++++++++++------ 1 file changed, 286 insertions(+), 53 deletions(-) diff --git a/gtk/gtkfontchooserwidget.c b/gtk/gtkfontchooserwidget.c index ed52352d7a..4347af862c 100644 --- a/gtk/gtkfontchooserwidget.c +++ b/gtk/gtkfontchooserwidget.c @@ -53,7 +53,15 @@ #include "gtkcombobox.h" #include "gtkgesturemultipress.h" -#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT) +#if (PANGO_VERSION_CHECK(1,44,0) && HB_VERSION_ATLEAST(2,2,0)) || \ + (defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT)) +#define HAVE_FONT_FEATURES 1 +#if !(PANGO_VERSION_CHECK(1,44,0) && HB_VERSION_ATLEAST(2,2,0)) +#define FONT_FEATURES_USE_PANGOFT2 1 +#endif +#endif + +#ifdef FONT_FEATURES_USE_PANGOFT2 #include #include #include @@ -62,6 +70,12 @@ #include #include "language-names.h" #include "script-names.h" +#elif defined (HAVE_FONT_FEATURES) +#include + +#if defined (_MSC_VER) && defined (__MSVC_PROJECTS__) +#pragma comment(lib, "harfbuzz") +#endif #endif #include "open-type-layout.h" @@ -763,7 +777,7 @@ change_tweak (GSimpleAction *action, g_simple_action_set_state (action, state); } -#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT) +#ifdef HAVE_FONT_FEATURES typedef struct { guint32 tag; @@ -823,7 +837,7 @@ gtk_font_chooser_widget_init (GtkFontChooserWidget *fontchooser) gtk_widget_init_template (GTK_WIDGET (fontchooser)); -#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT) +#ifdef HAVE_FONT_FEATURES priv->axes = g_hash_table_new_full (axis_hash, axis_equal, NULL, axis_free); #endif @@ -864,7 +878,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) +#ifdef HAVE_FONT_FEATURES gtk_font_chooser_widget_populate_features (fontchooser); #endif gtk_font_chooser_widget_set_cell_size (fontchooser); @@ -1475,7 +1489,7 @@ gtk_font_chooser_widget_ensure_selection (GtkFontChooserWidget *fontchooser) } } -#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT) +#ifdef HAVE_FONT_FEATURES /* OpenType variations */ @@ -1533,6 +1547,7 @@ adjustment_changed (GtkAdjustment *adjustment, priv->updating_variations = FALSE; } +#ifdef FONT_FEATURES_USE_PANGOFT2 static gboolean should_show_axis (FT_Var_Axis *ax) { @@ -1549,22 +1564,149 @@ is_named_instance (FT_Face face) return (face->face_index >> 16) > 0; } +#define TAG_WIDTH FT_MAKE_TAG ('w', 'd', 't', 'h') +#define TAG_WEIGHT FT_MAKE_TAG ('w', 'g', 'h', 't') +#define TAG_ITALIC FT_MAKE_TAG ('i', 't', 'a', 'l') +#define TAG_SLANT FT_MAKE_TAG ('s', 'l', 'n', 't') +#define TAG_OPTICAL_SIZE FT_MAKE_TAG ('o', 'p', 's', 'z') +#else +static gboolean +should_show_axis (hb_ot_var_axis_info_t *ax) +{ + if (ax->flags & HB_OT_VAR_AXIS_FLAG_HIDDEN) + return FALSE; + + return TRUE; +} + +static gboolean +is_named_instance (hb_face_t *face) +{ + /* FIXME */ + return FALSE; +} + +#define TAG_WIDTH HB_OT_TAG_VAR_AXIS_WIDTH +#define TAG_WEIGHT HB_OT_TAG_VAR_AXIS_WEIGHT +#define TAG_ITALIC HB_OT_TAG_VAR_AXIS_ITALIC +#define TAG_SLANT HB_OT_TAG_VAR_AXIS_SLANT +#define TAG_OPTICAL_SIZE HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE +#endif + static struct { guint32 tag; const char *name; } axis_names[] = { - { FT_MAKE_TAG ('w', 'd', 't', 'h'), N_("Width") }, - { FT_MAKE_TAG ('w', 'g', 'h', 't'), N_("Weight") }, - { FT_MAKE_TAG ('i', 't', 'a', 'l'), N_("Italic") }, - { FT_MAKE_TAG ('s', 'l', 'n', 't'), N_("Slant") }, - { FT_MAKE_TAG ('o', 'p', 's', 'z'), N_("Optical Size") }, + { TAG_WIDTH, N_("Width") }, + { TAG_WEIGHT, N_("Weight") }, + { TAG_ITALIC, N_("Italic") }, + { TAG_SLANT, N_("Slant") }, + { TAG_OPTICAL_SIZE, N_("Optical Size") }, }; +#undef TAG_WIDTH +#undef TAG_WEIGHT +#undef TAG_ITALIC +#undef TAG_SLANT +#undef TAG_OPTICAL_SIZE + +#ifdef FONT_FEATURES_USE_PANGOFT2 + +#define FONT_FACE_TYPE FT_Face +#define FONT_VAR_AXIS_TYPE FT_Var_Axis +#define FONT_VALUE_TYPE FT_Fixed + +/* + * We actually don't bother about the FT_Face here, but we use this so that we can have a single + * version of add_axis() taylored to PangoFT2 or Pango with HarfBuzz integrated + */ +static void * +get_font_name (FT_Face face, + FT_Var_Axis *ax, + const char *result) +{ + result = ax->name; +} + +static const float +get_float_value (FT_Fixed value) +{ + return FixedToFloat (value); +} + +static const float +get_axis_float_max (FT_Var_Axis *ax) +{ + return FixedToFloat (ax->maximum); +} + +static const float +get_axis_float_min (FT_Var_Axis *ax) +{ + return FixedToFloat (ax->minimum); +} + +static const float +get_axis_float_default (FT_Var_Axis *ax) +{ + return FixedToFloat (ax->def); +} + +#else +#define FONT_FACE_TYPE hb_face_t * +#define FONT_VAR_AXIS_TYPE hb_ot_var_axis_info_t +#define FONT_VALUE_TYPE int + +static void +get_font_name (hb_face_t *face, + hb_ot_var_axis_info_t *ax, + const char *name) +{ + char buffer[20]; + unsigned int buffer_len = 20; + + hb_ot_name_get_utf8 (face, ax->name_id, HB_LANGUAGE_INVALID, &buffer_len, buffer); + name = buffer; +} + +#define get_float_value(x) x + +static const float +get_axis_float_max (hb_ot_var_axis_info_t *ax) +{ + return ax->max_value; +} + +static const float +get_axis_float_min (hb_ot_var_axis_info_t *ax) +{ + return ax->min_value; +} + +static const float +get_axis_float_default (hb_ot_var_axis_info_t *ax) +{ + return ax->default_value; +} + +/* FIXME: This doesn't work if the font has an avar table */ +static float +denorm_coord (hb_ot_var_axis_info_t *axis, int coord) +{ + float r = coord / 16384.0; + + if (coord < 0) + return axis->default_value + r * (axis->default_value - axis->min_value); + else + return axis->default_value + r * (axis->max_value - axis->default_value); +} +#endif + static gboolean add_axis (GtkFontChooserWidget *fontchooser, - FT_Face face, - FT_Var_Axis *ax, - FT_Fixed value, + FONT_FACE_TYPE face, + FONT_VAR_AXIS_TYPE *ax, + FONT_VALUE_TYPE value, int row) { GtkFontChooserWidgetPrivate *priv = fontchooser->priv; @@ -1576,7 +1718,8 @@ add_axis (GtkFontChooserWidget *fontchooser, axis->tag = ax->tag; axis->fontchooser = GTK_WIDGET (fontchooser); - name = ax->name; + get_font_name (face, ax, name); + for (i = 0; i < G_N_ELEMENTS (axis_names); i++) { if (axis_names[i].tag == ax->tag) @@ -1585,18 +1728,19 @@ add_axis (GtkFontChooserWidget *fontchooser, break; } } + axis->label = gtk_label_new (name); gtk_widget_show (axis->label); gtk_widget_set_halign (axis->label, GTK_ALIGN_START); gtk_widget_set_valign (axis->label, GTK_ALIGN_BASELINE); gtk_grid_attach (GTK_GRID (priv->axis_grid), axis->label, 0, row, 1, 1); - axis->adjustment = gtk_adjustment_new ((double)FixedToFloat(value), - (double)FixedToFloat(ax->minimum), - (double)FixedToFloat(ax->maximum), + axis->adjustment = gtk_adjustment_new ((double)get_float_value (value), + (double)get_axis_float_min (ax), + (double)get_axis_float_max (ax), 1.0, 10.0, 0.0); axis->scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, axis->adjustment); gtk_widget_show (axis->scale); - gtk_scale_add_mark (GTK_SCALE (axis->scale), (double)FixedToFloat(ax->def), GTK_POS_TOP, NULL); + gtk_scale_add_mark (GTK_SCALE (axis->scale), (double)get_axis_float_default (ax), GTK_POS_TOP, NULL); gtk_widget_set_valign (axis->scale, GTK_ALIGN_BASELINE); gtk_widget_set_hexpand (axis->scale, TRUE); gtk_widget_set_size_request (axis->scale, 100, -1); @@ -1612,6 +1756,7 @@ add_axis (GtkFontChooserWidget *fontchooser, adjustment_changed (axis->adjustment, axis); g_signal_connect (axis->adjustment, "value-changed", G_CALLBACK (adjustment_changed), axis); + if (is_named_instance (face) || !should_show_axis (ax)) { gtk_widget_hide (axis->label); @@ -1629,9 +1774,21 @@ gtk_font_chooser_widget_update_font_variations (GtkFontChooserWidget *fontchoose { GtkFontChooserWidgetPrivate *priv = fontchooser->priv; PangoFont *pango_font; + +#ifdef FONT_FEATURES_USE_PANGOFT2 FT_Face ft_face; FT_MM_Var *ft_mm_var; FT_Error ret; +#else + hb_font_t *hb_font; + hb_face_t *hb_face; + const int *coords; + unsigned int n_coords; + hb_ot_var_axis_info_t *axes; + + int num_axes, i; +#endif + gboolean has_axis = FALSE; if (priv->updating_variations) @@ -1645,39 +1802,72 @@ 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)); - ret = FT_Get_MM_Var (ft_face, &ft_mm_var); - if (ret == 0) +#ifdef FONT_FEATURES_USE_PANGOFT2 + if (PANGO_IS_FC_FONT (pango_font)) { - int i; - FT_Fixed *coords; + ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)); - coords = g_new (FT_Fixed, ft_mm_var->num_axis); - for (i = 0; i < ft_mm_var->num_axis; i++) - coords[i] = ft_mm_var->axis[i].def; - - if (ft_face->face_index > 0) + ret = FT_Get_MM_Var (ft_face, &ft_mm_var); + if (ret == 0) { - int instance_id = ft_face->face_index >> 16; - if (instance_id && instance_id <= ft_mm_var->num_namedstyles) + int i; + FT_Fixed *coords; + + coords = g_new (FT_Fixed, ft_mm_var->num_axis); + for (i = 0; i < ft_mm_var->num_axis; i++) + coords[i] = ft_mm_var->axis[i].def; + + if (ft_face->face_index > 0) { - FT_Var_Named_Style *instance = &ft_mm_var->namedstyle[instance_id - 1]; - memcpy (coords, instance->coords, ft_mm_var->num_axis * sizeof (*coords)); + int instance_id = ft_face->face_index >> 16; + if (instance_id && instance_id <= ft_mm_var->num_namedstyles) + { + FT_Var_Named_Style *instance = &ft_mm_var->namedstyle[instance_id - 1]; + memcpy (coords, instance->coords, ft_mm_var->num_axis * sizeof (*coords)); + } } + + for (i = 0; i < ft_mm_var->num_axis; i++) + { + if (add_axis (fontchooser, ft_face, &ft_mm_var->axis[i], coords[i], i + 4)) + has_axis = TRUE; + } + + g_free (coords); + free (ft_mm_var); } - for (i = 0; i < ft_mm_var->num_axis; i++) - { - if (add_axis (fontchooser, ft_face, &ft_mm_var->axis[i], coords[i], i + 4)) - has_axis = TRUE; - } + pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font)); + } +#else + hb_font = pango_font_get_hb_font (pango_font); + hb_face = hb_font_get_face (hb_font); - g_free (coords); - free (ft_mm_var); + if (!hb_ot_var_has_data (hb_face)) + return FALSE; + + coords = hb_font_get_var_coords_normalized (hb_font, &n_coords); + + num_axes = hb_ot_var_get_axis_count (hb_face); + axes = g_new0 (hb_ot_var_axis_info_t, num_axes); + hb_ot_var_get_axis_infos (hb_face, 0, &num_axes, axes); + + for (i = 0; i < num_axes; i ++) + { + float value; + + if (coords && i < n_coords) + value = denorm_coord (&axes[i], coords[i]); + else + value = axes[i].default_value; + if (add_axis (fontchooser, hb_font_get_face (hb_font), &axes[i], value, i + 4)) + has_axis = TRUE; } - pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font)); + g_free (axes); +#endif + g_object_unref (pango_font); return has_axis; @@ -1807,6 +1997,7 @@ feat_pressed (GtkGesture *gesture, static char * find_affected_text (hb_tag_t feature_tag, + hb_font_t *hb_font, hb_face_t *hb_face, hb_tag_t script_tag, hb_tag_t lang_tag, @@ -1820,7 +2011,11 @@ find_affected_text (hb_tag_t feature_tag, chars = g_string_new (""); hb_ot_layout_table_find_script (hb_face, HB_OT_TAG_GSUB, script_tag, &script_index); + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS hb_ot_layout_script_find_language (hb_face, HB_OT_TAG_GSUB, script_index, lang_tag, &lang_index); + G_GNUC_END_IGNORE_DEPRECATIONS + if (hb_ot_layout_language_find_feature (hb_face, HB_OT_TAG_GSUB, script_index, lang_index, feature_tag, &feature_index)) { unsigned int lookup_indexes[32]; @@ -1840,8 +2035,8 @@ find_affected_text (hb_tag_t feature_tag, hb_set_t* glyphs_input = NULL; hb_set_t* glyphs_after = NULL; hb_set_t* glyphs_output = NULL; - hb_font_t *hb_font = NULL; hb_codepoint_t gid; + gboolean destroy_font = FALSE; glyphs_input = hb_set_create (); @@ -1854,8 +2049,16 @@ find_affected_text (hb_tag_t feature_tag, glyphs_after, glyphs_output); - hb_font = hb_font_create (hb_face); - hb_ft_font_set_funcs (hb_font); + +#ifdef FONT_FEATURES_USE_PANGOFT + if (hb_font == NULL) + { + /* only applicable if we are doing this via PangoFT2, where we need to create the hb_font_t */ + hb_font = hb_font_create (hb_face); + hb_ft_font_set_funcs (hb_font); + destroy_font = TRUE; + } +#endif gid = -1; while (hb_set_next (glyphs_input, &gid)) { @@ -1876,7 +2079,9 @@ find_affected_text (hb_tag_t feature_tag, } } hb_set_destroy (glyphs_input); - hb_font_destroy (hb_font); + + if (destroy_font) + hb_font_destroy (hb_font); } } @@ -1885,6 +2090,7 @@ find_affected_text (hb_tag_t feature_tag, static void update_feature_example (FeatureItem *item, + hb_font_t *hb_font, hb_face_t *hb_face, hb_tag_t script_tag, hb_tag_t lang_tag, @@ -1937,9 +2143,9 @@ update_feature_example (FeatureItem *item, else if (strcmp (item->name, "zero") == 0) input = g_strdup ("0"); else if (strcmp (item->name, "nalt") == 0) - input = find_affected_text (item->tag, hb_face, script_tag, lang_tag, 3); + input = find_affected_text (item->tag, hb_font, hb_face, script_tag, lang_tag, 3); else - input = find_affected_text (item->tag, hb_face, script_tag, lang_tag, 10); + input = find_affected_text (item->tag, hb_font, hb_face, script_tag, lang_tag, 10); if (input[0] != '\0') { @@ -2156,8 +2362,12 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser) { GtkFontChooserWidgetPrivate *priv = fontchooser->priv; PangoFont *pango_font; + +#ifdef FONT_FEATURES_USE_PANGOFT2 FT_Face ft_face; - hb_font_t *hb_font; +#endif + + hb_font_t *hb_font = NULL; hb_tag_t script_tag; hb_tag_t lang_tag; guint script_index = 0; @@ -2165,6 +2375,7 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser) int i, j; GList *l; gboolean has_feature = FALSE; + gboolean cleanup_hb_face = FALSE; for (l = priv->feature_items; l; l = l->next) { @@ -2178,8 +2389,17 @@ 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)), - hb_font = hb_ft_font_create (ft_face, NULL); + +#ifdef FONT_FEATURE_USE_PANGOFT2 + if (PANGO_IS_FC_FONT (pango_font)) + { + ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)), + hb_font = hb_ft_font_create (ft_face, NULL); + cleanup_hb_face = TRUE; + } +#else + hb_font = pango_font_get_hb_font (pango_font); +#endif if (hb_font) { @@ -2197,7 +2417,11 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser) for (i = 0; i < 2; i++) { hb_ot_layout_table_find_script (hb_face, table[i], script_tag, &script_index); + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS hb_ot_layout_script_find_language (hb_face, table[i], script_index, lang_tag, &lang_index); + G_GNUC_END_IGNORE_DEPRECATIONS + count = G_N_ELEMENTS (features); hb_ot_layout_language_get_feature_tags (hb_face, table[i], @@ -2214,6 +2438,8 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser) for (l = priv->feature_items; l; l = l->next) { FeatureItem *item = l->data; + hb_font_t *hb_font2 = NULL; + if (item->tag != features[j]) continue; @@ -2221,7 +2447,10 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser) gtk_widget_show (item->top); gtk_widget_show (gtk_widget_get_parent (item->top)); - update_feature_example (item, hb_face, script_tag, lang_tag, priv->font_desc); + if (!cleanup_hb_face) + hb_font2 = hb_font; + + update_feature_example (item, hb_font2, hb_face, script_tag, lang_tag, priv->font_desc); if (GTK_IS_RADIO_BUTTON (item->feat)) { @@ -2235,10 +2464,14 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser) } } - hb_face_destroy (hb_face); + if (cleanup_hb_face) + hb_face_destroy (hb_face); } - pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font)); +#if FONT_FEATURE_USE_PANGOFT2 + if (PANGO_IS_FC_FONT (pango_font)) + pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font)); +#endif g_object_unref (pango_font); return has_feature; @@ -2338,7 +2571,7 @@ gtk_font_chooser_widget_merge_font_desc (GtkFontChooserWidget *fontchooser gtk_font_chooser_widget_update_marks (fontchooser); -#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT) +#ifdef HAVE_FONT_FEATURES if (gtk_font_chooser_widget_update_font_features (fontchooser)) has_tweak = TRUE; if (gtk_font_chooser_widget_update_font_variations (fontchooser)) From c3c759cbddfe48a4253b5e9c6cb7817b862caeef Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Thu, 25 Nov 2021 12:39:39 +0800 Subject: [PATCH 2/9] Visual Studio projects: Define __MSVC_PROJECTS__ ...in the libgtk3 project, so that we can automatically link to harfbuzz.lib if we have a sufficiently-new version of Pango and HarfBuzz installed, so that the code to enable font features can be linked properly, even if we don't explicitly put harfbuzz.lib in the list of libraries that we feed into the linker in the project files. If one is using pre-Pango-1.44.x and/or pre-HarfBuzz-2.2.0 and intends to enable font features support, one still must update config.h.win32 to make sure HAVE_PANGOFT2 and HAVE_HARFBUZZ is defined, and put pangoft2-1.0.lib, harfbuzz.lib and freetype.lib (or so) in the "Additional Libraries" under the linker settings in the projects manually, as required before. --- win32/vs10/gtk3-build-defines.props | 2 +- win32/vs9/gtk3-build-defines.vsprops | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/win32/vs10/gtk3-build-defines.props b/win32/vs10/gtk3-build-defines.props index 50c8cf6fbe..4fddda3189 100644 --- a/win32/vs10/gtk3-build-defines.props +++ b/win32/vs10/gtk3-build-defines.props @@ -12,7 +12,7 @@ i686 x86_64 aarch64 - GTK_COMPILATION;G_LOG_DOMAIN="Gtk";GTK_HOST="$(GtkHostMachine)-pc-vs$(VSVer)";GTK_PRINT_BACKENDS="file";GTK_PRINT_BACKEND_ENABLE_UNSUPPORTED;$(GtkIncludedImmodulesDefines);GTK_LIBDIR="$(GtkDummyPrefix)/lib";GTK_DATADIR="$(GtkDummyPrefix)/share";GTK_DATA_PREFIX="$(GtkDummyPrefix)";GTK_SYSCONFDIR="$(GtkDummyPrefix)/etc";MULTIPRESS_CONFDIR="$(GtkDummyPrefix)/etc/gtk-$(ApiVersion)";MULTIPRESS_LOCALEDIR="$(GtkDummyPrefix)/share/locale";GTK_VERSION="$(GtkVersion)/etc";GTK_BINARY_VERSION="$(GtkBinaryVersion)/etc";GDK_DISABLE_DEPRECATED;ISOLATION_AWARE_ENABLED + GTK_COMPILATION;G_LOG_DOMAIN="Gtk";GTK_HOST="$(GtkHostMachine)-pc-vs$(VSVer)";GTK_PRINT_BACKENDS="file";GTK_PRINT_BACKEND_ENABLE_UNSUPPORTED;$(GtkIncludedImmodulesDefines);GTK_LIBDIR="$(GtkDummyPrefix)/lib";GTK_DATADIR="$(GtkDummyPrefix)/share";GTK_DATA_PREFIX="$(GtkDummyPrefix)";GTK_SYSCONFDIR="$(GtkDummyPrefix)/etc";MULTIPRESS_CONFDIR="$(GtkDummyPrefix)/etc/gtk-$(ApiVersion)";MULTIPRESS_LOCALEDIR="$(GtkDummyPrefix)/share/locale";GTK_VERSION="$(GtkVersion)/etc";GTK_BINARY_VERSION="$(GtkBinaryVersion)/etc";GDK_DISABLE_DEPRECATED;ISOLATION_AWARE_ENABLED;__MSVC_PROJECTS__ ole32.lib;advapi32.lib;shell32.lib;gdi32.lib pangowin32-1.0.lib;fribidi.lib;imm32.lib;$(CommonARM64SystemLibs) winmm.lib;dwmapi.lib;setupapi.lib;hid.lib;$(GtkGdkCommonLibs) diff --git a/win32/vs9/gtk3-build-defines.vsprops b/win32/vs9/gtk3-build-defines.vsprops index e47c348063..876e2406cc 100644 --- a/win32/vs9/gtk3-build-defines.vsprops +++ b/win32/vs9/gtk3-build-defines.vsprops @@ -41,11 +41,11 @@ /> Date: Thu, 25 Nov 2021 17:21:32 +0800 Subject: [PATCH 3/9] gtk-demo: Split out demo sources from Makefile.am This way, we can share the demo listing to be used in other build Makefile-based build systems, such as the auxiliary NMake Makefiles used to generate the various sources. --- demos/gtk-demo/Makefile.am | 78 ++------------------------------ demos/gtk-demo/demos-sources.mak | 75 ++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 75 deletions(-) create mode 100644 demos/gtk-demo/demos-sources.mak diff --git a/demos/gtk-demo/Makefile.am b/demos/gtk-demo/Makefile.am index 4a2f827469..9aa106257a 100644 --- a/demos/gtk-demo/Makefile.am +++ b/demos/gtk-demo/Makefile.am @@ -1,87 +1,15 @@ ## Makefile.am for gtk+/demos include $(top_srcdir)/Makefile.decl - -## These should be in the order you want them to appear in the -## demo app, which means alphabetized by demo title, not filename -demos_base = \ - application_demo.c \ - assistant.c \ - builder.c \ - button_box.c \ - changedisplay.c \ - clipboard.c \ - colorsel.c \ - combobox.c \ - css_accordion.c \ - css_basics.c \ - css_blendmodes.c \ - css_multiplebgs.c \ - css_pixbufs.c \ - css_shadows.c \ - cursors.c \ - dialog.c \ - drawingarea.c \ - editable_cells.c \ - entry_buffer.c \ - entry_completion.c \ - event_axes.c \ - expander.c \ - filtermodel.c \ - fishbowl.c \ - foreigndrawing.c \ - gestures.c \ - glarea.c \ - headerbar.c \ - hypertext.c \ - iconview.c \ - iconview_edit.c \ - images.c \ - infobar.c \ - links.c \ - listbox.c \ - flowbox.c \ - list_store.c \ - markup.c \ - menus.c \ - modelbutton.c \ - offscreen_window.c \ - offscreen_window2.c \ - overlay.c \ - overlay2.c \ - paint.c \ - panes.c \ - pickers.c \ - pixbufs.c \ - popover.c \ - printing.c \ - revealer.c \ - rotated_text.c \ - scale.c \ - search_entry.c \ - search_entry2.c \ - shortcuts.c \ - sidebar.c \ - sizegroup.c \ - spinbutton.c \ - spinner.c \ - stack.c \ - tabs.c \ - textmask.c \ - textview.c \ - textscroll.c \ - theming_style_classes.c \ - toolpalette.c \ - transparent.c \ - tree_store.c +include $(srcdir)/demos-sources.mak demos_opt = if BUILD_FONT_DEMO -demos_opt += font_features.c +demos_opt += $(font_features_demo) endif if OS_UNIX -demos_opt += pagesetup.c +demos_opt += $(page_setup_demo) endif demos = $(demos_base) $(demos_opt) diff --git a/demos/gtk-demo/demos-sources.mak b/demos/gtk-demo/demos-sources.mak new file mode 100644 index 0000000000..e6b1940330 --- /dev/null +++ b/demos/gtk-demo/demos-sources.mak @@ -0,0 +1,75 @@ +## These should be in the order you want them to appear in the +## demo app, which means alphabetized by demo title, not filename +demos_base = \ + application_demo.c \ + assistant.c \ + builder.c \ + button_box.c \ + changedisplay.c \ + clipboard.c \ + colorsel.c \ + combobox.c \ + css_accordion.c \ + css_basics.c \ + css_blendmodes.c \ + css_multiplebgs.c \ + css_pixbufs.c \ + css_shadows.c \ + cursors.c \ + dialog.c \ + drawingarea.c \ + editable_cells.c \ + entry_buffer.c \ + entry_completion.c \ + event_axes.c \ + expander.c \ + filtermodel.c \ + fishbowl.c \ + foreigndrawing.c \ + gestures.c \ + glarea.c \ + headerbar.c \ + hypertext.c \ + iconview.c \ + iconview_edit.c \ + images.c \ + infobar.c \ + links.c \ + listbox.c \ + flowbox.c \ + list_store.c \ + markup.c \ + menus.c \ + modelbutton.c \ + offscreen_window.c \ + offscreen_window2.c \ + overlay.c \ + overlay2.c \ + paint.c \ + panes.c \ + pickers.c \ + pixbufs.c \ + popover.c \ + printing.c \ + revealer.c \ + rotated_text.c \ + scale.c \ + search_entry.c \ + search_entry2.c \ + shortcuts.c \ + sidebar.c \ + sizegroup.c \ + spinbutton.c \ + spinner.c \ + stack.c \ + tabs.c \ + textmask.c \ + textview.c \ + textscroll.c \ + theming_style_classes.c \ + toolpalette.c \ + transparent.c \ + tree_store.c + +font_features_demo = font_features.c +page_setup_demo = pagesetup.c From 079ee4e31e055801a87a467ea9b267ca91786d2b Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Thu, 25 Nov 2021 17:46:16 +0800 Subject: [PATCH 4/9] win32/generate-msvc.mak: Add rule to regenerate demos.h.win32 We can regenerate demos.h.win32 with or without the font features demo by using the regenerate-demos-h-win32 target with or without secifying the FONT_FEATURES_DEMO=1 flag on the NMake command line. --- win32/config-msvc.mak.in | 5 +++++ win32/create-lists-msvc.mak | 14 ++++++++++++++ win32/generate-msvc.mak | 7 +++++++ 3 files changed, 26 insertions(+) diff --git a/win32/config-msvc.mak.in b/win32/config-msvc.mak.in index 3862f45323..b623a99491 100644 --- a/win32/config-msvc.mak.in +++ b/win32/config-msvc.mak.in @@ -46,6 +46,11 @@ AT_PLAT=aarch64 AT_PLAT=i686 !endif +demo_sources = $(demos_base) +!ifdef FONT_FEATURES_DEMO +demo_sources = $(demo_sources) $(font_features_demo) +!endif + # Please do not change anything beneath this line unless maintaining the NMake Makefiles GTK_VERSION = @GTK_VERSION@ diff --git a/win32/create-lists-msvc.mak b/win32/create-lists-msvc.mak index c53c29f10e..b1bf65d2c4 100644 --- a/win32/create-lists-msvc.mak +++ b/win32/create-lists-msvc.mak @@ -99,3 +99,17 @@ NULL= !if [del /f /q resources_sources.mak] !endif + +!if [call create-lists.bat header demo_sources.mak demo_actual_sources] +!endif + +!if [for %f in ($(demo_sources)) do @call create-lists.bat file demo_sources.mak ..\demos\gtk-demo\%f] +!endif + +!if [call create-lists.bat footer demo_sources.mak] +!endif + +!include demo_sources.mak + +!if [del /f /q demo_sources.mak] +!endif \ No newline at end of file diff --git a/win32/generate-msvc.mak b/win32/generate-msvc.mak index 4fb0c563e6..dd8691d127 100644 --- a/win32/generate-msvc.mak +++ b/win32/generate-msvc.mak @@ -3,6 +3,7 @@ # Items in here should not need to be edited unless # one is maintaining the NMake build files. +!include ../demos/gtk-demo/demos-sources.mak !include config-msvc.mak !include create-lists-msvc.mak @@ -193,6 +194,12 @@ all: \ @echo Generating $@... @$(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(@D) --generate-source $(@D)\iconbrowser.gresource.xml +regenerate-demos-h-win32: ..\demos\gtk-demo\geninclude.py $(demo_actual_sources) + @echo Regenerating demos.h.win32... + @-del ..\demos\gtk-demo\demos.h.win32 + @cd ..\demos\gtk-demo + @$(PYTHON) geninclude.py demos.h.win32 $(demo_sources) + # Remove the generated files clean: @-del /f /q ..\demos\icon-browser\resources.c From b8e78f83ce3482b2be3eb69ecc481b810cf42d05 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Thu, 25 Nov 2021 18:08:22 +0800 Subject: [PATCH 5/9] Font features demo: Port to newer Pango ...if Pango 1.44.0+ and HarfBuzz 2.2.0+ are available, otherwise we stick on to the current code path. This way, we can have people build and run the demo even without PangoFT2 if Pango 1.44.0 or later and HarfBuzz 2.2.0 or later is installed. --- demos/gtk-demo/font_features.c | 67 ++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/demos/gtk-demo/font_features.c b/demos/gtk-demo/font_features.c index 761bf8f38f..ab9ae0d66c 100644 --- a/demos/gtk-demo/font_features.c +++ b/demos/gtk-demo/font_features.c @@ -9,10 +9,19 @@ */ #include + +#if !(PANGO_VERSION_CHECK(1,44,0) && HB_VERSION_ATLEAST(2,2,0)) +#define FONT_FEATURES_USE_PANGOFT2 1 +#endif + +#ifdef FONT_FEATURES_USE_PANGOFT2 #include #include #include #include +#else +#include +#endif static GtkWidget *label; static GtkWidget *settings; @@ -205,19 +214,32 @@ static void update_script_combo (void) { GtkListStore *store; - hb_font_t *hb_font; + hb_font_t *hb_font = NULL; gint i, j, k, l; - FT_Face ft_face; PangoFont *pango_font; GHashTable *tags; GHashTableIter iter; TagPair *pair; + gboolean cleanup_hb_face = FALSE; + +#ifdef FONT_FEATURES_USE_PANGOFT2 + FT_Face ft_face; +#endif store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); pango_font = get_pango_font (); - ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)), - hb_font = hb_ft_font_create (ft_face, NULL); + +#ifdef FONT_FEATURES_USE_PANGOFT2 + if (PANGO_IS_FC_FONT (pango_font) + { + ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)), + hb_font = hb_ft_font_create (ft_face, NULL); + cleanup_hb_face = TRUE; + } +#else + hb_font = pango_font_get_hb_font (pango_font); +#endif tags = g_hash_table_new_full (tag_pair_hash, tag_pair_equal, g_free, NULL); @@ -264,10 +286,15 @@ update_script_combo (void) } } - hb_face_destroy (hb_face); + if (cleanup_hb_face) + hb_face_destroy (hb_face); } - pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font)); +#ifdef FONT_FEATURES_USE_PANGOFT2 + if (PANGO_IS_FC_FONT (pango_font) + pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font)); +#endif + g_object_unref (pango_font); g_hash_table_iter_init (&iter, tags); @@ -346,8 +373,12 @@ update_features (void) GtkTreeIter iter; guint script_index, lang_index; PangoFont *pango_font; + hb_font_t *hb_font = NULL; + gboolean cleanup_hb_face = FALSE; + +#ifdef FONT_FEATURES_USE_PANGOFT2 FT_Face ft_face; - hb_font_t *hb_font; +#endif for (i = 0; i < num_features; i++) gtk_widget_set_opacity (icon[i], 0); @@ -364,8 +395,17 @@ update_features (void) -1); pango_font = get_pango_font (); - ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)), - hb_font = hb_ft_font_create (ft_face, NULL); + +#ifdef FONT_FEATURES_USE_PANGOFT2 + if (PANGO_IS_FC_FONT (pango_font) + { + ft_face = pango_fc_font_lock_face (PANGO_FC_FONT (pango_font)), + hb_font = hb_ft_font_create (ft_face, NULL); + cleanup_hb_face = TRUE; + } +#else + hb_font = pango_font_get_hb_font (pango_font); +#endif if (hb_font) { @@ -397,10 +437,15 @@ update_features (void) } } - hb_face_destroy (hb_face); + if (cleanup_hb_face) + hb_face_destroy (hb_face); } - pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font)); +#ifdef FONT_FEATURES_USE_PANGOFT2 + if (PANGO_IS_FC_FONT (pango_font) + pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font)); +#endif + g_object_unref (pango_font); } From 720e335246531bf1a9e59745d9721638ac92ba64 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Thu, 25 Nov 2021 18:30:02 +0800 Subject: [PATCH 6/9] configure.ac: Check for Pango 1.44.0 or later ...and HarfBuzz 2.2.0 or later so that we can enable the font feature demo even if we do not have PangoFT2. --- configure.ac | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 5830d962fd..412ddbf6d7 100644 --- a/configure.ac +++ b/configure.ac @@ -1395,17 +1395,35 @@ fi ################################################## # Check for harfbuzz and pangoft2 ################################################## - PKG_CHECK_MODULES(GTK_FONT_CHOOSER_WIDGET, - harfbuzz >= 0.9 pangoft2, + harfbuzz >= 2.2.0 pango >= 1.44.0, build_font_demo=yes, build_font_demo=no) + +PKG_CHECK_MODULES(GTK_FONT_CHOOSER_WIDGET_FT, + harfbuzz >= 0.9 pangoft2, + build_font_demo_ft=yes, + build_font_demo_ft=no) + +if test "x$build_font_demo" = xno; then + if test "x$build_font_demo_ft" = xyes; then + build_font_demo=yes + else + build_font_demo=no + fi +fi + AM_CONDITIONAL(BUILD_FONT_DEMO, [ test "x$build_font_demo" = xyes ]) if test "x$build_font_demo" = xyes; then AC_DEFINE([HAVE_HARFBUZZ], 1, [defines whether we have HarfBuzz]) - AC_DEFINE([HAVE_PANGOFT], 1, [defines whether we have pangoft2]) - GTK_DEP_CFLAGS="$GTK_DEP_CFLAGS $GTK_FONT_CHOOSER_WIDGET_CFLAGS" - GTK_DEP_LIBS="$GTK_DEP_LIBS $GTK_FONT_CHOOSER_WIDGET_LIBS" + if test "x$build_font_demo_ft" = xyes; then + AC_DEFINE([HAVE_PANGOFT], 1, [defines whether we have pangoft2]) + GTK_DEP_CFLAGS="$GTK_DEP_CFLAGS $GTK_FONT_CHOOSER_WIDGET_FT_CFLAGS" + GTK_DEP_LIBS="$GTK_DEP_LIBS $GTK_FONT_CHOOSER_WIDGET_FT_LIBS" + else + GTK_DEP_CFLAGS="$GTK_DEP_CFLAGS $GTK_FONT_CHOOSER_WIDGET_CFLAGS" + GTK_DEP_LIBS="$GTK_DEP_LIBS $GTK_FONT_CHOOSER_WIDGET_LIBS" + fi fi if $PKG_CONFIG --exists x11; then From f82eb198f255c404c64641211e281ddb9f090ef3 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Thu, 25 Nov 2021 18:56:24 +0800 Subject: [PATCH 7/9] Meson: Enable font features demo on later Pango versions ...even if PangoFT2 is not present, provided that Pango 1.44.0+ and HarfBuzz 2.2.0+ are installed. The demo now has added support for later Pango versions that use HarfBuzz for shaping on all supported platforms. --- demos/gtk-demo/meson.build | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build index 82e08973a5..252da16d05 100644 --- a/demos/gtk-demo/meson.build +++ b/demos/gtk-demo/meson.build @@ -76,7 +76,13 @@ demos = files([ gtkdemo_deps = [libgtk_dep] -if harfbuzz_dep.found() and pangoft_dep.found() +if pango_dep.version().version_compare('>=1.44.0') and harfbuzz_dep.found() and cc.has_header_symbol( + 'hb-ot.h', + 'hb_ot_var_get_axis_count', + dependencies: harfbuzz_dep +) + demos += files('font_features.c') +elif harfbuzz_dep.found() and pangoft_dep.found() demos += files('font_features.c') gtkdemo_deps += [harfbuzz_dep, pangoft_dep] endif From 28337d68a310486978822824dc9c033dbe43538b Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Fri, 26 Nov 2021 16:04:32 +0800 Subject: [PATCH 8/9] Visual Studio projects: Update README for additional features Rename README_EGL_MSVC.txt to README_FEATURES_MSVC.txt, as we now have more features that can be included in the builds using the Visual Studio projects, which require additional depedencies and manual enabling. Specifically, this outlines how the font tweaking feature in libgtk can be enabled and for people who wish to do so, how to enable the Font Features demo in gtk3-demo.exe. --- win32/Makefile.am | 2 +- win32/README_EGL_MSVC.txt | 29 -------------- win32/README_FEATURES_MSVC.txt | 72 ++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 30 deletions(-) delete mode 100644 win32/README_EGL_MSVC.txt create mode 100644 win32/README_FEATURES_MSVC.txt diff --git a/win32/Makefile.am b/win32/Makefile.am index 31c8715269..e5f9a3ff73 100644 --- a/win32/Makefile.am +++ b/win32/Makefile.am @@ -49,7 +49,7 @@ EXTRA_DIST += \ replace.py \ pc_base.py \ gtkpc.py \ - README_EGL_MSVC.txt \ + README_FEATURES_MSVC.txt \ $(GENERATED_ITEMS) -include $(top_srcdir)/git.mk diff --git a/win32/README_EGL_MSVC.txt b/win32/README_EGL_MSVC.txt deleted file mode 100644 index f32b9a62fd..0000000000 --- a/win32/README_EGL_MSVC.txt +++ /dev/null @@ -1,29 +0,0 @@ -Notes on enabling EGL (ANGLE/D3D support) for Windows/Visual Studio builds -========================================================================== -There is now support in the GL context creation code for Windows in GDK for -creating and using EGL (OpenGL ES 3) contexts, which can be used instead of -the existing OpenGL (Desktop) support, especially when the graphics drivers -do not support OpenGL adequately. - -This support is not enabled by default in the project files. In order to do -so, please do the following: - --Obtain or compile a build of recent version of ANGLE. The one that comes - with QT 5.10.x is sufficiently recent, but not the one that comes with QT- - 5.6.x. Note that Visual Studio 2013 or later is required for building - ANGLE from QT-5.10.x, but the Visual Studio 2013-built ANGLE DLLs does work - without problems with GTK+ built with Visual Studio 2008~2013. You may - need to obtain D3Dcompiler_[47|43|42].dll if it does not come with the - system (which is part of the DirectX runtimes). Its headers and .lib - needs to be set to be found by the compiler and linker respectively before - building libepoxy. --Build libepoxy with EGL support, which has to be enabled explicitly on - Windows builds. Pass in -Degl=yes when building libepoxy using Meson. - Build and install, making sure the headers and .lib can be located by the - compiler and linker respectively. --Open the vsX/gtk+.sln, and open the project properties in the "gdk3-win32" - project. Under "C/C++", add GDK_WIN32_ENABLE_EGL in the "Preprocessor - Definitions" to the existing definitions in there for the configuration - that is being built. Then build the solution. --To force the use of the EGL code, set the envvar GDK_GL=(...,)gles , where (...,) - are the other GDK_GL options desired. diff --git a/win32/README_FEATURES_MSVC.txt b/win32/README_FEATURES_MSVC.txt new file mode 100644 index 0000000000..47f80c29cd --- /dev/null +++ b/win32/README_FEATURES_MSVC.txt @@ -0,0 +1,72 @@ +Preameble +========= +This file attempts to give further info about how to enable features +that are not available in the Visual Studio project files shipped +with the source release archive, i.e. beyond building GTK with the GDK +Win32 backend, with or without the Broadway GDK backend. + +The following also apply to Visual Studio builds done with Meson in terms +of getting the required dependencies for the optional features. + +========================================================================== +Notes on enabling EGL (ANGLE/D3D support) for Windows/Visual Studio builds +========================================================================== +There is now support in the GL context creation code for Windows in GDK for +creating and using EGL (OpenGL ES 3) contexts, which can be used instead of +the existing OpenGL (Desktop) support, especially when the graphics drivers +do not support OpenGL adequately. + +This support is not enabled by default in the project files. In order to do +so, please do the following: + +-Obtain or compile a build of recent version of ANGLE. The one that comes + with QT 5.10.x is sufficiently recent, but not the one that comes with QT- + 5.6.x. Note that Visual Studio 2013 or later is required for building + ANGLE from QT-5.10.x, but the Visual Studio 2013-built ANGLE DLLs does + work without problems with GTK+ built with Visual Studio 2008~2013. + You may need to obtain D3Dcompiler_[47|43|42].dll if it does not come + with the system (which is part of the DirectX runtimes). Visual Studio + 2015 or later can use ANGLE from QT 5.11.x or later, or from Google's + GIT repos, which may require later version of Visual Studio to build. + Its headers and .lib needs to be set to be found by the compiler and + linker respectively before building libepoxy. +-Build libepoxy with EGL support, which has to be enabled explicitly on + Windows builds. Pass in -Degl=yes when building libepoxy using Meson. + Build and install, making sure the headers and .lib can be located by the + compiler and linker respectively. +-Open the vsX/gtk+.sln, and open the project properties in the "gdk3-win32" + project. Under "C/C++", add GDK_WIN32_ENABLE_EGL in the "Preprocessor + Definitions" to the existing definitions in there for the configuration + that is being built. Then build the solution. +-To force the use of the EGL code, set the envvar GDK_GL=(...,)gles , + where (...,) are the other GDK_GL options desired. + +============================================================== +Enabling the font tweaking features and the font features demo +============================================================== +The font tweaking features in the GTK DLL is enabled automatically if +the Pango 1.44.0 and HarfBuzz 2.2.0 (or later) headers and libraries +(and hence DLLs) are found during compile time. Check in +gtkfontchooserwidget.c that the `#pragma comment(lib, "harfbuzz")` line +to ensure that you have your HarfBuzz .lib file named as such, which +is the default .lib name for HarfBuzz builds. + +Alternatively, they can be manually enabled by making sure that +`HAVE_HARFBUZZ` and `HAVE_PANGOFT2` are defined in config.h.win32, +meaning that PangoFT2 must be present, which depends on HarfBuzz, +FontConfig and FreeType. You will then need to add to the `gtk3` +projects the .lib's of PangoFT2, HarfBuzz and FreeType in the +"Additional Libraries" entry under the linker settings. + +Please note that the font features demo is not built into gtk3-demo +by default. To do that, run in a Visual Studio command prompt, go to +$(srcroot)\win32, and run +"nmake /f generate-msvc.mak regenerate-demos-h-win32 FONT_FEATURES_DEMO=1". +To undo that, run that command without "FONT_FEATURES_DEMO=1". Python must +be present in your PATH or passed in via PYTHON=. + +You will then need to add $(srcroot)\demos\gtk-demo\font_features.c into +the source list of the "gtk3-demo" project, and add the .lib file for +HarfBuzz, and if using pre-Pango 1.44.0 and/or pre-HarfBuzz 2.2.0, the +.lib files for PangoFT2 and FreeType into the "Additional Libraries" +entry under the linker settings. From 1b789197e54e0b9a3347640c73dddcfb6834c384 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 29 Nov 2021 12:59:28 +0800 Subject: [PATCH 9/9] fontchooser: Avoid setting variations needlessly Setting variations to their default value causes them to show up in the serialization of the font description - a font description has no idea about the default values, so can't filter them out. Avoid that. --- gtk/gtkfontchooserwidget.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/gtk/gtkfontchooserwidget.c b/gtk/gtkfontchooserwidget.c index 4347af862c..b4b8952cb1 100644 --- a/gtk/gtkfontchooserwidget.c +++ b/gtk/gtkfontchooserwidget.c @@ -781,6 +781,7 @@ change_tweak (GSimpleAction *action, typedef struct { guint32 tag; + float default_value; GtkAdjustment *adjustment; GtkWidget *label; GtkWidget *scale; @@ -1510,12 +1511,15 @@ add_font_variations (GtkFontChooserWidget *fontchooser, char tag[5]; double value; + value = gtk_adjustment_get_value (axis->adjustment); + if (value == axis->default_value) + continue; + tag[0] = (axis->tag >> 24) & 0xff; tag[1] = (axis->tag >> 16) & 0xff; tag[2] = (axis->tag >> 8) & 0xff; tag[3] = (axis->tag >> 0) & 0xff; tag[4] = '\0'; - value = gtk_adjustment_get_value (axis->adjustment); g_string_append_printf (s, "%s%s=%s", sep, tag, g_ascii_dtostr (buf, sizeof(buf), value)); sep = ","; } @@ -1535,12 +1539,9 @@ adjustment_changed (GtkAdjustment *adjustment, s = g_string_new (""); add_font_variations (fontchooser, s); - if (s->len > 0) - { - font_desc = pango_font_description_new (); - pango_font_description_set_variations (font_desc, s->str); - gtk_font_chooser_widget_take_font_desc (fontchooser, font_desc); - } + font_desc = pango_font_description_new (); + pango_font_description_set_variations (font_desc, s->str); + gtk_font_chooser_widget_take_font_desc (fontchooser, font_desc); g_string_free (s, TRUE); @@ -1717,6 +1718,7 @@ add_axis (GtkFontChooserWidget *fontchooser, axis = g_new (Axis, 1); axis->tag = ax->tag; axis->fontchooser = GTK_WIDGET (fontchooser); + axis->default_value = get_axis_float_default (ax); get_font_name (face, ax, name); @@ -2581,6 +2583,14 @@ gtk_font_chooser_widget_merge_font_desc (GtkFontChooserWidget *fontchooser g_simple_action_set_enabled (G_SIMPLE_ACTION (priv->tweak_action), has_tweak); } +#ifdef HAVE_FONT_FEATURES + if (mask & PANGO_FONT_MASK_VARIATIONS) + { + if (pango_font_description_get_variations (priv->font_desc)[0] == '\0') + pango_font_description_unset_fields (priv->font_desc, PANGO_FONT_MASK_VARIANT); + } +#endif + gtk_font_chooser_widget_update_preview_attributes (fontchooser); g_object_notify (G_OBJECT (fontchooser), "font");