[pango/pango2: 64/178] Clean up PangoFontFamily




commit c20daaf5da190d9d7a4e23b8dbe2cc98b11700cf
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Jun 11 11:20:35 2022 -0400

    Clean up PangoFontFamily
    
    Add properties back, add get_font_map api, and
    fix up interactions with subclasses.

 pango/pango-font-family-private.h    |  27 +++++-
 pango/pango-font-family.c            | 172 +++++++++++++++++++++++++++++------
 pango/pango-font-family.h            |   3 +
 pango/pango-fontmap.c                |  30 +++---
 pango/pango-generic-family-private.h |   7 +-
 pango/pango-generic-family.c         |  15 +--
 pango/pango-hbfamily-private.h       |  14 ---
 pango/pango-hbfamily.c               |  14 +--
 pango/pango-hbfont.c                 |   3 +-
 pango/pango-userfont.c               |   3 +-
 10 files changed, 191 insertions(+), 97 deletions(-)
---
diff --git a/pango/pango-font-family-private.h b/pango/pango-font-family-private.h
index 186df77b2..32b2fc41e 100644
--- a/pango/pango-font-family-private.h
+++ b/pango/pango-font-family-private.h
@@ -27,17 +27,40 @@ typedef struct _PangoFontFamilyClass PangoFontFamilyClass;
 struct _PangoFontFamily
 {
   GObject parent_instance;
+
+  PangoFontMap *map;
+  char *name;
 };
 
 struct _PangoFontFamilyClass
 {
   GObjectClass parent_class;
 
-  const char *    (* get_name)     (PangoFontFamily *family);
   PangoFontFace * (* get_face)     (PangoFontFamily *family,
                                     const char      *name);
-
 };
 
 #define PANGO_FONT_FAMILY_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FONT_FAMILY, 
PangoFontFamilyClass))
 #define PANGO_FONT_FAMILY_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_FONT_FAMILY, 
PangoFontFamilyClass))
+
+static inline void
+pango_font_family_set_name (PangoFontFamily *family,
+                            const char      *name)
+{
+  family->name = g_strdup (name);
+}
+
+static inline void
+pango_font_family_set_font_map (PangoFontFamily *family,
+                                PangoFontMap    *map)
+{
+  if (family->map)
+    g_object_remove_weak_pointer (G_OBJECT (family->map),
+                                  (gpointer *)&family->map);
+
+  family->map = map;
+
+  if (family->map)
+    g_object_add_weak_pointer (G_OBJECT (family->map),
+                               (gpointer *)&family->map);
+}
diff --git a/pango/pango-font-family.c b/pango/pango-font-family.c
index 91caba589..70eabaa06 100644
--- a/pango/pango-font-family.c
+++ b/pango/pango-font-family.c
@@ -37,6 +37,8 @@
  * to provide a list of font faces.
  */
 
+/* {{{ GListModel implementation */
+
 static GType
 pango_font_family_get_item_type (GListModel *list)
 {
@@ -66,16 +68,121 @@ pango_font_family_list_model_init (GListModelInterface *iface)
   iface->get_item = pango_font_family_get_item;
 }
 
+/* }}} */
+/* {{{ PangoFontFamily implementation */
+
+enum {
+  PROP_NAME = 1,
+  PROP_ITEM_TYPE,
+  PROP_N_ITEMS,
+  N_PROPERTIES
+};
+
+static GParamSpec *properties[N_PROPERTIES] = { NULL, };
+
 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (PangoFontFamily, pango_font_family, G_TYPE_OBJECT,
                                   G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, 
pango_font_family_list_model_init))
 
-static PangoFontFace *pango_font_family_real_get_face (PangoFontFamily *family,
-                                                       const char      *name);
+static PangoFontFace *
+pango_font_family_real_get_face (PangoFontFamily *family,
+                                 const char      *name)
+{
+  PangoFontFace *face;
+
+  face = NULL;
+
+  for (int i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (family)); i++)
+    {
+      PangoFontFace *f = g_list_model_get_item (G_LIST_MODEL (family), i);
+      g_object_unref (f);
+      if (name == NULL ||
+          strcmp (name, pango_font_face_get_face_name (f)) == 0)
+        {
+          face = f;
+          break;
+        }
+    }
+
+  return face;
+}
 
 static void
