From: Dominik Csapak Date: Wed, 24 May 2017 09:37:50 +0000 (+0200) Subject: add genfont2 and unifont build-dependency X-Git-Url: https://git.proxmox.com/?p=vncterm.git;a=commitdiff_plain;h=ebe1002c3d877aae90628636c7c7dc79e5f86653 add genfont2 and unifont build-dependency 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 --- diff --git a/Makefile b/Makefile index 792b5bd..8b37c66 100644 --- 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 diff --git a/debian/control b/debian/control index d5e9830..75627f1 100644 --- a/debian/control +++ b/debian/control @@ -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 index 0000000..798e0fe --- /dev/null +++ b/genfont2.c @@ -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 + + This tool converts the unifont.hex file format into + a binary format used in vncterm to render glyphs. +*/ + + +#include +#include +#include +#include +#include + +#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); +}