The main function. 
   70                              {
   71   int i, j;  
   72   unsigned codept;
   73   unsigned max_codept;
   74   int      modern_only = 0;  
   75   int      group, consonant1, vowel, consonant2;
   76   int      vowel_variation;
   78   unsigned tmp_glyph [16];  
   79   unsigned mask;
   80   unsigned overlapped;       
   81   int      ancient_choseong; 
   82 
   83   
   84
   85 
   86
   87
   88
   89 
   90
   91 
   92
   93
   94   unsigned grid[12][16][16];
   95 
   96   
   97
   98
   99
  100
  101
  102
  103
  104   
  106   
  107   
  108 
  109   int glyphs_overlap;     
  110   int cho_overlaps  = 0;  
  111   
  112 
  113   int  inindex = 0;
  114   int  outindex = 0;
  115   FILE *infp, *outfp;     
  116 
  117   void     parse_args (
int argc, 
char *argv[], 
int *inindex, 
int *outindex,
 
  118                        int *modern_only);
  122 
  124                        unsigned *combined_glyph);
  125   void print_glyph_txt (FILE *fp, 
unsigned codept, 
unsigned *this_glyph);
 
  126 
  127 
  128   
  129
  130
  131   if (argc > 1) {
  132      parse_args (argc, argv, &inindex, &outindex, &modern_only);
 
  133   }
  134 
  135   if (inindex == 0) {
  136      infp = stdin;
  137   }
  138   else {
  139      infp = fopen (argv[inindex], "r");
  140      if (infp == NULL) {
  141         fprintf (stderr, "\n*** ERROR: Cannot open %s for input.\n\n",
  142                  argv[inindex]);
  143         exit (EXIT_FAILURE);
  144      }
  145   }
  146   if (outindex == 0) {
  147      outfp = stdout;
  148   }
  149   else {
  150      outfp = fopen (argv[outindex], "w");
  151      if (outfp == NULL) {
  152         fprintf (stderr, "\n*** ERROR: Cannot open %s for output.\n\n",
  153                  argv[outindex]);
  154         exit (EXIT_FAILURE);
  155      }
  156   }
  157 
  158   
  159
  160
  161   for (codept = 0; codept < 
MAX_GLYPHS; codept++) {
 
  162      for (i = 0; i < 16; i++) glyph[codept][i] = 0x0000;
  163   }
  164 
  165   
  166
  167
  169      jungcho  [i] = 0;
  170   }
  171   
  172   
  173   
  174   
  175 
  176   
  177
  178
  180   if (max_codept > 0x8FF) {
  181      fprintf (stderr, "\nWARNING: Hangul glyph range exceeds PUA space.\n\n");
  182   }
  183 
  184   
  185
  186
  187
  188
  189
  190   if (modern_only) {
  191      for (i = 0x0073; i < 
JUNG_HEX; i++) {
 
  192         for (j = 0; j < 16; j++) glyph[i][j] = 0x0000;
  193      }
  194      for (i = 0x027A; i < 
JONG_HEX; i++) {
 
  195         for (j = 0; j < 16; j++) glyph[i][j] = 0x0000;
  196      }
  197      for (i = 0x032B; i < 0x0400; i++) {
  198         for (j = 0; j < 16; j++) glyph[i][j] = 0x0000;
  199      }
  200   }
  201 
  202   
  203
  204
  205
  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;  
 
  210         }
  211      }
  212   }
  213 
  214   
  215
  216
  217
  218   for (group = 0; group < 6; group++) {
  219      for (consonant1 = 
CHO_HEX + group;
 
  223         for (i = 0; i < 16; i++) { 
  224            mask = 0x8000;
  225            for (j = 0; j < 16; j++) {
  226               if (glyph[consonant1][i] & mask) grid[group][i][j] |= 
BLUE;
 
  227               mask >>= 1;  
  228            }
  229         }
  230      }
  231   }
  232 
  233   
  234
  235
  236
  237
  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]
  242                                   = grid[group][i][j];
  243         }
  244      }
  245   }
  246 
  247   
  248
  249
  250
  251   for (vowel = 
START_JUNG; vowel < TOTAL_JUNG; vowel++) {
 
  253      glyphs_overlap = 0;  
  254 
  255      for (i = 0; i < 16; i++) { 
  256         mask = 0x8000;
  257         for (j = 0; j < 16; j++) {
  259               
  260
  261
  262
  263
  264               if (grid[group][i][j] & 
BLUE) glyphs_overlap = 1;
 
  265 
  266               
  267               grid[group][i][j] |= 
GREEN;
 
  268            }
  269            mask >>= 1;  
  270         }  
  271      }  
  272      if (glyphs_overlap) {
  274         cho_overlaps++;
  275      }
  276   }  
  277 
  278   
  279
  280
  281
  282   for (vowel = 
START_JUNG; vowel < TOTAL_JUNG; vowel++) {
 
  283      
  284
  285
  286
  287
  288
  289
  291      
  292
  293
  294
  295      if (group < 3) group += 3;
  296      glyphs_overlap = 0;  
  297 
  298      for (i = 0; i < 16; i++) { 
  299         mask = 0x8000;  
  300         for (j = 0; j < 16; j++) {  
  301            
  304               
  305               if (grid [group + 3][i][j] & 
BLUE) glyphs_overlap = 1;
 
  306 
  307               
  308               grid [group + 3][i][j] |= 
GREEN;
 
  309            }
  310            mask >>= 1;  
  311         }  
  312      }  
  313      if (glyphs_overlap) {
  315         cho_overlaps++;
  316      }
  317   }  
  318 
  319   
  320
  321
  322
  323
  324   for (vowel = 
START_JUNG; vowel < TOTAL_JUNG; vowel++) {
 
  326      if (group < 3) group += 3;
  327      glyphs_overlap = 0;  
  328 
  329      for (i = 0; i < 16; i++) { 
  330         mask = 0x8000;
  331         for (j = 0; j < 16; j++) {
  334               
  335               if (grid[group + 6][i][j] & 
BLUE) glyphs_overlap = 1;
 
  336 
  337               grid[group + 6][i][j] |= 
GREEN;
 
  338            }
  339            mask >>= 1;  
  340         }  
  341      }  
  342      if (glyphs_overlap) {
  344         cho_overlaps++;
  345      }
  346   }  
  347 
  348 
  349   
  350
  351
  352   for (consonant2 = 0; consonant2 < TOTAL_JONG; consonant2++) {
  353      
  354
  355
  356
  357      if (consonant2 == 3) consonant2++;
  358 
  359      glyphs_overlap = 0;  
  360      for (i = 0; i < 16; i++) { 
  361         mask = 0x8000;
  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;
 
  368 
  369               grid[6][i][j] |= 
RED;
 
  370               grid[7][i][j] |= 
RED;
 
  371               grid[8][i][j] |= 
RED;
 
  372            }
  373            mask >>= 1;  
  374         }  
  375      }  
  376      
  377      
  378      
  379      
  380      
  381   }  
  382 
  383   
  384
  385
  386
  388 
  389   for (i = 0; i < 16; i++) { 
  390      mask = 0x8000;
  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;
 
  396         }
  397         mask >>= 1;  
  398      }
  399   }
  400 
  401 
  402   
  403
  404
  405
  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;
 
  410         }
  411      }
  412   }
  413 
  414 
  415   
  416
  417
  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");
  423 
  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");
  427 
  428   
  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");
  436 
  437   fprintf (outfp, 
"    <tr><td bgcolor=\"#%06X\">", 
BLUE);
 
  438   fprintf (outfp, "    </td>");
  439   fprintf (outfp, "<td>Choseong (Initial Consonant)</td></tr>\n");
  440 
  441   fprintf (outfp, 
"    <tr><td bgcolor=\"#%06X\">", 
GREEN);
 
  442   fprintf (outfp, "    </td>");
  443   fprintf (outfp, "<td>Jungseong (Medial Vowel/Diphthong)</td></tr>\n");
  444 
  445   fprintf (outfp, 
"    <tr><td bgcolor=\"#%06X\">", 
RED);
 
  446   fprintf (outfp, "    </td>");
  447   fprintf (outfp, "<td>Jongseong (Final Consonant)</td></tr>\n");
  448 
  449   fprintf (outfp, 
"    <tr><td bgcolor=\"#%06X\">", 
BLUE | 
GREEN);
 
  450   fprintf (outfp, "    </td>");
  451   fprintf (outfp, "<td>Choseong + Jungseong Overlap</td></tr>\n");
  452 
  453   fprintf (outfp, 
"    <tr><td bgcolor=\"#%06X\">", 
GREEN | 
RED);
 
  454   fprintf (outfp, "    </td>");
  455   fprintf (outfp, "<td>Jungseong + Jongseong Overlap</td></tr>\n");
  456 
  457   fprintf (outfp, 
"    <tr><td bgcolor=\"#%06X\">", 
RED | 
BLUE);
 
  458   fprintf (outfp, "    </td>");
  459   fprintf (outfp, "<td>Choseong + Jongseong Overlap</td></tr>\n");
  460 
  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");
  464 
  465   fprintf (outfp, "  </table>\n");
  466   fprintf (outfp, "  <br><br>\n");
  467 
  468 
  469   for (group = 0; group < 12; group++) {
  470      
  471      if ((group % 3) == 0) {
  472         fprintf (outfp, "  <table border=\"0\" cellpadding=\"10\">\n");
  473         fprintf (outfp, "    <tr>\n");
  474      }
  475 
  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");
  483   
  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\">",
  488                     grid[group][i][j]);
  489            fprintf (outfp, "    </td>\n");
  490         }
  491         fprintf (outfp, "          </tr>\n");
  492      }
  493   
  494      fprintf (outfp, "            </td>\n");
  495      fprintf (outfp, "          </tr>\n");
  496      fprintf (outfp, "        </table>\n");
  497      fprintf (outfp, "      </td>\n");
  498 
  499      if ((group % 3) == 2) {
  500         fprintf (outfp, "    </tr>\n");
  501         fprintf (outfp, "  </table>\n  </br>\n");
  502      }
  503   }
  504 
  505   
  506   fprintf (outfp, "</center>\n");
  507 
  508   
  509
  510
  511   fprintf (outfp, "<h2>%d Vowel Overlaps with Initial Consonants Found</h2>",
  512            cho_overlaps);
  513   fprintf (outfp, "<font size=\"+1\"><pre>\n");
  514 
  517        i++) {
  518      
  519
  520
  521
  522
  524         ancient_choseong = 0;  
  525         fprintf (outfp, "<font color=\"#0000FF\"><b>");
  528            fprintf (outfp, "Ancient ");
  529         }
  530         fprintf (outfp, "Vowel at 0x%04X and…</b>", i + PUA_START);
  531         fprintf (outfp, "</font>\n\n");
  532 
  533         
  534
  535
  536
  539 
  540         
  542 
  543         
  544
  545
  546
  547
  548
  549         if (vowel_variation > 0 && group < 3) group += 3;
  550 
  551         for (consonant1 = 0; consonant1 < TOTAL_CHO; consonant1++) {
  555 
  556            
  557
  558
  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;
  563            }
  564            
  565
  566
  567            if (overlapped != 0) {
  568 
  572                               tmp_glyph);
  573 
  575                                PUA_START +
  578                                tmp_glyph);
  579 
  580            }  
  581         }  
  582      }  
  583   }  
  584 
  585   fputc ('\n', outfp);
  586 
  587   fprintf (outfp, "</pre></font>\n");
  588   fprintf (outfp, "</body>\n");
  589   fprintf (outfp, "</html>\n");
  590 
  591   fclose (infp);
  592   fclose (outfp);
  593 
  594 
  595   exit (EXIT_SUCCESS);
  596}
#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.
#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.