[pango/redo-attrs: 7/13] Share more code between hbface and userface




commit d58342a37e90580cca7d2e55396291ee4af84407
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Jan 28 20:21:52 2022 -0500

    Share more code between hbface and userface
    
    Move some things as private api into PangoFontFace.

 pango/fonts.c                        |  99 +++++++++++++++++++
 pango/pango-coverage-private.h       |   6 +-
 pango/pango-coverage.c               |  10 +-
 pango/pango-font-private.h           |  12 +++
 pango/pango-font.h                   |   3 +
 pango/pango-generic-family-private.h |   6 +-
 pango/pango-generic-family.c         |  20 ----
 pango/pango-hbface-private.h         |  10 --
 pango/pango-hbface.c                 | 187 ++++++++++++++---------------------
 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 +++++++++-----------
 pango/pango-userfont.c               |   2 +-
 15 files changed, 287 insertions(+), 323 deletions(-)
---
diff --git a/pango/fonts.c b/pango/fonts.c
index 89607683..cec78486 100644
--- a/pango/fonts.c
+++ b/pango/fonts.c
@@ -2766,6 +2766,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)
 {
@@ -2778,6 +2800,9 @@ pango_font_face_class_init (PangoFontFaceClass *class G_GNUC_UNUSED)
 
   pclass->get_languages = pango_font_face_default_get_languages;
   pclass->supports_language = pango_font_face_default_supports_language;
+  pclass->has_char = pango_font_face_default_has_char;
+  pclass->get_faceid = pango_font_face_default_get_faceid;
+  pclass->create_font = pango_font_face_default_create_font;
 }
 
 static void
@@ -3001,6 +3026,80 @@ pango_font_face_get_languages (PangoFontFace *face)
   return pclass->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
