[pango/pango2: 4/168] Add new font face api




commit 9671f893a5ea464ea059ba090e6d91b1a5395c34
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Feb 18 09:11:01 2022 -0600

    Add new font face api

 pango/pango-font-face-private.h      |  17 ++-
 pango/pango-font-face.c              |  91 +++++++++++++++++
 pango/pango-font-face.h              |  11 +-
 pango/pango-generic-family-private.h |   6 +-
 pango/pango-generic-family.c         |  20 ----
 pango/pango-hbface-private.h         |   8 --
 pango/pango-hbface.c                 | 193 ++++++++++++++---------------------
 pango/pango-hbfamily-private.h       |  15 ++-
 pango/pango-hbfamily.c               |  57 +----------
 pango/pango-hbfontmap.c              |  65 ++++--------
 pango/pango-userface-private.h       |   9 --
 pango/pango-userface.c               | 109 +++++++++-----------
 12 files changed, 280 insertions(+), 321 deletions(-)
---
diff --git a/pango/pango-font-face-private.h b/pango/pango-font-face-private.h
index 71c9033e..f99f2022 100644
--- a/pango/pango-font-face-private.h
+++ b/pango/pango-font-face-private.h
@@ -36,13 +36,26 @@ struct _PangoFontFaceClass
   const char *           (* get_face_name)     (PangoFontFace *face);
   PangoFontDescription * (* describe)          (PangoFontFace *face);
   gboolean               (* is_synthesized)    (PangoFontFace *face);
-  gboolean               (*is_monospace)       (PangoFontFace *face);
-  gboolean               (*is_variable)        (PangoFontFace *face);
+  gboolean               (* is_monospace)      (PangoFontFace *face);
+  gboolean               (* is_variable)       (PangoFontFace *face);
   PangoFontFamily *      (* get_family)        (PangoFontFace *face);
   gboolean               (* supports_language) (PangoFontFace *face,
                                                 PangoLanguage *language);
   PangoLanguage **       (* get_languages)     (PangoFontFace *face);
+  gboolean               (* has_char)          (PangoFontFace *face,
+                                                gunichar       wc);
+  const char *           (* get_faceid)        (PangoFontFace *face);
+  PangoFont *            (* create_font)       (PangoFontFace              *face,
+                                                const PangoFontDescription *desc,
+                                                float                       dpi,
+                                                const PangoMatrix          *matrix);
 };
 
 #define PANGO_FONT_FACE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FONT_FACE, 
PangoFontFaceClass))
 #define PANGO_FONT_FACE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_FONT_FACE, 
PangoFontFaceClass))
+
+const char *    pango_font_face_get_faceid      (PangoFontFace              *face);
+PangoFont *     pango_font_face_create_font     (PangoFontFace              *face,
+                                                 const PangoFontDescription *desc,
+                                                 float                       dpi,
+                                                 const PangoMatrix          *matrix);
diff --git a/pango/pango-font-face.c b/pango/pango-font-face.c
index 8f57e0f3..7ac41df2 100644
--- a/pango/pango-font-face.c
+++ b/pango/pango-font-face.c
@@ -51,6 +51,28 @@ pango_font_face_default_get_languages (PangoFontFace *face)
   return NULL;
 }
 
+static gboolean
+pango_font_face_default_has_char (PangoFontFace *face,
+                                  gunichar       wc)
+{
+  return FALSE;
+}
+
+static const char *
+pango_font_face_default_get_faceid (PangoFontFace *face)
+{
+  return "";
+}
+
+static PangoFont *
+pango_font_face_default_create_font (PangoFontFace              *face,
+                                     const PangoFontDescription *desc,
+                                     float                       dpi,
+                                     const PangoMatrix          *matrix)
+{
+  return NULL;
+}
+
 static void
 pango_font_face_class_init (PangoFontFaceClass *class G_GNUC_UNUSED)
 {
@@ -58,6 +80,9 @@ pango_font_face_class_init (PangoFontFaceClass *class G_GNUC_UNUSED)
   class->is_variable = pango_font_face_default_is_variable;
   class->get_languages = pango_font_face_default_get_languages;
   class->supports_language = pango_font_face_default_supports_language;
+  class->has_char = pango_font_face_default_has_char;
+  class->get_faceid = pango_font_face_default_get_faceid;
+  class->create_font = pango_font_face_default_create_font;
 }
 
 static void
@@ -239,3 +264,69 @@ pango_font_face_get_languages (PangoFontFace *face)
   return PANGO_FONT_FACE_GET_CLASS (face)->get_languages (face);
 }
 
