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