forked from AuroraMiddleware/gtk
Port the font chooser to just use harfbuzz
This commit is contained in:
parent
41c52e955d
commit
eaa6301e53
@ -58,18 +58,10 @@
|
||||
#include "gtkeventcontrollerscroll.h"
|
||||
#include "gtkroot.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"
|
||||
#endif
|
||||
|
||||
#include "open-type-layout.h"
|
||||
|
||||
/**
|
||||
@ -920,10 +912,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)
|
||||
gtk_font_chooser_widget_populate_features (fontchooser);
|
||||
#endif
|
||||
|
||||
gtk_font_chooser_widget_set_cell_size (fontchooser);
|
||||
gtk_font_chooser_widget_take_font_desc (fontchooser, NULL);
|
||||
@ -1474,12 +1463,8 @@ gtk_font_chooser_widget_ensure_selection (GtkFontChooserWidget *fontchooser)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT)
|
||||
|
||||
/* OpenType variations */
|
||||
|
||||
#define FixedToFloat(f) (((float)(f))/65536.0)
|
||||
|
||||
static void
|
||||
add_font_variations (GtkFontChooserWidget *fontchooser,
|
||||
GString *s)
|
||||
@ -1534,49 +1519,56 @@ adjustment_changed (GtkAdjustment *adjustment,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_show_axis (FT_Var_Axis *ax)
|
||||
should_show_axis (hb_ot_var_axis_info_t *ax)
|
||||
{
|
||||
/* FIXME use FT_Get_Var_Axis_Flags */
|
||||
if (ax->tag == FT_MAKE_TAG ('o', 'p', 's', 'z'))
|
||||
if (ax->flags & HB_OT_VAR_AXIS_FLAG_HIDDEN)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_named_instance (FT_Face face)
|
||||
is_named_instance (hb_font_t *font)
|
||||
{
|
||||
return (face->face_index >> 16) > 0;
|
||||
/* FIXME */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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") },
|
||||
{ HB_OT_TAG_VAR_AXIS_WIDTH, N_("Width") },
|
||||
{ HB_OT_TAG_VAR_AXIS_WEIGHT, N_("Weight") },
|
||||
{ HB_OT_TAG_VAR_AXIS_ITALIC, N_("Italic") },
|
||||
{ HB_OT_TAG_VAR_AXIS_SLANT, N_("Slant") },
|
||||
{ HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE, N_("Optical Size") },
|
||||
};
|
||||
|
||||
static gboolean
|
||||
add_axis (GtkFontChooserWidget *fontchooser,
|
||||
FT_Face face,
|
||||
FT_Var_Axis *ax,
|
||||
FT_Fixed value,
|
||||
int row)
|
||||
add_axis (GtkFontChooserWidget *fontchooser,
|
||||
hb_font_t *hb_font,
|
||||
hb_ot_var_axis_info_t *ax,
|
||||
int value,
|
||||
int row)
|
||||
{
|
||||
GtkFontChooserWidgetPrivate *priv = gtk_font_chooser_widget_get_instance_private (fontchooser);
|
||||
hb_face_t *hb_face;
|
||||
Axis *axis;
|
||||
const char *name;
|
||||
char buffer[20];
|
||||
unsigned int buffer_len = 20;
|
||||
int i;
|
||||
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
axis = g_new (Axis, 1);
|
||||
axis->tag = ax->tag;
|
||||
axis->fontchooser = GTK_WIDGET (fontchooser);
|
||||
|
||||
name = ax->name;
|
||||
hb_ot_name_get_utf8 (hb_face, ax->name_id, HB_LANGUAGE_INVALID, &buffer_len, buffer);
|
||||
name = buffer;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (axis_names); i++)
|
||||
{
|
||||
if (axis_names[i].tag == ax->tag)
|
||||
@ -1585,16 +1577,18 @@ add_axis (GtkFontChooserWidget *fontchooser,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
axis->label = gtk_label_new (name);
|
||||
|
||||
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)value,
|
||||
(double)ax->min_value,
|
||||
(double)ax->max_value,
|
||||
1.0, 10.0, 0.0);
|
||||
axis->scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, axis->adjustment);
|
||||
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)ax->default_value, 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);
|
||||
@ -1609,7 +1603,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))
|
||||
if (is_named_instance (hb_font) || !should_show_axis (ax))
|
||||
{
|
||||
gtk_widget_hide (axis->label);
|
||||
gtk_widget_hide (axis->scale);
|
||||
@ -1621,15 +1615,31 @@ add_axis (GtkFontChooserWidget *fontchooser,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_font_chooser_widget_update_font_variations (GtkFontChooserWidget *fontchooser)
|
||||
{
|
||||
GtkFontChooserWidgetPrivate *priv = gtk_font_chooser_widget_get_instance_private (fontchooser);
|
||||
PangoFont *pango_font;
|
||||
FT_Face ft_face;
|
||||
FT_MM_Var *ft_mm_var;
|
||||
FT_Error ret;
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
const int *coords;
|
||||
unsigned int n_coords;
|
||||
unsigned int n_axes;
|
||||
hb_ot_var_axis_info_t *axes;
|
||||
gboolean has_axis = FALSE;
|
||||
int i;
|
||||
|
||||
if (priv->updating_variations)
|
||||
return FALSE;
|
||||
@ -1642,39 +1652,30 @@ 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));
|
||||
hb_font = pango_font_get_hb_font (pango_font);
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
ret = FT_Get_MM_Var (ft_face, &ft_mm_var);
|
||||
if (ret == 0)
|
||||
if (!hb_ot_var_has_data (hb_face))
|
||||
return FALSE;
|
||||
|
||||
coords = hb_font_get_var_coords_normalized (hb_font, &n_coords);
|
||||
|
||||
n_axes = hb_ot_var_get_axis_count (hb_face);
|
||||
axes = g_new0 (hb_ot_var_axis_info_t, n_axes);
|
||||
hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, axes);
|
||||
|
||||
for (i = 0; i < n_axes; i++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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, &axes[i], value, i + 4))
|
||||
has_axis = TRUE;
|
||||
}
|
||||
|
||||
pango_fc_font_unlock_face (PANGO_FC_FONT (pango_font));
|
||||
g_free (axes);
|
||||
g_object_unref (pango_font);
|
||||
|
||||
return has_axis;
|
||||
@ -1801,16 +1802,19 @@ feat_pressed (GtkGesture *gesture,
|
||||
|
||||
static char *
|
||||
find_affected_text (hb_tag_t feature_tag,
|
||||
hb_face_t *hb_face,
|
||||
hb_font_t *hb_font,
|
||||
hb_tag_t script_tag,
|
||||
hb_tag_t lang_tag,
|
||||
int max_chars)
|
||||
{
|
||||
hb_face_t *hb_face;
|
||||
unsigned int script_index = 0;
|
||||
unsigned int lang_index = 0;
|
||||
unsigned int feature_index = 0;
|
||||
GString *chars;
|
||||
|
||||
hb_face = hb_font_get_face (hb_font);
|
||||
|
||||
chars = g_string_new ("");
|
||||
|
||||
hb_ot_layout_table_find_script (hb_face, HB_OT_TAG_GSUB, script_tag, &script_index);
|
||||
@ -1838,7 +1842,6 @@ 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;
|
||||
|
||||
glyphs_input = hb_set_create ();
|
||||
@ -1852,9 +1855,6 @@ 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);
|
||||
|
||||
gid = -1;
|
||||
while (hb_set_next (glyphs_input, &gid)) {
|
||||
hb_codepoint_t ch;
|
||||
@ -1874,7 +1874,6 @@ find_affected_text (hb_tag_t feature_tag,
|
||||
}
|
||||
}
|
||||
hb_set_destroy (glyphs_input);
|
||||
hb_font_destroy (hb_font);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1883,7 +1882,7 @@ find_affected_text (hb_tag_t feature_tag,
|
||||
|
||||
static void
|
||||
update_feature_example (FeatureItem *item,
|
||||
hb_face_t *hb_face,
|
||||
hb_font_t *hb_font,
|
||||
hb_tag_t script_tag,
|
||||
hb_tag_t lang_tag,
|
||||
PangoFontDescription *font_desc)
|
||||
@ -1937,9 +1936,9 @@ update_feature_example (FeatureItem *item,
|
||||
else if (strcmp (item->name, "frac") == 0)
|
||||
input = g_strdup ("1/2 2/3 7/8");
|
||||
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, 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, script_tag, lang_tag, 10);
|
||||
|
||||
if (input[0] != '\0')
|
||||
{
|
||||
@ -2145,7 +2144,6 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser)
|
||||
{
|
||||
GtkFontChooserWidgetPrivate *priv = gtk_font_chooser_widget_get_instance_private (fontchooser);
|
||||
PangoFont *pango_font;
|
||||
FT_Face ft_face;
|
||||
hb_font_t *hb_font;
|
||||
hb_tag_t script_tag;
|
||||
hb_tag_t lang_tag;
|
||||
@ -2167,8 +2165,7 @@ 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);
|
||||
hb_font = pango_font_get_hb_font (pango_font);
|
||||
|
||||
if (hb_font)
|
||||
{
|
||||
@ -2214,7 +2211,7 @@ 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);
|
||||
update_feature_example (item, hb_font, script_tag, lang_tag, priv->font_desc);
|
||||
|
||||
if (GTK_IS_RADIO_BUTTON (item->feat))
|
||||
{
|
||||
@ -2227,11 +2224,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));
|
||||
g_object_unref (pango_font);
|
||||
|
||||
return has_feature;
|
||||
@ -2284,8 +2278,6 @@ update_font_features (GtkFontChooserWidget *fontchooser)
|
||||
gtk_font_chooser_widget_update_preview_attributes (fontchooser);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
gtk_font_chooser_widget_merge_font_desc (GtkFontChooserWidget *fontchooser,
|
||||
const PangoFontDescription *font_desc,
|
||||
@ -2331,12 +2323,11 @@ gtk_font_chooser_widget_merge_font_desc (GtkFontChooserWidget *fontchooser
|
||||
|
||||
gtk_font_chooser_widget_update_marks (fontchooser);
|
||||
|
||||
#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT)
|
||||
if (gtk_font_chooser_widget_update_font_features (fontchooser))
|
||||
has_tweak = TRUE;
|
||||
if (gtk_font_chooser_widget_update_font_variations (fontchooser))
|
||||
has_tweak = TRUE;
|
||||
#endif
|
||||
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (priv->tweak_action), has_tweak);
|
||||
}
|
||||
|
||||
@ -2553,4 +2544,3 @@ gtk_font_chooser_widget_get_tweak_action (GtkWidget *widget)
|
||||
|
||||
return priv->tweak_action;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,10 @@
|
||||
|
||||
#include "language-names.h"
|
||||
|
||||
#ifndef ISO_CODES_PREFIX
|
||||
#define ISO_CODES_PREFIX "/usr"
|
||||
#endif
|
||||
|
||||
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
|
||||
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user