diff --git a/gfx/thebes/gfxUserFontSet.cpp b/gfx/thebes/gfxUserFontSet.cpp index 44ebb45766624..ba698c7e03e12 100644 --- a/gfx/thebes/gfxUserFontSet.cpp +++ b/gfx/thebes/gfxUserFontSet.cpp @@ -254,7 +254,8 @@ gfxUserFontEntry::StoreUserFontData(gfxFontEntry* aFontEntry, bool aPrivate, const nsAString& aOriginalName, FallibleTArray* aMetadata, - uint32_t aMetaOrigLen) + uint32_t aMetaOrigLen, + uint8_t aCompression) { if (!aFontEntry->mUserFontData) { aFontEntry->mUserFontData = new gfxUserFontData; @@ -280,6 +281,7 @@ gfxUserFontEntry::StoreUserFontData(gfxFontEntry* aFontEntry, if (aMetadata) { userFontData->mMetadata.SwapElements(*aMetadata); userFontData->mMetaOrigLen = aMetaOrigLen; + userFontData->mCompression = aCompression; } } @@ -317,7 +319,25 @@ struct WOFFHeader { AutoSwap_PRUint32 privLen; }; -static void +struct WOFF2Header { + AutoSwap_PRUint32 signature; + AutoSwap_PRUint32 flavor; + AutoSwap_PRUint32 length; + AutoSwap_PRUint16 numTables; + AutoSwap_PRUint16 reserved; + AutoSwap_PRUint32 totalSfntSize; + AutoSwap_PRUint32 totalCompressedSize; + AutoSwap_PRUint16 majorVersion; + AutoSwap_PRUint16 minorVersion; + AutoSwap_PRUint32 metaOffset; + AutoSwap_PRUint32 metaCompLen; + AutoSwap_PRUint32 metaOrigLen; + AutoSwap_PRUint32 privOffset; + AutoSwap_PRUint32 privLen; +}; + +template +void CopyWOFFMetadata(const uint8_t* aFontData, uint32_t aLength, FallibleTArray* aMetadata, @@ -329,10 +349,11 @@ CopyWOFFMetadata(const uint8_t* aFontData, // This just saves a copy of the compressed data block; it does NOT check // that the block can be successfully decompressed, or that it contains // well-formed/valid XML metadata. - if (aLength < sizeof(WOFFHeader)) { + if (aLength < sizeof(HeaderT)) { return; } - const WOFFHeader* woff = reinterpret_cast(aFontData); + const HeaderT* woff = + reinterpret_cast(aFontData); uint32_t metaOffset = woff->metaOffset; uint32_t metaCompLen = woff->metaCompLen; if (!metaOffset || !metaCompLen || !woff->metaOrigLen) { @@ -397,7 +418,8 @@ gfxUserFontEntry::LoadNextSrc() // For src:local(), we don't care whether the request is from // a private window as there's no issue of caching resources; // local fonts are just available all the time. - StoreUserFontData(fe, false, nsString(), nullptr, 0); + StoreUserFontData(fe, false, nsString(), nullptr, 0, + gfxUserFontData::kUnknownCompression); mPlatformFontEntry = fe; SetLoadState(STATUS_LOADED); return; @@ -596,8 +618,15 @@ gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength) // to the gfxUserFontData record below. FallibleTArray metadata; uint32_t metaOrigLen = 0; + uint8_t compression = gfxUserFontData::kUnknownCompression; if (fontType == GFX_USERFONT_WOFF) { - CopyWOFFMetadata(aFontData, aLength, &metadata, &metaOrigLen); + CopyWOFFMetadata(aFontData, aLength, + &metadata, &metaOrigLen); + compression = gfxUserFontData::kZlibCompression; + } else if (fontType == GFX_USERFONT_WOFF2) { + CopyWOFFMetadata(aFontData, aLength, + &metadata, &metaOrigLen); + compression = gfxUserFontData::kBrotliCompression; } // copy OpenType feature/language settings from the userfont entry to the @@ -606,7 +635,7 @@ gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength) fe->mLanguageOverride = mLanguageOverride; fe->mFamilyName = mFamilyName; StoreUserFontData(fe, mFontSet->GetPrivateBrowsing(), originalFullName, - &metadata, metaOrigLen); + &metadata, metaOrigLen, compression); #ifdef PR_LOGGING if (LOG_ENABLED()) { nsAutoCString fontURI; diff --git a/gfx/thebes/gfxUserFontSet.h b/gfx/thebes/gfxUserFontSet.h index 245481a926b10..b2a5bfa8da7a5 100644 --- a/gfx/thebes/gfxUserFontSet.h +++ b/gfx/thebes/gfxUserFontSet.h @@ -92,7 +92,8 @@ class gfxUserFontData { public: gfxUserFontData() : mSrcIndex(0), mFormat(0), mMetaOrigLen(0), - mCRC32(0), mLength(0), mPrivate(false), mIsBuffer(false) + mCRC32(0), mLength(0), mCompression(kUnknownCompression), + mPrivate(false), mIsBuffer(false) { } virtual ~gfxUserFontData() { } @@ -106,8 +107,15 @@ class gfxUserFontData { uint32_t mMetaOrigLen; // length needed to decompress metadata uint32_t mCRC32; // Checksum uint32_t mLength; // Font length + uint8_t mCompression; // compression type bool mPrivate; // whether font belongs to a private window bool mIsBuffer; // whether the font source was a buffer + + enum { + kUnknownCompression = 0, + kZlibCompression = 1, + kBrotliCompression = 2 + }; }; // initially contains a set of userfont font entry objects, replaced with @@ -603,7 +611,8 @@ class gfxUserFontEntry : public gfxFontEntry { bool aPrivate, const nsAString& aOriginalName, FallibleTArray* aMetadata, - uint32_t aMetaOrigLen); + uint32_t aMetaOrigLen, + uint8_t aCompression); // general load state UserFontLoadState mUserFontLoadState; diff --git a/layout/inspector/nsFontFace.cpp b/layout/inspector/nsFontFace.cpp index 636f8f51b6a07..02be73a8d08c5 100644 --- a/layout/inspector/nsFontFace.cpp +++ b/layout/inspector/nsFontFace.cpp @@ -9,6 +9,7 @@ #include "gfxUserFontSet.h" #include "nsFontFaceLoader.h" #include "mozilla/gfx/2D.h" +#include "decode.h" #include "zlib.h" #include "mozilla/dom/FontFaceSet.h" @@ -202,13 +203,30 @@ nsFontFace::GetMetadata(nsAString & aMetadata) nsAutoCString str; str.SetLength(userFontData->mMetaOrigLen); if (str.Length() == userFontData->mMetaOrigLen) { - uLongf destLen = userFontData->mMetaOrigLen; - if (uncompress((Bytef *)(str.BeginWriting()), &destLen, - (const Bytef *)(userFontData->mMetadata.Elements()), - userFontData->mMetadata.Length()) == Z_OK && - destLen == userFontData->mMetaOrigLen) - { - AppendUTF8toUTF16(str, aMetadata); + switch (userFontData->mCompression) { + case gfxUserFontData::kZlibCompression: + { + uLongf destLen = userFontData->mMetaOrigLen; + if (uncompress((Bytef *)(str.BeginWriting()), &destLen, + (const Bytef *)(userFontData->mMetadata.Elements()), + userFontData->mMetadata.Length()) == Z_OK && + destLen == userFontData->mMetaOrigLen) { + AppendUTF8toUTF16(str, aMetadata); + } + } + break; + case gfxUserFontData::kBrotliCompression: + { + size_t decodedSize = userFontData->mMetaOrigLen; + if (BrotliDecompressBuffer(userFontData->mMetadata.Length(), + userFontData->mMetadata.Elements(), + &decodedSize, + (uint8_t*)str.BeginWriting()) == 1 && + decodedSize == userFontData->mMetaOrigLen) { + AppendUTF8toUTF16(str, aMetadata); + } + } + break; } } } diff --git a/layout/media/symbols.def.in b/layout/media/symbols.def.in index 063e0061abea5..6f15655a526cc 100644 --- a/layout/media/symbols.def.in +++ b/layout/media/symbols.def.in @@ -612,3 +612,4 @@ hb_unicode_funcs_set_eastasian_width_func hb_unicode_funcs_set_general_category_func hb_unicode_funcs_set_mirroring_func hb_unicode_funcs_set_script_func +BrotliDecompressBuffer