+/**
+ * pango_font_face_has_char:
+ * @face: a `PangoFontFace`
+ * @wc: a Unicode character
+ *
+ * Returns whether the face provides a glyph for this character.
+ *
+ * Returns: `TRUE` if @font can render @wc
+ */
+gboolean
+pango_font_face_has_char (PangoFontFace *face,
+                          gunichar       wc)
+{
+  g_return_val_if_fail (PANGO_IS_FONT_FACE (face), FALSE);
+
+  return PANGO_FONT_FACE_GET_CLASS (face)->has_char (face, wc);
+}
+
+/*< private >
+ * pango_font_face_get_faceid:
+ * @self: a `PangoHbFace`
+ *
+ * Returns the faceid of the face.
+ *
+ * The faceid is meant to uniquely identify the face among the
+ * faces of its family. It includes an identifier for the font
+ * file that is used (currently, we use the PostScript name for
+ * this), the face index, the instance ID, as well as synthetic
+ * tweaks such as emboldening and transforms and variations.
+ *
+ * [method@Pango.FontFace.describe] adds the faceid to the font
+ * description that it produces.
+ *
+ * See pango_hb_family_find_face() for the code that takes the
+ * faceid into account when searching for a face. It is careful
+ * to fall back to approximate matching if an exact match for
+ * the faceid isn't found. That should make it safe to preserve
+ * faceids when saving font descriptions in configuration or
+ * other data.
+ *
+ * There are no guarantees about the format of the string that
+ * this function produces, except for that it does not contain
+ * ' ', ',' or '=', so it can be safely embedded in the '@' part
+ * of a serialized font description.
+ *
+ * Returns: (transfer none): the faceid
+ */
+const char *
+pango_font_face_get_faceid (PangoFontFace *face)
+{
+  g_return_val_if_fail (PANGO_IS_FONT_FACE (face), "");
+
+  return PANGO_FONT_FACE_GET_CLASS (face)->get_faceid (face);
+}
+
+PangoFont *
+pango_font_face_create_font (PangoFontFace              *face,
+                             const PangoFontDescription *desc,
+                             float                       dpi,
+                             const PangoMatrix          *matrix)
+{
+  g_return_val_if_fail (PANGO_IS_FONT_FACE (face), NULL);
+
+  return PANGO_FONT_FACE_GET_CLASS (face)->create_font (face, desc, dpi, matrix);
+}
+
diff --git a/pango/pango-font-face.h b/pango/pango-font-face.h
index ac666c9b..64e55efb 100644
--- a/pango/pango-font-face.h
+++ b/pango/pango-font-face.h
@@ -46,11 +46,16 @@ PANGO_AVAILABLE_IN_1_46
 PangoFontFamily *       pango_font_face_get_family     (PangoFontFace  *face);
 
 PANGO_AVAILABLE_IN_ALL
-gboolean              pango_font_face_supports_language (PangoFontFace *face,
-                                                         PangoLanguage *language);
+gboolean                pango_font_face_supports_language
+                                                       (PangoFontFace  *face,
+                                                        PangoLanguage  *language);
 
 PANGO_AVAILABLE_IN_ALL
-PangoLanguage **      pango_font_face_get_languages     (PangoFontFace *face);
+PangoLanguage **        pango_font_face_get_languages  (PangoFontFace  *face);
+
+PANGO_AVAILABLE_IN_ALL
+gboolean                pango_font_face_has_char       (PangoFontFace  *face,
+                                                        gunichar        wc);
 
 
 G_END_DECLS
diff --git a/pango/pango-generic-family-private.h b/pango/pango-generic-family-private.h
index 5584e935..7ad767ee 100644
--- a/pango/pango-generic-family-private.h
+++ b/pango/pango-generic-family-private.h
@@ -30,13 +30,13 @@ struct _PangoGenericFamily
 
   PangoFontMap *map;
   char *name;
+
+  /* up to here shared with PangoHbFamily */
+
   GPtrArray *families;
 };
 
 
