summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn-Mark Bell <jmb@netsurf-browser.org>2022-05-22 21:36:08 +0100
committerJohn-Mark Bell <jmb@netsurf-browser.org>2022-05-22 21:36:08 +0100
commite58ebde8498df388975cf050382e4e9aadf2f050 (patch)
treebc0e67990895b9656deb846e22a873d7d6494513
parent7f8d135f7c3e2ba286cea01b4458c6e817f67794 (diff)
downloadlibrufl-e58ebde8498df388975cf050382e4e9aadf2f050.tar.gz
librufl-e58ebde8498df388975cf050382e4e9aadf2f050.tar.bz2
Expand non-UCS tests to check umap loading
These now take a configuration file defining the available encodings for each face and setting the expected number of umaps.
-rw-r--r--test/data/oldfminit/INDEX2
-rw-r--r--test/data/oldfminit/latin1.cfg28
-rw-r--r--test/harness-priv.h4
-rw-r--r--test/harness.c49
-rw-r--r--test/harness.h3
-rw-r--r--test/mocks.c16
-rw-r--r--test/oldfminit.c215
7 files changed, 307 insertions, 10 deletions
diff --git a/test/data/oldfminit/INDEX b/test/data/oldfminit/INDEX
index 5ea429d..b6a3e01 100644
--- a/test/data/oldfminit/INDEX
+++ b/test/data/oldfminit/INDEX
@@ -2,4 +2,4 @@
#
# Test Description
-Latin1 Simple Latin1 Encoding
+latin1.cfg Simple Latin1 Encoding
diff --git a/test/data/oldfminit/latin1.cfg b/test/data/oldfminit/latin1.cfg
new file mode 100644
index 0000000..646582a
--- /dev/null
+++ b/test/data/oldfminit/latin1.cfg
@@ -0,0 +1,28 @@
+# Configuration for Latin1 language fonts
+
+%expumaps Corpus.Bold 1
+%expumaps Corpus.Bold.Oblique 1
+%expumaps Corpus.Medium 1
+%expumaps Corpus.Medium.Oblique 1
+%expumaps Homerton.Bold 1
+%expumaps Homerton.Bold.Oblique 1
+%expumaps Homerton.Medium 1
+%expumaps Homerton.Medium.Oblique 1
+%expumaps Trinity.Bold 1
+%expumaps Trinity.Bold.Italic 1
+%expumaps Trinity.Medium 1
+%expumaps Trinity.Medium.Italic 1
+
+# Font name Encoding name Filename
+Corpus.Bold Latin1 Latin1
+Corpus.Bold.Oblique Latin1 Latin1
+Corpus.Medium Latin1 Latin1
+Corpus.Medium.Oblique Latin1 Latin1
+Homerton.Bold Latin1 Latin1
+Homerton.Bold.Oblique Latin1 Latin1
+Homerton.Medium Latin1 Latin1
+Homerton.Medium.Oblique Latin1 Latin1
+Trinity.Bold Latin1 Latin1
+Trinity.Bold.Italic Latin1 Latin1
+Trinity.Medium Latin1 Latin1
+Trinity.Medium.Italic Latin1 Latin1
diff --git a/test/harness-priv.h b/test/harness-priv.h
index 4c0615e..d27dd3d 100644
--- a/test/harness-priv.h
+++ b/test/harness-priv.h
@@ -28,10 +28,12 @@ typedef struct {
const char **encodings;
size_t n_encodings;
+ /* n_font_names * n_encodings entries */
+ char **encoding_filenames;
+
/* At most 256 active font handles */
rufl_test_harness_sized_font fonts[256];
int current_font;
- const char *encoding_filename;
char *buffer;
int buffer_flags;
diff --git a/test/harness.c b/test/harness.c
index af34cc9..eaf84a7 100644
--- a/test/harness.c
+++ b/test/harness.c
@@ -1,5 +1,6 @@
#include <assert.h>
#include <stdlib.h>
+#include <string.h>
#include "harness-priv.h"
@@ -7,8 +8,19 @@ rufl_test_harness_t *h = NULL;
static void rufl_test_harness_free(void)
{
+ size_t ni, ei;
+
free(h->font_names);
free(h->encodings);
+ if (h->encoding_filenames != NULL) {
+ for (ni = 0; ni != h->n_font_names; ni++) {
+ for (ei = 0; ei != h->n_encodings; ei++) {
+ free(h->encoding_filenames[
+ (ni * h->n_encodings) + ei]);
+ }
+ }
+ }
+ free(h->encoding_filenames);
free(h);
}
@@ -62,6 +74,9 @@ void rufl_test_harness_register_font(const char *name)
{
const char **names;
+ /* Encoding paths must be registered last */
+ assert(h->encoding_filenames == NULL);
+
names = realloc(h->font_names,
(h->n_font_names + 1) * sizeof(*names));
assert(names != NULL);
@@ -75,6 +90,9 @@ void rufl_test_harness_register_encoding(const char *encoding)
{
const char **encodings;
+ /* Encoding paths must be registered last */
+ assert(h->encoding_filenames == NULL);
+
encodings = realloc(h->encodings,
(h->n_encodings + 1) * sizeof(*encodings));
assert(encodings != NULL);
@@ -84,7 +102,34 @@ void rufl_test_harness_register_encoding(const char *encoding)
h->encodings[h->n_encodings++] = encoding;
}
-void rufl_test_harness_set_font_encoding(const char *path)
+void rufl_test_harness_set_font_encoding(const char *fontname,
+ const char *encoding, const char *path)
{
- h->encoding_filename = path;
+ size_t ni, ei;
+
+ if (h->encoding_filenames == NULL) {
+ h->encoding_filenames = calloc(
+ h->n_font_names * h->n_encodings,
+ sizeof(*h->encoding_filenames));
+ assert(h->encoding_filenames != NULL);
+ }
+
+ /* Find font index */
+ for (ni = 0; ni < h->n_font_names; ni++) {
+ if (strcmp(h->font_names[ni], fontname) == 0)
+ break;
+ }
+ assert(ni != h->n_font_names);
+
+ /* Find encoding index */
+ for (ei = 0; ei < h->n_encodings; ei++) {
+ if (strcmp(h->encodings[ei], encoding) == 0)
+ break;
+ }
+ assert(ei != h->n_encodings);
+
+ if (h->encoding_filenames[(ni * h->n_encodings) + ei] != NULL)
+ free(h->encoding_filenames[(ni * h->n_encodings) + ei]);
+ h->encoding_filenames[(ni * h->n_encodings) + ei] = strdup(path);
+ assert(h->encoding_filenames[(ni * h->n_encodings) + ei] != NULL);
}
diff --git a/test/harness.h b/test/harness.h
index bed4325..b62617f 100644
--- a/test/harness.h
+++ b/test/harness.h
@@ -4,6 +4,7 @@
void rufl_test_harness_init(int fm_version, bool fm_ucs, bool preload);
void rufl_test_harness_register_font(const char *name);
void rufl_test_harness_register_encoding(const char *encoding);
-void rufl_test_harness_set_font_encoding(const char *path);
+void rufl_test_harness_set_font_encoding(const char *fontname,
+ const char *encoding, const char *path);
#endif
diff --git a/test/mocks.c b/test/mocks.c
index 1c37431..01ffa7a 100644
--- a/test/mocks.c
+++ b/test/mocks.c
@@ -215,19 +215,27 @@ os_error *xfont_read_font_metrics (font_f font, font_bbox_info *bbox_info,
os_error *xfont_read_encoding_filename (font_f font, char *buffer, int size,
char **end)
{
+ const char *filename = NULL;
+ size_t ei;
+
if (font == 0)
return &font_bad_font_number;
if (h->fonts[font].refcnt == 0)
return &font_no_font;
- if (h->encoding_filename == NULL)
+ if (h->encoding_filenames == NULL)
+ return &font_encoding_not_found;
+ ei = h->fonts[font].encoding;
+ filename = h->encoding_filenames[
+ (h->fonts[font].name * h->n_encodings) + ei];
+ if (filename == NULL)
return &font_encoding_not_found;
- if (buffer == NULL || (size_t) size < strlen(h->encoding_filename) + 1)
+ if (buffer == NULL || (size_t) size < strlen(filename) + 1)
return &bad_parameters;
- strcpy(buffer, h->encoding_filename);
+ strcpy(buffer, filename);
if (end != NULL)
- *end = buffer + strlen(h->encoding_filename) + 1;
+ *end = buffer + strlen(filename) + 1;
return NULL;
}
diff --git a/test/oldfminit.c b/test/oldfminit.c
index 23eb501..4350949 100644
--- a/test/oldfminit.c
+++ b/test/oldfminit.c
@@ -1,14 +1,32 @@
#include <ftw.h>
+#include <libgen.h>
#include <stdio.h>
+#include <string.h>
#include <unistd.h>
#include "rufl.h"
+/* dirty! */
+#include "../src/rufl_internal.h"
+
#include "harness.h"
#include "testutils.h"
+struct expumap {
+ char *fontname;
+ size_t num_umaps;
+};
+
+struct cfg {
+ const char *datadir;
+
+ struct expumap *expumaps;
+ size_t n_expumaps;
+};
+
static char template[] = "/tmp/oldfminitXXXXXX";
static const char *ptmp = NULL;
+static struct cfg cfg;
static int ftw_cb(const char *path, const struct stat *sb,
int typeflag, struct FTW *ftwbuf)
@@ -24,12 +42,195 @@ static int ftw_cb(const char *path, const struct stat *sb,
static void cleanup(void)
{
+ if (cfg.expumaps != NULL) {
+ size_t i;
+
+ for (i = 0; i < cfg.n_expumaps; i++) {
+ free(cfg.expumaps[i].fontname);
+ }
+ free(cfg.expumaps);
+ }
+
if (ptmp == NULL)
return;
nftw(ptmp, ftw_cb, FOPEN_MAX, FTW_DEPTH | FTW_MOUNT | FTW_PHYS);
}
+static void parse_cfg(const char *path, struct cfg *cfg,
+ void (*cb)(struct cfg *cfg, const char *line, size_t len))
+{
+ FILE *fp;
+ char wbuf[4096];
+ size_t nleft = 0;
+
+ fp = fopen(path, "r");
+ assert(fp != NULL);
+
+ while (!feof(fp)) {
+ char buf[2048];
+ size_t nread;
+ const char *p, *s;
+
+ nread = fread(buf, 1, sizeof(buf), fp);
+ if (nread != sizeof(buf)) {
+ assert(ferror(fp) == 0);
+ }
+
+ memcpy(wbuf + nleft, buf, nread);
+ nleft += nread;
+
+ for (p = s = wbuf; p < wbuf + nleft; p++) {
+ if (*p == '\n') {
+ cb(cfg, s, p - s);
+ s = p+1;
+ }
+ }
+ if (s != wbuf + nleft) {
+ memmove(wbuf, s, p - s);
+ nleft = p - s;
+ } else {
+ nleft = 0;
+ }
+ assert(nleft < sizeof(buf));
+ }
+ assert(nleft == 0);
+
+ fclose(fp);
+}
+
+static void parse_expumaps(struct cfg *cfg, char *data, size_t len)
+{
+ char *p, *s;
+ const char *font = NULL, *count = NULL;
+ struct expumap *e;
+ size_t num_umaps;
+
+ for (p = s = data; p < data+len; p++) {
+ if (*p == ' ' || *p == '\t') {
+ *p = '\0';
+ if (s != p) {
+ if (font == NULL)
+ font = s;
+ else if (count == NULL)
+ count = s;
+ }
+ s = p+1;
+ }
+ }
+ if (count == NULL)
+ count = s;
+
+ num_umaps = strtoul(count, &p, 10);
+ assert((size_t)(p-count) == strlen(count));
+
+ e = realloc(cfg->expumaps, (cfg->n_expumaps + 1) * sizeof(*e));
+ assert(e != NULL);
+
+ cfg->expumaps = e;
+ cfg->expumaps[cfg->n_expumaps].fontname = strdup(font);
+ assert(cfg->expumaps[cfg->n_expumaps].fontname != NULL);
+ cfg->expumaps[cfg->n_expumaps].num_umaps = num_umaps;
+ cfg->n_expumaps++;
+}
+
+static void parse_directive(struct cfg *cfg, char *linecpy, size_t len)
+{
+ char *p, *s;
+ const char *directive = NULL;
+
+ for (p = s = linecpy; p < linecpy+len; p++) {
+ if (*p == ' ' || *p == '\t') {
+ *p = '\0';
+ if (s != p && directive == NULL) {
+ directive = s;
+ s = p+1;
+ break;
+ }
+ s = p+1;
+ }
+ }
+ if (directive == NULL)
+ directive = s;
+
+ if (strcmp("\%expumaps", directive) == 0) {
+ parse_expumaps(cfg, s, len - (s - linecpy));
+ }
+}
+
+static void parse_encoding(struct cfg *cfg, char *linecpy, size_t len)
+{
+ char *p, *s;
+ const char *font = NULL, *encoding = NULL, *file = NULL;
+ char *path;
+
+ for (p = s = linecpy; p < linecpy+len; p++) {
+ if (*p == ' ' || *p == '\t') {
+ *p = '\0';
+ if (s != p) {
+ if (font == NULL)
+ font = s;
+ else if (encoding == NULL)
+ encoding = s;
+ else if (file == NULL)
+ file = s;
+ }
+ s = p+1;
+ }
+ }
+ if (file == NULL)
+ file = s;
+
+ assert(font != NULL);
+ assert(encoding != NULL);
+ assert(file != NULL);
+
+ path = malloc(strlen(cfg->datadir) + strlen(file) + 2);
+ assert(path != NULL);
+ strcpy(path, cfg->datadir);
+ path[strlen(cfg->datadir)] = '/'; //XXX: platform-agnostic dirsep?
+ strcpy(path+strlen(cfg->datadir)+1, file);
+
+ rufl_test_harness_set_font_encoding(font, encoding, path);
+
+ free(path);
+}
+
+static void line_cb(struct cfg *cfg, const char *line, size_t len)
+{
+ char *linecpy;
+
+ if (len == 0 || line[0] == '#')
+ return;
+
+ linecpy = malloc(len + 1);
+ assert(linecpy != NULL);
+ memcpy(linecpy, line, len);
+ linecpy[len] = '\0';
+
+ if (line[0] == '%')
+ parse_directive(cfg, linecpy, len);
+ else
+ parse_encoding(cfg, linecpy, len);
+
+ free(linecpy);
+}
+
+static void read_config(const char *path, struct cfg *cfg)
+{
+ char *pathcpy;
+
+ pathcpy = strdup(path);
+ assert(pathcpy != NULL);
+
+ cfg->datadir = dirname(pathcpy);
+
+ parse_cfg(path, cfg, line_cb);
+
+ free(pathcpy);
+ cfg->datadir = NULL;
+}
+
int main(int argc, const char **argv)
{
int width, x;
@@ -47,13 +248,25 @@ int main(int argc, const char **argv)
chdir(ptmp);
rufl_test_harness_init(339, false, true);
- rufl_test_harness_set_font_encoding(argv[1]);
+
+ read_config(argv[1], &cfg);
assert(rufl_OK == rufl_init());
assert(NULL == rufl_fm_error);
assert(3 == rufl_family_list_entries);
assert(NULL != rufl_family_menu);
+ if (cfg.expumaps != NULL) {
+ size_t i, j;
+ for (i = 0; i != cfg.n_expumaps; i++) {
+ for (j = 0; j != rufl_font_list_entries; j++) {
+ if (strcmp(cfg.expumaps[i].fontname, rufl_font_list[j].identifier) == 0) {
+ assert(cfg.expumaps[i].num_umaps == rufl_font_list[j].num_umaps);
+ }
+ }
+ }
+ }
+
assert(rufl_OK == rufl_font_metrics("Corpus", rufl_WEIGHT_500,
&bbox, &xkern, &ykern, &italic,
&ascent, &descent, &xheight, &cap_height,