mirror of
git://git.proxmox.com/git/vncterm.git
synced 2025-01-02 05:17:38 +03:00
ebe1002c3d
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>
185 lines
4.3 KiB
C
185 lines
4.3 KiB
C
/*
|
|
|
|
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);
|
|
}
|