unifont-7.0.01.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
32 main (int argc, char **argv)
33 {
34
35    char teststring[MAXSTRING];  /* current input line                       */
36    int  loc;                    /* Unicode code point of current input line */
37    char *gstart;                /* glyph start, pointing into teststring    */
38
39    char combining[0x110000];
40
41    void add_single_circle(char *); /* add a single-width dashed circle */
42    void add_double_circle(char *); /* add a double-width dashed circle */
43
44    FILE *infilefp;
45
46    /*
47       if (argc != 3) {
48          fprintf (stderr,
49                 "\n\nUsage: %s combining.txt nonprinting.hex < unifont.hex > unifontfull.hex\n\n");
50          exit (EXIT_FAILURE);
51       }
52    */
53
54    /*
55       Read the combining characters list.
56    */
57    /* Start with no combining code points flagged */
58    memset (combining, 0, 0x110000 * sizeof (char));
59
60    if ((infilefp = fopen (argv[1],"r")) == NULL) {
61       fprintf (stderr,"ERROR - combining characters file %s not found.\n\n",
62               argv[1]);
63       exit (EXIT_FAILURE);
64    }
65
66    /* Flag list of combining characters to add a dashed circle. */
67    while (fscanf (infilefp, "%X", &loc) != EOF) combining[loc] = 1;
68
69    fclose (infilefp); /* all done reading combining.txt */
70
71    /* Now read the non-printing glyphs; they never have dashed circles */
72    if ((infilefp = fopen (argv[2],"r")) == NULL) {
73       fprintf (stderr,"ERROR - nonprinting characters file %s not found.\n\n",
74               argv[1]);
75       exit (EXIT_FAILURE);
76    }
77
78    /* Reset list of nonprinting characters to avoid adding a dashed circle. */
79    while (fscanf (infilefp, "%X:%*s", &loc) != EOF) combining[loc] = 0;
80
81    fclose (infilefp); /* all done reading nonprinting.hex */
82
83    /*
84       Read the hex glyphs.
85    */
86    teststring[MAXSTRING - 1] = '\0';   /* so there's no chance we leave array  */
87    while (fgets (teststring, MAXSTRING-1, stdin) != NULL) {
88       sscanf (teststring, "%X", &loc);     /* loc == the Uniocde code point    */
89       gstart = index (teststring,':') + 1; /* start of glyph bitmap            */
90       if (combining[loc]) {                /* if a combining character         */
91          if (strlen (gstart) < 35) add_single_circle (gstart); /* single-width */
92          else add_double_circle (gstart);                      /* double-width */
93       }
94       printf ("%s", teststring); /* output the new character .hex string */
95    }
96
97    exit (EXIT_SUCCESS);
98 }
99
100
101 /*
102    add_single_circle - superimpose a single-width dashed combining circle.
103 */
104 void
105 add_single_circle (char *glyphstring)
106 {
107
108    char newstring[256];
109    /* Circle hex string pattern is "00000008000024004200240000000000" */
110    char circle[32]={0x0,0x0,  /* row  1 */
111                     0x0,0x0,  /* row  2 */
112                     0x0,0x0,  /* row  3 */
113                     0x0,0x0,  /* row  4 */
114                     0x0,0x0,  /* row  5 */
115                     0x0,0x0,  /* row  6 */
116                     0x2,0x4,  /* row  7 */
117                     0x0,0x0,  /* row  8 */
118                     0x4,0x2,  /* row  9 */
119                     0x0,0x0,  /* row 10 */
120                     0x2,0x4,  /* row 11 */
121                     0x0,0x0,  /* row 12 */
122                     0x0,0x0,  /* row 13 */
123                     0x0,0x0,  /* row 14 */
124                     0x0,0x0,  /* row 15 */
125                     0x0,0x0}; /* row 16 */
126
127    int digit1, digit2; /* corresponding digits in each string */
128
129    int i; /* index variables */
130
131    /* for each character position, OR the corresponding circle glyph value */
132    for (i = 0; i < 32; i++) {
133       glyphstring[i] = toupper (glyphstring[i]);
134
135       /* Convert ASCII character to a hexadecimal integer */
136       digit1 = (glyphstring[i] <= '9') ?
137                (glyphstring[i] - '0') : (glyphstring[i] - 'A' + 0xA);
138
139       /* Superimpose dashed circle */
140       digit2 = digit1 | circle[i];
141
142       /* Convert hexadecimal integer to an ASCII character */
143       newstring[i] = (digit2 <= 9) ?
144                      ('0' + digit2) : ('A' + digit2 - 0xA);
145    }
146
147    /* Terminate string for output */
148    newstring[i++] = '\n';
149    newstring[i++] = '\0';
150
151    strncpy (glyphstring, newstring, i);
152
153    return;
154 }
155
156
157 /*
158    add_double_circle - superimpose a single-width dashed combining circle.
159 */
160 void
161 add_double_circle (char *glyphstring)
162 {
163
164    char newstring[256];
165    /* Circle hex string pattern is "00000008000024004200240000000000" */
166    char circle[64]={0x0,0x0,0x0,0x0,  /* row  1 */
167                     0x0,0x0,0x0,0x0,  /* row  2 */
168                     0x0,0x0,0x0,0x0,  /* row  3 */
169                     0x0,0x0,0x0,0x0,  /* row  4 */
170                     0x0,0x0,0x0,0x0,  /* row  5 */
171                     0x0,0x0,0x0,0x0,  /* row  6 */
172                     0x0,0x2,0x4,0x0,  /* row  7 */
173                     0x0,0x0,0x0,0x0,  /* row  8 */
174                     0x0,0x4,0x2,0x0,  /* row  9 */
175                     0x0,0x0,0x0,0x0,  /* row 10 */
176                     0x0,0x2,0x4,0x0,  /* row 11 */
177                     0x0,0x0,0x0,0x0,  /* row 12 */
178                     0x0,0x0,0x0,0x0,  /* row 13 */
179                     0x0,0x0,0x0,0x0,  /* row 14 */
180                     0x0,0x0,0x0,0x0,  /* row 15 */
181                     0x0,0x0,0x0,0x0}; /* row 16 */
182
183    int digit1, digit2; /* corresponding digits in each string */
184
185    int i; /* index variables */
186
187    /* for each character position, OR the corresponding circle glyph value */
188    for (i = 0; i < 64; i++) {
189       glyphstring[i] = toupper (glyphstring[i]);
190
191       /* Convert ASCII character to a hexadecimal integer */
192       digit1 = (glyphstring[i] <= '9') ?
193                (glyphstring[i] - '0') : (glyphstring[i] - 'A' + 0xA);
194
195       /* Superimpose dashed circle */
196       digit2 = digit1 | circle[i];
197
198       /* Convert hexadecimal integer to an ASCII character */
199       newstring[i] = (digit2 <= 9) ?
200                      ('0' + digit2) : ('A' + digit2 - 0xA);
201    }
202
203    /* Terminate string for output */
204    newstring[i++] = '\n';
205    newstring[i++] = '\0';
206
207    strncpy (glyphstring, newstring, i);
208
209    return;
210 }
211