GNU Unifont  15.1.01
Pan-Unicode font with complete Unicode Plane 0 coverage and partial coverage of higher planes
unifont-support.c
Go to the documentation of this file.
1 /**
2  @file: unifont-support.c
3 
4  @brief: Support functions for Unifont .hex files.
5 
6  @author Paul Hardy
7 
8  @copyright Copyright © 2023 Paul Hardy
9 */
10 /*
11  LICENSE:
12 
13  This program is free software: you can redistribute it and/or modify
14  it under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 2 of the License, or
16  (at your option) any later version.
17 
18  This program is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  GNU General Public License for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with this program. If not, see <http://www.gnu.org/licenses/>.
25 */
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 
30 
31 /**
32  @brief Decode a Unifont .hex file into Uniocde code point and glyph.
33 
34  This function takes one line from a Unifont .hex file and decodes
35  it into a code point followed by a 16-row glyph array. The glyph
36  array can be one byte (8 columns) or two bytes (16 columns).
37 
38  @param[in] hexstring The Unicode .hex string for one code point.
39  @param[out] width The number of columns in a glyph with 16 rows.
40  @param[out] codept The code point, contained in the first .hex file field.
41  @param[out] glyph The Unifont glyph, as 16 rows by 1 or 2 bytes wide.
42 */
43 void
44 parse_hex (char *hexstring,
45  int *width,
46  unsigned *codept,
47  unsigned char glyph[16][2]) {
48 
49  int i;
50  int row;
51  int length;
52 
53  sscanf (hexstring, "%X", codept);
54  length = strlen (hexstring);
55  for (i = length - 1; i > 0 && hexstring[i] != '\n'; i--);
56  hexstring[i] = '\0';
57  for (i = 0; i < 9 && hexstring[i] != ':'; i++);
58  i++; /* Skip over ':' */
59  *width = (length - i) * 4 / 16; /* 16 rows per glyphbits */
60 
61  for (row = 0; row < 16; row++) {
62  sscanf (&hexstring[i], "%2hhX", &glyph [row][0]);
63  i += 2;
64  if (*width > 8) {
65  sscanf (&hexstring[i], "%2hhX", &glyph [row][1]);
66  i += 2;
67  }
68  else {
69  glyph [row][1] = 0x00;
70  }
71  }
72 
73 
74  return;
75 }
76 
77 
78 /**
79  @brief Convert a Unifont binary glyph into a binary glyph array of bits.
80 
81  This function takes a Unifont 16-row by 1- or 2-byte wide binary glyph
82  and returns an array of 16 rows by 16 columns. For each output array
83  element, a 1 indicates the corresponding bit was set in the binary
84  glyph, and a 0 indicates the corresponding bit was not set.
85 
86  @param[in] width The number of columns in the glyph.
87  @param[in] glyph The binary glyph, as a 16-row by 2-byte array.
88  @param[out] glyphbits The converted glyph, as a 16-row, 16-column array.
89 */
90 void
91 glyph2bits (int width,
92  unsigned char glyph[16][2],
93  unsigned char glyphbits [16][16]) {
94 
95  unsigned char tmp_byte;
96  unsigned char mask;
97  int row, column;
98 
99  for (row = 0; row < 16; row++) {
100  tmp_byte = glyph [row][0];
101  mask = 0x80;
102  for (column = 0; column < 8; column++) {
103  glyphbits [row][column] = tmp_byte & mask ? 1 : 0;
104  mask >>= 1;
105  }
106 
107  if (width > 8)
108  tmp_byte = glyph [row][1];
109  else
110  tmp_byte = 0x00;
111 
112  mask = 0x80;
113  for (column = 8; column < 16; column++) {
114  glyphbits [row][column] = tmp_byte & mask ? 1 : 0;
115  mask >>= 1;
116  }
117  }
118 
119 
120  return;
121 }
122 
123 
124 /**
125  @brief Transpose a Unifont .hex format glyph into 2 column-major sub-arrays.
126 
127  This function takes a 16-by-16 cell bit array made from a Unifont
128  glyph (as created by the glyph2bits function) and outputs a transposed
129  array of 2 sets of 8 or 16 columns, depending on the glyph width.
130  This format simplifies outputting these bit patterns on a graphics
131  display with a controller chip designed to output a column of 8 pixels
132  at a time.
133 
134  For a line of text with Unifont output, first all glyphs can have
135  their first 8 rows of pixels displayed on a line. Then the second
136  8 rows of all glyphs on the line can be displayed. This simplifies
137  code for such controller chips that are designed to automatically
138  increment input bytes of column data by one column at a time for
139  each successive byte.
140 
141  The glyphbits array contains a '1' in each cell where the corresponding
142  non-transposed glyph has a pixel set, and 0 in each cell where a pixel
143  is not set.
144 
145  @param[in] width The number of columns in the glyph.
146  @param[in] glyphbits The 16-by-16 pixel glyph bits.
147  @param[out] transpose The array of 2 sets of 8 ot 16 columns of 8 pixels.
148 */
149 void
150 hexpose (int width,
151  unsigned char glyphbits [16][16],
152  unsigned char transpose [2][16]) {
153 
154  int column;
155 
156 
157  for (column = 0; column < 8; column++) {
158  transpose [0][column] =
159  (glyphbits [ 0][column] << 7) |
160  (glyphbits [ 1][column] << 6) |
161  (glyphbits [ 2][column] << 5) |
162  (glyphbits [ 3][column] << 4) |
163  (glyphbits [ 4][column] << 3) |
164  (glyphbits [ 5][column] << 2) |
165  (glyphbits [ 6][column] << 1) |
166  (glyphbits [ 7][column] );
167  transpose [1][column] =
168  (glyphbits [ 8][column] << 7) |
169  (glyphbits [ 9][column] << 6) |
170  (glyphbits [10][column] << 5) |
171  (glyphbits [11][column] << 4) |
172  (glyphbits [12][column] << 3) |
173  (glyphbits [13][column] << 2) |
174  (glyphbits [14][column] << 1) |
175  (glyphbits [15][column] );
176  }
177  if (width > 8) {
178  for (column = 8; column < width; column++) {
179  transpose [0][column] =
180  (glyphbits [0][column] << 7) |
181  (glyphbits [1][column] << 6) |
182  (glyphbits [2][column] << 5) |
183  (glyphbits [3][column] << 4) |
184  (glyphbits [4][column] << 3) |
185  (glyphbits [5][column] << 2) |
186  (glyphbits [6][column] << 1) |
187  (glyphbits [7][column] );
188  transpose [1][column] =
189  (glyphbits [ 8][column] << 7) |
190  (glyphbits [ 9][column] << 6) |
191  (glyphbits [10][column] << 5) |
192  (glyphbits [11][column] << 4) |
193  (glyphbits [12][column] << 3) |
194  (glyphbits [13][column] << 2) |
195  (glyphbits [14][column] << 1) |
196  (glyphbits [15][column] );
197  }
198  }
199  else {
200  for (column = 8; column < width; column++)
201  transpose [0][column] = transpose [1][column] = 0x00;
202  }
203 
204 
205  return;
206 }
207 
208 
209 /**
210  @brief Convert a glyph code point and byte array into a Unifont .hex string.
211 
212  This function takes a code point and a 16-row by 1- or 2-byte binary
213  glyph, and converts it into a Unifont .hex format character array.
214 
215  @param[in] width The number of columns in the glyph.
216  @param[in] codept The code point to appear in the output .hex string.
217  @param[in] glyph The glyph, with each of 16 rows 1 or 2 bytes wide.
218  @param[out] outstring The output string, in Unifont .hex format.
219 */
220 void
221 glyph2string (int width, unsigned codept,
222  unsigned char glyph [16][2],
223  char *outstring) {
224 
225  int i; /* index into outstring array */
226  int row;
227 
228  if (codept <= 0xFFFF) {
229  sprintf (outstring, "%04X:", codept);
230  i = 5;
231  }
232  else {
233  sprintf (outstring, "%06X:", codept);
234  i = 7;
235  }
236 
237  for (row = 0; row < 16; row++) {
238  sprintf (&outstring[i], "%02X", glyph [row][0]);
239  i += 2;
240 
241  if (width > 8) {
242  sprintf (&outstring[i], "%02X", glyph [row][1]);
243  i += 2;
244  }
245  }
246 
247  outstring[i] = '\0'; /* terminate output string */
248 
249 
250  return;
251 }
252 
253 
254 /**
255  @brief Convert a code point and transposed glyph into a Unifont .hex string.
256 
257  This function takes a code point and a transposed Unifont glyph
258  of 2 rows of 8 pixels in a column, and converts it into a Unifont
259  .hex format character array.
260 
261  @param[in] width The number of columns in the glyph.
262  @param[in] codept The code point to appear in the output .hex string.
263  @param[in] transpose The transposed glyph, with 2 sets of 8-row data.
264  @param[out] outstring The output string, in Unifont .hex format.
265 */
266 void
267 xglyph2string (int width, unsigned codept,
268  unsigned char transpose [2][16],
269  char *outstring) {
270 
271  int i; /* index into outstring array */
272  int column;
273 
274  if (codept <= 0xFFFF) {
275  sprintf (outstring, "%04X:", codept);
276  i = 5;
277  }
278  else {
279  sprintf (outstring, "%06X:", codept);
280  i = 7;
281  }
282 
283  for (column = 0; column < 8; column++) {
284  sprintf (&outstring[i], "%02X", transpose [0][column]);
285  i += 2;
286  }
287  if (width > 8) {
288  for (column = 8; column < 16; column++) {
289  sprintf (&outstring[i], "%02X", transpose [0][column]);
290  i += 2;
291  }
292  }
293  for (column = 0; column < 8; column++) {
294  sprintf (&outstring[i], "%02X", transpose [1][column]);
295  i += 2;
296  }
297  if (width > 8) {
298  for (column = 8; column < 16; column++) {
299  sprintf (&outstring[i], "%02X", transpose [1][column]);
300  i += 2;
301  }
302  }
303 
304  outstring[i] = '\0'; /* terminate output string */
305 
306 
307  return;
308 }
309 
void hexpose(int width, unsigned char glyphbits[16][16], unsigned char transpose[2][16])
Transpose a Unifont .hex format glyph into 2 column-major sub-arrays.
void glyph2bits(int width, unsigned char glyph[16][2], unsigned char glyphbits[16][16])
Convert a Unifont binary glyph into a binary glyph array of bits.
void xglyph2string(int width, unsigned codept, unsigned char transpose[2][16], char *outstring)
Convert a code point and transposed glyph into a Unifont .hex string.
void parse_hex(char *hexstring, int *width, unsigned *codept, unsigned char glyph[16][2])
Decode a Unifont .hex file into Uniocde code point and glyph.
void glyph2string(int width, unsigned codept, unsigned char glyph[16][2], char *outstring)
Convert a glyph code point and byte array into a Unifont .hex string.