woff2_info.cc (4932B)
1 /* Copyright 2014 Google Inc. All Rights Reserved. 2 3 Distributed under MIT license. 4 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 */ 6 7 /* A commandline tool for dumping info about a woff2 file. */ 8 9 #include <string> 10 11 #include "file.h" 12 #include "./woff2_common.h" 13 #include "./buffer.h" 14 #include "./font.h" 15 #include "./table_tags.h" 16 #include "./variable_length.h" 17 18 std::string PrintTag(int tag) { 19 if (tag & 0x80808080) { 20 return std::string("_xfm"); // print _xfm for xform tables (else garbage) 21 } 22 char printable[] = { 23 static_cast<char>((tag >> 24) & 0xFF), 24 static_cast<char>((tag >> 16) & 0xFF), 25 static_cast<char>((tag >> 8) & 0xFF), 26 static_cast<char>(tag & 0xFF) 27 }; 28 return std::string(printable, 4); 29 } 30 31 int main(int argc, char **argv) { 32 if (argc != 2) { 33 fprintf(stderr, "One argument, the input filename, must be provided.\n"); 34 return 1; 35 } 36 37 std::string filename(argv[1]); 38 std::string outfilename = filename.substr(0, filename.find_last_of(".")) + ".woff2"; 39 fprintf(stdout, "Processing %s => %s\n", 40 filename.c_str(), outfilename.c_str()); 41 std::string input = woff2::GetFileContent(filename); 42 43 woff2::Buffer file(reinterpret_cast<const uint8_t*>(input.data()), 44 input.size()); 45 46 printf("WOFF2Header\n"); 47 uint32_t signature, flavor, length, totalSfntSize, totalCompressedSize; 48 uint32_t metaOffset, metaLength, metaOrigLength, privOffset, privLength; 49 uint16_t num_tables, reserved, major, minor; 50 if (!file.ReadU32(&signature)) return 1; 51 if (!file.ReadU32(&flavor)) return 1; 52 if (!file.ReadU32(&length)) return 1; 53 if (!file.ReadU16(&num_tables)) return 1; 54 if (!file.ReadU16(&reserved)) return 1; 55 if (!file.ReadU32(&totalSfntSize)) return 1; 56 if (!file.ReadU32(&totalCompressedSize)) return 1; 57 if (!file.ReadU16(&major)) return 1; 58 if (!file.ReadU16(&minor)) return 1; 59 if (!file.ReadU32(&metaOffset)) return 1; 60 if (!file.ReadU32(&metaLength)) return 1; 61 if (!file.ReadU32(&metaOrigLength)) return 1; 62 if (!file.ReadU32(&privOffset)) return 1; 63 if (!file.ReadU32(&privLength)) return 1; 64 65 if (signature != 0x774F4632) { 66 printf("Invalid signature: %08x\n", signature); 67 return 1; 68 } 69 printf("signature 0x%08x\n", signature); 70 printf("flavor 0x%08x\n", flavor); 71 printf("length %d\n", length); 72 printf("numTables %d\n", num_tables); 73 printf("reserved %d\n", reserved); 74 printf("totalSfntSize %d\n", totalSfntSize); 75 printf("totalCompressedSize %d\n", totalCompressedSize); 76 printf("majorVersion %d\n", major); 77 printf("minorVersion %d\n", minor); 78 printf("metaOffset %d\n", metaOffset); 79 printf("metaLength %d\n", metaLength); 80 printf("metaOrigLength %d\n", metaOrigLength); 81 printf("privOffset %d\n", privOffset); 82 printf("privLength %d\n", privLength); 83 84 std::vector<uint32_t> table_tags; 85 printf("TableDirectory starts at +%zu\n", file.offset()); 86 printf("Entry offset flags tag origLength txLength\n"); 87 for (auto i = 0; i < num_tables; i++) { 88 size_t offset = file.offset(); 89 uint8_t flags; 90 uint32_t tag, origLength, transformLength; 91 if (!file.ReadU8(&flags)) return 1; 92 if ((flags & 0x3f) == 0x3f) { 93 if (!file.ReadU32(&tag)) return 1; 94 } else { 95 tag = woff2::kKnownTags[flags & 0x3f]; 96 } 97 table_tags.push_back(tag); 98 if (!ReadBase128(&file, &origLength)) return 1; 99 100 printf("%5d %6zu 0x%02x %s %10d", i, offset, flags, 101 PrintTag(tag).c_str(), origLength); 102 103 uint8_t xform_version = (flags >> 6) & 0x3; 104 if (tag == woff2::kGlyfTableTag || tag == woff2::kLocaTableTag) { 105 if (xform_version == 0) { 106 if (!ReadBase128(&file, &transformLength)) return 1; 107 printf(" %8d", transformLength); 108 } 109 } else if (xform_version > 0) { 110 if (!ReadBase128(&file, &transformLength)) return 1; 111 printf(" %8d", transformLength); 112 } 113 printf("\n"); 114 } 115 116 // Collection header 117 if (flavor == woff2::kTtcFontFlavor) { 118 uint32_t version, numFonts; 119 if (!file.ReadU32(&version)) return 1; 120 if (!woff2::Read255UShort(&file, &numFonts)) return 1; 121 printf("CollectionHeader 0x%08x %d fonts\n", version, numFonts); 122 123 for (auto i = 0; i < numFonts; i++) { 124 uint32_t numTables, flavor; 125 if (!woff2::Read255UShort(&file, &numTables)) return 1; 126 if (!file.ReadU32(&flavor)) return 1; 127 printf("CollectionFontEntry %d flavor 0x%08x %d tables\n", i, flavor, 128 numTables); 129 for (auto j = 0; j < numTables; j++) { 130 uint32_t table_idx; 131 if (!woff2::Read255UShort(&file, &table_idx)) return 1; 132 if (table_idx >= table_tags.size()) return 1; 133 printf(" %d %s (idx %d)\n", j, 134 PrintTag(table_tags[table_idx]).c_str(), table_idx); 135 } 136 } 137 } 138 139 printf("TableDirectory ends at +%zu\n", file.offset()); 140 141 return 0; 142 }