Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(287)

Unified Diff: src/ots.cc

Issue 658573004: Updating to new OTS repo from https://github.com/khaledhosny/ots.git (Closed) Base URL: https://chromium.googlesource.com/external/ots@master
Patch Set: Adding Colored Emoji changes from external/git repo Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« .gitmodules ('K') | « src/ots.h ('k') | src/post.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ots.cc
diff --git a/src/ots.cc b/src/ots.cc
old mode 100644
new mode 100755
index e2dd0a29692307f3cbd6b7af76f7ff29348e4d54..51bc3a9456e1e5a2517c56ff2992660907a78370
--- a/src/ots.cc
+++ b/src/ots.cc
@@ -14,7 +14,9 @@
#include <map>
#include <vector>
+#ifndef OTS_DISABLE_WOFF2
#include "woff2.h"
+#endif
// The OpenType Font File
// http://www.microsoft.com/typography/otspec/cmap.htm
@@ -24,6 +26,11 @@ namespace {
bool g_debug_output = true;
bool g_enable_woff2 = false;
+// Generate a message with or without a table tag, when 'header' is the OpenTypeFile pointer
+#define OTS_FAILURE_MSG_TAG(msg_,tag_) OTS_FAILURE_MSG_TAG_(header, msg_, tag_)
+#define OTS_FAILURE_MSG_HDR(msg_) OTS_FAILURE_MSG_(header, msg_)
+
+
struct OpenTypeTable {
uint32_t tag;
uint32_t chksum;
@@ -164,27 +171,27 @@ bool ProcessTTF(ots::OpenTypeFile *header,
// we disallow all files > 1GB in size for sanity.
if (length > 1024 * 1024 * 1024) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("file exceeds 1GB");
}
if (!file.ReadTag(&header->version)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error reading version tag");
}
if (!ots::IsValidVersionTag(header->version)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("invalid version tag");
}
if (!file.ReadU16(&header->num_tables) ||
!file.ReadU16(&header->search_range) ||
!file.ReadU16(&header->entry_selector) ||
!file.ReadU16(&header->range_shift)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error reading table directory search header");
}
// search_range is (Maximum power of 2 <= numTables) x 16. Thus, to avoid
// overflow num_tables is, at most, 2^16 / 16 = 2^12
if (header->num_tables >= 4096 || header->num_tables < 1) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("excessive (or zero) number of tables");
}
unsigned max_pow2 = 0;
@@ -196,13 +203,13 @@ bool ProcessTTF(ots::OpenTypeFile *header,
// Don't call ots_failure() here since ~25% of fonts (250+ fonts) in
// http://www.princexml.com/fonts/ have unexpected search_range value.
if (header->search_range != expected_search_range) {
- OTS_WARNING("bad search range");
+ OTS_FAILURE_MSG_HDR("bad search range");
header->search_range = expected_search_range; // Fix the value.
}
// entry_selector is Log2(maximum power of 2 <= numTables)
if (header->entry_selector != max_pow2) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("incorrect entrySelector for table directory");
}
// range_shift is NumTables x 16-searchRange. We know that 16*num_tables
@@ -211,7 +218,7 @@ bool ProcessTTF(ots::OpenTypeFile *header,
const uint16_t expected_range_shift =
16 * header->num_tables - header->search_range;
if (header->range_shift != expected_range_shift) {
- OTS_WARNING("bad range shift");
+ OTS_FAILURE_MSG_HDR("bad range shift");
header->range_shift = expected_range_shift; // the same as above.
}
@@ -224,7 +231,7 @@ bool ProcessTTF(ots::OpenTypeFile *header,
!file.ReadU32(&table.chksum) ||
!file.ReadU32(&table.offset) ||
!file.ReadU32(&table.length)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error reading table directory");
}
table.uncompressed_length = table.length;
@@ -241,23 +248,23 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
// we disallow all files > 1GB in size for sanity.
if (length > 1024 * 1024 * 1024) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("file exceeds 1GB");
}
uint32_t woff_tag;
if (!file.ReadTag(&woff_tag)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error reading WOFF marker");
}
if (woff_tag != Tag("wOFF")) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("invalid WOFF marker");
}
if (!file.ReadTag(&header->version)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error reading version tag");
}
if (!ots::IsValidVersionTag(header->version)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("invalid version tag");
}
header->search_range = 0;
@@ -266,27 +273,27 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
uint32_t reported_length;
if (!file.ReadU32(&reported_length) || length != reported_length) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("incorrect file size in WOFF header");
}
if (!file.ReadU16(&header->num_tables) || !header->num_tables) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error reading number of tables");
}
uint16_t reserved_value;
if (!file.ReadU16(&reserved_value) || reserved_value) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error in reserved field of WOFF header");
}
uint32_t reported_total_sfnt_size;
if (!file.ReadU32(&reported_total_sfnt_size)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error reading total sfnt size");
}
// We don't care about these fields of the header:
// uint16_t major_version, minor_version
if (!file.Skip(2 * 2)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error skipping WOFF header fields");
}
// Checks metadata block size.
@@ -296,11 +303,11 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
if (!file.ReadU32(&meta_offset) ||
!file.ReadU32(&meta_length) ||
!file.ReadU32(&meta_length_orig)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error reading WOFF header fields");
}
if (meta_offset) {
if (meta_offset >= length || length - meta_offset < meta_length) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("invalid metadata block location/size");
}
}
@@ -309,11 +316,11 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
uint32_t priv_length;
if (!file.ReadU32(&priv_offset) ||
!file.ReadU32(&priv_length)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error reading WOFF header fields");
}
if (priv_offset) {
if (priv_offset >= length || length - priv_offset < priv_length) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("invalid private block location/size");
}
}
@@ -331,12 +338,12 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
!file.ReadU32(&table.length) ||
!file.ReadU32(&table.uncompressed_length) ||
!file.ReadU32(&table.chksum)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error reading table directory");
}
total_sfnt_size += ots::Round4(table.uncompressed_length);
if (total_sfnt_size > std::numeric_limits<uint32_t>::max()) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("sfnt size overflow");
}
tables.push_back(table);
if (i == 0 || tables[first_index].offset > table.offset)
@@ -346,17 +353,17 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
}
if (reported_total_sfnt_size != total_sfnt_size) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("uncompressed sfnt size mismatch");
}
// Table data must follow immediately after the header.
if (tables[first_index].offset != ots::Round4(file.offset())) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("junk before tables in WOFF file");
}
if (tables[last_index].offset >= length ||
length - tables[last_index].offset < tables[last_index].length) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("invalid table location/size");
}
// Blocks must follow immediately after the previous block.
// (Except for padding with a maximum of three null bytes)
@@ -364,35 +371,36 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
static_cast<uint64_t>(tables[last_index].offset) +
static_cast<uint64_t>(tables[last_index].length));
if (block_end > std::numeric_limits<uint32_t>::max()) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("invalid table location/size");
}
if (meta_offset) {
if (block_end != meta_offset) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("invalid metadata block location");
}
block_end = ots::Round4(static_cast<uint64_t>(meta_offset) +
static_cast<uint64_t>(meta_length));
if (block_end > std::numeric_limits<uint32_t>::max()) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("invalid metadata block size");
}
}
if (priv_offset) {
if (block_end != priv_offset) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("invalid private block location");
}
block_end = ots::Round4(static_cast<uint64_t>(priv_offset) +
static_cast<uint64_t>(priv_length));
if (block_end > std::numeric_limits<uint32_t>::max()) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("invalid private block size");
}
}
if (block_end != ots::Round4(length)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("file length mismatch (trailing junk?)");
}
return ProcessGeneric(header, woff_tag, output, data, length, tables, file);
}
+#ifndef OTS_DISABLE_WOFF2
bool ProcessWOFF2(ots::OpenTypeFile *header,
ots::OTSStream *output, const uint8_t *data, size_t length) {
size_t decompressed_size = ots::ComputeWOFF2FinalSize(data, length);
@@ -411,6 +419,53 @@ bool ProcessWOFF2(ots::OpenTypeFile *header,
}
return ProcessTTF(header, output, &decompressed_buffer[0], decompressed_size);
}
+#endif
+
+ots::TableAction GetTableAction(ots::OpenTypeFile *header, uint32_t tag) {
+ ots::TableAction action = ots::TABLE_ACTION_DEFAULT;
+
+ action = header->context->GetTableAction(htonl(tag));
+
+ if (action == ots::TABLE_ACTION_DEFAULT) {
+ action = ots::TABLE_ACTION_DROP;
+
+ for (unsigned i = 0; ; ++i) {
+ if (table_parsers[i].parse == NULL) break;
+
+ if (Tag(table_parsers[i].tag) == tag) {
+ action = ots::TABLE_ACTION_SANITIZE;
+ break;
+ }
+ }
+ }
+
+ assert(action != ots::TABLE_ACTION_DEFAULT); // Should never return this.
+ return action;
+}
+
+bool GetTableData(const uint8_t *data,
+ const OpenTypeTable table,
+ Arena *arena,
+ size_t *table_length,
+ const uint8_t **table_data) {
+ if (table.uncompressed_length != table.length) {
+ // Compressed table. Need to uncompress into memory first.
+ *table_length = table.uncompressed_length;
+ *table_data = (*arena).Allocate(*table_length);
+ uLongf dest_len = *table_length;
+ int r = uncompress((Bytef*) *table_data, &dest_len,
+ data + table.offset, table.length);
+ if (r != Z_OK || dest_len != *table_length) {
+ return false;
+ }
+ } else {
+ // Uncompressed table. We can process directly from memory.
+ *table_data = data + table.offset;
+ *table_length = table.length;
+ }
+
+ return true;
+}
bool ProcessGeneric(ots::OpenTypeFile *header, uint32_t signature,
ots::OTSStream *output,
@@ -428,46 +483,46 @@ bool ProcessGeneric(ots::OpenTypeFile *header, uint32_t signature,
const uint32_t this_tag = ntohl(tables[i].tag);
const uint32_t prev_tag = ntohl(tables[i - 1].tag);
if (this_tag <= prev_tag) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("table directory not correctly ordered");
}
}
// all tag names must be built from printable ASCII characters
if (!CheckTag(tables[i].tag)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_TAG("invalid table tag", &tables[i].tag);
}
// tables must be 4-byte aligned
if (tables[i].offset & 3) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_TAG("misaligned table", &tables[i].tag);
}
// and must be within the file
if (tables[i].offset < data_offset || tables[i].offset >= length) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_TAG("invalid table offset", &tables[i].tag);
}
// disallow all tables with a zero length
if (tables[i].length < 1) {
// Note: malayalam.ttf has zero length CVT table...
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_TAG("zero-length table", &tables[i].tag);
}
// disallow all tables with a length > 1GB
if (tables[i].length > 1024 * 1024 * 1024) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_TAG("table length exceeds 1GB", &tables[i].tag);
}
// disallow tables where the uncompressed size is < the compressed size.
if (tables[i].uncompressed_length < tables[i].length) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_TAG("invalid compressed table", &tables[i].tag);
}
if (tables[i].uncompressed_length > tables[i].length) {
// We'll probably be decompressing this table.
// disallow all tables which uncompress to > 30 MB
if (tables[i].uncompressed_length > 30 * 1024 * 1024) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_TAG("uncompressed length exceeds 30MB", &tables[i].tag);
}
if (uncompressed_sum + tables[i].uncompressed_length < uncompressed_sum) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_TAG("overflow of uncompressed sum", &tables[i].tag);
}
uncompressed_sum += tables[i].uncompressed_length;
@@ -480,13 +535,13 @@ bool ProcessGeneric(ots::OpenTypeFile *header, uint32_t signature,
end_byte = ots::Round4(end_byte);
}
if (!end_byte || end_byte > length) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_TAG("table overruns end of file", &tables[i].tag);
}
}
// All decompressed tables uncompressed must be <= 30MB.
if (uncompressed_sum > 30 * 1024 * 1024) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("uncompressed sum exceeds 30MB");
}
std::map<uint32_t, OpenTypeTable> table_map;
@@ -508,7 +563,7 @@ bool ProcessGeneric(ots::OpenTypeFile *header, uint32_t signature,
for (unsigned i = 0; i < overlap_checker.size(); ++i) {
overlap_count += (overlap_checker[i].second ? 1 : -1);
if (overlap_count > 1) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("overlapping tables");
}
}
@@ -517,12 +572,13 @@ bool ProcessGeneric(ots::OpenTypeFile *header, uint32_t signature,
for (unsigned i = 0; ; ++i) {
if (table_parsers[i].parse == NULL) break;
- const std::map<uint32_t, OpenTypeTable>::const_iterator it
- = table_map.find(Tag(table_parsers[i].tag));
+ uint32_t tag = Tag(table_parsers[i].tag);
+ const std::map<uint32_t, OpenTypeTable>::const_iterator it = table_map.find(tag);
+ ots::TableAction action = GetTableAction(header, tag);
if (it == table_map.end()) {
- if (table_parsers[i].required) {
- return OTS_FAILURE();
+ if (table_parsers[i].required && action == ots::TABLE_ACTION_SANITIZE) {
+ return OTS_FAILURE_MSG_TAG("missing required table", table_parsers[i].tag);
}
continue;
}
@@ -530,35 +586,26 @@ bool ProcessGeneric(ots::OpenTypeFile *header, uint32_t signature,
const uint8_t* table_data;
size_t table_length;
- if (it->second.uncompressed_length != it->second.length) {
- // compressed table. Need to uncompress into memory first.
- table_length = it->second.uncompressed_length;
- table_data = arena.Allocate(table_length);
- uLongf dest_len = table_length;
- int r = uncompress((Bytef*) table_data, &dest_len,
- data + it->second.offset, it->second.length);
- if (r != Z_OK || dest_len != table_length) {
- return OTS_FAILURE();
- }
- } else {
- // uncompressed table. We can process directly from memory.
- table_data = data + it->second.offset;
- table_length = it->second.length;
+ if (!GetTableData(data, it->second, &arena, &table_length, &table_data)) {
+ return OTS_FAILURE_MSG_TAG("uncompress failed", table_parsers[i].tag);
}
- if (!table_parsers[i].parse(header, table_data, table_length)) {
- return OTS_FAILURE();
+ if (action == ots::TABLE_ACTION_SANITIZE &&
+ !table_parsers[i].parse(header, table_data, table_length)) {
+ // TODO: parsers should generate specific messages detailing the failure;
+ // once those are all added, we won't need a generic failure message here
+ return OTS_FAILURE_MSG_TAG("failed to parse table", table_parsers[i].tag);
}
}
if (header->cff) {
// font with PostScript glyph
if (header->version != Tag("OTTO")) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("wrong font version for PostScript glyph data");
}
if (header->glyf || header->loca) {
// mixing outline formats is not recommended
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("font contains both PS and TT glyphs");
}
} else {
if ((!header->glyf || !header->loca) && (!header->cbdt || !header->cblc)) {
@@ -578,25 +625,35 @@ bool ProcessGeneric(ots::OpenTypeFile *header, uint32_t signature,
}
}
+ for (std::map<uint32_t, OpenTypeTable>::const_iterator it = table_map.begin();
+ it != table_map.end(); ++it) {
+ ots::TableAction action = GetTableAction(header, it->first);
+ if (action == ots::TABLE_ACTION_PASSTHRU) {
+ num_output_tables++;
+ }
+ }
+
uint16_t max_pow2 = 0;
while (1u << (max_pow2 + 1) <= num_output_tables) {
max_pow2++;
}
const uint16_t output_search_range = (1u << max_pow2) << 4;
+ // most of the errors here are highly unlikely - they'd only occur if the
+ // output stream returns a failure, e.g. lack of space to write
output->ResetChecksum();
if (!output->WriteTag(header->version) ||
!output->WriteU16(num_output_tables) ||
!output->WriteU16(output_search_range) ||
!output->WriteU16(max_pow2) ||
!output->WriteU16((num_output_tables << 4) - output_search_range)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error writing output");
}
const uint32_t offset_table_chksum = output->chksum();
const size_t table_record_offset = output->Tell();
if (!output->Pad(16 * num_output_tables)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error writing output");
}
std::vector<OutputTable> out_tables;
@@ -621,31 +678,72 @@ bool ProcessGeneric(ots::OpenTypeFile *header, uint32_t signature,
head_table_offset = out.offset;
}
if (!table_parsers[i].serialise(output, header)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_TAG("failed to serialize table", table_parsers[i].tag);
}
const size_t end_offset = output->Tell();
if (end_offset <= out.offset) {
// paranoid check. |end_offset| is supposed to be greater than the offset,
// as long as the Tell() interface is implemented correctly.
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error writing output");
}
out.length = end_offset - out.offset;
// align tables to four bytes
if (!output->Pad((4 - (end_offset & 3)) % 4)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error writing output");
}
out.chksum = output->chksum();
out_tables.push_back(out);
}
+ for (std::map<uint32_t, OpenTypeTable>::const_iterator it = table_map.begin();
+ it != table_map.end(); ++it) {
+ ots::TableAction action = GetTableAction(header, it->first);
+ if (action == ots::TABLE_ACTION_PASSTHRU) {
+ OutputTable out;
+ out.tag = it->second.tag;
+ out.offset = output->Tell();
+
+ output->ResetChecksum();
+ if (it->second.tag == Tag("head")) {
+ head_table_offset = out.offset;
+ }
+
+ const uint8_t* table_data;
+ size_t table_length;
+
+ if (!GetTableData(data, it->second, &arena, &table_length, &table_data)) {
+ return OTS_FAILURE_MSG_HDR("Failed to uncompress table");
+ }
+
+ if (!output->Write(table_data, table_length)) {
+ return OTS_FAILURE_MSG_HDR("Failed to serialize table");
+ }
+
+ const size_t end_offset = output->Tell();
+ if (end_offset <= out.offset) {
+ // paranoid check. |end_offset| is supposed to be greater than the offset,
+ // as long as the Tell() interface is implemented correctly.
+ return OTS_FAILURE_MSG_HDR("error writing output");
+ }
+ out.length = end_offset - out.offset;
+
+ // align tables to four bytes
+ if (!output->Pad((4 - (end_offset & 3)) % 4)) {
+ return OTS_FAILURE_MSG_HDR("error writing output");
+ }
+ out.chksum = output->chksum();
+ out_tables.push_back(out);
+ }
+ }
+
const size_t end_of_file = output->Tell();
// Need to sort the output tables for inclusion in the file
std::sort(out_tables.begin(), out_tables.end(), OutputTable::SortByTag);
if (!output->Seek(table_record_offset)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error writing output");
}
output->ResetChecksum();
@@ -655,7 +753,7 @@ bool ProcessGeneric(ots::OpenTypeFile *header, uint32_t signature,
!output->WriteU32(out_tables[i].chksum) ||
!output->WriteU32(out_tables[i].offset) ||
!output->WriteU32(out_tables[i].length)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error writing output");
}
tables_chksum += out_tables[i].chksum;
}
@@ -668,17 +766,17 @@ bool ProcessGeneric(ots::OpenTypeFile *header, uint32_t signature,
// seek into the 'head' table and write in the checksum magic value
if (!head_table_offset) {
- return OTS_FAILURE(); // not reached.
+ return OTS_FAILURE_MSG_HDR("internal error!");
}
if (!output->Seek(head_table_offset + 8)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error writing output");
}
if (!output->WriteU32(chksum_magic)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error writing output");
}
if (!output->Seek(end_of_file)) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_HDR("error writing output");
}
return true;
@@ -688,8 +786,6 @@ bool ProcessGeneric(ots::OpenTypeFile *header, uint32_t signature,
namespace ots {
-bool g_drop_color_bitmap_tables = true;
-
bool IsValidVersionTag(uint32_t tag) {
return tag == Tag("\x00\x01\x00\x00") ||
// OpenType fonts with CFF data have 'OTTO' tag.
@@ -707,23 +803,26 @@ void EnableWOFF2() {
g_enable_woff2 = true;
}
-void DoNotDropColorBitmapTables() {
- g_drop_color_bitmap_tables = false;
-}
-
-bool Process(OTSStream *output, const uint8_t *data, size_t length) {
+bool OTSContext::Process(OTSStream *output,
+ const uint8_t *data,
+ size_t length) {
OpenTypeFile header;
+
+ header.context = this;
+
if (length < 4) {
- return OTS_FAILURE();
+ return OTS_FAILURE_MSG_(&header, "file less than 4 bytes");
}
bool result;
if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == 'F') {
result = ProcessWOFF(&header, output, data, length);
+#ifndef OTS_DISABLE_WOFF2
} else if (g_enable_woff2 &&
data[0] == 'w' && data[1] == 'O' && data[2] == 'F' &&
data[3] == '2') {
result = ProcessWOFF2(&header, output, data, length);
+#endif
} else {
result = ProcessTTF(&header, output, data, length);
}
@@ -735,6 +834,12 @@ bool Process(OTSStream *output, const uint8_t *data, size_t length) {
return result;
}
+// For backward compatibility
+bool Process(OTSStream *output, const uint8_t *data, size_t length) {
+ static OTSContext context;
+ return context.Process(output, data, length);
+}
+
#if !defined(_MSC_VER) && defined(OTS_DEBUG)
bool Failure(const char *f, int l, const char *fn) {
if (g_debug_output) {
@@ -743,18 +848,6 @@ bool Failure(const char *f, int l, const char *fn) {
}
return false;
}
-
-void Warning(const char *f, int l, const char *format, ...) {
- if (g_debug_output) {
- std::fprintf(stderr, "WARNING at %s:%d: ", f, l);
- std::va_list va;
- va_start(va, format);
- std::vfprintf(stderr, format, va);
- va_end(va);
- std::fprintf(stderr, "\n");
- std::fflush(stderr);
- }
-}
#endif
} // namespace ots
« .gitmodules ('K') | « src/ots.h ('k') | src/post.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698