Index: third_party/woff2/src/woff2_enc.cc |
diff --git a/third_party/woff2/src/woff2_enc.cc b/third_party/woff2/src/woff2_enc.cc |
index 215fb0c47ce27b1e964a13a8e8a3171309bf4612..920c614fcc1f4b4926d13e0e5149b43efcbe851b 100644 |
--- a/third_party/woff2/src/woff2_enc.cc |
+++ b/third_party/woff2/src/woff2_enc.cc |
@@ -23,8 +23,8 @@ |
#include <string> |
#include <vector> |
-#include "./buffer.h" |
#include "./encode.h" |
+#include "./buffer.h" |
#include "./font.h" |
#include "./normalize.h" |
#include "./round.h" |
@@ -34,10 +34,12 @@ |
#include "./variable_length.h" |
#include "./woff2_common.h" |
+ |
namespace woff2 { |
namespace { |
+ |
using std::string; |
using std::vector; |
@@ -45,6 +47,7 @@ using std::vector; |
const size_t kWoff2HeaderSize = 48; |
const size_t kWoff2EntrySize = 20; |
+ |
bool Compress(const uint8_t* data, const size_t len, |
uint8_t* result, uint32_t* result_len, |
brotli::BrotliParams::Mode mode, int quality) { |
@@ -82,7 +85,7 @@ int KnownTableIndex(uint32_t tag) { |
} |
void StoreTableEntry(const Table& table, size_t* offset, uint8_t* dst) { |
- uint8_t flag_byte = KnownTableIndex(table.tag); |
+ uint8_t flag_byte = (table.flags & 0xC0) | KnownTableIndex(table.tag); |
dst[(*offset)++] = flag_byte; |
// The index here is treated as a set of flag bytes because |
// bits 6 and 7 of the byte are reserved for future use as flags. |
@@ -109,6 +112,7 @@ size_t TableEntrySize(const Table& table) { |
size_t ComputeWoff2Length(const FontCollection& font_collection, |
const std::vector<Table>& tables, |
std::map<uint32_t, uint16_t> index_by_offset, |
+ size_t compressed_data_length, |
size_t extended_metadata_length) { |
size_t size = kWoff2HeaderSize; |
@@ -137,10 +141,8 @@ size_t ComputeWoff2Length(const FontCollection& font_collection, |
} |
// compressed data |
- for (const auto& table : tables) { |
- size += table.dst_length; |
- size = Round4(size); |
- } |
+ size += compressed_data_length; |
+ size = Round4(size); |
size += extended_metadata_length; |
return size; |
@@ -217,7 +219,7 @@ bool TransformFontCollection(FontCollection* font_collection) { |
for (auto& font : font_collection->fonts) { |
if (!TransformGlyfAndLocaTables(&font)) { |
#ifdef FONT_COMPRESSION_BIN |
- fprintf(stderr, "Font transformation failed.\n"); |
+ fprintf(stderr, "glyf/loca transformation failed.\n"); |
#endif |
return FONT_COMPRESSION_FAILURE(); |
} |
@@ -248,8 +250,20 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length, |
return FONT_COMPRESSION_FAILURE(); |
} |
- if (!TransformFontCollection(&font_collection)) { |
+ if (params.allow_transforms && !TransformFontCollection(&font_collection)) { |
return FONT_COMPRESSION_FAILURE(); |
+ } else { |
+ // glyf/loca use 11 to flag "not transformed" |
+ for (auto& font : font_collection.fonts) { |
+ Font::Table* glyf_table = font.FindTable(kGlyfTableTag); |
+ Font::Table* loca_table = font.FindTable(kLocaTableTag); |
+ if (glyf_table) { |
+ glyf_table->flag_byte |= 0xc0; |
+ } |
+ if (loca_table) { |
+ loca_table->flag_byte |= 0xc0; |
+ } |
+ } |
} |
// Although the compressed size of each table in the final woff2 file won't |
@@ -291,6 +305,11 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length, |
return FONT_COMPRESSION_FAILURE(); |
} |
+#ifdef FONT_COMPRESSION_BIN |
+ fprintf(stderr, "Compressed %zu to %u.\n", total_transform_length, |
+ total_compressed_length); |
+#endif |
+ |
// Compress the extended metadata |
// TODO(user): how does this apply to collections |
uint32_t compressed_metadata_buf_length = |
@@ -331,30 +350,25 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length, |
Table table; |
table.tag = src_table.tag; |
- table.flags = 0; |
+ table.flags = src_table.flag_byte; |
table.src_length = src_table.length; |
table.transform_length = src_table.length; |
const uint8_t* transformed_data = src_table.data; |
const Font::Table* transformed_table = |
font.FindTable(src_table.tag ^ 0x80808080); |
if (transformed_table != NULL) { |
+ table.flags = transformed_table->flag_byte; |
table.flags |= kWoff2FlagsTransform; |
table.transform_length = transformed_table->length; |
transformed_data = transformed_table->data; |
- } |
- if (tables.empty()) { |
- table.dst_length = total_compressed_length; |
- table.dst_data = &compression_buf[0]; |
- } else { |
- table.dst_length = 0; |
- table.dst_data = NULL; |
+ |
} |
tables.push_back(table); |
} |
} |
size_t woff2_length = ComputeWoff2Length(font_collection, tables, |
- index_by_offset, compressed_metadata_buf_length); |
+ index_by_offset, total_compressed_length, compressed_metadata_buf_length); |
if (woff2_length > *result_length) { |
#ifdef FONT_COMPRESSION_BIN |
fprintf(stderr, "Result allocation was too small (%zd vs %zd bytes).\n", |
@@ -444,10 +458,10 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length, |
} |
// compressed data format (http://www.w3.org/TR/WOFF2/#table_format) |
- for (const auto& table : tables) { |
- StoreBytes(table.dst_data, table.dst_length, &offset, result); |
- offset = Round4(offset); |
- } |
+ |
+ StoreBytes(&compression_buf[0], total_compressed_length, &offset, result); |
+ offset = Round4(offset); |
+ |
StoreBytes(compressed_metadata_buf.data(), compressed_metadata_buf_length, |
&offset, result); |