GNU Unifont: src/unipagecount.c Source File

GNU Unifont 17.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 21 October 2023 [Paul Hardy]:
53 - Added full prototype for mkftable function in main function.
54
55 6 September 2025 [Paul Hardy]:
56 - Changed pageno from "int" to "unsigned" for compatibility
57 with sscanf definition.
58*/
59
60#include <stdio.h>
61#include <stdlib.h>
62
63#define MAXBUF 256 ///< Maximum input line size - 1.
64
65
66/**
67 @brief The main function.
68
69 @param[in] argc The count of command line arguments.
70 @param[in] argv Pointer to array of command line arguments.
71 @return This program exits with status 0.
72*/
73int
74main (int argc, char *argv[])
75{
76
77 char inbuf[MAXBUF]; /* Max 256 characters in an input line */
78 int i, j; /* loop variables */
79 unsigned plane=0; /* Unicode plane number, 0 to 0x16 */
80 unsigned page; /* unicode page (256 bytes wide) */
81 unsigned unichar; /* unicode character */
82 int pagecount[256] = {256 * 0};
83 int onepage=0; /* set to one if printing character grid for one page */
84 unsigned pageno=0; /* page number selected if only examining one page */
85 int html=0; /* =0: print plain text; =1: print HTML */
86 int links=0; /* =1: print HTML links; =0: don't print links */
87
88 /* make (print) flipped HTML table */
89 void mkftable (unsigned plane, int pagecount[256], int links);
90
91 size_t strlen(const char *s);
92
93 if (argc > 1 && argv[1][0] == '-') { /* Parse option */
94 plane = 0;
95 for (i = 1; i < argc; i++) {
96 switch (argv[i][1]) {
97 case 'p': /* specified -p<hexpage> -- use given page number */
98 sscanf (&argv[1][2], "%x", &pageno);
99 if (pageno >= 0 && pageno <= 255) onepage = 1;
100 break;
101 case 'h': /* print HTML table instead of text table */
102 html = 1;
103 break;
104 case 'l': /* print hyperlinks in HTML table */
105 links = 1;
106 html = 1;
107 break;
108 case 'P': /* Plane number specified */
109 plane = atoi(&argv[1][2]);
110 break;
111 }
112 }
113 }
114 /*
115 Initialize pagecount to account for noncharacters.
116 */
117 if (!onepage && plane==0) {
118 pagecount[0xfd] = 32; /* for U+FDD0..U+FDEF */
119 }
120 pagecount[0xff] = 2; /* for U+nnFFFE, U+nnFFFF */
121 /*
122 Read one line at a time from input. The format is:
123
124 <hexpos>:<hexbitmap>
125
126 where <hexpos> is the hexadecimal Unicode character position
127 in the range 00..FF and <hexbitmap> is the sequence of hexadecimal
128 digits of the character, laid out in a grid from left to right,
129 top to bottom. The character is assumed to be 16 rows of variable
130 width.
131 */
132 while (fgets (inbuf, MAXBUF-1, stdin) != NULL) {
133 sscanf (inbuf, "%X", &unichar);
134 page = unichar >> 8;
135 if (onepage) { /* only increment counter if this is page we want */
136 if (page == pageno) { /* character is in the page we want */
137 pagecount[unichar & 0xff]++; /* mark character as covered */
138 }
139 }
140 else { /* counting all characters in all pages */
141 if (plane == 0) {
142 /* Don't add in noncharacters (U+FDD0..U+FDEF, U+FFFE, U+FFFF) */
143 if (unichar < 0xfdd0 || (unichar > 0xfdef && unichar < 0xfffe))
144 pagecount[page]++;
145 }
146 else {
147 if ((page >> 8) == plane) { /* code point is in desired plane */
148 pagecount[page & 0xFF]++;
149 }
150 }
151 }
152 }
153 if (html) {
154 mkftable (plane, pagecount, links);
155 }
156 else { /* Otherwise, print plain text table */
157 if (plane > 0) fprintf (stdout, " ");
158 fprintf (stdout,
159 " 0 1 2 3 4 5 6 7 8 9 A B C D E F\n");
160 for (i=0; i<0x10; i++) {
161 fprintf (stdout,"%02X%X ", plane, i); /* row header */
162 for (j=0; j<0x10; j++) {
163 if (onepage) {
164 if (pagecount[i*16+j])
165 fprintf (stdout," * ");
166 else
167 fprintf (stdout," . ");
168 }
169 else {
170 fprintf (stdout, "%3X ", pagecount[i*16+j]);
171 }
172 }
173 fprintf (stdout,"\n");
174 }
175
176 }
177 exit (0);
178}
179
180
181/**
182 @brief Create an HTML table linked to PNG images.
183
184 This function creates an HTML table to show PNG files
185 in a 16 by 16 grid. The background color of each "page"
186 of 256 code points is shaded from red (for 0% coverage)
187 to green (for 100% coverage).
188
189 @param[in] plane The Unicode plane, 0..17.
190 @param[in] pagecount Array with count of glyphs in each 256 code point range.
191 @param[in] links 1 = generate hyperlinks, 0 = do not generate hyperlinks.
192*/
193void
194mkftable (unsigned plane, int pagecount[256], int links)
195{
196 int i, j;
197 int count;
198 unsigned bgcolor;
199
200 printf ("<html>\n");
201 printf ("<body>\n");
202 printf ("<table border=\"3\" align=\"center\">\n");
203 printf (" <tr><th colspan=\"16\" bgcolor=\"#ffcc80\">");
204 printf ("GNU Unifont Glyphs<br>with Page Coverage for Plane %d<br>(Green=100%%, Red=0%%)</th></tr>\n", plane);
205 for (i = 0x0; i <= 0xF; i++) {
206 printf (" <tr>\n");
207 for (j = 0x0; j <= 0xF; j++) {
208 count = pagecount[ (i << 4) | j ];
209
210 /* print link in cell if links == 1 */
211 if (plane != 0 || (i < 0xd || (i == 0xd && j < 0x8) || (i == 0xf && j > 0x8))) {
212 /* background color is light green if completely done */
213 if (count == 0x100) bgcolor = 0xccffcc;
214 /* otherwise background is a shade of yellow to orange to red */
215 else bgcolor = 0xff0000 | (count << 8) | (count >> 1);
216 printf (" <td bgcolor=\"#%06X\">", bgcolor);
217 if (plane == 0)
218 printf ("<a href=\"png/plane%02X/uni%02X%X%X.png\">%X%X</a>", plane, plane, i, j, i, j);
219 else
220 printf ("<a href=\"png/plane%02X/uni%02X%X%X.png\">%02X%X%X</a>", plane, plane, i, j, plane, i, j);
221 printf ("</td>\n");
222 }
223 else if (i == 0xd) {
224 if (j == 0x8) {
225 printf (" <td align=\"center\" colspan=\"8\" bgcolor=\"#cccccc\">");
226 printf ("<b>Surrogate Pairs</b>");
227 printf ("</td>\n");
228 } /* otherwise don't print anything more columns in this row */
229 }
230 else if (i == 0xe) {
231 if (j == 0x0) {
232 printf (" <td align=\"center\" colspan=\"16\" bgcolor=\"#cccccc\">");
233 printf ("<b>Private Use Area</b>");
234 printf ("</td>\n");
235 } /* otherwise don't print any more columns in this row */
236 }
237 else if (i == 0xf) {
238 if (j == 0x0) {
239 printf (" <td align=\"center\" colspan=\"9\" bgcolor=\"#cccccc\">");
240 printf ("<b>Private Use Area</b>");
241 printf ("</td>\n");
242 }
243 }
244 }
245 printf (" </tr>\n");
246 }
247 printf ("</table>\n");
248 printf ("</body>\n");
249 printf ("</html>\n");
250
251 return;
252}
main
int main(int argc, char *argv[])
The main function.
Definition: unipagecount.c:74
mkftable
void mkftable(unsigned plane, int pagecount[256], int links)
Create an HTML table linked to PNG images.
Definition: unipagecount.c:194
MAXBUF
#define MAXBUF
Maximum input line size - 1.
Definition: unipagecount.c:63