52 #define MAXFILENAME 1024 
   60 #define GREEN   0x00CC00   
   62 #define BLACK   0x000000   
   63 #define WHITE   0xFFFFFF   
   70 main (
int argc, 
char *argv[]) {
 
   75    int      group, consonant1, vowel, consonant2;
 
   78    unsigned tmp_glyph [16];  
 
   94    unsigned grid[12][16][16];
 
  110    int cho_overlaps  = 0;  
 
  117    void     parse_args (
int argc, 
char *argv[], 
int *inindex, 
int *outindex,
 
  124                         unsigned *combined_glyph);
 
  125    void print_glyph_txt (FILE *fp, 
unsigned codept, 
unsigned *this_glyph);
 
  132       parse_args (argc, argv, &inindex, &outindex, &modern_only);
 
  139       infp = fopen (argv[inindex], 
"r");
 
  141          fprintf (stderr, 
"\n*** ERROR: Cannot open %s for input.\n\n",
 
  150       outfp = fopen (argv[outindex], 
"w");
 
  152          fprintf (stderr, 
"\n*** ERROR: Cannot open %s for output.\n\n",
 
  161    for (codept = 0; codept < 
MAX_GLYPHS; codept++) {
 
  162       for (i = 0; i < 16; i++) glyph[codept][i] = 0x0000;
 
  180    if (max_codept > 0x8FF) {
 
  181       fprintf (stderr, 
"\nWARNING: Hangul glyph range exceeds PUA space.\n\n");
 
  191       for (i = 0x0073; i < 
JUNG_HEX; i++) {
 
  192          for (j = 0; j < 16; j++) glyph[i][j] = 0x0000;
 
  194       for (i = 0x027A; i < 
JONG_HEX; i++) {
 
  195          for (j = 0; j < 16; j++) glyph[i][j] = 0x0000;
 
  197       for (i = 0x032B; i < 0x0400; i++) {
 
  198          for (j = 0; j < 16; j++) glyph[i][j] = 0x0000;
 
  206    for (group = 0; group < 12; group++) {
 
  207       for (i = 0; i < 16; i++) {
 
  208          for (j = 0; j < 16; j++) {
 
  209             grid[group][i][j] = 
BLACK;  
 
  218    for (group = 0; group < 6; group++) {
 
  219       for (consonant1 = 
CHO_HEX + group;
 
  223          for (i = 0; i < 16; i++) { 
 
  225             for (j = 0; j < 16; j++) {
 
  226                if (glyph[consonant1][i] & mask) grid[group][i][j] |= 
BLUE;
 
  238    for (group = 3; group < 6; group++) {
 
  239       for (i = 0; i < 16; i++) {
 
  240          for (j = 0; j < 16; j++) {
 
  241             grid[group + 6][i][j] = grid[group + 3][i][j]
 
  251    for (vowel = 
START_JUNG; vowel < TOTAL_JUNG; vowel++) {
 
  255       for (i = 0; i < 16; i++) { 
 
  257          for (j = 0; j < 16; j++) {
 
  264                if (grid[group][i][j] & 
BLUE) glyphs_overlap = 1;
 
  267                grid[group][i][j] |= 
GREEN;
 
  272       if (glyphs_overlap) {
 
  282    for (vowel = 
START_JUNG; vowel < TOTAL_JUNG; vowel++) {
 
  295       if (group < 3) group += 3;
 
  298       for (i = 0; i < 16; i++) { 
 
  300          for (j = 0; j < 16; j++) {  
 
  305                if (grid [group + 3][i][j] & 
BLUE) glyphs_overlap = 1;
 
  308                grid [group + 3][i][j] |= 
GREEN;
 
  313       if (glyphs_overlap) {
 
  324    for (vowel = 
START_JUNG; vowel < TOTAL_JUNG; vowel++) {
 
  326       if (group < 3) group += 3;
 
  329       for (i = 0; i < 16; i++) { 
 
  331          for (j = 0; j < 16; j++) {
 
  335                if (grid[group + 6][i][j] & 
BLUE) glyphs_overlap = 1;
 
  337                grid[group + 6][i][j] |= 
GREEN;
 
  342       if (glyphs_overlap) {
 
  352    for (consonant2 = 0; consonant2 < TOTAL_JONG; consonant2++) {
 
  357       if (consonant2 == 3) consonant2++;
 
  360       for (i = 0; i < 16; i++) { 
 
  362          for (j = 0; j < 16; j++) {
 
  365                if (grid[6][i][j] & 
GREEN ||
 
  366                    grid[7][i][j] & 
GREEN ||
 
  367                    grid[8][i][j] & 
GREEN) glyphs_overlap = 1;
 
  369                grid[6][i][j] |= 
RED;
 
  370                grid[7][i][j] |= 
RED;
 
  371                grid[8][i][j] |= 
RED;
 
  389    for (i = 0; i < 16; i++) { 
 
  391       for (j = 0; j < 16; j++) {
 
  392          if (glyph[codept][i] & mask) {
 
  393             grid[ 9][i][j] |= 
RED;
 
  394             grid[10][i][j] |= 
RED;
 
  395             grid[11][i][j] |= 
RED;
 
  406    for (group = 0; group < 12; group++) {
 
  407       for (i = 0; i < 16; i++) {
 
  408          for (j = 0; j < 16; j++) {
 
  409             if (grid[group][i][j] == 
BLACK) grid[group][i][j] = 
WHITE;
 
  418    fprintf (outfp, 
"<html>\n");
 
  419    fprintf (outfp, 
"<head>\n");
 
  420    fprintf (outfp, 
"  <title>Johab 6/3/1 Overlaps</title>\n");
 
  421    fprintf (outfp, 
"</head>\n");
 
  422    fprintf (outfp, 
"<body bgcolor=\"#FFFFCC\">\n");
 
  424    fprintf (outfp, 
"<center>\n");
 
  425    fprintf (outfp, 
"  <h1>Unifont Hangul Jamo Syllable Components</h1>\n");
 
  426    fprintf (outfp, 
"  <h2>Johab 6/3/1 Overlap</h2><br><br>\n");
 
  429    fprintf (outfp, 
"  <table border=\"1\" cellpadding=\"10\">\n");
 
  430    fprintf (outfp, 
"    <tr><th colspan=\"2\" align=\"center\" bgcolor=\"#FFCC80\">");
 
  431    fprintf (outfp, 
"<font size=\"+1\">Key</font></th></tr>\n");
 
  432    fprintf (outfp, 
"    <tr>\n");
 
  433    fprintf (outfp, 
"      <th align=\"center\" bgcolor=\"#FFFF80\">Color</th>\n");
 
  434    fprintf (outfp, 
"      <th align=\"center\" bgcolor=\"#FFFF80\">Letter(s)</th>\n");
 
  435    fprintf (outfp, 
"    </tr>\n");
 
  437    fprintf (outfp, 
"    <tr><td bgcolor=\"#%06X\">", 
BLUE);
 
  438    fprintf (outfp, 
"    </td>");
 
  439    fprintf (outfp, 
"<td>Choseong (Initial Consonant)</td></tr>\n");
 
  441    fprintf (outfp, 
"    <tr><td bgcolor=\"#%06X\">", 
GREEN);
 
  442    fprintf (outfp, 
"    </td>");
 
  443    fprintf (outfp, 
"<td>Jungseong (Medial Vowel/Diphthong)</td></tr>\n");
 
  445    fprintf (outfp, 
"    <tr><td bgcolor=\"#%06X\">", 
RED);
 
  446    fprintf (outfp, 
"    </td>");
 
  447    fprintf (outfp, 
"<td>Jongseong (Final Consonant)</td></tr>\n");
 
  449    fprintf (outfp, 
"    <tr><td bgcolor=\"#%06X\">", 
BLUE | 
GREEN);
 
  450    fprintf (outfp, 
"    </td>");
 
  451    fprintf (outfp, 
"<td>Choseong + Jungseong Overlap</td></tr>\n");
 
  453    fprintf (outfp, 
"    <tr><td bgcolor=\"#%06X\">", 
GREEN | 
RED);
 
  454    fprintf (outfp, 
"    </td>");
 
  455    fprintf (outfp, 
"<td>Jungseong + Jongseong Overlap</td></tr>\n");
 
  457    fprintf (outfp, 
"    <tr><td bgcolor=\"#%06X\">", 
RED | 
BLUE);
 
  458    fprintf (outfp, 
"    </td>");
 
  459    fprintf (outfp, 
"<td>Choseong + Jongseong Overlap</td></tr>\n");
 
  461    fprintf (outfp, 
"    <tr><td bgcolor=\"#%06X\">", 
RED | 
GREEN | 
BLUE);
 
  462    fprintf (outfp, 
"    </td>");
 
  463    fprintf (outfp, 
"<td>Choseong + Jungseong + Jongseong Overlap</td></tr>\n");
 
  465    fprintf (outfp, 
"  </table>\n");
 
  466    fprintf (outfp, 
"  <br><br>\n");
 
  469    for (group = 0; group < 12; group++) {
 
  471       if ((group % 3) == 0) {
 
  472          fprintf (outfp, 
"  <table border=\"0\" cellpadding=\"10\">\n");
 
  473          fprintf (outfp, 
"    <tr>\n");
 
  476       fprintf (outfp, 
"      <td>\n");
 
  477       fprintf (outfp, 
"        <table border=\"3\" cellpadding=\"2\">\n");
 
  478       fprintf (outfp, 
"          <tr><th colspan=\"16\" bgcolor=\"#FFFF80\">");
 
  479       fprintf (outfp, 
"Choseong Group %d, %s %s</th></tr>\n",
 
  480                group < 6 ? group : (group > 8 ? group - 6 : group - 3),
 
  481                group < 6 ? (group < 3 ? 
"No" : 
"Without") : 
"With",
 
  482                group < 9 ? 
"Jongseong" : 
"Nieun");
 
  484       for (i = 0; i < 16; i++) {
 
  485          fprintf (outfp, 
"          <tr>\n");
 
  486          for (j = 0; j < 16; j++) {
 
  487             fprintf (outfp, 
"            <td bgcolor=\"#%06X\">",
 
  489             fprintf (outfp, 
"    </td>\n");
 
  491          fprintf (outfp, 
"          </tr>\n");
 
  494       fprintf (outfp, 
"            </td>\n");
 
  495       fprintf (outfp, 
"          </tr>\n");
 
  496       fprintf (outfp, 
"        </table>\n");
 
  497       fprintf (outfp, 
"      </td>\n");
 
  499       if ((group % 3) == 2) {
 
  500          fprintf (outfp, 
"    </tr>\n");
 
  501          fprintf (outfp, 
"  </table>\n  </br>\n");
 
  506    fprintf (outfp, 
"</center>\n");
 
  511    fprintf (outfp, 
"<h2>%d Vowel Overlaps with Initial Consonants Found</h2>",
 
  513    fprintf (outfp, 
"<font size=\"+1\"><pre>\n");
 
  524          ancient_choseong = 0;  
 
  525          fprintf (outfp, 
"<font color=\"#0000FF\"><b>");
 
  528             fprintf (outfp, 
"Ancient ");
 
  530          fprintf (outfp, 
"Vowel at 0x%04X and…</b>", i + PUA_START);
 
  531          fprintf (outfp, 
"</font>\n\n");
 
  549          if (vowel_variation > 0 && group < 3) group += 3;
 
  551          for (consonant1 = 0; consonant1 < TOTAL_CHO; consonant1++) {
 
  559             if (overlapped && consonant1 >= 19 && ancient_choseong == 0) {
 
  560                fprintf (outfp, 
"<font color=\"#0000FF\"><b>");
 
  561                fprintf (outfp, 
"…Ancient Choseong…</b></font>\n");
 
  562                ancient_choseong = 1;
 
  567             if (overlapped != 0) {
 
  587    fprintf (outfp, 
"</pre></font>\n");
 
  588    fprintf (outfp, 
"</body>\n");
 
  589    fprintf (outfp, 
"</html>\n");
 
  608 parse_args (
int argc, 
char *argv[], 
int *inindex, 
int *outindex,
 
  612    int strncmp (
const char *s1, 
const char *s2, 
size_t n);
 
  617    while (arg_count < argc) {
 
  619       if (strncmp (argv [arg_count], 
"-i", 2) == 0) {
 
  621          if (arg_count < argc) {
 
  622             *inindex = arg_count;
 
  626       else if (strncmp (argv [arg_count], 
"-m", 2) == 0 ||
 
  627                strncmp (argv [arg_count], 
"--modern", 8) == 0) {
 
  631       else if (strncmp (argv [arg_count], 
"-o", 2) == 0) {
 
  633          if (arg_count < argc) {
 
  634             *outindex = arg_count;
 
  638       else if (strncmp (argv [arg_count], 
"-h",     2) == 0 ||
 
  639                strncmp (argv [arg_count], 
"--help", 6) == 0) {
 
  640          printf (
"\nunijohab2html [options]\n\n");
 
  641          printf (
"     Generates an HTML page of overlapping Hangul letters from an input\n");
 
  642          printf (
"     Unifont .hex file encoded in Johab 6/3/1 format.\n\n");
 
  644          printf (
"     Option        Parameters   Function\n");
 
  645          printf (
"     ------        ----------   --------\n");
 
  646          printf (
"     -h, --help                 Print this message and exit.\n\n");
 
  647          printf (
"     -i            input_file   Unifont hangul-base.hex formatted input file.\n\n");
 
  648          printf (
"     -o            output_file  HTML output file showing overlapping letters.\n\n");
 
  649          printf (
"     -m, --modern               Only examine modern Hangul letters.\n\n");
 
  650          printf (
"     Example:\n\n");
 
  651          printf (
"          unijohab2html -i hangul-base.hex -o hangul-syllables.html\n\n");
 
Define constants and function prototypes for using Hangul glyphs.
#define CHO_VARIATIONS
6 choseong variations
#define JONG_VARIATIONS
1 jongseong variation
void print_glyph_txt(FILE *fp, unsigned codept, unsigned *this_glyph)
Print one glyph in Unifont hexdraw plain text style.
#define JUNG_HEX
Location of first jungseong (will be 0x2FB)
int glyph_overlap(unsigned *glyph1, unsigned *glyph2)
See if two glyphs overlap.
#define JUNG_ANCIENT_HEX
Location of first ancient jungseong.
#define JUNG_VARIATIONS
3 jungseong variations
void combine_glyphs(unsigned *glyph1, unsigned *glyph2, unsigned *combined_glyph)
Combine two glyphs into one glyph.
#define CHO_HEX
Location of first choseong (location 0x0000 is a blank glyph)
int cho_variation(int choseong, int jungseong, int jongseong)
Return the Johab 6/3/1 choseong variation for a syllable.
#define JUNG_EXTB_HEX
U+D7B0 Extended-B jungseong.
#define JONG_HEX
Location of first jongseong (will be 0x421)
unsigned hangul_read_base16(FILE *infp, unsigned base[][16])
Read hangul-base.hex file into a unsigned array.
#define MAX_GLYPHS
An OpenType font has at most 65536 glyphs.
int main(int argc, char *argv[])
The main function.
#define START_JUNG
Vowel index of first vowel with which to begin.
#define BLUE
Color code for slightly unsaturated HTML blue.
#define BLACK
Color code for HTML black.
#define WHITE
Color code for HTML white.
#define RED
Color code for slightly unsaturated HTML red.
#define GREEN
Color code for slightly unsaturated HTML green.
void parse_args(int argc, char *argv[], int *inindex, int *outindex, int *modern_only)
Parse command line arguments.