зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1270537 - Update woff2 code to latest upstream. r=milan
This commit is contained in:
Родитель
126baca8ab
Коммит
b2cd16a8c5
|
@ -11,7 +11,7 @@ The in-tree copy is updated by running
|
|||
sh update.sh
|
||||
from within the modules/woff2 directory.
|
||||
|
||||
Current version: [commit 643c7b45891cbeb5dc1f7599a4c9b53fbe82a08f].
|
||||
Current version: [commit afbecce5ff16faf92ce637eab991810f5b66f803].
|
||||
|
||||
redefine-unique_ptr.patch redefines the class std::unique_ptr to workaround a
|
||||
build issue with missing C++11 features.
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
diff --git a/modules/woff2/src/port.h b/modules/woff2/src/port.h
|
||||
--- a/modules/woff2/src/port.h
|
||||
+++ b/modules/woff2/src/port.h
|
||||
@@ -12,16 +12,18 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Helper function for bit twiddling and macros for branch prediction.
|
||||
|
||||
#ifndef WOFF2_PORT_H_
|
||||
#define WOFF2_PORT_H_
|
||||
|
||||
+#include <assert.h>
|
||||
+
|
||||
namespace woff2 {
|
||||
|
||||
typedef unsigned int uint32;
|
||||
|
||||
inline int Log2Floor(uint32 n) {
|
||||
#if defined(__GNUC__)
|
||||
return n == 0 ? -1 : 31 ^ __builtin_clz(n);
|
||||
#else
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
EXPORTS += [
|
||||
'src/woff2_dec.h',
|
||||
'src/woff2_out.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
|
@ -13,6 +14,7 @@ UNIFIED_SOURCES += [
|
|||
'src/variable_length.cc',
|
||||
'src/woff2_common.cc',
|
||||
'src/woff2_dec.cc',
|
||||
'src/woff2_out.cc',
|
||||
]
|
||||
|
||||
# We allow warnings for third-party code that can be updated from upstream.
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
diff --git a/modules/woff2/src/woff2_dec.cc b/modules/woff2/src/woff2_dec.cc
|
||||
--- a/modules/woff2/src/woff2_dec.cc
|
||||
+++ b/modules/woff2/src/woff2_dec.cc
|
||||
@@ -20,16 +20,24 @@
|
||||
#include <algorithm>
|
||||
#include <complex>
|
||||
@@ -22,16 +22,25 @@
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
+#include "mozilla/UniquePtr.h"
|
||||
+namespace std
|
||||
+{
|
||||
|
@ -18,7 +18,7 @@ diff --git a/modules/woff2/src/woff2_dec.cc b/modules/woff2/src/woff2_dec.cc
|
|||
+ #define default_delete DefaultDelete
|
||||
+ #define unique_ptr UniquePtr
|
||||
+}
|
||||
|
||||
+
|
||||
#include "./decode.h"
|
||||
#include "./buffer.h"
|
||||
#include "./port.h"
|
||||
|
@ -26,3 +26,4 @@ diff --git a/modules/woff2/src/woff2_dec.cc b/modules/woff2/src/woff2_dec.cc
|
|||
#include "./store_bytes.h"
|
||||
#include "./table_tags.h"
|
||||
#include "./variable_length.h"
|
||||
#include "./woff2_common.h"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// File IO helpers
|
||||
// File IO helpers.
|
||||
|
||||
#ifndef WOFF2_FILE_H_
|
||||
#define WOFF2_FILE_H_
|
||||
|
@ -22,18 +22,20 @@
|
|||
|
||||
namespace woff2 {
|
||||
|
||||
inline std::string GetFileContent(std::string filename) {
|
||||
using std::string;
|
||||
|
||||
|
||||
inline string GetFileContent(string filename) {
|
||||
std::ifstream ifs(filename.c_str(), std::ios::binary);
|
||||
return std::string(
|
||||
return string(
|
||||
std::istreambuf_iterator<char>(ifs.rdbuf()),
|
||||
std::istreambuf_iterator<char>());
|
||||
}
|
||||
|
||||
inline void SetFileContents(std::string filename, std::string content) {
|
||||
inline void SetFileContents(string filename, string::iterator start,
|
||||
string::iterator end) {
|
||||
std::ofstream ofs(filename.c_str(), std::ios::binary);
|
||||
std::copy(content.begin(),
|
||||
content.end(),
|
||||
std::ostream_iterator<char>(ofs));
|
||||
std::copy(start, end, std::ostream_iterator<char>(ofs));
|
||||
}
|
||||
|
||||
} // namespace woff2
|
||||
|
|
|
@ -49,11 +49,7 @@ std::vector<uint32_t> Font::OutputOrderedTags() const {
|
|||
output_order.push_back(table.tag);
|
||||
}
|
||||
|
||||
// Alphabetize and do not put loca immediately after glyf
|
||||
// This violates woff2 spec but results in a font that passes OTS
|
||||
std::sort(output_order.begin(), output_order.end());
|
||||
// TODO(user): change to match spec once browsers are on newer OTS
|
||||
/*
|
||||
// Alphabetize then put loca immediately after glyf
|
||||
auto glyf_loc = std::find(output_order.begin(), output_order.end(),
|
||||
kGlyfTableTag);
|
||||
auto loca_loc = std::find(output_order.begin(), output_order.end(),
|
||||
|
@ -62,7 +58,7 @@ std::vector<uint32_t> Font::OutputOrderedTags() const {
|
|||
output_order.erase(loca_loc);
|
||||
output_order.insert(std::find(output_order.begin(), output_order.end(),
|
||||
kGlyfTableTag) + 1, kLocaTableTag);
|
||||
}*/
|
||||
}
|
||||
|
||||
return output_order;
|
||||
}
|
||||
|
@ -145,7 +141,7 @@ bool ReadTrueTypeCollection(Buffer* file, const uint8_t* data, size_t len,
|
|||
}
|
||||
|
||||
std::vector<uint32_t> offsets;
|
||||
for (auto i = 0; i < num_fonts; i++) {
|
||||
for (size_t i = 0; i < num_fonts; i++) {
|
||||
uint32_t offset;
|
||||
if (!file->ReadU32(&offset)) {
|
||||
return FONT_COMPRESSION_FAILURE();
|
||||
|
@ -185,15 +181,14 @@ bool ReadFontCollection(const uint8_t* data, size_t len,
|
|||
FontCollection* font_collection) {
|
||||
Buffer file(data, len);
|
||||
|
||||
uint32_t flavor;
|
||||
if (!file.ReadU32(&flavor)) {
|
||||
if (!file.ReadU32(&font_collection->flavor)) {
|
||||
return FONT_COMPRESSION_FAILURE();
|
||||
}
|
||||
|
||||
if (flavor != kTtcFontFlavor) {
|
||||
if (font_collection->flavor != kTtcFontFlavor) {
|
||||
font_collection->fonts.resize(1);
|
||||
Font& font = font_collection->fonts[0];
|
||||
font.flavor = flavor;
|
||||
font.flavor = font_collection->flavor;
|
||||
return ReadTrueTypeFont(&file, data, len, &font);
|
||||
}
|
||||
return ReadTrueTypeCollection(&file, data, len, font_collection);
|
||||
|
@ -290,7 +285,7 @@ bool WriteFontCollection(const FontCollection& font_collection, uint8_t* dst,
|
|||
size_t offset = 0;
|
||||
|
||||
// It's simpler if this just a simple sfnt
|
||||
if (font_collection.fonts.size() == 1) {
|
||||
if (font_collection.flavor != kTtcFontFlavor) {
|
||||
return WriteFont(font_collection.fonts[0], &offset, dst, dst_size);
|
||||
}
|
||||
|
||||
|
@ -301,7 +296,7 @@ bool WriteFontCollection(const FontCollection& font_collection, uint8_t* dst,
|
|||
|
||||
// Offset Table, zeroed for now
|
||||
size_t offset_table = offset; // where to write offsets later
|
||||
for (int i = 0; i < font_collection.fonts.size(); i++) {
|
||||
for (size_t i = 0; i < font_collection.fonts.size(); i++) {
|
||||
StoreU32(0, &offset, dst);
|
||||
}
|
||||
|
||||
|
@ -312,7 +307,7 @@ bool WriteFontCollection(const FontCollection& font_collection, uint8_t* dst,
|
|||
}
|
||||
|
||||
// Write fonts and their offsets.
|
||||
for (int i = 0; i < font_collection.fonts.size(); i++) {
|
||||
for (size_t i = 0; i < font_collection.fonts.size(); i++) {
|
||||
const auto& font = font_collection.fonts[i];
|
||||
StoreU32(offset, &offset_table, dst);
|
||||
if (!WriteFont(font, &offset, dst, dst_size)) {
|
||||
|
|
|
@ -61,6 +61,7 @@ struct Font {
|
|||
|
||||
// Accomodates both singular (OTF, TTF) and collection (TTC) fonts
|
||||
struct FontCollection {
|
||||
uint32_t flavor;
|
||||
uint32_t header_version;
|
||||
// (offset, first use of table*) pairs
|
||||
std::map<uint32_t, Font::Table*> tables;
|
||||
|
|
|
@ -122,7 +122,7 @@ bool ReadGlyph(const uint8_t* data, size_t len, Glyph* glyph) {
|
|||
uint8_t flag_repeat = 0;
|
||||
for (int i = 0; i < num_contours; ++i) {
|
||||
flags[i].resize(glyph->contours[i].size());
|
||||
for (int j = 0; j < glyph->contours[i].size(); ++j) {
|
||||
for (size_t j = 0; j < glyph->contours[i].size(); ++j) {
|
||||
if (flag_repeat == 0) {
|
||||
if (!buffer.ReadU8(&flag)) {
|
||||
return FONT_COMPRESSION_FAILURE();
|
||||
|
@ -143,7 +143,7 @@ bool ReadGlyph(const uint8_t* data, size_t len, Glyph* glyph) {
|
|||
// Read the x coordinates.
|
||||
int prev_x = 0;
|
||||
for (int i = 0; i < num_contours; ++i) {
|
||||
for (int j = 0; j < glyph->contours[i].size(); ++j) {
|
||||
for (size_t j = 0; j < glyph->contours[i].size(); ++j) {
|
||||
uint8_t flag = flags[i][j];
|
||||
if (flag & kFLAG_XSHORT) {
|
||||
// single byte x-delta coord value
|
||||
|
@ -170,7 +170,7 @@ bool ReadGlyph(const uint8_t* data, size_t len, Glyph* glyph) {
|
|||
// Read the y coordinates.
|
||||
int prev_y = 0;
|
||||
for (int i = 0; i < num_contours; ++i) {
|
||||
for (int j = 0; j < glyph->contours[i].size(); ++j) {
|
||||
for (size_t j = 0; j < glyph->contours[i].size(); ++j) {
|
||||
uint8_t flag = flags[i][j];
|
||||
if (flag & kFLAG_YSHORT) {
|
||||
// single byte y-delta coord value
|
||||
|
|
|
@ -58,8 +58,7 @@ inline void Store16(int val, size_t* offset, uint8_t* dst) {
|
|||
((val & 0xFF) << 8) | ((val & 0xFF00) >> 8);
|
||||
*offset += 2;
|
||||
#elif (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
||||
*reinterpret_cast<uint16_t*>(dst + *offset) =
|
||||
static_cast<uint16_t>(val);
|
||||
*reinterpret_cast<uint16_t*>(dst + *offset) = static_cast<uint16_t>(val);
|
||||
*offset += 2;
|
||||
#else
|
||||
dst[(*offset)++] = val >> 8;
|
||||
|
|
|
@ -39,7 +39,7 @@ void WriteBytes(std::vector<uint8_t>* out, const uint8_t* data, size_t len) {
|
|||
}
|
||||
|
||||
void WriteBytes(std::vector<uint8_t>* out, const std::vector<uint8_t>& in) {
|
||||
for (int i = 0; i < in.size(); ++i) {
|
||||
for (size_t i = 0; i < in.size(); ++i) {
|
||||
out->push_back(in[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,8 @@ namespace woff2 {
|
|||
|
||||
uint32_t ComputeULongSum(const uint8_t* buf, size_t size) {
|
||||
uint32_t checksum = 0;
|
||||
for (size_t i = 0; i < size; i += 4) {
|
||||
size_t aligned_size = size & ~3;
|
||||
for (size_t i = 0; i < aligned_size; i += 4) {
|
||||
#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
|
||||
uint32_t v = *reinterpret_cast<const uint32_t*>(buf + i);
|
||||
checksum += (((v & 0xFF) << 24) | ((v & 0xFF00) << 8) |
|
||||
|
@ -35,6 +36,16 @@ uint32_t ComputeULongSum(const uint8_t* buf, size_t size) {
|
|||
(buf[i + 2] << 8) | buf[i + 3];
|
||||
#endif
|
||||
}
|
||||
|
||||
// treat size not aligned on 4 as if it were padded to 4 with 0's
|
||||
if (size != aligned_size) {
|
||||
uint32_t v = 0;
|
||||
for (size_t i = aligned_size; i < size; ++i) {
|
||||
v |= buf[i] << (24 - 8 * (i & 3));
|
||||
}
|
||||
checksum += v;
|
||||
}
|
||||
|
||||
return checksum;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
output.resize(output_size);
|
||||
|
||||
woff2::SetFileContents(outfilename, output);
|
||||
woff2::SetFileContents(outfilename, output.begin(), output.end());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
#include "./woff2_out.h"
|
||||
|
||||
namespace woff2 {
|
||||
|
||||
|
@ -31,6 +32,11 @@ size_t ComputeWOFF2FinalSize(const uint8_t *data, size_t length);
|
|||
bool ConvertWOFF2ToTTF(uint8_t *result, size_t result_length,
|
||||
const uint8_t *data, size_t length);
|
||||
|
||||
// Decompresses the font into out. Returns true on success.
|
||||
// Works even if WOFF2Header totalSfntSize is wrong.
|
||||
bool ConvertWOFF2ToTTF(const uint8_t *data, size_t length,
|
||||
WOFF2Out* out);
|
||||
|
||||
} // namespace woff2
|
||||
|
||||
#endif // WOFF2_WOFF2_DEC_H_
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
|
||||
#include "file.h"
|
||||
#include "./file.h"
|
||||
#include "./woff2_dec.h"
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
using std::string;
|
||||
|
||||
|
@ -31,24 +31,18 @@ int main(int argc, char **argv) {
|
|||
|
||||
string filename(argv[1]);
|
||||
string outfilename = filename.substr(0, filename.find_last_of(".")) + ".ttf";
|
||||
fprintf(stdout, "Processing %s => %s\n",
|
||||
filename.c_str(), outfilename.c_str());
|
||||
|
||||
string input = woff2::GetFileContent(filename);
|
||||
const uint8_t* raw_input = reinterpret_cast<const uint8_t*>(input.data());
|
||||
string output(std::min(woff2::ComputeWOFF2FinalSize(raw_input, input.size()),
|
||||
woff2::kDefaultMaxSize), 0);
|
||||
woff2::WOFF2StringOut out(&output);
|
||||
|
||||
size_t decompressed_size = woff2::ComputeWOFF2FinalSize(
|
||||
reinterpret_cast<const uint8_t*>(input.data()), input.size());
|
||||
string output(decompressed_size, 0);
|
||||
const bool ok = woff2::ConvertWOFF2ToTTF(
|
||||
reinterpret_cast<uint8_t*>(&output[0]), decompressed_size,
|
||||
reinterpret_cast<const uint8_t*>(input.data()), input.size());
|
||||
const bool ok = woff2::ConvertWOFF2ToTTF(raw_input, input.size(), &out);
|
||||
|
||||
if (!ok) {
|
||||
fprintf(stderr, "Decompression failed\n");
|
||||
return 1;
|
||||
if (ok) {
|
||||
woff2::SetFileContents(outfilename, output.begin(),
|
||||
output.begin() + out.Size());
|
||||
}
|
||||
|
||||
woff2::SetFileContents(outfilename, output);
|
||||
|
||||
return 0;
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "./compressor.h"
|
||||
#include "./buffer.h"
|
||||
#include "./encode.h"
|
||||
#include "./font.h"
|
||||
#include "./normalize.h"
|
||||
#include "./round.h"
|
||||
|
@ -47,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) {
|
||||
|
@ -120,7 +121,7 @@ size_t ComputeWoff2Length(const FontCollection& font_collection,
|
|||
}
|
||||
|
||||
// for collections only, collection tables
|
||||
if (font_collection.fonts.size() > 1) {
|
||||
if (font_collection.flavor == kTtcFontFlavor) {
|
||||
size += 4; // UInt32 Version of TTC Header
|
||||
size += Size255UShort(font_collection.fonts.size()); // 255UInt16 numFonts
|
||||
|
||||
|
@ -147,14 +148,6 @@ size_t ComputeWoff2Length(const FontCollection& font_collection,
|
|||
return size;
|
||||
}
|
||||
|
||||
size_t ComputeTTFLength(const std::vector<Table>& tables) {
|
||||
size_t size = 12 + 16 * tables.size(); // sfnt header
|
||||
for (const auto& table : tables) {
|
||||
size += Round4(table.src_length);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t ComputeUncompressedLength(const Font& font) {
|
||||
// sfnt header + offset table
|
||||
size_t size = 12 + 16 * font.num_tables;
|
||||
|
@ -168,7 +161,7 @@ size_t ComputeUncompressedLength(const Font& font) {
|
|||
}
|
||||
|
||||
size_t ComputeUncompressedLength(const FontCollection& font_collection) {
|
||||
if (font_collection.fonts.size() == 1) {
|
||||
if (font_collection.flavor != kTtcFontFlavor) {
|
||||
return ComputeUncompressedLength(font_collection.fonts[0]);
|
||||
}
|
||||
size_t size = CollectionHeaderSize(font_collection.header_version,
|
||||
|
@ -279,20 +272,22 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length,
|
|||
std::vector<uint8_t> compression_buf(compression_buffer_size);
|
||||
uint32_t total_compressed_length = compression_buffer_size;
|
||||
|
||||
// Collect all transformed data into one place.
|
||||
// Collect all transformed data into one place in output order.
|
||||
std::vector<uint8_t> transform_buf(total_transform_length);
|
||||
size_t transform_offset = 0;
|
||||
for (const auto& font : font_collection.fonts) {
|
||||
for (const auto& i : font.tables) {
|
||||
const Font::Table* table = font.FindTable(i.second.tag ^ 0x80808080);
|
||||
if (i.second.IsReused()) continue;
|
||||
if (i.second.tag & 0x80808080) continue;
|
||||
for (const auto tag : font.OutputOrderedTags()) {
|
||||
const Font::Table& original = font.tables.at(tag);
|
||||
if (original.IsReused()) continue;
|
||||
if (tag & 0x80808080) continue;
|
||||
const Font::Table* table_to_store = font.FindTable(tag ^ 0x80808080);
|
||||
if (table_to_store == NULL) table_to_store = &original;
|
||||
|
||||
if (table == NULL) table = &i.second;
|
||||
StoreBytes(table->data, table->length,
|
||||
StoreBytes(table_to_store->data, table_to_store->length,
|
||||
&transform_offset, &transform_buf[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// Compress all transformed data in one stream.
|
||||
if (!Woff2Compress(transform_buf.data(), total_transform_length,
|
||||
&compression_buf[0],
|
||||
|
@ -377,13 +372,12 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length,
|
|||
}
|
||||
*result_length = woff2_length;
|
||||
|
||||
const Font& first_font = font_collection.fonts[0];
|
||||
size_t offset = 0;
|
||||
|
||||
// start of woff2 header (http://www.w3.org/TR/WOFF2/#woff20Header)
|
||||
StoreU32(kWoff2Signature, &offset, result);
|
||||
if (font_collection.fonts.size() == 1) {
|
||||
StoreU32(first_font.flavor, &offset, result);
|
||||
if (font_collection.flavor != kTtcFontFlavor) {
|
||||
StoreU32(font_collection.fonts[0].flavor, &offset, result);
|
||||
} else {
|
||||
StoreU32(kTtcFontFlavor, &offset, result);
|
||||
}
|
||||
|
@ -394,9 +388,9 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length,
|
|||
StoreU32(ComputeUncompressedLength(font_collection), &offset, result);
|
||||
StoreU32(total_compressed_length, &offset, result); // totalCompressedSize
|
||||
|
||||
// TODO(user): is always taking this from the first tables head OK?
|
||||
// font revision
|
||||
StoreBytes(first_font.FindTable(kHeadTableTag)->data + 4, 4, &offset, result);
|
||||
// Let's just all be v1.0
|
||||
Store16(1, &offset, result); // majorVersion
|
||||
Store16(0, &offset, result); // minorVersion
|
||||
if (compressed_metadata_buf_length > 0) {
|
||||
StoreU32(woff2_length - compressed_metadata_buf_length,
|
||||
&offset, result); // metaOffset
|
||||
|
@ -418,7 +412,7 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length,
|
|||
}
|
||||
|
||||
// for collections only, collection table directory
|
||||
if (font_collection.fonts.size() > 1) {
|
||||
if (font_collection.flavor == kTtcFontFlavor) {
|
||||
StoreU32(font_collection.header_version, &offset, result);
|
||||
Store255UShort(font_collection.fonts.size(), &offset, result);
|
||||
for (const Font& font : font_collection.fonts) {
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Output buffer for WOFF2 decompression.
|
||||
|
||||
#include "./woff2_out.h"
|
||||
|
||||
namespace woff2 {
|
||||
|
||||
WOFF2StringOut::WOFF2StringOut(string* buf)
|
||||
: buf_(buf),
|
||||
max_size_(kDefaultMaxSize),
|
||||
offset_(0) {}
|
||||
|
||||
bool WOFF2StringOut::Write(const void *buf, size_t n) {
|
||||
return Write(buf, offset_, n);
|
||||
}
|
||||
|
||||
bool WOFF2StringOut::Write(const void *buf, size_t offset, size_t n) {
|
||||
if (offset > max_size_ || n > max_size_ - offset) {
|
||||
return false;
|
||||
}
|
||||
if (offset == buf_->size()) {
|
||||
buf_->append(static_cast<const char*>(buf), n);
|
||||
} else {
|
||||
if (offset + n > buf_->size()) {
|
||||
buf_->append(offset + n - buf_->size(), 0);
|
||||
}
|
||||
buf_->replace(offset, n, static_cast<const char*>(buf), n);
|
||||
}
|
||||
offset_ = std::max(offset_, offset + n);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WOFF2StringOut::SetMaxSize(size_t max_size) {
|
||||
max_size_ = max_size;
|
||||
if (offset_ > max_size_) {
|
||||
offset_ = max_size_;
|
||||
}
|
||||
}
|
||||
|
||||
WOFF2MemoryOut::WOFF2MemoryOut(uint8_t* buf, size_t buf_size)
|
||||
: buf_(buf),
|
||||
buf_size_(buf_size),
|
||||
offset_(0) {}
|
||||
|
||||
bool WOFF2MemoryOut::Write(const void *buf, size_t n) {
|
||||
return Write(buf, offset_, n);
|
||||
}
|
||||
|
||||
bool WOFF2MemoryOut::Write(const void *buf, size_t offset, size_t n) {
|
||||
if (offset > buf_size_ || n > buf_size_ - offset) {
|
||||
return false;
|
||||
}
|
||||
std::memcpy(buf_ + offset, buf, n);
|
||||
offset_ = std::max(offset_, offset + n);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace woff2
|
|
@ -0,0 +1,114 @@
|
|||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Output buffer for WOFF2 decompression.
|
||||
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Output buffer for WOFF2 decompression.
|
||||
|
||||
#ifndef WOFF2_WOFF2_OUT_H_
|
||||
#define WOFF2_WOFF2_OUT_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "./port.h"
|
||||
|
||||
namespace woff2 {
|
||||
|
||||
// Suggested max size for output.
|
||||
const size_t kDefaultMaxSize = 30 * 1024 * 1024;
|
||||
|
||||
using std::string;
|
||||
|
||||
|
||||
/**
|
||||
* Output interface for the woff2 decoding.
|
||||
*
|
||||
* Writes to arbitrary offsets are supported to facilitate updating offset
|
||||
* table and checksums after tables are ready. Reading the current size is
|
||||
* supported so a 'loca' table can be built up while writing glyphs.
|
||||
*
|
||||
* By default limits size to kDefaultMaxSize.
|
||||
*/
|
||||
class WOFF2Out {
|
||||
public:
|
||||
virtual ~WOFF2Out(void) {}
|
||||
|
||||
// Append n bytes of data from buf.
|
||||
// Return true if all written, false otherwise.
|
||||
virtual bool Write(const void *buf, size_t n) = 0;
|
||||
|
||||
// Write n bytes of data from buf at offset.
|
||||
// Return true if all written, false otherwise.
|
||||
virtual bool Write(const void *buf, size_t offset, size_t n) = 0;
|
||||
|
||||
virtual size_t Size() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Expanding memory block for woff2 out. By default limited to kDefaultMaxSize.
|
||||
*/
|
||||
class WOFF2StringOut : public WOFF2Out {
|
||||
public:
|
||||
// Create a writer that writes its data to buf.
|
||||
// buf->size() will grow to at most max_size
|
||||
// buf may be sized (e.g. using EstimateWOFF2FinalSize) or empty.
|
||||
explicit WOFF2StringOut(string* buf);
|
||||
|
||||
bool Write(const void *buf, size_t n) override;
|
||||
bool Write(const void *buf, size_t offset, size_t n) override;
|
||||
size_t Size() override { return offset_; }
|
||||
size_t MaxSize() { return max_size_; }
|
||||
void SetMaxSize(size_t max_size);
|
||||
private:
|
||||
string* buf_;
|
||||
size_t max_size_;
|
||||
size_t offset_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fixed memory block for woff2 out.
|
||||
*/
|
||||
class WOFF2MemoryOut : public WOFF2Out {
|
||||
public:
|
||||
// Create a writer that writes its data to buf.
|
||||
WOFF2MemoryOut(uint8_t* buf, size_t buf_size);
|
||||
|
||||
bool Write(const void *buf, size_t n) override;
|
||||
bool Write(const void *buf, size_t offset, size_t n) override;
|
||||
size_t Size() override { return offset_; }
|
||||
private:
|
||||
uint8_t* buf_;
|
||||
size_t buf_size_;
|
||||
size_t offset_;
|
||||
};
|
||||
|
||||
} // namespace woff2
|
||||
|
||||
#endif // WOFF2_WOFF2_OUT_H_
|
|
@ -13,7 +13,6 @@ perl -p -i -e "s/\[commit [0-9a-f]{40}\]/[${COMMIT}]/" README.mozilla;
|
|||
rm -rf src
|
||||
mv ${MY_TEMP_DIR}/woff2/src src
|
||||
patch -p3 < redefine-unique_ptr.patch
|
||||
patch -p3 < missing-assert-header.patch
|
||||
rm -rf ${MY_TEMP_DIR}
|
||||
hg add src
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче