aboutsummaryrefslogtreecommitdiffstats
path: root/demo.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2021-08-13 16:57:18 +0200
committerMattias Andrée <maandree@kth.se>2021-08-13 16:57:18 +0200
commit513ee4f15567048b619848edb092cdc4f33fe1c0 (patch)
tree46a58fa34f1bd5307e4e4267f53c8db1f62acfde /demo.c
downloadlibparsepsf-513ee4f15567048b619848edb092cdc4f33fe1c0.tar.gz
libparsepsf-513ee4f15567048b619848edb092cdc4f33fe1c0.tar.bz2
libparsepsf-513ee4f15567048b619848edb092cdc4f33fe1c0.tar.xz
First commit1.0
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r--demo.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/demo.c b/demo.c
new file mode 100644
index 0000000..dcefc36
--- /dev/null
+++ b/demo.c
@@ -0,0 +1,203 @@
+/* See LICENSE file for copyright and license details. */
+#include "libparsepsf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static size_t
+readfile(int fd, char **datap, size_t *sizep)
+{
+ size_t len = 0;
+ ssize_t r;
+ for (;;) {
+ if (len == *sizep) {
+ *datap = realloc(*datap, *sizep += 4096);
+ if (!*datap) {
+ perror("realloc");
+ exit(1);
+ }
+ }
+ r = read(fd, &(*datap)[len], *sizep - len);
+ if (r <= 0) {
+ if (!r)
+ break;
+ perror("read");
+ exit(1);
+ }
+ len += (size_t)r;
+ }
+ return len;
+}
+
+
+static uint8_t *
+genreplacement(const struct libparsepsf_font *font)
+{
+ size_t glyph, size, i, linesize, xoff, yoff;
+ int invert = 0, round = 0;
+ uint8_t *data, xbit;
+
+ glyph = libparsepsf_get_glyph(font, "�", NULL, NULL);
+ if (!glyph) {
+ invert = 1;
+ round = 1;
+ glyph = libparsepsf_get_glyph(font, "?", NULL, NULL);
+ if (!glyph) {
+ round = 0;
+ glyph = libparsepsf_get_glyph(font, " ", NULL, NULL);
+ }
+ }
+ glyph -= (glyph ? 1 : 0);
+
+ linesize = font->width / 8 + (font->width % 8 ? 1 : 0);
+ size = linesize * font->height;
+ data = malloc(size);
+ if (!data) {
+ perror("malloc");
+ exit(1);
+ }
+
+ memcpy(data, &font->glyph_data[glyph * size], size);
+ if (invert)
+ for (i = 0; i < size; i++)
+ data[i] ^= 0xFF;
+ if (round) {
+ yoff = (font->height - 1) * linesize;
+ xoff = (font->width - 1) / 8;
+ xbit = 0x80 >> ((font->width - 1) % 8);
+ data[0] ^= 0x80;
+ data[yoff] ^= 0x80;
+ data[xoff] ^= xbit;
+ data[yoff + xoff] ^= xbit;
+ }
+
+ return data;
+}
+
+
+static void
+printglyphrow(const struct libparsepsf_font *font, const uint8_t *gd, const char *bg, const char *fg)
+{
+ uint8_t bit;
+ size_t x;
+
+ bit = 0x80;
+ for (x = 0; x < font->width; x++) {
+ printf("%s", (*gd & bit) ? fg : bg);
+ bit >>= 1;
+ if (!bit) {
+ bit = 0x80;
+ gd = &gd[1];
+ }
+ }
+}
+
+
+static void
+printglyph(const struct libparsepsf_font *font, size_t glyph, const char *bg, const char *fg)
+{
+ const uint8_t *gd;
+ size_t width = font->width / 8 + (font->width % 8 ? 1 : 0);
+ size_t glyphsize = width * font->height;
+ size_t y;
+
+ if (glyph > font->num_glyphs) {
+ fprintf(stderr, "glyph does not exist!\n");
+ exit(1);
+ }
+
+ for (y = 0; y < font->height; y++) {
+ gd = &font->glyph_data[glyph * glyphsize + y * width];
+ printglyphrow(font, gd, bg, fg);
+ printf("\033[0m\n");
+ }
+}
+
+
+static void
+printline(const struct libparsepsf_font *font, const char *line, size_t linelen)
+{
+ const char *c, *bg, *fg;
+ const uint8_t *gd;
+ size_t width = font->width / 8 + (font->width % 8 ? 1 : 0);
+ size_t glyphsize = width * font->height;
+ size_t glyph, rem, y;
+ uint8_t *replacement = genreplacement(font);
+
+ for (y = 0; y < font->height; y++) {
+ rem = linelen;
+ for (c = line; rem;) {
+ glyph = libparsepsf_get_glyph(font, c, &rem, &c);
+ if (!glyph) {
+ do {
+ c = &c[1];
+ rem -= 1;
+ } while ((*c & 0xC0) == 0x80);
+ bg = "\033[1;30;40m[]";
+ fg = "\033[1;31;41m[]";
+ gd = &replacement[y * width];
+ } else {
+ glyph -= 1;
+ bg = "\033[1;30;40m[]";
+ fg = "\033[1;37;47m[]";
+ gd = &font->glyph_data[glyph * glyphsize + y * width];
+ }
+ printglyphrow(font, gd, bg, fg);
+ }
+ printf("\033[0m\n");
+ }
+
+ free(replacement);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ unsigned long int glyph;
+ uint32_t uver;
+ char *data = NULL;
+ size_t len, size = 0;
+ struct libparsepsf_font font;
+
+ if (argc) {
+ argc--;
+ argv++;
+ }
+
+ len = readfile(STDIN_FILENO, &data, &size);
+ if (libparsepsf_parse_font(data, len, &font, &uver)) {
+ perror("libparsepsf_parse_font");
+ free(data);
+ exit(1);
+ }
+ free(data);
+
+ if (uver) {
+ fprintf(stderr, "WARNING: Font format version is not fully supported: "
+ "version 2.%lu\n", (unsigned long int)uver);
+ }
+
+ printf("#glyphs = %zu\n", font.num_glyphs);
+ printf("width = %zu\n", font.width);
+ printf("height = %zu\n", font.height);
+
+ if (!argc) {
+ printline(&font, "", 1);
+ } else if (argc == 2 && !strcmp(argv[0], "-g")) {
+ glyph = strtoul(argv[1], NULL, 0);
+ printglyph(&font, (size_t)glyph, "\033[1;30;40m[]", "\033[1;37;47m[]");
+ } else if (argc == 2 && !strcmp(argv[0], "-x")) {
+ glyph = strtoul(argv[1], NULL, 16);
+ printglyph(&font, (size_t)glyph, "\033[1;30;40m[]", "\033[1;37;47m[]");
+ } else {
+ for (; argc--; argv++)
+ printline(&font, *argv, strlen(*argv));
+ }
+
+ libparsepsf_destroy_font(&font);
+ return 0;
+}