GNU Unifont 17.0.01
Pan-Unicode font with complete Unicode Plane 0 coverage and partial coverage of higher planes
unigencircles.c
Go to the documentation of this file.
1/**
2 @file unigencircles.c
3
4 @brief unigencircles - Superimpose dashed combining circles
5 on combining glyphs
6
7 @author Paul Hardy
8
9 @copyright Copyright (C) 2013, Paul Hardy.
10*/
11/*
12 LICENSE:
13
14 This program is free software: you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program. If not, see <http://www.gnu.org/licenses/>.
26*/
27
28/*
29 8 July 2017 [Paul Hardy]:
30 - Reads new second field that contains an x-axis offset for
31 each combining character in "*combining.txt" files.
32 - Uses the above x-axis offset value for a combining character
33 to print combining circle in the left half of a double
34 diacritic combining character grid, or in the center for
35 other combining characters.
36 - Adds exceptions for U+01107F (Brahmi number joiner) and
37 U+01D1A0 (vertical stroke musical ornament); they are in
38 a combining.txt file for positioning, but are not actually
39 Unicode combining characters.
40 - Typo fix: "single-width"-->"double-width" in comment for
41 add_double_circle function.
42
43 12 August 2017 [Paul Hardy]:
44 - Hard-code Miao vowels to show combining circles after
45 removing them from font/plane01/plane01-combining.txt.
46
47 26 December 2017 [Paul Hardy]:
48 - Remove Miao hard-coding; they are back in unibmp2hex.c and
49 in font/plane01/plane01-combining.txt.
50
51 11 May 2019 [Paul Hardy]:
52 - Changed strncpy calls to memcpy calls to avoid a compiler
53 warning.
54
55 6 September 2025 [Paul Hardy]:
56 - Changed loc from "int" to "unsigned" for compatibility with
57 fscanf and sscanf definitions.
58*/
59
60
61#include <stdio.h>
62#include <stdlib.h>
63#include <string.h>
64#include <ctype.h>
65
66#define MAXSTRING 256 ///< Maximum input line length - 1.
67
68
69/**
70 @brief The main function.
71
72 @param[in] argc The count of command line arguments.
73 @param[in] argv Pointer to array of command line arguments.
74 @return This program exits with status EXIT_SUCCESS.
75*/
76int
77main (int argc, char **argv)
78{
79
80 char teststring[MAXSTRING]; /* current input line */
81 unsigned loc; /* Unicode code point of current input line */
82 int offset; /* offset value of a combining character */
83 char *gstart; /* glyph start, pointing into teststring */
84
85 char combining[0x110000]; /* 1 --> combining glyph; 0 --> non-combining */
86 char x_offset [0x110000]; /* second value in *combining.txt files */
87
88 void add_single_circle(char *); /* add a single-width dashed circle */
89 void add_double_circle(char *, int); /* add a double-width dashed circle */
90
91 FILE *infilefp;
92
93 /*
94 if (argc != 3) {
95 fprintf (stderr,
96 "\n\nUsage: %s combining.txt nonprinting.hex < unifont.hex > unifontfull.hex\n\n");
97 exit (EXIT_FAILURE);
98 }
99 */
100
101 /*
102 Read the combining characters list.
103 */
104 /* Start with no combining code points flagged */
105 memset (combining, 0, 0x110000 * sizeof (char));
106 memset (x_offset , 0, 0x110000 * sizeof (char));
107
108 if ((infilefp = fopen (argv[1],"r")) == NULL) {
109 fprintf (stderr,"ERROR - combining characters file %s not found.\n\n",
110 argv[1]);
111 exit (EXIT_FAILURE);
112 }
113
114 /* Flag list of combining characters to add a dashed circle. */
115 while (fscanf (infilefp, "%X:%d", &loc, &offset) != EOF) {
116 /*
117 U+01107F and U+01D1A0 are not defined as combining characters
118 in Unicode; they were added in a combining.txt file as the
119 only way to make them look acceptable in proximity to other
120 glyphs in their script.
121 */
122 if (loc != 0x01107F && loc != 0x01D1A0) {
123 combining[loc] = 1;
124 x_offset [loc] = offset;
125 }
126 }
127 fclose (infilefp); /* all done reading combining.txt */
128
129 /* Now read the non-printing glyphs; they never have dashed circles */
130 if ((infilefp = fopen (argv[2],"r")) == NULL) {
131 fprintf (stderr,"ERROR - nonprinting characters file %s not found.\n\n",
132 argv[1]);
133 exit (EXIT_FAILURE);
134 }
135
136 /* Reset list of nonprinting characters to avoid adding a dashed circle. */
137 while (fscanf (infilefp, "%X:%*s", &loc) != EOF) combining[loc] = 0;
138
139 fclose (infilefp); /* all done reading nonprinting.hex */
140
141 /*
142 Read the hex glyphs.
143 */
144 teststring[MAXSTRING - 1] = '\0'; /* so there's no chance we leave array */
145 while (fgets (teststring, MAXSTRING-1, stdin) != NULL) {
146 sscanf (teststring, "%X", &loc); /* loc == the Uniocde code point */
147 gstart = strchr (teststring,':') + 1; /* start of glyph bitmap */
148 if (combining[loc]) { /* if a combining character */
149 if (strlen (gstart) < 35)
150 add_single_circle (gstart); /* single-width */
151 else
152 add_double_circle (gstart, x_offset[loc]); /* double-width */
153 }
154 printf ("%s", teststring); /* output the new character .hex string */
155 }
156
157 exit (EXIT_SUCCESS);
158}
159
160
161/**
162 @brief Superimpose a single-width dashed combining circle on a glyph bitmap.
163
164 @param[in,out] glyphstring A single-width glyph, 8x16 pixels.
165*/
166void
167add_single_circle (char *glyphstring)
168{
169
170 char newstring[256];
171 /* Circle hex string pattern is "00000008000024004200240000000000" */
172 char circle[32]={0x0,0x0, /* row 1 */
173 0x0,0x0, /* row 2 */
174 0x0,0x0, /* row 3 */
175 0x0,0x0, /* row 4 */
176 0x0,0x0, /* row 5 */
177 0x0,0x0, /* row 6 */
178 0x2,0x4, /* row 7 */
179 0x0,0x0, /* row 8 */
180 0x4,0x2, /* row 9 */
181 0x0,0x0, /* row 10 */
182 0x2,0x4, /* row 11 */
183 0x0,0x0, /* row 12 */
184 0x0,0x0, /* row 13 */
185 0x0,0x0, /* row 14 */
186 0x0,0x0, /* row 15 */
187 0x0,0x0}; /* row 16 */
188
189 int digit1, digit2; /* corresponding digits in each string */
190
191 int i; /* index variables */
192
193 /* for each character position, OR the corresponding circle glyph value */
194 for (i = 0; i < 32; i++) {
195 glyphstring[i] = toupper (glyphstring[i]);
196
197 /* Convert ASCII character to a hexadecimal integer */
198 digit1 = (glyphstring[i] <= '9') ?
199 (glyphstring[i] - '0') : (glyphstring[i] - 'A' + 0xA);
200
201 /* Superimpose dashed circle */
202 digit2 = digit1 | circle[i];
203
204 /* Convert hexadecimal integer to an ASCII character */
205 newstring[i] = (digit2 <= 9) ?
206 ('0' + digit2) : ('A' + digit2 - 0xA);
207 }
208
209 /* Terminate string for output */
210 newstring[i++] = '\n';
211 newstring[i++] = '\0';
212
213 memcpy (glyphstring, newstring, i);
214
215 return;
216}
217
218
219/**
220 @brief Superimpose a double-width dashed combining circle on a glyph bitmap.
221
222 @param[in,out] glyphstring A double-width glyph, 16x16 pixels.
223*/
224void
225add_double_circle (char *glyphstring, int offset)
226{
227
228 char newstring[256];
229 /* Circle hex string pattern is "00000008000024004200240000000000" */
230
231 /* For double diacritical glyphs (offset = -8) */
232 /* Combining circle is left-justified. */
233 char circle08[64]={0x0,0x0,0x0,0x0, /* row 1 */
234 0x0,0x0,0x0,0x0, /* row 2 */
235 0x0,0x0,0x0,0x0, /* row 3 */
236 0x0,0x0,0x0,0x0, /* row 4 */
237 0x0,0x0,0x0,0x0, /* row 5 */
238 0x0,0x0,0x0,0x0, /* row 6 */
239 0x2,0x4,0x0,0x0, /* row 7 */
240 0x0,0x0,0x0,0x0, /* row 8 */
241 0x4,0x2,0x0,0x0, /* row 9 */
242 0x0,0x0,0x0,0x0, /* row 10 */
243 0x2,0x4,0x0,0x0, /* row 11 */
244 0x0,0x0,0x0,0x0, /* row 12 */
245 0x0,0x0,0x0,0x0, /* row 13 */
246 0x0,0x0,0x0,0x0, /* row 14 */
247 0x0,0x0,0x0,0x0, /* row 15 */
248 0x0,0x0,0x0,0x0}; /* row 16 */
249
250 /* For all other combining glyphs (offset = -16) */
251 /* Combining circle is centered in 16 columns. */
252 char circle16[64]={0x0,0x0,0x0,0x0, /* row 1 */
253 0x0,0x0,0x0,0x0, /* row 2 */
254 0x0,0x0,0x0,0x0, /* row 3 */
255 0x0,0x0,0x0,0x0, /* row 4 */
256 0x0,0x0,0x0,0x0, /* row 5 */
257 0x0,0x0,0x0,0x0, /* row 6 */
258 0x0,0x2,0x4,0x0, /* row 7 */
259 0x0,0x0,0x0,0x0, /* row 8 */
260 0x0,0x4,0x2,0x0, /* row 9 */
261 0x0,0x0,0x0,0x0, /* row 10 */
262 0x0,0x2,0x4,0x0, /* row 11 */
263 0x0,0x0,0x0,0x0, /* row 12 */
264 0x0,0x0,0x0,0x0, /* row 13 */
265 0x0,0x0,0x0,0x0, /* row 14 */
266 0x0,0x0,0x0,0x0, /* row 15 */
267 0x0,0x0,0x0,0x0}; /* row 16 */
268
269 char *circle; /* points into circle16 or circle08 */
270
271 int digit1, digit2; /* corresponding digits in each string */
272
273 int i; /* index variables */
274
275
276 /*
277 Determine if combining circle is left-justified (offset = -8)
278 or centered (offset = -16).
279 */
280 circle = (offset >= -8) ? circle08 : circle16;
281
282 /* for each character position, OR the corresponding circle glyph value */
283 for (i = 0; i < 64; i++) {
284 glyphstring[i] = toupper (glyphstring[i]);
285
286 /* Convert ASCII character to a hexadecimal integer */
287 digit1 = (glyphstring[i] <= '9') ?
288 (glyphstring[i] - '0') : (glyphstring[i] - 'A' + 0xA);
289
290 /* Superimpose dashed circle */
291 digit2 = digit1 | circle[i];
292
293 /* Convert hexadecimal integer to an ASCII character */
294 newstring[i] = (digit2 <= 9) ?
295 ('0' + digit2) : ('A' + digit2 - 0xA);
296 }
297
298 /* Terminate string for output */
299 newstring[i++] = '\n';
300 newstring[i++] = '\0';
301
302 memcpy (glyphstring, newstring, i);
303
304 return;
305}
306
int main(void)
The main function.
Definition: unibdf2hex.c:46
void add_double_circle(char *glyphstring, int offset)
Superimpose a double-width dashed combining circle on a glyph bitmap.
#define MAXSTRING
Maximum input line length - 1.
Definition: unigencircles.c:66
void add_single_circle(char *glyphstring)
Superimpose a single-width dashed combining circle on a glyph bitmap.