add genfont2 and unifont build-dependency
authorDominik Csapak <d.csapak@proxmox.com>
Wed, 24 May 2017 09:37:50 +0000 (11:37 +0200)
committerWolfgang Bumiller <w.bumiller@proxmox.com>
Wed, 24 May 2017 10:55:19 +0000 (12:55 +0200)
this patch introduces a new tool to generate font data
it uses a new build-dependency, namely unifont, which is an opensource
font with printable charachters for the unicode range from
0x0000 to 0xFFFF

we generate a file which is easily mmap'able and has the same bitformat
we used before (minus the codepoint -> address translation)

note that some characters are using 2 columns as width, so to have a
static lookup, we need to make each character 32 byte long
(1 byte per line, 16 lines per terminal column)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Makefile
debian/control
genfont2.c [new file with mode: 0644]

index 792b5bd..8b37c66 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -24,6 +24,13 @@ glyphs.h: genfont
 genfont: genfont.c
        gcc -g -O2 -o $@ genfont.c -Wall -D_GNU_SOURCE -lz
 
+font.data: genfont2
+       ./genfont2 -o font.data.tmp -i /usr/share/unifont/unifont.hex
+       mv font.data.tmp font.data
+
+genfont2: genfont2.c
+       gcc -g -O2 -o $@ genfont2.c -Wall -Wextra -D_GNU_SOURCE -lz
+
 .PHONY: vnc
 ${VNCLIB} vnc: ${VNCSRC}
        rm -rf ${VNCDIR}
@@ -70,7 +77,7 @@ upload: ${DEB}
 
 .PHONY: clean
 clean:
-       rm -rf vncterm vncterm.1 vncterm_*.deb genfont *~ ${VNCDIR} vncterm-*.tar.gz glyph.h.tmp build *.changes
+       rm -rf vncterm vncterm.1 vncterm_*.deb genfont genfont2 *~ ${VNCDIR} vncterm-*.tar.gz glyph.h.tmp build *.changes font.data.tmp font.data
 
 .PHONY: distclean
 distclean: clean
index d5e9830..75627f1 100644 (file)
@@ -7,6 +7,7 @@ Build-Depends:
     libpng-dev,
     libglib2.0-dev,
     libgnutls28-dev,
+    unifont
 Standards-Version: 3.9.3
 
 Package: vncterm
diff --git a/genfont2.c b/genfont2.c
new file mode 100644 (file)
index 0000000..798e0fe
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+
+     Copyright (C) 2017 Proxmox Server Solutions GmbH
+
+     Copyright: vncterm is under GNU GPL, the GNU General Public License.
+
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation; version 2 dated June, 1991.
+
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with this program; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+     02111-1307, USA.
+
+     Author: Dominik Csapak <d.csapak@proxmox.com>
+
+     This tool converts the unifont.hex file format into
+     a binary format used in vncterm to render glyphs.
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <getopt.h>
+
+#define NUMCODEPOINTS 0xFFFF
+#define GLYPHLINES 16
+#define INDEXLENGTH 4
+
+/* parses strings like 00F0 to the integer */
+long
+parsehex(char *val, size_t length)
+{
+    unsigned int value = 0;
+
+    for (size_t i = 0; i < length; i++) {
+       value *= 16;
+       if (val[i] >= '0' && val[i] <= '9') {
+           value += (val[i] - '0');
+       } else if (val[i] >= 'A' && val[i] <= 'F') {
+           value += (val[i] - 'A' + 10);
+       } else if (val[i] >= 'a' && val[i] <= 'f') {
+           value += (val[i] - 'a' + 10);
+       } else {
+           return -1;
+       }
+    }
+
+    return value;
+}
+
+void usage(char **argv) {
+    printf("Usage: %s [OPTION]...\n", argv[0]);
+    printf("Converts font data from hex format into binary format used by vncterm.\n");
+
+    printf("\n");
+    printf("  -o, --output    file for output, if omitted, write to STDOUT\n");
+    printf("  -i, --input     file for input, if omitted read from STDIN\n");
+    printf("  -h, --help      display this help\n");
+
+    printf("\nThe input has to be formatted in the hex format of unifont.\n");
+}
+
+int
+main (int argc, char** argv)
+{
+    FILE *fd;
+    FILE *outfd;
+    char *line = NULL;
+    char *tmp = NULL;
+    char *fontfile = NULL;
+    char *outfile = NULL;
+    size_t linesize = 0;
+    uint8_t emptyglyph[GLYPHLINES*2] = { 0 };
+    uint8_t glyph[GLYPHLINES*2] = { 0 };
+    int nextcodepoint = 0;
+    int codepoint = 0;
+    int c;
+
+    static struct option long_options[] = {
+       {"help", no_argument, 0, 'h'},
+       {"output", required_argument, 0, 'o'},
+       {"input", required_argument, 0, 'i'},
+       { 0 , 0, 0, 0}
+    };
+    int option_index = 0;
+
+    while((c = getopt_long(argc, argv, "hi:o:", long_options, &option_index)) != -1) {
+       switch (c) {
+           case 'h':
+               usage(argv);
+               exit(0);
+               break;
+           case 'o':
+               outfile = optarg;
+               break;
+           case 'i':
+               fontfile = optarg;
+               break;
+           default:
+               usage(argv);
+               exit(1);
+       }
+    }
+
+    if (fontfile != NULL){
+       fd = fopen(fontfile, "r");
+       if (fd == NULL) {
+           fprintf(stderr, "Error opening '%s'\n", fontfile);
+           perror(NULL);
+           exit(2);
+       }
+    } else {
+       fd = stdin;
+    }
+
+    if (outfile != NULL) {
+       outfd = fopen(outfile, "w");
+       if (outfd == NULL) {
+           fprintf(stderr, "Error opening '%s'\n", outfile);
+           perror(NULL);
+           exit(2);
+       }
+    } else {
+       outfd = stdout;
+    }
+
+
+    while (getline(&line, &linesize, fd) != -1) {
+       codepoint = parsehex(line, INDEXLENGTH);
+       if (codepoint == -1) {
+           fprintf(stderr, "Cannot parse codepoint index: '%s'\n", line);
+           free(line);
+           exit(4);
+       }
+
+       /* fill in missing codepoints with empty glyphs */
+       while (nextcodepoint++ < codepoint) {
+           fwrite(emptyglyph, sizeof(emptyglyph), 1, outfd);
+       }
+
+       tmp = line + INDEXLENGTH + 1;
+       size_t i = 0;
+
+       /* parse until end of line */
+       while (*(tmp+i*2) != '\n' && i < sizeof(glyph)) {
+           int value = parsehex(tmp+i*2, 2);
+
+           if (value == -1) {
+               fprintf(stderr, "Cannot parse glyph from line: '%s' at position %ld ('%s')\n", line, i*2, tmp+i*2);
+               free(line);
+               exit(4);
+           }
+
+           glyph[i++] = (uint8_t)value;
+       }
+
+       /* if we have a 1width glyph, fill the rest with zeroes */
+       while (i < sizeof(glyph)) {
+           glyph[i++] = 0;
+       }
+
+       fwrite(glyph, sizeof(glyph), 1, outfd);
+    }
+
+    if(errno) {
+       perror("Cannot not read line from file");
+    }
+
+    while (nextcodepoint++ <= NUMCODEPOINTS) {
+       fwrite(emptyglyph, sizeof(emptyglyph), 1, outfd);
+    }
+
+    free(line);
+    exit(0);
+}