2 unigencircles.c -- program to superimpose dashed combining circles
5 Author: Paul Hardy, 2013.
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
31 int main(int argc, char **argv) {
33 char teststring[MAXSTRING]; /* current input line */
34 int loc; /* Unicode code point of current input line */
35 char *gstart; /* glyph start, pointing into teststring */
37 char combining[0x10000];
39 void add_single_circle(char *); /* add a single-width dashed circle */
40 void add_double_circle(char *); /* add a double-width dashed circle */
47 "\n\nUsage: %s combining.txt nonprinting.hex < unifont.hex > unifontfull.hex\n\n");
53 Read the combining characters list.
55 /* Start with no combining code points flagged */
56 memset(combining, 0, 0x10000 * sizeof(char));
58 if ((infilefp = fopen(argv[1],"r")) == NULL) {
59 fprintf(stderr,"ERROR - combining characters file %s not found.\n\n",
64 /* Flag list of combining characters to add a dashed circle. */
65 while (fscanf(infilefp, "%X", &loc) != EOF) combining[loc] = 1;
67 fclose(infilefp); /* all done reading combining.txt */
69 /* Now read the non-printing glyphs; they never have dashed circles */
70 if ((infilefp = fopen(argv[2],"r")) == NULL) {
71 fprintf(stderr,"ERROR - nonprinting characters file %s not found.\n\n",
76 /* Reset list of nonprinting characters to avoid adding a dashed circle. */
77 while (fscanf(infilefp, "%X:%*s", &loc) != EOF) combining[loc] = 0;
79 fclose(infilefp); /* all done reading nonprinting.hex */
84 teststring[MAXSTRING - 1] = '\0'; /* so there's no chance we leave array */
85 while (fgets(teststring, MAXSTRING-1, stdin) != NULL) {
86 sscanf(teststring, "%X", &loc); /* loc == the Uniocde code point */
87 gstart = index(teststring,':') + 1; /* start of glyph bitmap */
88 if (combining[loc]) { /* if a combining character */
89 if (strlen(gstart) < 35) add_single_circle(gstart); /* single-width */
90 else add_double_circle(gstart); /* double-width */
92 printf("%s", teststring); /* output the new character .hex string */
100 add_single_circle() - superimpose a single-width dashed combining circle.
102 void add_single_circle(char *glyphstring) {
105 /* Circle hex string pattern is "00000008000024004200240000000000" */
106 char circle[32]={0x0,0x0, /* row 1 */
115 0x0,0x0, /* row 10 */
116 0x2,0x4, /* row 11 */
117 0x0,0x0, /* row 12 */
118 0x0,0x0, /* row 13 */
119 0x0,0x0, /* row 14 */
120 0x0,0x0, /* row 15 */
121 0x0,0x0}; /* row 16 */
123 int digit1, digit2; /* corresponding digits in each string */
125 int i; /* index variables */
127 /* for each character position, OR the corresponding circle glyph value */
128 for (i = 0; i < 32; i++) {
129 glyphstring[i] = toupper(glyphstring[i]);
131 /* Convert ASCII character to a hexadecimal integer */
132 digit1 = (glyphstring[i] <= '9') ?
133 (glyphstring[i] - '0') : (glyphstring[i] - 'A' + 0xA);
135 /* Superimpose dashed circle */
136 digit2 = digit1 | circle[i];
138 /* Convert hexadecimal integer to an ASCII character */
139 newstring[i] = (digit2 <= 9) ?
140 ('0' + digit2) : ('A' + digit2 - 0xA);
143 /* Terminate string for output */
144 newstring[i++] = '\n';
145 newstring[i++] = '\0';
147 strncpy(glyphstring, newstring, i);
154 add_double_circle() - superimpose a single-width dashed combining circle.
156 void add_double_circle(char *glyphstring) {
159 /* Circle hex string pattern is "00000008000024004200240000000000" */
160 char circle[64]={0x0,0x0,0x0,0x0, /* row 1 */
161 0x0,0x0,0x0,0x0, /* row 2 */
162 0x0,0x0,0x0,0x0, /* row 3 */
163 0x0,0x0,0x0,0x0, /* row 4 */
164 0x0,0x0,0x0,0x0, /* row 5 */
165 0x0,0x0,0x0,0x0, /* row 6 */
166 0x0,0x2,0x4,0x0, /* row 7 */
167 0x0,0x0,0x0,0x0, /* row 8 */
168 0x0,0x4,0x2,0x0, /* row 9 */
169 0x0,0x0,0x0,0x0, /* row 10 */
170 0x0,0x2,0x4,0x0, /* row 11 */
171 0x0,0x0,0x0,0x0, /* row 12 */
172 0x0,0x0,0x0,0x0, /* row 13 */
173 0x0,0x0,0x0,0x0, /* row 14 */
174 0x0,0x0,0x0,0x0, /* row 15 */
175 0x0,0x0,0x0,0x0}; /* row 16 */
177 int digit1, digit2; /* corresponding digits in each string */
179 int i; /* index variables */
181 /* for each character position, OR the corresponding circle glyph value */
182 for (i = 0; i < 64; i++) {
183 glyphstring[i] = toupper(glyphstring[i]);
185 /* Convert ASCII character to a hexadecimal integer */
186 digit1 = (glyphstring[i] <= '9') ?
187 (glyphstring[i] - '0') : (glyphstring[i] - 'A' + 0xA);
189 /* Superimpose dashed circle */
190 digit2 = digit1 | circle[i];
192 /* Convert hexadecimal integer to an ASCII character */
193 newstring[i] = (digit2 <= 9) ?
194 ('0' + digit2) : ('A' + digit2 - 0xA);
197 /* Terminate string for output */
198 newstring[i++] = '\n';
199 newstring[i++] = '\0';
201 strncpy(glyphstring, newstring, i);