-pango_font_family_class_init (PangoFontFamilyClass *class G_GNUC_UNUSED)
+pango_font_family_finalize (GObject *object)
 {
+  PangoFontFamily *family = PANGO_FONT_FAMILY (object);
+
+  g_free (family->name);
+  if (family->map)
+    g_object_remove_weak_pointer (G_OBJECT (family->map), (gpointer *)&family->map);
+
+  G_OBJECT_CLASS (pango_font_family_parent_class)->finalize (object);
+}
+
+static void
+pango_font_family_get_property (GObject    *object,
+                                guint       property_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+  PangoFontFamily *family = PANGO_FONT_FAMILY (object);
+
+  switch (property_id)
+    {
+    case PROP_NAME:
+      g_value_set_string (value, family->name);
+      break;
+
+    case PROP_ITEM_TYPE:
+      g_value_set_gtype (value, PANGO_TYPE_FONT);
+      break;
+
+    case PROP_N_ITEMS:
+      g_value_set_uint (value, pango_font_family_get_n_items (G_LIST_MODEL (object)));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+static void
+pango_font_family_class_init (PangoFontFamilyClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->finalize = pango_font_family_finalize;
+  object_class->get_property = pango_font_family_get_property;
+
   class->get_face = pango_font_family_real_get_face;
+
+  /**
+   * PangoFontFamily:name: (attributes org.gtk.Property.get=pango_font_family_get_name)
+   *
+   * The name of the family.
+   */
+  properties[PROP_NAME] =
+      g_param_spec_string ("name", NULL, NULL, NULL,
+                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+  /**
+   * PangoFontFamily:item-type:
+   *
+   * The type of objects that the family contains.
+   */
+  properties[PROP_ITEM_TYPE] =
+      g_param_spec_gtype ("item-type", NULL, NULL, PANGO_TYPE_FONT_FACE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+  /**
+   * PangoFontFamily:n-items:
+   *
+   * The number of faces contained in the family.
+   */
+  properties[PROP_N_ITEMS] =
+      g_param_spec_uint ("n-items", "", "", 0, G_MAXUINT, 0,
+                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+  g_object_class_install_properties (object_class, N_PROPERTIES, properties);
 }
 
 static void
@@ -83,6 +190,34 @@ pango_font_family_init (PangoFontFamily *family G_GNUC_UNUSED)
 {
 }
 
+/* }}} */
+/* {{{ Public API */
+
+/**
+ * pango_font_family_get_font_map:
+ * @family: a `PangoFontFamily`
+ *
+ * Returns the `PangoFontMap that @family belongs to.
+ *
+ * Note that the family maintains a *weak* reference to
+ * the font map, so if all references to font map are
+ * dropped, the font map will be finalized even if there
+ * are fonts created with the font map that are still alive.
+ * In that case this function will return %NULL.
+ *
+ * It is the responsibility of the user to ensure that the
+ * font map is kept alive. In most uses this is not an issue
+ * as a `PangoContext` holds a reference to the font map.
+
+ *
+ * Return value: (transfer none) (nullable): the `PangoFontMap
+ */
+PangoFontMap *
+pango_font_family_get_font_map (PangoFontFamily *family)
+{
+  return family->map;
+}
+
 /**
  * pango_font_family_get_name:
  * @family: a `PangoFontFamily`
@@ -97,34 +232,11 @@ pango_font_family_init (PangoFontFamily *family G_GNUC_UNUSED)
  *   by the family object and must not be modified or freed.
  */
 const char *
-pango_font_family_get_name (PangoFontFamily  *family)
+pango_font_family_get_name (PangoFontFamily *family)
 {
   g_return_val_if_fail (PANGO_IS_FONT_FAMILY (family), NULL);
 
-  return PANGO_FONT_FAMILY_GET_CLASS (family)->get_name (family);
-}
-
-static PangoFontFace *
-pango_font_family_real_get_face (PangoFontFamily *family,
-                                 const char      *name)
-{
-  PangoFontFace *face;
-
-  face = NULL;
-
-  for (int i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (family)); i++)
-    {
-      PangoFontFace *f = g_list_model_get_item (G_LIST_MODEL (family), i);
-      g_object_unref (f);
-      if (name == NULL ||
-          strcmp (name, pango_font_face_get_face_name (f)) == 0)
-        {
-          face = f;
-          break;
-        }
-    }
-
-  return face;
+  return family->name;
 }
 
 /**
@@ -147,3 +259,7 @@ pango_font_family_get_face (PangoFontFamily *family,
 
   return PANGO_FONT_FAMILY_GET_CLASS (family)->get_face (family, name);
 }
+
+/* }}} */
+
+/* vim:set foldmethod=marker expandtab: */
diff --git a/pango/pango-font-family.h b/pango/pango-font-family.h
index 3e7709f64..be14ebe95 100644
--- a/pango/pango-font-family.h
+++ b/pango/pango-font-family.h
@@ -32,6 +32,9 @@ G_BEGIN_DECLS
 PANGO_AVAILABLE_IN_ALL
 PANGO_DECLARE_INTERNAL_TYPE (PangoFontFamily, pango_font_family, PANGO, FONT_FAMILY, GObject)
 
+PANGO_AVAILABLE_IN_ALL
+PangoFontMap *          pango_font_family_get_font_map  (PangoFontFamily  *family);
+
 PANGO_AVAILABLE_IN_ALL
 const char *            pango_font_family_get_name      (PangoFontFamily  *family) G_GNUC_PURE;
 
diff --git a/pango/pango-fontmap.c b/pango/pango-fontmap.c
index 1f74f77cf..c814e98e4 100644
--- a/pango/pango-fontmap.c
+++ b/pango/pango-fontmap.c
@@ -194,14 +194,8 @@ pango_fontset_cache (PangoFontsetCached *fontset,
 /* }}} */
 /* {{{ Utilities */
 
-typedef struct {
-  PangoFontFamily family;
-  PangoFontMap *map;
-  const char *name;
-} FamilyKey;
-
 static guint
-pango_family_hash (const FamilyKey *key)
+pango_family_hash (const PangoFontFamily *key)
 {
   const char *p;
   guint32 h = 5381;
@@ -213,8 +207,8 @@ pango_family_hash (const FamilyKey *key)
 }
 
 static gboolean
-pango_family_equal (const FamilyKey *a,
-                    const FamilyKey *b)
+pango_family_equal (const PangoFontFamily *a,
+                    const PangoFontFamily *b)
 {
   return g_ascii_strcasecmp (a->name, b->name) == 0;
 }
@@ -223,10 +217,10 @@ static PangoFontFamily *
 find_family (PangoFontMap *self,
              const char   *family_name)
 {
-  FamilyKey lookup;
+  PangoFontFamily lookup;
   PangoFontFamily *family;
 
-  lookup.name = family_name;
+  lookup.name = (char *)family_name;
 
   family = PANGO_FONT_FAMILY (g_hash_table_lookup (self->families_hash, &lookup));
 
@@ -887,24 +881,23 @@ pango_font_map_add_family (PangoFontMap    *self,
 
   g_return_if_fail (PANGO_IS_FONT_MAP (self));
   g_return_if_fail (PANGO_IS_HB_FAMILY (family) || PANGO_IS_GENERIC_FAMILY (family));
-  g_return_if_fail (((CommonFamily *)family)->map == NULL);
+  g_return_if_fail (family->map == NULL);
 
   if (!self->in_populate)
     g_ptr_array_add (self->added_families, g_object_ref (family));
 
-  name = ((CommonFamily *)family)->name;
+  name = family->name;
 
   position = 0;
   while (position < self->families->len)
     {
       PangoFontFamily *f = g_ptr_array_index (self->families, position);
-      if (g_ascii_strcasecmp (name, ((CommonFamily *)f)->name) < 0)
+      if (g_ascii_strcasecmp (name, f->name) < 0)
         break;
       position++;
     }
 
-  ((CommonFamily *)family)->map = self;
-  g_object_add_weak_pointer (G_OBJECT (self), (gpointer *)&((CommonFamily *)family)->map);
+  pango_font_family_set_font_map (family, self);
 
   g_ptr_array_insert (self->families, position, family);
   g_hash_table_add (self->families_hash, family);
@@ -930,7 +923,7 @@ pango_font_map_remove_family (PangoFontMap    *self,
 
   g_return_if_fail (PANGO_IS_FONT_MAP (self));
   g_return_if_fail (PANGO_IS_HB_FAMILY (family) || PANGO_IS_GENERIC_FAMILY (family));
-  g_return_if_fail (((CommonFamily *)family)->map == self);
+  g_return_if_fail (family->map == self);
 
   if (!g_ptr_array_find (self->added_families, family, &position))
     return;
@@ -938,8 +931,7 @@ pango_font_map_remove_family (PangoFontMap    *self,
   g_hash_table_remove (self->families_hash, family);
   g_ptr_array_remove_index (self->families, position);
 
-  g_object_remove_weak_pointer (G_OBJECT (self), (gpointer *)&((CommonFamily *)family)->map);
-  ((CommonFamily *)family)->map = NULL;
+  pango_font_family_set_font_map (family, NULL);
 
   if (!self->in_populate)
     g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 0);
diff --git a/pango/pango-generic-family-private.h b/pango/pango-generic-family-private.h
index 7ad767eed..21774c4ae 100644
--- a/pango/pango-generic-family-private.h
+++ b/pango/pango-generic-family-private.h
@@ -21,18 +21,13 @@
 
 #include "pango-font.h"
 #include "pango-generic-family.h"
-#include "pango-hbfamily-private.h"
+#include "pango-font-family-private.h"
 
 
 struct _PangoGenericFamily
 {
   PangoFontFamily parent_instance;
 
-  PangoFontMap *map;
-  char *name;
-
-  /* up to here shared with PangoHbFamily */
-
   GPtrArray *families;
 };
 
diff --git a/pango/pango-generic-family.c b/pango/pango-generic-family.c
index 565a9930b..d78946474 100644
--- a/pango/pango-generic-family.c
+++ b/pango/pango-generic-family.c
@@ -23,6 +23,7 @@
 #include <gio/gio.h>
 
 #include "pango-generic-family-private.h"
+#include "pango-hbfamily-private.h"
 #include "pango-impl-utils.h"
 #include "pango-hbface-private.h"
 #include "pango-font-private.h"
@@ -115,29 +116,17 @@ pango_generic_family_finalize (GObject *object)
 {
   PangoGenericFamily *self = PANGO_GENERIC_FAMILY (object);
 
-  g_free (self->name);
   g_ptr_array_unref (self->families);
 
   G_OBJECT_CLASS (pango_generic_family_parent_class)->finalize (object);
 }
 
-static const char *
-pango_generic_family_get_name (PangoFontFamily *family)
-{
-  PangoGenericFamily *self = PANGO_GENERIC_FAMILY (family);
-
-  return self->name;
-}
-
 static void
 pango_generic_family_class_init (PangoGenericFamilyClass *class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (class);
-  PangoFontFamilyClass *family_class = PANGO_FONT_FAMILY_CLASS (class);
 
   object_class->finalize = pango_generic_family_finalize;
-
-  family_class->get_name = pango_generic_family_get_name;
 }
 
 /* }}} */
@@ -207,7 +196,7 @@ pango_generic_family_new (const char *name)
 
   self = g_object_new (PANGO_TYPE_GENERIC_FAMILY, NULL);
 
-  self->name = g_strdup (name);
+  pango_font_family_set_name (PANGO_FONT_FAMILY (self), name);
 
   return self;
 }
diff --git a/pango/pango-hbfamily-private.h b/pango/pango-hbfamily-private.h
index c99a97624..5719609f1 100644
--- a/pango/pango-hbfamily-private.h
+++ b/pango/pango-hbfamily-private.h
@@ -27,24 +27,10 @@
 
 G_DECLARE_FINAL_TYPE (PangoHbFamily, pango_hb_family, PANGO, HB_FAMILY, PangoFontFamily)
 
-typedef struct _CommonFamily CommonFamily;
-struct _CommonFamily
-{
-  PangoFontFamily parent_instance;
-
-  PangoFontMap *map;
-  char *name;
-};
-
 struct _PangoHbFamily
 {
   PangoFontFamily parent_instance;
 
-  PangoFontMap *map;
-  char *name;
-
-  /* up to here shared with PangoGenericFamily */
-
   GPtrArray *faces;
 };
 
diff --git a/pango/pango-hbfamily.c b/pango/pango-hbfamily.c
index 3a8ea7aba..7096104e1 100644
--- a/pango/pango-hbfamily.c
+++ b/pango/pango-hbfamily.c
@@ -133,20 +133,11 @@ pango_hb_family_finalize (GObject *object)
 {
   PangoHbFamily *self = PANGO_HB_FAMILY (object);
 
-  g_free (self->name);
   g_ptr_array_unref (self->faces);
 
   G_OBJECT_CLASS (pango_hb_family_parent_class)->finalize (object);
 }
 
-static const char *
-pango_hb_family_get_name (PangoFontFamily *family)
-{
-  PangoHbFamily *self = PANGO_HB_FAMILY (family);
-
-  return self->name;
-}
-
 static PangoFontFace *
 pango_hb_family_get_face (PangoFontFamily *family,
                           const char      *name)
@@ -172,7 +163,6 @@ pango_hb_family_class_init (PangoHbFamilyClass *class)
 
   object_class->finalize = pango_hb_family_finalize;
 
-  family_class->get_name = pango_hb_family_get_name;
   family_class->get_face = pango_hb_family_get_face;
 }
 
@@ -194,7 +184,7 @@ pango_hb_family_new (const char *name)
 
   self = g_object_new (PANGO_TYPE_HB_FAMILY, NULL);
 
-  self->name = g_strdup (name);
+  pango_font_family_set_name (PANGO_FONT_FAMILY (self), name);
 
   return self;
 }
@@ -233,6 +223,7 @@ pango_hb_family_add_face (PangoHbFamily *self,
   ((CommonFace *)face)->family = PANGO_FONT_FAMILY (self);
 
   g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);
+  g_object_notify (G_OBJECT (self), "n-items");
 }
 
 /*< private >
@@ -258,6 +249,7 @@ pango_hb_family_remove_face (PangoHbFamily *self,
   g_ptr_array_remove_index (self->faces, position);
 
   g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 0);
+  g_object_notify (G_OBJECT (self), "n-items");
 }
 
 /*< private >
diff --git a/pango/pango-hbfont.c b/pango/pango-hbfont.c
index 33b37a9cd..bc51c03d5 100644
--- a/pango/pango-hbfont.c
+++ b/pango/pango-hbfont.c
@@ -111,9 +111,8 @@ static PangoFontMap *
 pango_hb_font_get_font_map (PangoFont *font)
 {
   PangoHbFont *self = PANGO_HB_FONT (font);
-  PangoHbFamily *family = PANGO_HB_FAMILY (self->face->family);
 
-  return family->map;
+  return self->face->family->map;
 }
 
 static PangoVariant
diff --git a/pango/pango-userfont.c b/pango/pango-userfont.c
index 16b51a5f0..ed7671e52 100644
--- a/pango/pango-userfont.c
+++ b/pango/pango-userfont.c
@@ -245,9 +245,8 @@ static PangoFontMap *
 pango_user_font_get_font_map (PangoFont *font)
 {
   PangoUserFont *self = PANGO_USER_FONT (font);
-  PangoHbFamily *family = PANGO_HB_FAMILY (self->face->family);
 
-  return family->map;
+  return self->face->family->map;
 }
 
 static hb_bool_t


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