Bug 964613 - check userfont sets for enabled/disabled local fonts when platform fontlist changes occur. r=jfkthame

This commit is contained in:
John Daggett 2014-04-17 23:17:22 +09:00
parent a2e36f9b6f
commit c14d659b10
7 changed files with 113 additions and 8 deletions

View File

@ -830,13 +830,13 @@ gfxMacPlatformFontList::RegisteredFontsChangedNotificationCallback(CFNotificatio
return; return;
} }
gfxMacPlatformFontList* fl = static_cast<gfxMacPlatformFontList*>(observer);
// xxx - should be carefully pruning the list of fonts, not rebuilding it from scratch // xxx - should be carefully pruning the list of fonts, not rebuilding it from scratch
static_cast<gfxMacPlatformFontList*>(observer)->UpdateFontList(); fl->UpdateFontList();
// modify a preference that will trigger reflow everywhere // modify a preference that will trigger reflow everywhere
static const char kPrefName[] = "font.internaluseonly.changed"; fl->ForceGlobalReflow();
bool fontInternalChange = Preferences::GetBool(kPrefName, false);
Preferences::SetBool(kPrefName, !fontInternalChange);
} }
gfxFontEntry* gfxFontEntry*

View File

@ -9,6 +9,7 @@
#include "prlog.h" #include "prlog.h"
#include "gfxPlatformFontList.h" #include "gfxPlatformFontList.h"
#include "gfxUserFontSet.h"
#include "nsUnicharUtils.h" #include "nsUnicharUtils.h"
#include "nsUnicodeRange.h" #include "nsUnicodeRange.h"
@ -303,6 +304,21 @@ gfxPlatformFontList::ResolveFontName(const nsAString& aFontName, nsAString& aRes
return false; return false;
} }
static PLDHashOperator
RebuildLocalFonts(nsPtrHashKey<gfxUserFontSet>* aKey,
void* aClosure)
{
aKey->GetKey()->RebuildLocalRules();
return PL_DHASH_NEXT;
}
void
gfxPlatformFontList::UpdateFontList()
{
InitFontList();
mUserFontSetList.EnumerateEntries(RebuildLocalFonts, nullptr);
}
struct FontListData { struct FontListData {
FontListData(nsIAtom *aLangGroup, FontListData(nsIAtom *aLangGroup,
const nsACString& aGenericFamily, const nsACString& aGenericFamily,
@ -797,6 +813,11 @@ gfxPlatformFontList::LoadFontInfo()
} }
#endif #endif
if (done) {
mOtherFamilyNamesInitialized = true;
mFaceNamesInitialized = true;
}
return done; return done;
} }
@ -820,8 +841,6 @@ gfxPlatformFontList::CleanupLoader()
} }
#endif #endif
mOtherFamilyNamesInitialized = true;
mFaceNamesInitialized = true;
gfxFontInfoLoader::CleanupLoader(); gfxFontInfoLoader::CleanupLoader();
} }
@ -839,6 +858,15 @@ gfxPlatformFontList::GetPrefsAndStartLoader()
StartLoader(delay, interval); StartLoader(delay, interval);
} }
void
gfxPlatformFontList::ForceGlobalReflow()
{
// modify a preference that will trigger reflow everywhere
static const char kPrefName[] = "font.internaluseonly.changed";
bool fontInternalChange = Preferences::GetBool(kPrefName, false);
Preferences::SetBool(kPrefName, !fontInternalChange);
}
// Support for memory reporting // Support for memory reporting
static size_t static size_t

View File

