/*
unigencircles.c -- program to superimpose dashed combining circles
on combining glyphs.
Author: Paul Hardy, 2013.
LICENSE:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include
#include
#include
#include
#define MAXSTRING 256
int
main (int argc, char **argv)
{
char teststring[MAXSTRING]; /* current input line */
int loc; /* Unicode code point of current input line */
char *gstart; /* glyph start, pointing into teststring */
char combining[0x110000];
void add_single_circle(char *); /* add a single-width dashed circle */
void add_double_circle(char *); /* add a double-width dashed circle */
FILE *infilefp;
/*
if (argc != 3) {
fprintf (stderr,
"\n\nUsage: %s combining.txt nonprinting.hex < unifont.hex > unifontfull.hex\n\n");
exit (EXIT_FAILURE);
}
*/
/*
Read the combining characters list.
*/
/* Start with no combining code points flagged */
memset (combining, 0, 0x110000 * sizeof (char));
if ((infilefp = fopen (argv[1],"r")) == NULL) {
fprintf (stderr,"ERROR - combining characters file %s not found.\n\n",
argv[1]);
exit (EXIT_FAILURE);
}
/* Flag list of combining characters to add a dashed circle. */
while (fscanf (infilefp, "%X", &loc) != EOF) combining[loc] = 1;
fclose (infilefp); /* all done reading combining.txt */
/* Now read the non-printing glyphs; they never have dashed circles */
if ((infilefp = fopen (argv[2],"r")) == NULL) {
fprintf (stderr,"ERROR - nonprinting characters file %s not found.\n\n",
argv[1]);
exit (EXIT_FAILURE);
}
/* Reset list of nonprinting characters to avoid adding a dashed circle. */
while (fscanf (infilefp, "%X:%*s", &loc) != EOF) combining[loc] = 0;
fclose (infilefp); /* all done reading nonprinting.hex */
/*
Read the hex glyphs.
*/
teststring[MAXSTRING - 1] = '\0'; /* so there's no chance we leave array */
while (fgets (teststring, MAXSTRING-1, stdin) != NULL) {
sscanf (teststring, "%X", &loc); /* loc == the Uniocde code point */
gstart = index (teststring,':') + 1; /* start of glyph bitmap */
if (combining[loc]) { /* if a combining character */
if (strlen (gstart) < 35) add_single_circle (gstart); /* single-width */
else add_double_circle (gstart); /* double-width */
}
printf ("%s", teststring); /* output the new character .hex string */
}
exit (EXIT_SUCCESS);
}
/*
add_single_circle - superimpose a single-width dashed combining circle.
*/
void
add_single_circle (char *glyphstring)
{
char newstring[256];
/* Circle hex string pattern is "00000008000024004200240000000000" */
char circle[32]={0x0,0x0, /* row 1 */
0x0,0x0, /* row 2 */
0x0,0x0, /* row 3 */
0x0,0x0, /* row 4 */
0x0,0x0, /* row 5 */
0x0,0x0, /* row 6 */
0x2,0x4, /* row 7 */
0x0,0x0, /* row 8 */
0x4,0x2, /* row 9 */
0x0,0x0, /* row 10 */
0x2,0x4, /* row 11 */
0x0,0x0, /* row 12 */
0x0,0x0, /* row 13 */
0x0,0x0, /* row 14 */
0x0,0x0, /* row 15 */
0x0,0x0}; /* row 16 */
int digit1, digit2; /* corresponding digits in each string */
int i; /* index variables */
/* for each character position, OR the corresponding circle glyph value */
for (i = 0; i < 32; i++) {
glyphstring[i] = toupper (glyphstring[i]);
/* Convert ASCII character to a hexadecimal integer */
digit1 = (glyphstring[i] <= '9') ?
(glyphstring[i] - '0') : (glyphstring[i] - 'A' + 0xA);
/* Superimpose dashed circle */
digit2 = digit1 | circle[i];
/* Convert hexadecimal integer to an ASCII character */
newstring[i] = (digit2 <= 9) ?
('0' + digit2) : ('A' + digit2 - 0xA);
}
/* Terminate string for output */
newstring[i++] = '\n';
newstring[i++] = '\0';
strncpy (glyphstring, newstring, i);
return;
}
/*
add_double_circle - superimpose a single-width dashed combining circle.
*/
void
add_double_circle (char *glyphstring)
{
char newstring[256];
/* Circle hex string pattern is "00000008000024004200240000000000" */
char circle[64]={0x0,0x0,0x0,0x0, /* row 1 */
0x0,0x0,0x0,0x0, /* row 2 */
0x0,0x0,0x0,0x0, /* row 3 */
0x0,0x0,0x0,0x0, /* row 4 */
0x0,0x0,0x0,0x0, /* row 5 */
0x0,0x0,0x0,0x0, /* row 6 */
0x0,0x2,0x4,0x0, /* row 7 */
0x0,0x0,0x0,0x0, /* row 8 */
0x0,0x4,0x2,0x0, /* row 9 */
0x0,0x0,0x0,0x0, /* row 10 */
0x0,0x2,0x4,0x0, /* row 11 */
0x0,0x0,0x0,0x0, /* row 12 */
0x0,0x0,0x0,0x0, /* row 13 */
0x0,0x0,0x0,0x0, /* row 14 */
0x0,0x0,0x0,0x0, /* row 15 */
0x0,0x0,0x0,0x0}; /* row 16 */
int digit1, digit2; /* corresponding digits in each string */
int i; /* index variables */
/* for each character position, OR the corresponding circle glyph value */
for (i = 0; i < 64; i++) {
glyphstring[i] = toupper (glyphstring[i]);
/* Convert ASCII character to a hexadecimal integer */
digit1 = (glyphstring[i] <= '9') ?
(glyphstring[i] - '0') : (glyphstring[i] - 'A' + 0xA);
/* Superimpose dashed circle */
digit2 = digit1 | circle[i];
/* Convert hexadecimal integer to an ASCII character */
newstring[i] = (digit2 <= 9) ?
('0' + digit2) : ('A' + digit2 - 0xA);
}
/* Terminate string for output */
newstring[i++] = '\n';
newstring[i++] = '\0';
strncpy (glyphstring, newstring, i);
return;
}