diff options
author | John-Mark Bell <jmb@netsurf-browser.org> | 2022-05-22 21:36:08 +0100 |
---|---|---|
committer | John-Mark Bell <jmb@netsurf-browser.org> | 2022-05-22 21:36:08 +0100 |
commit | e58ebde8498df388975cf050382e4e9aadf2f050 (patch) | |
tree | bc0e67990895b9656deb846e22a873d7d6494513 | |
parent | 7f8d135f7c3e2ba286cea01b4458c6e817f67794 (diff) | |
download | librufl-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/INDEX | 2 | ||||
-rw-r--r-- | test/data/oldfminit/latin1.cfg | 28 | ||||
-rw-r--r-- | test/harness-priv.h | 4 | ||||
-rw-r--r-- | test/harness.c | 49 | ||||
-rw-r--r-- | test/harness.h | 3 | ||||
-rw-r--r-- | test/mocks.c | 16 | ||||
-rw-r--r-- | test/oldfminit.c | 215 |
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, |