+ *
+ * Since: 1.44
+ */
+gboolean
+pango_font_face_has_char (PangoFontFace *face,
+                          gunichar       wc)
+{
+  PangoFontFaceClassPrivate *pclass = PANGO_FONT_FACE_GET_CLASS_PRIVATE (face);
+
+  g_return_val_if_fail (PANGO_IS_FONT_FACE (face), FALSE);
+
+  return pclass->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)
+{
+  PangoFontFaceClassPrivate *pclass = PANGO_FONT_FACE_GET_CLASS_PRIVATE (face);
+
+  g_return_val_if_fail (PANGO_IS_FONT_FACE (face), "");
+
+  return pclass->get_faceid (face);
+}
+
+PangoFont *
+pango_font_face_create_font (PangoFontFace              *face,
+                             const PangoFontDescription *desc,
+                             float                       dpi,
+                             const PangoMatrix          *matrix)
+{
+  PangoFontFaceClassPrivate *pclass = PANGO_FONT_FACE_GET_CLASS_PRIVATE (face);
+
+  g_return_val_if_fail (PANGO_IS_FONT_FACE (face), NULL);
+
+  return pclass->create_font (face, desc, dpi, matrix);
+}
+
 /**
  * pango_font_has_char:
  * @font: a `PangoFont`
diff --git a/pango/pango-coverage-private.h b/pango/pango-coverage-private.h
index a156913b..59f24a77 100644
--- a/pango/pango-coverage-private.h
+++ b/pango/pango-coverage-private.h
@@ -43,7 +43,7 @@ struct _PangoCoverage
   GObject parent_instance;
 
   hb_set_t *chars;
-  PangoUserFace *face;
+  PangoFontFace *face;
 };
 
 struct _PangoCoverageClass
@@ -58,8 +58,8 @@ struct _PangoCoverageClass
   PangoCoverage *    (* copy) (PangoCoverage      *coverage);
 };
 
-PangoCoverage *pango_coverage_new_for_hb_face (hb_face_t *hb_face);
-PangoCoverage *pango_coverage_new_for_user_face (PangoUserFace *face);
+PangoCoverage *pango_coverage_new_for_hb_face (hb_face_t     *hb_face);
+PangoCoverage *pango_coverage_new_for_face    (PangoFontFace *face);
 
 G_END_DECLS
 
diff --git a/pango/pango-coverage.c b/pango/pango-coverage.c
index d7b5b2a8..93d51922 100644
--- a/pango/pango-coverage.c
+++ b/pango/pango-coverage.c
@@ -38,10 +38,8 @@ pango_coverage_finalize (GObject *object)
 {
   PangoCoverage *coverage = PANGO_COVERAGE (object);
 
-  if (coverage->chars)
-    hb_set_destroy (coverage->chars);
-  if (coverage->face)
-    g_object_unref (coverage->face);
+  g_clear_pointer (&coverage->chars, hb_set_destroy);
+  g_clear_object (&coverage->face);
 
   G_OBJECT_CLASS (pango_coverage_parent_class)->finalize (object);
 }
@@ -52,7 +50,7 @@ pango_coverage_real_get (PangoCoverage *coverage,
 {
   if (coverage->face)
     {
-      if (pango_user_face_has_char (coverage->face, index))
+      if (pango_font_face_has_char (coverage->face, index))
         return PANGO_COVERAGE_EXACT;
       else
        return PANGO_COVERAGE_NONE;
@@ -158,7 +156,7 @@ pango_coverage_new_for_hb_face (hb_face_t *hb_face)
 }
 
 PangoCoverage *
-pango_coverage_new_for_user_face (PangoUserFace *face)
+pango_coverage_new_for_face (PangoFontFace *face)
 {
   PangoCoverage *coverage;
 
diff --git a/pango/pango-font-private.h b/pango/pango-font-private.h
index 92647e86..123721dd 100644
--- a/pango/pango-font-private.h
+++ b/pango/pango-font-private.h
@@ -37,11 +37,23 @@ typedef struct {
   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);
 } PangoFontFaceClassPrivate;
 
 #define PANGO_FONT_FACE_GET_CLASS_PRIVATE(font) ((PangoFontFaceClassPrivate *) \
    g_type_class_get_private ((GTypeClass *) PANGO_FONT_FACE_GET_CLASS (font), PANGO_TYPE_FONT_FACE))
 
+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);
 
 typedef struct {
   gboolean         (* is_hinted) (PangoFont *font);
diff --git a/pango/pango-font.h b/pango/pango-font.h
index f4824c80..8d83be34 100644
--- a/pango/pango-font.h
+++ b/pango/pango-font.h
@@ -552,6 +552,9 @@ gboolean              pango_font_face_supports_language (PangoFontFace *face,
 PANGO_AVAILABLE_IN_1_52
 PangoLanguage **      pango_font_face_get_languages     (PangoFontFace *face);
 
+PANGO_AVAILABLE_IN_1_52
+gboolean              pango_font_face_has_char          (PangoFontFace *face,
+                                                         gunichar       wc);
 
 
 /*
diff --git a/pango/pango-generic-family-private.h b/pango/pango-generic-family-private.h
index 78e17610..82d7d769 100644
--- a/pango/pango-generic-family-private.h
+++ b/pango/pango-generic-family-private.h
@@ -31,13 +31,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 fd555eab..4b91fd2e 100644
--- a/pango/pango-generic-family.c
+++ b/pango/pango-generic-family.c
@@ -100,26 +100,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 b1118006..965edf80 100644
--- a/pango/pango-hbface-private.h
+++ b/pango/pango-hbface-private.h
@@ -32,7 +32,6 @@ struct _CommonFace {
   PangoFontDescription *description;
   char *name;
   PangoFontFamily *family;
-  char *psname;
   char *faceid;
 };
 
@@ -43,7 +42,6 @@ struct _PangoHbFace
   PangoFontDescription *description;
   char *name;
   PangoFontFamily *family;
-  char *psname;
   char *faceid;
 
   /* up to here shared with PangoUserFace */
@@ -61,9 +59,6 @@ struct _PangoHbFace
   gboolean synthetic;
 };
 
