b=569770 part 3: provide public access to gfxFontEntry font table cache r=jfkthame

--HG--
extra : rebase_source : ea989eec6d22c0201a58cbe0bb045470e14907f0
This commit is contained in:
Karl Tomlinson 2010-12-09 20:28:47 +13:00
parent 5bcb36df4f
commit 7ed492d291
4 changed files with 68 additions and 22 deletions

View File

@ -419,7 +419,10 @@ gfxDWriteFont::GetFontTable(PRUint32 aTag)
if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
// for downloaded fonts, there may be layout tables cached in the entry
// even though they're absent from the sanitized platform font
return mFontEntry->GetFontTable(aTag);
hb_blob_t *blob;
if (mFontEntry->GetExistingFontTable(aTag, &blob)) {
return blob;
}
}
return nsnull;

View File

@ -317,8 +317,8 @@ gfxFontEntry::FontTableHashEntry::GetBlob() const
return hb_blob_reference(mBlob);
}
hb_blob_t *
gfxFontEntry::GetFontTable(PRUint32 aTag)
PRBool
gfxFontEntry::GetExistingFontTable(PRUint32 aTag, hb_blob_t **aBlob)
{
if (!mFontTableCache.IsInitialized()) {
// we do this here rather than on fontEntry construction
@ -327,21 +327,36 @@ gfxFontEntry::GetFontTable(PRUint32 aTag)
}
FontTableHashEntry *entry = mFontTableCache.GetEntry(aTag);
if (entry) {
return entry->GetBlob();
if (!entry) {
return PR_FALSE;
}
entry = mFontTableCache.PutEntry(aTag);
*aBlob = entry->GetBlob();
return PR_TRUE;
}
hb_blob_t *
gfxFontEntry::ShareFontTableAndGetBlob(PRUint32 aTag,
nsTArray<PRUint8>* aBuffer)
{
if (NS_UNLIKELY(!mFontTableCache.IsInitialized())) {
// we do this here rather than on fontEntry construction
// because not all shapers will access the table cache at all
mFontTableCache.Init(10);
}
FontTableHashEntry *entry = mFontTableCache.PutEntry(aTag);
if (NS_UNLIKELY(!entry)) { // OOM
return nsnull;
}
nsTArray<PRUint8> buffer;
if (NS_FAILED(GetFontTable(aTag, buffer))) {
return nsnull; // leaves the null entry cached in the hashtable
if (!aBuffer) {
// ensure the entry is null
entry->Clear();
return nsnull;
}
return entry->ShareTableAndGetBlob(buffer, &mFontTableCache);
return entry->ShareTableAndGetBlob(*aBuffer, &mFontTableCache);
}
void
@ -1037,6 +1052,19 @@ gfxFont::~gfxFont()
}
}
hb_blob_t *
gfxFont::GetFontTable(PRUint32 aTag) {
hb_blob_t *blob;
if (mFontEntry->GetExistingFontTable(aTag, &blob))
return blob;
nsTArray<PRUint8> buffer;
PRBool haveTable = NS_SUCCEEDED(mFontEntry->GetFontTable(aTag, buffer));
return mFontEntry->ShareFontTableAndGetBlob(aTag,
haveTable ? &buffer : nsnull);
}
/**
* A helper function in case we need to do any rounding or other
* processing here.

View File

@ -286,12 +286,23 @@ public:
already_AddRefed<gfxFont> FindOrMakeFont(const gfxFontStyle *aStyle,
PRBool aNeedsBold);
// Subclasses should override this if they can do something more efficient
// than getting tables with GetFontTable() and caching them in the entry.
// Get an existing font table cache entry in aBlob if it has been
// registered, or return PR_FALSE if not. Callers must call
// hb_blob_destroy on aBlob if PR_TRUE is returned.
//
// Note that some gfxFont implementations may not call this at all,
// if it is more efficient to get the table from the OS at that level.
virtual hb_blob_t *GetFontTable(PRUint32 aTag);
PRBool GetExistingFontTable(PRUint32 aTag, hb_blob_t** aBlob);
// Elements of aTable are transferred (not copied) to and returned in a
// new hb_blob_t which is registered on the gfxFontEntry, but the initial
// reference is owned by the caller. Removing the last reference
// unregisters the table from the font entry.
//
// Pass NULL for aBuffer to indicate that the table is not present and
// NULL will be returned. Also returns NULL on OOM.
hb_blob_t *ShareFontTableAndGetBlob(PRUint32 aTag,
nsTArray<PRUint8>* aTable);
// Preload a font table into the cache (used to store layout tables for
// harfbuzz, when they will be stripped from the actual sfnt being
@ -978,15 +989,16 @@ public:
// returns a pointer to data owned by the fontEntry or the OS,
// which will remain valid until released.
//
// Default implementations forward to the font entry, which
// maintains a shared table cache; however, subclasses may
// override if they can provide more efficient table access.
// Get pointer to a specific font table, or an empty blob if
// Default implementations forward to the font entry,
// and maintain a shared table.
//
// Subclasses should override this if they can provide more efficient
// access than getting tables with mFontEntry->GetFontTable() and sharing
// them via the entry.
//
// Get pointer to a specific font table, or NULL if
// the table doesn't exist in the font
virtual hb_blob_t *GetFontTable(PRUint32 aTag) {
return mFontEntry->GetFontTable(aTag);
}
virtual hb_blob_t *GetFontTable(PRUint32 aTag);
// subclasses may provide hinted glyph widths (in font units);
// if they do not override this, harfbuzz will use unhinted widths

View File

@ -384,7 +384,10 @@ gfxMacFont::GetFontTable(PRUint32 aTag)
if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
// for downloaded fonts, there may be layout tables cached in the entry
// even though they're absent from the sanitized platform font
return mFontEntry->GetFontTable(aTag);
hb_blob_t *blob;
if (mFontEntry->GetExistingFontTable(aTag, &blob)) {
return blob;
}
}
return nsnull;