6 extern uint32_t fontdata_size
;
7 extern uint32_t fontdata
[];
10 uint32_t mdir_nuse
= 0;
11 uint32_t sdir_gkey
= 0;
12 uint32_t sdir_bkey
= 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
)
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);
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
))
42 if(fontdata
[offset
] > 1) {
43 std::cerr
<< "Font verify error: Bad glyph type for codepoint " << cp
<< "." << std::endl
;
46 if(fontdata
[offset
] == 0)
48 else if(fontdata
[offset
] == 1)
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
;
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
;
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
);
75 } else if(foffset
!= 0) {
76 std::cerr
<< "Font verify error: Bad codepoint with nonzero offset: " << i
<< " of "
77 << snum
<< "." << std::endl
;
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
;
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 << "."
97 for(uint32_t i
= 0; i
< msize
; i
++)
98 verify_subdirectory(fontdata
[offset
++], mseed
, msize
, i
);
103 if(fontdata_size
== 0) {
104 std::cerr
<< "Font verify error: Empty fontdata." << std::endl
;
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
;