unifont-6.3.20131215.tar.gz
[unifont.git] / src / unipagecount.c
1 /*
2    unipagecount - program to count the number of glyphs defined in each page
3                   of 256 bytes, and print them in an 8 x 8 grid.  Input is
4                   from stdin.  Output is to stdout.
5
6    Synopsis: unipagecount < font_file.hex > count.txt
7              unipagecount -phex_page_num < font_file.hex  -- just 256 points
8              unipagecount -h < font_file.hex              -- HTML table
9              unipagecount -l < font_file.hex              -- linked HTML table
10
11    Author: Paul Hardy, unifoundry <at> unifoundry.com, December 2007
12    
13    Copyright (C) 2007, 2008, 2013 Paul Hardy
14
15    LICENSE:
16
17       This program is free software: you can redistribute it and/or modify
18       it under the terms of the GNU General Public License as published by
19       the Free Software Foundation, either version 3 of the License, or
20       (at your option) any later version.
21
22       This program is distributed in the hope that it will be useful,
23       but WITHOUT ANY WARRANTY; without even the implied warranty of
24       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25       GNU General Public License for more details.
26
27       You should have received a copy of the GNU General Public License
28       along with this program.  If not, see <http://www.gnu.org/licenses/>.
29 */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33
34 #define MAXBUF 256 /* maximum input line size */
35
36 int
37 main (int argc, char *argv[])
38 {
39
40    char inbuf[MAXBUF]; /* Max 256 characters in an input line */
41    int i, j;  /* loop variables */
42    unsigned page;  /* unicode page (256 bytes wide) */
43    unsigned unichar; /* unicode character */
44    int pagecount[256] = {256 * 0};
45    int onepage=0; /* set to one if printing character grid for one page */
46    int pageno=0; /* page number selected if only examining one page */
47    int html=0;   /* =0: print plain text; =1: print HTML */
48    int links=0;  /* =1: print HTML links; =0: don't print links */
49    void mkftable();  /* make (print) flipped HTML table */
50
51    size_t strlen();
52
53    if (argc > 1 && argv[1][0] == '-') {  /* Parse option */
54       switch (argv[1][1]) {
55          case 'p':  /* specified -p<hexpage> -- use given page number */
56             sscanf (&argv[1][2], "%x", &pageno);
57             if (pageno >= 0 && pageno <= 255) onepage = 1;
58             break;
59          case 'h':  /* print HTML table instead of text table */
60             html = 1;
61             break;
62          case 'l':  /* print hyperlinks in HTML table */
63             links = 1;
64             html = 1;
65             break;
66       }
67    }
68    /*
69       Initialize pagecount to account for noncharacters.
70    */
71    if (!onepage) {
72       pagecount[0xfd] = 32;  /* for U+FDD0..U+FDEF */
73       pagecount[0xff] = 2;   /* for U+FFFE, U+FFFF */
74    }
75    /*
76       Read one line at a time from input.  The format is:
77
78          <hexpos>:<hexbitmap>
79
80       where <hexpos> is the hexadecimal Unicode character position
81       in the range 00..FF and <hexbitmap> is the sequence of hexadecimal
82       digits of the character, laid out in a grid from left to right,
83       top to bottom.  The character is assumed to be 16 rows of variable
84       width.
85    */
86    while (fgets (inbuf, MAXBUF-1, stdin) != NULL) {
87       sscanf (inbuf, "%X", &unichar);
88       page = unichar >> 8;
89       if (onepage) { /* only increment counter if this is page we want */
90          if (page == pageno) { /* character is in the page we want */
91             pagecount[unichar & 0xff]++; /* mark character as covered */
92          }
93       }
94       else { /* counting all characters in all pages */
95          /* Don't add in noncharacters (U+FDD0..U+FDEF, U+FFFE, U+FFFF) */
96          if (unichar < 0xfdd0 || (unichar > 0xfdef && unichar < 0xfffe))
97             pagecount[page]++;
98       }
99    }
100    if (html) {
101       mkftable (pagecount, links);
102    }
103    else {  /* Otherwise, print plain text table */
104       fprintf (stdout,
105          "   0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F\n");
106       for (i=0; i<0x10; i++) {
107          fprintf (stdout,"%X ", i); /* row header */
108          for (j=0; j<0x10; j++) {
109             if (onepage) {
110                if (pagecount[i*16+j])
111                   fprintf (stdout," *  ");
112                else
113                   fprintf (stdout," .  ");
114             }
115             else {
116                fprintf (stdout, "%3X ", pagecount[i*16+j]);
117             }
118          }
119          fprintf (stdout,"\n");
120       }
121    
122    }
123    exit (0);
124 }
125
126
127 /*
128    mkftable - function to create an HTML table to show flipped bmp files
129               in a 16 by 16 grid.
130 */
131
132 void
133 mkftable (int pagecount[256], int links)
134 {
135    int i, j;
136    int count;
137    unsigned bgcolor;
138    
139    printf ("<html>\n");
140    printf ("<body>\n");
141    printf ("<table border=\"3\" align=\"center\">\n");
142    printf ("  <tr><th colspan=\"16\" bgcolor=\"#ffcc80\">");
143    printf ("GNU Unifont Page Coverage<br>(Green=100%%, Red=0%%)</th></tr>\n");
144    for (i = 0x0; i <= 0xF; i++) {
145       printf ("  <tr>\n");
146       for (j = 0x0; j <= 0xF; j++) {
147          count = pagecount[ (i << 4) | j ];
148          
149          /* print link in cell if links == 1 */
150          if (i < 0xd || (i == 0xd && j < 0x8) || (i == 0xf && j > 0x8)) {
151             /* background color is light green if completely done */
152             if (count == 0x100) bgcolor = 0xccffcc;
153             /* otherwise background is a shade of yellow to orange to red */
154             else bgcolor = 0xff0000 | (count << 8) | (count >> 1);
155             printf ("    <td bgcolor=\"#%06X\">", bgcolor);
156             printf ("<a href=\"bmp/uni%X%X.bmp\">%X%X</a>", i, j, i, j);
157             printf ("</td>\n");
158          }
159          else if (i == 0xd) {
160             if (j == 0x8) {
161                printf ("    <td align=\"center\" colspan=\"8\" bgcolor=\"#cccccc\">");
162                printf ("<b>Surrogate Pairs</b>");
163                printf ("</td>\n");
164             }  /* otherwise don't print anything more columns in this row */
165          }
166          else if (i == 0xe) {
167             if (j == 0x0) {
168                printf ("    <td align=\"center\" colspan=\"16\" bgcolor=\"#cccccc\">");
169                printf ("<b>Private Use</b>");
170                printf ("</td>\n");
171             }  /* otherwise don't print any more columns in this row */
172          }
173          else if (i == 0xf) {
174             if (j == 0x0) {
175                printf ("    <td align=\"center\" colspan=\"9\" bgcolor=\"#cccccc\">");
176                printf ("<b>Private Use</b>");
177                printf ("</td>\n");
178             }
179          }
180       }
181       printf ("  </tr>\n");
182    }
183    printf ("</table>\n");
184    printf ("</body>\n");
185    printf ("</html>\n");
186
187    return;
188 }