GNU Unifont: src/unihexgen.c Source File

GNU Unifont 17.0.04 Pan-Unicode font with complete Unicode Plane 0 coverage and partial coverage of higher planes

unihexgen.c
Go to the documentation of this file.
1/**
2 @file unihexgen.c
3
4 @brief unihexgen - Generate a series of glyphs containing
5 hexadecimal code points
6
7 @author Paul Hardy
8
9 @copyright Copyright (C) 2013 Paul Hardy
10
11 This program generates glyphs in Unifont .hex format that contain
12 four- or six-digit hexadecimal numbers in a 16x16 pixel area. These
13 are rendered as white digits on a black background.
14
15 argv[1] is the starting code point (as a hexadecimal
16 string, with no leading "0x".
17
18 argv[2] is the ending code point (as a hexadecimal
19 string, with no leading "0x".
20
21 For example:
22
23 unihexgen e000 f8ff > pua.hex
24
25 This generates the Private Use Area glyph file.
26
27 This utility program works in Roman Czyborra's unifont.hex file
28 format, the basis of the GNU Unifont package.
29*/
30/*
31 This program is released under the terms of the GNU General Public
32 License version 2, or (at your option) a later version.
33
34 LICENSE:
35
36 This program is free software: you can redistribute it and/or modify
37 it under the terms of the GNU General Public License as published by
38 the Free Software Foundation, either version 2 of the License, or
39 (at your option) any later version.
40
41 This program is distributed in the hope that it will be useful,
42 but WITHOUT ANY WARRANTY; without even the implied warranty of
43 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
44 GNU General Public License for more details.
45
46 You should have received a copy of the GNU General Public License
47 along with this program. If not, see <http://www.gnu.org/licenses/>.
48*/
49/*
50 6 September 2025 [Paul Hardy]:
51 - Changed startcp, endcp, and thiscp from "int" to "unsigned"
52 for compatibility with sscanf definition.
53*/
54#include <stdio.h>
55#include <stdlib.h>
56
57
58/**
59 @brief Bitmap pattern for each hexadecimal digit.
60
61 hexdigit[][] definition: the bitmap pattern for
62 each hexadecimal digit.
63
64 Each digit is drawn as a 4 wide by 5 high bitmap,
65 so each digit row is one hexadecimal digit, and
66 each entry has 5 rows.
67
68 For example, the entry for digit 1 is:
69
70 {0x2,0x6,0x2,0x2,0x7},
71
72 which corresponds graphically to:
73
74 --#- ==> 0010 ==> 0x2
75 -##- ==> 0110 ==> 0x6
76 --#- ==> 0010 ==> 0x2
77 --#- ==> 0010 ==> 0x2
78 -### ==> 0111 ==> 0x7
79
80 These row values will then be exclusive-ORed with four one bits
81 (binary 1111, or 0xF) to form white digits on a black background.
82
83
84 Functions hexprint4 and hexprint6 share the hexdigit array;
85 they print four-digit and six-digit hexadecimal code points
86 in a single glyph, respectively.
87*/
88 char hexdigit[16][5] = {
89 {0x6,0x9,0x9,0x9,0x6}, /* 0x0 */
90 {0x2,0x6,0x2,0x2,0x7}, /* 0x1 */
91 {0xF,0x1,0xF,0x8,0xF}, /* 0x2 */
92 {0xE,0x1,0x7,0x1,0xE}, /* 0x3 */
93 {0x9,0x9,0xF,0x1,0x1}, /* 0x4 */
94 {0xF,0x8,0xF,0x1,0xF}, /* 0x5 */
95 {0x6,0x8,0xE,0x9,0x6}, /* 0x6 */ // {0x8,0x8,0xF,0x9,0xF} [alternate square form of 6]
96 {0xF,0x1,0x2,0x4,0x4}, /* 0x7 */
97 {0x6,0x9,0x6,0x9,0x6}, /* 0x8 */
98 {0x6,0x9,0x7,0x1,0x6}, /* 0x9 */ // {0xF,0x9,0xF,0x1,0x1} [alternate square form of 9]
99 {0xF,0x9,0xF,0x9,0x9}, /* 0xA */
100 {0xE,0x9,0xE,0x9,0xE}, /* 0xB */
101 {0x7,0x8,0x8,0x8,0x7}, /* 0xC */
102 {0xE,0x9,0x9,0x9,0xE}, /* 0xD */
103 {0xF,0x8,0xE,0x8,0xF}, /* 0xE */
104 {0xF,0x8,0xE,0x8,0x8} /* 0xF */
105};
106
107
108/**
109 @brief The main function.
110
111 @param[in] argc The count of command line arguments.
112 @param[in] argv Pointer to array of command line arguments (code point range).
113 @return This program exits with status EXIT_SUCCESS.
114*/
115int
116main (int argc, char *argv[])
117{
118
119 unsigned startcp, endcp, thiscp;
120 void hexprint4(int); /* function to print one 4-digit unifont.hex code point */
121 void hexprint6(int); /* function to print one 6-digit unifont.hex code point */
122
123 if (argc != 3) {
124 fprintf (stderr,"\n%s - generate unifont.hex code points as\n", argv[0]);
125 fprintf (stderr,"four-digit hexadecimal numbers in a 2 by 2 grid,\n");
126 fprintf (stderr,"or six-digit hexadecimal numbers in a 3 by 2 grid.\n");
127 fprintf (stderr,"Syntax:\n\n");
128 fprintf (stderr," %s first_code_point last_code_point > glyphs.hex\n\n", argv[0]);
129 fprintf (stderr,"Example (to generate glyphs for the Private Use Area):\n\n");
130 fprintf (stderr," %s e000 f8ff > pua.hex\n\n", argv[0]);
131 exit (EXIT_FAILURE);
132 }
133
134 sscanf (argv[1], "%x", &startcp);
135 sscanf (argv[2], "%x", &endcp);
136
137 startcp &= 0xFFFFFF; /* limit to 6 hex digits */
138 endcp &= 0xFFFFFF; /* limit to 6 hex digits */
139
140 /*
141 For each code point in the desired range, generate a glyph.
142 */
143 for (thiscp = startcp; thiscp <= endcp; thiscp++) {
144 if (thiscp <= 0xFFFF) {
145 hexprint4 (thiscp); /* print digits 2/line, 2 lines */
146 }
147 else {
148 hexprint6 (thiscp); /* print digits 3/line, 2 lines */
149 }
150 }
151 exit (EXIT_SUCCESS);
152}
153
154
155/**
156 @brief Generate a bitmap containing a 4-digit Unicode code point.
157
158 Takes a 4-digit Unicode code point as an argument
159 and prints a unifont.hex string for it to stdout.
160
161 @param[in] thiscp The current code point for which to generate a glyph.
162*/
163void
164hexprint4 (int thiscp)
165{
166
167 int grid[16]; /* the glyph grid we'll build */
168
169 int row; /* row number in current glyph */
170 int digitrow; /* row number in current hex digit being rendered */
171 int rowbits; /* 1 & 0 bits to draw current glyph row */
172
173 int d1, d2, d3, d4; /* four hexadecimal digits of each code point */
174
175 d1 = (thiscp >> 12) & 0xF;
176 d2 = (thiscp >> 8) & 0xF;
177 d3 = (thiscp >> 4) & 0xF;
178 d4 = (thiscp ) & 0xF;
179
180 /* top and bottom rows are white */
181 grid[0] = grid[15] = 0x0000;
182
183 /* 14 inner rows are 14-pixel wide black lines, centered */
184 for (row = 1; row < 15; row++) grid[row] = 0x7FFE;
185
186 printf ("%04X:", thiscp);
187
188 /*
189 Render the first row of 2 hexadecimal digits
190 */
191 digitrow = 0; /* start at top of first row of digits to render */
192 for (row = 2; row < 7; row++) {
193 rowbits = (hexdigit[d1][digitrow] << 9) |
194 (hexdigit[d2][digitrow] << 3);
195 grid[row] ^= rowbits; /* digits appear as white on black background */
196 digitrow++;
197 }
198
199 /*
200 Render the second row of 2 hexadecimal digits
201 */
202 digitrow = 0; /* start at top of first row of digits to render */
203 for (row = 9; row < 14; row++) {
204 rowbits = (hexdigit[d3][digitrow] << 9) |
205 (hexdigit[d4][digitrow] << 3);
206 grid[row] ^= rowbits; /* digits appear as white on black background */
207 digitrow++;
208 }
209
210 for (row = 0; row < 16; row++) printf ("%04X", grid[row] & 0xFFFF);
211
212 putchar ('\n');
213
214 return;
215}
216
217
218/**
219 @brief Generate a bitmap containing a 6-digit Unicode code point.
220
221 Takes a 6-digit Unicode code point as an argument
222 and prints a unifont.hex string for it to stdout.
223
224 @param[in] thiscp The current code point for which to generate a glyph.
225*/
226void
227hexprint6 (int thiscp)
228{
229
230 int grid[16]; /* the glyph grid we'll build */
231
232 int row; /* row number in current glyph */
233 int digitrow; /* row number in current hex digit being rendered */
234 int rowbits; /* 1 & 0 bits to draw current glyph row */
235
236 int d1, d2, d3, d4, d5, d6; /* six hexadecimal digits of each code point */
237
238 d1 = (thiscp >> 20) & 0xF;
239 d2 = (thiscp >> 16) & 0xF;
240 d3 = (thiscp >> 12) & 0xF;
241 d4 = (thiscp >> 8) & 0xF;
242 d5 = (thiscp >> 4) & 0xF;
243 d6 = (thiscp ) & 0xF;
244
245 /* top and bottom rows are white */
246 grid[0] = grid[15] = 0x0000;
247
248 /* 14 inner rows are 16-pixel wide black lines, centered */
249 for (row = 1; row < 15; row++) grid[row] = 0xFFFF;
250
251
252 printf ("%06X:", thiscp);
253
254 /*
255 Render the first row of 3 hexadecimal digits
256 */
257 digitrow = 0; /* start at top of first row of digits to render */
258 for (row = 2; row < 7; row++) {
259 rowbits = (hexdigit[d1][digitrow] << 11) |
260 (hexdigit[d2][digitrow] << 6) |
261 (hexdigit[d3][digitrow] << 1);
262 grid[row] ^= rowbits; /* digits appear as white on black background */
263 digitrow++;
264 }
265
266 /*
267 Render the second row of 3 hexadecimal digits
268 */
269 digitrow = 0; /* start at top of first row of digits to render */
270 for (row = 9; row < 14; row++) {
271 rowbits = (hexdigit[d4][digitrow] << 11) |
272 (hexdigit[d5][digitrow] << 6) |
273 (hexdigit[d6][digitrow] << 1);
274 grid[row] ^= rowbits; /* digits appear as white on black background */
275 digitrow++;
276 }
277
278 for (row = 0; row < 16; row++) printf ("%04X", grid[row] & 0xFFFF);
279
280 putchar ('\n');
281
282 return;
283}
284
main
int main(int argc, char *argv[])
The main function.
Definition: unihexgen.c:116
hexprint4
void hexprint4(int thiscp)
Generate a bitmap containing a 4-digit Unicode code point.
Definition: unihexgen.c:164
hexprint6
void hexprint6(int thiscp)
Generate a bitmap containing a 6-digit Unicode code point.
Definition: unihexgen.c:227
hexdigit
char hexdigit[16][5]
Bitmap pattern for each hexadecimal digit.
Definition: unihexgen.c:88