summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2022-06-14 21:17:57 -0400
committerMatthias Clasen <mclasen@redhat.com>2022-06-22 13:57:26 -0400
commit031c610eb1ef240cc7a165416a02b48cff1070d7 (patch)
treeec9baf59e3eba5de0359048d088b4df83e5bafc0
parentaee6b79e1ecb061616fed1dfe539d802a2b681f6 (diff)
downloadpango-031c610eb1ef240cc7a165416a02b48cff1070d7.tar.gz
tests: Unify font loading code
We want full control over what gets loaded here, so avoid using fontconfig.
-rw-r--r--tests/test-break.c39
-rw-r--r--tests/test-common.c280
-rw-r--r--tests/test-common.h2
-rw-r--r--tests/test-layout.c42
4 files changed, 290 insertions, 73 deletions
diff --git a/tests/test-break.c b/tests/test-break.c
index f815fae2..42cd5346 100644
--- a/tests/test-break.c
+++ b/tests/test-break.c
@@ -29,12 +29,10 @@
#include "config.h"
#include <pango/pangocairo.h>
-#include <pango/pangofc-fontmap.h>
#include "test-common.h"
#include "validate-log-attrs.h"
-static PangoFontMap *map = NULL;
static PangoContext *context;
static gboolean opt_hex_chars;
@@ -360,31 +358,6 @@ test_break (gconstpointer d)
g_free (expected_file);
}
-static void
-install_fonts (const char *dir)
-{
- FcConfig *config;
- char *path;
- gsize len;
- char *conf;
-
- config = FcConfigCreate ();
-
- path = g_build_filename (dir, "fonts.conf", NULL);
- g_file_get_contents (path, &conf, &len, NULL);
-
- if (!FcConfigParseAndLoadFromMemory (config, (const FcChar8 *) conf, TRUE))
- g_error ("Failed to parse fontconfig configuration");
-
- g_free (conf);
- g_free (path);
-
- FcConfigAppFontAddDir (config, (const FcChar8 *) dir);
- map = PANGO_FONT_MAP (pango_fc_font_map_new ());
- pango_fc_font_map_set_config (PANGO_FC_FONT_MAP (map), config);
- FcConfigDestroy (config);
-}
-
int
main (int argc, char *argv[])
{
@@ -417,12 +390,10 @@ main (int argc, char *argv[])
if (opt_fonts)
{
install_fonts (opt_fonts);
+ context = pango_font_map_create_context (pango_font_map_get_default ());
g_free (opt_fonts);
}
- if (map)
- context = pango_font_map_create_context (map);
-
if (opt_legend)
{
g_print ("test-break uses the following symbols for log attrs\n\n");
@@ -455,14 +426,10 @@ main (int argc, char *argv[])
if (!opt_fonts)
{
- path = g_test_build_filename (G_TEST_DIST, "fonts", NULL);
- install_fonts (path);
- g_free (path);
+ install_fonts (NULL);
+ context = pango_font_map_create_context (pango_font_map_get_default ());
}
- if (map)
- context = pango_font_map_create_context (map);
-
path = g_test_build_filename (G_TEST_DIST, "breaks", NULL);
dir = g_dir_open (path, 0, &error);
g_free (path);
diff --git a/tests/test-common.c b/tests/test-common.c
index 99733d3b..861a06d6 100644
--- a/tests/test-common.c
+++ b/tests/test-common.c
@@ -34,6 +34,8 @@
#include <pango/pangocairo.h>
#include "test-common.h"
+#include <hb-ot.h>
+
char *
diff_with_file (const char *file,
char *text,
@@ -234,3 +236,281 @@ get_script_name (GUnicodeScript s)
return nick;
}
+static void
+add_file (PangoFontMap *map,
+ const char *path,
+ const char *name)
+{
+ char *fullname;
+ hb_blob_t *blob;
+ hb_face_t *hbface;
+ PangoHbFace *face;
+
+ fullname = g_build_filename (path, name, NULL);
+
+ blob = hb_blob_create_from_file_or_fail (fullname);
+ if (!blob)
+ g_error ("No font data in %s", fullname);
+
+ g_free (fullname);
+
+ hbface = hb_face_create (blob, 0);
+ hb_face_make_immutable (hbface);
+
+ if (hb_ot_var_get_axis_count (hbface) == 0)
+ {
+ /* Add the default instance */
+ face = pango_hb_face_new_from_hb_face (hbface, -1, NULL, NULL);
+ pango_font_map_add_face (map, PANGO_FONT_FACE (face));
+ return;
+ }
+
+ /* Add the variable face */
+ face = pango_hb_face_new_from_hb_face (hbface, -2, "Variable", NULL);
+ pango_font_map_add_face (map, PANGO_FONT_FACE (face));
+
+ if (hb_ot_var_get_named_instance_count (hbface) > 0)
+ {
+ /* Add named instances */
+ for (int i = 0; i < hb_ot_var_get_named_instance_count (hbface); i++)
+ {
+ face = pango_hb_face_new_from_hb_face (hbface, i, NULL, NULL);
+ pango_font_map_add_face (map, PANGO_FONT_FACE (face));
+ }
+ }
+
+ hb_face_destroy (hbface);
+}
+
+static void
+add_generic_family (PangoFontMap *map,
+ const char *path,
+ const char *name)
+{
+ char *fullname;
+ char *contents;
+ gsize length;
+ char *basename;
+ char **families;
+ GError *error = NULL;
+ PangoGenericFamily *generic;
+
+ g_assert (g_str_has_suffix (name, ".generic"));
+
+ fullname = g_build_filename (path, name, NULL);
+
+ if (!g_file_get_contents (fullname, &contents, &length, &error))
+ g_error ("Failed to load %s: %s", fullname, error->message);
+
+ g_free (fullname);
+
+ basename = g_strdup (name);
+ basename[strlen (name) - strlen (".generic")] = '\0';
+
+ generic = pango_generic_family_new (basename);
+
+ families = g_strsplit (contents, "\n", -1);
+ for (int i = 0; families[i]; i++)
+ {
+ const char *name = families[i];
+ PangoFontFamily *family;
+
+ if (name[0] == '\0')
+ continue;
+
+ family = pango_font_map_get_family (map, name);
+ if (!family)
+ {
+ g_warning ("no such family: %s", name);
+ continue;
+ }
+
+ pango_generic_family_add_family (generic, family);
+ }
+
+ pango_font_map_add_family (map, PANGO_FONT_FAMILY (generic));
+
+ g_strfreev (families);
+ g_free (basename);
+ g_free (contents);
+}
+
+static void
+add_synthetic_faces (PangoFontMap *map,
+ const char *path,
+ const char *name)
+{
+ char *fullname;
+ char *contents;
+ GError *error = NULL;
+ gsize length;
+ char *basename;
+ PangoFontFamily *family;
+ gboolean make_italic;
+ PangoMatrix italic_matrix = { 1, 0.2, 0, 1, 0, 0 };
+ PangoHbFace *newface;
+ GSList *newfaces, *l;
+
+ g_assert (g_str_has_suffix (name, ".synthetic"));
+
+ fullname = g_build_filename (path, name, NULL);
+
+ if (!g_file_get_contents (fullname, &contents, &length, &error))
+ g_error ("Failed to load %s: %s", fullname, error->message);
+
+ g_free (fullname);
+
+ basename = g_strdup (name);
+ basename[strlen (name) - strlen (".synthetic")] = '\0';
+
+ family = pango_font_map_get_family (map, basename);
+ if (!family)
+ g_error ("Family %s not found", basename);
+
+ make_italic = strstr (contents, "Italic") != NULL;
+
+ newfaces = NULL;
+
+
+ for (int i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (family)); i++)
+ {
+ PangoHbFace *face = g_list_model_get_item (G_LIST_MODEL (family), i);
+
+ if (make_italic)
+ {
+ char *name;
+ PangoFontDescription *desc;
+
+ name = g_strconcat (pango_font_face_get_name (PANGO_FONT_FACE (face)),
+ " Italic",
+ NULL);
+ desc = pango_font_face_describe (PANGO_FONT_FACE (face));
+ pango_font_description_set_style (desc, PANGO_STYLE_ITALIC);
+ pango_font_description_unset_fields (desc, ~(PANGO_FONT_MASK_FAMILY|
+ PANGO_FONT_MASK_STYLE|
+ PANGO_FONT_MASK_STRETCH|
+ PANGO_FONT_MASK_WEIGHT));
+ newface = pango_hb_face_new_synthetic (face, &italic_matrix, FALSE, name, desc);
+ newfaces = g_slist_prepend (newfaces, newface);
+
+ g_free (name);
+ pango_font_description_free (desc);
+ }
+
+ g_object_unref (face);
+ }
+
+
+ for (l = newfaces; l; l = l->next)
+ {
+ newface = l->data;
+ pango_font_map_add_face (map, PANGO_FONT_FACE (newface));
+ }
+
+ g_slist_free (newfaces);
+
+ g_free (basename);
+ g_free (contents);
+}
+
+void
+install_fonts (const char *path)
+{
+ PangoFontMap *map;
+ GDir *dir;
+ GError *error = NULL;
+ const char *name;
+ GPtrArray *generic;
+ GPtrArray *synthetic;
+ char *testpath = NULL;
+
+ map = pango_font_map_new ();
+
+ if (!path)
+ path = testpath = g_test_build_filename (G_TEST_DIST, "fonts", NULL);
+
+ dir = g_dir_open (path, 0, &error);
+
+ if (!dir)
+ g_error ("Failed to install fonts: %s", error->message);
+
+ generic = g_ptr_array_new ();
+ synthetic = g_ptr_array_new ();
+
+ while (TRUE)
+ {
+ name = g_dir_read_name (dir);
+ if (name == NULL)
+ break;
+
+ if (g_str_has_suffix (name, ".ttf") ||
+ g_str_has_suffix (name, ".otf"))
+ add_file (map, path, name);
+ else if (g_str_has_suffix (name, ".generic"))
+ g_ptr_array_add (generic, (gpointer) name);
+ else if (g_str_has_suffix (name, ".synthetic"))
+ g_ptr_array_add (synthetic, (gpointer) name);
+ }
+
+ /* Add generics and synthetics in a second path,
+ * so all families are already added.
+ */
+ for (int i = 0; i < generic->len; i++)
+ {
+ name = g_ptr_array_index (generic, i);
+ add_generic_family (map, path, name);
+ }
+ g_ptr_array_free (generic, TRUE);
+
+ for (int i = 0; i < synthetic->len; i++)
+ {
+ name = g_ptr_array_index (synthetic, i);
+ add_synthetic_faces (map, path, name);
+ }
+ g_ptr_array_free (synthetic, TRUE);
+
+
+ pango_font_map_set_default (map);
+
+ g_object_unref (map);
+ g_dir_close (dir);
+
+ g_free (testpath);
+}
+
+void
+dump_fonts (void)
+{
+ PangoFontMap *map;
+
+ map = pango_font_map_get_default ();
+
+ for (int i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (map)); i++)
+ {
+ PangoFontFamily *family = g_list_model_get_item (G_LIST_MODEL (map), i);
+
+ if (PANGO_IS_GENERIC_FAMILY (family))
+ {
+ g_print ("%s (generic)\n", pango_font_family_get_name (family));
+ }
+ else
+ {
+ g_print ("%s\n", pango_font_family_get_name (family));
+
+ 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);
+
+ g_print ("\t%s %s%s\n",
+ pango_font_family_get_name (family),
+ pango_font_face_get_name (face),
+ pango_font_face_is_variable (face) ? " (variable)" : "");
+
+ g_object_unref (face);
+ }
+ }
+
+ g_object_unref (family);
+ }
+}
+
diff --git a/tests/test-common.h b/tests/test-common.h
index 6fe96133..d29db299 100644
--- a/tests/test-common.h
+++ b/tests/test-common.h
@@ -25,5 +25,7 @@ void print_attr_list (PangoAttrList *attrs,
const char *get_script_name (GUnicodeScript s);
+void install_fonts (const char *path);
+void dump_fonts (void);
#endif
diff --git a/tests/test-layout.c b/tests/test-layout.c
index 8b7fe37f..f83fbc36 100644
--- a/tests/test-layout.c
+++ b/tests/test-layout.c
@@ -27,12 +27,10 @@
#include <unistd.h>
#endif
-#include "config.h"
#include <pango/pangocairo.h>
-#include <pango/pangofc-fontmap.h>
#include "test-common.h"
-static PangoFontMap *map = NULL;
+#include <hb-ot.h>
static void
test_layout (gconstpointer d)
@@ -62,7 +60,7 @@ test_layout (gconstpointer d)
g_assert_no_error (error);
orig = g_bytes_new_take (contents, length);
- context = pango_font_map_create_context (map);
+ context = pango_font_map_create_context (pango_font_map_get_default ());
layout = pango_layout_deserialize (context, orig, PANGO_LAYOUT_DESERIALIZE_CONTEXT, &error);
g_assert_no_error (error);
@@ -99,33 +97,6 @@ test_layout (gconstpointer d)
g_free (diff);
}
-static void
-install_fonts (const char *dir)
-{
- FcConfig *config;
- char *path;
- gsize len;
- char *conf;
-
- config = FcConfigCreate ();
-
- path = g_build_filename (dir, "fonts.conf", NULL);
- g_file_get_contents (path, &conf, &len, NULL);
-
- if (!FcConfigParseAndLoadFromMemory (config, (const FcChar8 *) conf, TRUE))
- g_error ("Failed to parse fontconfig configuration");
-
- g_free (conf);
- g_free (path);
-
- FcConfigAppFontAddDir (config, (const FcChar8 *) dir);
-
- map = PANGO_FONT_MAP (pango_fc_font_map_new ());
- pango_fc_font_map_set_config (PANGO_FC_FONT_MAP (map), config);
-
- FcConfigDestroy (config);
-}
-
int
main (int argc, char *argv[])
{
@@ -144,6 +115,7 @@ main (int argc, char *argv[])
option_context = g_option_context_new ("");
g_option_context_add_main_entries (option_context, entries, NULL);
g_option_context_set_ignore_unknown_options (option_context, TRUE);
+
if (!g_option_context_parse (option_context, &argc, &argv, &error))
{
g_error ("failed to parse options: %s", error->message);
@@ -171,7 +143,7 @@ main (int argc, char *argv[])
g_file_get_contents (argv[1], &contents, &length, &error);
g_assert_no_error (error);
orig = g_bytes_new_take (contents, length);
- context = pango_font_map_create_context (map);
+ context = pango_font_map_create_context (pango_font_map_get_default ());
layout = pango_layout_deserialize (context, orig, PANGO_LAYOUT_DESERIALIZE_CONTEXT, &error);
g_assert_no_error (error);
@@ -192,11 +164,7 @@ main (int argc, char *argv[])
g_test_init (&argc, &argv, NULL);
if (!opt_fonts)
- {
- path = g_test_build_filename (G_TEST_DIST, "fonts", NULL);
- install_fonts (path);
- g_free (path);
- }
+ install_fonts (NULL);
path = g_test_build_filename (G_TEST_DIST, "layouts", NULL);
dir = g_dir_open (path, 0, &error);