[gtk] font chooser: Make the language property writable



commit 5a68ac27cf6dd932002239ddb544c2cc75c352ef
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Apr 2 13:34:22 2018 -0400

    font chooser: Make the language property writable
    
    This is meant as an input to the font chooser.
    We don't want the user to select a language, but
    rather have fonts presented as they would work for
    the current language. Therefore, do away with the
    lang/script combo on the tweak page.

 gtk/gtkfontbutton.c            |  28 +++++-
 gtk/gtkfontchooser.c           |  20 +++-
 gtk/gtkfontchooser.h           |   3 +
 gtk/gtkfontchooserdialog.c     |   2 +-
 gtk/gtkfontchooserwidget.c     | 208 +++++++++++------------------------------
 gtk/ui/gtkfontchooserwidget.ui |  13 ---
 6 files changed, 101 insertions(+), 173 deletions(-)
---
diff --git a/gtk/gtkfontbutton.c b/gtk/gtkfontbutton.c
index 57b86d82b8..6c06029bf8 100644
--- a/gtk/gtkfontbutton.c
+++ b/gtk/gtkfontbutton.c
@@ -84,7 +84,7 @@ struct _GtkFontButtonPrivate
   PangoFontMap         *font_map;
   gint                  font_size;
   char                 *font_features;
-  char                 *language;
+  PangoLanguage        *language;
   gchar                *preview_text;
   GtkFontFilterFunc     font_filter;
   gpointer              font_filter_data;
@@ -139,6 +139,8 @@ static void        gtk_font_button_set_font_name (GtkFontButton *button,
 static const char *gtk_font_button_get_font_name (GtkFontButton *button);
 static void        gtk_font_button_set_level     (GtkFontButton       *font_button,
                                                   GtkFontChooserLevel  level);
+static void        gtk_font_button_set_language  (GtkFontButton *button,
+                                                  const char    *language);
 
 static guint font_button_signals[LAST_SIGNAL] = { 0 };
 
@@ -164,9 +166,6 @@ clear_font_data (GtkFontButton *font_button)
 
   g_free (priv->font_features);
   priv->font_features = NULL;
-
-  g_free (priv->language);
-  priv->language = NULL;
 }
 
 static void
@@ -609,6 +608,7 @@ gtk_font_button_init (GtkFontButton *font_button)
   font_button->priv->level = GTK_FONT_CHOOSER_LEVEL_FAMILY |
                              GTK_FONT_CHOOSER_LEVEL_STYLE |
                              GTK_FONT_CHOOSER_LEVEL_SIZE;
+  font_button->priv->language = pango_language_get_default ();
 
   gtk_font_button_take_font_desc (font_button, NULL);
 
