Skip to content

Commit

Permalink
Bug 1064737 pt 3 - Read metadata from a WOFF2 font if present. r=jdag…
Browse files Browse the repository at this point in the history
…gett
  • Loading branch information
jfkthame committed Oct 4, 2014
1 parent 0d2cfaf commit 21fd93a
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 16 deletions.
43 changes: 36 additions & 7 deletions gfx/thebes/gfxUserFontSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -280,6 +281,7 @@ gfxUserFontEntry::StoreUserFontData(gfxFontEntry* aFontEntry,
if (aMetadata) {
userFontData->mMetadata.SwapElements(*aMetadata);
userFontData->mMetaOrigLen = aMetaOrigLen;
userFontData->mCompression = aCompression;
}
}

Expand Down Expand Up @@ -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,
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down
13 changes: 11 additions & 2 deletions gfx/thebes/gfxUserFontSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -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() { }

Expand All @@ -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
Expand Down Expand Up @@ -603,7 +611,8 @@ class gfxUserFontEntry : public gfxFontEntry {
bool aPrivate,
const nsAString& aOriginalName,
FallibleTArray<uint8_t>* aMetadata,
uint32_t aMetaOrigLen);
uint32_t aMetaOrigLen,
uint8_t aCompression);

// general load state
UserFontLoadState mUserFontLoadState;
Expand Down
32 changes: 25 additions & 7 deletions layout/inspector/nsFontFace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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;
}
}
}
Expand Down
1 change: 1 addition & 0 deletions layout/media/symbols.def.in
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 21fd93a

Please sign in to comment.