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