@@ -661,6 +661,9 @@ gtk_font_button_set_property (GObject      *object,
     case GTK_FONT_CHOOSER_PROP_FONT_DESC:
       gtk_font_button_take_font_desc (font_button, g_value_dup_boxed (value));
       break;
+    case GTK_FONT_CHOOSER_PROP_LANGUAGE:
+      gtk_font_button_set_language (font_button, g_value_get_string (value));
+      break;
     case GTK_FONT_CHOOSER_PROP_LEVEL:
       gtk_font_button_set_level (font_button, g_value_get_flags (value));
       break;
@@ -706,7 +709,7 @@ gtk_font_button_get_property (GObject    *object,
       g_value_set_string (value, priv->font_features);
       break;
     case GTK_FONT_CHOOSER_PROP_LANGUAGE:
-      g_value_set_string (value, priv->language);
+      g_value_set_string (value, pango_language_to_string (priv->language));
       break;
     case GTK_FONT_CHOOSER_PROP_LEVEL:
       g_value_set_flags (value, priv->level);
@@ -919,6 +922,7 @@ gtk_font_button_clicked (GtkButton *button,
 
       gtk_font_chooser_set_show_preview_entry (font_dialog, priv->show_preview_entry);
       gtk_font_chooser_set_level (GTK_FONT_CHOOSER (font_dialog), priv->level);
+      gtk_font_chooser_set_language (GTK_FONT_CHOOSER (font_dialog), priv->language);
 
       if (priv->preview_text)
         {
@@ -1332,3 +1336,17 @@ gtk_font_button_set_level (GtkFontButton       *button,
 
   g_object_notify (G_OBJECT (button), "level");
 }
+
+static void
+gtk_font_button_set_language (GtkFontButton *button,
+                              const char    *language)
+{
+  GtkFontButtonPrivate *priv = button->priv;
+
+  priv->language = pango_language_from_string (language);
+
+  if (priv->font_dialog)
+    gtk_font_chooser_set_language (GTK_FONT_CHOOSER (priv->font_dialog), language);
+
+  g_object_notify (G_OBJECT (button), "language");
+}
diff --git a/gtk/gtkfontchooser.c b/gtk/gtkfontchooser.c
index 70ab30a3e5..f7e0d20167 100644
--- a/gtk/gtkfontchooser.c
+++ b/gtk/gtkfontchooser.c
@@ -148,7 +148,7 @@ gtk_font_chooser_default_init (GtkFontChooserInterface *iface)
                           P_("Language"),
                           P_("Language for which features have been selected"),
                           "",
-                          GTK_PARAM_READABLE));
+                          GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
 
   /**
    * GtkFontChooser::font-activated:
@@ -559,7 +559,7 @@ gtk_font_chooser_get_font_features (GtkFontChooser *fontchooser)
  * gtk_font_chooser_get_language:
  * @fontchooser: a #GtkFontChooser
  *
- * Gets the currently-selected language for font features.
+ * Gets the language that is used for font features.
  *
  * Returns: the currently selected language
  */
@@ -574,3 +574,19 @@ gtk_font_chooser_get_language (GtkFontChooser *fontchooser)
 
   return text;
 }
+
+/**
+ * gtk_font_chooser_set_language:
+ * @fontchooser: a #GtkFontChooser
+ * @language: a language
+ *
+ * Sets the language to use for font features.
+ */
+void
+gtk_font_chooser_set_language (GtkFontChooser *fontchooser,
+                               const char     *language)
+{
+  g_return_if_fail (GTK_IS_FONT_CHOOSER (fontchooser));
+
+  g_object_set (fontchooser, "language", language, NULL);
+}
diff --git a/gtk/gtkfontchooser.h b/gtk/gtkfontchooser.h
index d04026ba37..922258839c 100644
--- a/gtk/gtkfontchooser.h
+++ b/gtk/gtkfontchooser.h
@@ -154,6 +154,9 @@ GDK_AVAILABLE_IN_ALL
 char *           gtk_font_chooser_get_font_features        (GtkFontChooser   *fontchooser);
 GDK_AVAILABLE_IN_ALL
 char *           gtk_font_chooser_get_language             (GtkFontChooser   *fontchooser);
+GDK_AVAILABLE_IN_ALL
+void             gtk_font_chooser_set_language             (GtkFontChooser   *fontchooser,
+                                                            const char       *language);
 
 G_END_DECLS
 
diff --git a/gtk/gtkfontchooserdialog.c b/gtk/gtkfontchooserdialog.c
index a2ab27da6e..185ea38e26 100644
--- a/gtk/gtkfontchooserdialog.c
+++ b/gtk/gtkfontchooserdialog.c
@@ -213,7 +213,7 @@ gtk_font_chooser_dialog_class_init (GtkFontChooserDialogClass *klass)
   /* Bind class to template
    */
   gtk_widget_class_set_template_from_resource (widget_class,
-                                              "/org/gtk/libgtk/ui/gtkfontchooserdialog.ui");
+                                               "/org/gtk/libgtk/ui/gtkfontchooserdialog.ui");
 
   gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserDialog, fontchooser);
   gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserDialog, select_button);
diff --git a/gtk/gtkfontchooserwidget.c b/gtk/gtkfontchooserwidget.c
index e68c9ff783..46d697c316 100644
--- a/gtk/gtkfontchooserwidget.c
+++ b/gtk/gtkfontchooserwidget.c
@@ -120,13 +120,12 @@ struct _GtkFontChooserWidgetPrivate
 
   GtkWidget       *axis_grid;
   GtkWidget       *feature_box;
-  GtkWidget       *feature_language_combo;
 
   PangoFontMap         *font_map;
 
   PangoFontDescription *font_desc;
   char                 *font_features;
-  PangoLanguage        *font_language;
+  PangoLanguage        *language;
   GtkTreeIter           font_iter;      /* invalid if font not available or pointer into model
                                            (not filter_model) to the row containing font */
   GtkFontFilterFunc filter_func;
