set correct version in control
[vncterm.git] / genfont.c
1 /*
2
3 Copyright (C) 2007 Proxmox Server Solutions GmbH
4
5 Copyright: vzdump 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: Dietmar Maurer <dietmar@proxmox.com>
22
23 */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <zlib.h> /* read compressed console fonts */
28 #include <glob.h>
29 #include <string.h>
30
31 /* map unicode to font */
32 static unsigned short vt_fontmap[65536];
33
34 /* font glyph storage */
35 static unsigned char *vt_font_data = NULL;
36 static int vt_font_size = 0;
37 static int vt_font_maxsize = 0;
38
39 /* PSF stuff */
40
41
42 #define PSF_MAGIC1 0x36
43 #define PSF_MAGIC2 0x04
44
45 #define PSF_MODE256NOSFM 0
46 #define PSF_MODE512NOSFM 1
47 #define PSF_MODE256SFM 2
48 #define PSF_MODE512SFM 3
49
50 #define PSF_SEPARATOR 0xFFFF
51
52 struct psf_header
53 {
54 unsigned char magic1, magic2; /* Magic number */
55 unsigned char mode; /* PSF font mode */
56 unsigned char charheight; /* Character size */
57 };
58
59 #define PSF_MAGIC_OK(x) ((x).magic1 == PSF_MAGIC1 && (x).magic2 == PSF_MAGIC2)
60 #define PSF_MODE_VALID(x) ((x) <= PSF_MODE512SFM)
61 #define PSF_MODE_HAS512(x) (((x) == 1) || ((x) == 3))
62 #define PSF_MODE_HASSFM(x) (((x) == 2) || ((x) == 3))
63
64 typedef unsigned short unicode;
65
66 static int
67 font_add_glyph (const char *data)
68 {
69
70 if (vt_font_size >= vt_font_maxsize) {
71 vt_font_maxsize += 256;
72 vt_font_data = realloc (vt_font_data, vt_font_maxsize*16);
73 }
74
75 memcpy (vt_font_data + vt_font_size*16, data, 16);
76
77 vt_font_size += 1;
78
79 return vt_font_size - 1;
80 }
81
82 static int
83 load_psf_font (const char *filename, int is_default)
84 {
85 struct psf_header psfhdr;
86
87 gzFile *f = gzopen (filename, "rb");
88 if (f == NULL) {
89 fprintf (stderr, "unable to read file %s\n", filename);
90 exit(-1);
91 }
92
93 // read psf header
94 if (gzread(f, &psfhdr, sizeof(struct psf_header)) != sizeof(struct psf_header)) {
95 fprintf (stderr, "unable to read psf font header (%s)\n", filename);
96 gzclose (f);
97 return -1;
98 }
99
100 if (!PSF_MAGIC_OK(psfhdr) || !PSF_MODE_VALID(psfhdr.mode) ||
101 !PSF_MODE_HASSFM(psfhdr.mode) || (psfhdr.charheight != 16)) {
102 fprintf (stderr, "no valid 8*16 psf font (%s)\n", filename);
103 gzclose (f);
104 return -1;
105 }
106
107 int charcount = ((PSF_MODE_HAS512(psfhdr.mode)) ? 512 : 256);
108
109 int size = 16*charcount;
110
111 char *chardata = (char *)malloc (size);
112
113 if (size != gzread(f, chardata, size)) {
114 fprintf (stderr, "unable to read font character data (%s)\n", filename);
115 gzclose (f);
116 return -1;
117 }
118
119 unicode unichar;
120 int glyph;
121
122 for (glyph = 0 ;glyph < charcount ;glyph++) {
123 int fi = 0;
124 while (gzread (f, &unichar, sizeof(unicode)) == sizeof(unicode) &&
125 (unichar != PSF_SEPARATOR)) {
126 if (!vt_fontmap[unichar]) {
127 if (!fi) {
128 fi = font_add_glyph (chardata + glyph*16);
129 }
130 vt_fontmap[unichar] = fi;
131 }
132 }
133
134 if (is_default && fi && glyph < 256) {
135 vt_fontmap[0xf000 + glyph] = fi;
136 }
137 }
138
139 free (chardata);
140 gzclose (f);
141
142 return 0;
143 }
144
145 void
146 print_glyphs ()
147 {
148 int i, j;
149
150 printf ("static int vt_font_size = %d;\n\n", vt_font_size);
151
152 printf ("static unsigned char vt_font_data[] = {\n");
153 for (i = 0; i < vt_font_size; i++) {
154 printf ("\t/* %d 0x%02x */\n", i, i);
155 for (j = 0; j < 16; j++) {
156 unsigned char d = vt_font_data[i*16+j];
157 printf ("\t0x%02X, /* ", d);
158 int k;
159 for (k = 128; k > 0; k = k>>1) {
160 printf ("%c", (d & k) ? '1': '0');
161 }
162 printf (" */\n");
163 }
164 printf ("\n");
165 }
166 printf ("};\n\n");
167
168 printf ("static unsigned short vt_fontmap[65536] = {\n");
169 for (i = 0; i < 0x0ffff; i++) {
170 printf ("\t/* 0x%04X => */ %d,\n", i, vt_fontmap[i]);
171 }
172 printf ("};\n\n");
173
174 }
175
176 int
177 main (int argc, char** argv)
178 {
179 char empty[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
180 glob_t globbuf;
181
182 font_add_glyph (empty);
183
184 /* font load order is only important if glyphs are redefined */
185 load_psf_font ("/usr/share/consolefonts/default8x16.psf.gz", 1); /* vga default */
186 load_psf_font ("/usr/share/consolefonts/lat1u-16.psf.gz", 0); /* Latin-1 */
187 load_psf_font ("/usr/share/consolefonts/lat2u-16.psf.gz", 0); /* Latin-2 */
188 load_psf_font ("/usr/share/consolefonts/lat4u-16.psf.gz", 0); /* Baltic */
189
190 load_psf_font ("/usr/share/consolefonts/iso07.f16.psf.gz", 0); /* Greek */
191 load_psf_font ("/usr/share/consolefonts/Goha-16.psf.gz", 0); /* Ethiopic */
192
193 /* fixme: Arabic, Japanese letters ? */
194
195 if (0) {
196 glob("/usr/share/consolefonts/*", GLOB_ERR, NULL, &globbuf);
197
198 int i;
199 for (i = 0; i < globbuf.gl_pathc; i++) {
200 int pc = vt_font_size;
201 load_psf_font (globbuf.gl_pathv[i], 0);
202 if (vt_font_size > pc) {
203 printf ("TEST: %s %d\n", globbuf.gl_pathv[i], vt_font_size - pc);
204 }
205 }
206 } else {
207
208 print_glyphs ();
209
210 }
211
212 exit (0);
213 }