Index: Source/platform/fonts/opentype/OpenTypeSanitizer.cpp |
diff --git a/Source/platform/fonts/opentype/OpenTypeSanitizer.cpp b/Source/platform/fonts/opentype/OpenTypeSanitizer.cpp |
index 1a6724407b97f2f220026e263fbfe6f40b7e2bf8..45d7c9fe373a36e39e1be42cb0ea0868a8fdbb21 100644 |
--- a/Source/platform/fonts/opentype/OpenTypeSanitizer.cpp |
+++ b/Source/platform/fonts/opentype/OpenTypeSanitizer.cpp |
@@ -35,22 +35,26 @@ |
#include "platform/SharedBuffer.h" |
#include "opentype-sanitiser.h" |
#include "ots-memory-stream.h" |
+#include "third_party/brotli/src/woff2/woff2_dec.h" |
+#include "wtf/Vector.h" |
namespace blink { |
-PassRefPtr<SharedBuffer> OpenTypeSanitizer::sanitize() |
-{ |
- if (!m_buffer) |
- return nullptr; |
+// This is the largest web font size which we'll try to transcode. |
+static const size_t maxWebFontSize = 30 * 1024 * 1024; // 30 MB |
- // This is the largest web font size which we'll try to transcode. |
- static const size_t maxWebFontSize = 30 * 1024 * 1024; // 30 MB |
- if (m_buffer->size() > maxWebFontSize) |
- return nullptr; |
+static bool isWoff2(SharedBuffer* buffer) |
+{ |
+ static const size_t signatureSize = 4; |
+ if (buffer->size() < signatureSize) |
+ return false; |
- if (RuntimeEnabledFeatures::woff2Enabled()) |
- ots::EnableWOFF2(); |
+ const char* signature = buffer->data(); |
+ return signature[0] == 'w' && signature[1] == 'O' && signature[2] == 'F' && signature[3] == '2'; |
+} |
+static PassRefPtr<SharedBuffer> transcode(const uint8_t* targetData, size_t targetDataSize) |
+{ |
// A transcoded font is usually smaller than an original font. |
// However, it can be slightly bigger than the original one due to |
// name table replacement and/or padding for glyf table. |
@@ -58,14 +62,40 @@ PassRefPtr<SharedBuffer> OpenTypeSanitizer::sanitize() |
// With WOFF fonts, however, we'll be decompressing, so the result can be |
// much larger than the original. |
- ots::ExpandingMemoryStream output(m_buffer->size(), maxWebFontSize); |
- if (!ots::Process(&output, reinterpret_cast<const uint8_t*>(m_buffer->data()), m_buffer->size())) |
+ ots::ExpandingMemoryStream output(targetDataSize, maxWebFontSize); |
+ if (!ots::Process(&output, targetData, targetDataSize)) |
return nullptr; |
const size_t transcodeLen = output.Tell(); |
return SharedBuffer::create(static_cast<unsigned char*>(output.get()), transcodeLen); |
} |
+PassRefPtr<SharedBuffer> OpenTypeSanitizer::sanitize() |
+{ |
+ if (!m_buffer) |
+ return nullptr; |
+ |
+ if (m_buffer->size() > maxWebFontSize) |
+ return nullptr; |
+ |
+ if (RuntimeEnabledFeatures::woff2Enabled()) |
+ ots::EnableWOFF2(); |
+ |
+ const uint8_t* originalData = reinterpret_cast<const uint8_t*>(m_buffer->data()); |
+ size_t originalDataSize = m_buffer->size(); |
+ if (RuntimeEnabledFeatures::woff2Enabled() && isWoff2(m_buffer)) { |
+ size_t woff2Size = woff2::ComputeWOFF2FinalSize(originalData, originalDataSize); |
+ if (woff2Size > maxWebFontSize) |
+ return nullptr; |
+ |
+ Vector<uint8_t> woff2Output(woff2Size); |
+ if (!woff2::ConvertWOFF2ToTTF(woff2Output.data(), woff2Size, originalData, originalDataSize)) |
+ return nullptr; |
+ return transcode(woff2Output.data(), woff2Size); |
+ } |
+ return transcode(originalData, originalDataSize); |
+} |
+ |
bool OpenTypeSanitizer::supportsFormat(const String& format) |
{ |
return equalIgnoringCase(format, "woff") |