-void                    pango_generic_family_set_font_map       (PangoGenericFamily      *self,
-                                                                 PangoFontMap            *map);
-
 PangoFontFace *         pango_generic_family_find_face          (PangoGenericFamily     *self,
                                                                  PangoFontDescription   *description,
                                                                  PangoLanguage          *language,
diff --git a/pango/pango-generic-family.c b/pango/pango-generic-family.c
index 586310de..99e3dc1a 100644
--- a/pango/pango-generic-family.c
+++ b/pango/pango-generic-family.c
@@ -166,26 +166,6 @@ pango_generic_family_class_init (PangoGenericFamilyClass *class)
 /* }}} */
 /* {{{ Private API */
 
-/*< private >
- * pango_generic_family_set_font_map:
- * @self: a `PangoGenericFamily`
- * @map: (nullable): a `PangoFontMap`
- *
- * Sets the map of @self.
- */
-void
-pango_generic_family_set_font_map (PangoGenericFamily *self,
-                                   PangoFontMap       *map)
-{
-  if (self->map)
-    g_object_remove_weak_pointer (G_OBJECT (self->map), (gpointer *)&self->map);
-
-  self->map = map;
-
-  if (self->map)
-    g_object_add_weak_pointer (G_OBJECT (self->map), (gpointer *)&self->map);
-}
-
 /*< private >
  * pango_generic_family_find_face:
  * @family: a `PangoGenericFamily`
diff --git a/pango/pango-hbface-private.h b/pango/pango-hbface-private.h
index 71a95ac4..e523cbe1 100644
--- a/pango/pango-hbface-private.h
+++ b/pango/pango-hbface-private.h
@@ -62,9 +62,6 @@ struct _PangoHbFace
   gboolean synthetic;
 };
 
-void                    pango_hb_face_set_family        (PangoHbFace          *self,
-                                                         PangoFontFamily      *family);
-
 PangoLanguageSet *      pango_hb_face_get_language_set  (PangoHbFace          *self);
 
 void                    pango_hb_face_set_language_set  (PangoHbFace          *self,
@@ -72,8 +69,3 @@ void                    pango_hb_face_set_language_set  (PangoHbFace          *s
 
 void                    pango_hb_face_set_matrix        (PangoHbFace          *self,
                                                          const PangoMatrix    *matrix);
-
-gboolean                pango_hb_face_has_char          (PangoHbFace          *self,
-                                                         gunichar              wc);
-
-const char *            pango_hb_face_get_faceid        (PangoHbFace          *self);
diff --git a/pango/pango-hbface.c b/pango/pango-hbface.c
index 1410d00e..6330822d 100644
--- a/pango/pango-hbface.c
+++ b/pango/pango-hbface.c
@@ -22,6 +22,7 @@
 
 #include "pango-font-private.h"
 #include "pango-hbface-private.h"
+#include "pango-hbfont.h"
 
 #include "pango-language-set-simple-private.h"
 
@@ -211,25 +212,50 @@ hb_face_is_monospace (hb_face_t *face)
   return res;
 }
 
-static void
-ensure_psname (PangoHbFace *self)
-{
-  char *p;
+ static void
+ensure_faceid (PangoHbFace *self)
+ {
+  double slant;
+  char buf0[32], buf1[32], buf2[32];
+  char *str = NULL;
+  char *psname;
+   char *p;
 
-  if (self->psname)
+  if (self->faceid)
     return;
 
   ensure_hb_face (self);
 
-  self->psname = get_name_from_hb_face (self->face, HB_OT_NAME_ID_POSTSCRIPT_NAME, HB_OT_NAME_ID_INVALID);
+  psname = get_name_from_hb_face (self->face, HB_OT_NAME_ID_POSTSCRIPT_NAME, HB_OT_NAME_ID_INVALID);
 
   /* PostScript name should not contain problematic chars, but just in case,
    * make sure we don't have any ' ', '=' or ',' that would give us parsing
    * problems.
    */
-  p = self->psname;
+  p = psname;
   while ((p = strpbrk (p, " =,")) != NULL)
     *p = '?';
+
+  if (self->matrix)
+    slant = pango_matrix_get_slant_ratio (self->matrix);
+  else
+    slant = 0.;
+
+  if (self->n_variations > 0)
+    str = variations_to_string (self->variations, self->n_variations, "_", ":");
+
+  self->faceid = g_strdup_printf ("hb:%s:%u:%d:%d:%s:%s:%s%s%s",
+                                  psname,
+                                  self->index,
+                                  self->instance_id,
+                                  self->embolden,
+                                  g_ascii_formatd (buf0, sizeof (buf0), "%g", self->x_scale),
+                                  g_ascii_formatd (buf1, sizeof (buf1), "%g", self->y_scale),
+                                  g_ascii_formatd (buf2, sizeof (buf2), "%g", slant),
+                                  self->n_variations > 0 ? ":" : "",
+                                  self->n_variations > 0 ? str : "");
+  g_free (str);
+  g_free (psname);
 }
 
 static const char *
@@ -315,7 +341,10 @@ pango_hb_face_describe (PangoFontFace *face)
   PangoHbFace *self = PANGO_HB_FACE (face);
 
   if ((pango_font_description_get_set_fields (self->description) & PANGO_FONT_MASK_FACEID) == 0)
