1 # This script generates various 'interesting' fonts, and outputs an HTML file
2 # containing the subsetted fonts and the original fonts.
3 # View the output in browsers (preferably multiple, on multiple platforms) to
4 # make sure the output looks the same as the original.
9 use lib 'ext/Font-TTF/lib';
17 # The following fonts need to exist in a directory called 'testfonts':
21 LinLibertine_Re-4.1.8.ttf
30 die "Run '$0', or '$0 n' where n is the number of the test to rebuild\n"
31 if defined $index and $index !~ /^\d+$/;
34 # These aren't proper tests (they drop features that affect the rendering)
35 # TODO: fix them so they are proper, and test that they're really dropping the
37 # [ [qw(DejaVuSans.ttf FedraSansPro-Demi.ttf)], ["fluffily لا f"], [20], [qw(aalt ccmp dlig fina hlig init liga locl medi rlig salt kern mark mkmk)] ],
38 # [ [qw(DejaVuSans.ttf FedraSansPro-Demi.ttf)], ["fluffily لا f"], [20], [qw(liga)] ],
39 # [ [qw(DejaVuSans.ttf FedraSansPro-Demi.ttf)], ["fluffily لا f"], [20], [qw(fina init rlig)] ],
40 # [ [qw(DejaVuSans.ttf FedraSansPro-Demi.ttf)], ["fluffily لا f"], [20], [] ],
43 [ [@all], ["Hello world ABC abc 123"], [20] ],
45 # Substitution and NFC issues
46 [ [qw(GenBasR.ttf DejaVuSans.ttf FedraSansPro-Demi.ttf)], [
52 "i<span class='h'>\x{0300}</span>",
54 [ [qw(DejaVuSans.ttf FedraSansPro-Demi.ttf)], [
55 "s\x{0323}\x{0307}", # s, combining dot below, combining dot above
56 "s\x{0307}\x{0323}", # s, combining dot above, combining dot below
57 "\x{1e61}\x{0323}", # s with dot above, combining dot below
58 "\x{1e63}\x{0307}", # s with dot below, combining dot above
59 "\x{212b}", # angstrom
63 [ [qw(LinLibertine_Re-4.1.8.ttf DejaVuSans.ttf FedraSansPro-Demi.ttf)], [
65 "f<span>l</span>uf<span>f</span>ily",
66 "f<span class='h'>l</span>uf<span class='h'>f</span>ily",
70 [ [qw(DejaVuSans.ttf FedraSansPro-Demi.ttf calibri.ttf)],
71 ["|VAVAV|", "ToToT", "x//x"], [20], ['kern'] ],
74 [ [@all], ["VABC(123) fTo fluffiest f<span class='h'>f</span>i!\@#,. \x{00e2}\x{00eb}I\x{0303}o\x{0300}u\x{030a}\x{0305}\x{0303} i\x{0331}\x{0301} \x{0d23}\x{0d4d}\x{200d} παρακαλώ хэлло 你好 表示问候 やあ التل<span class='h'>ف</span>ون הלו"], [20, 8] ],
78 my $common_css = <<EOF;
80 font-family: Courier, monospace;
88 text-decoration: underline;
95 border: 1px #aaa solid;
104 if (not $font_cache{$fn}) {
105 my $s = new Font::Subsetter();
107 $font_cache{$fn} = $s;
109 return Clone::clone($font_cache{$fn});
113 # if (0) { my $j = 0;
114 for my $j (0..$#all) {
116 (my $eot_fn = $fn) =~ s/\.[ot]tf$/.eot/i;
117 if (not -e "testfonts/$eot_fn") {
118 Font::EOTWrapper::convert("testfonts/$fn", "testfonts/$eot_fn");
120 $common_css .= <<EOF;
122 font-family: original-$j;
123 src: url(../testfonts/$eot_fn);
126 font-family: original-$j;
127 src: url(../testfonts/$fn) format("truetype");
130 $std_fonts{$all[$j]} = "original-$j";
136 if (not defined $index) {
137 open $out, '>', 'testoutput/tests.html' or die $!;
138 binmode $out, ':utf8';
142 <meta charset="utf-8">
143 <title>Font tests</title>
151 for my $test (@tests) {
152 for my $fn (@{$test->[0]}) {
153 for my $text (@{$test->[1]}) {
155 next if defined $index and $index != $i;
157 print encode('utf-8', "$fn -- $text\n");
159 (my $text_plain = $text) =~ s/<.*?>//g;
163 $features = { DEFAULT => 0 };
164 $features->{$_} = 1 for @{$test->[3]};
167 my $s = new_font("testfonts/$fn");
168 $s->subset("testfonts/$fn", $text_plain, { features => $features });
169 my $path = sprintf '%03d', $i;
170 $s->write("testoutput/$path.ttf");
171 my $old_glyphs = $s->num_glyphs_old;
172 my $new_glyphs = $s->num_glyphs_new;
173 my @glyph_names = $s->glyph_names;
176 Font::EOTWrapper::convert("testoutput/$path.ttf", "testoutput/$path.eot");
178 my $fragment = <<EOF;
180 \@font-face { /* for IE */
181 font-family: subsetted-$i;
185 font-family: subsetted-$i;
186 src: url($path.ttf) format("truetype");
191 for my $size (@{$test->[2]}) {
193 <p title="$fn -- $path -- $old_glyphs vs $new_glyphs" class="box"><span style="font-family: $std_fonts{$fn}; font-size: ${size}pt">$text</span>
195 <span style="font-family: subsetted-$i; font-size: ${size}pt">$text</span></p>
199 print $out qq{\n\n$fragment<a href="$path.html">#</a>} if not defined $index;
201 open my $html, '>', "testoutput/$path.html";
202 binmode $html, ':utf8';
205 <meta charset="utf-8">
206 <title>Font test $path</title>
209 .glyphs { font-family: serif; font-size: 10pt; }
210 .sizes { font-size: 8pt; }
214 print $html qq{<p class="glyphs">}, (join ' ', map "$_", sort @glyph_names), qq{</p>};
215 print $html qq{<pre class="sizes">}, dump_sizes("testoutput/$path.ttf"), qq{</pre>};
217 print $out "<hr>\n" if not defined $index;
223 my $font = Font::TTF::Font->open($fn) or die "Failed to open $fn: $!";
227 for (sort keys %$font) {
229 my $l = $font->{$_}{' LENGTH'};
233 $out .= "Total: $s\n";