[pango/simple-fontmap: 4/9] Add PangoFcHbFontMap




commit 6541e38a319fcb621decd74b1aa1be4d57b59a8c
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Nov 1 22:04:14 2021 -0400

    Add PangoFcHbFontMap
    
    This is a new fontmap implementation that works by
    populating a PangoHbFontMap from fontconfig data. It
    relies on the base class to provide caching and lookups.
    
    In contrast to the existing fontconfig fontmap, this
    does not include every font in every fontset.

 pango/meson.build         |   1 +
 pango/pangofc-hbfontmap.c | 688 ++++++++++++++++++++++++++++++++++++++++++++++
 pango/pangofc-hbfontmap.h |  41 +++
 3 files changed, 730 insertions(+)
---
diff --git a/pango/meson.build b/pango/meson.build
index 79bc313f..4519973b 100644
--- a/pango/meson.build
+++ b/pango/meson.build
@@ -212,6 +212,7 @@ if build_pangoft2
   pangofc_public_sources = [
     'pangofc-font.c',
     'pangofc-fontmap.c',
+    'pangofc-hbfontmap.c',
     'pangofc-language-set.c',
     'pangofc-decoder.c',
     'pango-trace.c',
diff --git a/pango/pangofc-hbfontmap.c b/pango/pangofc-hbfontmap.c
new file mode 100644
index 00000000..85f04592
--- /dev/null
+++ b/pango/pangofc-hbfontmap.c
@@ -0,0 +1,688 @@
+/* Pango
+ *
+ * Copyright (C) 2021 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include <math.h>
+
+#include <gio/gio.h>
+
+#include "pangofc-hbfontmap.h"
+#include "pango-hbfamily-private.h"
+#include "pango-hbfontmap-private.h"
+#include "pango-hbface-private.h"
+#include "pango-hbfont-private.h"
+#include "pango-context.h"
+#include "pango-impl-utils.h"
+#include "pango-trace-private.h"
+#include "pangofc-language-set-private.h"
+
+#include <fontconfig/fontconfig.h>
+#include <hb-ot.h>
+
+
+/**
+ * PangoFcHbFontMap:
+ *
+ * `PangoFcHbFontMap` is a subclass of `PangoHbFontMap` that uses
+ * fontconfig to populate the fontmap with the available fonts.
+ */
+
+
+/* The maximum number of faces to include in each of the generic aliases */
+
+#define MAX_ALIAS_FACES 20
+
+
+struct _PangoFcHbFontMap
+{
+  PangoHbFontMap parent_instance;
+
+  FcConfig *config;
+};
+
+struct _PangoFcHbFontMapClass
+{
+  PangoHbFontMapClass parent_class;
+};
+
+/* {{{ Utilities */
+
+static PangoHbFace *
+find_face_by_file (PangoFcHbFontMap *self,
+                   const char       *file,
+                   unsigned int      index,
+                   int               instance_id)
+{
+  PangoHbFontMap *simple = PANGO_HB_FONT_MAP (self);
+
+  for (int i = 0; i < simple->families->len; i++)
+    {
+      PangoHbFamily *family = g_ptr_array_index (simple->families, i);
+
+      for (int j = 0; j < family->faces->len; j++)
+        {
+          PangoHbFace *face = g_ptr_array_index (family->faces, j);
+
+          if (face->index == index &&
+              face->instance_id == instance_id &&
+              g_strcmp0 (face->file, file) == 0)
+            return face;
+        }
+    }
+
+  return NULL;
+}
+
+/* }}} */
+/* {{{ Fontconfig utilities */ 
+
+static gboolean
+is_supported_font_format (FcPattern *pattern)
+{
+  FcResult res;
+  const char *fontformat;
+  const char *file;
+
+  /* Harfbuzz loads woff fonts, but we don't get any glyphs */
+  res = FcPatternGetString (pattern, FC_FILE, 0, (FcChar8 **)(void*)&file);
+  if (res == FcResultMatch &&
+      (g_str_has_suffix (file, ".woff") || g_str_has_suffix (file, ".woff2")))
+    return FALSE;
+
+  res = FcPatternGetString (pattern, FC_FONTFORMAT, 0, (FcChar8 **)(void*)&fontformat);
+  if (res != FcResultMatch)
+    return FALSE;
+
+  /* Harfbuzz supports only SFNT fonts */
+
+  /* FIXME: "CFF" is used for both CFF in OpenType and bare CFF files, but
+   * HarfBuzz does not support the later and FontConfig does not seem
+   * to have a way to tell them apart.
+   */
+  if (g_ascii_strcasecmp (fontformat, "TrueType") == 0 ||
+      g_ascii_strcasecmp (fontformat, "CFF") == 0)
+    return TRUE;
+
+  return FALSE;
+}
+
+static PangoStyle
+convert_fc_slant_to_pango (int fc_style)
+{
+  switch (fc_style)
+    {
+    case FC_SLANT_ROMAN:
+      return PANGO_STYLE_NORMAL;
+    case FC_SLANT_ITALIC:
+      return PANGO_STYLE_ITALIC;
+    case FC_SLANT_OBLIQUE:
+      return PANGO_STYLE_OBLIQUE;
+    default:
+      return PANGO_STYLE_NORMAL;
+    }
+}
+
+static PangoStretch
+convert_fc_width_to_pango (int fc_stretch)
+{
+  switch (fc_stretch)
+    {
+    case FC_WIDTH_NORMAL:
+      return PANGO_STRETCH_NORMAL;
+    case FC_WIDTH_ULTRACONDENSED:
+      return PANGO_STRETCH_ULTRA_CONDENSED;
+    case FC_WIDTH_EXTRACONDENSED:
+      return PANGO_STRETCH_EXTRA_CONDENSED;
+    case FC_WIDTH_CONDENSED:
+      return PANGO_STRETCH_CONDENSED;
+    case FC_WIDTH_SEMICONDENSED:
+      return PANGO_STRETCH_SEMI_CONDENSED;
+    case FC_WIDTH_SEMIEXPANDED:
+      return PANGO_STRETCH_SEMI_EXPANDED;
+    case FC_WIDTH_EXPANDED:
+      return PANGO_STRETCH_EXPANDED;
+    case FC_WIDTH_EXTRAEXPANDED:
+      return PANGO_STRETCH_EXTRA_EXPANDED;
+    case FC_WIDTH_ULTRAEXPANDED:
+      return PANGO_STRETCH_ULTRA_EXPANDED;
+    default:
+      return PANGO_STRETCH_NORMAL;
+    }
+}
+
+static PangoWeight
+convert_fc_weight_to_pango (double fc_weight)
+{
+  return FcWeightToOpenTypeDouble (fc_weight);
+}
+
+#define PANGO_FC_GRAVITY "gravity"
+
+/* Create font description that matches the pattern.
+ * We explicitly don't want to include variant, gravity,
+ * variations and font features here, since there are
+ * handled on the font level, by PangoHbFont, not
+ * by PangoHbFace.
+ */
+static PangoFontDescription *
+pango_font_description_from_pattern (FcPattern *pattern,
+                                     gboolean   include_size)
+{
+  PangoFontDescription *desc;
+  PangoStyle style;
+  PangoWeight weight;
+  PangoStretch stretch;
+  double size;
+
+  FcChar8 *s;
+  int i;
+  double d;
+  FcResult res;
+
+  desc = pango_font_description_new ();
+
+  res = FcPatternGetString (pattern, FC_FAMILY, 0, (FcChar8 **) &s);
+  g_assert (res == FcResultMatch);
+
+  pango_font_description_set_family (desc, (gchar *)s);
+
+  if (FcPatternGetInteger (pattern, FC_SLANT, 0, &i) == FcResultMatch)
+    style = convert_fc_slant_to_pango (i);
+  else
+    style = PANGO_STYLE_NORMAL;
+
+  pango_font_description_set_style (desc, style);
+
+  if (FcPatternGetDouble (pattern, FC_WEIGHT, 0, &d) == FcResultMatch)
+    weight = convert_fc_weight_to_pango (d);
+  else
+    weight = PANGO_WEIGHT_NORMAL;
+
+  pango_font_description_set_weight (desc, weight);
+
+  if (FcPatternGetInteger (pattern, FC_WIDTH, 0, &i) == FcResultMatch)
+    stretch = convert_fc_width_to_pango (i);
+  else
+    stretch = PANGO_STRETCH_NORMAL;
+
+  pango_font_description_set_stretch (desc, stretch);
+
+  if (include_size && FcPatternGetDouble (pattern, FC_SIZE, 0, &size) == FcResultMatch)
+    {
+      FcMatrix *fc_matrix;
+      double scale_factor = 1;
+
+      if (FcPatternGetMatrix (pattern, FC_MATRIX, 0, &fc_matrix) == FcResultMatch)
+        {
+          PangoMatrix mat = PANGO_MATRIX_INIT;
+
+          mat.xx = fc_matrix->xx;
+          mat.xy = fc_matrix->xy;
+          mat.yx = fc_matrix->yx;
+          mat.yy = fc_matrix->yy;
+
+          scale_factor = pango_matrix_get_font_scale_factor (&mat);
+        }
+
+      pango_font_description_set_size (desc, scale_factor * size * PANGO_SCALE);
+    }
+
+  return desc;
+}
+
+static const char *
+style_name_from_pattern (FcPattern *pattern)
+{
+  const char *font_style;
+  int weight, slant;
+
+  if (FcPatternGetString (pattern, FC_STYLE, 0, (FcChar8 **)(void*)&font_style) == FcResultMatch)
+    return font_style;
+
+  if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &weight) != FcResultMatch)
+    weight = FC_WEIGHT_MEDIUM;
+
+  if (FcPatternGetInteger(pattern, FC_SLANT, 0, &slant) != FcResultMatch)
+    slant = FC_SLANT_ROMAN;
+
+  if (weight <= FC_WEIGHT_MEDIUM)
+    {
+      if (slant == FC_SLANT_ROMAN)
+        return "Regular";
+      else
+        return "Italic";
+    }
+  else
+    {
+      if (slant == FC_SLANT_ROMAN)
+        return "Bold";
+      else
+        return "Bold Italic";
+    }
+
+  return "Normal";
+}
+
+static gboolean
+font_matrix_from_pattern (FcPattern   *pattern,
+                          PangoMatrix *matrix)
+{
+  FcMatrix fc_matrix, *fc_matrix_val;
+  int i;
+
+  FcMatrixInit (&fc_matrix);
+  for (i = 0; FcPatternGetMatrix (pattern, FC_MATRIX, i, &fc_matrix_val) == FcResultMatch; i++)
+    FcMatrixMultiply (&fc_matrix, &fc_matrix, fc_matrix_val);
+
+  if (i > 0)
+    {
+      matrix->xx = fc_matrix.xx;
+      matrix->yx = fc_matrix.yx;
+      matrix->xy = - fc_matrix.xy;
+      matrix->yy = - fc_matrix.yy;
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static PangoHbFace *
+pango_hb_face_from_pattern (FcPattern  *pattern,
+                            GHashTable *lang_hash)
+{
+  const char *family_name, *file;
+  int index;
+  int instance_id;
+  PangoFontDescription *description;
+  const char *name;
+  PangoHbFace *face;
+  PangoMatrix font_matrix;
+  FcLangSet *langs;
+
+  if (!is_supported_font_format (pattern))
+    return NULL;
+
+  if (FcPatternGetString (pattern, FC_FAMILY, 0, (FcChar8 **)(void*)&family_name) != FcResultMatch)
+    return NULL;
+
+  if (FcPatternGetString (pattern, FC_FILE, 0, (FcChar8 **)(void*)&file) != FcResultMatch)
+    return NULL;
+
+  if (FcPatternGetInteger (pattern, FC_INDEX, 0, &index) != FcResultMatch)
+    index = 0;
+
+  instance_id = (index >> 16) - 1;
+  index = index & 0xffff;
+
+  name = style_name_from_pattern (pattern);
+  description = pango_font_description_from_pattern (pattern, FALSE);
+
+  face = pango_hb_face_new_from_file (file, index, instance_id, name, description);
+
+  pango_font_description_free (description);
+
+  if (font_matrix_from_pattern (pattern, &font_matrix))
+    pango_hb_face_set_matrix (face, &font_matrix);
+
+  if (FcPatternGetLangSet (pattern, FC_LANG, 0, &langs) == FcResultMatch)
+    {
+      PangoFcLanguageSet lookup;
+      PangoLanguageSet *languages;
+
+      lookup.langs = langs;
+      languages = g_hash_table_lookup (lang_hash, &lookup);
+      if (!languages)
+        {
+          languages = PANGO_LANGUAGE_SET (pango_fc_language_set_new (langs));
+          g_hash_table_add (lang_hash, languages);
+        }
+      pango_hb_face_set_languages (face, languages);
+    }
+
+  return face;
+}
+
+static void
+pango_fc_hb_font_map_populate (PangoHbFontMap *simple)
+{
+  PangoFcHbFontMap *self = PANGO_FC_HB_FONT_MAP (simple);
+  FcPattern *pat;
+  FcFontSet *fontset;
+  int k;
+  GHashTable *lang_hash;
+  FcObjectSet *os;
+  gint64 before G_GNUC_UNUSED;
+
+  before = PANGO_TRACE_CURRENT_TIME;
+
+  os = FcObjectSetBuild (FC_FAMILY, FC_SPACING, FC_STYLE, FC_WEIGHT,
+                         FC_WIDTH, FC_SLANT, FC_VARIABLE, FC_FONTFORMAT,
+                         FC_FILE, FC_INDEX, FC_LANG, NULL);
+
+  pat = FcPatternCreate ();
+  fontset = FcFontList (self->config, pat, os);
+  FcPatternDestroy (pat);
+
+  lang_hash = g_hash_table_new_full ((GHashFunc) pango_fc_language_set_hash,
+                                     (GEqualFunc) pango_fc_language_set_equal,
+                                     NULL, g_object_unref);
+
+  for (k = 0; k < fontset->nfont; k++)
+    {
+      PangoHbFace *face = pango_hb_face_from_pattern (fontset->fonts[k], lang_hash);
+      if (!face)
+        continue;
+
+      pango_hb_font_map_add_face (PANGO_HB_FONT_MAP (self), face);
+      g_object_unref (face);
+    }
+
+  g_hash_table_unref (lang_hash);
+
+  FcFontSetDestroy (fontset);
+
+  /* Add alias families */
+  const char *alias_names[] = {
+    "monospace", "sans-serif", "serif", "cursive", "fantasy", "system-ui", "emoji"
+  };
+  FcLangSet *no_langs = FcLangSetCreate ();
+  FcLangSet *emoji_langs = FcLangSetCreate ();
+
+  FcLangSetAdd (emoji_langs, (FcChar8 *)"und-zsye");
+
+  for (int i = 0; i < G_N_ELEMENTS (alias_names); i++)
+    {
+      FcPattern *pattern;
+      FcFontSet *ret;
+      FcResult res;
+      PangoHbFamily *alias_family;
+      int n_faces;
+
+      if (pango_font_map_get_family (PANGO_FONT_MAP (self), alias_names[i]))
+        continue;
+
+      pattern = FcPatternCreate ();
+      FcPatternAddString (pattern, FC_FAMILY, (FcChar8 *) alias_names[i]);
+
+      FcConfigSubstitute (self->config, pattern, FcMatchPattern);
+      FcDefaultSubstitute (pattern);
+
+      alias_family = pango_hb_family_new (PANGO_FONT_MAP (self),
+                                          alias_names[i],
+                                          strcmp (alias_names[i], "monospace") == 0,
+                                          FALSE);
+      g_ptr_array_add (PANGO_HB_FONT_MAP (self)->families, alias_family);
+      g_hash_table_add (PANGO_HB_FONT_MAP (self)->families_hash, alias_family);
+
+      n_faces = 0;
+      ret = FcFontSort (self->config, pattern, TRUE, NULL, &res);
+      for (int j = 0; j < ret->nfont; j++)
+        {
+          PangoHbFace *face;
+          const char *file;
+          int index;
+          int instance_id;
+          PangoHbFace *alias_face;
+          PangoFontDescription *desc;
+          FcLangSet *langs;
+          int spacing;
+
+          pat = ret->fonts[j];
+
+          if (!is_supported_font_format (pat))
+            continue;
+
+          if (FcPatternGetLangSet (pat, FC_LANG, 0, &langs) != FcResultMatch)
+            continue;
+
+          if (FcLangSetEqual (langs, no_langs))
+            continue;
+
+          if ((strcmp (alias_names[i], "emoji") == 0) != FcLangSetEqual (langs, emoji_langs))
+            continue;
+
+          if (FcPatternGetInteger (pat, FC_SPACING, 0, &spacing) != FcResultMatch)
+            spacing = FC_PROPORTIONAL;
+
+          if (strcmp (alias_names[i], "monospace") == 0 && spacing != FC_MONO)
+            continue;
+
+          if (FcPatternGetString (pat, FC_FILE, 0, (FcChar8 **)(void*)&file) != FcResultMatch)
+            continue;
+
+          if (FcPatternGetInteger (pat, FC_INDEX, 0, &index) != FcResultMatch)
+            index = 0;
+
+          instance_id = (index >> 16) - 1;
+          index = index & 0xffff;
+
+          face = find_face_by_file (self, file, index, instance_id);
+          if (!face)
+            continue;
+
+          desc = pango_font_description_new ();
+          pango_font_description_set_family (desc, alias_names[i]);
+          alias_face = pango_hb_face_new_variant (PANGO_HB_FACE (face), NULL, FALSE, desc);
+          pango_hb_family_add_face (alias_family, alias_face);
+          g_object_unref (alias_face);
+          pango_font_description_free (desc);
+
+          n_faces++;
+          if (n_faces == MAX_ALIAS_FACES)
+            break;
+       }
+
+      FcFontSetDestroy (ret);
+      FcPatternDestroy (pattern);
+    }
+
+  FcLangSetDestroy (no_langs);
+  FcLangSetDestroy (emoji_langs);
+
+  FcObjectSetDestroy (os);
+
+  /* Synthesize missing Bold and Italics */
+  for (int i = 0; i < PANGO_HB_FONT_MAP (self)->families->len; i++)
+    {
+      PangoHbFamily *family = g_ptr_array_index (PANGO_HB_FONT_MAP (self)->families, i);
+      PangoHbFace *regular_face = NULL;
+      int regular_weight = 0;
+      int bold_weight = 1000;
+      gboolean has_italic = FALSE;
+      gboolean has_bold = FALSE;
+      gboolean has_bold_italic = FALSE;
+
+      for (int j = 0; j < g_list_model_get_n_items (G_LIST_MODEL (family)); j++)
+        {
+          PangoFontFace *face = g_list_model_get_item (G_LIST_MODEL (family), j);
+          PangoFontDescription *desc;
+          int weight;
+          PangoStyle style;
+
+          desc = pango_font_face_describe (face);
+          weight = pango_font_description_get_weight (desc);
+          style = pango_font_description_get_style (desc);
+          pango_font_description_free (desc);
+
+          if (style == PANGO_STYLE_NORMAL)
+            {
+              if (abs (weight - (int)PANGO_WEIGHT_NORMAL) < abs (regular_weight - (int)PANGO_WEIGHT_NORMAL))
+                {
+                  regular_weight = weight;
+                  regular_face = PANGO_HB_FACE (face);
+                }
+              if (abs (weight - (int)PANGO_WEIGHT_BOLD) < abs (bold_weight - (int)PANGO_WEIGHT_BOLD))
+                {
+                  bold_weight = weight;
+                  has_bold = TRUE;
+                }
+            }
+          else
+            {
+              if (weight < PANGO_WEIGHT_SEMIBOLD)
+                has_italic = TRUE;
+              else
+                has_bold_italic = TRUE;
+            }
+
+          g_object_unref (face);
+        }
+
+      if (regular_face && !has_italic)
+        {
+          PangoFontDescription *desc;
+          PangoHbFace *face;
+
+          desc = pango_font_description_new ();
+          pango_font_description_set_style (desc, PANGO_STYLE_ITALIC);
+          face = pango_hb_face_new_variant (regular_face,
+                                            &(PangoMatrix) { 1, -0.2, 0, 1, 0, 0 },
+                                            FALSE,
+                                            desc);
+          pango_hb_family_add_face (family, face);
+          g_object_unref (face);
+          pango_font_description_free (desc);
+        }
+
+      if (regular_face && !has_bold)
+        {
+          PangoFontDescription *desc;
+          PangoHbFace *face;
+
+          desc = pango_font_description_new ();
+          pango_font_description_set_weight (desc, PANGO_WEIGHT_BOLD);
+          face = pango_hb_face_new_variant (regular_face, NULL, TRUE, desc);
+          pango_hb_family_add_face (family, face);
+          g_object_unref (face);
+          pango_font_description_free (desc);
+        }
+
+      if (regular_face && !has_bold_italic)
+        {
+          PangoFontDescription *desc;
+          PangoHbFace *face;
+
+          desc = pango_font_description_new ();
+          pango_font_description_set_style (desc, PANGO_STYLE_ITALIC);
+          pango_font_description_set_weight (desc, PANGO_WEIGHT_BOLD);
+          face = pango_hb_face_new_variant (regular_face,
+                                            &(PangoMatrix) { 1, -0.2, 0, 1, 0, 0 },
+                                            TRUE,
+                                            desc);
+          pango_hb_family_add_face (family, face);
+          g_object_unref (face);
+          pango_font_description_free (desc);
+        }
+    }
+
+  pango_trace_mark (before, "populate FcFontMap2", NULL);
+}
+
+/* }}} */
+/* {{{ PangoFontMap implementation */
+
+G_DEFINE_TYPE (PangoFcHbFontMap, pango_fc_hb_font_map, PANGO_TYPE_HB_FONT_MAP)
+
+static void
+pango_fc_hb_font_map_init (PangoFcHbFontMap *self)
+{
+  pango_hb_font_map_repopulate (PANGO_HB_FONT_MAP (self));
+}
+
+static void
+pango_fc_hb_font_map_finalize (GObject *object)
+{
+  PangoFcHbFontMap *self = PANGO_FC_HB_FONT_MAP (object);
+
+  if (self->config)
+    FcConfigDestroy (self->config);
+
+  G_OBJECT_CLASS (pango_fc_hb_font_map_parent_class)->finalize (object);
+}
+
+static void
+pango_fc_hb_font_map_class_init (PangoFcHbFontMapClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  PangoHbFontMapClass *hb_font_map_class = PANGO_HB_FONT_MAP_CLASS (class);
+  gint64 before G_GNUC_UNUSED;
+
+  before = PANGO_TRACE_CURRENT_TIME;
+
+  FcInit ();
+
+  pango_trace_mark (before, "FcInit", NULL);
+
+  object_class->finalize = pango_fc_hb_font_map_finalize;
+
+  hb_font_map_class->populate = pango_fc_hb_font_map_populate;
+}
+
+/* }}} */
+/* {{{ Public API */
+
+/**
+ * pango_fc_hb_font_map_new:
+ *
+ * Creates a new `PangoFcHbFontMap` object.
+ *
+ * Unless overridden by [method@PangoFc.HbFontMap.set_config],
+ * this font map uses the default fontconfig configuration.
+ *
+ * Returns: a new `PangoFcHbFontMap`
+ */
+PangoFcHbFontMap *
+pango_fc_hb_font_map_new (void)
+{
+  return g_object_new (PANGO_TYPE_FC_HB_FONT_MAP, NULL);
+}
+
+/**
+ * pango_fc_hb_font_map_set_config:
+ * @self: a `PangoFcHbFontMap`
+ * @config: (nullable): the `FcConfig` to use, or `NULL` to use
+ *   the default configuration
+ *
+ * Sets the fontconfig configuration to use.
+ *
+ * Note that changing the fontconfig configuration
+ * removes all cached font families, faces and fonts.
+ */
+void
+pango_fc_hb_font_map_set_config (PangoFcHbFontMap *self,
+                                 FcConfig        *config)
+{
+  g_return_if_fail (PANGO_IS_FC_HB_FONT_MAP (self));
+
+  if (self->config)
+    FcConfigDestroy (self->config);
+
+  self->config = config;
+
+  if (self->config)
+    FcConfigReference (self->config);
+
+  pango_hb_font_map_repopulate (PANGO_HB_FONT_MAP (self));
+}
+
+/* }}} */
+
+/* vim:set foldmethod=marker expandtab: */
diff --git a/pango/pangofc-hbfontmap.h b/pango/pangofc-hbfontmap.h
new file mode 100644
index 00000000..cb589c32
--- /dev/null
+++ b/pango/pangofc-hbfontmap.h
@@ -0,0 +1,41 @@
+/* Pango
+ * pangofc-fontmap2.h: Base fontmap type for fontconfig-based backends
+ *
+ * Copyright (C) 2021 Red Hat, Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#pragma once
+
+#include <pango/pango.h>
+#include <fontconfig/fontconfig.h>
+
+G_BEGIN_DECLS
+
+#define PANGO_TYPE_FC_HB_FONT_MAP      (pango_fc_hb_font_map_get_type ())
+
+PANGO_AVAILABLE_IN_1_52
+PANGO_DECLARE_INTERNAL_TYPE (PangoFcHbFontMap, pango_fc_hb_font_map, PANGO, FC_HB_FONT_MAP, PangoHbFontMap)
+
+PANGO_AVAILABLE_IN_1_52
+PangoFcHbFontMap *      pango_fc_hb_font_map_new         (void);
+
+PANGO_AVAILABLE_IN_1_52
+void                    pango_fc_hb_font_map_set_config  (PangoFcHbFontMap *self,
+                                                          FcConfig         *config);
+
+G_END_DECLS


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