-    pango_font_description_set_faceid (self->description, pango_hb_face_get_faceid (self));
+    {
+      ensure_faceid (self);
+      pango_font_description_set_faceid (self->description, self->faceid);
+    }
 
   return pango_font_description_copy (self->description);
 }
@@ -391,6 +420,45 @@ pango_hb_face_get_languages (PangoFontFace *face)
   return NULL;
 }
 
+static gboolean
+pango_hb_face_has_char (PangoFontFace *face,
+                        gunichar       wc)
+{
+  PangoHbFace *self = PANGO_HB_FACE (face);
+  hb_font_t *hb_font;
+  hb_codepoint_t glyph;
+  gboolean ret;
+
+  ensure_hb_face (self);
+
+  hb_font = hb_font_create (self->face);
+  ret = hb_font_get_nominal_glyph (hb_font, wc, &glyph);
+  hb_font_destroy (hb_font);
+
+  return ret;
+}
+
+static const char *
+pango_hb_face_get_faceid (PangoFontFace *face)
+{
+  PangoHbFace *self = PANGO_HB_FACE (face);
+
+  ensure_faceid (self);
+
+  return self->faceid;
+}
+
+static PangoFont *
+pango_hb_face_create_font (PangoFontFace              *face,
+                           const PangoFontDescription *desc,
+                           float                       dpi,
+                           const PangoMatrix          *matrix)
+{
+  PangoHbFace *self = PANGO_HB_FACE (face);
+
+  return PANGO_FONT (pango_hb_font_new_for_description (self, desc, dpi, matrix));
+}
+
 static void
 pango_hb_face_class_init (PangoHbFaceClass *class)
 {
@@ -407,27 +475,14 @@ pango_hb_face_class_init (PangoHbFaceClass *class)
   face_class->is_variable = pango_hb_face_is_variable;
   face_class->supports_language = pango_hb_face_supports_language;
   face_class->get_languages = pango_hb_face_get_languages;
+  face_class->has_char = pango_hb_face_has_char;
+  face_class->get_faceid = pango_hb_face_get_faceid;
+  face_class->create_font = pango_hb_face_create_font;
 }
 
 /* }}} */
 /* {{{ Private API */
 
-/*< private >
- * pango_hb_face_set_family:
- * @self: a `PangoHbFace`
- * @family: a `PangoFontFamily`
- *
- * Sets the font family of a `PangoHbFace`.
- *
- * This should only be called by fontmap implementations.
- */
-void
-pango_hb_face_set_family (PangoHbFace     *self,
-                          PangoFontFamily *family)
-{
-  self->family = family;
-}
-
 /*< private >
  * pango_hb_face_get_language_set:
  * @face: a `PangoHbFace`
@@ -480,96 +535,6 @@ pango_hb_face_set_matrix (PangoHbFace       *self,
   pango_matrix_scale (self->matrix, 1./self->x_scale, 1./self->y_scale);
 }
 
-/*< private >
- * pango_hb_face_has_char:
- * @self: a `PangoHbFace`
- * @wc: a Unicode character
- *
- * Returns whether the face provides a glyph for this character.
- *
- * Returns: `TRUE` if @font can render @wc
- */
-gboolean
-pango_hb_face_has_char (PangoHbFace *self,
-                        gunichar     wc)
-{
-  hb_font_t *hb_font;
-  hb_codepoint_t glyph;
-  gboolean ret;
-
-  ensure_hb_face (self);
-
-  hb_font = hb_font_create (self->face);
-  ret = hb_font_get_nominal_glyph (hb_font, wc, &glyph);
-  hb_font_destroy (hb_font);
-
-  return ret;
-}
-
-/*< private >
- * pango_hb_face_get_faceid:
- * @self: a `PangoHbFace`
- *
- * Returns the faceid of the face.
- *
- * The faceid is meant to uniquely identify the face among the
- * faces of its family. It includes an identifier for the font
- * file that is used (currently, we use the PostScript name for
- * this), the face index, the instance ID, as well as synthetic
- * tweaks such as emboldening and transforms and variations.
- *
- * [method@Pango.FontFace.describe] adds the faceid to the font
- * description that it produces.
- *
- * See pango_hb_family_find_face() for the code that takes the
- * faceid into account when searching for a face. It is careful
- * to fall back to approximate matching if an exact match for
- * the faceid isn't found. That should make it safe to preserve
- * faceids when saving font descriptions in configuration or
- * other data.
- *
- * There are no guarantees about the format of the string that
- * this function produces, except for that it does not contain
- * ' ', ',' or '=', so it can be safely embedded in the '@' part
- * of a serialized font description.
- *
- * Returns: (transfer none): the faceid
- */
-const char *
-pango_hb_face_get_faceid (PangoHbFace *self)
-{
-  if (!self->faceid)
-    {
-      double slant;
-      char buf0[32], buf1[32], buf2[32];
-      char *str = NULL;
-
-      ensure_psname (self);
-
-      if (self->matrix)
-        slant = pango_matrix_get_slant_ratio (self->matrix);
-      else
-        slant = 0.;
-
-      if (self->n_variations > 0)
-        str = variations_to_string (self->variations, self->n_variations, "_", ":");
-
-      self->faceid = g_strdup_printf ("hb:%s:%u:%d:%d:%s:%s:%s%s%s",
-                                      self->psname,
-                                      self->index,
-                                      self->instance_id,
-                                      self->embolden,
-                                      g_ascii_formatd (buf0, sizeof (buf0), "%g", self->x_scale),
-                                      g_ascii_formatd (buf1, sizeof (buf1), "%g", self->y_scale),
-                                      g_ascii_formatd (buf2, sizeof (buf2), "%g", slant),
-                                      self->n_variations > 0 ? ":" : "",
-                                      self->n_variations > 0 ? str : "");
-      g_free (str);
-    }
-
-  return self->faceid;
-}
-
 /* }}} */
  /* {{{ Public API */
 
