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.
This commit is contained in:
@@ -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 <pango/pangofc-font.h>
|
||||
#include <hb.h>
|
||||
#include <hb-ot.h>
|
||||
@@ -62,6 +70,12 @@
|
||||
#include <freetype/ftmm.h>
|
||||
#include "language-names.h"
|
||||
#include "script-names.h"
|
||||
#elif defined (HAVE_FONT_FEATURES)
|
||||
#include <hb-ot.h>
|
||||
|
||||
#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))
|
||||
|
||||
Reference in New Issue
Block a user