unigencircles.c
Go to the documentation of this file.
/**
@file unigencircles.c
@brief unigencircles - Superimpose dashed combining circles
on combining glyphs
@author Paul Hardy
@copyright Copyright (C) 2013, Paul Hardy.
*/
/*
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 <http://www.gnu.org/licenses/>.
*/
/*
8 July 2017 [Paul Hardy]:
- Reads new second field that contains an x-axis offset for
each combining character in "*combining.txt" files.
- Uses the above x-axis offset value for a combining character
to print combining circle in the left half of a double
diacritic combining character grid, or in the center for
other combining characters.
- Adds exceptions for U+01107F (Brahmi number joiner) and
U+01D1A0 (vertical stroke musical ornament); they are in
a combining.txt file for positioning, but are not actually
Unicode combining characters.
- Typo fix: "single-width"-->"double-width" in comment for
add_double_circle function.
12 August 2017 [Paul Hardy]:
- Hard-code Miao vowels to show combining circles after
removing them from font/plane01/plane01-combining.txt.
26 December 2017 [Paul Hardy]:
- Remove Miao hard-coding; they are back in unibmp2hex.c and
in font/plane01/plane01-combining.txt.
11 May 2019 [Paul Hardy]:
- Changed strncpy calls to memcpy calls to avoid a compiler
warning.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAXSTRING 256 ///< Maximum input line length - 1.
/**
@brief The main function.
@param[in] argc The count of command line arguments.
@param[in] argv Pointer to array of command line arguments.
@return This program exits with status EXIT_SUCCESS.
*/
int
main (int argc, char **argv)
{
char teststring[MAXSTRING]; /* current input line */
int loc; /* Unicode code point of current input line */
int offset; /* offset value of a combining character */
char *gstart; /* glyph start, pointing into teststring */
char combining[0x110000]; /* 1 --> combining glyph; 0 --> non-combining */
char x_offset [0x110000]; /* second value in *combining.txt files */
void add_single_circle(char *); /* add a single-width dashed circle */
void add_double_circle(char *, int); /* 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));
memset (x_offset , 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:%d", &loc, &offset) != EOF) {
/*
U+01107F and U+01D1A0 are not defined as combining characters
in Unicode; they were added in a combining.txt file as the
only way to make them look acceptable in proximity to other
glyphs in their script.
*/
if (loc != 0x01107F && loc != 0x01D1A0) {
combining[loc] = 1;
x_offset [loc] = offset;
}
}
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 = strchr (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, x_offset[loc]); /* double-width */
}
printf ("%s", teststring); /* output the new character .hex string */
}
exit (EXIT_SUCCESS);
}
/**
@brief Superimpose a single-width dashed combining circle on a glyph bitmap.
@param[in,out] glyphstring A single-width glyph, 8x16 pixels.
*/
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';
memcpy (glyphstring, newstring, i);
return;
}
/**
@brief Superimpose a double-width dashed combining circle on a glyph bitmap.
@param[in,out] glyphstring A double-width glyph, 16x16 pixels.
*/
void
add_double_circle (char *glyphstring, int offset)
{
char newstring[256];
/* Circle hex string pattern is "00000008000024004200240000000000" */
/* For double diacritical glyphs (offset = -8) */
/* Combining circle is left-justified. */
char circle08[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 */
0x2,0x4,0x0,0x0, /* row 7 */
0x0,0x0,0x0,0x0, /* row 8 */
0x4,0x2,0x0,0x0, /* row 9 */
0x0,0x0,0x0,0x0, /* row 10 */
0x2,0x4,0x0,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 */
/* For all other combining glyphs (offset = -16) */
/* Combining circle is centered in 16 columns. */
char circle16[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 */
char *circle; /* points into circle16 or circle08 */
int digit1, digit2; /* corresponding digits in each string */
int i; /* index variables */
/*
Determine if combining circle is left-justified (offset = -8)
or centered (offset = -16).
*/
circle = (offset >= -8) ? circle08 : circle16;
/* 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';
memcpy (glyphstring, newstring, i);
return;
}
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
main
int main(int argc, char **argv)
The main function.
Definition: unigencircles.c:73
add_single_circle
void add_single_circle(char *glyphstring)
Superimpose a single-width dashed combining circle on a glyph bitmap.
Definition: unigencircles.c:163