@@ -211,10 +210,11 @@ static void     gtk_font_chooser_widget_cell_data_func         (GtkTreeViewColum
 static void                gtk_font_chooser_widget_set_level (GtkFontChooserWidget *fontchooser,
                                                               GtkFontChooserLevel   level);
 static GtkFontChooserLevel gtk_font_chooser_widget_get_level (GtkFontChooserWidget *fontchooser);
+static void                gtk_font_chooser_widget_set_language (GtkFontChooserWidget *fontchooser,
+                                                                 const char           *language);
 static void selection_changed (GtkTreeSelection *selection,
                                GtkFontChooserWidget *fontchooser);
 static void update_font_features (GtkFontChooserWidget *fontchooser);
-static void update_language (GtkFontChooserWidget *fontchooser);
 
 static void gtk_font_chooser_widget_iface_init (GtkFontChooserIface *iface);
 
@@ -307,6 +307,9 @@ gtk_font_chooser_widget_set_property (GObject         *object,
     case GTK_FONT_CHOOSER_PROP_LEVEL:
       gtk_font_chooser_widget_set_level (fontchooser, g_value_get_flags (value));
       break;
+    case GTK_FONT_CHOOSER_PROP_LANGUAGE:
+      gtk_font_chooser_widget_set_language (fontchooser, g_value_get_string (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -345,7 +348,7 @@ gtk_font_chooser_widget_get_property (GObject         *object,
       g_value_set_string (value, fontchooser->priv->font_features);
       break;
     case GTK_FONT_CHOOSER_PROP_LANGUAGE:
-      g_value_set_string (value, pango_language_to_string (fontchooser->priv->font_language));
+      g_value_set_string (value, pango_language_to_string (fontchooser->priv->language));
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -590,8 +593,8 @@ gtk_font_chooser_widget_update_preview_attributes (GtkFontChooserWidget *fontcho
   pango_attr_list_insert (attrs, pango_attr_font_desc_new (priv->font_desc));
   if (priv->font_features)
     pango_attr_list_insert (attrs, pango_attr_font_features_new (priv->font_features));
-  if (priv->font_language)
-    pango_attr_list_insert (attrs, pango_attr_language_new (priv->font_language));
+  if (priv->language)
+    pango_attr_list_insert (attrs, pango_attr_language_new (priv->language));
 
   gtk_entry_set_attributes (GTK_ENTRY (priv->preview), attrs);
 
@@ -754,7 +757,6 @@ gtk_font_chooser_widget_class_init (GtkFontChooserWidgetClass *klass)
   gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserWidget, grid);
   gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserWidget, font_name_label);
   gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserWidget, feature_box);
-  gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserWidget, feature_language_combo);
   gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserWidget, axis_grid);
 
   gtk_widget_class_bind_template_callback (widget_class, text_changed_cb);
@@ -767,10 +769,6 @@ gtk_font_chooser_widget_class_init (GtkFontChooserWidgetClass *klass)
   gtk_widget_class_bind_template_callback (widget_class, output_cb);
   gtk_widget_class_bind_template_callback (widget_class, selection_changed);
 
-#if defined(HAVE_HARFBUZZ) && defined(HAVE_PANGOFT)
-  gtk_widget_class_bind_template_callback (widget_class, update_language);
-#endif
-
   gtk_widget_class_set_css_name (widget_class, I_("fontchooser"));
 }
 
@@ -869,6 +867,7 @@ gtk_font_chooser_widget_init (GtkFontChooserWidget *fontchooser)
   priv->level = GTK_FONT_CHOOSER_LEVEL_FAMILY |
                 GTK_FONT_CHOOSER_LEVEL_STYLE |
                 GTK_FONT_CHOOSER_LEVEL_SIZE;
+  priv->language = pango_language_get_default ();
 
   /* Set default preview text */
   gtk_entry_set_text (GTK_ENTRY (priv->preview), priv->preview_text);
