Mark as transformed. Correct how table records were used by font.cc when writing collections.
This commit is contained in:
+21
-8
@@ -223,20 +223,33 @@ bool WriteFont(const Font& font, uint8_t* dst, size_t dst_size) {
|
|||||||
return WriteFont(font, &offset, dst, dst_size);
|
return WriteFont(font, &offset, dst, dst_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WriteTableRecord(const Font::Table* table, size_t* offset, uint8_t* dst,
|
||||||
|
size_t dst_size) {
|
||||||
|
if (dst_size < *offset + kSfntEntrySize) {
|
||||||
|
return FONT_COMPRESSION_FAILURE();
|
||||||
|
}
|
||||||
|
if (table->IsReused()) {
|
||||||
|
table = table->reuse_of;
|
||||||
|
}
|
||||||
|
StoreU32(table->tag, offset, dst);
|
||||||
|
StoreU32(table->checksum, offset, dst);
|
||||||
|
StoreU32(table->offset, offset, dst);
|
||||||
|
StoreU32(table->length, offset, dst);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool WriteTable(const Font::Table& table, size_t* offset, uint8_t* dst,
|
bool WriteTable(const Font::Table& table, size_t* offset, uint8_t* dst,
|
||||||
size_t dst_size) {
|
size_t dst_size) {
|
||||||
StoreU32(table.tag, offset, dst);
|
if (!WriteTableRecord(&table, offset, dst, dst_size)) {
|
||||||
StoreU32(table.checksum, offset, dst);
|
return false;
|
||||||
StoreU32(table.offset, offset, dst);
|
|
||||||
StoreU32(table.length, offset, dst);
|
|
||||||
|
|
||||||
if (table.offset + table.length < table.offset ||
|
|
||||||
dst_size < table.offset + table.length) {
|
|
||||||
return FONT_COMPRESSION_FAILURE();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the actual table data if it's the first time we've seen it
|
// Write the actual table data if it's the first time we've seen it
|
||||||
if (!table.IsReused()) {
|
if (!table.IsReused()) {
|
||||||
|
if (table.offset + table.length < table.offset ||
|
||||||
|
dst_size < table.offset + table.length) {
|
||||||
|
return FONT_COMPRESSION_FAILURE();
|
||||||
|
}
|
||||||
memcpy(dst + table.offset, table.data, table.length);
|
memcpy(dst + table.offset, table.data, table.length);
|
||||||
size_t padding_size = (4 - (table.length & 3)) & 3;
|
size_t padding_size = (4 - (table.length & 3)) & 3;
|
||||||
if (table.offset + table.length + padding_size < padding_size ||
|
if (table.offset + table.length + padding_size < padding_size ||
|
||||||
|
|||||||
+41
-5
@@ -215,10 +215,14 @@ uint32_t ComputeHeaderChecksum(const Font& font) {
|
|||||||
checksum += (font.num_tables << 16 | search_range);
|
checksum += (font.num_tables << 16 | search_range);
|
||||||
checksum += (max_pow2 << 16 | range_shift);
|
checksum += (max_pow2 << 16 | range_shift);
|
||||||
for (const auto& i : font.tables) {
|
for (const auto& i : font.tables) {
|
||||||
checksum += i.second.tag;
|
const Font::Table* table = &i.second;
|
||||||
checksum += i.second.checksum;
|
if (table->IsReused()) {
|
||||||
checksum += i.second.offset;
|
table = table->reuse_of;
|
||||||
checksum += i.second.length;
|
}
|
||||||
|
checksum += table->tag;
|
||||||
|
checksum += table->checksum;
|
||||||
|
checksum += table->offset;
|
||||||
|
checksum += table->length;
|
||||||
}
|
}
|
||||||
return checksum;
|
return checksum;
|
||||||
}
|
}
|
||||||
@@ -227,16 +231,21 @@ uint32_t ComputeHeaderChecksum(const Font& font) {
|
|||||||
|
|
||||||
bool FixChecksums(Font* font) {
|
bool FixChecksums(Font* font) {
|
||||||
Font::Table* head_table = font->FindTable(kHeadTableTag);
|
Font::Table* head_table = font->FindTable(kHeadTableTag);
|
||||||
|
if (head_table == NULL) {
|
||||||
|
return FONT_COMPRESSION_FAILURE();
|
||||||
|
}
|
||||||
if (head_table->reuse_of != NULL) {
|
if (head_table->reuse_of != NULL) {
|
||||||
head_table = head_table->reuse_of;
|
head_table = head_table->reuse_of;
|
||||||
}
|
}
|
||||||
if (head_table == NULL || head_table->length < 12) {
|
if (head_table->length < 12) {
|
||||||
return FONT_COMPRESSION_FAILURE();
|
return FONT_COMPRESSION_FAILURE();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* head_buf = &head_table->buffer[0];
|
uint8_t* head_buf = &head_table->buffer[0];
|
||||||
size_t offset = 8;
|
size_t offset = 8;
|
||||||
StoreU32(0, &offset, head_buf);
|
StoreU32(0, &offset, head_buf);
|
||||||
uint32_t file_checksum = 0;
|
uint32_t file_checksum = 0;
|
||||||
|
uint32_t head_checksum = 0;
|
||||||
for (auto& i : font->tables) {
|
for (auto& i : font->tables) {
|
||||||
Font::Table* table = &i.second;
|
Font::Table* table = &i.second;
|
||||||
if (table->IsReused()) {
|
if (table->IsReused()) {
|
||||||
@@ -244,17 +253,44 @@ bool FixChecksums(Font* font) {
|
|||||||
}
|
}
|
||||||
table->checksum = ComputeULongSum(table->data, table->length);
|
table->checksum = ComputeULongSum(table->data, table->length);
|
||||||
file_checksum += table->checksum;
|
file_checksum += table->checksum;
|
||||||
|
|
||||||
|
if (table->tag == kHeadTableTag) {
|
||||||
|
head_checksum = table->checksum;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file_checksum += ComputeHeaderChecksum(*font);
|
file_checksum += ComputeHeaderChecksum(*font);
|
||||||
offset = 8;
|
offset = 8;
|
||||||
StoreU32(0xb1b0afba - file_checksum, &offset, head_buf);
|
StoreU32(0xb1b0afba - file_checksum, &offset, head_buf);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
bool MarkTransformed(Font* font) {
|
||||||
|
Font::Table* head_table = font->FindTable(kHeadTableTag);
|
||||||
|
if (head_table == NULL) {
|
||||||
|
return FONT_COMPRESSION_FAILURE();
|
||||||
|
}
|
||||||
|
if (head_table->reuse_of != NULL) {
|
||||||
|
head_table = head_table->reuse_of;
|
||||||
|
}
|
||||||
|
if (head_table->length < 17) {
|
||||||
|
return FONT_COMPRESSION_FAILURE();
|
||||||
|
}
|
||||||
|
// set bit 11 of head table 'flags' to indicate that font has undergone
|
||||||
|
// lossless modifying transform
|
||||||
|
int head_flags = head_table->data[16];
|
||||||
|
head_table->buffer[16] = head_flags | 0x08;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
bool NormalizeWithoutFixingChecksums(Font* font) {
|
bool NormalizeWithoutFixingChecksums(Font* font) {
|
||||||
return (MakeEditableBuffer(font, kHeadTableTag) &&
|
return (MakeEditableBuffer(font, kHeadTableTag) &&
|
||||||
RemoveDigitalSignature(font) &&
|
RemoveDigitalSignature(font) &&
|
||||||
|
MarkTransformed(font) &&
|
||||||
NormalizeGlyphs(font) &&
|
NormalizeGlyphs(font) &&
|
||||||
NormalizeOffsets(font));
|
NormalizeOffsets(font));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user