/* $NetBSD: bdfload.c,v 1.1 2019/01/02 22:05:24 macallan Exp $ */ /* * Copyright (c) 2018 Michael Lorenz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * a crude BDF loader for wsdisplay */ #include #include #include #include #include #include #include #include #include #include void interpret(FILE *foo) { char line[128], *arg, name[64] = "foop", *buffer, 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; while (fgets(line, sizeof(line), foo) != NULL) { int i = 0; /* separate keyword from parameters */ len = strlen(line); while (!isspace(line[i]) && (i < len)) i++; line[i] = 0; arg = &line[i + 1]; i = 0; len = strlen(arg); /* get rid of garbage */ while ((!iscntrl(arg[i])) && (arg[i] != 0)) { i++; } arg[i] = 0; if (strcmp(line, "FAMILY_NAME") == 0) { /* cut off quotation marks */ strncpy(name, arg + 1, 64); name[strlen(name) - 1] = 0; printf("name: %s\n", name); } else if (strcmp(line, "FONTBOUNDINGBOX") == 0) { int res; res = sscanf(arg, "%d %d %d %d", &width, &height, &x, &y); stride = (width + 7) >> 3; printf("box %d x %d\n", width, height); if (stride > 2) { printf("no fonts wider than 16 work for now\n"); exit(1); } charsize = height * stride; buflen = 256 * charsize; buffer = malloc(buflen); if (buffer == NULL) { printf("failed to allocate %dKB for glyphs\n", buflen); exit(1); } } else if (strcmp(line, "CHARS") == 0) { if (sscanf(arg, "%d", &num) == 1) printf("number of characters: %d\n", num); } else if (strcmp(line, "STARTCHAR") == 0) { in_char = 1; } else if (strcmp(line, "ENDCHAR") == 0) { in_char = 0; current = -1; } else if (strcmp(line, "ENCODING") == 0) { if (sscanf(arg, "%d", ¤t) == 1) { if (current >= 0 && current < 256) { if (current < first) first = current; if (current > last) last = current; } } } else if (strcmp(line, "BBX") == 0) { int cx, cy, cwi, che; if (sscanf(arg, "%d %d %d %d", &cwi, &che, &cx, &cy) == 4) { left = cx; lines = che; top = height + y - che - cy; if (left < bl) bl = left; if (top < bt) bt = top; if ((left + cwi) > br) br = left + cwi; if ((top + che) > bb) bb = top + che; } } else if (strcmp(line, "BITMAP") == 0) { int i, j, k, l; char num[32]; char *gptr = &buffer[charsize * current]; char *bptr = gptr + top; uint16_t *bptr16 = (uint16_t *)gptr; bptr16 += top; /* see if the character is in range */ if ((current < 0) || (current > 255)) continue; /* now we read & render the character */ for (i = 0; i < lines; i++) { fgets(num, 32, foo); sscanf(num, "%x", &l); if ((stride) == 2 && (strlen(num) < 4)) l = l << 8; l = l >> left; if (stride == 1) { *gptr = l; gptr++; } else { *bptr16 = htobe16(l); bptr16++; } } } } printf("range %d to %d\n", first, last); 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.stride = stride; f.encoding = WSDISPLAY_FONTENC_ISO; 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); } void 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; } interpret(foo); } else { printf("usage: bdfload \n"); } }