unifont-6.3.20131020.tar.gz
[unifont.git] / src / unigencircles.c
1 /*
2    unigencircles.c -- program to superimpose dashed combining circles
3                       on combining glyphs.
4
5    Author: Paul Hardy, 2013.
6
7    LICENSE:
8
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.
13
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.
18
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/>.
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27
28 #define MAXSTRING       256
29
30
31 int main(int argc, char **argv) {
32
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    */
36
37    char combining[0x10000];
38
39    void add_single_circle(char *); /* add a single-width dashed circle */
40    void add_double_circle(char *); /* add a double-width dashed circle */
41
42    FILE *infilefp;
43
44    /*
45       if (argc != 3) {
46          fprintf(stderr,
47                 "\n\nUsage: %s combining.txt nonprinting.hex < unifont.hex > unifontfull.hex\n\n");
48          exit(EXIT_FAILURE);
49       }
50    */
51
52    /*
53       Read the combining characters list.
54    */
55    /* Start with no combining code points flagged */
56    memset(combining, 0, 0x10000 * sizeof(char));
57
58    if ((infilefp = fopen(argv[1],"r")) == NULL) {
59       fprintf(stderr,"ERROR - combining characters file %s not found.\n\n",
60               argv[1]);
61       exit(EXIT_FAILURE);
62    }
63
64    /* Flag list of combining characters to add a dashed circle. */
65    while (fscanf(infilefp, "%X", &loc) != EOF) combining[loc] = 1;
66
67    fclose(infilefp); /* all done reading combining.txt */
68
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",
72               argv[1]);
73       exit(EXIT_FAILURE);
74    }
75
76    /* Reset list of nonprinting characters to avoid adding a dashed circle. */
77    while (fscanf(infilefp, "%X:%*s", &loc) != EOF) combining[loc] = 0;
78
79    fclose(infilefp); /* all done reading nonprinting.hex */
80
81    /*
82       Read the hex glyphs.
83    */
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 */
91       }
92       printf("%s", teststring); /* output the new character .hex string */
93    }
94
95    exit(EXIT_SUCCESS);
96 }
97
98
99 /*
100    add_single_circle() - superimpose a single-width dashed combining circle.
101 */
102 void add_single_circle(char *glyphstring) {
103
104    char newstring[256];
105    /* Circle hex string pattern is "00000008000024004200240000000000" */
106    char circle[32]={0x0,0x0,  /* row  1 */
107                     0x0,0x0,  /* row  2 */
108                     0x0,0x0,  /* row  3 */
109                     0x0,0x0,  /* row  4 */
110                     0x0,0x0,  /* row  5 */
111                     0x0,0x0,  /* row  6 */
112                     0x2,0x4,  /* row  7 */
113                     0x0,0x0,  /* row  8 */
114                     0x4,0x2,  /* row  9 */
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 */
122
123    int digit1, digit2; /* corresponding digits in each string */
124
125    int i; /* index variables */
126
127    /* for each character position, OR the corresponding circle glyph value */
128    for (i = 0; i < 32; i++) {
129       glyphstring[i] = toupper(glyphstring[i]);
130
131       /* Convert ASCII character to a hexadecimal integer */
132       digit1 = (glyphstring[i] <= '9') ?
133                (glyphstring[i] - '0') : (glyphstring[i] - 'A' + 0xA);
134
135       /* Superimpose dashed circle */
136       digit2 = digit1 | circle[i];
137
138       /* Convert hexadecimal integer to an ASCII character */
139       newstring[i] = (digit2 <= 9) ?
140                      ('0' + digit2) : ('A' + digit2 - 0xA);
141    }
142
143    /* Terminate string for output */
144    newstring[i++] = '\n';
145    newstring[i++] = '\0';
146
147    strncpy(glyphstring, newstring, i);
148
149    return;
150 }
151
152
153 /*
154    add_double_circle() - superimpose a single-width dashed combining circle.
155 */
156 void add_double_circle(char *glyphstring) {
157
158    char newstring[256];
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 */
176
177    int digit1, digit2; /* corresponding digits in each string */
178
179    int i; /* index variables */
180
181    /* for each character position, OR the corresponding circle glyph value */
182    for (i = 0; i < 64; i++) {
183       glyphstring[i] = toupper(glyphstring[i]);
184
185       /* Convert ASCII character to a hexadecimal integer */
186       digit1 = (glyphstring[i] <= '9') ?
187                (glyphstring[i] - '0') : (glyphstring[i] - 'A' + 0xA);
188
189       /* Superimpose dashed circle */
190       digit2 = digit1 | circle[i];
191
192       /* Convert hexadecimal integer to an ASCII character */
193       newstring[i] = (digit2 <= 9) ?
194                      ('0' + digit2) : ('A' + digit2 - 0xA);
195    }
196
197    /* Terminate string for output */
198    newstring[i++] = '\n';
199    newstring[i++] = '\0';
200
201    strncpy(glyphstring, newstring, i);
202
203    return;
204 }
205