bdfload.c revision 51bbcd86
151bbcd86Smacallan/*	$NetBSD: bdfload.c,v 1.12 2022/08/29 14:54:04 macallan Exp $	*/
2d5f9d0dbSmacallan
3d5f9d0dbSmacallan/*
4d5f9d0dbSmacallan * Copyright (c) 2018 Michael Lorenz
5d5f9d0dbSmacallan * All rights reserved.
6d5f9d0dbSmacallan *
7d5f9d0dbSmacallan * Redistribution and use in source and binary forms, with or without
8d5f9d0dbSmacallan * modification, are permitted provided that the following conditions
9d5f9d0dbSmacallan * are met:
10d5f9d0dbSmacallan * 1. Redistributions of source code must retain the above copyright
11d5f9d0dbSmacallan *    notice, this list of conditions and the following disclaimer.
12d5f9d0dbSmacallan * 2. Redistributions in binary form must reproduce the above copyright
13d5f9d0dbSmacallan *    notice, this list of conditions and the following disclaimer in the
14d5f9d0dbSmacallan *    documentation and/or other materials provided with the distribution.
15d5f9d0dbSmacallan *
16d5f9d0dbSmacallan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17d5f9d0dbSmacallan * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18d5f9d0dbSmacallan * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19d5f9d0dbSmacallan * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20d5f9d0dbSmacallan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21d5f9d0dbSmacallan * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22d5f9d0dbSmacallan * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23d5f9d0dbSmacallan * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24d5f9d0dbSmacallan * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25d5f9d0dbSmacallan * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26d5f9d0dbSmacallan */
27d5f9d0dbSmacallan
28d5f9d0dbSmacallan/*
29d5f9d0dbSmacallan * a crude BDF loader for wsdisplay
30d5f9d0dbSmacallan */
31d5f9d0dbSmacallan
32d5f9d0dbSmacallan#include <stdlib.h>
33d5f9d0dbSmacallan#include <stdio.h>
34d5f9d0dbSmacallan#include <fcntl.h>
35d5f9d0dbSmacallan#include <unistd.h>
36d5f9d0dbSmacallan#include <string.h>
37d5f9d0dbSmacallan#include <errno.h>
38d5f9d0dbSmacallan#include <ctype.h>
39d5f9d0dbSmacallan#include <sys/ioctl.h>
40d5f9d0dbSmacallan#include <err.h>
41d5f9d0dbSmacallan
42d5f9d0dbSmacallan#include <dev/wscons/wsconsio.h>
43d5f9d0dbSmacallan
442b154882Suwe/*
452b154882Suwe * wsdisplay_font but with strings embedded and integer fields in
462b154882Suwe * little endian
472b154882Suwe */
482b154882Suwestruct wsfthdr {
492b154882Suwe	char magic[4];		/* "WSFT" */
502b154882Suwe	char name[64];
512b154882Suwe	uint32_t firstchar;
522b154882Suwe	uint32_t numchars;
532b154882Suwe	uint32_t encoding;
542b154882Suwe	uint32_t fontwidth;
552b154882Suwe	uint32_t fontheight;
562b154882Suwe	uint32_t stride;
572b154882Suwe	uint32_t bitorder;
582b154882Suwe	uint32_t byteorder;
592b154882Suwe};
602b154882Suwe
612b154882Suwe
622b154882Suweconst struct encmap {
632b154882Suwe	const char *name;
642b154882Suwe	int encoding;
652b154882Suwe} encmap[] = {
662b154882Suwe	{ "cp437",	WSDISPLAY_FONTENC_IBM },
672b154882Suwe	{ "ibm",	WSDISPLAY_FONTENC_IBM },
682b154882Suwe	{ "iso",	WSDISPLAY_FONTENC_ISO },
692b154882Suwe	{ "iso-8859-1",	WSDISPLAY_FONTENC_ISO },
702b154882Suwe	{ "iso-8859-2",	WSDISPLAY_FONTENC_ISO2 },
712b154882Suwe	{ "iso-8859-7",	WSDISPLAY_FONTENC_ISO7 },
722b154882Suwe	{ "iso2",	WSDISPLAY_FONTENC_ISO2 },
732b154882Suwe	{ "iso7",	WSDISPLAY_FONTENC_ISO7 },
742b154882Suwe	{ "iso8859-1",	WSDISPLAY_FONTENC_ISO },
752b154882Suwe	{ "iso8859-2",	WSDISPLAY_FONTENC_ISO2 },
762b154882Suwe	{ "iso8859-7",	WSDISPLAY_FONTENC_ISO7 },
772b154882Suwe	{ "koi8-r",	WSDISPLAY_FONTENC_KOI8_R },
782b154882Suwe	{ "koi8r",	WSDISPLAY_FONTENC_KOI8_R },
792b154882Suwe	{ "latin-1",	WSDISPLAY_FONTENC_ISO },
802b154882Suwe	{ "latin-2",	WSDISPLAY_FONTENC_ISO2 },
812b154882Suwe	{ "latin1",	WSDISPLAY_FONTENC_ISO },
822b154882Suwe	{ "latin2",	WSDISPLAY_FONTENC_ISO2 },
832b154882Suwe	{ "pcvt",	WSDISPLAY_FONTENC_PCVT },
842b154882Suwe	{ NULL, -1 }
852b154882Suwe};
862b154882Suwe
872b154882Suweconst char * const encname[] = {
882b154882Suwe#define _ENC(_e) [_e] = #_e
892b154882Suwe	_ENC(WSDISPLAY_FONTENC_ISO),
902b154882Suwe	_ENC(WSDISPLAY_FONTENC_IBM),
912b154882Suwe	_ENC(WSDISPLAY_FONTENC_PCVT),
922b154882Suwe	_ENC(WSDISPLAY_FONTENC_ISO7),
932b154882Suwe	_ENC(WSDISPLAY_FONTENC_ISO2),
942b154882Suwe	_ENC(WSDISPLAY_FONTENC_KOI8_R),
952b154882Suwe};
962b154882Suwe
972b154882Suwe
982b154882Suweconst char *ofile = NULL;
992b154882Suweint encoding = -1;
10061348eb3Smacallanint verbose = 0;
101554a5d78Smacallanint dump = 0;
1022d60533cSmacallanint header = 0;
1037d6aaba4Smacallanchar commentbuf[2048] = "";
1047d6aaba4Smacallanint commentptr = 0;
10551bbcd86Smacallanchar fontname[64] = "";
1062b154882Suwe
107554a5d78Smacallanvoid
108554a5d78Smacallandump_line(char *gptr, int stride)
109554a5d78Smacallan{
110554a5d78Smacallan	int i, j, msk, c;
111554a5d78Smacallan
112554a5d78Smacallan	for (i = 0; i < stride; i++) {
113554a5d78Smacallan		c = gptr[i];
114554a5d78Smacallan		msk = 0x80;
115554a5d78Smacallan		for (j = 0; j < 8; j++) {
116554a5d78Smacallan			putchar((c & msk) != 0 ? '#' : ' ');
117554a5d78Smacallan			msk = msk >> 1;
118554a5d78Smacallan		}
119554a5d78Smacallan	}
120ec211365Smacallan	printf("\n");
121554a5d78Smacallan}
122554a5d78Smacallan
1232d60533cSmacallanvoid
1242d60533cSmacallanwrite_wsf(const char *oname, struct wsdisplay_font *f, char *buffer, int buflen)
1252d60533cSmacallan{
1262d60533cSmacallan	struct wsfthdr h;
1272d60533cSmacallan
1282d60533cSmacallan	memset(&h, 0, sizeof(h));
1292d60533cSmacallan	strncpy(h.magic, "WSFT", sizeof(h.magic));
1302d60533cSmacallan	strncpy(h.name, f->name, sizeof(h.name));
1312d60533cSmacallan	h.firstchar = htole32(f->firstchar);
1322d60533cSmacallan	h.numchars = htole32(f->numchars);
1332d60533cSmacallan	h.encoding = htole32(f->encoding);
1342d60533cSmacallan	h.fontwidth = htole32(f->fontwidth);
1352d60533cSmacallan	h.fontheight = htole32(f->fontheight);
1362d60533cSmacallan	h.stride = htole32(f->stride);
1372d60533cSmacallan	h.bitorder = htole32(f->bitorder);
1382d60533cSmacallan	h.byteorder = htole32(f->byteorder);
1392d60533cSmacallan
1402d60533cSmacallan	int wsfd = open(ofile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
1412d60533cSmacallan	if (wsfd < 0)
1422d60533cSmacallan		err(EXIT_FAILURE, "%s", ofile);
1432d60533cSmacallan
1442d60533cSmacallan	ssize_t nwritten;
1452d60533cSmacallan	nwritten = write(wsfd, &h, sizeof(h));
1462d60533cSmacallan	if (nwritten < 0)
1472d60533cSmacallan		err(EXIT_FAILURE, "%s", ofile);
1482d60533cSmacallan	if (nwritten != sizeof(h))
1492d60533cSmacallan		errx(EXIT_FAILURE, "%s: partial write", ofile);
1502d60533cSmacallan
1512d60533cSmacallan	nwritten = write(wsfd, buffer, buflen);
1522d60533cSmacallan	if (nwritten < 0)
1532d60533cSmacallan		err(EXIT_FAILURE, "%s", ofile);
1542d60533cSmacallan	if (nwritten != buflen)
1552d60533cSmacallan		errx(EXIT_FAILURE, "%s: partial write", ofile);
1562d60533cSmacallan	close(wsfd);
1572d60533cSmacallan}
1582d60533cSmacallan
1592d60533cSmacallanint
16051bbcd86Smacallanwrite_header(const char *filename, struct wsdisplay_font *f,
1612d60533cSmacallan             char *buffer, int buflen)
1622d60533cSmacallan{
1632d60533cSmacallan	FILE *output;
1647dd7205fSmacallan	int i, j, x, y, idx, pxls, left;
1652d60533cSmacallan	char fontname[64], c, msk;
1662d60533cSmacallan
1672d60533cSmacallan	/* now output as a header file */
16851bbcd86Smacallan	snprintf(fontname, sizeof(fontname), "%s_%dx%d", f->name,
1692d60533cSmacallan	    f->fontwidth, f->fontheight);
1702d60533cSmacallan	for (i = 0; i < strlen(fontname); i++) {
1712d60533cSmacallan		if (isblank((int)fontname[i]))
1722d60533cSmacallan			fontname[i]='_';
1732d60533cSmacallan	}
1742d60533cSmacallan	if ((output = fopen(filename, "w")) == NULL) {
1752d60533cSmacallan		fprintf(stderr, "Can't open output file %s\n", filename);
1762d60533cSmacallan		return -1;
1772d60533cSmacallan	}
1787d6aaba4Smacallan	if (commentptr > 0) {
1797d6aaba4Smacallan		fprintf(output, "/*\n");
1807d6aaba4Smacallan		fputs(commentbuf, output);
1817d6aaba4Smacallan		fprintf(output, "*/\n\n");
1827d6aaba4Smacallan	}
1837d6aaba4Smacallan
1842d60533cSmacallan	fprintf(output, "static u_char %s_data[];\n", fontname);
1852d60533cSmacallan	fprintf(output, "\n");
1862d60533cSmacallan	fprintf(output, "static struct wsdisplay_font %s = {\n", fontname);
18751bbcd86Smacallan	fprintf(output, "\t\"%s\",\t\t\t/* typeface name */\n", f->name);
1882d60533cSmacallan	fprintf(output, "\t%d,\t\t\t\t/* firstchar */\n", f->firstchar);
1892d60533cSmacallan	fprintf(output, "\t%d,\t\t\t\t/* numchars */\n", f->numchars);
1902d60533cSmacallan	fprintf(output, "\t%d,\t\t\t\t/* encoding */\n", f->encoding);
1912d60533cSmacallan	fprintf(output, "\t%d,\t\t\t\t/* fontwidth */\n", f->fontwidth);
1922d60533cSmacallan	fprintf(output, "\t%d,\t\t\t\t/* fontheight */\n", f->fontheight);
1932d60533cSmacallan	fprintf(output, "\t%d,\t\t\t\t/* stride */\n", f->stride);
1942d60533cSmacallan	fprintf(output, "\tWSDISPLAY_FONTORDER_L2R,\t/* bit order */\n");
1952d60533cSmacallan	fprintf(output, "\tWSDISPLAY_FONTORDER_L2R,\t/* byte order */\n");
1962d60533cSmacallan	fprintf(output, "\t%s_data\t\t/* data */\n", fontname);
1972d60533cSmacallan	fprintf(output, "};\n\n");
1982d60533cSmacallan	fprintf(output, "static u_char %s_data[] = {\n", fontname);
1992d60533cSmacallan	for (i = f->firstchar; i < f->firstchar + f->numchars; i++) {
2002d60533cSmacallan		fprintf(output, "\t/* %d */\n", i);
2012d60533cSmacallan		idx = i * f->stride * f->fontheight;
2022d60533cSmacallan		for (y = 0; y < f->fontheight; y++) {
2032d60533cSmacallan			for (x = 0; x < f->stride; x++) {
2042d60533cSmacallan				fprintf(output, "0x%02x, ",buffer[idx + x]);
2052d60533cSmacallan			}
2062d60533cSmacallan			fprintf(output, "/* ");
2077dd7205fSmacallan			pxls = f->fontwidth;
2082d60533cSmacallan			for (x = 0; x < f->stride; x++) {
2092d60533cSmacallan				c = buffer[idx + x];
2102d60533cSmacallan				msk = 0x80;
2117dd7205fSmacallan				left = pxls > 8 ? 8 : pxls;
2127dd7205fSmacallan				for (j = 0; j < left; j++) {
213426ebb7fSmacallan					fprintf(output, "%s",
214426ebb7fSmacallan					    (c & msk) != 0 ? "[]" : ". ");
2152d60533cSmacallan					msk = msk >> 1;
2162d60533cSmacallan				}
2177dd7205fSmacallan				pxls -= 8;
2182d60533cSmacallan			}
2192d60533cSmacallan			fprintf(output, " */\n");
2202d60533cSmacallan
2212d60533cSmacallan			idx += f->stride;
2222d60533cSmacallan		}
2232d60533cSmacallan	}
2242d60533cSmacallan	fprintf(output, "};\n");
2252d60533cSmacallan	fclose(output);
2262d60533cSmacallan	return 0;
2272d60533cSmacallan}
2282d60533cSmacallan
229d5f9d0dbSmacallanvoid
230d5f9d0dbSmacallaninterpret(FILE *foo)
231d5f9d0dbSmacallan{
23251bbcd86Smacallan	char line[128], *arg, name[64] = "foo", *buffer;
2332b154882Suwe	int buflen = -1;
234d5f9d0dbSmacallan	int len, in_char = 0, current = -1, stride = 0, charsize = 0;
235d5f9d0dbSmacallan	int width, height, x, y, num;
236d5f9d0dbSmacallan	int first = 255, last = 0;
237d5f9d0dbSmacallan	int left, top, lines;
238d5f9d0dbSmacallan	int bl = 255, bt = 255, br = -1, bb = -1;
239d5f9d0dbSmacallan	struct wsdisplay_font f;
2402b154882Suwe	int status;
241d5f9d0dbSmacallan
242d5f9d0dbSmacallan	while (fgets(line, sizeof(line), foo) != NULL) {
243d5f9d0dbSmacallan		int i = 0;
244d5f9d0dbSmacallan		/* separate keyword from parameters */
245d5f9d0dbSmacallan		len = strlen(line);
246d5f9d0dbSmacallan		while (!isspace(line[i]) && (i < len)) i++;
247d5f9d0dbSmacallan		line[i] = 0;
248d5f9d0dbSmacallan		arg = &line[i + 1];
249d5f9d0dbSmacallan		i = 0;
250d5f9d0dbSmacallan		len = strlen(arg);
251d5f9d0dbSmacallan		/* get rid of garbage */
252d5f9d0dbSmacallan		while ((!iscntrl(arg[i])) && (arg[i] != 0)) {
253d5f9d0dbSmacallan			i++;
254d5f9d0dbSmacallan		}
255d5f9d0dbSmacallan		arg[i] = 0;
256d5f9d0dbSmacallan		if (strcmp(line, "FAMILY_NAME") == 0) {
257d5f9d0dbSmacallan			/* cut off quotation marks */
258d5f9d0dbSmacallan			strncpy(name, arg + 1, 64);
259d5f9d0dbSmacallan			name[strlen(name) - 1] = 0;
26061348eb3Smacallan			if (verbose) printf("name: %s\n", name);
2617d6aaba4Smacallan		} else if (strcmp(line, "COMMENT") == 0) {
2627d6aaba4Smacallan			commentptr += snprintf(&commentbuf[commentptr],
2637d6aaba4Smacallan					      2048 - commentptr,
2647d6aaba4Smacallan					      "%s\n", arg);
265d5f9d0dbSmacallan		} else if (strcmp(line, "FONTBOUNDINGBOX") == 0) {
266d5f9d0dbSmacallan			int res;
267d5f9d0dbSmacallan			res = sscanf(arg, "%d %d %d %d",
268d5f9d0dbSmacallan					  &width, &height, &x, &y);
269d5f9d0dbSmacallan			stride = (width + 7) >> 3;
27061348eb3Smacallan			if (verbose) printf("box %d x %d\n", width, height);
271d5f9d0dbSmacallan			if (stride > 2) {
27261348eb3Smacallan				err(EXIT_FAILURE,
27361348eb3Smacallan				    "no fonts wider than 16 work for now\n");
274d5f9d0dbSmacallan			}
275d5f9d0dbSmacallan			charsize = height * stride;
276d5f9d0dbSmacallan			buflen = 256 * charsize;
2772b154882Suwe			buffer = calloc(1, buflen);
278d5f9d0dbSmacallan			if (buffer == NULL) {
27961348eb3Smacallan				err(EXIT_FAILURE,
28061348eb3Smacallan				    "failed to allocate %dKB for glyphs\n",
281d5f9d0dbSmacallan				    buflen);
282ce18d260Suwe			}
283d5f9d0dbSmacallan		} else if (strcmp(line, "CHARS") == 0) {
284d5f9d0dbSmacallan			if (sscanf(arg, "%d", &num) == 1)
28561348eb3Smacallan				if (verbose)
28661348eb3Smacallan				    printf("number of characters: %d\n", num);
287d5f9d0dbSmacallan		} else if (strcmp(line, "STARTCHAR") == 0) {
288d5f9d0dbSmacallan			in_char = 1;
289d5f9d0dbSmacallan		} else if (strcmp(line, "ENDCHAR") == 0) {
290d5f9d0dbSmacallan			in_char = 0;
291d5f9d0dbSmacallan			current = -1;
292d5f9d0dbSmacallan		} else if (strcmp(line, "ENCODING") == 0) {
293d5f9d0dbSmacallan			if (sscanf(arg, "%d", &current) == 1) {
294d5f9d0dbSmacallan				if (current >= 0 && current < 256) {
295d5f9d0dbSmacallan					if (current < first) first = current;
296d5f9d0dbSmacallan					if (current > last) last = current;
297554a5d78Smacallan					if (dump) printf("glyph %d\n", current);
298d5f9d0dbSmacallan				}
299d5f9d0dbSmacallan			}
300d5f9d0dbSmacallan		} else if (strcmp(line, "BBX") == 0) {
301d5f9d0dbSmacallan			int cx, cy, cwi, che;
302d5f9d0dbSmacallan			if (sscanf(arg, "%d %d %d %d", &cwi, &che, &cx, &cy)
303d5f9d0dbSmacallan			     == 4) {
304d5f9d0dbSmacallan				left = cx;
305d5f9d0dbSmacallan				lines = che;
306d5f9d0dbSmacallan				top = height + y - che - cy;
307d5f9d0dbSmacallan				if (left < bl) bl = left;
308d5f9d0dbSmacallan				if (top < bt) bt = top;
309d5f9d0dbSmacallan				if ((left + cwi) > br) br = left + cwi;
310d5f9d0dbSmacallan				if ((top + che) > bb) bb = top + che;
311554a5d78Smacallan				if(dump && verbose) printf("top %d left %d\n", top, left);
312d5f9d0dbSmacallan			}
313d5f9d0dbSmacallan		} else if (strcmp(line, "BITMAP") == 0) {
314d5f9d0dbSmacallan			int i, j, k, l;
315d5f9d0dbSmacallan			char num[32];
316d5f9d0dbSmacallan			char *gptr = &buffer[charsize * current];
317d5f9d0dbSmacallan			char *bptr = gptr + top;
318d5f9d0dbSmacallan			uint16_t *bptr16 = (uint16_t *)gptr;
319d5f9d0dbSmacallan			bptr16 += top;
320d5f9d0dbSmacallan			/* see if the character is in range */
321d5f9d0dbSmacallan			if ((current < 0) || (current > 255)) continue;
322d5f9d0dbSmacallan			/* now we read & render the character */
323d5f9d0dbSmacallan			for (i = 0; i < lines; i++) {
324d5f9d0dbSmacallan				fgets(num, 32, foo);
325d5f9d0dbSmacallan				sscanf(num, "%x", &l);
326d5f9d0dbSmacallan				if ((stride) == 2 && (strlen(num) < 4))
327d5f9d0dbSmacallan					l = l << 8;
328d5f9d0dbSmacallan				l = l >> left;
329d5f9d0dbSmacallan				if (stride == 1) {
330b9e0dc8cSmacallan					*bptr = l;
331b9e0dc8cSmacallan					bptr++;
332d5f9d0dbSmacallan				} else {
333d5f9d0dbSmacallan					*bptr16 = htobe16(l);
334d5f9d0dbSmacallan					bptr16++;
335ce18d260Suwe				}
336d5f9d0dbSmacallan			}
337554a5d78Smacallan			if (dump) {
338554a5d78Smacallan				gptr = &buffer[charsize * current];
339554a5d78Smacallan				for (i = 0; i < height; i++) {
340554a5d78Smacallan					dump_line(gptr, stride);
341554a5d78Smacallan					gptr += stride;
342554a5d78Smacallan				}
343554a5d78Smacallan			}
344d5f9d0dbSmacallan		}
345d5f9d0dbSmacallan	}
34661348eb3Smacallan	if (verbose) {
34761348eb3Smacallan		printf("range %d to %d\n", first, last);
34861348eb3Smacallan		printf("encoding: %s\n", encname[encoding]);
34961348eb3Smacallan		printf("actual box: %d %d %d %d\n", bl, bt, br, bb);
35061348eb3Smacallan	}
3512b154882Suwe
352d5f9d0dbSmacallan	/* now stuff it into a something wsfont understands */
353d5f9d0dbSmacallan	f.fontwidth = width /*(width + 3) & ~3*/;
354d5f9d0dbSmacallan	f.fontheight = height;
355d5f9d0dbSmacallan	f.firstchar = first;
3562b154882Suwe	f.numchars = last - first + 1;
357d5f9d0dbSmacallan	f.stride = stride;
3582b154882Suwe	f.encoding = encoding;
35951bbcd86Smacallan	if (fontname[0] == 0) {
36051bbcd86Smacallan		f.name = name;
36151bbcd86Smacallan	} else f.name = fontname;
362d5f9d0dbSmacallan	f.bitorder = WSDISPLAY_FONTORDER_L2R;
363d5f9d0dbSmacallan	f.byteorder = WSDISPLAY_FONTORDER_L2R;
364d5f9d0dbSmacallan	f.data = &buffer[first * charsize];
365d5f9d0dbSmacallan
3662b154882Suwe	if (ofile == NULL) {
3672b154882Suwe		int fdev = open("/dev/wsfont", O_RDWR, 0);
3682b154882Suwe		if (fdev < 0)
3692b154882Suwe			err(EXIT_FAILURE, "/dev/wsfont");
3702b154882Suwe		status = ioctl(fdev, WSDISPLAYIO_LDFONT, &f);
3712b154882Suwe		if (status != 0)
3722b154882Suwe			err(EXIT_FAILURE, "WSDISPLAYIO_LDFONT");
3732b154882Suwe		close(fdev);
3742b154882Suwe	}
3752b154882Suwe	else {
3762d60533cSmacallan		if (header == 0) {
3772d60533cSmacallan			write_wsf(ofile, &f, buffer, buflen);
3782d60533cSmacallan		} else
37951bbcd86Smacallan			write_header(ofile, &f, buffer, buflen);
3802b154882Suwe	}
381d5f9d0dbSmacallan}
382d5f9d0dbSmacallan
3832b154882Suwe__dead void
3842b154882Suweusage()
3852b154882Suwe{
38651bbcd86Smacallan	fprintf(stderr, "usage: bdfload [-vdh] [-e encoding] [-N name] [-o ofile.wsf] font.bdf\n");
3872b154882Suwe	exit(EXIT_FAILURE);
3882b154882Suwe}
3892b154882Suwe
3902b154882Suweint
391d5f9d0dbSmacallanmain(int argc, char *argv[])
392d5f9d0dbSmacallan{
393d5f9d0dbSmacallan	FILE *foo;
3942b154882Suwe	const char *encname = NULL;
3952b154882Suwe
3962b154882Suwe	int c;
39751bbcd86Smacallan	while ((c = getopt(argc, argv, "e:o:N:vdh")) != -1) {
3982b154882Suwe		switch (c) {
3992b154882Suwe
4002b154882Suwe		/* font encoding */
4012b154882Suwe		case 'e':
4022b154882Suwe			if (encname != NULL)
4032b154882Suwe				usage();
4042b154882Suwe			encname = optarg;
4052b154882Suwe			break;
4062b154882Suwe
4072b154882Suwe		/* output file name */
4082b154882Suwe		case 'o':
4092b154882Suwe			if (ofile != NULL)
4102b154882Suwe				usage();
4112b154882Suwe			ofile = optarg;
4122b154882Suwe			break;
4132b154882Suwe
41461348eb3Smacallan		case 'v':
41561348eb3Smacallan			verbose = 1;
41661348eb3Smacallan			break;
41761348eb3Smacallan
418554a5d78Smacallan		case 'd':
419554a5d78Smacallan			dump = 1;
420554a5d78Smacallan			break;
421554a5d78Smacallan
4222d60533cSmacallan		case 'h':
4232d60533cSmacallan			header = 1;
4242d60533cSmacallan			break;
42551bbcd86Smacallan		case 'N':
42651bbcd86Smacallan			strncpy(fontname, optarg, 64);
42751bbcd86Smacallan			printf("given name: %s\n", fontname);
42851bbcd86Smacallan			break;
4292b154882Suwe		case '?':	/* FALLTHROUGH */
4302b154882Suwe		default:
4312b154882Suwe			usage();
432d5f9d0dbSmacallan		}
433d5f9d0dbSmacallan	}
4342b154882Suwe
4352b154882Suwe	argc -= optind;
4362b154882Suwe	argv += optind;
4372b154882Suwe
4382b154882Suwe	if (encname == NULL) {
4392b154882Suwe		encoding = WSDISPLAY_FONTENC_ISO;
4402b154882Suwe	}
4412b154882Suwe	else {
4422b154882Suwe		for (const struct encmap *e = encmap; e->name; ++e) {
4432b154882Suwe			if (strcmp(e->name, encname) == 0) {
4442b154882Suwe				encoding = e->encoding;
4452b154882Suwe				break;
4462b154882Suwe			}
4472b154882Suwe		}
4482b154882Suwe	}
4492b154882Suwe
4502b154882Suwe	/* get encoding from the bdf file? */
4512b154882Suwe	if (encoding == -1)
4522b154882Suwe		encoding = WSDISPLAY_FONTENC_ISO;
4532b154882Suwe
4542b154882Suwe	if (argc == 0)
4552b154882Suwe		usage();
4562b154882Suwe
4572b154882Suwe	const char *bdfname = argv[0];
4582b154882Suwe	foo = fopen(bdfname, "r");
4592b154882Suwe	if (foo == NULL)
4602b154882Suwe		err(EXIT_FAILURE, "%s", bdfname);
4612b154882Suwe
4622b154882Suwe	interpret(foo);
4632b154882Suwe	return EXIT_SUCCESS;
464d5f9d0dbSmacallan}
465