[pango/simple-fontmap: 5/16] Add PangoSimpleFamily
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pango/simple-fontmap: 5/16] Add PangoSimpleFamily
- Date: Thu, 23 Dec 2021 17:20:14 +0000 (UTC)
commit caf042766248b897e5bed32de34a1c69604f74e9
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Oct 29 19:05:34 2021 -0400
Add PangoSimpleFamily
This is a straightforward implementation of
PangoFontFamily that could be used to replace
all our existing implementations.
pango/meson.build | 1 +
pango/pango-simple-family-private.h | 34 +++++
pango/pango-simple-family.c | 258 ++++++++++++++++++++++++++++++++++++
3 files changed, 293 insertions(+)
---
diff --git a/pango/meson.build b/pango/meson.build
index 23a21613..b6b98f68 100644
--- a/pango/meson.build
+++ b/pango/meson.build
@@ -31,6 +31,7 @@ pango_sources = [
'json/gtkjsonparser.c',
'json/gtkjsonprinter.c',
'pango-hbface.c',
+ 'pango-simple-family.c',
]
pango_headers = [
diff --git a/pango/pango-simple-family-private.h b/pango/pango-simple-family-private.h
new file mode 100644
index 00000000..6988a14d
--- /dev/null
+++ b/pango/pango-simple-family-private.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "pango-font.h"
+
+#define PANGO_TYPE_SIMPLE_FAMILY (pango_simple_family_get_type ())
+
+PANGO_AVAILABLE_IN_1_50
+G_DECLARE_FINAL_TYPE (PangoSimpleFamily, pango_simple_family, PANGO, SIMPLE_FAMILY, PangoFontFamily)
+
+struct _PangoSimpleFamily
+{
+ PangoFontFamily parent_instance;
+
+ PangoFontMap *map;
+
+ char *name;
+ GPtrArray *faces;
+ gboolean monospace;
+ gboolean variable;
+};
+
+PANGO_AVAILABLE_IN_1_50
+PangoSimpleFamily * pango_simple_family_new (PangoFontMap *map,
+ const char *name,
+ gboolean monospace,
+ gboolean variable);
+
+PANGO_AVAILABLE_IN_1_50
+void pango_simple_family_add_face (PangoSimpleFamily *self,
+ PangoFontFace *face);
+
+PangoFontFace * pango_simple_family_find_face (PangoSimpleFamily *self,
+ PangoFontDescription *description,
+ PangoLanguage *language);
diff --git a/pango/pango-simple-family.c b/pango/pango-simple-family.c
new file mode 100644
index 00000000..dacca2c6
--- /dev/null
+++ b/pango/pango-simple-family.c
@@ -0,0 +1,258 @@
+/* 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 <gio/gio.h>
+
+#include "pango-simple-family-private.h"
+#include "pango-impl-utils.h"
+#include "pango-hbface-private.h"
+
+/* {{{ GListModel implementation */
+
+static GType
+pango_simple_family_get_item_type (GListModel *list)
+{
+ return PANGO_TYPE_FONT_FACE;
+}
+
+static guint
+pango_simple_family_get_n_items (GListModel *list)
+{
+ PangoSimpleFamily *self = PANGO_SIMPLE_FAMILY (list);
+
+ return self->faces->len;
+}
+
+static gpointer
+pango_simple_family_get_item (GListModel *list,
+ guint position)
+{
+ PangoSimpleFamily *self = PANGO_SIMPLE_FAMILY (list);
+
+ if (position < self->faces->len)
+ return g_object_ref (g_ptr_array_index (self->faces, position));
+
+ return NULL;
+}
+
+static void
+pango_simple_family_list_model_init (GListModelInterface *iface)
+{
+ iface->get_item_type = pango_simple_family_get_item_type;
+ iface->get_n_items = pango_simple_family_get_n_items;
+ iface->get_item = pango_simple_family_get_item;
+}
+
+/* }}} */
+/* {{{ PangoFontFamily implementation */
+
+struct _PangoSimpleFamilyClass
+{
+ PangoFontFamilyClass parent_class;
+};
+
+G_DEFINE_TYPE_WITH_CODE (PangoSimpleFamily, pango_simple_family, PANGO_TYPE_FONT_FAMILY,
+ G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, pango_simple_family_list_model_init))
+
+static void
+pango_simple_family_init (PangoSimpleFamily *self)
+{
+ self->faces = g_ptr_array_new_with_free_func (g_object_unref);
+}
+
+static void
+pango_simple_family_finalize (GObject *object)
+{
+ PangoSimpleFamily *self = PANGO_SIMPLE_FAMILY (object);
+
+ g_free (self->name);
+ g_ptr_array_unref (self->faces);
+
+ G_OBJECT_CLASS (pango_simple_family_parent_class)->finalize (object);
+}
+
+static const char *
+pango_simple_family_get_name (PangoFontFamily *family)
+{
+ PangoSimpleFamily *self = PANGO_SIMPLE_FAMILY (family);
+
+ return self->name;
+}
+
+static void
+pango_simple_family_list_faces (PangoFontFamily *family,
+ PangoFontFace ***faces,
+ int *n_faces)
+{
+ PangoSimpleFamily *self = PANGO_SIMPLE_FAMILY (family);
+
+ if (faces)
+ *faces = g_memdup2 (self->faces->pdata, self->faces->len * sizeof (PangoFontFace *));
+
+ if (n_faces)
+ *n_faces = self->faces->len;
+}
+
+static PangoFontFace *
+pango_simple_family_get_face (PangoFontFamily *family,
+ const char *name)
+{
+ PangoSimpleFamily *self = PANGO_SIMPLE_FAMILY (family);
+
+ for (int i = 0; i < self->faces->len; i++)
+ {
+ PangoFontFace *face = g_ptr_array_index (self->faces, i);
+
+ if (name == NULL || strcmp (name, pango_font_face_get_face_name (face)) == 0)
+ return PANGO_FONT_FACE (face);
+ }
+
+ return NULL;
+}
+
+static gboolean
+pango_simple_family_is_monospace (PangoFontFamily *family)
+{
+ PangoSimpleFamily *self = PANGO_SIMPLE_FAMILY (family);
+
+ return self->monospace;
+}
+
+static gboolean
+pango_simple_family_is_variable (PangoFontFamily *family)
+{
+ PangoSimpleFamily *self = PANGO_SIMPLE_FAMILY (family);
+
+ return self->variable;
+}
+
+static void
+pango_simple_family_class_init (PangoSimpleFamilyClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ PangoFontFamilyClass *family_class = PANGO_FONT_FAMILY_CLASS (class);
+
+ object_class->finalize = pango_simple_family_finalize;
+
+ family_class->list_faces = pango_simple_family_list_faces;
+ family_class->get_name = pango_simple_family_get_name;
+ family_class->get_face = pango_simple_family_get_face;
+ family_class->is_monospace = pango_simple_family_is_monospace;
+ family_class->is_variable = pango_simple_family_is_variable;
+}
+
+/* }}} */
+/* {{{ Private API */
+
+/*< private >
+ * pango_simple_family_new:
+ * @map: the font map
+ * @name: the family name
+ * @monospace: whether this family is monospace
+ * @variable: whether this family is variable
+ *
+ * Creates a new `PangoSimpleFamily`.
+ *
+ * Returns: a newly created `PangoSimpleFamily`
+ */
+PangoSimpleFamily *
+pango_simple_family_new (PangoFontMap *map,
+ const char *name,
+ gboolean monospace,
+ gboolean variable)
+{
+ PangoSimpleFamily *self;
+
+ self = g_object_new (PANGO_TYPE_SIMPLE_FAMILY, NULL);
+
+ self->name = g_strdup (name);
+ self->monospace = monospace;
+ self->variable = variable;
+
+ self->map = map;
+ g_object_add_weak_pointer (G_OBJECT (map), (gpointer *)&self->map);
+
+ return self;
+}
+
+/*< private >
+ * pango_simple_family_add_face:
+ * @self: a `PangoSimpleFamily`
+ * @face: a `PangoFontFace` to add
+ *
+ * Adds a `PangoFontFace` to a `PangoSimpleFamily`.
+ *
+ * It is an error to call this function more than
+ * once for the same face.
+ */
+void
+pango_simple_family_add_face (PangoSimpleFamily *self,
+ PangoFontFace *face)
+{
+ g_ptr_array_add (self->faces, g_object_ref (face));
+ pango_hb_face_set_family (PANGO_HB_FACE (face), PANGO_FONT_FAMILY (self));
+}
+
+static gboolean
+face_covers_language (PangoHbFace *face,
+ PangoLanguage *language)
+{
+ PangoLanguage **languages = pango_hb_face_get_languages (face);
+ for (int i = 0; languages[i]; i++)
+ {
+ if (languages[i] == language)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+PangoFontFace *
+pango_simple_family_find_face (PangoSimpleFamily *family,
+ PangoFontDescription *description,
+ PangoLanguage *language)
+{
+ PangoHbFace *face = NULL;
+ PangoFontDescription *best = NULL;
+ gboolean covers = FALSE;
+
+ for (int i = 0; i < family->faces->len; i++)
+ {
+ PangoHbFace *face2 = g_ptr_array_index (family->faces, i);
+ gboolean covers2 = face_covers_language (face2, language);
+
+ if ((covers2 && !covers) ||
+ (covers2 == covers &&
+ pango_font_description_better_match (description, best, face2->description)))
+ {
+ face = face2;
+ best = face2->description;
+ covers = covers2;
+ }
+ }
+
+ return PANGO_FONT_FACE (face);
+}
+
+/* }}} */
+
+/* vim:set foldmethod=marker expandtab: */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]