bdfload.c revision ce18d260
1/* $NetBSD: bdfload.c,v 1.2 2022/05/09 15:47:27 uwe Exp $ */ 2 3/* 4 * Copyright (c) 2018 Michael Lorenz 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28/* 29 * a crude BDF loader for wsdisplay 30 */ 31 32#include <stdlib.h> 33#include <stdio.h> 34#include <fcntl.h> 35#include <unistd.h> 36#include <string.h> 37#include <errno.h> 38#include <ctype.h> 39#include <sys/ioctl.h> 40#include <err.h> 41 42#include <dev/wscons/wsconsio.h> 43 44void 45interpret(FILE *foo) 46{ 47 char line[128], *arg, name[64] = "foop", *buffer, buflen = -1; 48 int len, in_char = 0, current = -1, stride = 0, charsize = 0; 49 int width, height, x, y, num; 50 int first = 255, last = 0; 51 int left, top, lines; 52 int bl = 255, bt = 255, br = -1, bb = -1; 53 struct wsdisplay_font f; 54 int fdev; 55 56 while (fgets(line, sizeof(line), foo) != NULL) { 57 int i = 0; 58 /* separate keyword from parameters */ 59 len = strlen(line); 60 while (!isspace(line[i]) && (i < len)) i++; 61 line[i] = 0; 62 arg = &line[i + 1]; 63 i = 0; 64 len = strlen(arg); 65 /* get rid of garbage */ 66 while ((!iscntrl(arg[i])) && (arg[i] != 0)) { 67 i++; 68 } 69 arg[i] = 0; 70 if (strcmp(line, "FAMILY_NAME") == 0) { 71 /* cut off quotation marks */ 72 strncpy(name, arg + 1, 64); 73 name[strlen(name) - 1] = 0; 74 printf("name: %s\n", name); 75 } else if (strcmp(line, "FONTBOUNDINGBOX") == 0) { 76 int res; 77 res = sscanf(arg, "%d %d %d %d", 78 &width, &height, &x, &y); 79 stride = (width + 7) >> 3; 80 printf("box %d x %d\n", width, height); 81 if (stride > 2) { 82 printf("no fonts wider than 16 work for now\n"); 83 exit(1); 84 } 85 charsize = height * stride; 86 buflen = 256 * charsize; 87 buffer = malloc(buflen); 88 if (buffer == NULL) { 89 printf("failed to allocate %dKB for glyphs\n", 90 buflen); 91 exit(1); 92 } 93 } else if (strcmp(line, "CHARS") == 0) { 94 if (sscanf(arg, "%d", &num) == 1) 95 printf("number of characters: %d\n", num); 96 } else if (strcmp(line, "STARTCHAR") == 0) { 97 in_char = 1; 98 } else if (strcmp(line, "ENDCHAR") == 0) { 99 in_char = 0; 100 current = -1; 101 } else if (strcmp(line, "ENCODING") == 0) { 102 if (sscanf(arg, "%d", ¤t) == 1) { 103 if (current >= 0 && current < 256) { 104 if (current < first) first = current; 105 if (current > last) last = current; 106 } 107 } 108 } else if (strcmp(line, "BBX") == 0) { 109 int cx, cy, cwi, che; 110 if (sscanf(arg, "%d %d %d %d", &cwi, &che, &cx, &cy) 111 == 4) { 112 left = cx; 113 lines = che; 114 top = height + y - che - cy; 115 if (left < bl) bl = left; 116 if (top < bt) bt = top; 117 if ((left + cwi) > br) br = left + cwi; 118 if ((top + che) > bb) bb = top + che; 119 } 120 } else if (strcmp(line, "BITMAP") == 0) { 121 int i, j, k, l; 122 char num[32]; 123 char *gptr = &buffer[charsize * current]; 124 char *bptr = gptr + top; 125 uint16_t *bptr16 = (uint16_t *)gptr; 126 bptr16 += top; 127 /* see if the character is in range */ 128 if ((current < 0) || (current > 255)) continue; 129 /* now we read & render the character */ 130 for (i = 0; i < lines; i++) { 131 fgets(num, 32, foo); 132 sscanf(num, "%x", &l); 133 if ((stride) == 2 && (strlen(num) < 4)) 134 l = l << 8; 135 l = l >> left; 136 if (stride == 1) { 137 *gptr = l; 138 gptr++; 139 } else { 140 *bptr16 = htobe16(l); 141 bptr16++; 142 } 143 } 144 } 145 } 146 printf("range %d to %d\n", first, last); 147 printf("actual box: %d %d %d %d\n", bl, bt, br, bb); 148 /* now stuff it into a something wsfont understands */ 149 f.fontwidth = width /*(width + 3) & ~3*/; 150 f.fontheight = height; 151 f.firstchar = first; 152 f.numchars = last - first; 153 f.stride = stride; 154 f.encoding = WSDISPLAY_FONTENC_ISO; 155 f.name = name; 156 f.bitorder = WSDISPLAY_FONTORDER_L2R; 157 f.byteorder = WSDISPLAY_FONTORDER_L2R; 158 f.data = &buffer[first * charsize]; 159 160 fdev = open("/dev/wsfont", O_RDWR, 0); 161 if (fdev < 0) errx(1, "unable to open /dev/wsfont"); 162 ioctl(fdev, WSDISPLAYIO_LDFONT, &f); 163 close(fdev); 164} 165 166void 167main(int argc, char *argv[]) 168{ 169 FILE *foo; 170 if (argc > 1) { 171 foo = fopen(argv[1], "r"); 172 if (foo == NULL) { 173 printf("fopen error %d\n", errno); 174 return; 175 } 176 interpret(foo); 177 } else { 178 printf("usage: bdfload <arg>\n"); 179 } 180} 181