diff --git a/pango/pango-hbfamily-private.h b/pango/pango-hbfamily-private.h
index bf5545b8..c99a9762 100644
--- a/pango/pango-hbfamily-private.h
+++ b/pango/pango-hbfamily-private.h
@@ -27,20 +27,29 @@
 
 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;
 };
 
 PangoHbFamily *         pango_hb_family_new             (const char             *name);
 
-void                    pango_hb_family_set_font_map    (PangoHbFamily          *self,
-                                                         PangoFontMap           *map);
-
 void                    pango_hb_family_add_face        (PangoHbFamily          *self,
                                                          PangoFontFace          *face);
 
diff --git a/pango/pango-hbfamily.c b/pango/pango-hbfamily.c
index 05edcefb..66ea27e2 100644
--- a/pango/pango-hbfamily.c
+++ b/pango/pango-hbfamily.c
@@ -68,35 +68,6 @@ pango_hb_family_list_model_init (GListModelInterface *iface)
 /* }}} */
 /* {{{ Utilities */
 
-static void
-face_set_family (PangoFontFace   *face,
-                 PangoFontFamily *family)
-{
-  if (PANGO_IS_HB_FACE (face))
-    pango_hb_face_set_family (PANGO_HB_FACE (face), family);
-  else
-    pango_user_face_set_family (PANGO_USER_FACE (face), family);
-}
-
-static const char *
-face_get_faceid (PangoFontFace *face)
-{
-  if (PANGO_IS_HB_FACE (face))
-    return pango_hb_face_get_faceid (PANGO_HB_FACE (face));
-  else
-    return pango_user_face_get_faceid (PANGO_USER_FACE (face));
-}
-
-static gboolean
-face_has_char (PangoFontFace *face,
-               gunichar       wc)
-{
-  if (PANGO_IS_HB_FACE (face))
-    return pango_hb_face_has_char (PANGO_HB_FACE (face), wc);
-  else
-    return pango_user_face_has_char (PANGO_USER_FACE (face), wc);
-}
-
 static int
 sort_face_func (PangoFontFace *face1,
                 PangoFontFace *face2)
@@ -262,26 +233,6 @@ pango_hb_family_new (const char *name)
   return self;
 }
 
