blob: 75d6370fd4371315f64af4a1ddc0b60a0db16049 [file] [log] [blame]
Raph Leviendcecdd82012-03-23 11:21:16 -07001// Copyright 2011 Google Inc. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package com.google.typography.font.compression;
6
Raph Leviendcecdd82012-03-23 11:21:16 -07007import com.google.common.collect.Lists;
Raph Leviendcecdd82012-03-23 11:21:16 -07008import com.google.common.io.Files;
9import com.google.typography.font.sfntly.Font;
10import com.google.typography.font.sfntly.FontFactory;
Raph Leviendcecdd82012-03-23 11:21:16 -070011
Raph Leviendcecdd82012-03-23 11:21:16 -070012import java.io.File;
13import java.io.IOException;
14import java.io.PrintWriter;
Raph Leviendcecdd82012-03-23 11:21:16 -070015import java.util.List;
Raph Leviendcecdd82012-03-23 11:21:16 -070016
17/**
18 * A command-line tool for running different experimental compression code over
19 * a corpus of fonts, and gathering statistics, particularly compression
20 * efficiency.
21 *
David Kuettel42726b62013-04-11 17:40:54 -070022 * This is not intended to be production code.
Raph Leviendcecdd82012-03-23 11:21:16 -070023 *
David Kuettel19411b72013-04-11 14:49:57 -070024 * @author Raph Levien
Raph Leviendcecdd82012-03-23 11:21:16 -070025 */
26public class CompressionRunner {
Raph Leviendcecdd82012-03-23 11:21:16 -070027
28 public static void main(String[] args) throws IOException {
29 boolean generateOutput = false;
30 List<String> descs = Lists.newArrayList();
31 String baseline = "gzip";
32
33 List<String> filenames = Lists.newArrayList();
34 for (int i = 0; i < args.length; i++) {
35 if (args[i].charAt(0) == '-') {
36 if (args[i].equals("-o")) {
37 generateOutput = true;
38 } else if (args[i].equals("-x")) {
39 descs.add(args[i + 1]);
40 i++;
41 } else if (args[i].equals("-b")) {
42 baseline = args[i + 1];
43 i++;
44 }
45 } else {
46 filenames.add(args[i]);
47 }
48 }
49
50 // String baseline = "glyf/triplet,code,push:lzma";
51 // String baseline = "glyf/cbbox,triplet,code,push:hdmx:lzma";
52 // descs.add("woff2");
53 if (descs.isEmpty()) {
David Kuettelc0d9d602013-04-10 18:44:14 -070054 descs.add("glyf/cbbox,triplet,code,reslice:woff2/lzma");
Raph Leviendcecdd82012-03-23 11:21:16 -070055 }
David Kuettel42726b62013-04-11 17:40:54 -070056 run(filenames, baseline, descs, generateOutput);
Raph Leviendcecdd82012-03-23 11:21:16 -070057 }
58
David Kuettel42726b62013-04-11 17:40:54 -070059 private static void run(List<String> filenames, String baseline, List<String> descs,
60 boolean generateOutput) throws IOException {
Raph Leviendcecdd82012-03-23 11:21:16 -070061 PrintWriter o = new PrintWriter(System.out);
62 List<StatsCollector> stats = Lists.newArrayList();
63 for (int i = 0; i < descs.size(); i++) {
64 stats.add(new StatsCollector());
65 }
66 FontFactory fontFactory = FontFactory.getInstance();
67 o.println("<html>");
68 for (String filename : filenames) {
69 byte[] bytes = Files.toByteArray(new File(filename));
70 Font font = fontFactory.loadFonts(bytes)[0];
David Kuettel42726b62013-04-11 17:40:54 -070071 byte[] baselineResult = Experiment.run(font, baseline);
Raph Leviendcecdd82012-03-23 11:21:16 -070072 o.printf("<!-- %s: baseline %d bytes", new File(filename).getName(), baselineResult.length);
73 for (int i = 0; i < descs.size(); i++) {
David Kuettel42726b62013-04-11 17:40:54 -070074 byte[] expResult = Experiment.run(font, descs.get(i));
Raph Leviendcecdd82012-03-23 11:21:16 -070075 if (generateOutput) {
76 String newFilename = filename;
77 if (newFilename.endsWith(".ttf")) {
78 newFilename = newFilename.substring(0, newFilename.length() - 4);
79 }
80 newFilename += ".woff2";
81 Files.write(expResult, new File(newFilename));
82 }
83 double percent = 100. * expResult.length / baselineResult.length;
84 stats.get(i).addStat(percent);
85 o.printf(", %c %.2f%%", 'A' + i, percent);
86 }
87 o.printf(" -->\n");
88 }
89 stats.get(0).chartHeader(o, descs.size());
90 for (int i = 0; i < descs.size(); i++) {
91 stats.get(i).chartData(o, i + 1);
92 }
93 stats.get(0).chartEnd(o);
94 o.printf("<p>baseline: %s</p>\n", baseline);
95 for (int i = 0; i < descs.size(); i++) {
96 StatsCollector sc = stats.get(i);
97 o.printf("<p>%c: %s: median %f, mean %f</p>\n",
98 'A' + i, descs.get(i), sc.median(), sc.mean());
99 }
100 stats.get(0).chartFooter(o);
101 o.close();
102 }
Raph Leviendcecdd82012-03-23 11:21:16 -0700103}