/* 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); }