-/*< private >
- * pango_hb_family_set_font_map:
- * @self: a `PangoHbFamily`
- * @map: (nullable): a `PangoFontMap`
- *
- * Sets the map of @self.
- G*/
-void
-pango_hb_family_set_font_map (PangoHbFamily *self,
-                              PangoFontMap  *map)
-{
-  if (self->map)
-    g_object_remove_weak_pointer (G_OBJECT (self->map), (gpointer *)&self->map);
-
-  self->map = map;
-
-  if (self->map)
-    g_object_add_weak_pointer (G_OBJECT (self->map), (gpointer *)&self->map);
-}
-
 /*< private >
  * pango_hb_family_add_face:
  * @self: a `PangoHbFamily`
@@ -313,7 +264,7 @@ pango_hb_family_add_face (PangoHbFamily *self,
 
   g_ptr_array_insert (self->faces, position, face);
 
-  face_set_family (face, PANGO_FONT_FAMILY (self));
+  ((CommonFace *)face)->family = PANGO_FONT_FAMILY (self);
 
   g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);
 }
@@ -336,7 +287,7 @@ pango_hb_family_remove_face (PangoHbFamily *self,
   if (!g_ptr_array_find (self->faces, face, &position))
     return;
 
-  face_set_family (face, NULL);
+  ((CommonFace *)face)->family = NULL;
 
   g_ptr_array_remove_index (self->faces, position);
 
@@ -377,7 +328,7 @@ pango_hb_family_find_face (PangoHbFamily        *family,
       for (int i = 0; i < family->faces->len; i++)
         {
           PangoFontFace *face2 = g_ptr_array_index (family->faces, i);
-          const char *faceid2 = face_get_faceid (face2);
+          const char *faceid2 = pango_font_face_get_faceid (face2);
 
           if (g_strcmp0 (faceid, faceid2) == 0)
             return face2;
@@ -393,7 +344,7 @@ pango_hb_family_find_face (PangoHbFamily        *family,
       if (language && !pango_font_face_supports_language (face2, language))
         continue;
 
-      if (wc && !face_has_char (face2, wc))
+      if (wc && !pango_font_face_has_char (face2, wc))
         continue;
 
       if (!pango_font_description_is_similar (description, ((CommonFace *)face2)->description))
diff --git a/pango/pango-hbfontmap.c b/pango/pango-hbfontmap.c
index d5b83c82..89f80a30 100644
--- a/pango/pango-hbfontmap.c
+++ b/pango/pango-hbfontmap.c
@@ -32,6 +32,7 @@
 #include "pango-userface-private.h"
 #include "pango-userfont-private.h"
 #include "pango-fontset.h"
+#include "pango-font-face-private.h"
 #include "pango-trace-private.h"
 #include "pango-context.h"
 
@@ -155,18 +156,6 @@ pango_fontset_cached_finalize (GObject *object)
   G_OBJECT_CLASS (pango_fontset_cached_parent_class)->finalize (object);
 }
 
-static PangoFont *
-font_new_for_description (PangoFontFace              *face,
-                          const PangoFontDescription *description,
-                          float                       dpi,
-                          const PangoMatrix          *matrix)
-{
-  if (PANGO_IS_HB_FACE (face))
-    return PANGO_FONT (pango_hb_font_new_for_description (PANGO_HB_FACE (face), description, dpi, matrix));
-  else
-    return PANGO_FONT (pango_user_font_new_for_description (PANGO_USER_FACE (face), description, dpi, 
matrix));
-}
-
 static PangoFont *
 pango_fontset_cached_get_font (PangoFontset *fontset,
                                guint         wc)
@@ -207,10 +196,10 @@ pango_fontset_cached_get_font (PangoFontset *fontset,
                                                  wc);
           if (face)
             {
-              retval = font_new_for_description (face,
-                                                 self->description,
-                                                 self->dpi,
-                                                 self->matrix);
+              retval = pango_font_face_create_font (face,
+                                                    self->description,
+                                                    self->dpi,
+                                                    self->matrix);
               break;
             }
         }
@@ -234,7 +223,7 @@ pango_fontset_cached_get_first_font (PangoFontsetCached *self)
   else if (PANGO_IS_GENERIC_FAMILY (item))
     {
       PangoFontFace *face = pango_generic_family_find_face (PANGO_GENERIC_FAMILY (item), self->description, 
self->language, 0);
-      return font_new_for_description (face, self->description, self->dpi, self->matrix);
+      return pango_font_face_create_font (face, self->description, self->dpi, self->matrix);
     }
 
   return NULL;
@@ -287,7 +276,7 @@ pango_fontset_cached_foreach (PangoFontset            *fontset,
       else if (PANGO_IS_GENERIC_FAMILY (item))
         {
           PangoFontFace *face = pango_generic_family_find_face (PANGO_GENERIC_FAMILY (item), 
self->description, self->language, 0);
-          font = font_new_for_description (face, self->description, self->dpi, self->matrix);
+          font = pango_font_face_create_font (face, self->description, self->dpi, self->matrix);
         }
 
       if ((*func) (fontset, font, data))
@@ -334,18 +323,11 @@ static void
 pango_fontset_cached_add_face (PangoFontsetCached *self,
                                PangoFontFace      *face)
 {
-  if (PANGO_IS_HB_FACE (face))
-    g_ptr_array_add (self->items,
-                     pango_hb_font_new_for_description (PANGO_HB_FACE (face),
-                                                        self->description,
-                                                        self->dpi,
-                                                        self->matrix));
-  else
-    g_ptr_array_add (self->items,
-                     pango_user_font_new_for_description (PANGO_USER_FACE (face),
-                                                          self->description,
-                                                          self->dpi,
-                                                          self->matrix));
+  g_ptr_array_add (self->items,
+                   pango_font_face_create_font (face,
+                                                self->description,
+                                                self->dpi,
+                                                self->matrix));
 }
 
 static void
@@ -870,10 +852,7 @@ pango_hb_font_map_add_face (PangoHbFontMap *self,
 
   g_return_if_fail (PANGO_IS_HB_FACE (face) || PANGO_IS_USER_FACE (face));
 
-  if (PANGO_IS_HB_FACE (face))
-    description = PANGO_HB_FACE (face)->description;
-  else
-    description = PANGO_USER_FACE (face)->description;
+  description = ((CommonFace *)face)->description;
 
   if (pango_font_description_get_set_fields (description) &
       (PANGO_FONT_MASK_VARIANT | PANGO_FONT_MASK_GRAVITY))
@@ -973,25 +952,24 @@ pango_hb_font_map_add_family (PangoHbFontMap  *self,
   int position;
 
   g_return_if_fail (PANGO_IS_HB_FAMILY (family) || PANGO_IS_GENERIC_FAMILY (family));
+  g_return_if_fail (((CommonFamily *)family)->map == NULL);
 
   if (!self->in_populate)
     g_ptr_array_add (self->added_families, g_object_ref (family));
 
-  name = pango_font_family_get_name (PANGO_FONT_FAMILY (family));
+  name = ((CommonFamily *)family)->name;
 
   position = 0;
   while (position < self->families->len)
     {
       PangoFontFamily *f = g_ptr_array_index (self->families, position);
-      if (g_ascii_strcasecmp (name, pango_font_family_get_name (f)) < 0)
+      if (g_ascii_strcasecmp (name, ((CommonFamily *)f)->name) < 0)
         break;
       position++;
     }
 
-  if (PANGO_IS_HB_FAMILY (family))
-    pango_hb_family_set_font_map (PANGO_HB_FAMILY (family), PANGO_FONT_MAP (self));
-  else
-    pango_generic_family_set_font_map (PANGO_GENERIC_FAMILY (family), PANGO_FONT_MAP (self));
+  ((CommonFamily *)family)->map = PANGO_FONT_MAP (self);
+  g_object_add_weak_pointer (G_OBJECT (self), (gpointer *)&((CommonFamily *)family)->map);
 
   g_ptr_array_insert (self->families, position, family);
   g_hash_table_add (self->families_hash, family);
@@ -1016,6 +994,7 @@ pango_hb_font_map_remove_family (PangoHbFontMap  *self,
   unsigned int position;
 
   g_return_if_fail (PANGO_IS_HB_FAMILY (family) || PANGO_IS_GENERIC_FAMILY (family));
+  g_return_if_fail (((CommonFamily *)family)->map == (PangoFontMap *)self);
 
   if (!g_ptr_array_find (self->added_families, family, &position))
     return;
@@ -1023,10 +1002,8 @@ pango_hb_font_map_remove_family (PangoHbFontMap  *self,
   g_hash_table_remove (self->families_hash, family);
   g_ptr_array_remove_index (self->families, position);
 
-  if (PANGO_IS_HB_FAMILY (family))
-    pango_hb_family_set_font_map (PANGO_HB_FAMILY (family), NULL);
-  else
-    pango_generic_family_set_font_map (PANGO_GENERIC_FAMILY (family), NULL);
+  g_object_remove_weak_pointer (G_OBJECT (self), (gpointer *)&((CommonFamily *)family)->map);
+  ((CommonFamily *)family)->map = NULL;
 
   if (!self->in_populate)
     g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 0);
diff --git a/pango/pango-userface-private.h b/pango/pango-userface-private.h
index 08787495..8e996293 100644
--- a/pango/pango-userface-private.h
+++ b/pango/pango-userface-private.h
@@ -31,7 +31,6 @@ struct _PangoUserFace
   PangoFontDescription *description;
   char *name;
   PangoFontFamily *family;
-  char *psname;
   char *faceid;
 
   /* up to here shared with PangoHbFace */
