GNU Unifont  15.0.05
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 
56 
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <string.h>
60 #include <ctype.h>
61 
62 #define MAXSTRING 256 ///< Maximum input line length - 1.
63 
64 
65 /**
66  @brief The main function.
67 
68  @param[in] argc The count of command line arguments.
69  @param[in] argv Pointer to array of command line arguments.
70  @return This program exits with status EXIT_SUCCESS.
71 */
72 int
73 main (int argc, char **argv)
74 {
75 
76  char teststring[MAXSTRING]; /* current input line */
77  int loc; /* Unicode code point of current input line */
78  int offset; /* offset value of a combining character */
79  char *gstart; /* glyph start, pointing into teststring */
80 
81  char combining[0x110000]; /* 1 --> combining glyph; 0 --> non-combining */
82  char x_offset [0x110000]; /* second value in *combining.txt files */
83 
84  void add_single_circle(char *); /* add a single-width dashed circle */
85  void add_double_circle(char *, int); /* add a double-width dashed circle */
86 
87  FILE *infilefp;
88 
89  /*
90  if (argc != 3) {
91  fprintf (stderr,
92  "\n\nUsage: %s combining.txt nonprinting.hex < unifont.hex > unifontfull.hex\n\n");
93  exit (EXIT_FAILURE);
94  }
95  */
96 
97  /*
98  Read the combining characters list.
99  */
100  /* Start with no combining code points flagged */
101  memset (combining, 0, 0x110000 * sizeof (char));
102  memset (x_offset , 0, 0x110000 * sizeof (char));
103 
104  if ((infilefp = fopen (argv[1],"r")) == NULL) {
105  fprintf (stderr,"ERROR - combining characters file %s not found.\n\n",
106  argv[1]);
107  exit (EXIT_FAILURE);
108  }
109 
110  /* Flag list of combining characters to add a dashed circle. */
111  while (fscanf (infilefp, "%X:%d", &loc, &offset) != EOF) {
112  /*
113  U+01107F and U+01D1A0 are not defined as combining characters
114  in Unicode; they were added in a combining.txt file as the
115  only way to make them look acceptable in proximity to other
116  glyphs in their script.
117  */
118  if (loc != 0x01107F && loc != 0x01D1A0) {
119  combining[loc] = 1;
120  x_offset [loc] = offset;
121  }
122  }
123  fclose (infilefp); /* all done reading combining.txt */
124 
125  /* Now read the non-printing glyphs; they never have dashed circles */
126  if ((infilefp = fopen (argv[2],"r")) == NULL) {
127  fprintf (stderr,"ERROR - nonprinting characters file %s not found.\n\n",
128  argv[1]);
129  exit (EXIT_FAILURE);
130  }
131 
132  /* Reset list of nonprinting characters to avoid adding a dashed circle. */
133  while (fscanf (infilefp, "%X:%*s", &loc) != EOF) combining[loc] = 0;
134 
135  fclose (infilefp); /* all done reading nonprinting.hex */
136 
137  /*
138  Read the hex glyphs.
139  */
140  teststring[MAXSTRING - 1] = '\0'; /* so there's no chance we leave array */
141  while (fgets (teststring, MAXSTRING-1, stdin) != NULL) {
142  sscanf (teststring, "%X", &loc); /* loc == the Uniocde code point */
143  gstart = strchr (teststring,':') + 1; /* start of glyph bitmap */
144  if (combining[loc]) { /* if a combining character */
145  if (strlen (gstart) < 35)
146  add_single_circle (gstart); /* single-width */
147  else
148  add_double_circle (gstart, x_offset[loc]); /* double-width */
149  }
150  printf ("%s", teststring); /* output the new character .hex string */
151  }
152 
153  exit (EXIT_SUCCESS);
154 }
155 
156 
157 /**
158  @brief Superimpose a single-width dashed combining circle on a glyph bitmap.
159 
160  @param[in,out] glyphstring A single-width glyph, 8x16 pixels.
161 */
162 void
163 add_single_circle (char *glyphstring)
164 {
165 
166  char newstring[256];
167  /* Circle hex string pattern is "00000008000024004200240000000000" */
168  char circle[32]={0x0,0x0, /* row 1 */
169  0x0,0x0, /* row 2 */
170  0x0,0x0, /* row 3 */
171  0x0,0x0, /* row 4 */
172  0x0,0x0, /* row 5 */
173  0x0,0x0, /* row 6 */
174  0x2,0x4, /* row 7 */
175  0x0,0x0, /* row 8 */
176  0x4,0x2, /* row 9 */
177  0x0,0x0, /* row 10 */
178  0x2,0x4, /* row 11 */
179  0x0,0x0, /* row 12 */
180  0x0,0x0, /* row 13 */
181  0x0,0x0, /* row 14 */
182  0x0,0x0, /* row 15 */
183  0x0,0x0}; /* row 16 */
184 
185  int digit1, digit2; /* corresponding digits in each string */
186 
187  int i; /* index variables */
188 
189  /* for each character position, OR the corresponding circle glyph value */
190  for (i = 0; i < 32; i++) {
191  glyphstring[i] = toupper (glyphstring[i]);
192 
193  /* Convert ASCII character to a hexadecimal integer */
194  digit1 = (glyphstring[i] <= '9') ?
195  (glyphstring[i] - '0') : (glyphstring[i] - 'A' + 0xA);
196 
197  /* Superimpose dashed circle */
198  digit2 = digit1 | circle[i];
199 
200  /* Convert hexadecimal integer to an ASCII character */
201  newstring[i] = (digit2 <= 9) ?
202  ('0' + digit2) : ('A' + digit2 - 0xA);
203  }
204 
205  /* Terminate string for output */
206  newstring[i++] = '\n';
207  newstring[i++] = '\0';
208 
209  memcpy (glyphstring, newstring, i);
210 
211  return;
212 }
213 
214 
215 /**
216  @brief Superimpose a double-width dashed combining circle on a glyph bitmap.
217 
218  @param[in,out] glyphstring A double-width glyph, 16x16 pixels.
219 */
220 void
221 add_double_circle (char *glyphstring, int offset)
222 {
223 
224  char newstring[256];
225  /* Circle hex string pattern is "00000008000024004200240000000000" */
226 
227  /* For double diacritical glyphs (offset = -8) */
228  /* Combining circle is left-justified. */
229  char circle08[64]={0x0,0x0,0x0,0x0, /* row 1 */
230  0x0,0x0,0x0,0x0, /* row 2 */
231  0x0,0x0,0x0,0x0, /* row 3 */
232  0x0,0x0,0x0,0x0, /* row 4 */
233  0x0,0x0,0x0,0x0, /* row 5 */
234  0x0,0x0,0x0,0x0, /* row 6 */
235  0x2,0x4,0x0,0x0, /* row 7 */
236  0x0,0x0,0x0,0x0, /* row 8 */
237  0x4,0x2,0x0,0x0, /* row 9 */
238  0x0,0x0,0x0,0x0, /* row 10 */
239  0x2,0x4,0x0,0x0, /* row 11 */
240  0x0,0x0,0x0,0x0, /* row 12 */
241  0x0,0x0,0x0,0x0, /* row 13 */
242  0x0,0x0,0x0,0x0, /* row 14 */
243  0x0,0x0,0x0,0x0, /* row 15 */
244  0x0,0x0,0x0,0x0}; /* row 16 */
245 
246  /* For all other combining glyphs (offset = -16) */
247  /* Combining circle is centered in 16 columns. */
248  char circle16[64]={0x0,0x0,0x0,0x0, /* row 1 */
249  0x0,0x0,0x0,0x0, /* row 2 */
250  0x0,0x0,0x0,0x0, /* row 3 */
251  0x0,0x0,0x0,0x0, /* row 4 */
252  0x0,0x0,0x0,0x0, /* row 5 */
253  0x0,0x0,0x0,0x0, /* row 6 */
254  0x0,0x2,0x4,0x0, /* row 7 */
255  0x0,0x0,0x0,0x0, /* row 8 */
256  0x0,0x4,0x2,0x0, /* row 9 */
257  0x0,0x0,0x0,0x0, /* row 10 */
258  0x0,0x2,0x4,0x0, /* row 11 */
259  0x0,0x0,0x0,0x0, /* row 12 */
260  0x0,0x0,0x0,0x0, /* row 13 */
261  0x0,0x0,0x0,0x0, /* row 14 */
262  0x0,0x0,0x0,0x0, /* row 15 */
263  0x0,0x0,0x0,0x0}; /* row 16 */
264 
265  char *circle; /* points into circle16 or circle08 */
266 
267  int digit1, digit2; /* corresponding digits in each string */
268 
269  int i; /* index variables */
270 
271 
272  /*
273  Determine if combining circle is left-justified (offset = -8)
274  or centered (offset = -16).
275  */
276  circle = (offset >= -8) ? circle08 : circle16;
277 
278  /* for each character position, OR the corresponding circle glyph value */
279  for (i = 0; i < 64; i++) {
280  glyphstring[i] = toupper (glyphstring[i]);
281 
282  /* Convert ASCII character to a hexadecimal integer */
283  digit1 = (glyphstring[i] <= '9') ?
284  (glyphstring[i] - '0') : (glyphstring[i] - 'A' + 0xA);
285 
286  /* Superimpose dashed circle */
287  digit2 = digit1 | circle[i];
288 
289  /* Convert hexadecimal integer to an ASCII character */
290  newstring[i] = (digit2 <= 9) ?
291  ('0' + digit2) : ('A' + digit2 - 0xA);
292  }
293 
294  /* Terminate string for output */
295  newstring[i++] = '\n';
296  newstring[i++] = '\0';
297 
298  memcpy (glyphstring, newstring, i);
299 
300  return;
301 }
302 
add_single_circle
void add_single_circle(char *glyphstring)
Superimpose a single-width dashed combining circle on a glyph bitmap.
Definition: unigencircles.c:163
main
int main(int argc, char **argv)
The main function.
Definition: unigencircles.c:73
add_double_circle
void add_double_circle(char *glyphstring, int offset)
Superimpose a double-width dashed combining circle on a glyph bitmap.
Definition: unigencircles.c:221
MAXSTRING
#define MAXSTRING
Maximum input line length - 1.
Definition: unigencircles.c:62