The main function. 
   64{
   65 
   66   int i; 
   67 
   69   int  loc;
   70   char *gstart;
   71 
   72   char glyph_width[0x20000];
   74 
   75   FILE *infilefp;
   76 
   77   if (argc != 3) {
   78      fprintf (stderr, "\n\nUsage: %s <unifont.hex> <combining.txt>\n\n", argv[0]);
   79      exit (EXIT_FAILURE);
   80   }
   81 
   82   
   83
   84
   85   if ((infilefp = fopen (argv[1],"r")) == NULL) {
   86      fprintf (stderr,"ERROR - hex input file %s not found.\n\n", argv[1]);
   87      exit (EXIT_FAILURE);
   88   }
   89 
   90   
   91   memset (glyph_width, -1, 0x20000 * sizeof (char));
   92   memset (pikto_width, -1, (
PIKTO_SIZE) * 
sizeof (
char));
 
   93 
   95   while (fgets (teststring, 
MAXSTRING-1, infilefp) != NULL) {
 
   96      sscanf (teststring, "%X:%*s", &loc);
   97      if (loc < 0x20000) {
   98         gstart = strchr (teststring,':') + 1;
   99         
  100
  101
  102
  103         glyph_width[loc] = (strlen (gstart) - 1) >> 5;
  104      }
  106         gstart = strchr (teststring,':') + 1;
  107         pikto_width[loc - 
PIKTO_START] = strlen (gstart) <= 34 ? 1 : 2;
 
  108      }
  109   }
  110 
  111   fclose (infilefp);
  112 
  113   
  114
  115
  116   if ((infilefp = fopen (argv[2],"r")) == NULL) {
  117      fprintf (stderr,"ERROR - combining characters file %s not found.\n\n", argv[2]);
  118      exit (EXIT_FAILURE);
  119   }
  120 
  121   while (fgets (teststring, 
MAXSTRING-1, infilefp) != NULL) {
 
  122      sscanf (teststring, "%X:%*s", &loc);
  123      if (loc < 0x20000) glyph_width[loc] = 0;
  124   }
  125 
  126   fclose (infilefp);
  127 
  128   
  129
  130 
  131
  132
  133
  134
  135
  136
  137
  138
  139 
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166 
  167
  168
  169 
  170
  171
  172
  173
  174   
  175
  176
  177
  178 
  179   
  180
  181 
  182
  183 
  184
  185 
  186
  187
  188
  189
  190
  191
  192   
  193 
  194   
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205   
  206   
  207   
  208 
  209   
  210
  211
  212   for (i = 0xFDD0; i <= 0xFDEF; i++) glyph_width[i] = -1;
  213   glyph_width[0xFFFE] = -1; 
  214   glyph_width[0xFFFF] = -1; 
  215 
  216   
  217   for (i = 0xD800; i <= 0xDFFF; i++) glyph_width[i]=-1;
  218 
  219   
  220   for (i = 0x4E00; i <= 0x9FFF; i++) if (glyph_width[i] < 0) glyph_width[i] = 2;
  221   for (i = 0x3400; i <= 0x4DBF; i++) if (glyph_width[i] < 0) glyph_width[i] = 2;
  222   for (i = 0xF900; i <= 0xFAFF; i++) if (glyph_width[i] < 0) glyph_width[i] = 2;
  223 
  224   
  225
  226
  227   printf ("/*\n");
  228   printf ("   wcwidth and wcswidth functions, as per IEEE 1003.1-2008\n");
  229   printf ("   System Interfaces, pp. 2241 and 2251.\n\n");
  230   printf ("   Author: Paul Hardy, 2013\n\n");
  231   printf ("   Copyright (c) 2013 Paul Hardy\n\n");
  232   printf ("   LICENSE:\n");
  233   printf ("\n");
  234   printf ("      This program is free software: you can redistribute it and/or modify\n");
  235   printf ("      it under the terms of the GNU General Public License as published by\n");
  236   printf ("      the Free Software Foundation, either version 2 of the License, or\n");
  237   printf ("      (at your option) any later version.\n");
  238   printf ("\n");
  239   printf ("      This program is distributed in the hope that it will be useful,\n");
  240   printf ("      but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
  241   printf ("      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n");
  242   printf ("      GNU General Public License for more details.\n");
  243   printf ("\n");
  244   printf ("      You should have received a copy of the GNU General Public License\n");
  245   printf ("      along with this program.  If not, see <http://www.gnu.org/licenses/>.\n");
  246   printf ("*/\n\n");
  247 
  248   printf ("#include <wchar.h>\n\n");
  249   printf ("/* Definitions for Pikto CSUR Private Use Area glyphs */\n");
  250   printf (
"#define PIKTO_START\t0x%06X\n", 
PIKTO_START);
 
  251   printf (
"#define PIKTO_END\t0x%06X\n", 
PIKTO_END);
 
  252   printf ("#define PIKTO_SIZE\t(PIKTO_END - PIKTO_START + 1)\n");
  253   printf ("\n\n");
  254   printf ("/* wcwidth -- return charcell positions of one code point */\n");
  255   printf ("inline int\nwcwidth (wchar_t wc)\n{\n");
  256   printf ("   return (wcswidth (&wc, 1));\n");
  257   printf ("}\n");
  258   printf ("\n\n");
  259   printf ("int\nwcswidth (const wchar_t *pwcs, size_t n)\n{\n\n");
  260   printf ("   int i;                    /* loop variable                                      */\n");
  261   printf ("   unsigned codept;          /* Unicode code point of current character            */\n");
  262   printf ("   unsigned plane;           /* Unicode plane, 0x00..0x10                          */\n");
  263   printf ("   unsigned lower17;         /* lower 17 bits of Unicode code point                */\n");
  264   printf ("   unsigned lower16;         /* lower 16 bits of Unicode code point                */\n");
  265   printf ("   int lowpt, midpt, highpt; /* for binary searching in plane1zeroes[]             */\n");
  266   printf ("   int found;                /* for binary searching in plane1zeroes[]             */\n");
  267   printf ("   int totalwidth;           /* total width of string, in charcells (1 or 2/glyph) */\n");
  268   printf ("   int illegalchar;          /* Whether or not this code point is illegal          */\n");
  269   putchar ('\n');
  270 
  271   
  272
  273
  274
  275   printf ("   char glyph_width[0x20000] = {");
  276   for (i = 0; i < 0x10000; i++) {
  277      if ((i & 0x1F) == 0)
  278         printf ("\n      /* U+%04X */ ", i);
  279      printf ("%d,", glyph_width[i]);
  280   }
  281   for (i = 0x10000; i < 0x20000; i++) {
  282      if ((i & 0x1F) == 0)
  283         printf ("\n      /* U+%06X */ ", i);
  284      printf ("%d", glyph_width[i]);
  285      if (i < 0x1FFFF) putchar (',');
  286   }
  287   printf ("\n   };\n\n");
  288 
  289   
  290
  291
  292   printf ("   char pikto_width[PIKTO_SIZE] = {");
  294      if ((i & 0x1F) == 0)
  296      printf ("%d", pikto_width[i]);
  298   }
  299   printf ("\n   };\n\n");
  300 
  301   
  302
  303
  304   printf ("\n");
  305   printf ("   illegalchar = totalwidth = 0;\n");
  306   printf ("   for (i = 0; !illegalchar && i < n; i++) {\n");
  307   printf ("      codept  = pwcs[i];\n");
  308   printf ("      plane   = codept >> 16;\n");
  309   printf ("      lower17 = codept & 0x1FFFF;\n");
  310   printf ("      lower16 = codept & 0xFFFF;\n");
  311   printf ("      if (plane < 2) { /* the most common case */\n");
  312   printf ("         if (glyph_width[lower17] < 0) illegalchar = 1;\n");
  313   printf ("         else totalwidth += glyph_width[lower17];\n");
  314   printf ("      }\n");
  315   printf ("      else { /* a higher plane or beyond Unicode range */\n");
  316   printf ("         if  ((lower16 == 0xFFFE) || (lower16 == 0xFFFF)) {\n");
  317   printf ("            illegalchar = 1;\n");
  318   printf ("         }\n");
  319   printf ("         else if (plane < 4) {  /* Ideographic Plane */\n");
  320   printf ("            totalwidth += 2; /* Default ideographic width */\n");
  321   printf ("         }\n");
  322   printf ("         else if (plane == 0x0F) {  /* CSUR Private Use Area */\n");
  323   printf ("            if (lower16 <= 0x0E6F) { /* Kinya */\n");
  324   printf ("               totalwidth++; /* all Kinya syllables have width 1 */\n");
  325   printf ("            }\n");
  326   printf ("            else if (lower16 <= (PIKTO_END & 0xFFFF)) { /* Pikto */\n");
  327   printf ("               if (pikto_width[lower16 - (PIKTO_START & 0xFFFF)] < 0) illegalchar = 1;\n");
  328   printf ("               else totalwidth += pikto_width[lower16 - (PIKTO_START & 0xFFFF)];\n");
  329   printf ("            }\n");
  330   printf ("         }\n");
  331   printf ("         else if (plane > 0x10) {\n");
  332   printf ("            illegalchar = 1;\n");
  333   printf ("         }\n");
  334   printf ("         /* Other non-printing in higher planes; return -1 as per IEEE 1003.1-2008. */\n");
  335   printf ("         else if (/* language tags */\n");
  336   printf ("                  codept == 0x0E0001 || (codept >= 0x0E0020 && codept <= 0x0E007F) ||\n");
  337   printf ("                  /* variation selectors, 0x0E0100..0x0E01EF */\n");
  338   printf ("                  (codept >= 0x0E0100 && codept <= 0x0E01EF)) {\n");
  339   printf ("            illegalchar = 1;\n");
  340   printf ("         }\n");
  341   printf ("         /*\n");
  342   printf ("            Unicode plane 0x02..0x10 printing character\n");
  343   printf ("         */\n");
  344   printf ("         else {\n");
  345   printf ("            illegalchar = 1; /* code is not in font */\n");
  346   printf ("         }\n");
  347   printf ("\n");
  348   printf ("      }\n");
  349   printf ("   }\n");
  350   printf ("   if (illegalchar) totalwidth = -1;\n");
  351   printf ("\n");
  352   printf ("   return (totalwidth);\n");
  353   printf ("\n");
  354   printf ("}\n");
  355 
  356   exit (EXIT_SUCCESS);
  357}
#define MAXSTRING
Maximum input line length - 1.
#define PIKTO_START
Start of Pikto code point range.
#define PIKTO_END
End of Pikto code point range.