@@ -44,11 +43,3 @@ struct _PangoUserFace
   gpointer user_data;
   GDestroyNotify destroy;
 };
-
-void                    pango_user_face_set_family        (PangoUserFace        *self,
-                                                           PangoFontFamily      *family);
-
-gboolean                pango_user_face_has_char          (PangoUserFace        *self,
-                                                           gunichar              wc);
-
-const char *            pango_user_face_get_faceid        (PangoUserFace        *self);
diff --git a/pango/pango-userface.c b/pango/pango-userface.c
index 5899d8b5..bfe1755d 100644
--- a/pango/pango-userface.c
+++ b/pango/pango-userface.c
@@ -45,22 +45,27 @@
  /* {{{ Utilities */
 
 static void
-ensure_psname (PangoUserFace *self)
+ensure_faceid (PangoUserFace *self)
 {
+  char *psname;
   char *p;
 
-  if (self->psname)
+  if (self->faceid)
     return;
 
-  self->psname = g_strconcat (pango_font_description_get_family (self->description), "_", self->name, NULL);
+  psname = g_strconcat (pango_font_description_get_family (self->description), "_", self->name, NULL);
 
   /* PostScript name should not contain problematic chars, but just in case,
    * make sure we don't have any ' ', '=' or ',' that would give us parsing
    * problems.
    */
-  p = self->psname;
+  p = psname;
   while ((p = strpbrk (p, " =,")) != NULL)
     *p = '?';
+
+  self->faceid = g_strconcat ("user:", psname, NULL);
+
+  g_free (psname);
 }
 
 static const char *