@@ -1694,102 +1693,28 @@ gtk_font_chooser_widget_update_font_variations (GtkFontChooserWidget *fontchoose
 
 /* OpenType features */
 
+/* look for a lang / script combination that matches the
+ * language property and is supported by the hb_face. If
+ * none is found, return the default lang / script tags.
+ */
 static void
-add_script (GtkListStore *store,
-            guint         script_index,
-            hb_tag_t      script,
-            guint         lang_index,
-            hb_tag_t      lang)
-{
-  char langbuf[5];
-  const char *langname;
-
-  if (lang == HB_OT_TAG_DEFAULT_LANGUAGE)
-    langname = C_("Language", "Default");
-  else
-    {
-      langname = get_language_name_for_tag (lang);
-      if (!langname)
-        {
-          hb_tag_to_string (lang, langbuf);
-          langbuf[4] = 0;
-          langname = langbuf;
-        }
-    }
-
-  gtk_list_store_insert_with_values (store, NULL, -1,
-                                     0, langname,
-                                     1, script_index,
-                                     2, lang_index,
-                                     3, lang,
-                                     -1);
-}
-
-static int
-feature_language_sort_func (GtkTreeModel *model,
-                            GtkTreeIter  *a,
-                            GtkTreeIter  *b,
-                            gpointer      user_data)
-{
-  char *sa, *sb;
-  int ret;
-
-  gtk_tree_model_get (model, a, 0, &sa, -1);
-  gtk_tree_model_get (model, b, 0, &sb, -1);
-
-  ret = strcmp (sa, sb);
-
-  g_free (sa);
-  g_free (sb);
-
-  return ret;
-}
-
-typedef struct {
-  hb_tag_t script_tag;
-  hb_tag_t lang_tag;
-  unsigned int script_index;
-  unsigned int lang_index;
-} TagPair;
-
-static guint
-tag_pair_hash (gconstpointer data)
-{
-  const TagPair *pair = data;
-
-  return pair->script_tag + pair->lang_tag;
-}
-
-static gboolean
-tag_pair_equal (gconstpointer a, gconstpointer b)
-{
-  const TagPair *pair_a = a;
-  const TagPair *pair_b = b;
-
-  return pair_a->script_tag == pair_b->script_tag && pair_a->lang_tag == pair_b->lang_tag;
-}
-
-static void
-update_language_combo (GtkFontChooserWidget *fontchooser,
-                       hb_face_t            *hb_face)
+find_language_and_script (GtkFontChooserWidget *fontchooser,
+                          hb_face_t            *hb_face,
+                          hb_tag_t             *lang_tag,
+                          hb_tag_t             *script_tag)
 {
   GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
-  GtkListStore *store;
   gint i, j, k;
   hb_tag_t scripts[80];
   unsigned int n_scripts;
   unsigned int count;
   hb_tag_t table[2] = { HB_OT_TAG_GSUB, HB_OT_TAG_GPOS };
-  GHashTable *tags;
-  GHashTableIter iter;
-  TagPair *pair;
+  hb_language_t lang;
+  const char *langname, *p;
 
-  tags = g_hash_table_new_full (tag_pair_hash, tag_pair_equal, g_free, NULL);
-
-  pair = g_new (TagPair, 1);
-  pair->script_tag = HB_OT_TAG_DEFAULT_SCRIPT;
-  pair->lang_tag = HB_OT_TAG_DEFAULT_LANGUAGE;
-  g_hash_table_add (tags, pair);
+  langname = pango_language_to_string (priv->language);
+  p = strchr (langname, '-');
+  lang = hb_language_from_string (langname, p ? p - langname : -1);
 
   n_scripts = 0;
   for (i = 0; i < 2; i++)
@@ -1814,30 +1739,22 @@ update_language_combo (GtkFontChooserWidget *fontchooser,
 
       for (k = 0; k < n_languages; k++)
         {
-          pair = g_new (TagPair, 1);
-          pair->script_tag = scripts[j];
-          pair->lang_tag = languages[k];
-          pair->script_index = j;
-          pair->lang_index = k;
-          g_hash_table_add (tags, pair);
+          hb_language_t *l;
+          char buf[5], buf2[5];
+          hb_tag_to_string (languages[k], buf); buf[4] = '\0';
+          hb_tag_to_string (scripts[j], buf2); buf2[4] = '\0';
+          l = hb_ot_tag_to_language (languages[k]);
+          if (l == lang)
+            {
+              *script_tag = scripts[j];
+              *lang_tag = languages[k];
+              return;
+            }
         }
     }
 
-  store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
-
-  g_hash_table_iter_init (&iter, tags);
-  while (g_hash_table_iter_next (&iter, (gpointer *)&pair, NULL))
-    add_script (store, pair->script_index, pair->script_tag, pair->lang_index, pair->lang_tag);
-
-  g_hash_table_unref (tags);
-
-  gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (store),
-                                           feature_language_sort_func, NULL, NULL);
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
-                                        GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
-                                        GTK_SORT_ASCENDING);
-  gtk_combo_box_set_model (GTK_COMBO_BOX (priv->feature_language_combo), GTK_TREE_MODEL (store));
-  gtk_combo_box_set_active (GTK_COMBO_BOX (priv->feature_language_combo), 0);
+  *lang_tag = HB_OT_TAG_DEFAULT_LANGUAGE;
+  *script_tag = HB_OT_TAG_DEFAULT_SCRIPT;
 }
 
 typedef struct {
@@ -2241,16 +2158,14 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser)
   PangoFont *pango_font;
   FT_Face ft_face;
   hb_font_t *hb_font;
