|
|
@@ -8,11 +8,12 @@
|
|
|
|
|
|
#include <woff2/decode.h>
|
|
|
|
|
|
-#include <stdlib.h>
|
|
|
+#include <cstdlib>
|
|
|
#include <algorithm>
|
|
|
#include <complex>
|
|
|
#include <cstring>
|
|
|
#include <limits>
|
|
|
+#include <memory>
|
|
|
#include <string>
|
|
|
#include <vector>
|
|
|
#include <map>
|
|
|
@@ -106,12 +107,12 @@ struct RebuildMetadata {
|
|
|
std::map<std::pair<uint32_t, uint32_t>, uint32_t> checksums;
|
|
|
};
|
|
|
|
|
|
-int WithSign(int flag, int baseval) {
|
|
|
+auto WithSign(int flag, int baseval) -> int {
|
|
|
// Precondition: 0 <= baseval < 65536 (to avoid integer overflow)
|
|
|
return (flag & 1) ? baseval : -baseval;
|
|
|
}
|
|
|
|
|
|
-bool _SafeIntAddition(int a, int b, int* result) {
|
|
|
+auto _SafeIntAddition(int a, int b, int* result) -> bool {
|
|
|
if (PREDICT_FALSE(
|
|
|
((a > 0) && (b > std::numeric_limits<int>::max() - a)) ||
|
|
|
((a < 0) && (b < std::numeric_limits<int>::min() - a)))) {
|
|
|
@@ -121,8 +122,8 @@ bool _SafeIntAddition(int a, int b, int* result) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-bool TripletDecode(const uint8_t* flags_in, const uint8_t* in, size_t in_size,
|
|
|
- unsigned int n_points, Point* result, size_t* in_bytes_consumed) {
|
|
|
+auto TripletDecode(const uint8_t* flags_in, const uint8_t* in, size_t in_size,
|
|
|
+ unsigned int n_points, Point* result, size_t* in_bytes_consumed) -> bool {
|
|
|
int x = 0;
|
|
|
int y = 0;
|
|
|
|
|
|
@@ -190,9 +191,9 @@ bool TripletDecode(const uint8_t* flags_in, const uint8_t* in, size_t in_size,
|
|
|
|
|
|
// This function stores just the point data. On entry, dst points to the
|
|
|
// beginning of a simple glyph. Returns true on success.
|
|
|
-bool StorePoints(unsigned int n_points, const Point* points,
|
|
|
+auto StorePoints(unsigned int n_points, const Point* points,
|
|
|
unsigned int n_contours, unsigned int instruction_length,
|
|
|
- uint8_t* dst, size_t dst_size, size_t* glyph_size) {
|
|
|
+ uint8_t* dst, size_t dst_size, size_t* glyph_size) -> bool {
|
|
|
// I believe that n_contours < 65536, in which case this is safe. However, a
|
|
|
// comment and/or an assert would be good.
|
|
|
unsigned int flag_offset = kEndPtsOfContoursOffset + 2 * n_contours + 2 +
|
|
|
@@ -320,8 +321,8 @@ void ComputeBbox(unsigned int n_points, const Point* points, uint8_t* dst) {
|
|
|
}
|
|
|
|
|
|
|
|
|
-bool SizeOfComposite(Buffer composite_stream, size_t* size,
|
|
|
- bool* have_instructions) {
|
|
|
+auto SizeOfComposite(Buffer composite_stream, size_t* size,
|
|
|
+ bool* have_instructions) -> bool {
|
|
|
size_t start_offset = composite_stream.offset();
|
|
|
bool we_have_instructions = false;
|
|
|
|
|
|
@@ -355,7 +356,7 @@ bool SizeOfComposite(Buffer composite_stream, size_t* size,
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-bool Pad4(WOFF2Out* out) {
|
|
|
+auto Pad4(WOFF2Out* out) -> bool {
|
|
|
uint8_t zeroes[] = {0, 0, 0};
|
|
|
if (PREDICT_FALSE(out->Size() + 3 < out->Size())) {
|
|
|
return FONT_COMPRESSION_FAILURE();
|
|
|
@@ -370,8 +371,8 @@ bool Pad4(WOFF2Out* out) {
|
|
|
}
|
|
|
|
|
|
// Build TrueType loca table
|
|
|
-bool StoreLoca(const std::vector<uint32_t>& loca_values, int index_format,
|
|
|
- uint32_t* checksum, WOFF2Out* out) {
|
|
|
+auto StoreLoca(const std::vector<uint32_t>& loca_values, int index_format,
|
|
|
+ uint32_t* checksum, WOFF2Out* out) -> bool {
|
|
|
// TODO(user) figure out what index format to use based on whether max
|
|
|
// offset fits into uint16_t or not
|
|
|
const uint64_t loca_size = loca_values.size();
|
|
|
@@ -382,8 +383,7 @@ bool StoreLoca(const std::vector<uint32_t>& loca_values, int index_format,
|
|
|
std::vector<uint8_t> loca_content(loca_size * offset_size);
|
|
|
uint8_t* dst = &loca_content[0];
|
|
|
size_t offset = 0;
|
|
|
- for (size_t i = 0; i < loca_values.size(); ++i) {
|
|
|
- uint32_t value = loca_values[i];
|
|
|
+ for (unsigned int value : loca_values) {
|
|
|
if (index_format) {
|
|
|
offset = StoreU32(dst, offset, value);
|
|
|
} else {
|
|
|
@@ -398,10 +398,10 @@ bool StoreLoca(const std::vector<uint32_t>& loca_values, int index_format,
|
|
|
}
|
|
|
|
|
|
// Reconstruct entire glyf table based on transformed original
|
|
|
-bool ReconstructGlyf(const uint8_t* data, Table* glyf_table,
|
|
|
+auto ReconstructGlyf(const uint8_t* data, Table* glyf_table,
|
|
|
uint32_t* glyf_checksum, Table * loca_table,
|
|
|
uint32_t* loca_checksum, WOFF2FontInfo* info,
|
|
|
- WOFF2Out* out) {
|
|
|
+ WOFF2Out* out) -> bool {
|
|
|
static const int kNumSubStreams = 7;
|
|
|
Buffer file(data, glyf_table->transform_length);
|
|
|
uint32_t version;
|
|
|
@@ -548,7 +548,7 @@ bool ReconstructGlyf(const uint8_t* data, Table* glyf_table,
|
|
|
size_t triplet_bytes_consumed = 0;
|
|
|
if (points_size < total_n_points) {
|
|
|
points_size = total_n_points;
|
|
|
- points.reset(new Point[points_size]);
|
|
|
+ points = std::make_unique<Point[]>(points_size);
|
|
|
}
|
|
|
if (PREDICT_FALSE(!TripletDecode(flags_buf, triplet_buf, triplet_size,
|
|
|
total_n_points, points.get(), &triplet_bytes_consumed))) {
|
|
|
@@ -650,18 +650,18 @@ bool ReconstructGlyf(const uint8_t* data, Table* glyf_table,
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-Table* FindTable(std::vector<Table*>* tables, uint32_t tag) {
|
|
|
+auto FindTable(std::vector<Table*>* tables, uint32_t tag) -> Table* {
|
|
|
for (Table* table : *tables) {
|
|
|
if (table->tag == tag) {
|
|
|
return table;
|
|
|
}
|
|
|
}
|
|
|
- return NULL;
|
|
|
+ return nullptr;
|
|
|
}
|
|
|
|
|
|
// Get numberOfHMetrics, https://www.microsoft.com/typography/otspec/hhea.htm
|
|
|
-bool ReadNumHMetrics(const uint8_t* data, size_t data_size,
|
|
|
- uint16_t* num_hmetrics) {
|
|
|
+auto ReadNumHMetrics(const uint8_t* data, size_t data_size,
|
|
|
+ uint16_t* num_hmetrics) -> bool {
|
|
|
// Skip 34 to reach 'hhea' numberOfHMetrics
|
|
|
Buffer buffer(data, data_size);
|
|
|
if (PREDICT_FALSE(!buffer.Skip(34) || !buffer.ReadU16(num_hmetrics))) {
|
|
|
@@ -671,13 +671,13 @@ bool ReadNumHMetrics(const uint8_t* data, size_t data_size,
|
|
|
}
|
|
|
|
|
|
// http://dev.w3.org/webfonts/WOFF2/spec/Overview.html#hmtx_table_format
|
|
|
-bool ReconstructTransformedHmtx(const uint8_t* transformed_buf,
|
|
|
+auto ReconstructTransformedHmtx(const uint8_t* transformed_buf,
|
|
|
size_t transformed_size,
|
|
|
uint16_t num_glyphs,
|
|
|
uint16_t num_hmetrics,
|
|
|
const std::vector<int16_t>& x_mins,
|
|
|
uint32_t* checksum,
|
|
|
- WOFF2Out* out) {
|
|
|
+ WOFF2Out* out) -> bool {
|
|
|
Buffer hmtx_buff_in(transformed_buf, transformed_size);
|
|
|
|
|
|
uint8_t hmtx_flags;
|
|
|
@@ -768,8 +768,8 @@ bool ReconstructTransformedHmtx(const uint8_t* transformed_buf,
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-bool Woff2Uncompress(uint8_t* dst_buf, size_t dst_size,
|
|
|
- const uint8_t* src_buf, size_t src_size) {
|
|
|
+auto Woff2Uncompress(uint8_t* dst_buf, size_t dst_size,
|
|
|
+ const uint8_t* src_buf, size_t src_size) -> bool {
|
|
|
size_t uncompressed_size = dst_size;
|
|
|
BrotliDecoderResult result = BrotliDecoderDecompress(
|
|
|
src_size, src_buf, &uncompressed_size, dst_buf);
|
|
|
@@ -780,8 +780,8 @@ bool Woff2Uncompress(uint8_t* dst_buf, size_t dst_size,
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-bool ReadTableDirectory(Buffer* file, std::vector<Table>* tables,
|
|
|
- size_t num_tables) {
|
|
|
+auto ReadTableDirectory(Buffer* file, std::vector<Table>* tables,
|
|
|
+ size_t num_tables) -> bool {
|
|
|
uint32_t src_offset = 0;
|
|
|
for (size_t i = 0; i < num_tables; ++i) {
|
|
|
Table* table = &(*tables)[i];
|
|
|
@@ -839,8 +839,8 @@ bool ReadTableDirectory(Buffer* file, std::vector<Table>* tables,
|
|
|
}
|
|
|
|
|
|
// Writes a single Offset Table entry
|
|
|
-size_t StoreOffsetTable(uint8_t* result, size_t offset, uint32_t flavor,
|
|
|
- uint16_t num_tables) {
|
|
|
+auto StoreOffsetTable(uint8_t* result, size_t offset, uint32_t flavor,
|
|
|
+ uint16_t num_tables) -> size_t {
|
|
|
offset = StoreU32(result, offset, flavor); // sfnt version
|
|
|
offset = Store16(result, offset, num_tables); // num_tables
|
|
|
unsigned max_pow2 = 0;
|
|
|
@@ -855,7 +855,7 @@ size_t StoreOffsetTable(uint8_t* result, size_t offset, uint32_t flavor,
|
|
|
return offset;
|
|
|
}
|
|
|
|
|
|
-size_t StoreTableEntry(uint8_t* result, uint32_t offset, uint32_t tag) {
|
|
|
+auto StoreTableEntry(uint8_t* result, uint32_t offset, uint32_t tag) -> size_t {
|
|
|
offset = StoreU32(result, offset, tag);
|
|
|
offset = StoreU32(result, offset, 0);
|
|
|
offset = StoreU32(result, offset, 0);
|
|
|
@@ -864,7 +864,7 @@ size_t StoreTableEntry(uint8_t* result, uint32_t offset, uint32_t tag) {
|
|
|
}
|
|
|
|
|
|
// First table goes after all the headers, table directory, etc
|
|
|
-uint64_t ComputeOffsetToFirstTable(const WOFF2Header& hdr) {
|
|
|
+auto ComputeOffsetToFirstTable(const WOFF2Header& hdr) -> uint64_t {
|
|
|
uint64_t offset = kSfntHeaderSize +
|
|
|
kSfntEntrySize * static_cast<uint64_t>(hdr.num_tables);
|
|
|
if (hdr.header_version) {
|
|
|
@@ -877,7 +877,7 @@ uint64_t ComputeOffsetToFirstTable(const WOFF2Header& hdr) {
|
|
|
return offset;
|
|
|
}
|
|
|
|
|
|
-std::vector<Table*> Tables(WOFF2Header* hdr, size_t font_index) {
|
|
|
+auto Tables(WOFF2Header* hdr, size_t font_index) -> std::vector<Table*> {
|
|
|
std::vector<Table*> tables;
|
|
|
if (PREDICT_FALSE(hdr->header_version)) {
|
|
|
for (auto index : hdr->ttc_fonts[font_index].table_indices) {
|
|
|
@@ -893,12 +893,12 @@ std::vector<Table*> Tables(WOFF2Header* hdr, size_t font_index) {
|
|
|
|
|
|
// Offset tables assumed to have been written in with 0's initially.
|
|
|
// WOFF2Header isn't const so we can use [] instead of at() (which upsets FF)
|
|
|
-bool ReconstructFont(uint8_t* transformed_buf,
|
|
|
+auto ReconstructFont(uint8_t* transformed_buf,
|
|
|
const uint32_t transformed_buf_size,
|
|
|
RebuildMetadata* metadata,
|
|
|
WOFF2Header* hdr,
|
|
|
size_t font_index,
|
|
|
- WOFF2Out* out) {
|
|
|
+ WOFF2Out* out) -> bool {
|
|
|
size_t dest_offset = out->Size();
|
|
|
uint8_t table_entry[12];
|
|
|
WOFF2FontInfo* info = &metadata->font_infos[font_index];
|
|
|
@@ -915,7 +915,7 @@ bool ReconstructFont(uint8_t* transformed_buf,
|
|
|
return FONT_COMPRESSION_FAILURE();
|
|
|
}
|
|
|
|
|
|
- if (glyf_table != NULL) {
|
|
|
+ if (glyf_table != nullptr) {
|
|
|
if (PREDICT_FALSE((glyf_table->flags & kWoff2FlagsTransform)
|
|
|
!= (loca_table->flags & kWoff2FlagsTransform))) {
|
|
|
#ifdef FONT_COMPRESSION_BIN
|
|
|
@@ -1043,7 +1043,7 @@ bool ReconstructFont(uint8_t* transformed_buf,
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-bool ReadWOFF2Header(const uint8_t* data, size_t length, WOFF2Header* hdr) {
|
|
|
+auto ReadWOFF2Header(const uint8_t* data, size_t length, WOFF2Header* hdr) -> bool {
|
|
|
Buffer file(data, length);
|
|
|
|
|
|
uint32_t signature;
|
|
|
@@ -1226,8 +1226,8 @@ bool ReadWOFF2Header(const uint8_t* data, size_t length, WOFF2Header* hdr) {
|
|
|
}
|
|
|
|
|
|
// Write everything before the actual table data
|
|
|
-bool WriteHeaders(const uint8_t* data, size_t length, RebuildMetadata* metadata,
|
|
|
- WOFF2Header* hdr, WOFF2Out* out) {
|
|
|
+auto WriteHeaders(RebuildMetadata* metadata,
|
|
|
+ WOFF2Header* hdr, WOFF2Out* out) -> bool {
|
|
|
std::vector<uint8_t> output(ComputeOffsetToFirstTable(*hdr), 0);
|
|
|
|
|
|
// Re-order tables in output (OTSpec) order
|
|
|
@@ -1309,7 +1309,7 @@ bool WriteHeaders(const uint8_t* data, size_t length, RebuildMetadata* metadata,
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
-size_t ComputeWOFF2FinalSize(const uint8_t* data, size_t length) {
|
|
|
+auto ComputeWOFF2FinalSize(const uint8_t* data, size_t length) -> size_t {
|
|
|
Buffer file(data, length);
|
|
|
uint32_t total_length;
|
|
|
|
|
|
@@ -1320,25 +1320,25 @@ size_t ComputeWOFF2FinalSize(const uint8_t* data, size_t length) {
|
|
|
return total_length;
|
|
|
}
|
|
|
|
|
|
-bool ConvertWOFF2ToTTF(uint8_t *result, size_t result_length,
|
|
|
- const uint8_t *data, size_t length) {
|
|
|
+auto ConvertWOFF2ToTTF(uint8_t *result, size_t result_length,
|
|
|
+ const uint8_t *data, size_t length) -> bool {
|
|
|
WOFF2MemoryOut out(result, result_length);
|
|
|
return ConvertWOFF2ToTTF(data, length, &out);
|
|
|
}
|
|
|
|
|
|
-bool ConvertWOFF2ToTTF(const uint8_t* data, size_t length,
|
|
|
- WOFF2Out* out) {
|
|
|
+auto ConvertWOFF2ToTTF(const uint8_t* data, size_t length,
|
|
|
+ WOFF2Out* out) -> bool {
|
|
|
RebuildMetadata metadata;
|
|
|
WOFF2Header hdr;
|
|
|
if (!ReadWOFF2Header(data, length, &hdr)) {
|
|
|
return FONT_COMPRESSION_FAILURE();
|
|
|
}
|
|
|
|
|
|
- if (!WriteHeaders(data, length, &metadata, &hdr, out)) {
|
|
|
+ if (!WriteHeaders(&metadata, &hdr, out)) {
|
|
|
return FONT_COMPRESSION_FAILURE();
|
|
|
}
|
|
|
|
|
|
- const float compression_ratio = (float) hdr.uncompressed_size / length;
|
|
|
+ const float compression_ratio = static_cast<float>(hdr.uncompressed_size) / length;
|
|
|
if (compression_ratio > kMaxPlausibleCompressionRatio) {
|
|
|
#ifdef FONT_COMPRESSION_BIN
|
|
|
fprintf(stderr, "Implausible compression ratio %.01f\n", compression_ratio);
|