From 17a93f72f3343e6839f625972ba743ec61441c49 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sun, 8 Jan 2023 21:40:02 +0100 Subject: Partially implement libfonts_get_default_font, libfonts_get_{default,output}_rendering_settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- Makefile | 8 ++- common.h | 35 ++++++---- libfonts_confsplit__.c | 44 ++++++++++++ libfonts_get_default_font.c | 90 +++++++++++++++++++++++-- libfonts_get_default_rendering_settings.c | 82 ++++++++++++++++++++++- libfonts_get_output_rendering_settings.c | 108 ++++++++++++++++++++++++++++-- libfonts_getenv__.c | 14 ++++ libfonts_gethome__.c | 14 ++++ libfonts_getline__.c | 65 ++++++++++++++++++ libfonts_parse_aa__.c | 51 ++++++++++++++ libfonts_parse_double__.c | 23 +++++++ libfonts_parse_order__.c | 105 +++++++++++++++++++++++++++++ libfonts_parse_uint32__.c | 36 ++++++++++ 13 files changed, 648 insertions(+), 27 deletions(-) create mode 100644 libfonts_confsplit__.c create mode 100644 libfonts_getline__.c create mode 100644 libfonts_parse_aa__.c create mode 100644 libfonts_parse_double__.c create mode 100644 libfonts_parse_order__.c create mode 100644 libfonts_parse_uint32__.c diff --git a/Makefile b/Makefile index c915208..71676a7 100644 --- a/Makefile +++ b/Makefile @@ -31,15 +31,21 @@ PUBLIC_OBJ =\ OBJ =\ $(PUBLIC_OBJ)\ + libfonts_confsplit__.o\ libfonts_getenv__.o\ libfonts_gethome__.o\ + libfonts_getline__.o\ + libfonts_parse_aa__.o\ + libfonts_parse_double__.o\ + libfonts_parse_order__.o\ + libfonts_parse_uint32__.o HDR =\ common.h\ libfonts.h LOBJ = $(OBJ:.o=.lo) -TESTS = $(PUBLIC_OBJ:.o=.test) +TESTS = $(OBJ:.o=.test) all: libfonts.a libfonts.$(LIBEXT) $(TESTS) diff --git a/common.h b/common.h index 99298f1..082f806 100644 --- a/common.h +++ b/common.h @@ -2,6 +2,7 @@ #include "libfonts.h" #include #include +#include #include #include #include @@ -11,22 +12,23 @@ #include #include + #define DOUBLE_TOLERANCE 0.000001 #define LIST_RENDERING_SETTINGS(X, _)\ - X("dpi-x", dpi_x, 96) _\ - X("dpi-y", dpi_y, 96) _\ - X("ref-width", reference_width, 0) _\ - X("ref-height", reference_height, 0) _\ - X("subpixel-order", subpixel_order, LIBFONTS_SUBPIXEL_ORDER_UNKNOWN) _\ - X("greyscale-min", min_dpsqi_for_greyscale, 0) _\ - X("subpixel-min", min_dpsqi_for_subpixel, 0) _\ - X("h-grey-text-aa", horizontal_grey_text_antialiasing, LIBFONTS_ANTIALIASING_GREYSCALE) _\ - X("v-grey-text-aa", vertical_grey_text_antialiasing, LIBFONTS_ANTIALIASING_GREYSCALE) _\ - X("d-grey-text-aa", diagonal_grey_text_antialiasing, LIBFONTS_ANTIALIASING_GREYSCALE) _\ - X("h-coloured-text-aa", horizontal_colour_text_antialiasing, LIBFONTS_ANTIALIASING_GREYSCALE) _\ - X("v-coloured-text-aa", vertical_colour_text_antialiasing, LIBFONTS_ANTIALIASING_GREYSCALE) _\ - X("d-coloured-text-aa", diagonal_colour_text_antialiasing, LIBFONTS_ANTIALIASING_GREYSCALE) + X(0, "dpi-x", dpi_x, 96, libfonts_parse_double__) _\ + X(1, "dpi-y", dpi_y, 96, libfonts_parse_double__) _\ + X(2, "ref-width", reference_width, 0, libfonts_parse_uint32__) _\ + X(3, "ref-height", reference_height, 0, libfonts_parse_uint32__) _\ + X(4, "subpixel-order", subpixel_order, LIBFONTS_SUBPIXEL_ORDER_UNKNOWN, libfonts_parse_order__) _\ + X(5, "greyscale-min", min_dpsqi_for_greyscale, 0, libfonts_parse_double__) _\ + X(6, "subpixel-min", min_dpsqi_for_subpixel, 0, libfonts_parse_double__) _\ + X(7, "h-grey-text-aa", horizontal_grey_text_antialiasing, LIBFONTS_ANTIALIASING_GREYSCALE, libfonts_parse_aa__) _\ + X(8, "v-grey-text-aa", vertical_grey_text_antialiasing, LIBFONTS_ANTIALIASING_GREYSCALE, libfonts_parse_aa__) _\ + X(9, "d-grey-text-aa", diagonal_grey_text_antialiasing, LIBFONTS_ANTIALIASING_GREYSCALE, libfonts_parse_aa__) _\ + X(10, "h-coloured-text-aa", horizontal_colour_text_antialiasing, LIBFONTS_ANTIALIASING_GREYSCALE, libfonts_parse_aa__) _\ + X(11, "v-coloured-text-aa", vertical_colour_text_antialiasing, LIBFONTS_ANTIALIASING_GREYSCALE, libfonts_parse_aa__) _\ + X(12, "d-coloured-text-aa", diagonal_colour_text_antialiasing, LIBFONTS_ANTIALIASING_GREYSCALE, libfonts_parse_aa__) static inline void @@ -50,6 +52,13 @@ eq(double a, double b) const char *libfonts_getenv__(const char *name, struct libfonts_context *ctx); char *libfonts_gethome__(struct libfonts_context *ctx); +ssize_t libfonts_getline__(int fd, char **linep, char **bufp, size_t *sizep, size_t *offp, size_t *availp); +char *libfonts_confsplit__(char *line); + +int libfonts_parse_double__(double *outp, const char *value); +int libfonts_parse_uint32__(uint32_t *outp, const char *value); +int libfonts_parse_order__(enum libfonts_subpixel_order *outp, const char *value); +int libfonts_parse_aa__(enum libfonts_antialiasing *outp, const char *value); #ifdef TEST diff --git a/libfonts_confsplit__.c b/libfonts_confsplit__.c new file mode 100644 index 0000000..959a4b4 --- /dev/null +++ b/libfonts_confsplit__.c @@ -0,0 +1,44 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +char * +libfonts_confsplit__(char *line) +{ + size_t p, q; + + p = 0; + while (line[p] && line[p] != '=') + p += 1; + if (!line[p]) + return NULL; + + q = p; + while (q && isblank(line[q - 1])) + q -= 1; + if (!q) + return NULL; + line[q] = '\0'; + + p++; + while (isblank(line[p])) + p++; + if (!line[p]) + return NULL; + + return &line[p]; +} + + +#else + + +int +main(void) +{ + return 0; /* TODO add test */ +} + + +#endif diff --git a/libfonts_get_default_font.c b/libfonts_get_default_font.c index 98e60d7..f8809bc 100644 --- a/libfonts_get_default_font.c +++ b/libfonts_get_default_font.c @@ -15,6 +15,13 @@ getn(char **outp, const char *file_part1, size_t file_part1_len, const char *fil { size_t file_part2_len = strlen(file_part2); char *path; + int fd; + ssize_t len; + char *line, *buf = NULL; + size_t size = 0, off = 0, avail = 0; + char *value; + + *outp = NULL; if (file_part1_len > SIZE_MAX - file_part2_len - 1) goto enomem; @@ -29,14 +36,85 @@ getn(char **outp, const char *file_part1, size_t file_part1_len, const char *fil memcpy(path, file_part1, file_part1_len); memcpy(&path[file_part1_len], file_part2, file_part2_len + 1); - /* TODO - * sans-serif = $FONTNAME - * serif = $FONTNAME - * monospace = $FONTNAME - */ +open_again: + fd = open(path, O_RDONLY); + if (fd < 0) { + switch (errno) { + case EINTR: + goto open_again; + case EMFILE: + case ENFILE: + case ENOMEM: + case ENOSPC: + free(path); + return -1; + case EFBIG: + case EOVERFLOW: + case EISDIR: + case ELOOP: + case ENODEV: + case ENOTDIR: + case ENXIO: + /* TODO print warning using `ctx` */ + goto out; + default: + goto out; + } + } + for (;;) { + len = libfonts_getline__(fd, &line, &buf, &size, &off, &avail); + if (len < 0) { + if (errno == EINTR) + continue; + free(*outp); + *outp = NULL; + fail: + free(buf); + free(path); + close(fd); + return -1; + } + if (!len) + break; + line[len -= 1] = '\0'; + + while (isblank(*line)) { + line++; + len--; + } + if (!*line || *line == '#') + continue; + while (len && isblank(line[len - 1])) + len -= 1; + line[len] = '\0'; + + value = libfonts_confsplit__(line); + if (!value) { + /* TODO warning */ + continue; + } + + if (!strcmp(line, name)) { + if (*outp) { + /* TODO warning */ + free(*outp); + *outp = NULL; + } + *outp = strdup(value); + if (!*outp) + goto fail; + } else if (strcmp(line, "sans-serif") && strcmp(line, "serif") && strcmp(line, "monospace")) { + /* TODO warning */ + } + } + + free(buf); + close(fd); + +out: free(path); - return 0; + return *outp != NULL; } static int diff --git a/libfonts_get_default_rendering_settings.c b/libfonts_get_default_rendering_settings.c index 21de5a9..ebdc51c 100644 --- a/libfonts_get_default_rendering_settings.c +++ b/libfonts_get_default_rendering_settings.c @@ -9,6 +9,12 @@ getn(const char *file_part1, size_t file_part1_len, const char *file_part2, { size_t file_part2_len = strlen(file_part2); char *path; + int fd; + ssize_t len; + char *line, *buf = NULL; + size_t size = 0, off = 0, avail = 0; + char *value; + unsigned int found_fields = 0; if (file_part1_len > SIZE_MAX - file_part2_len - 1) goto enomem; @@ -23,8 +29,80 @@ getn(const char *file_part1, size_t file_part1_len, const char *file_part2, memcpy(path, file_part1, file_part1_len); memcpy(&path[file_part1_len], file_part2, file_part2_len + 1); - /* TODO (use LIST_RENDERING_SETTINGS) */ +open_again: + fd = open(path, O_RDONLY); + if (fd < 0) { + switch (errno) { + case EINTR: + goto open_again; + case EMFILE: + case ENFILE: + case ENOMEM: + case ENOSPC: + free(path); + return -1; + case EFBIG: + case EOVERFLOW: + case EISDIR: + case ELOOP: + case ENODEV: + case ENOTDIR: + case ENXIO: + /* TODO print warning using `ctx` */ + goto out; + default: + goto out; + } + } + + for (;;) { + len = libfonts_getline__(fd, &line, &buf, &size, &off, &avail); + if (len < 0) { + if (errno == EINTR) + continue; + free(buf); + free(path); + close(fd); + return -1; + } + if (!len) + break; + line[len -= 1] = '\0'; + + while (isblank(*line)) + line++; + if (!*line || *line == '#') + continue; + while (len && isblank(line[len - 1])) + len -= 1; + line[len] = '\0'; + + value = libfonts_confsplit__(line); + if (!value) { + /* TODO warning */ + continue; + } + +#define X(INDEX, CONFNAME, CNAME, DEFVAL, PARSER)\ + if (!strcmp(line, CONFNAME)) {\ + if (found_fields & (1U << INDEX)) {\ + /* TODO warning */\ + }\ + found_fields |= (1U << INDEX);\ + if (!PARSER(&settings->CNAME, value)) {\ + /* TODO warning */\ + }\ + } else + LIST_RENDERING_SETTINGS(X,) { + /* TODO warning */ + } +#undef X + } + free(buf); + close(fd); + +out: free(path); return 1; } @@ -47,7 +125,7 @@ libfonts_get_default_rendering_settings(struct libfonts_rendering_settings *sett size_t len; if (settings) { -#define X(CONFNAME, CNAME, DEFVAL) settings->CNAME = DEFVAL +#define X(INDEX, CONFNAME, CNAME, DEFVAL, PARSER) settings->CNAME = DEFVAL LIST_RENDERING_SETTINGS(X, ;); #undef X } diff --git a/libfonts_get_output_rendering_settings.c b/libfonts_get_output_rendering_settings.c index f634550..2cecf3c 100644 --- a/libfonts_get_output_rendering_settings.c +++ b/libfonts_get_output_rendering_settings.c @@ -9,6 +9,15 @@ getn(const char *file_part1, size_t file_part1_len, const char *file_part2, { size_t file_part2_len = strlen(file_part2); char *path; + int fd; + ssize_t len; + char *line, *buf = NULL; + size_t size = 0, off = 0, avail = 0; + int found = 0; + int in_the_section = 0; + int in_a_section = 0; + char *value; + unsigned int found_fields = 0; if (file_part1_len > SIZE_MAX - file_part2_len - 1) goto enomem; @@ -23,12 +32,101 @@ getn(const char *file_part1, size_t file_part1_len, const char *file_part2, memcpy(path, file_part1, file_part1_len); memcpy(&path[file_part1_len], file_part2, file_part2_len + 1); - /* TODO aliases should be declarable above the first "[$name]" */ - /* TODO look for "[$name]" */ - /* TODO (use LIST_RENDERING_SETTINGS) */ +open_again: + fd = open(path, O_RDONLY); + if (fd < 0) { + switch (errno) { + case EINTR: + goto open_again; + case EMFILE: + case ENFILE: + case ENOMEM: + case ENOSPC: + free(path); + return -1; + case EFBIG: + case EOVERFLOW: + case EISDIR: + case ELOOP: + case ENODEV: + case ENOTDIR: + case ENXIO: + /* TODO print warning using `ctx` */ + goto out; + default: + goto out; + } + } + + for (;;) { + len = libfonts_getline__(fd, &line, &buf, &size, &off, &avail); + if (len < 0) { + if (errno == EINTR) + continue; + free(buf); + free(path); + close(fd); + return -1; + } + if (!len) + break; + line[len -= 1] = '\0'; + + while (isblank(*line)) { + line++; + len--; + } + if (!*line || *line == '#') + continue; + while (len && isblank(line[len - 1])) + len -= 1; + line[len] = '\0'; + + if (line[0] == '[' && line[len - 1] == ']') { + in_a_section = 1; + line = &line[1]; + len -= 2; + line[len] = '\0'; + found |= in_the_section = !strcmp(line, name); + found_fields = 0; + + } else if (!in_a_section) { + value = libfonts_confsplit__(line); + if (!value) { + /* TODO warning */ + continue; + } + /* TODO aliases should be declarable above the first "[%s]" */ + + } else if (in_the_section) { + value = libfonts_confsplit__(line); + if (!value) { + /* TODO warning */ + continue; + } +#define X(INDEX, CONFNAME, CNAME, DEFVAL, PARSER)\ + if (!strcmp(line, CONFNAME)) {\ + if (found_fields & (1U << INDEX)) {\ + /* TODO warning */\ + }\ + found_fields |= (1U << INDEX);\ + if (!PARSER(&settings->CNAME, value)) {\ + /* TODO warning */\ + }\ + } else + LIST_RENDERING_SETTINGS(X,) { + /* TODO warning */ + } +#undef X + } + } + + free(buf); + close(fd); +out: free(path); - return 1; + return found; } static int @@ -54,7 +152,7 @@ libfonts_get_output_rendering_settings(struct libfonts_rendering_settings *setti } if (settings) { -#define X(CONFNAME, CNAME, DEFVAL) settings->CNAME = DEFVAL +#define X(INDEX, CONFNAME, CNAME, DEFVAL, PARSER) settings->CNAME = DEFVAL LIST_RENDERING_SETTINGS(X, ;); #undef X } diff --git a/libfonts_getenv__.c b/libfonts_getenv__.c index d998337..8ea0ce6 100644 --- a/libfonts_getenv__.c +++ b/libfonts_getenv__.c @@ -1,5 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include "common.h" +#ifndef TEST const char * @@ -28,3 +29,16 @@ ok: return *envp; return ctx->ignore_process_environ ? NULL : getenv(name); } + + +#else + + +int +main(void) +{ + return 0; /* TODO add test */ +} + + +#endif diff --git a/libfonts_gethome__.c b/libfonts_gethome__.c index 902029f..f05dbfb 100644 --- a/libfonts_gethome__.c +++ b/libfonts_gethome__.c @@ -1,5 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include "common.h" +#ifndef TEST char * @@ -38,3 +39,16 @@ libfonts_gethome__(struct libfonts_context *ctx) free(buf); return ret; } + + +#else + + +int +main(void) +{ + return 0; /* TODO add test */ +} + + +#endif diff --git a/libfonts_getline__.c b/libfonts_getline__.c new file mode 100644 index 0000000..58b1adc --- /dev/null +++ b/libfonts_getline__.c @@ -0,0 +1,65 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +/* alternative to getline(3) that does not have a line length limit */ + +ssize_t +libfonts_getline__(int fd, char **linep, char **bufp, size_t *sizep, size_t *offp, size_t *availp) +{ + size_t len, size; + ssize_t r; + char *new; + + for (;;) { + for (len = 0; *offp + len < *availp; len++) { + if ((*bufp)[*offp + len] == '\n') { + *linep = &(*bufp)[*offp]; + *offp += len += 1; + return (ssize_t)len; + } + } + + if (*offp) { + memmove(&(*bufp)[0], &(*bufp)[*offp], *availp -= *offp); + *offp = 0; + } + + if (*availp == *sizep) { + if (*sizep > SIZE_MAX - 128) + goto enomem; + size = *sizep + 128; + new = realloc(*bufp, size); + if (!new) { + enomem: + errno = ENOMEM; + return -1; + } + *bufp = new; + *sizep = size; + } + r = read(fd, &(*bufp)[*availp], *sizep - *availp); + if (r <= 0) { + if (r < 0) + return -1; + *linep = *bufp; + *offp = *availp; + return (ssize_t)*availp; + } + *availp += (size_t)r; + } +} + + +#else + + +int +main(void) +{ + return 0; /* TODO add test */ +} + + +#endif diff --git a/libfonts_parse_aa__.c b/libfonts_parse_aa__.c new file mode 100644 index 0000000..5946b1c --- /dev/null +++ b/libfonts_parse_aa__.c @@ -0,0 +1,51 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +#define LIST_ANTIALIASINGS(X)\ + X(LIBFONTS_ANTIALIASING_UNSPECIFIED, "unspecified")\ + X(LIBFONTS_ANTIALIASING_NONE, "none")\ + X(LIBFONTS_ANTIALIASING_NONE, "aliased")\ + X(LIBFONTS_ANTIALIASING_GREYSCALE, "greyscale")\ + X(LIBFONTS_ANTIALIASING_GREYSCALE, "grayscale")\ + X(LIBFONTS_ANTIALIASING_GREYSCALE, "grey")\ + X(LIBFONTS_ANTIALIASING_GREYSCALE, "gray")\ + X(LIBFONTS_ANTIALIASING_GREYSCALE, "antialiased")\ + X(LIBFONTS_ANTIALIASING_GREYSCALE_FORCED, "greyscale!")\ + X(LIBFONTS_ANTIALIASING_GREYSCALE_FORCED, "grayscale!")\ + X(LIBFONTS_ANTIALIASING_GREYSCALE_FORCED, "grey!")\ + X(LIBFONTS_ANTIALIASING_GREYSCALE_FORCED, "gray!")\ + X(LIBFONTS_ANTIALIASING_GREYSCALE_FORCED, "antialiased!")\ + X(LIBFONTS_ANTIALIASING_SUBPIXEL, "subpixel")\ + X(LIBFONTS_ANTIALIASING_SUBPIXEL, "glitter")\ + X(LIBFONTS_ANTIALIASING_SUBPIXEL_FORCED, "subpixel!")\ + X(LIBFONTS_ANTIALIASING_SUBPIXEL_FORCED, "glitter!") + +int +libfonts_parse_aa__(enum libfonts_antialiasing *outp, const char *value) +{ +#define X(C, S)\ + if (!strcasecmp(value, S)) {\ + *outp = C;\ + } else + LIST_ANTIALIASINGS(X) { + return 0; + } +#undef X + return 1; + +} + + +#else + + +int +main(void) +{ + return 0; /* TODO add test */ +} + + +#endif diff --git a/libfonts_parse_double__.c b/libfonts_parse_double__.c new file mode 100644 index 0000000..30fc61d --- /dev/null +++ b/libfonts_parse_double__.c @@ -0,0 +1,23 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libfonts_parse_double__(double *outp, const char *value) +{ + return 0; /* TODO implement */ +} + + +#else + + +int +main(void) +{ + return 0; /* TODO add test */ +} + + +#endif diff --git a/libfonts_parse_order__.c b/libfonts_parse_order__.c new file mode 100644 index 0000000..53b4aa4 --- /dev/null +++ b/libfonts_parse_order__.c @@ -0,0 +1,105 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +#define LIST_SUBPIXEL_ORDERS(X)\ + X(LIBFONTS_SUBPIXEL_ORDER_UNKNOWN, "unknown")\ + X(LIBFONTS_SUBPIXEL_ORDER_NONRGB, "non-rgb")\ + X(LIBFONTS_SUBPIXEL_ORDER_NONLINEAR, "non-linear")\ + X(LIBFONTS_SUBPIXEL_ORDER_OTHER, "other")\ + X(LIBFONTS_SUBPIXEL_ORDER_RGB, "rgb")\ + X(LIBFONTS_SUBPIXEL_ORDER_R_G_B, "r:g:b")\ + X(LIBFONTS_SUBPIXEL_ORDER_R_G_B, "vrgb")\ + X(LIBFONTS_SUBPIXEL_ORDER_BGR, "bgr")\ + X(LIBFONTS_SUBPIXEL_ORDER_B_G_R, "b:g:r")\ + X(LIBFONTS_SUBPIXEL_ORDER_B_G_R, "vbgr")\ + X(LIBFONTS_SUBPIXEL_ORDER_GBR, "gbr")\ + X(LIBFONTS_SUBPIXEL_ORDER_G_B_R, "g:b:r")\ + X(LIBFONTS_SUBPIXEL_ORDER_G_B_R, "vgbr")\ + X(LIBFONTS_SUBPIXEL_ORDER_RBG, "rbg")\ + X(LIBFONTS_SUBPIXEL_ORDER_R_B_G, "r:b:g")\ + X(LIBFONTS_SUBPIXEL_ORDER_R_B_G, "vrbg")\ + X(LIBFONTS_SUBPIXEL_ORDER_BRG, "brg")\ + X(LIBFONTS_SUBPIXEL_ORDER_B_R_G, "b:r:g")\ + X(LIBFONTS_SUBPIXEL_ORDER_B_R_G, "vbrg")\ + X(LIBFONTS_SUBPIXEL_ORDER_GRB, "grb")\ + X(LIBFONTS_SUBPIXEL_ORDER_G_R_B, "g:r:b")\ + X(LIBFONTS_SUBPIXEL_ORDER_G_R_B, "vgrb")\ + X(LIBFONTS_SUBPIXEL_ORDER_RR_GB, "rr:gb")\ + X(LIBFONTS_SUBPIXEL_ORDER_GR_BR, "gr:br")\ + X(LIBFONTS_SUBPIXEL_ORDER_BG_RR, "bg:rr")\ + X(LIBFONTS_SUBPIXEL_ORDER_RB_RG, "rb:rg")\ + X(LIBFONTS_SUBPIXEL_ORDER_RR_BG, "rr:bg")\ + X(LIBFONTS_SUBPIXEL_ORDER_BR_GR, "br:gr")\ + X(LIBFONTS_SUBPIXEL_ORDER_GB_RR, "gb:rr")\ + X(LIBFONTS_SUBPIXEL_ORDER_RG_RB, "rg:rb")\ + X(LIBFONTS_SUBPIXEL_ORDER_GG_RB, "gg:rb")\ + X(LIBFONTS_SUBPIXEL_ORDER_RG_BG, "rg:bg")\ + X(LIBFONTS_SUBPIXEL_ORDER_BR_GG, "br:gg")\ + X(LIBFONTS_SUBPIXEL_ORDER_GB_GR, "gb:gr")\ + X(LIBFONTS_SUBPIXEL_ORDER_GG_BR, "gg:br")\ + X(LIBFONTS_SUBPIXEL_ORDER_BG_RG, "bg:rg")\ + X(LIBFONTS_SUBPIXEL_ORDER_RB_GG, "rb:gg")\ + X(LIBFONTS_SUBPIXEL_ORDER_GR_GB, "gr:gb")\ + X(LIBFONTS_SUBPIXEL_ORDER_BB_RG, "bb:rg")\ + X(LIBFONTS_SUBPIXEL_ORDER_RB_GB, "rb:gb")\ + X(LIBFONTS_SUBPIXEL_ORDER_GR_BB, "gr:bb")\ + X(LIBFONTS_SUBPIXEL_ORDER_BG_BR, "bg:br")\ + X(LIBFONTS_SUBPIXEL_ORDER_BB_GR, "bb:gr")\ + X(LIBFONTS_SUBPIXEL_ORDER_GB_RB, "gb:rb")\ + X(LIBFONTS_SUBPIXEL_ORDER_RG_BB, "rg:bb")\ + X(LIBFONTS_SUBPIXEL_ORDER_BR_BG, "br:bg")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_RR_GB, "balanced rr:gb")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_GR_BR, "balanced gr:br")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_BG_RR, "balanced bg:rr")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_RB_RG, "balanced rb:rg")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_RR_BG, "balanced rr:bg")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_BR_GR, "balanced br:gr")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_GB_RR, "balanced gb:rr")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_RG_RB, "balanced rg:rb")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_GG_RB, "balanced gg:rb")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_RG_BG, "balanced rg:bg")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_BR_GG, "balanced br:gg")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_GB_GR, "balanced gb:gr")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_GG_BR, "balanced gg:br")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_BG_RG, "balanced bg:rg")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_RB_GG, "balanced rb:gg")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_GR_GB, "balanced gr:gb")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_BB_RG, "balanced bb:rg")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_RB_GB, "balanced rb:gb")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_GR_BB, "balanced gr:bb")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_BG_BR, "balanced bg:br")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_BB_GR, "balanced bb:gr")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_GB_RB, "balanced gb:rb")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_RG_BB, "balanced rg:bb")\ + X(LIBFONTS_SUBPIXEL_ORDER_BALANCED_BR_BG, "balanced br:bg") + +int +libfonts_parse_order__(enum libfonts_subpixel_order *outp, const char *value) +{ +#define X(C, S)\ + if (!strcasecmp(value, S)) {\ + *outp = C;\ + } else + LIST_SUBPIXEL_ORDERS(X) { + *outp = LIBFONTS_SUBPIXEL_ORDER_OTHER; + return 0; + } +#undef X + return 1; + +} + + +#else + + +int +main(void) +{ + return 0; /* TODO add test */ +} + + +#endif diff --git a/libfonts_parse_uint32__.c b/libfonts_parse_uint32__.c new file mode 100644 index 0000000..f87f19e --- /dev/null +++ b/libfonts_parse_uint32__.c @@ -0,0 +1,36 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +int +libfonts_parse_uint32__(uint32_t *outp, const char *value) +{ + uint32_t out = 0, digit; + value += *value == '+'; + if (!*value) + return 0; + while (isdigit(*value)) { + digit = (*value & 15); + if (out > (UINT32_C(0xFFFFFFFF) - digit) / 10) + return 0; + out = out * 10 + digit; + } + if (*value) + return 0; + *outp = out; + return 1; +} + + +#else + + +int +main(void) +{ + return 0; /* TODO add test */ +} + + +#endif -- cgit v1.2.3-70-g09d2