[pango/pango2: 105/168] Add PangoGenericFamily




commit 59bedb94358ab8cf4a5a537fdf91d47b44610c16
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Jan 9 18:36:47 2022 -0500

    Add PangoGenericFamily
    
    This is a PangoFontFamily implementation that will
    act as a union of other families.

 pango/meson.build                    |   2 +
 pango/pango-generic-family-private.h |  44 ++++++
 pango/pango-generic-family.c         | 280 +++++++++++++++++++++++++++++++++++
 pango/pango-generic-family.h         |  38 +++++
 pango/pango.h                        |   1 +
 5 files changed, 365 insertions(+)
---
diff --git a/pango/meson.build b/pango/meson.build
index 995f5233..92db28e7 100644
--- a/pango/meson.build
+++ b/pango/meson.build
@@ -43,6 +43,7 @@ pango_sources = [
   'pango-line-iter.c',
   'pango-hbface.c',
   'pango-hbfamily.c',
+  'pango-generic-family.c',
 ]
 
 pango_headers = [
@@ -61,6 +62,7 @@ pango_headers = [
   'pango-fontmap.h',
   'pango-fontset.h',
   'pango-fontset-simple.h',
+  'pango-generic-family.h',
   'pango-glyph.h',
   'pango-glyph-item.h',
   'pango-gravity.h',
diff --git a/pango/pango-generic-family-private.h b/pango/pango-generic-family-private.h
new file mode 100644
index 00000000..efc2bfb2
--- /dev/null
+++ b/pango/pango-generic-family-private.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 Matthias Clasen
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "pango-font.h"
+#include "pango-hbface.h"
+#include "pango-generic-family.h"
+#include "pango-hbfamily-private.h"
+
+
+struct _PangoGenericFamily
+{
+  PangoFontFamily parent_instance;
+
+  PangoFontMap *map;
+  char *name;
+  GPtrArray *families;
+};
+
+
+void                    pango_generic_family_set_font_map       (PangoGenericFamily      *self,
+                                                                 PangoFontMap            *map);
+
+PangoHbFace *           pango_generic_family_find_face          (PangoGenericFamily     *self,
+                                                                 PangoFontDescription   *description,
+                                                                 PangoLanguage          *language,
+                                                                 gunichar                wc);
diff --git a/pango/pango-generic-family.c b/pango/pango-generic-family.c
new file mode 100644
index 00000000..d8c3dc7f
--- /dev/null
+++ b/pango/pango-generic-family.c
@@ -0,0 +1,280 @@
+/* Pango
+ *
+ * Copyright (C) 2022 Matthias Clasen
+ *
+ * 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 <gio/gio.h>
+
+#include "pango-generic-family-private.h"
+#include "pango-impl-utils.h"
+#include "pango-hbface-private.h"
+#include "pango-font-private.h"
+
+/**
+ * PangoGenericFamily:
+ *
+ * An implementation of `PangoFontFamily`
+ * that provides faces from other families.
+ *
+ * `PangoGenericFamily can be used to e.g. assemble a
+ * generic 'sans-serif' family from a number of other
+ * font families.
+ */
+
+
+/* {{{ GListModel implementation */
+
+static GType
+pango_generic_family_get_item_type (GListModel *list)
+{
+  return PANGO_TYPE_FONT_FACE;
+}
+
+static guint
+pango_generic_family_get_n_items (GListModel *list)
+{
+  PangoGenericFamily *self = PANGO_GENERIC_FAMILY (list);
+  guint n;
+
+  n = 0;
+  for (int i = 0; i < self->families->len; i++)
+    {
+      PangoHbFamily *family = g_ptr_array_index (self->families, i);
+
+      n += g_list_model_get_n_items (G_LIST_MODEL (family));
+    }
+
+  return n;
+}
+
+static gpointer
+pango_generic_family_get_item (GListModel *list,
+                               guint       position)
+{
+  PangoGenericFamily *self = PANGO_GENERIC_FAMILY (list);
+  guint pos;
+
+  pos = position;
+  for (int i = 0; i < self->families->len; i++)
+    {
+      PangoHbFamily *family = g_ptr_array_index (self->families, i);
+
+      if (pos < g_list_model_get_n_items (G_LIST_MODEL (family)))
+        return g_list_model_get_item (G_LIST_MODEL (family), pos);
+
+      pos -= g_list_model_get_n_items (G_LIST_MODEL (family));
+    }
+
+  return NULL;
+}
+
+static void
+pango_generic_family_list_model_init (GListModelInterface *iface)
+{
+  iface->get_item_type = pango_generic_family_get_item_type;
+  iface->get_n_items = pango_generic_family_get_n_items;
+  iface->get_item = pango_generic_family_get_item;
+}
+
+/* }}} */
+/* {{{ PangoFontFamily implementation */
+
+struct _PangoGenericFamilyClass
+{
+  PangoFontFamilyClass parent_class;
+};
+
+G_DEFINE_TYPE_WITH_CODE (PangoGenericFamily, pango_generic_family, PANGO_TYPE_FONT_FAMILY,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, pango_generic_family_list_model_init))
+
+static void
+pango_generic_family_init (PangoGenericFamily *self)
+{
+  self->families = g_ptr_array_new_with_free_func (g_object_unref);
+}
+
+static void
+pango_generic_family_finalize (GObject *object)
+{
+  PangoGenericFamily *self = PANGO_GENERIC_FAMILY (object);
+
+  g_free (self->name);
+  g_ptr_array_unref (self->families);
+
+  G_OBJECT_CLASS (pango_generic_family_parent_class)->finalize (object);
+}
+
+static const char *
+pango_generic_family_get_name (PangoFontFamily *family)
+{
+  PangoGenericFamily *self = PANGO_GENERIC_FAMILY (family);
+
+  return self->name;
+}
+
+static gboolean
+pango_generic_family_is_generic (PangoFontFamily *family)
+{
+  return TRUE;
+}
+
+static gboolean
+pango_generic_family_is_monospace (PangoFontFamily *family)
+{
+  PangoGenericFamily *self = PANGO_GENERIC_FAMILY (family);
+
+  return strcmp (self->name, "monospace") == 0;
+}
+
+static gboolean
+pango_generic_family_is_variable (PangoFontFamily *family)
+{
+  return FALSE;
+}
+
+static void
+pango_generic_family_class_init (PangoGenericFamilyClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  PangoFontFamilyClass *family_class = PANGO_FONT_FAMILY_CLASS (class);
+
+  object_class->finalize = pango_generic_family_finalize;
+
+  family_class->get_name = pango_generic_family_get_name;
+  family_class->is_generic = pango_generic_family_is_generic;
+  family_class->is_monospace = pango_generic_family_is_monospace;
+  family_class->is_variable = pango_generic_family_is_variable;
+}
+
+/* }}} */
+/* {{{ 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`
+ * @description: `PangoFontDescription` to match
+ * @language: (nullable): `PangoLanguage` to support
+ * @wc: a Unicode character, or 0 to ignore
+ *
+ * Finds the face that best matches the font description while
+ * also supporting the given language and character, from the first
+ * family in @family that has any matching faces.
+ *
+ * Returns: (transfer none) (nullable): the face
+ */
+PangoHbFace *
+pango_generic_family_find_face (PangoGenericFamily   *self,
+                                PangoFontDescription *description,
+                                PangoLanguage        *language,
+                                gunichar              wc)
+{
+  PangoHbFace *face = NULL;
+
+  for (int i = 0; i < self->families->len; i++)
+    {
+      PangoHbFamily *family = g_ptr_array_index (self->families, i);
+
+      face = pango_hb_family_find_face (family, description, language, wc);
+      if (face)
+        break;
+    }
+
+  /* last resort */
+  if (!face && self->families->len > 0)
+    {
+      PangoHbFamily *family = g_ptr_array_index (self->families, 0);
+      face = g_list_model_get_item (G_LIST_MODEL (family), 0);
+      g_object_unref (face);
+    }
+
+  return face;
+}
+
+/* }}} */
+/* {{{ Public API */
+
+/**
+ * pango_generic_family_new:
+ * @name: the family name
+ *
+ * Creates a new `PangoGenericFamily`.
+ *
+ * A generic family does not contain faces, but will return
+ * faces from other families that match a given query.
+ *
+ * Returns: a newly created `PangoGenericFamily`
+ */
+PangoGenericFamily *
+pango_generic_family_new (const char *name)
+{
+  PangoGenericFamily *self;
+
+  g_return_val_if_fail (name != NULL, NULL);
+
+  self = g_object_new (PANGO_TYPE_GENERIC_FAMILY, NULL);
+
+  self->name = g_strdup (name);
+
+  return self;
+}
+
+/**
+ * pango_generic_family_add_family:
+ * @self: a `PangoGenericFamily`
+ * @family: (transfer none): a `PangoFontFamily` to add
+ *
+ * Adds a `PangoFontFamily` to a `PangoGenericFamily`.
+ *
+ * It is an error to call this function more than
+ * once for the same family.
+ */
+void
+pango_generic_family_add_family (PangoGenericFamily *self,
+                                 PangoFontFamily    *family)
+{
+  g_return_if_fail (PANGO_IS_GENERIC_FAMILY (self));
+  g_return_if_fail (PANGO_IS_FONT_FAMILY (family));
+
+  g_ptr_array_add (self->families, g_object_ref (family));
+}
+
+/* }}} */
+
+/* vim:set foldmethod=marker expandtab: */
diff --git a/pango/pango-generic-family.h b/pango/pango-generic-family.h
new file mode 100644
index 00000000..fc6de855
--- /dev/null
+++ b/pango/pango-generic-family.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 Matthias Clasen
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "pango-font.h"
+
+G_BEGIN_DECLS
+
+#define PANGO_TYPE_GENERIC_FAMILY (pango_generic_family_get_type ())
+
+PANGO_AVAILABLE_IN_ALL
+PANGO_DECLARE_INTERNAL_TYPE (PangoGenericFamily, pango_generic_family, PANGO, GENERIC_FAMILY, 
PangoFontFamily)
+
+PANGO_AVAILABLE_IN_ALL
+PangoGenericFamily *    pango_generic_family_new                (const char              *name);
+
+PANGO_AVAILABLE_IN_ALL
+void                    pango_generic_family_add_family         (PangoGenericFamily      *self,
+                                                                 PangoFontFamily         *family);
+
+G_END_DECLS
diff --git a/pango/pango.h b/pango/pango.h
index 9cb63161..128950a0 100644
--- a/pango/pango.h
+++ b/pango/pango.h
@@ -38,6 +38,7 @@
 #include <pango/pango-fontmap.h>
 #include <pango/pango-fontset.h>
 #include <pango/pango-fontset-simple.h>
+#include <pango/pango-generic-family.h>
 #include <pango/pango-glyph.h>
 #include <pango/pango-glyph-item.h>
 #include <pango/pango-gravity.h>


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