-  hb_tag_t script_tag = FT_MAKE_TAG('l','a','t','n');
-  hb_tag_t lang_tag = FT_MAKE_TAG('D','E','U',' ');
+  hb_tag_t script_tag;
+  hb_tag_t lang_tag;
   guint script_index = 0;
   guint lang_index = 0;
   int i, j;
   GList *l;
   gboolean has_feature = FALSE;
 
-  gtk_widget_hide (priv->feature_language_combo);
-
   for (l = priv->feature_items; l; l = l->next)
     {
       FeatureItem *item = l->data;
@@ -2276,7 +2191,7 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser)
 
       hb_face = hb_font_get_face (hb_font);
 
-      update_language_combo (fontchooser, hb_face);
+      find_language_and_script (fontchooser, hb_face, &lang_tag, &script_tag);
 
       n_features = 0;
       for (i = 0; i < 2; i++)
@@ -2305,7 +2220,6 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser)
               has_feature = TRUE;
               gtk_widget_show (item->top);
               gtk_widget_show (gtk_widget_get_parent (item->top));
-              gtk_widget_show (priv->feature_language_combo);
 
               update_feature_example (item, hb_face, script_tag, lang_tag, priv->font_desc);
 
@@ -2377,33 +2291,6 @@ update_font_features (GtkFontChooserWidget *fontchooser)
   gtk_font_chooser_widget_update_preview_attributes (fontchooser);
 }
 
-static void
-update_language (GtkFontChooserWidget *fontchooser)
-{
-  GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
-  GtkTreeIter iter;
-
-  if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (priv->feature_language_combo), &iter))
-    {
-      GtkTreeModel *model;
-      PangoLanguage *lang;
-      hb_tag_t lang_tag;
-
-      model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->feature_language_combo));
-      gtk_tree_model_get (model, &iter,
-                          3, &lang_tag,
-                          -1);
-      lang = pango_language_from_string (hb_language_to_string (hb_ot_tag_to_language (lang_tag)));
-      if (priv->font_language != lang)
-        {
-          priv->font_language = lang;
-          g_object_notify (G_OBJECT (fontchooser), "language");
-        }
-    }
-
-  gtk_font_chooser_widget_update_preview_attributes (fontchooser);
-}
-
 #endif
 
 static void
@@ -2633,6 +2520,23 @@ gtk_font_chooser_widget_get_level (GtkFontChooserWidget *fontchooser)
   return priv->level;
 }
 
+static void
+gtk_font_chooser_widget_set_language (GtkFontChooserWidget *fontchooser,
+                                      const char           *language)
+{
+  GtkFontChooserWidgetPrivate *priv = fontchooser->priv;
+  PangoLanguage *lang;
+
+  lang = pango_language_from_string (language);
+  if (priv->language == lang)
+    return;
+
+  priv->language = lang;
+  g_object_notify (G_OBJECT (fontchooser), "language");
+
+  gtk_font_chooser_widget_update_preview_attributes (fontchooser);
+}
+
 static void
 gtk_font_chooser_widget_iface_init (GtkFontChooserIface *iface)
 {
diff --git a/gtk/ui/gtkfontchooserwidget.ui b/gtk/ui/gtkfontchooserwidget.ui
index 901438cb07..64a1c16754 100644
--- a/gtk/ui/gtkfontchooserwidget.ui
+++ b/gtk/ui/gtkfontchooserwidget.ui
@@ -289,19 +289,6 @@
                       <object class="GtkBox" id="feature_box">
                         <property name="orientation">vertical</property>
                         <property name="spacing">12</property>
-                        <child>
-                          <object class="GtkComboBox" id="feature_language_combo">
-                            <property name="halign">start</property>
-                            <property name="margin-top">10</property>
-                            <signal name="changed" handler="update_language" swapped="yes"/>
-                            <child>
-                              <object class="GtkCellRendererText"/>
-                              <attributes>
-                                <attribute name="text">0</attribute>
-                              </attributes>
-                            </child>
-                          </object>
-                        </child>
                       </object>
                     </child>
                   </object>


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