-void                    pango_hb_face_set_family        (PangoHbFace          *self,
-                                                         PangoFontFamily      *family);
-
 PangoLanguageSet *      pango_hb_face_get_language_set  (PangoHbFace          *self);
 
 PANGO_AVAILABLE_IN_1_52
@@ -73,8 +68,3 @@ void                    pango_hb_face_set_language_set  (PangoHbFace          *s
 PANGO_AVAILABLE_IN_1_52
 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 5adc1061..9b2df6ca 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"
 
@@ -209,24 +210,49 @@ hb_face_is_monospace (hb_face_t *face)
 }
 
 static void
-ensure_psname (PangoHbFace *self)
+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 *
@@ -312,7 +338,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);
 }
@@ -388,6 +417,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)
 {
@@ -409,27 +477,14 @@ pango_hb_face_class_init (PangoHbFaceClass *class)
 
   pclass->supports_language = pango_hb_face_supports_language;
   pclass->get_languages = pango_hb_face_get_languages;
+  pclass->has_char = pango_hb_face_has_char;
+  pclass->get_faceid = pango_hb_face_get_faceid;
+  pclass->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`
@@ -482,96 +537,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 40f9232a..3f4be52d 100644
--- a/pango/pango-hbfamily-private.h
+++ b/pango/pango-hbfamily-private.h
@@ -27,21 +27,30 @@
 PANGO_AVAILABLE_IN_1_52
 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;
 };
 
 PANGO_AVAILABLE_IN_1_52
 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 ebed6200..dd2e8ca8 100644
--- a/pango/pango-hbfamily.c
+++ b/pango/pango-hbfamily.c
@@ -67,35 +67,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)
@@ -276,26 +247,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`
@@ -327,7 +278,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);
 }
@@ -350,7 +301,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);
 
@@ -391,7 +342,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;
@@ -407,7 +358,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 db7bd8a8..87fc4db1 100644
--- a/pango/pango-hbfontmap.c
+++ b/pango/pango-hbfontmap.c
@@ -31,6 +31,7 @@
 #include "pango-userface-private.h"
 #include "pango-userfont-private.h"
 #include "pango-fontset.h"
+#include "pango-font-private.h"
 #include "pango-trace-private.h"
 #include "pango-context.h"
 
@@ -154,18 +155,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)
@@ -206,10 +195,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;
             }
         }
@@ -233,7 +222,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;
@@ -286,7 +275,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))
@@ -333,18 +322,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
@@ -884,10 +866,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))
@@ -991,25 +970,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);
@@ -1034,6 +1012,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;
@@ -1041,10 +1020,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 8465036e..de5c2d1d 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 63b9ac1f..9b3c4f49 100644
--- a/pango/pango-userface.c
+++ b/pango/pango-userface.c
@@ -38,22 +38,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 *
@@ -209,7 +214,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);
 }
@@ -240,11 +248,43 @@ 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)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (class);
   PangoFontFaceClass *face_class = PANGO_FONT_FACE_CLASS (class);
+  PangoFontFaceClassPrivate *pclass;
 
   object_class->finalize = pango_user_face_finalize;
 
@@ -255,63 +295,12 @@ 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 */
+  pclass = g_type_class_get_private ((GTypeClass *) class, PANGO_TYPE_FONT_FACE);
 
-/*< 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;
+  pclass->has_char = pango_user_face_has_char;
+  pclass->get_faceid = pango_user_face_get_faceid;
+  pclass->create_font = pango_user_face_create_font;
 }
 
 /* }}} */
diff --git a/pango/pango-userfont.c b/pango/pango-userfont.c
index 10ccea13..68aac711 100644
--- a/pango/pango-userfont.c
+++ b/pango/pango-userfont.c
@@ -94,7 +94,7 @@ pango_user_font_get_coverage (PangoFont     *font,
 {
   PangoUserFont *self = PANGO_USER_FONT (font);
 
-  return pango_coverage_new_for_user_face (self->face);
+  return pango_coverage_new_for_face (PANGO_FONT_FACE (self->face));
 }
 
 static void


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