@ -82,6 +82,8 @@ struct FontListSizes {
uint32_t mCharMapsSize; // memory used for cmap coverage info uint32_t mCharMapsSize; // memory used for cmap coverage info
}; };
class gfxUserFontSet;
class gfxPlatformFontList : public gfxFontInfoLoader class gfxPlatformFontList : public gfxFontInfoLoader
{ {
public: public:
@ -115,7 +117,7 @@ public:
virtual bool ResolveFontName(const nsAString& aFontName, virtual bool ResolveFontName(const nsAString& aFontName,
nsAString& aResolvedFontName); nsAString& aResolvedFontName);
void UpdateFontList() { InitFontList(); } void UpdateFontList();
void ClearPrefFonts() { mPrefFonts.Clear(); } void ClearPrefFonts() { mPrefFonts.Clear(); }
@ -178,6 +180,15 @@ public:
// remove the cmap from the shared cmap set // remove the cmap from the shared cmap set
void RemoveCmap(const gfxCharacterMap *aCharMap); void RemoveCmap(const gfxCharacterMap *aCharMap);
// keep track of userfont sets to notify when global fontlist changes occur
void AddUserFontSet(gfxUserFontSet *aUserFontSet) {
mUserFontSetList.PutEntry(aUserFontSet);
}
void RemoveUserFontSet(gfxUserFontSet *aUserFontSet) {
mUserFontSetList.RemoveEntry(aUserFontSet);
}
protected: protected:
class MemoryReporter MOZ_FINAL : public nsIMemoryReporter class MemoryReporter MOZ_FINAL : public nsIMemoryReporter
{ {
@ -254,6 +265,9 @@ protected:
// read the loader initialization prefs, and start it // read the loader initialization prefs, and start it
void GetPrefsAndStartLoader(); void GetPrefsAndStartLoader();
// for font list changes that affect all documents
void ForceGlobalReflow();
// used by memory reporter to accumulate sizes of family names in the hash // used by memory reporter to accumulate sizes of family names in the hash
static size_t static size_t
SizeOfFamilyNameEntryExcludingThis(const nsAString& aKey, SizeOfFamilyNameEntryExcludingThis(const nsAString& aKey,
@ -305,6 +319,8 @@ protected:
uint32_t mStartIndex; uint32_t mStartIndex;
uint32_t mIncrement; uint32_t mIncrement;
uint32_t mNumFamilies; uint32_t mNumFamilies;
nsTHashtable<nsPtrHashKey<gfxUserFontSet> > mUserFontSetList;
}; };
#endif /* GFXPLATFORMFONTLIST_H_ */ #endif /* GFXPLATFORMFONTLIST_H_ */

View File

@ -18,6 +18,7 @@
#include "gfxFontConstants.h" #include "gfxFontConstants.h"
#include "mozilla/Services.h" #include "mozilla/Services.h"
#include "mozilla/gfx/2D.h" #include "mozilla/gfx/2D.h"
#include "gfxPlatformFontList.h"
#include "opentype-sanitiser.h" #include "opentype-sanitiser.h"
#include "ots-memory-stream.h" #include "ots-memory-stream.h"
@ -102,13 +103,21 @@ gfxProxyFontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeed
} }
gfxUserFontSet::gfxUserFontSet() gfxUserFontSet::gfxUserFontSet()
: mFontFamilies(5) : mFontFamilies(5), mLocalRulesUsed(false)
{ {
IncrementGeneration(); IncrementGeneration();
gfxPlatformFontList *fp = gfxPlatformFontList::PlatformFontList();
if (fp) {
fp->AddUserFontSet(this);
}
} }
gfxUserFontSet::~gfxUserFontSet() gfxUserFontSet::~gfxUserFontSet()
{ {
gfxPlatformFontList *fp = gfxPlatformFontList::PlatformFontList();
if (fp) {
fp->RemoveUserFontSet(this);
}
} }
gfxFontEntry* gfxFontEntry*
@ -539,6 +548,7 @@ gfxUserFontSet::LoadNext(gfxMixedFontFamily *aFamily,
gfxFontEntry *fe = gfxFontEntry *fe =
gfxPlatform::GetPlatform()->LookupLocalFont(aProxyEntry, gfxPlatform::GetPlatform()->LookupLocalFont(aProxyEntry,
currSrc.mLocalName); currSrc.mLocalName);
mLocalRulesUsed = true;
if (fe) { if (fe) {
LOG(("userfonts (%p) [src %d] loaded local: (%s) for (%s) gen: %8.8x\n", LOG(("userfonts (%p) [src %d] loaded local: (%s) for (%s) gen: %8.8x\n",
this, aProxyEntry->mSrcIndex, this, aProxyEntry->mSrcIndex,
@ -664,6 +674,13 @@ gfxUserFontSet::IncrementGeneration()
mGeneration = sFontSetGeneration; mGeneration = sFontSetGeneration;
} }
void
gfxUserFontSet::RebuildLocalRules()
{
if (mLocalRulesUsed) {
DoRebuildUserFontSet();
}
}
gfxFontEntry* gfxFontEntry*
gfxUserFontSet::LoadFont(gfxMixedFontFamily *aFamily, gfxUserFontSet::LoadFont(gfxMixedFontFamily *aFamily,

View File

@ -242,6 +242,9 @@ public:
// increment the generation on font load // increment the generation on font load
void IncrementGeneration(); void IncrementGeneration();
// rebuild if local rules have been used
void RebuildLocalRules();
class UserFontCache { class UserFontCache {
public: public:
// Record a loaded user-font in the cache. This requires that the // Record a loaded user-font in the cache. This requires that the
@ -418,11 +421,17 @@ protected:
static bool OTSMessage(void *aUserData, const char *format, ...); static bool OTSMessage(void *aUserData, const char *format, ...);
// helper method for performing the actual userfont set rebuild
virtual void DoRebuildUserFontSet() = 0;
// font families defined by @font-face rules // font families defined by @font-face rules
nsRefPtrHashtable<nsStringHashKey, gfxMixedFontFamily> mFontFamilies; nsRefPtrHashtable<nsStringHashKey, gfxMixedFontFamily> mFontFamilies;
uint64_t mGeneration; uint64_t mGeneration;
// true when local names have been looked up, false otherwise
bool mLocalRulesUsed;
static PRLogModuleInfo* GetUserFontsLog(); static PRLogModuleInfo* GetUserFontsLog();
private: private:

View File

@ -490,9 +490,24 @@ nsUserFontSet::UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules)
IncrementGeneration(); IncrementGeneration();
} }
// local rules have been rebuilt, so clear the flag
mLocalRulesUsed = false;
return modified; return modified;
} }
static bool
HasLocalSrc(const nsCSSValue::Array *aSrcArr)
{
size_t numSrc = aSrcArr->Count();
for (size_t i = 0; i < numSrc; i++) {
if (aSrcArr->Item(i).GetUnit() == eCSSUnit_Local_Font) {
return true;
}
}
return false;
}
void void
nsUserFontSet::InsertRule(nsCSSFontFaceRule* aRule, uint8_t aSheetType, nsUserFontSet::InsertRule(nsCSSFontFaceRule* aRule, uint8_t aSheetType,
nsTArray<FontFaceRuleRecord>& aOldRules, nsTArray<FontFaceRuleRecord>& aOldRules,
@ -524,8 +539,20 @@ nsUserFontSet::InsertRule(nsCSSFontFaceRule* aRule, uint8_t aSheetType,
// to the new rule list, and put the entry into the appropriate family // to the new rule list, and put the entry into the appropriate family
for (uint32_t i = 0; i < aOldRules.Length(); ++i) { for (uint32_t i = 0; i < aOldRules.Length(); ++i) {
const FontFaceRuleRecord& ruleRec = aOldRules[i]; const FontFaceRuleRecord& ruleRec = aOldRules[i];
if (ruleRec.mContainer.mRule == aRule && if (ruleRec.mContainer.mRule == aRule &&
ruleRec.mContainer.mSheetType == aSheetType) { ruleRec.mContainer.mSheetType == aSheetType) {
// if local rules were used, don't use the old font entry
// for rules containing src local usage
if (mLocalRulesUsed) {
aRule->GetDesc(eCSSFontDesc_Src, val);
unit = val.GetUnit();
if (unit == eCSSUnit_Array && HasLocalSrc(val.GetArrayValue())) {
break;
}
}
AddFontFace(fontfamily, ruleRec.mFontEntry); AddFontFace(fontfamily, ruleRec.mFontEntry);
mRules.AppendElement(ruleRec); mRules.AppendElement(ruleRec);
aOldRules.RemoveElementAt(i); aOldRules.RemoveElementAt(i);
@ -983,3 +1010,9 @@ nsUserFontSet::GetPrivateBrowsing()
nsCOMPtr<nsILoadContext> loadContext = ps->GetDocument()->GetLoadContext(); nsCOMPtr<nsILoadContext> loadContext = ps->GetDocument()->GetLoadContext();
return loadContext && loadContext->UsePrivateBrowsing(); return loadContext && loadContext->UsePrivateBrowsing();
} }
void
nsUserFontSet::DoRebuildUserFontSet()
{
mPresContext->RebuildUserFontSet();
}

View File

@ -87,6 +87,8 @@ protected:
virtual bool GetPrivateBrowsing() MOZ_OVERRIDE; virtual bool GetPrivateBrowsing() MOZ_OVERRIDE;
virtual void DoRebuildUserFontSet() MOZ_OVERRIDE;
nsPresContext* mPresContext; // weak reference nsPresContext* mPresContext; // weak reference
// Set of all loaders pointing to us. These are not strong pointers, // Set of all loaders pointing to us. These are not strong pointers,