]> git.proxmox.com Git - vncterm.git/blob - genfont2.c
buildsys: cleanup
[vncterm.git] / genfont2.c
1 /*
2
3 Copyright (C) 2017 Proxmox Server Solutions GmbH
4
5 Copyright: vncterm is under GNU GPL, the GNU General Public License.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; version 2 dated June, 1991.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA.
20
21 Author: Dominik Csapak <d.csapak@proxmox.com>
22
23 This tool converts the unifont.hex file format into
24 a binary format used in vncterm to render glyphs.
25 */
26
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <inttypes.h>
31 #include <errno.h>
32 #include <getopt.h>
33
34 #define NUMCODEPOINTS 0xFFFF
35 #define GLYPHLINES 16
36 #define INDEXLENGTH 4
37
38 /* parses strings like 00F0 to the integer */
39 long
40 parsehex(char *val, size_t length)
41 {
42 unsigned int value = 0;
43
44 for (size_t i = 0; i < length; i++) {
45 value *= 16;
46 if (val[i] >= '0' && val[i] <= '9') {
47 value += (val[i] - '0');
48 } else if (val[i] >= 'A' && val[i] <= 'F') {
49 value += (val[i] - 'A' + 10);
50 } else if (val[i] >= 'a' && val[i] <= 'f') {
51 value += (val[i] - 'a' + 10);
52 } else {
53 return -1;
54 }
55 }
56
57 return value;
58 }
59
60 void usage(char **argv) {
61 printf("Usage: %s [OPTION]...\n", argv[0]);
62 printf("Converts font data from hex format into binary format used by vncterm.\n");
63
64 printf("\n");
65 printf(" -o, --output file for output, if omitted, write to STDOUT\n");
66 printf(" -i, --input file for input, if omitted read from STDIN\n");
67 printf(" -h, --help display this help\n");
68
69 printf("\nThe input has to be formatted in the hex format of unifont.\n");
70 }
71
72 int
73 main (int argc, char** argv)
74 {
75 FILE *fd;
76 FILE *outfd;
77 char *line = NULL;
78 char *tmp = NULL;
79 char *fontfile = NULL;
80 char *outfile = NULL;
81 size_t linesize = 0;
82 uint8_t emptyglyph[GLYPHLINES*2] = { 0 };
83 uint8_t glyph[GLYPHLINES*2] = { 0 };
84 int nextcodepoint = 0;
85 int codepoint = 0;
86 int c;
87
88 static struct option long_options[] = {
89 {"help", no_argument, 0, 'h'},
90 {"output", required_argument, 0, 'o'},
91 {"input", required_argument, 0, 'i'},
92 { 0 , 0, 0, 0}
93 };
94 int option_index = 0;
95
96 while((c = getopt_long(argc, argv, "hi:o:", long_options, &option_index)) != -1) {
97 switch (c) {
98 case 'h':
99 usage(argv);
100 exit(0);
101 break;
102 case 'o':
103 outfile = optarg;
104 break;
105 case 'i':
106 fontfile = optarg;
107 break;
108 default:
109 usage(argv);
110 exit(1);
111 }
112 }
113
114 if (fontfile != NULL){
115 fd = fopen(fontfile, "r");
116 if (fd == NULL) {
117 fprintf(stderr, "Error opening '%s'\n", fontfile);
118 perror(NULL);
119 exit(2);
120 }
121 } else {
122 fd = stdin;
123 }
124
125 if (outfile != NULL) {
126 outfd = fopen(outfile, "w");
127 if (outfd == NULL) {
128 fprintf(stderr, "Error opening '%s'\n", outfile);
129 perror(NULL);
130 exit(2);
131 }
132 } else {
133 outfd = stdout;
134 }
135
136
137 while (getline(&line, &linesize, fd) != -1) {
138 codepoint = parsehex(line, INDEXLENGTH);
139 if (codepoint == -1) {
140 fprintf(stderr, "Cannot parse codepoint index: '%s'\n", line);
141 free(line);
142 exit(4);
143 }
144
145 /* fill in missing codepoints with empty glyphs */
146 while (nextcodepoint++ < codepoint) {
147 fwrite(emptyglyph, sizeof(emptyglyph), 1, outfd);
148 }
149
150 tmp = line + INDEXLENGTH + 1;
151 size_t i = 0;
152
153 /* parse until end of line */
154 while (*(tmp+i*2) != '\n' && i < sizeof(glyph)) {
155 int value = parsehex(tmp+i*2, 2);
156
157 if (value == -1) {
158 fprintf(stderr, "Cannot parse glyph from line: '%s' at position %ld ('%s')\n", line, i*2, tmp+i*2);
159 free(line);
160 exit(4);
161 }
162
163 glyph[i++] = (uint8_t)value;
164 }
165
166 /* if we have a 1width glyph, fill the rest with zeroes */
167 while (i < sizeof(glyph)) {
168 glyph[i++] = 0;
169 }
170
171 fwrite(glyph, sizeof(glyph), 1, outfd);
172 }
173
174 if(errno) {
175 perror("Cannot not read line from file");
176 }
177
178 while (nextcodepoint++ <= NUMCODEPOINTS) {
179 fwrite(emptyglyph, sizeof(emptyglyph), 1, outfd);
180 }
181
182 free(line);
183 exit(0);
184 }