[pango/simple-fontmap: 1/6] Add PangoHbFont and PangoSimpleFontMap
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pango/simple-fontmap: 1/6] Add PangoHbFont and PangoSimpleFontMap
- Date: Sat, 23 Oct 2021 18:14:38 +0000 (UTC)
commit 171f52897114c63bbd690dbe25384a5a439a4452
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Aug 27 22:08:14 2021 -0400
Add PangoHbFont and PangoSimpleFontMap
This is an attempt to make a font backend that does
not depend on platform specifics and can be used in
tests.
We add PangoHbFont and PangoHbFace to wrap hb_font_t
and hb_face_t, and a very basic fontmap implementation.
pango/meson.build | 3 +
pango/pango-hbface-private.h | 23 +++
pango/pango-hbface.c | 143 +++++++++++++++
pango/pango-hbface.h | 36 ++++
pango/pango-hbfont-private.h | 15 ++
pango/pango-hbfont.c | 416 +++++++++++++++++++++++++++++++++++++++++++
pango/pango-hbfont.h | 41 +++++
pango/pango-simplefontmap.c | 332 ++++++++++++++++++++++++++++++++++
pango/pango-simplefontmap.h | 46 +++++
pango/pango.h | 1 +
10 files changed, 1056 insertions(+)
---
diff --git a/pango/meson.build b/pango/meson.build
index 084de229..482372cb 100644
--- a/pango/meson.build
+++ b/pango/meson.build
@@ -27,6 +27,9 @@ pango_sources = [
'pango-utils.c',
'reorder-items.c',
'shape.c',
+ 'pango-hbfont.c',
+ 'pango-hbface.c',
+ 'pango-simplefontmap.c',
]
pango_headers = [
diff --git a/pango/pango-hbface-private.h b/pango/pango-hbface-private.h
new file mode 100644
index 00000000..e6f378cc
--- /dev/null
+++ b/pango/pango-hbface-private.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "pango-hbface.h"
+#include "pango-fontmap.h"
+#include <hb.h>
+
+struct _PangoHbFace
+{
+ PangoFontFace parent_instance;
+
+ hb_blob_t *blob;
+ unsigned int index;
+ hb_face_t *face;
+ PangoFontDescription *description;
+ char *name;
+ const char *family;
+
+ PangoFontMap *map;
+};
+
+void
+pango_hb_face_set_font_map (PangoHbFace *self,
+ PangoFontMap *map);
diff --git a/pango/pango-hbface.c b/pango/pango-hbface.c
new file mode 100644
index 00000000..5f9306b1
--- /dev/null
+++ b/pango/pango-hbface.c
@@ -0,0 +1,143 @@
+/* Pango
+ *
+ * Copyright (C) 2021 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 "pango-hbface-private.h"
+
+#include <hb-ot.h>
+
+struct _PangoHbFaceClass
+{
+ PangoFontFaceClass parent_class;
+};
+
+G_DEFINE_TYPE (PangoHbFace, pango_hb_face, PANGO_TYPE_FONT_FACE)
+
+static void
+pango_hb_face_init (PangoHbFace *self)
+{
+}
+
+static void
+pango_hb_face_finalize (GObject *object)
+{
+ PangoHbFace *self = PANGO_HB_FACE (object);
+
+ hb_blob_destroy (self->blob);
+ hb_face_destroy (self->face);
+ pango_font_description_free (self->description);
+ if (self->map)
+ g_object_remove_weak_pointer (G_OBJECT (self->map), (gpointer *)&self->map);
+ g_free (self->name);
+
+ G_OBJECT_CLASS (pango_hb_face_parent_class)->finalize (object);
+}
+
+static const char *
+pango_hb_face_get_face_name (PangoFontFace *face)
+{
+ PangoHbFace *self = PANGO_HB_FACE (face);
+
+ return self->name;
+}
+
+static PangoFontDescription *
+pango_hb_face_describe (PangoFontFace *face)
+{
+ PangoHbFace *self = PANGO_HB_FACE (face);
+
+ return pango_font_description_copy (self->description);
+}
+
+static PangoFontFamily *
+pango_hb_face_get_family (PangoFontFace *face)
+{
+ PangoHbFace *self = PANGO_HB_FACE (face);
+
+ if (self->map)
+ return pango_font_map_get_family (self->map, self->family);
+
+ return NULL;
+}
+
+static void
+pango_hb_face_class_init (PangoHbFaceClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ PangoFontFaceClass *face_class = PANGO_FONT_FACE_CLASS (class);
+
+ object_class->finalize = pango_hb_face_finalize;
+
+ face_class->get_face_name = pango_hb_face_get_face_name;
+ face_class->describe = pango_hb_face_describe;
+ face_class->list_sizes = NULL;
+ face_class->is_synthesized = NULL;
+ face_class->get_family = pango_hb_face_get_family;
+}
+
+static char *
+get_name_from_hb_face (hb_face_t *face,
+ hb_ot_name_id_t name_id)
+{
+ char buf[256];
+ unsigned int len = sizeof (buf);
+ hb_language_t language;
+
+ language = hb_language_from_string ("en", -1);
+
+ hb_ot_name_get_utf8 (face, name_id, language, &len, buf);
+
+ return g_strdup (buf);
+}
+
+PangoHbFace *
+pango_hb_face_new (const char *file,
+ unsigned int index)
+{
+ PangoHbFace *self;
+ char *name;
+
+ self = g_object_new (PANGO_TYPE_HB_FACE, NULL);
+
+ self->blob = hb_blob_create_from_file (file);
+ self->index = index;
+ self->face = hb_face_create (self->blob, index);
+
+ name = get_name_from_hb_face (self->face, HB_OT_NAME_ID_FULL_NAME);
+ self->description = pango_font_description_from_string (name);
+ g_free (name);
+
+ self->family = pango_font_description_get_family (self->description);
+
+ self->name = get_name_from_hb_face (self->face, HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY);
+ if (!self->name)
+ self->name = get_name_from_hb_face (self->face, HB_OT_NAME_ID_FONT_SUBFAMILY);
+
+ return self;
+}
+
+void
+pango_hb_face_set_font_map (PangoHbFace *self,
+ PangoFontMap *map)
+{
+ self->map = map;
+ g_object_add_weak_pointer (G_OBJECT (map), (gpointer *)&self->map);
+}
diff --git a/pango/pango-hbface.h b/pango/pango-hbface.h
new file mode 100644
index 00000000..96efb6a2
--- /dev/null
+++ b/pango/pango-hbface.h
@@ -0,0 +1,36 @@
+/* Pango
+ *
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <pango/pango-font.h>
+
+#include <hb.h>
+
+G_BEGIN_DECLS
+
+#define PANGO_TYPE_HB_FACE (pango_hb_face_get_type ())
+G_DECLARE_FINAL_TYPE (PangoHbFace, pango_hb_face, PANGO, HB_FACE, PangoFontFace)
+
+PANGO_AVAILABLE_IN_1_50
+PangoHbFace *pango_hb_face_new (const char *file,
+ unsigned int index);
+
+G_END_DECLS
diff --git a/pango/pango-hbfont-private.h b/pango/pango-hbfont-private.h
new file mode 100644
index 00000000..3e1c98d1
--- /dev/null
+++ b/pango/pango-hbfont-private.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "pango-hbfont.h"
+#include "pango-hbface.h"
+#include <hb.h>
+
+struct _PangoHbFont
+{
+ PangoFont parent_instance;
+
+ PangoHbFace *face;
+ PangoFontDescription *description;
+ PangoGravity gravity;
+ double dpi;
+};
diff --git a/pango/pango-hbfont.c b/pango/pango-hbfont.c
new file mode 100644
index 00000000..74895845
--- /dev/null
+++ b/pango/pango-hbfont.c
@@ -0,0 +1,416 @@
+/* Pango
+ *
+ * Copyright (C) 2021 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 "pango-hbfont-private.h"
+
+#include "pango-font-private.h"
+#include "pango-coverage-private.h"
+#include "pango-hbface-private.h"
+#include "pango-impl-utils.h"
+
+#include <hb-ot.h>
+
+struct _PangoHbFontClass
+{
+ PangoFontClass parent_class;
+};
+
+G_DEFINE_TYPE (PangoHbFont, pango_hb_font, PANGO_TYPE_FONT)
+
+static void
+pango_hb_font_init (PangoHbFont *self)
+{
+ self->gravity = PANGO_GRAVITY_SOUTH;
+ self->dpi = 96.;
+}
+
+static void
+pango_hb_font_finalize (GObject *object)
+{
+ PangoHbFont *self = PANGO_HB_FONT (object);
+
+ g_object_unref (self->face);
+ pango_font_description_free (self->description);
+
+ G_OBJECT_CLASS (pango_hb_font_parent_class)->finalize (object);
+}
+
+static PangoFontDescription *
+pango_hb_font_describe (PangoFont *font)
+{
+ PangoHbFont *self = PANGO_HB_FONT (font);
+
+ return pango_font_description_copy (self->description);
+}
+
+/* {{{ PangoHbCoverage */
+
+typedef struct
+{
+ PangoCoverage parent_instance;
+ hb_font_t *hb_font;
+} PangoHbCoverage;
+
+typedef struct
+{
+ PangoCoverageClass parent_class;
+} PangoHbCoverageClass;
+
+GType pango_hb_coverage_get_type (void) G_GNUC_CONST;
+
+G_DEFINE_TYPE (PangoHbCoverage, pango_hb_coverage, PANGO_TYPE_COVERAGE)
+
+static void
+pango_hb_coverage_init (PangoHbCoverage *self)
+{
+}
+
+static PangoCoverageLevel
+pango_hb_coverage_get (PangoCoverage *coverage,
+ int index)
+{
+ PangoHbCoverage *self = (PangoHbCoverage*)coverage;
+ hb_codepoint_t glyph;
+
+ return hb_font_get_nominal_glyph (self->hb_font, index, &glyph)
+ ? PANGO_COVERAGE_EXACT
+ : PANGO_COVERAGE_NONE;
+}
+
+static void
+pango_hb_coverage_set (PangoCoverage *coverage,
+ int index,
+ PangoCoverageLevel level)
+{
+}
+
+static PangoCoverage *
+pango_hb_coverage_copy (PangoCoverage *coverage)
+{
+ PangoHbCoverage *self = (PangoHbCoverage*)coverage;
+ PangoHbCoverage *copy;
+
+ copy = g_object_new (pango_hb_coverage_get_type (), NULL);
+ copy->hb_font = hb_font_reference (self->hb_font);
+
+ return (PangoCoverage *)copy;
+}
+
+static void
+pango_hb_coverage_finalize (GObject *object)
+{
+ PangoHbCoverage *self = (PangoHbCoverage*)object;
+
+ hb_font_destroy (self->hb_font);
+
+ G_OBJECT_CLASS (pango_hb_coverage_parent_class)->finalize (object);
+}
+
+static void
+pango_hb_coverage_class_init (PangoHbCoverageClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ PangoCoverageClass *coverage_class = PANGO_COVERAGE_CLASS (class);
+
+ object_class->finalize = pango_hb_coverage_finalize;
+
+ coverage_class->get = pango_hb_coverage_get;
+ coverage_class->set = pango_hb_coverage_set;
+ coverage_class->copy = pango_hb_coverage_copy;
+}
+
+/* }}} */
+
+static PangoCoverage *
+pango_hb_font_get_coverage (PangoFont *font,
+ PangoLanguage *language G_GNUC_UNUSED)
+{
+ hb_font_t *hb_font = pango_font_get_hb_font (font);
+ PangoHbCoverage *coverage;
+
+ coverage = g_object_new (pango_hb_coverage_get_type (), NULL);
+ coverage->hb_font = hb_font_reference (hb_font);
+
+ return (PangoCoverage *)coverage;
+}
+
+static int
+get_average_char_width (hb_font_t *font,
+ const char *text)
+{
+ int width = 0;
+
+ for (const char *p = text; *p; p = g_utf8_next_char (p))
+ {
+ gunichar wc;
+ hb_codepoint_t glyph;
+ hb_glyph_extents_t extents;
+
+ wc = g_utf8_get_char (p);
+ if (hb_font_get_nominal_glyph (font, wc, &glyph) &&
+ hb_font_get_glyph_extents (font, glyph, &extents))
+ {
+ width += extents.x_bearing + extents.width;
+ }
+ }
+
+ return width / pango_utf8_strwidth (text);
+}
+
+static int
+get_max_char_width (hb_font_t *font,
+ const char *text)
+{
+ int width = 0;
+
+ for (const char *p = text; *p; p = g_utf8_next_char (p))
+ {
+ gunichar wc;
+ hb_codepoint_t glyph;
+ hb_glyph_extents_t extents;
+
+ wc = g_utf8_get_char (p);
+ if (hb_font_get_nominal_glyph (font, wc, &glyph) &&
+ hb_font_get_glyph_extents (font, glyph, &extents))
+ {
+ width = MAX (width, extents.x_bearing + extents.width);
+ }
+ }
+
+ return width;
+}
+
+static void
+pango_hb_font_get_glyph_extents (PangoFont *font,
+ PangoGlyph glyph,
+ PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect)
+{
+ hb_font_t *hb_font = pango_font_get_hb_font (font);
+ hb_glyph_extents_t extents;
+
+ /* FIXME handle unknown glyphs and visible ignorables */
+ hb_font_get_glyph_extents (hb_font, glyph, &extents);
+
+ if (ink_rect)
+ {
+ ink_rect->x = extents.x_bearing;
+ ink_rect->width = extents.width;
+ ink_rect->y = - extents.y_bearing;
+ ink_rect->height = - extents.height;
+ }
+
+ if (logical_rect)
+ {
+ hb_font_extents_t font_extents;
+ hb_position_t x, y;
+ hb_direction_t direction;
+
+ direction = PANGO_GRAVITY_IS_VERTICAL (PANGO_HB_FONT (font)->gravity)
+ ? HB_DIRECTION_TTB : HB_DIRECTION_LTR;
+
+ hb_font_get_extents_for_direction (hb_font, direction, &font_extents);
+ hb_font_get_glyph_advance_for_direction (hb_font, glyph, direction, &x, &y);
+
+ logical_rect->x = 0;
+ logical_rect->width = x;
+ logical_rect->y = - font_extents.ascender;
+ logical_rect->height = font_extents.ascender - font_extents.descender;
+ }
+}
+
+static PangoFontMetrics *
+pango_hb_font_get_metrics (PangoFont *font,
+ PangoLanguage *language)
+{
+ hb_font_t *hb_font = pango_font_get_hb_font (font);
+ PangoFontMetrics *metrics;
+ hb_font_extents_t extents;
+ hb_position_t position;
+
+ metrics = pango_font_metrics_new ();
+
+ hb_font_get_extents_for_direction (hb_font, HB_DIRECTION_LTR, &extents);
+
+ metrics->descent = - extents.descender;
+ metrics->ascent = extents.ascender;
+ metrics->height = extents.ascender - extents.descender + extents.line_gap;
+
+ metrics->underline_thickness = PANGO_SCALE;
+ metrics->underline_position = - PANGO_SCALE;
+ metrics->strikethrough_thickness = PANGO_SCALE;
+ metrics->strikethrough_position = metrics->ascent / 2;
+
+ if (hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_TAG_UNDERLINE_SIZE, &position))
+ metrics->underline_thickness = position;
+
+ if (hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_TAG_UNDERLINE_OFFSET, &position))
+ metrics->underline_position = position;
+
+ if (hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_TAG_STRIKEOUT_SIZE, &position))
+ metrics->strikethrough_thickness = position;
+
+ if (hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_TAG_STRIKEOUT_OFFSET, &position))
+ metrics->strikethrough_position = position;
+
+ metrics->approximate_char_width = get_average_char_width (hb_font, pango_language_get_sample_string
(language));
+ metrics->approximate_digit_width = get_max_char_width (hb_font, "0123456789");
+
+ return metrics;
+}
+
+static void
+parse_variations (const char *variations,
+ hb_ot_var_axis_info_t *axes,
+ int n_axes,
+ float *coords)
+{
+ const char *p;
+ const char *end;
+ hb_variation_t var;
+ int i;
+
+ p = variations;
+ while (p && *p)
+ {
+ end = strchr (p, ',');
+ if (hb_variation_from_string (p, end ? end - p: -1, &var))
+ {
+ for (i = 0; i < n_axes; i++)
+ {
+ if (axes[i].tag == var.tag)
+ {
+ coords[axes[i].axis_index] = var.value;
+ break;
+ }
+ }
+ }
+
+ p = end ? end + 1 : NULL;
+ }
+}
+
+static hb_font_t *
+pango_hb_font_create_hb_font (PangoFont *font)
+{
+ PangoHbFont *self = PANGO_HB_FONT (font);
+ hb_face_t *hb_face = self->face->face;
+ hb_font_t *hb_font;
+ int size;
+ unsigned int n_axes;
+ hb_ot_var_axis_info_t axes[32];
+ float coords[32];
+ const char *variations;
+
+ hb_font = hb_font_create (hb_face);
+
+ // TODO Matrix ?
+
+ /* Size */
+ size = pango_font_description_get_size (self->description);
+ hb_font_set_scale (hb_font,
+ size * (self->dpi / 72.),
+ size * (self->dpi / 72.));
+
+ /* Variations */
+ n_axes = G_N_ELEMENTS (axes);
+ hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, axes);
+ if (n_axes > 0)
+ {
+ for (int i = 0; i < n_axes; i++)
+ coords[axes[i].axis_index] = axes[i].default_value;
+
+ variations = pango_font_description_get_variations (self->description);
+ parse_variations (variations, axes, n_axes, coords);
+
+ hb_font_set_var_coords_design (hb_font, coords, n_axes);
+ }
+
+ return hb_font;
+}
+
+static PangoLanguage **
+pango_hb_font_get_languages (PangoFont *font)
+{
+ // TODO Use HB_OT_META_TAG_SUPPORTED_LANGUAGES
+ return NULL;
+}
+
+static gboolean
+pango_hb_font_has_char (PangoFont *font,
+ gunichar wc)
+{
+ hb_font_t *hb_font = pango_font_get_hb_font (font);
+ hb_codepoint_t glyph;
+
+ return hb_font_get_nominal_glyph (hb_font, wc, &glyph);
+}
+
+static PangoFontFace *
+pango_hb_font_get_face (PangoFont *font)
+{
+ PangoHbFont *self = PANGO_HB_FONT (font);
+
+ return PANGO_FONT_FACE (self->face);
+}
+
+static void
+pango_hb_font_class_init (PangoHbFontClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ PangoFontClass *font_class = PANGO_FONT_CLASS (class);
+ PangoFontClassPrivate *pclass;
+
+ object_class->finalize = pango_hb_font_finalize;
+
+ font_class->describe = pango_hb_font_describe;
+ font_class->get_coverage = pango_hb_font_get_coverage;
+ font_class->get_glyph_extents = pango_hb_font_get_glyph_extents;
+ font_class->get_metrics = pango_hb_font_get_metrics;
+ font_class->create_hb_font = pango_hb_font_create_hb_font;
+
+ pclass = g_type_class_get_private ((GTypeClass *) class, PANGO_TYPE_FONT);
+
+ pclass->get_languages = pango_hb_font_get_languages;
+ pclass->has_char = pango_hb_font_has_char;
+ pclass->get_face = pango_hb_font_get_face;
+}
+
+PangoHbFont *
+pango_hb_font_new (PangoHbFace *face,
+ const PangoFontDescription *description,
+ PangoGravity gravity,
+ double dpi)
+{
+ PangoHbFont *font;
+
+ font = g_object_new (PANGO_TYPE_HB_FONT, NULL);
+
+ font->face = g_object_ref (face);
+ font->description = pango_font_description_copy (description);
+ font->gravity = gravity;
+ font->dpi = dpi;
+
+ return font;
+}
+
+/* vim:set foldmethod=marker expandtab: */
diff --git a/pango/pango-hbfont.h b/pango/pango-hbfont.h
new file mode 100644
index 00000000..3d388701
--- /dev/null
+++ b/pango/pango-hbfont.h
@@ -0,0 +1,41 @@
+/* Pango
+ *
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <pango/pango-font.h>
+#include <pango/pango-hbface.h>
+
+#include <hb.h>
+
+G_BEGIN_DECLS
+
+#define PANGO_TYPE_HB_FONT (pango_hb_font_get_type ())
+
+PANGO_AVAILABLE_IN_1_50
+G_DECLARE_FINAL_TYPE (PangoHbFont, pango_hb_font, PANGO, HB_FONT, PangoFont)
+
+PANGO_AVAILABLE_IN_1_50
+PangoHbFont * pango_hb_font_new (PangoHbFace *face,
+ const PangoFontDescription *description,
+ PangoGravity gravity,
+ double dpi);
+
+G_END_DECLS
diff --git a/pango/pango-simplefontmap.c b/pango/pango-simplefontmap.c
new file mode 100644
index 00000000..4dc0a885
--- /dev/null
+++ b/pango/pango-simplefontmap.c
@@ -0,0 +1,332 @@
+/* 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 "pango-simplefontmap.h"
+#include "pango-hbface-private.h"
+#include "pango-hbfont-private.h"
+#include "pango-context.h"
+#include "pango-impl-utils.h"
+
+struct _PangoSimpleFontMap
+{
+ PangoFontMap parent_instance;
+
+ GPtrArray *families;
+ GPtrArray *faces;
+
+ double dpi;
+};
+
+struct _PangoSimpleFontMapClass
+{
+ PangoFontMapClass parent_class;
+};
+
+G_DEFINE_TYPE (PangoSimpleFontMap, pango_simple_font_map, PANGO_TYPE_FONT_MAP)
+
+static void
+pango_simple_font_map_init (PangoSimpleFontMap *self)
+{
+ self->families = g_ptr_array_new_with_free_func (g_object_unref);
+ self->faces = g_ptr_array_new_with_free_func (g_object_unref);
+
+ self->dpi = 96.;
+}
+
+static void
+pango_simple_font_map_finalize (GObject *object)
+{
+ PangoSimpleFontMap *self = PANGO_SIMPLE_FONT_MAP (object);
+
+ g_ptr_array_free (self->families, TRUE);
+ g_ptr_array_free (self->faces, TRUE);
+
+ G_OBJECT_CLASS (pango_simple_font_map_parent_class)->finalize (object);
+}
+
+/* {{{ PangoSimpleFamily */
+
+#define PANGO_TYPE_SIMPLE_FAMILY (pango_simple_family_get_type ())
+G_DECLARE_FINAL_TYPE (PangoSimpleFamily, pango_simple_family, PANGO, SIMPLE_FAMILY, PangoFontFamily)
+
+struct _PangoSimpleFamily
+{
+ PangoFontFamily parent_instance;
+
+ PangoSimpleFontMap *map;
+ char *name;
+};
+
+struct _PangoSimpleFamilyClass
+{
+ PangoFontFamilyClass parent_class;
+};
+
+G_DEFINE_TYPE (PangoSimpleFamily, pango_simple_family, PANGO_TYPE_FONT_FAMILY)
+
+static void
+pango_simple_family_init (PangoSimpleFamily *self)
+{
+}
+
+static void
+pango_simple_family_finalize (GObject *object)
+{
+ PangoSimpleFamily *self = PANGO_SIMPLE_FAMILY (object);
+
+ g_free (self->name);
+ if (self->map)
+ g_object_remove_weak_pointer (G_OBJECT (self->map), (gpointer *)&self->map);
+
+ 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);
+ GPtrArray *result;
+
+ if (!self->map)
+ {
+ if (faces)
+ *faces = NULL;
+ if (n_faces)
+ *n_faces = 0;
+ return;
+ }
+
+ result = g_ptr_array_new ();
+ for (int i = 0; i < self->map->faces->len; i++)
+ {
+ PangoHbFace *face = g_ptr_array_index (self->map->faces, i);
+
+ if (strcmp (self->name, face->family) == 0)
+ g_ptr_array_add (result, face);
+ }
+
+ if (n_faces)
+ *n_faces = result->len;
+
+ if (faces)
+ *faces = (PangoFontFace **) g_ptr_array_free (result, FALSE);
+}
+
+static PangoFontFace *
+pango_simple_family_get_face (PangoFontFamily *family,
+ const char *name)
+{
+ PangoSimpleFamily *self = PANGO_SIMPLE_FAMILY (family);
+
+ if (!self->map)
+ return NULL;
+
+ for (int i = 0; i < self->map->faces->len; i++)
+ {
+ PangoHbFace *face = g_ptr_array_index (self->map->faces, i);
+
+ if (strcmp (self->name, face->family) == 0 &&
+ strcmp (name, face->name) == 0)
+ return PANGO_FONT_FACE (face);
+ }
+
+ return NULL;
+}
+
+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->is_monospace = NULL;
+ family_class->is_variable = NULL;
+ family_class->get_face = pango_simple_family_get_face;
+}
+
+static PangoSimpleFamily *
+pango_simple_family_new (const char *name,
+ PangoSimpleFontMap *map)
+{
+ PangoSimpleFamily *self;
+
+ self = g_object_new (PANGO_TYPE_SIMPLE_FAMILY, NULL);
+
+ self->name = g_strdup (name);
+ self->map = map;
+ g_object_add_weak_pointer (G_OBJECT (map), (gpointer *)&self->map);
+
+ return self;
+}
+
+/* }}} */
+
+static PangoFont *
+pango_simple_font_map_load_font (PangoFontMap *map,
+ PangoContext *context,
+ const PangoFontDescription *desc)
+{
+ PangoSimpleFontMap *self = PANGO_SIMPLE_FONT_MAP (map);
+ PangoFontDescription *best = NULL;
+ PangoHbFace *face = NULL;
+ PangoHbFont *font;
+
+ for (int i = 0; i < self->faces->len; i++)
+ {
+ PangoHbFace *face2 = g_ptr_array_index (self->faces, i);
+
+ if (pango_font_description_better_match (desc, best, face2->description))
+ {
+ face = face2;
+ best = face2->description;
+ }
+ }
+ if (face == NULL)
+ face = g_ptr_array_index (self->faces, 0);
+
+ font = pango_hb_font_new (face, desc, pango_context_get_gravity (context), self->dpi);
+
+ return PANGO_FONT (font);
+}
+
+static PangoFontset *
+pango_simple_font_map_load_fontset (PangoFontMap *map,
+ PangoContext *context,
+ const PangoFontDescription *description,
+ PangoLanguage *language)
+{
+ PangoFontsetSimple *fontset;
+
+ // TODO: Do the FcFontSort thing
+ fontset = pango_fontset_simple_new (language);
+ pango_fontset_simple_append (fontset, pango_font_map_load_font (map, context, description));
+
+ return PANGO_FONTSET (fontset);
+}
+
+static void
+pango_simple_font_map_list_families (PangoFontMap *map,
+ PangoFontFamily ***families,
+ int *n_families)
+{
+ PangoSimpleFontMap *self = PANGO_SIMPLE_FONT_MAP (map);
+
+ if (self->families->len == 0)
+ {
+ if (families)
+ *families = NULL;
+ if (n_families)
+ *n_families = 0;
+
+ return;
+ }
+
+ if (n_families)
+ *n_families = self->families->len;
+
+ if (families)
+ *families = g_memdup2 (self->families->pdata, self->families->len * sizeof (PangoFontFamily *));
+}
+
+static PangoFontFamily *
+pango_simple_font_map_get_family (PangoFontMap *map,
+ const char *name)
+{
+ PangoSimpleFontMap *self = PANGO_SIMPLE_FONT_MAP (map);
+
+ for (int i = 0; i < self->families->len; i++)
+ {
+ PangoSimpleFamily *family = g_ptr_array_index (self->families, i);
+
+ if (strcmp (name, family->name) == 0)
+ return PANGO_FONT_FAMILY (family);
+ }
+
+ return NULL;
+}
+
+static void
+pango_simple_font_map_class_init (PangoSimpleFontMapClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ PangoFontMapClass *map_class = PANGO_FONT_MAP_CLASS (class);
+
+ object_class->finalize = pango_simple_font_map_finalize;
+
+ map_class->load_font = pango_simple_font_map_load_font;
+ map_class->load_fontset = pango_simple_font_map_load_fontset;
+ map_class->list_families = pango_simple_font_map_list_families;
+ map_class->get_family = pango_simple_font_map_get_family;
+ map_class->get_face = NULL;
+}
+
+PangoSimpleFontMap *
+pango_simple_font_map_new (void)
+{
+ return g_object_new (PANGO_TYPE_SIMPLE_FONT_MAP, NULL);
+}
+
+void
+pango_simple_font_map_add_file (PangoSimpleFontMap *self,
+ const char *file,
+ unsigned int index)
+{
+ PangoFontMap *map = PANGO_FONT_MAP (self);
+ PangoHbFace *face;
+
+ face = pango_hb_face_new (file, index);
+
+ pango_hb_face_set_font_map (face, map);
+
+ if (!pango_simple_font_map_get_family (map, face->family))
+ g_ptr_array_add (self->families, pango_simple_family_new (face->family, self));
+
+ g_ptr_array_add (self->faces, face);
+}
+
+void
+pango_simple_font_map_set_resolution (PangoSimpleFontMap *self,
+ double dpi)
+{
+ self->dpi = dpi;
+
+ pango_font_map_changed (PANGO_FONT_MAP (self));
+}
+
+/* vim:set foldmethod=marker expandtab: */
diff --git a/pango/pango-simplefontmap.h b/pango/pango-simplefontmap.h
new file mode 100644
index 00000000..9aa67fd3
--- /dev/null
+++ b/pango/pango-simplefontmap.h
@@ -0,0 +1,46 @@
+/* Pango
+ *
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <pango-font.h>
+#include <pango-fontmap.h>
+#include <hb.h>
+
+G_BEGIN_DECLS
+
+#define PANGO_TYPE_SIMPLE_FONT_MAP (pango_simple_font_map_get_type ())
+
+PANGO_AVAILABLE_IN_1_50
+G_DECLARE_FINAL_TYPE (PangoSimpleFontMap, pango_simple_font_map, PANGO, SIMPLE_FONT_MAP, PangoFontMap)
+
+PANGO_AVAILABLE_IN_1_50
+PangoSimpleFontMap * pango_simple_font_map_new (void);
+
+PANGO_AVAILABLE_IN_1_50
+void pango_simple_font_map_add_file (PangoSimpleFontMap *self,
+ const char *file,
+ unsigned int index);
+
+PANGO_AVAILABLE_IN_1_50
+void pango_simple_font_map_set_resolution (PangoSimpleFontMap *self,
+ double dpi);
+
+G_END_DECLS
diff --git a/pango/pango.h b/pango/pango.h
index 8dc86b13..cf594e55 100644
--- a/pango/pango.h
+++ b/pango/pango.h
@@ -45,6 +45,7 @@
#include <pango/pango-markup.h>
#include <pango/pango-renderer.h>
#include <pango/pango-script.h>
+#include <pango/pango-simplefontmap.h>
#include <pango/pango-tabs.h>
#include <pango/pango-types.h>
#include <pango/pango-utils.h>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]