@@ -216,7 +221,10 @@ pango_user_face_describe (PangoFontFace *face)
   PangoUserFace *self = PANGO_USER_FACE (face);
 
   if ((pango_font_description_get_set_fields (self->description) & PANGO_FONT_MASK_FACEID) == 0)
-    pango_font_description_set_faceid (self->description, pango_user_face_get_faceid (self));
+    {
+      ensure_faceid (self);
+      pango_font_description_set_faceid (self->description, self->faceid);
+    }
 
   return pango_font_description_copy (self->description);
 }
@@ -247,6 +255,37 @@ pango_user_face_is_variable (PangoFontFace *face)
   return FALSE;
 }
 
+static gboolean
+pango_user_face_has_char (PangoFontFace *face,
+                          gunichar       wc)
+{
+  PangoUserFace *self = PANGO_USER_FACE (face);
+  hb_codepoint_t glyph;
+
+  return self->glyph_func (self, wc, &glyph, self->user_data);
+}
+
+static const char *
+pango_user_face_get_faceid (PangoFontFace *face)
+{
+  PangoUserFace *self = PANGO_USER_FACE (face);
+
+  ensure_faceid (self);
+
+  return self->faceid;
+}
+
+static PangoFont *
+pango_user_face_create_font (PangoFontFace              *face,
+                             const PangoFontDescription *desc,
+                             float                       dpi,
+                             const PangoMatrix          *matrix)
+{
+  PangoUserFace *self = PANGO_USER_FACE (face);
+
+  return PANGO_FONT (pango_user_font_new_for_description (self, desc, dpi, matrix));
+}
+
 static void
 pango_user_face_class_init (PangoUserFaceClass *class)
 {
@@ -261,63 +300,9 @@ pango_user_face_class_init (PangoUserFaceClass *class)
   face_class->get_family = pango_user_face_get_family;
   face_class->is_monospace = pango_user_face_is_monospace;
   face_class->is_variable = pango_user_face_is_variable;
-}
-
-/* }}} */
-/* {{{ Private API */
-
-/*< private >
- * pango_user_face_set_family:
- * @self: a `PangoUserFace`
- * @family: a `PangoFontFamily`
- *
- * Sets the font family of a `PangoUserFace`.
- *
- * This should only be called by fontmap implementations.
- */
-void
-pango_user_face_set_family (PangoUserFace   *self,
-                            PangoFontFamily *family)
-{
-  self->family = family;
-}
-
-/*< private >
- * pango_user_face_has_char:
- * @self: a `PangoUserFace`
- * @wc: a Unicode character
- *
- * Returns whether the face provides a glyph for this character.
- *
- * Returns: `TRUE` if @font can render @wc
- */
-gboolean
-pango_user_face_has_char (PangoUserFace *self,
-                          gunichar     wc)
-{
-  hb_codepoint_t glyph;
-
-  return self->glyph_func (self, wc, &glyph, self->user_data);
-}
-
-/*< private >
- * pango_user_face_get_faceid:
- * @self: a `PangoUserFace`
- *
- * Returns the faceid of the face.
- *
- * Returns: (transfer none): the faceid
- */
-const char *
-pango_user_face_get_faceid (PangoUserFace *self)
-{
-  if (!self->faceid)
-    {
-      ensure_psname (self);
-      self->faceid = g_strconcat ("user:", self->psname, NULL);
-    }
-
-  return self->faceid;
+  face_class->has_char = pango_user_face_has_char;
+  face_class->get_faceid = pango_user_face_get_faceid;
+  face_class->create_font = pango_user_face_create_font;
 }
 
 /* }}} */


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