Make git diff --check happy
[lsnes.git] / fonts / verifyhexfont.cpp
blob05107332b4cec7e225be2c9e5571a2290bdbb1b0
1 #include <cstdint>
2 #include <cstdlib>
3 #include <iostream>
4 #include <set>
6 extern uint32_t fontdata_size;
7 extern uint32_t fontdata[];
9 uint32_t mdir_use = 0;
10 uint32_t mdir_nuse = 0;
11 uint32_t sdir_gkey = 0;
12 uint32_t sdir_bkey = 0;
13 uint32_t ftype0 = 0;
14 uint32_t ftype1 = 0;
15 std::set<uint32_t> seen;
17 //This is Jenkin's MIX function.
18 uint32_t keyhash(uint32_t key, uint32_t item, uint32_t mod)
20 uint32_t a = key;
21 uint32_t b = 0;
22 uint32_t c = item;
23 a=a-b; a=a-c; a=a^(c >> 13);
24 b=b-c; b=b-a; b=b^(a << 8);
25 c=c-a; c=c-b; c=c^(b >> 13);
26 a=a-b; a=a-c; a=a^(c >> 12);
27 b=b-c; b=b-a; b=b^(a << 16);
28 c=c-a; c=c-b; c=c^(b >> 5);
29 a=a-b; a=a-c; a=a^(c >> 3);
30 b=b-c; b=b-a; b=b^(a << 10);
31 c=c-a; c=c-b; c=c^(b >> 15);
32 return c % mod;
35 void verify_font(uint32_t cp, uint32_t offset)
37 if(offset >= fontdata_size) {
38 std::cerr << "Font verify error: Bad offset for codepoint " << cp << "." << std::endl;
40 if(seen.count(offset))
41 return;
42 if(fontdata[offset] > 1) {
43 std::cerr << "Font verify error: Bad glyph type for codepoint " << cp << "." << std::endl;
44 exit(1);
46 if(fontdata[offset] == 0)
47 ftype0++;
48 else if(fontdata[offset] == 1)
49 ftype1++;
50 seen.insert(offset);
53 void verify_subdirectory(uint32_t offset, uint32_t mseed, uint32_t msize, uint32_t snum)
55 if(offset + 2 > fontdata_size) {
56 std::cerr << "Font verify error: Subdirectory offset out of range: " << offset << "." << std::endl;
57 exit(1);
59 uint32_t sseed = fontdata[offset++];
60 uint32_t ssize = fontdata[offset++];
61 if(offset + 2 * ssize > fontdata_size) {
62 std::cerr << "Font verify error: Subdirectory offset out of range: " << offset - 2 << "." << std::endl;
63 exit(1);
65 if(ssize)
66 mdir_use++;
67 else
68 mdir_nuse++;
69 for(uint32_t i = 0; i < ssize; i++) {
70 uint32_t cp = fontdata[offset++];
71 uint32_t foffset = fontdata[offset++];
72 if(keyhash(mseed, cp, msize) == snum && keyhash(sseed, cp, ssize) == i) {
73 verify_font(cp, foffset);
74 sdir_gkey++;
75 } else if(foffset != 0) {
76 std::cerr << "Font verify error: Bad codepoint with nonzero offset: " << i << " of "
77 << snum << "." << std::endl;
78 exit(1);
79 } else
80 sdir_bkey++;
84 void verify_main_directory(uint32_t offset)
86 if(offset + 2 > fontdata_size) {
87 std::cerr << "Font verify error: Main directory offset out of range: " << offset << "." << std::endl;
88 exit(1);
90 uint32_t mseed = fontdata[offset++];
91 uint32_t msize = fontdata[offset++];
92 if(offset + msize > fontdata_size) {
93 std::cerr << "Font verify error: Main directory offset out of range: " << offset - 2 << "."
94 << std::endl;
95 exit(1);
97 for(uint32_t i = 0; i < msize; i++)
98 verify_subdirectory(fontdata[offset++], mseed, msize, i);
101 int main()
103 if(fontdata_size == 0) {
104 std::cerr << "Font verify error: Empty fontdata." << std::endl;
105 exit(1);
107 verify_main_directory(fontdata[0]);
108 std::cerr << "Font verify successful!" << std::endl;
109 std::cerr << "Main directory entries: " << (mdir_use + mdir_nuse) << " (" << mdir_use << " used + "
110 << mdir_nuse << " not_used)." << std::endl;
111 std::cerr << "Subdirectory entries: " << (sdir_gkey + sdir_bkey) << " (" << sdir_gkey << " good + "
112 << sdir_bkey << " bad)." << std::endl;
113 std::cerr << "Distinct glyphs: " << (ftype0 + ftype1) << " (" << ftype0 << " narrow + "
114 << ftype1 << " wide)." << std::endl;
115 return 0;