summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/normalize.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/normalize.cc')
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/normalize.cc309
1 files changed, 0 insertions, 309 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/normalize.cc b/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/normalize.cc
deleted file mode 100644
index dc4bfe6c5c7..00000000000
--- a/Build/source/texk/dvisvgm/dvisvgm-src/libs/woff2/src/normalize.cc
+++ /dev/null
@@ -1,309 +0,0 @@
-/* Copyright 2013 Google Inc. All Rights Reserved.
-
- Distributed under MIT license.
- See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
-*/
-
-/* Glyph normalization */
-
-#include "./normalize.h"
-
-#include <inttypes.h>
-#include <stddef.h>
-
-#include "./buffer.h"
-#include "./port.h"
-#include "./font.h"
-#include "./glyph.h"
-#include "./round.h"
-#include "./store_bytes.h"
-#include "./table_tags.h"
-#include "./woff2_common.h"
-
-namespace woff2 {
-
-namespace {
-
-void StoreLoca(int index_fmt, uint32_t value, size_t* offset, uint8_t* dst) {
- if (index_fmt == 0) {
- Store16(value >> 1, offset, dst);
- } else {
- StoreU32(value, offset, dst);
- }
-}
-
-} // namespace
-
-namespace {
-
-bool WriteNormalizedLoca(int index_fmt, int num_glyphs, Font* font) {
- Font::Table* glyf_table = font->FindTable(kGlyfTableTag);
- Font::Table* loca_table = font->FindTable(kLocaTableTag);
-
- int glyph_sz = index_fmt == 0 ? 2 : 4;
- loca_table->buffer.resize(Round4(num_glyphs + 1) * glyph_sz);
- loca_table->length = (num_glyphs + 1) * glyph_sz;
-
- uint8_t* glyf_dst = num_glyphs ? &glyf_table->buffer[0] : NULL;
- uint8_t* loca_dst = &loca_table->buffer[0];
- uint32_t glyf_offset = 0;
- size_t loca_offset = 0;
-
- for (int i = 0; i < num_glyphs; ++i) {
- StoreLoca(index_fmt, glyf_offset, &loca_offset, loca_dst);
- Glyph glyph;
- const uint8_t* glyph_data;
- size_t glyph_size;
- if (!GetGlyphData(*font, i, &glyph_data, &glyph_size) ||
- (glyph_size > 0 && !ReadGlyph(glyph_data, glyph_size, &glyph))) {
- return FONT_COMPRESSION_FAILURE();
- }
- size_t glyf_dst_size = glyf_table->buffer.size() - glyf_offset;
- if (!StoreGlyph(glyph, glyf_dst + glyf_offset, &glyf_dst_size)) {
- return FONT_COMPRESSION_FAILURE();
- }
- glyf_dst_size = Round4(glyf_dst_size);
- if (glyf_dst_size > std::numeric_limits<uint32_t>::max() ||
- glyf_offset + static_cast<uint32_t>(glyf_dst_size) < glyf_offset ||
- (index_fmt == 0 && glyf_offset + glyf_dst_size >= (1UL << 17))) {
- return FONT_COMPRESSION_FAILURE();
- }
- glyf_offset += glyf_dst_size;
- }
-
- StoreLoca(index_fmt, glyf_offset, &loca_offset, loca_dst);
-
- glyf_table->buffer.resize(glyf_offset);
- glyf_table->data = glyf_offset ? &glyf_table->buffer[0] : NULL;
- glyf_table->length = glyf_offset;
- loca_table->data = loca_offset ? &loca_table->buffer[0] : NULL;
-
- return true;
-}
-
-} // namespace
-
-namespace {
-
-bool MakeEditableBuffer(Font* font, int tableTag) {
- Font::Table* table = font->FindTable(tableTag);
- if (table == NULL) {
- return FONT_COMPRESSION_FAILURE();
- }
- if (table->IsReused()) {
- return true;
- }
- uint32_t sz = Round4(table->length);
- table->buffer.resize(sz);
- uint8_t* buf = &table->buffer[0];
- memcpy(buf, table->data, table->length);
- if (PREDICT_FALSE(sz > table->length)) {
- memset(buf + table->length, 0, sz - table->length);
- }
- table->data = buf;
- return true;
-}
-
-} // namespace
-
-bool NormalizeGlyphs(Font* font) {
- Font::Table* head_table = font->FindTable(kHeadTableTag);
- Font::Table* glyf_table = font->FindTable(kGlyfTableTag);
- Font::Table* loca_table = font->FindTable(kLocaTableTag);
- if (head_table == NULL) {
- return FONT_COMPRESSION_FAILURE();
- }
- // If you don't have glyf/loca this transform isn't very interesting
- if (loca_table == NULL && glyf_table == NULL) {
- return true;
- }
- // It would be best if you didn't have just one of glyf/loca
- if ((glyf_table == NULL) != (loca_table == NULL)) {
- return FONT_COMPRESSION_FAILURE();
- }
- // Must share neither or both loca & glyf
- if (loca_table->IsReused() != glyf_table->IsReused()) {
- return FONT_COMPRESSION_FAILURE();
- }
- if (loca_table->IsReused()) {
- return true;
- }
-
- int index_fmt = head_table->data[51];
- int num_glyphs = NumGlyphs(*font);
-
- // We need to allocate a bit more than its original length for the normalized
- // glyf table, since it can happen that the glyphs in the original table are
- // 2-byte aligned, while in the normalized table they are 4-byte aligned.
- // That gives a maximum of 2 bytes increase per glyph. However, there is no
- // theoretical guarantee that the total size of the flags plus the coordinates
- // is the smallest possible in the normalized version, so we have to allow
- // some general overhead.
- // TODO(user) Figure out some more precise upper bound on the size of
- // the overhead.
- size_t max_normalized_glyf_size = 1.1 * glyf_table->length + 2 * num_glyphs;
-
- glyf_table->buffer.resize(max_normalized_glyf_size);
-
- // if we can't write a loca using short's (index_fmt 0)
- // try again using longs (index_fmt 1)
- if (!WriteNormalizedLoca(index_fmt, num_glyphs, font)) {
- if (index_fmt != 0) {
- return FONT_COMPRESSION_FAILURE();
- }
-
- // Rewrite loca with 4-byte entries & update head to match
- index_fmt = 1;
- if (!WriteNormalizedLoca(index_fmt, num_glyphs, font)) {
- return FONT_COMPRESSION_FAILURE();
- }
- head_table->buffer[51] = 1;
- }
-
- return true;
-}
-
-bool NormalizeOffsets(Font* font) {
- uint32_t offset = 12 + 16 * font->num_tables;
- for (auto tag : font->OutputOrderedTags()) {
- auto& table = font->tables[tag];
- table.offset = offset;
- offset += Round4(table.length);
- }
- return true;
-}
-
-namespace {
-
-uint32_t ComputeHeaderChecksum(const Font& font) {
- uint32_t checksum = font.flavor;
- uint16_t max_pow2 = font.num_tables ? Log2Floor(font.num_tables) : 0;
- uint16_t search_range = max_pow2 ? 1 << (max_pow2 + 4) : 0;
- uint16_t range_shift = (font.num_tables << 4) - search_range;
- checksum += (font.num_tables << 16 | search_range);
- checksum += (max_pow2 << 16 | range_shift);
- for (const auto& i : font.tables) {
- const Font::Table* table = &i.second;
- if (table->IsReused()) {
- table = table->reuse_of;
- }
- checksum += table->tag;
- checksum += table->checksum;
- checksum += table->offset;
- checksum += table->length;
- }
- return checksum;
-}
-
-} // namespace
-
-bool FixChecksums(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 < 12) {
- return FONT_COMPRESSION_FAILURE();
- }
-
- uint8_t* head_buf = &head_table->buffer[0];
- size_t offset = 8;
- StoreU32(0, &offset, head_buf);
- uint32_t file_checksum = 0;
- for (auto& i : font->tables) {
- Font::Table* table = &i.second;
- if (table->IsReused()) {
- table = table->reuse_of;
- }
- table->checksum = ComputeULongSum(table->data, table->length);
- file_checksum += table->checksum;
- }
-
- file_checksum += ComputeHeaderChecksum(*font);
- offset = 8;
- StoreU32(0xb1b0afba - file_checksum, &offset, head_buf);
-
- 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) {
- return (MakeEditableBuffer(font, kHeadTableTag) &&
- RemoveDigitalSignature(font) &&
- MarkTransformed(font) &&
- NormalizeGlyphs(font) &&
- NormalizeOffsets(font));
-}
-
-bool NormalizeFont(Font* font) {
- return (NormalizeWithoutFixingChecksums(font) &&
- FixChecksums(font));
-}
-
-bool NormalizeFontCollection(FontCollection* font_collection) {
- if (font_collection->fonts.size() == 1) {
- return NormalizeFont(&font_collection->fonts[0]);
- }
-
- uint32_t offset = CollectionHeaderSize(font_collection->header_version,
- font_collection->fonts.size());
- for (auto& font : font_collection->fonts) {
- if (!NormalizeWithoutFixingChecksums(&font)) {
-#ifdef FONT_COMPRESSION_BIN
- fprintf(stderr, "Font normalization failed.\n");
-#endif
- return FONT_COMPRESSION_FAILURE();
- }
- offset += kSfntHeaderSize + kSfntEntrySize * font.num_tables;
- }
-
- // Start table offsets after TTC Header and Sfnt Headers
- for (auto& font : font_collection->fonts) {
- for (auto tag : font.OutputOrderedTags()) {
- Font::Table& table = font.tables[tag];
- if (table.IsReused()) {
- table.offset = table.reuse_of->offset;
- } else {
- table.offset = offset;
- offset += Round4(table.length);
- }
- }
- }
-
- // Now we can fix the checksums
- for (auto& font : font_collection->fonts) {
- if (!FixChecksums(&font)) {
-#ifdef FONT_COMPRESSION_BIN
- fprintf(stderr, "Failed to fix checksums\n");
-#endif
- return FONT_COMPRESSION_FAILURE();
- }
- }
-
- return true;
-}
-
-} // namespace woff2