Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[xsrc/trunk]: xsrc/local/programs/bdfload bdfload: Teach it to write wsf font...



details:   https://anonhg.NetBSD.org/xsrc/rev/d40ab11ddc76
branches:  trunk
changeset: 6988:d40ab11ddc76
user:      uwe <uwe%NetBSD.org@localhost>
date:      Wed Jun 08 19:19:42 2022 +0000

description:
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.

diffstat:

 local/programs/bdfload/bdfload.c |  190 +++++++++++++++++++++++++++++++++++---
 1 files changed, 171 insertions(+), 19 deletions(-)

diffs (243 lines):

diff -r 79212929a2ab -r d40ab11ddc76 local/programs/bdfload/bdfload.c
--- a/local/programs/bdfload/bdfload.c  Sun May 29 12:40:36 2022 +0000
+++ b/local/programs/bdfload/bdfload.c  Wed Jun 08 19:19:42 2022 +0000
@@ -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 @@
                        }
                        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 @@
                }
        }
        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;
 }



Home | Main Index | Thread Index | Old Index