mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-25 20:01:50 +00:00
Bug 1064737 pt 3 - Read metadata from a WOFF2 font if present. r=jdaggett
This commit is contained in:
parent
0d2cfaf334
commit
21fd93a194
@ -254,7 +254,8 @@ gfxUserFontEntry::StoreUserFontData(gfxFontEntry* aFontEntry,
|
||||
bool aPrivate,
|
||||
const nsAString& aOriginalName,
|
||||
FallibleTArray<uint8_t>* 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<typename HeaderT>
|
||||
void
|
||||
CopyWOFFMetadata(const uint8_t* aFontData,
|
||||
uint32_t aLength,
|
||||
FallibleTArray<uint8_t>* 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<const WOFFHeader*>(aFontData);
|
||||
const HeaderT* woff =
|
||||
reinterpret_cast<const HeaderT*>(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<uint8_t> metadata;
|
||||
uint32_t metaOrigLen = 0;
|
||||
uint8_t compression = gfxUserFontData::kUnknownCompression;
|
||||
if (fontType == GFX_USERFONT_WOFF) {
|
||||
CopyWOFFMetadata(aFontData, aLength, &metadata, &metaOrigLen);
|
||||
CopyWOFFMetadata<WOFFHeader>(aFontData, aLength,
|
||||
&metadata, &metaOrigLen);
|
||||
compression = gfxUserFontData::kZlibCompression;
|
||||
} else if (fontType == GFX_USERFONT_WOFF2) {
|
||||
CopyWOFFMetadata<WOFF2Header>(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;
|
||||
|
@ -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 @@ public:
|
||||
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 @@ protected:
|
||||
bool aPrivate,
|
||||
const nsAString& aOriginalName,
|
||||
FallibleTArray<uint8_t>* aMetadata,
|
||||
uint32_t aMetaOrigLen);
|
||||
uint32_t aMetaOrigLen,
|
||||
uint8_t aCompression);
|
||||
|
||||
// general load state
|
||||
UserFontLoadState mUserFontLoadState;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user