diff options
Diffstat (limited to 'libfonts_encode_font_description.c')
-rw-r--r-- | libfonts_encode_font_description.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/libfonts_encode_font_description.c b/libfonts_encode_font_description.c new file mode 100644 index 0000000..8e0d87a --- /dev/null +++ b/libfonts_encode_font_description.c @@ -0,0 +1,105 @@ +/* See LICENSE file for copyright and license details. */ +#include "libfonts.h" +#include <ctype.h> +#include <errno.h> +#include <string.h> + +#define LIST_FIELDS(X)\ + X(foundry)\ + X(family_name)\ + X(weight_name)\ + X(slant)\ + X(setwidth_name)\ + X(add_style_name)\ + X(pixel_size)\ + X(point_size)\ + X(resolution_x)\ + X(resolution_y)\ + X(spacing)\ + X(average_width)\ + X(charset_registry)\ + X(charset_encoding) + + +static char * +encode(char *out, const char *s) +{ + for (; *s; s++) + *out++ = (*s == '-' ? '~' : *s); + return out; +} + +static char * +encode_range(char *out, const char *s) +{ + if (*s == '-') { + *out++ = '~'; + s++; + } + for (; *s; s++) + *out++ = (*s == '-' ? isdigit(s[-1]) ? '_' : '~' : *s); + return out; +} + +int +libfonts_encode_font_description(const struct libfonts_font_description *desc, char out[static 256]) +{ + size_t n = 1; + char *p; + + if (desc->private_font_name) { + if (strlen(desc->private_font_name) > 255) + goto einval; + stpcpy(out, desc->private_font_name); + return 0; + } + + if (desc->xlfd_version) + n += strlen(desc->xlfd_version) + 1; + +#define X(F)\ + if (!desc->F)\ + goto einval;\ + n += strlen(desc->F) + 1; + LIST_FIELDS(X) +#undef X + + if (desc->charset_subset) + n += strlen(desc->charset_subset) + 2; + + if (desc->unrecognised_fields) + n += strlen(desc->unrecognised_fields) + 1; + + if (n > 255) + goto einval; + + p = out; + if (desc->xlfd_version) { + *p++ = '+'; + p = encode(p, desc->xlfd_version); + } + +#define X(F)\ + *p++ = '-';\ + p = encode(p, desc->F); + LIST_FIELDS(X) +#undef X + + if (desc->charset_subset) { + *p++ = '['; + p = encode_range(p, desc->charset_subset); + *p++ = ']'; + } + + if (desc->unrecognised_fields) { + *p++ = '-'; + p = stpcpy(p, desc->unrecognised_fields); + } + + *p = '\0'; + return 0; + +einval: + errno = EINVAL; + return -1; +} |