1 /*
2     psftools: Manipulate console fonts in the .PSF format
3     Copyright (C) 2000, 2005, 2007  John Elliott
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 
20 /* Convert a PSF file to a C include file in the format used by the
21  * NetBSD kernel. */
22 
23 #include "cnvshell.h"
24 #include "psflib.h"
25 
26 char *cnv_progname = "PSF2BSD";
27 
28 static char helpbuf[2000];
29 static char *cpbuf;
30 static char *fnbuf;
31 static char *tnbuf;
32 static char *fontname = NULL;
33 static char *typename = NULL;
34 static char *codepage = NULL;
35 static int first = -1;
36 static int last = -1;
37 
cnv_set_option(int ddash,char * variable,char * value)38 char *cnv_set_option(int ddash, char *variable, char *value)
39 {
40 	if (!strcmp(variable, "name"))
41 	{
42 		fnbuf = malloc(1 + strlen(value));
43 		if (!fnbuf) return "Out of memory";
44 		strcpy(fnbuf, value);
45 		fontname = fnbuf;
46 		return NULL;
47 	}
48 	if (!strcmp(variable, "typeface"))
49 	{
50 		tnbuf = malloc(1 + strlen(value));
51 		if (!tnbuf) return "Out of memory";
52 		strcpy(tnbuf, value);
53 		typename = tnbuf;
54 		return NULL;
55 	}
56 	if (!strcmp(variable, "encoding"))
57 	{
58 		if (!strcmp(value, "437"))
59 			codepage = "WSDISPLAY_FONTENC_IBM";
60 		else if (!strcmp(value, "819"))
61 			codepage = "WSDISPLAY_FONTENC_ISO";
62 		else if (!strcmp(value, "28591"))
63 			codepage = "WSDISPLAY_FONTENC_ISO";
64 		else
65 		{
66 			cpbuf = malloc(1 + strlen(value));
67 			if (!cpbuf) return "Out of memory";
68 			strcpy(cpbuf, value);
69 			codepage = cpbuf;
70 		}
71 		return NULL;
72 	}
73 	if (!strcmp(variable, "first"))
74 	{
75 		first = atoi(value);
76 		return NULL;
77 	}
78 	if (!strcmp(variable, "last"))
79 	{
80 		last = atoi(value);
81 		return NULL;
82 	}
83 	if (strlen(variable) > 2000) variable[2000] = 0;
84 	if (strlen(variable) > 2000) variable[2000] = 0;
85 	sprintf(helpbuf, "Unknown option: %s\n", variable);
86 	return helpbuf;
87 }
88 
89 /* Return help string */
cnv_help(void)90 char *cnv_help(void)
91 {
92 	sprintf(helpbuf, "Syntax: %s psffile incfile { options }\n\n",
93 			cnv_progname);
94 	strcat (helpbuf, "Options: \n"
95                      "    --name=name     Set structure name (default: 'font')\n"
96                      "    --typeface=name  Set typeface name (default: match structure name)\n"
97                      "    --encoding=437  Select IBM encoding\n"
98                      "    --encoding=819  Select ISO-8859-1 encoding\n"
99 		     "    --encoding=...  Set literal encoding name\n"
100 		     "    --first=nnn     Set first character to include\n"
101 		     "    --last=nnn      Set last character to include\n"
102 		     );
103 
104 	return helpbuf;
105 }
106 
dumpbyte(FILE * fp,psf_byte value)107 void dumpbyte(FILE *fp, psf_byte value)
108 {
109 	int mask;
110 
111 	for (mask = 0x80; mask != 0; mask = mask >> 1)
112 	{
113 		fprintf(fp, "%c", (value & mask) ? '#' : '-');
114 	}
115 }
116 
cnv_execute(FILE * infile,FILE * outfile)117 char *cnv_execute(FILE *infile, FILE *outfile)
118 {
119 	int rv, stride, nstr;
120 	psf_dword nchar, nrow;
121 	PSF_FILE psf;
122 
123 	if (fontname == NULL)
124 	{
125 		fontname = "font";
126 	}
127 	if (codepage == NULL)
128 	{
129 		codepage = "WSDISPLAY_FONTENC_ISO";
130 	}
131 	if (typename == NULL)
132 	{
133 		typename = fontname;
134 	}
135 	psf_file_new(&psf);
136 	rv = psf_file_read(&psf, infile);
137 
138 	if (rv != PSF_E_OK) return psf_error_string(rv);
139 	if (first == -1 || first >= psf.psf_length)
140 	{
141 		first = 0;
142 	}
143 	if (last == -1 || last >= psf.psf_length)
144 	{
145 		last = psf.psf_length - 1;
146 	}
147 	if (last < first)
148 	{
149 		last = first;
150 	}
151 
152 	stride = (psf.psf_width + 7) / 8;
153 	fprintf(outfile, "static u_char %s_data[];\n\n", fontname);
154 	fprintf(outfile, "static struct wsdisplay_font %s = {\n", fontname);
155 	fprintf(outfile, "\t\"%s\",\t\t\t\t/* typeface name */\n", typename);
156 	fprintf(outfile, "\t%d,\t\t\t\t/* firstchar */\n", first);
157 	fprintf(outfile, "\t%d,\t\t\t\t/* numchars */\n", last - first + 1);
158 	fprintf(outfile, "\t%s,\t\t/* encoding */\n", codepage);
159 	fprintf(outfile, "\t%ld,\t\t\t\t/* width */\n", psf.psf_width);
160 	fprintf(outfile, "\t%ld,\t\t\t\t/* height */\n", psf.psf_height);
161 	fprintf(outfile, "\t%d,\t\t\t\t/* stride */\n", stride);
162 	fprintf(outfile, "\tWSDISPLAY_FONTORDER_L2R,\t/* bit order */\n");
163 	fprintf(outfile, "\tWSDISPLAY_FONTORDER_L2R,\t/* byte order */\n");
164 	fprintf(outfile, "\t%s_data\t\t\t/* data */\n", fontname);
165 	fprintf(outfile, "};\n\n");
166 
167 	fprintf(outfile, "static u_char %s_data[] = {\n", fontname);
168 	for (nchar = first; nchar <= last; nchar++)
169 	{
170 		if (stride > 1)	fprintf(outfile, "\t");
171 		fprintf(outfile, "\t\t/* 0x%02lx  ", nchar);
172 		if (nchar >= 0x20 && nchar < 0x7F)
173 			fprintf(outfile, "('%c')", (int)nchar);
174 		else	fprintf(outfile, "     ");
175 		fprintf(outfile, " */\n");
176 		for (nrow = 0; nrow < psf.psf_height; nrow++)
177 		{
178 			psf_byte *ptr = psf.psf_data + nchar * psf.psf_charlen;
179 
180 			ptr += nrow * stride;
181 			fprintf(outfile, "\t");
182 			for (nstr = 0; nstr < stride; nstr++)
183 			{
184 				fprintf(outfile, "0x%02x, ", ptr[nstr]);
185 			}
186 			fprintf(outfile, "\t/* ");
187 			for (nstr = 0; nstr < stride; nstr++)
188 			{
189 				dumpbyte(outfile, ptr[nstr]);
190 			}
191 			fprintf(outfile, " */\n");
192 		}
193 		fprintf(outfile, "\n");
194 	}
195 	fprintf(outfile, "};\n");
196 	psf_file_delete(&psf);
197 	return NULL;
198 }
199 
200