Module Name: xsrc Committed By: uwe Date: Wed Jun 8 19:19:42 UTC 2022
Modified Files: xsrc/local/programs/bdfload: bdfload.c Log Message: bdfload: Teach it to write wsf font files. wsfontload(8) now groks simple "wsf" file format - that is basically a header of kinda struct wsdisplay_font but with string fields embedded and numeric fields in little-endian and font data afterwards. Teach bdfload to write out such files if -o file.wsf argument is specified. While here fix a couple of bugs too (sorry, should have been separate commits). Fix an off by one in numchars calculations. Fix the type of buflen. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 xsrc/local/programs/bdfload/bdfload.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: xsrc/local/programs/bdfload/bdfload.c diff -u xsrc/local/programs/bdfload/bdfload.c:1.2 xsrc/local/programs/bdfload/bdfload.c:1.3 --- xsrc/local/programs/bdfload/bdfload.c:1.2 Mon May 9 15:47:27 2022 +++ xsrc/local/programs/bdfload/bdfload.c Wed Jun 8 19:19:42 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: bdfload.c,v 1.2 2022/05/09 15:47:27 uwe Exp $ */ +/* $NetBSD: bdfload.c,v 1.3 2022/06/08 19:19:42 uwe Exp $ */ /* * Copyright (c) 2018 Michael Lorenz @@ -41,17 +41,76 @@ #include <dev/wscons/wsconsio.h> +/* + * wsdisplay_font but with strings embedded and integer fields in + * little endian + */ +struct wsfthdr { + char magic[4]; /* "WSFT" */ + char name[64]; + uint32_t firstchar; + uint32_t numchars; + uint32_t encoding; + uint32_t fontwidth; + uint32_t fontheight; + uint32_t stride; + uint32_t bitorder; + uint32_t byteorder; +}; + + +const struct encmap { + const char *name; + int encoding; +} encmap[] = { + { "cp437", WSDISPLAY_FONTENC_IBM }, + { "ibm", WSDISPLAY_FONTENC_IBM }, + { "iso", WSDISPLAY_FONTENC_ISO }, + { "iso-8859-1", WSDISPLAY_FONTENC_ISO }, + { "iso-8859-2", WSDISPLAY_FONTENC_ISO2 }, + { "iso-8859-7", WSDISPLAY_FONTENC_ISO7 }, + { "iso2", WSDISPLAY_FONTENC_ISO2 }, + { "iso7", WSDISPLAY_FONTENC_ISO7 }, + { "iso8859-1", WSDISPLAY_FONTENC_ISO }, + { "iso8859-2", WSDISPLAY_FONTENC_ISO2 }, + { "iso8859-7", WSDISPLAY_FONTENC_ISO7 }, + { "koi8-r", WSDISPLAY_FONTENC_KOI8_R }, + { "koi8r", WSDISPLAY_FONTENC_KOI8_R }, + { "latin-1", WSDISPLAY_FONTENC_ISO }, + { "latin-2", WSDISPLAY_FONTENC_ISO2 }, + { "latin1", WSDISPLAY_FONTENC_ISO }, + { "latin2", WSDISPLAY_FONTENC_ISO2 }, + { "pcvt", WSDISPLAY_FONTENC_PCVT }, + { NULL, -1 } +}; + +const char * const encname[] = { +#define _ENC(_e) [_e] = #_e + _ENC(WSDISPLAY_FONTENC_ISO), + _ENC(WSDISPLAY_FONTENC_IBM), + _ENC(WSDISPLAY_FONTENC_PCVT), + _ENC(WSDISPLAY_FONTENC_ISO7), + _ENC(WSDISPLAY_FONTENC_ISO2), + _ENC(WSDISPLAY_FONTENC_KOI8_R), +}; + + +const char *ofile = NULL; +int encoding = -1; + + void interpret(FILE *foo) { - char line[128], *arg, name[64] = "foop", *buffer, buflen = -1; + char line[128], *arg, name[64] = "foop", *buffer; + int buflen = -1; int len, in_char = 0, current = -1, stride = 0, charsize = 0; int width, height, x, y, num; int first = 255, last = 0; int left, top, lines; int bl = 255, bt = 255, br = -1, bb = -1; struct wsdisplay_font f; - int fdev; + int status; while (fgets(line, sizeof(line), foo) != NULL) { int i = 0; @@ -84,7 +143,7 @@ interpret(FILE *foo) } charsize = height * stride; buflen = 256 * charsize; - buffer = malloc(buflen); + buffer = calloc(1, buflen); if (buffer == NULL) { printf("failed to allocate %dKB for glyphs\n", buflen); @@ -144,37 +203,130 @@ interpret(FILE *foo) } } printf("range %d to %d\n", first, last); + printf("encoding: %s\n", encname[encoding]); printf("actual box: %d %d %d %d\n", bl, bt, br, bb); + /* now stuff it into a something wsfont understands */ f.fontwidth = width /*(width + 3) & ~3*/; f.fontheight = height; f.firstchar = first; - f.numchars = last - first; + f.numchars = last - first + 1; f.stride = stride; - f.encoding = WSDISPLAY_FONTENC_ISO; + f.encoding = encoding; f.name = name; f.bitorder = WSDISPLAY_FONTORDER_L2R; f.byteorder = WSDISPLAY_FONTORDER_L2R; f.data = &buffer[first * charsize]; - fdev = open("/dev/wsfont", O_RDWR, 0); - if (fdev < 0) errx(1, "unable to open /dev/wsfont"); - ioctl(fdev, WSDISPLAYIO_LDFONT, &f); - close(fdev); + if (ofile == NULL) { + int fdev = open("/dev/wsfont", O_RDWR, 0); + if (fdev < 0) + err(EXIT_FAILURE, "/dev/wsfont"); + status = ioctl(fdev, WSDISPLAYIO_LDFONT, &f); + if (status != 0) + err(EXIT_FAILURE, "WSDISPLAYIO_LDFONT"); + close(fdev); + } + else { + struct wsfthdr h; + + memset(&h, 0, sizeof(h)); + strncpy(h.magic, "WSFT", sizeof(h.magic)); + strncpy(h.name, f.name, sizeof(h.name)); + h.firstchar = htole32(f.firstchar); + h.numchars = htole32(f.numchars); + h.encoding = htole32(f.encoding); + h.fontwidth = htole32(f.fontwidth); + h.fontheight = htole32(f.fontheight); + h.stride = htole32(f.stride); + h.bitorder = htole32(f.bitorder); + h.byteorder = htole32(f.byteorder); + + int wsfd = open(ofile, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (wsfd < 0) + err(EXIT_FAILURE, "%s", ofile); + + ssize_t nwritten; + nwritten = write(wsfd, &h, sizeof(h)); + if (nwritten < 0) + err(EXIT_FAILURE, "%s", ofile); + if (nwritten != sizeof(h)) + errx(EXIT_FAILURE, "%s: partial write", ofile); + + nwritten = write(wsfd, buffer, buflen); + if (nwritten < 0) + err(EXIT_FAILURE, "%s", ofile); + if (nwritten != buflen) + errx(EXIT_FAILURE, "%s: partial write", ofile); + close(wsfd); + } } -void + +__dead void +usage() +{ + fprintf(stderr, "usage: bdfload [-e encoding] [-o ofile.wsf] font.bdf\n"); + exit(EXIT_FAILURE); +} + +int main(int argc, char *argv[]) { FILE *foo; - if (argc > 1) { - foo = fopen(argv[1], "r"); - if (foo == NULL) { - printf("fopen error %d\n", errno); - return; + const char *encname = NULL; + + int c; + while ((c = getopt(argc, argv, "e:o:")) != -1) { + switch (c) { + + /* font encoding */ + case 'e': + if (encname != NULL) + usage(); + encname = optarg; + break; + + /* output file name */ + case 'o': + if (ofile != NULL) + usage(); + ofile = optarg; + break; + + case '?': /* FALLTHROUGH */ + default: + usage(); } - interpret(foo); - } else { - printf("usage: bdfload <arg>\n"); } + + argc -= optind; + argv += optind; + + if (encname == NULL) { + encoding = WSDISPLAY_FONTENC_ISO; + } + else { + for (const struct encmap *e = encmap; e->name; ++e) { + if (strcmp(e->name, encname) == 0) { + encoding = e->encoding; + break; + } + } + } + + /* get encoding from the bdf file? */ + if (encoding == -1) + encoding = WSDISPLAY_FONTENC_ISO; + + if (argc == 0) + usage(); + + const char *bdfname = argv[0]; + foo = fopen(bdfname, "r"); + if (foo == NULL) + err(EXIT_FAILURE, "%s", bdfname); + + interpret(foo); + return EXIT_SUCCESS; }