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